如何解决相同平面中另一个多边形内的多边形
| 我的OpenGL代码中有一个奇怪的行为。我想在地面上铺地毯。 在下面的代码中,如果GROUND_SIZE大于2071并且CARPET_HEIGHT小于0.0003,则较小的多边形将不会绘制。绘制顺序不会更改生成的图像。#include <GL/glut.h>
const int GROUND_SIZE = 3000;
const bool GROUND_FirsT = true;
const float CARPET_HEIGHT = 0.0003;
void carpet(){
glColor3f(1.0,0.0,0.0);
glBegin(GL_QUADS);
glnormal3f(0,1,0);
glVertex3f(-1.0,-1.0,CARPET_HEIGHT);
glVertex3f( 1.0,1.0,CARPET_HEIGHT);
glVertex3f(-1.0,CARPET_HEIGHT);
glEnd();
}
void ground(){
glColor3f(0.0,0.7,0);
glVertex3f(-GROUND_SIZE,-GROUND_SIZE,0);
glVertex3f( GROUND_SIZE,GROUND_SIZE,0);
glEnd();
}
void draw(){
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if (GROUND_FirsT) {
ground();
carpet();
}
else {
carpet();
ground();
}
glutSwapBuffers();
}
int main(){
int argc = 1; char* argv[] = { (char*)\"\" };
glutinit(&argc,argv);
glutinitdisplayMode(gluT_RGBA | gluT_DEPTH | gluT_DOUBLE);
glutinitwindowPosition(100,50);
glutinitwindowSize(640,640);
glutCreateWindow(\"Window\");
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
glClearColor(0.0f,1.0f,1.0f);
glutdisplayFunc(draw);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,0.1,1000.0);
gluLookAt(0.0,-5.0,0.0f,1);
glutMainLoop();
return 0;
}
我想了解OpenGL用于确定是否会绘制同一平面中另一个多边形内部的多边形的规则。
谢谢
解决方法
首先,一些代码错误。
切勿将gluLookAt矩阵放在GL_PROJECTION矩阵中。这可以在您的灯光下播放havok。 gluLookAt的矩阵应该是您放入GL_MODELVIEW中的第一个矩阵。
将GL_MODELVIEW矩阵作为默认矩阵也是一个好主意。也就是说,任何切换到GL_PROJECTION(或纹理矩阵之一)的代码都负责在处理完另一个矩阵后立即切换回GL_MODELVIEW。
最后,调用glClearDepth和glDepthFunc总是一种很好的形式。默认值(1.0和GL_LESS)正是您想要的,但是明确说明这些东西总是很好的。这样,您就不必遍历整个规范以确保默认值就是您认为的默认值。
现在,讨论主要问题。
规则只是深度缓冲区的规则。同时既简单又复杂。
首先,有两个平面的斜率。虽然它们在世界空间中肯定具有相同的斜率,但在投影后空间中不一定具有相同的斜率。这是由于从世界空间到投影后空间的各种计算中的浮点误差。
其次,如果它们之间的Z差异太小,则可能发生的事情是它们将获得相同的Z值应用于它们。否则由于浮点误差,地毯甚至可能具有较小的Z值。
我想如果您对视角进行动画处理,您会看到地毯平面突然弹出和弹出。
您可以做的一件简单的事情就是始终在地平面之后绘制地毯,并对glDepthFunc使用GL_LEQUAL。再次由于浮点错误,这可能无法100%地起作用。
下一步是使用多边形偏移。这是将基元的Z值偏移某个固定值。对于本次讨论而言,其工作方式的细节过于技术性(如果您感到好奇,请查看OpenGL规范),但是基本思想是您的
carpet
函数应如下所示:
glEnable(GL_POLYGON_OFFSET_FILL); //Activates polygon offsets for filled triangles.
glPolygonOffset(0,2); //The 2 is just for safety\'s sake; 1 ought to be enough.
//Draw the carpet
glDisable(GL_POLYGON_OFFSET_FILL); //Turn off polygon offsetting.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。