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

然后我设置了 VBO

   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/

更新得到 了这个,但我想要 这个(或者没有纹理这个)。

第二张和第三张图片是用glm制作的。我研究了资源,但由于我对 OpenGL 的了解有限,所以我不太了解。

4

5 回答 5

3

如果您尝试将两个纹理应用到您的对象,您真的想设置两个纹理并使用多重纹理来实现这种外观。您的方法是两次绘制几何图形,这是对性能的巨大浪费。

多重纹理将仅从两个纹理单元中采样,而仅绘制一次几何图形。您可以使用着色器(真正应该做的事情)来做到这一点,或者您仍然可以使用固定功能管道(参见:http ://bluevoid.com/opengl/sig00/advanced00/notes/node62.html )

于 2009-08-21T13:52:22.630 回答
1

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

您想要完成的事情可以使用multitexturing来完成。

于 2009-08-21T13:52:41.193 回答
0

这只是一个疯狂的猜测,因为您没有提供任何实际问题的屏幕截图,但您为什么禁用深度测试?您肯定想在第一次通过标准 GL_LESS 时启用深度测试,然后使用 GL_EQUAL 进行第二次通过吗?

编辑:

IE

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); 
于 2009-08-21T13:53:07.980 回答
0

尝试禁用混合和绘制单通道,并将纹理函数设置为GL_DECAL而不是GL_MODULATE. 这将基于纹理的 Alpha 通道在顶点颜色和纹理颜色之间混合,但将 Alpha 通道设置为顶点颜色。

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

于 2009-08-23T17:35:53.153 回答
-1

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

于 2009-08-21T13:47:30.530 回答