2009-08-21 273 views
2

我有一个纹理,有一些透明透明的部分我想应用于其面部是一些不透明材质的对象(或颜色,如果更简单),但最终的对象变得透明。我希望最终的对象是完全不透明的。渲染透明纹理

这里是我的代码:

首先,我设置的材料:

glDisable(GL_COLOR_MATERIAL); 
    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT); 
    glColor4f(0.00, 0.00, 0.00, 1.00); 
    glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); 
    glColor4f(0.80, 0.80, 0.80, 1.00); 
    glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); 
    glColor4f(0.01, 0.01, 0.01, 1.00); 
    glEnable(GL_COLOR_MATERIAL); 

然后,我设置了维也纳组织

glBindTexture(GL_TEXTURE_2D, object->texture); 
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 

    glBindBuffer(GL_ARRAY_BUFFER, object->object); 
    glVertexPointer(3, GL_FLOAT, sizeof(Vertex), ver_offset); 
    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), tex_offset); 
    glNormalPointer(GL_FLOAT, sizeof(Vertex), nor_offset); 

最后我拉拢的对象

glEnable(GL_BLEND); 
    glDisable(GL_DEPTH_TEST); 

    glDisable(GL_TEXTURE_2D); 
    glBlendFunc(GL_ONE, GL_ZERO); 
    glDrawArrays(GL_TRIANGLES, 0, object->num_faces); 

    glEnable(GL_TEXTURE_2D); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    glDrawArrays(GL_TRIANGLES, 0, object->num_faces); 

    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

    glDisable(GL_BLEND); 
    glEnable(GL_DEPTH_TEST); 

我尝试传递不同以glBlendFunc()的参数为准。我已上载这里来源:http://dpaste.com/83559/

UPDATE得到this,但我想this(或没有纹理this)。

第二张和第三张照片是用glm生产的。我研究过这些资料,但由于我对OpenGL的了解有限,所以我不太了解。

+0

你想达到什么目的?有一些实心像素的透明物体?或者是一些带有透明纹理的固体物体,显示下方的纯色? – 2009-08-21 13:48:33

+0

后者:一个具有透明纹理的固体对象,显示下方的纯色? – Alexandru 2009-08-21 15:12:02

+0

感谢您的更新......并且按照我的建议,确定了您的Z-Buffering。 – Goz 2009-08-22 06:22:21

回答

3

如果你想要将两个纹理应用到你的对象,你真的想设置两个纹理,并使用multitexturing来实现这个样子。你的方法正在绘制几何图形,这是一个巨大的性能浪费。

多重纹理将仅从两个纹理单元进行采样,而仅绘制一次几何图形。您可以使用着色器(事情应该完成的方式)或者仍然可以使用固定功能流水线(请​​参阅:http://bluevoid.com/opengl/sig00/advanced00/notes/node62.html

+0

我不同意应该使用着色器完成所有的事情。但是你已经打败了我19秒;-) – hirschhornsalz 2009-08-21 13:58:18

+0

OpenGL 3.X已经完全淘汰FFP的部分,着色器是未来。 – 2009-08-21 14:01:12

+0

我不想纹理。我需要一种材质和一种纹理(如灰色金属(材质)上的绘画(纹理))。我同意两次绘制几何图形是浪费时间,并且可能出现问题,所以我正在寻找替代方案。 – Alexandru 2009-08-21 15:11:04

-1

像素着色器会更简单。否则我认为你需要多遍渲染或多个纹理。 你可以在这里找到全面的细节:http://www.opengl.org/resources/faq/technical/transparency.htm

+0

Pixelshaders比多纹理更简单?当然是 – hirschhornsalz 2009-08-21 13:55:05

+0

!它取决于你的目标平台和引擎,但是如果你想获得像玻璃一样的下降透明度效果或者裁剪出来,使用简单的像素着色器要比使用固定功能管线更容易 – 2009-08-21 13:57:46

1

AFAIK混合功能采用片段颜色(与纹理颜色相反)。因此,如果您再次使用混合绘制对象,则三角形变得透明。

你想要完成的工作可以使用多纹理完成。

0

这只是一个疯狂的猜测,因为你没有提供任何实际问题的截图,但为什么你禁用深度测试?当然你想用标准的GL_LESS对第一遍进行深度测试,然后用GL_EQUAL进行第二次传递?

编辑:

glEnable(GL_BLEND); 
glEnable(GL_DEPTH_TEST); // ie do not disable 
glDepthFunc(GL_LESS); // only pass polys have a z value less than ones already in the z-buffer (ie are in front of any previous pixels) 

glDisable(GL_TEXTURE_2D); 
glBlendFunc(GL_ONE, GL_ZERO); 
glDrawArrays(GL_TRIANGLES, 0, object->num_faces); 

// for the second pass we only want to blend pixels where they occupy the same position 
// as in the previous pass. Therefore set to equal and only pixels that match the 
// previous pass will be blended together. 
glDepthFunc(GL_EQUAL); 

glEnable(GL_TEXTURE_2D); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
glDrawArrays(GL_TRIANGLES, 0, object->num_faces); 

glDisableClientState(GL_VERTEX_ARRAY); 
glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

glDisable(GL_BLEND); 
0

尝试禁用混合和绘图设置为GL_DECAL,而不是你的GL_MODULATE质地功能的单通。这将根据纹理的alpha通道在顶点颜色和纹理颜色之间进行混合,但将Alpha通道设置为顶点颜色。

请注意,这将忽略在纹理不透明的任何位置应用于顶点颜色的任何照明,但根据您的描述,这听起来像预期的效果。