OpenGL纹理对象可见性(GLUT)

时间:2011-06-22 21:03:25

标签: c opengl textures glut

我正在尝试使用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;
}

1 个答案:

答案 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()