我在屏幕上绘制了一个glutSolidCube和一个glutSolidTeapot。
每当我激活glEnable(GL_CULL_FACE)时,我会为每个对象获得不同的结果。我可以正确显示立方体(glCullFace(GL_BACK)),或茶壶(glCullFace(GL_FRONT)),但不能同时显示它们。
如果我禁用剔除,那么它们都会正确显示,但我希望能够激活它。
我定义的其他对象也没有正确显示。
由于这些objets是在GLUT中定义的,我可以猜测这不是他们法线的问题,或者是它?
我展示了效果的图像:
光线定义:
void setLighting(void) {
//setMaterial();
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
//ambient light color variables
GLfloat alr = 0.0;
GLfloat alg = 0.0;
GLfloat alb = 0.0;
//diffuse light color variables
GLfloat dlr = 1.0;
GLfloat dlg = 1.0;
GLfloat dlb = 1.0;
//specular light color variables
GLfloat slr = 1.0;
GLfloat slg = 1.0;
GLfloat slb = 1.0;
//light position variables
GLfloat lx = 0.0;
GLfloat ly = 100.0;
GLfloat lz = 100.0;
GLfloat lw = 0.0;
GLfloat DiffuseLight[] = {dlr, dlg, dlb}; //set DiffuseLight[] to the specified values
GLfloat AmbientLight[] = {alr, alg, alb}; //set AmbientLight[] to the specified values
GLfloat SpecularLight[] = {slr, slg, slb}; //set AmbientLight[] to the specified values
GLfloat LightPosition[] = {lx, ly, lz, lw}; //set the LightPosition to the specified values
GLfloat global_ambient[] = { 0.1f, 0.1f, 0.1f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glEnable(GL_LIGHTING);
glLightfv (GL_LIGHT0, GL_DIFFUSE, DiffuseLight); //change the light accordingly
glLightfv (GL_LIGHT0, GL_AMBIENT, AmbientLight); //change the light accordingly
glLightfv (GL_LIGHT0, GL_SPECULAR, SpecularLight); //change the light accordingly
glLightfv (GL_LIGHT0, GL_POSITION, LightPosition); //change the light accordingly
}
深度测试和剔除启用:
glEnable(GL_DEPTH_TEST); // Enable the depth buffer
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Ask for nicest perspective correction
glEnable(GL_CULL_FACE); // Cull back facing polygons
glCullFace(GL_BACK);
答案 0 :(得分:2)
你的深度缓冲看起来很糟糕。
你呢,
我知道你发布的关于你定义的物体的部分与过剩的茶壶相比,但是过剩的茶壶确实有一个CCW顶点缠绕,所以当你打开剔除时它没有出现这一事实让我深入思考缓冲液中。
答案 1 :(得分:1)
简单的面部剔除基于顶点的顺序 - 无论它们是在屏幕空间中顺时针方向还是逆时针方向。因此,问题可能在于顶点的定义顺序,或者您可能正在应用某种类型的变换,这会颠倒顺序(例如,负缩放)。法线只在照明中发挥作用。
答案 2 :(得分:1)
这句话似乎很奇怪:
每当我激活glEnable(GL_CULL_FACE)时,我会为每个对象获得不同的结果。我可以正确显示立方体(glCullFace(GL_BACK)),或茶壶(glCullFace(GL_FRONT)),但不能同时显示它们。
对此有两种可能的解释:
您的GLUT是否有缺陷,或者您(意外地?)交换了Z轴(例如,通过使用近和远裁剪平面的所有负距离)。
您切换了正面缠绕方向(致电glFrontFace
)
我定义的其他对象也没有正确显示。
正面由屏幕空间顶点绕组确定。顶点顺时针或逆时针在屏幕上排序。默认情况下,OpenGL假定以顶点逆时针方向绘制的面作为正面。不考虑法线。
我认为解决此问题的最简单方法是交换提交顶点的顺序。
答案 3 :(得分:-1)
我认为 GLUT 茶壶只有在没有启用 CULL_FACE 的情况下才能正确渲染,这表明生成的法线与顶点顺序不对应。这样做的视觉效果是茶壶似乎与其他物体以相反的方向旋转。这就是众所周知的旋转空心面罩的效果。大脑试图从灯光中获取线索来理解场景。如果我在绘制之前通过 glScalef(-1,-1,-1) 反转空间,它看起来就像一个普通的茶壶,即使在剔除时也是如此。
另请注意,茶壶不是封闭的表面,通过剔除,您可以沿着盖子周围的缝隙看穿它。
如果你想在这个不可剔除的茶壶旁边组合“剔除”对象,你可以在渲染茶壶时关闭剔除。
答案 4 :(得分:-2)
天哪,我最近几天一直在研究这个,只是找到了解决方案。
显然!,您必须设置:
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE); // Don't waste energy trying the glCullFace(GL_BACK);
// thing since its set at GL_BACK by default.
// Yes, it does cuts triangle NOT facing you.
另外,请确保您的相机不在像 0.0000001f 到 10 亿的疯狂距离。
然后,除了一个晦涩的教程之外,我没有在任何地方找到它,但是您必须设置深度帧缓冲区(是的,还有另外 5 行)。
在生成 framebuffername ( glGenFramebuffers(1, &FramebufferName);) 之后和显示/循环之前,将这 5 行放在任何地方,这样就可以了。我在 FramebufferName 生成之前尝试过它,但它没有用。但是在纹理生成之前或之后,它仍然有效。
// The depth buffer
GLuint depthrenderbuffer = 0;
glGenRenderbuffers(1, &depthrenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, windowWidth, windowHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer);
多年来,这个 openGL 确实让我发疯,但我仍然找不到一个完整的高级 C++ 库,它包含每个 opengl 调用。但我现在正在构建一个,如果有人感兴趣,我可能会在这几天发布它。