我的程序必须显示一个旋转的立方体,用简单的灯照亮。 问题是立方体正在闪烁。当我撤回调用glEnable(GL_DEPTH_TEST)时,立方体不闪烁,但我可以看到它内部的面(这是正常的,因为没有深度测试)。但是这个电话是必不可少的所以我不明白为什么这个函数的调用不能正常工作。
这是我的代码:
#include <iostream>
#include <SDL/SDL.h>
#include <gl/glut.h>
const static int WIDTH = 640;
const static int HEIGHT = 480;
GLfloat angle = 0.0f;
static GLfloat position[4] = {0.0, 50.0, -50.0, 1.0};
static GLfloat diffuse[3] = {0.64, 0.64, 0.64};
static GLfloat specular[3] = {0.64, 0.64, 0.64};
static GLfloat emissive[3] = {0.0, 0.0, 1.0};
static GLfloat vertices[72] =
{
1.000000, -1.000000, -1.000000, //V1
1.000000, -1.000000, 1.000000, //V2
-1.000000, -1.000000, 1.000000, //V3
-1.000000, -1.000000, -1.000000, //V4
1.000000, 1.000000, -0.999999, //V5
-1.000000, 1.000000, -1.000000, //V8
-1.000000, 1.000000, 1.000000, //V7
0.999999, 1.000000, 1.000001, //V6
1.000000, -1.000000, -1.000000, //V1
1.000000, 1.000000, -0.999999, //V5
0.999999, 1.000000, 1.000001, //V6
1.000000, -1.000000, 1.000000, //V2
1.000000, -1.000000, 1.000000, //V2
0.999999, 1.000000, 1.000001, //V6
-1.000000, 1.000000, 1.000000, //V7
-1.000000, -1.000000, 1.000000, //V3
-1.000000, -1.000000, 1.000000, //V3
-1.000000, 1.000000, 1.000000, //V7
-1.000000, 1.000000, -1.000000, //V8
-1.000000, -1.000000, -1.000000, //V4
1.000000, 1.000000, -0.999999, //V5
1.000000, -1.000000, -1.000000, //V1
-1.000000, -1.000000, -1.000000, //V4
-1.000000, 1.000000, -1.000000 //V8
};
static GLfloat normals[72] =
{
0.000000, -1.000000, 0.000000,
0.000000, -1.000000, 0.000000,
0.000000, -1.000000, 0.000000,
0.000000, -1.000000, 0.000000,
0.000000, 1.000000, 0.000000,
0.000000, 1.000000, 0.000000,
0.000000, 1.000000, 0.000000,
0.000000, 1.000000, 0.000000,
1.000000, 0.000000, 0.000000,
1.000000, 0.000000, 0.000000,
1.000000, 0.000000, 0.000000,
1.000000, 0.000000, 0.000000,
-0.000000, -0.000000, 1.000000,
-0.000000, -0.000000, 1.000000,
-0.000000, -0.000000, 1.000000,
-0.000000, -0.000000, 1.000000,
-1.000000, -0.000000, -0.000000,
-1.000000, -0.000000, -0.000000,
-1.000000, -0.000000, -0.000000,
-1.000000, -0.000000, -0.000000,
0.000000, -0.000000, -1.000000,
0.000000, -0.000000, -1.000000,
0.000000, -0.000000, -1.000000,
0.000000, -0.000000, -1.000000
};
static void eventListener(SDL_Event *pEvent, bool *pContinue)
{
while (SDL_PollEvent(pEvent))
{
switch(pEvent->type)
{
case SDL_QUIT:
*pContinue = false;
break;
case SDL_KEYDOWN:
switch (pEvent->key.keysym.sym)
{
case SDLK_ESCAPE:
*pContinue = false;
break;
}
}
}
}
static void beginRender(void)
{
/*Perspective*/
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, WIDTH, HEIGHT);
gluPerspective(60.0, (float)(WIDTH/HEIGHT), 0.0f, 1000.0f);
gluLookAt(0.0f, 0.0, 7.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
/*Clear screen*/
glClearDepth(1.0f);
glClearColor(0.13f, 0.12f, 0.13f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*Prepare model transformations*/
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/*Light settings*/
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
/*Depth test*/
glEnable(GL_DEPTH_TEST); //PROBLEM COMES FROM HERE
}
static void renderFrame(void)
{
/*light position*/
glLightfv(GL_LIGHT0, GL_POSITION, position);
/*Model transformations*/
glPushMatrix();
glRotatef(angle, 0.0f, 1.0f, 1.0f);
/*Light materials*/
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialfv(GL_FRONT, GL_EMISSION, emissive);
glMateriali(GL_FRONT, GL_SHININESS, 10);
/*Model rendering*/
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glNormalPointer(GL_FLOAT, 0, normals);
glDrawArrays(GL_QUADS, 0, 24);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
angle += 0.010f;
glPopMatrix();
}
static void endRender(void)
{
glFlush();
SDL_GL_SwapBuffers();
}
static void startRendering(void)
{
bool continuer = true;
SDL_Event event;
while (continuer)
{
eventListener(&event, &continuer);
beginRender();
renderFrame();
endRender();
}
}
int main(int ac, char **av)
{
SDL_Init(SDL_INIT_VIDEO);
SDL_WM_SetCaption("Test luminosity",NULL);
SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_OPENGL | SDL_DOUBLEBUF);
startRendering();
SDL_Quit();
return (0);
}
这是带glEnable(GL_DEPTH_TEST)的屏幕(面部闪烁)
没有这个电话(没有闪烁显示但没有深度测试)
我尝试了几个代码组合而没有成功。
有人可以帮助我吗?
提前感谢您的帮助。
答案 0 :(得分:8)
您的近剪裁平面设置不正确,因此您的Z缓冲无法正常工作。
gluPerspective(60.0, (float)(WIDTH/HEIGHT), 0.0f, 1000.0f);
^^^^
将它设置在合理的距离 - 尽可能远的地方。
另外,请勿将相机方向(即视图变换)放入投影矩阵......
最后,请注意,大多数此功能已弃用,并且在较新版本的GL中不再可用。建议的方法是处理您自己的矩阵计算,并使用可编程管道来渲染几何体。