Winapi 如何正确设置OpenGL场景以可视化单个对象
我需要为我的网格工具包编写一个简单的可视化工具。我正在使用的对象始终位于[-1,1]^3框(含)内,因此我需要确保用户完全可以看到该对象。我还想有一个可能性,旋转一个物体周围的相机,就像用户是“飞行”周围的物体 我就是这样做的:Winapi 如何正确设置OpenGL场景以可视化单个对象,winapi,opengl,wgl,Winapi,Opengl,Wgl,我需要为我的网格工具包编写一个简单的可视化工具。我正在使用的对象始终位于[-1,1]^3框(含)内,因此我需要确保用户完全可以看到该对象。我还想有一个可能性,旋转一个物体周围的相机,就像用户是“飞行”周围的物体 我就是这样做的: static void Reshape(int w, int h) { glViewport(0,0,(GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity()
static void Reshape(int w, int h)
{
glViewport(0,0,(GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float maxDistance = sqrt(2);
if (w <= h)
{
glOrtho(-maxDistance, maxDistance, -maxDistance * (GLfloat)h / (GLfloat)w,
maxDistance * (GLfloat)h / (GLfloat)w, -6.0, 6.0);
}
else
{
glOrtho(-maxDistance * (GLfloat)w / (GLfloat)h, maxDistance * (GLfloat)w / (GLfloat)h,
-maxDistance, maxDistance, -6.0, 6.0);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
static void PolarView(GLdouble distance, GLdouble twist, GLdouble elevation)
{
double centerx, centery, centerz;
double eyex, eyey, eyez;
eyex = distance * cos(-twist) * cos(elevation);
eyey = distance * sin(-twist) * cos(elevation);
eyez = distance * sin(elevation);
centerx = centery = centerz = 0;
gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, 0, 0, 1);
}
我的像素格式描述符:
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
32, // Depth buffer size
0,
0,
PFD_MAIN_PLANE,
0,
0,
0,
0
};
我找到了一些解决方法:
- 交换近平面和远平面的值
- 将
设置为glDepthFunc
并将GL\u更大
设置为glClearDepth
0
好的,如果出现偶数个错误,我的代码将正常工作。但第一个错误在哪里
- 你读过吗
你的代码有一点可疑,那就是近平面的负数。负Z值位于摄影机后面,这在渲染3D场景时通常是错误的。然而,这本身不应该引起您看到的问题,Z的范围[-6,6]应该为这种场景提供足够的精度
您正在呼叫glEnable(GL_深度_测试)?您是否将
GL\u DEPTH\u BUFFER\u位
传递给glClear
每一帧
更新:您正在调用glPolygonMode(GL\u-FRONT,GL\u-LINE)
。这意味着前向三角形仅以轮廓绘制,这意味着如果前向三角形A与另一个前向三角形B重叠,则您可以通过A看到B的边缘。对于凸体,这不会发生,因此您不会注意到问题
如果希望三角形遮挡其后面的三角形,则需要使用模式GL\u fill
填充它们。要获得线框图形,需要使用白色填充绘制模型,然后使用黑色轮廓再次绘制模型,如下所示:
glDepthFunc(GL_LEQUAL);
glPolygonMode(GL_FRONT, GL_FILL);
/* draw the model in white */
glDepthFunc(GL_EQUAL);
glPolygonMode(GL_FRONT, GL_LINE);
/* draw the model again in black */
glDepthFunc(GL_LEQUAL);
glPolygonMode(GL_前端,GL_填充);
/*把模型画成白色*/
glDepthFunc(GL_等于);
glPolygonMode(GL_前端,GL_线);
/*再次以黑色绘制模型*/
我们的想法是,在模型的第二个过程中,我们只想绘制轮廓,这些轮廓不会被第一个过程中绘制的更靠近摄影机的三角形(即Z较低的三角形)遮挡
另一个想法:我认为你的相机可能指向错误的方向。这就解释了为什么使用glOrtho透视图绘制场景是错误的,而使用glFrustum透视图绘制场景是错误的。在格洛托的案例中,整个场景都在摄影机后面绘制;这就是为什么它的Z顺序画错了。将“近平面”设置为正数时,将剔除整个场景。“8.070如何自动计算显示整个模型的视图?(我知道边界球体和上方向向量)。”中的条目回答了我的问题。但是,我的设置略有不同,以下是我重写的PolarView和重塑功能:
static void Reshape(int w, int h)
{
float diameter = sqrt(3);
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLdouble zNear = 1;
GLdouble zFar = zNear + diameter * 2;
GLdouble left = -diameter;
GLdouble right = diameter;
GLdouble top = -diameter;
GLdouble bottom = diameter;
double aspect = (double)w / (double)h;
if (aspect < 1)
{
bottom /= aspect;
top /= aspect;
}
else
{
left *= aspect;
right *= aspect;
}
glOrtho(left, right, bottom, top, zNear, zFar);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
static void PolarView(GLdouble twist, GLdouble elevation)
{
float diameter = sqrt(3);
double distance = diameter * 2;
double centerx, centery, centerz;
double eyex, eyey, eyez;
eyex = distance * cos(twist) * cos(elevation);
eyey = distance * sin(twist) * cos(elevation);
eyez = distance * sin(elevation);
centerx = centery = centerz = 0;
gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, 0, 0, 1);
}
静态空洞重塑(int w,int h)
{
浮子直径=sqrt(3);
GLVIEW(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_投影);
glLoadIdentity();
glznear=1;
GLZfar=zNear+直径*2;
GLdouble left=-直径;
GLdouble right=直径;
gl双顶部=-直径;
GLD双底=直径;
双方向=(双)w/(双)h;
如果(方面<1)
{
底部/=侧面;
顶端/=侧面;
}
其他的
{
左*=纵横比;
右*=方面;
}
格洛托(左、右、下、上、zNear、zFar);
glMatrixMode(GLU模型视图);
glLoadIdentity();
}
静态空心PolarView(GLdouble twist,GLdouble elevation)
{
浮子直径=sqrt(3);
双倍距离=直径*2;
双centerx、centery、centerz;
双目镜,双目镜,双目镜;
eyex=距离*cos(扭转)*cos(仰角);
eyey=距离*sin(扭转)*cos(仰角);
eyez=距离*sin(高程);
centerx=centery=centerz=0;
gluLookAt(eyex,eyey,eyez,centerx,centery,centerz,0,0,1);
}
您需要详细说明问题所在。这很难理解。甚至可能是一个屏幕截图?那个链接对我没有帮助。我在问题中添加了更多的代码。无论我如何绘制多边形(GL_线或GL_填充),问题仍然存在。有没有证据表明使用GL_线渲染不应该使用深度缓冲区?你能照我上面建议的那样拍摄模型的屏幕截图吗?上传了带有平面填充面的新渲染模型。你使用的是glOrtho,这使得区分(查看)哪些三角形近/远有点困难。如果生成网格时遇到问题,则必须按特定顺序生成三角形。看见
static void Reshape(int w, int h)
{
float diameter = sqrt(3);
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLdouble zNear = 1;
GLdouble zFar = zNear + diameter * 2;
GLdouble left = -diameter;
GLdouble right = diameter;
GLdouble top = -diameter;
GLdouble bottom = diameter;
double aspect = (double)w / (double)h;
if (aspect < 1)
{
bottom /= aspect;
top /= aspect;
}
else
{
left *= aspect;
right *= aspect;
}
glOrtho(left, right, bottom, top, zNear, zFar);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
static void PolarView(GLdouble twist, GLdouble elevation)
{
float diameter = sqrt(3);
double distance = diameter * 2;
double centerx, centery, centerz;
double eyex, eyey, eyez;
eyex = distance * cos(twist) * cos(elevation);
eyey = distance * sin(twist) * cos(elevation);
eyez = distance * sin(elevation);
centerx = centery = centerz = 0;
gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, 0, 0, 1);
}