渲染透明纹理

时间:2009-08-21 13:42:39

标签: opengl textures alphablending

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

这是我的代码:

首先我设置材料:

   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);

然后我设置了VBOs

   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/

更新获取 this,但我想要 this(或没有纹理this)。

第二张和第三张照片是glm生成的。我研究了这些资源,但由于我对OpenGL的了解有限,我对此并不了解。

5 个答案:

答案 0 :(得分:3)

如果您尝试将两个纹理应用于对象,则确实需要设置两个纹理并使用多纹理来实现此外观。你的方法是将几何图形绘制两次,这是对性能的巨大浪费。

多纹理只会从两个纹理单元中采样,而只能绘制一次几何体。您可以使用着色器(事情应该完成的方式)执行此操作,或者您仍然可以使用固定功能管道(请参阅:http://bluevoid.com/opengl/sig00/advanced00/notes/node62.html

答案 1 :(得分:1)

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

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

答案 2 :(得分: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); 

答案 3 :(得分:0)

尝试禁用混合并绘制单个过程,并将纹理函数设置为GL_DECAL而不是GL_MODULATE。这将根据纹理的alpha通道在顶点颜色和纹理颜色之间进行混合,但将Alpha通道设置为顶点颜色。

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

答案 4 :(得分:-1)

使用像素着色器会更简单。否则我认为你需要多遍渲染或多个纹理。 您可以在此处找到详细信息:http://www.opengl.org/resources/faq/technical/transparency.htm