OpenGL混合问题
我想画一个站在桌子上的水族馆(容器)。 水族箱的墙壁需要融合。
但是,如果我先画桌子,然后画水族馆,我会得到:
- 从桌子上方看:好的
- 从桌子底部看:错误,我仍然看到水族馆
如果我先画 aquariun,然后画桌子,我得到:
- 从桌子上方看:错误,水族箱墙壁对桌子没有影响(但它们会影响背景)
- 从表格底部看:错误,我仍然看到水族馆
有图片解释它:
http://img213.imageshack.us/img213/6609/pictureem.jpg
代码: 主程序
int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
Cam.SetPrespective();
//----------------
GLfloat LightPosition0[]= { 0.0, 0.0, 0.2, 1.0f };
GLfloat LightAmbient0[]= { 0, 0, 0, 1.0f };
GLfloat LightDiffuse0[]= { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat LightSpecular0[]= { 1.0f, 1.0f, 1.0f, 1.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient0); // Setup The Ambient Light
glLightfv(GL_LIGHT0, GL_POSITION,LightPosition0); // Position The Light
glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse0); // Setup The Diffuse Light
glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpecular0); // Setup The Diffuse Light
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
//----------------
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
glLightfv(GL_LIGHT2, GL_POSITION,LightPosition); // Position The Light
glLightfv(GL_LIGHT2, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
drawContainer(); //container drawn first in this example
//.. draw other things
drawTable();
drawGround();
/*
//.. draw other things
drawTable();
drawGround();
drawContainer(); //container drawn last in this example
*/
CheckKeys();
if(mouse)
{
CheckMouse();
}
return TRUE;
}
void drawTable()
{
glColor3f(1.0f, 0.5f, 1.0f);
GLfloat cx = MIN_X+(MAX_X-MIN_X)/2.0f;
GLfloat cy = MIN_Y-0.1f;
GLfloat cz = MIN_Z+(MAX_Z-MIN_Z)/2.0f;
GLfloat cr = sqrt((MAX_X-MIN_X)*(MAX_X-MIN_X)+(MAX_Z-MIN_Z)*(MAX_Z-MIN_Z))*0.85f;
int th = 5.0f; //centerPieceThickness
drawCylinder(cx,cy,cz,th,cr);
glColor3f(0.7f, 0.5f, 0.5f);
drawCylinder(MAX_X+cr*0.155f, cy-th, MAX_Z+cr*0.155f, 25*th, cr*0.035f);
drawCylinder(MAX_X+cr*0.155f, cy-th, MIN_Z-cr*0.155f, 25*th, cr*0.035f);
drawCylinder(MIN_X-cr*0.155f, cy-th, MIN_Z-cr*0.155f, 25*th, cr*0.035f);
drawCylinder(MIN_X-cr*0.155f, cy-th, MAX_Z+cr*0.155f, 25*th, cr*0.035f);
}
void drawGround()
{
int th = 5.0f;
GLfloat cx = MIN_X+(MAX_X-MIN_X)/2.0f;
GLfloat cy = MIN_Y-0.1f;
GLfloat cz = MIN_Z+(MAX_Z-MIN_Z)/2.0f;
GLfloat cr = sqrt((MAX_X-MIN_X)*(MAX_X-MIN_X)+(MAX_Z-MIN_Z)*(MAX_Z-MIN_Z))*8.5f;
glColor3f(0.0f, 0.6f, 0.0f);
drawCylinder(cx,cy-26*th,cz,10.f,cr);
}
void drawContainer()
{
glColor3f(0.2f, 0.2f, 0.2f);
drawCuboid(MIN_X-0.5, MAX_X+0.5f, MIN_Y-0.5, MIN_Y+0.5, MIN_Z-0.5f, MIN_Z+0.5f);
drawCuboid(MIN_X-0.5, MAX_X+0.5f, MIN_Y-0.5, MIN_Y+0.5, MAX_Z-0.5f, MAX_Z+0.5f);
drawCuboid(MIN_X-0.5, MAX_X+0.5f, MAX_Y-0.5, MAX_Y+0.5, MIN_Z-0.5f, MIN_Z+0.5f);
drawCuboid(MIN_X-0.5, MAX_X+0.5f, MAX_Y-0.5, MAX_Y+0.5, MAX_Z-0.5f, MAX_Z+0.5f);
drawCuboid(MIN_X-0.5, MIN_X+0.5f, MIN_Y-0.5, MAX_Y+0.5, MIN_Z-0.5f, MIN_Z+0.5f);
drawCuboid(MIN_X-0.5, MIN_X+0.5f, MIN_Y-0.5, MAX_Y+0.5, MAX_Z-0.5f, MAX_Z+0.5f);
drawCuboid(MAX_X-0.5, MAX_X+0.5f, MIN_Y-0.5, MAX_Y+0.5, MIN_Z-0.5f, MIN_Z+0.5f);
drawCuboid(MAX_X-0.5, MAX_X+0.5f, MIN_Y-0.5, MAX_Y+0.5, MAX_Z-0.5f, MAX_Z+0.5f);
drawCuboid(MIN_X-0.5, MIN_X+0.5f, MIN_Y-0.5, MIN_Y+0.5, MIN_Z-0.5f, MAX_Z+0.5f);
drawCuboid(MIN_X-0.5, MIN_X+0.5f, MAX_Y-0.5, MAX_Y+0.5, MIN_Z-0.5f, MAX_Z+0.5f);
drawCuboid(MAX_X-0.5, MAX_X+0.5f, MIN_Y-0.5, MIN_Y+0.5, MIN_Z-0.5f, MAX_Z+0.5f);
drawCuboid(MAX_X-0.5, MAX_X+0.5f, MAX_Y-0.5, MAX_Y+0.5, MIN_Z-0.5f, MAX_Z+0.5f);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glColor4f(0.5f,1.0f,1.0f,0.12f);
drawCuboid(MIN_X,MAX_X,MIN_Y,MAX_Y,MIN_Z,MAX_Z);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
}
I want to draw aquarium (container) standing on table.
Walls of aquarium need to be blended.
But, if I draw table first and then aquarium I get:
- looking from the up of the table: ok
- looking from the bottom of the table: wrong, I still see aquarium
If I draw aquariun first and then table I get:
- looking from the up of the table: wrong, aquarium walls have no effect on the table (they affect the backgrounf, though)
- looking from the bottom of the table: wrong, I still see aquarium
There is picture that explains it:
http://img213.imageshack.us/img213/6609/pictureem.jpg
Code:
main.cpp
int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
Cam.SetPrespective();
//----------------
GLfloat LightPosition0[]= { 0.0, 0.0, 0.2, 1.0f };
GLfloat LightAmbient0[]= { 0, 0, 0, 1.0f };
GLfloat LightDiffuse0[]= { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat LightSpecular0[]= { 1.0f, 1.0f, 1.0f, 1.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient0); // Setup The Ambient Light
glLightfv(GL_LIGHT0, GL_POSITION,LightPosition0); // Position The Light
glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse0); // Setup The Diffuse Light
glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpecular0); // Setup The Diffuse Light
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
//----------------
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
glLightfv(GL_LIGHT2, GL_POSITION,LightPosition); // Position The Light
glLightfv(GL_LIGHT2, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
drawContainer(); //container drawn first in this example
//.. draw other things
drawTable();
drawGround();
/*
//.. draw other things
drawTable();
drawGround();
drawContainer(); //container drawn last in this example
*/
CheckKeys();
if(mouse)
{
CheckMouse();
}
return TRUE;
}
void drawTable()
{
glColor3f(1.0f, 0.5f, 1.0f);
GLfloat cx = MIN_X+(MAX_X-MIN_X)/2.0f;
GLfloat cy = MIN_Y-0.1f;
GLfloat cz = MIN_Z+(MAX_Z-MIN_Z)/2.0f;
GLfloat cr = sqrt((MAX_X-MIN_X)*(MAX_X-MIN_X)+(MAX_Z-MIN_Z)*(MAX_Z-MIN_Z))*0.85f;
int th = 5.0f; //centerPieceThickness
drawCylinder(cx,cy,cz,th,cr);
glColor3f(0.7f, 0.5f, 0.5f);
drawCylinder(MAX_X+cr*0.155f, cy-th, MAX_Z+cr*0.155f, 25*th, cr*0.035f);
drawCylinder(MAX_X+cr*0.155f, cy-th, MIN_Z-cr*0.155f, 25*th, cr*0.035f);
drawCylinder(MIN_X-cr*0.155f, cy-th, MIN_Z-cr*0.155f, 25*th, cr*0.035f);
drawCylinder(MIN_X-cr*0.155f, cy-th, MAX_Z+cr*0.155f, 25*th, cr*0.035f);
}
void drawGround()
{
int th = 5.0f;
GLfloat cx = MIN_X+(MAX_X-MIN_X)/2.0f;
GLfloat cy = MIN_Y-0.1f;
GLfloat cz = MIN_Z+(MAX_Z-MIN_Z)/2.0f;
GLfloat cr = sqrt((MAX_X-MIN_X)*(MAX_X-MIN_X)+(MAX_Z-MIN_Z)*(MAX_Z-MIN_Z))*8.5f;
glColor3f(0.0f, 0.6f, 0.0f);
drawCylinder(cx,cy-26*th,cz,10.f,cr);
}
void drawContainer()
{
glColor3f(0.2f, 0.2f, 0.2f);
drawCuboid(MIN_X-0.5, MAX_X+0.5f, MIN_Y-0.5, MIN_Y+0.5, MIN_Z-0.5f, MIN_Z+0.5f);
drawCuboid(MIN_X-0.5, MAX_X+0.5f, MIN_Y-0.5, MIN_Y+0.5, MAX_Z-0.5f, MAX_Z+0.5f);
drawCuboid(MIN_X-0.5, MAX_X+0.5f, MAX_Y-0.5, MAX_Y+0.5, MIN_Z-0.5f, MIN_Z+0.5f);
drawCuboid(MIN_X-0.5, MAX_X+0.5f, MAX_Y-0.5, MAX_Y+0.5, MAX_Z-0.5f, MAX_Z+0.5f);
drawCuboid(MIN_X-0.5, MIN_X+0.5f, MIN_Y-0.5, MAX_Y+0.5, MIN_Z-0.5f, MIN_Z+0.5f);
drawCuboid(MIN_X-0.5, MIN_X+0.5f, MIN_Y-0.5, MAX_Y+0.5, MAX_Z-0.5f, MAX_Z+0.5f);
drawCuboid(MAX_X-0.5, MAX_X+0.5f, MIN_Y-0.5, MAX_Y+0.5, MIN_Z-0.5f, MIN_Z+0.5f);
drawCuboid(MAX_X-0.5, MAX_X+0.5f, MIN_Y-0.5, MAX_Y+0.5, MAX_Z-0.5f, MAX_Z+0.5f);
drawCuboid(MIN_X-0.5, MIN_X+0.5f, MIN_Y-0.5, MIN_Y+0.5, MIN_Z-0.5f, MAX_Z+0.5f);
drawCuboid(MIN_X-0.5, MIN_X+0.5f, MAX_Y-0.5, MAX_Y+0.5, MIN_Z-0.5f, MAX_Z+0.5f);
drawCuboid(MAX_X-0.5, MAX_X+0.5f, MIN_Y-0.5, MIN_Y+0.5, MIN_Z-0.5f, MAX_Z+0.5f);
drawCuboid(MAX_X-0.5, MAX_X+0.5f, MAX_Y-0.5, MAX_Y+0.5, MIN_Z-0.5f, MAX_Z+0.5f);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glColor4f(0.5f,1.0f,1.0f,0.12f);
drawCuboid(MIN_X,MAX_X,MIN_Y,MAX_Y,MIN_Z,MAX_Z);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于不透明(不透明聚合物):
启用 GL_DEPTH_TEST,并渲染所有这些。
对于透明多边形:保留
GL_DEPTH_TEST
,但使用glDepthMask(GL_FALSE)
禁用深度写入,然后在渲染之前从后到前对透明多边形进行排序。另请参阅常见问题解答
For opaque (non-transparent polys):
Enable GL_DEPTH_TEST, and render all these.
For transparent polys: Keep
GL_DEPTH_TEST
but disable depth write withglDepthMask(GL_FALSE)
and then sort the transparent polygons from back to front before rendering.See also the FAQ
我怀疑问题是由drawContainer()中的glDisable(GL_DEPTH_TEST)引起的。我建议注释掉 GL_DEPTH_TEST 行——在这种情况下,水族馆相对于桌子和地板是否正确?
I suspect that the problem is caused by the glDisable(GL_DEPTH_TEST) in drawContainer(). I suggest commenting out the GL_DEPTH_TEST lines -- does the aquarium appear correct with respect to the table and floor in that case?