我正在尝试使用C中的GLUT在openGL中创建一个带纹理的表对象,但是当涉及到某些元素的“可见性”时它会失败,例如当桌子倒置时你应该看到它的腿,否则它应该被隐藏(至少部分隐藏)。我在下面发布代码,你可以使用键盘上的L和J键来旋转X和I / K键来旋转Y因子。提前谢谢!
#include <GL/glut.h>
#include <math.h>
#define TEXWIDTH 32
#define TEXHEIGHT 32
GLubyte def_tekstury[TEXHEIGHT][TEXWIDTH][3];
GLuint id_tekstury;
int done = 0;
const unsigned char left = 'j';
const unsigned char right = 'l';
const unsigned char down = 'k';
const unsigned char up = 'i';
const GLfloat GL_PI=3.1415f;
int proba[4] = {1,2,31,32};
void generate_def_tekstury()
{
int s, t;
/* generujemy zolto-czerwona szachownice o polach 4x4 */
for (s = 0; s < TEXWIDTH; ++s) {
for (t = 0; t < TEXHEIGHT; ++t) {
if ((s % 8 < 4 && t % 8 < 4) || (s % 8 >= 4 && t % 8 >= 4)) {
def_tekstury[t][s][0] = 255;
def_tekstury[t][s][1] = 255;
def_tekstury[t][s][2] = 0;
} else {
def_tekstury[t][s][0] = 255;
def_tekstury[t][s][1] = 0;
def_tekstury[t][s][2] = 0;
}
}
}
/* kwadrat w lewym downnym rogu jest bialy, w lewym gornym zielony */
for (s = 0; s < 4; ++s) {
for (t = 0; t < 4; ++t) {
def_tekstury[t][s][0] = 255;
def_tekstury[t][s][1] = 255;
def_tekstury[t][s][2] = 255;
}
for (t = TEXHEIGHT - 4; t < TEXHEIGHT; ++t) {
def_tekstury[t][s][0] = 0;
def_tekstury[t][s][1] = 255;
def_tekstury[t][s][2] = 0;
}
}
}
void init()
{
glClearColor(0.560784, 0.560784, 0.737255, 0.0);
glEnable(GL_TEXTURE_2D);
//glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
/* tworzymy nowa teksture*/
glGenTextures(1, &id_tekstury);
/* wybierz jako biezaca */
glBindTexture(GL_TEXTURE_2D, id_tekstury);
/* ustaw jej parametry */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
/* zaladuj dane tekseli */
generate_def_tekstury();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, TEXWIDTH,
TEXHEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, def_tekstury);
}
void keyboard(unsigned char key, int x, int y)
{
if (key == down)
{
glRotatef(-10,0.0f,1.0f,0.0f);
glutPostRedisplay();
}
if (key == left)
{
glRotatef(-10,-1.0f,0.0f,0.0f);
glutPostRedisplay();
}
if (key == right)
{
glRotatef(10,1.0f,0.0f,0.0f);
glutPostRedisplay();
}
if (key == up)
{
glRotatef(10,0.0f,1.0f,0.0f);
glutPostRedisplay();
}
}
void display(void)
{
int c,c1;
GLfloat x,y,z,kat;
if(done == 0)
{
glOrtho(-7.0, 7.0 , -7.0, 7.0, -7.0, 7.0);
done = 1;
}
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 0.0);
glRotatef(20,1.0f,0.0f,0.0f);
glRotatef(20,0.0f,1.0f,0.0f);
//gluLookAt(- , eyeY , eyeZ , centerX , centerY , centerZ , upX , upY , upZ )
//glEnable(GL_CULL_FACE);
//glCullFace(GL_BACK);
glFrontFace(GL_CW);
//zmianarysowaniatylniej
//glPolygonMode(GL_BACK, GL_LINE);
glBegin(GL_QUADS);
//spod stołu
//glColor3f(0.55f, 0.34f, 0.23f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-5.0f,-1.0f,5.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-5.0f,-1.0f,-5.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(5.0f,-1.0f,-5.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(5.0f,-1.0f,5.0f);
//wierzch stołu
//glColor3f(0.55f, 0.34f, 0.23f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-5.0f,-0.6f,5.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-5.0f,-0.6f,-5.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(5.0f,-0.6f,-5.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(5.0f,-0.6f,5.0f);
//lewa
//glColor3f(0.55f, 0.34f, 0.23f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-5.0f,-1.0f,-5.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-5.0f,-1.0f,5.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-5.0f,-0.6f,5.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-5.0f,-0.6f,-5.0f);
//prawa
//glColor3f(0.55f, 0.34f, 0.23f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(5.0f,-0.6f,-5.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(5.0f,-0.6f,5.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(5.0f,-1.0f,5.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(5.0f,-1.0f,-5.0f);
//przod
//glColor3f(0.55f, 0.34f, 0.23f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-5.0f,-1.0f,5.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(5.0f,-1.0f,5.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(5.0f,-0.6f,5.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-5.0f,-0.6f,5.0f);
//sciana tylnia
//glColor3f(0.55f, 0.34f, 0.23f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-5.0f,-0.6f,-5.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(5.0f,-0.6f,-5.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(5.0f,-1.0f,-5.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-5.0f,-1.0f,-5.0f);
glEnd();
x=0.0;
y=0.0;
z=0.0;
kat=0.0;
for(c=-1; c<2; c=c+2)
{
for(c1=-1; c1<2; c1=c1+2)
{
glBegin(GL_QUAD_STRIP);
for(kat = 0.0f; kat < (2.0f*GL_PI); kat += (GL_PI/32.0f))
{
x = 0.4f*sin(kat)-3.0f*c;
z = 0.4f*cos(kat)-3.0f*c1;
glTexCoord2f(0.0f, 1.0f);
glVertex3f(x, -0.6, z);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(x, 4.0, z);
}
glEnd();
}
}
glFlush();
}
int main(int argc, char *argv[])
{
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(800, 600);
glutInit(&argc, argv);
glutCreateWindow("Okno OpenGL");
init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
答案 0 :(得分:2)
您需要的是启用Z缓冲即深度测试。首先你需要一个深度缓冲区(你肯定也想要双缓冲,否则你可以看到图像是如何渲染的,导致闪烁):
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
然后您必须使用
启用深度测试glEnable(GL_DEPTH_TEST);
要使深度测试正常工作,您必须在开始渲染新帧时清除深度缓冲区:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
由于我们启用了双缓冲,因此在display()
// glFlush();
glutSwapBuffers(); // Buffer swapping implies a glFlush()