2010-09-22 89 views
5

我想画水族馆(容器)站在桌子上。 水族馆的墙壁需要混合。OpenGL混合问题

但是,如果我先画表格,然后水族馆我得到:
- 从上表看:OK
- 从表的底部看:错了,我仍然看到水族馆

如果我先绘制aquariun然后桌子,我会得到:
- 从桌子上看:错误的,水族馆墙壁对桌子没有影响(它们影响backgrounf,虽然)
- 从桌子底部看:错,我还是看水族馆

有画面,解释它:

http://img213.imageshack.us/img213/6609/pictureem.jpg

代码: 的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); 


} 
+0

缩进您的代码更好。 – karlphillip 2010-09-22 20:32:09

+0

好的。我已经做到了。 – Ichibann 2010-09-22 20:35:02

回答

4

我怀疑问题是由glDisable(GL_DEPTH_TEST)在drawContainer(引起的)。我建议评论GL_DEPTH_TEST这几行 - 在这种情况下,水族箱在桌子和地板上看起来是否正确?

+0

是的,那有效:)。但只有当水族馆最后被吸引。我怀疑这可能是解决方案,但当时水族馆被首先吸引... – Ichibann 2010-09-22 21:23:12

+0

你仍然需要排序透明多晶。请参阅下面的答案。 – Justicle 2010-09-22 21:32:55

+0

我不知道我为什么要这样做。现在看起来我想从水族箱的任何一侧看。 – Ichibann 2010-09-22 21:58:41

5

对于不透明(不透明的多边形): 启用GL_DEPTH_TEST并渲染所有这些。

对于透明多边形:保留GL_DEPTH_TEST但禁用深度写入glDepthMask(GL_FALSE),然后在渲染之前从后向前排列透明多边形。

另请参阅FAQ