Reputation: 25840
I have one texture that has some portions which are transparent transparent I want to apply over an object whose faces are some opaque material (or colour if it's simpler) but the final object gets transparent. I want the final object to be totally opaque.
Here is my code:
First I set the material:
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);
Then I setup the 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);
And finally I draw the object
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);
I tried passing different arguments to glBlendFunc() with no prevail. I've uploaded the source here: http://dpaste.com/83559/
UPDATE I get this, but I want this (or without texture this).
The 2nd and the 3rd picture are produces with glm. I studied the sources, but since my knowledge of OpenGL is limited I didn't understand much.
Upvotes: 2
Views: 2504
Reputation: 3446
Try disabling blending and drawing a single pass with your texture function set to GL_DECAL
instead of GL_MODULATE
. This will blend between the vertex color and the texture color based on the texture’s alpha channel, but leave the alpha channel set to the vertex color.
Note that this will ignore any lighting applied to the vertex color anywhere the texture was opaque, but this sounds like the intended effect, based on your description.
Upvotes: 0
Reputation: 62333
This is just a wild guess, as you have failed to provide any screenshots of what the actual problem is, but why do you disable the depth test? Surely you want to enable depth testing on the first pass with a standard GL_LESS and then do the second pass with GL_EQUAL?
Edit:
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);
Upvotes: 0
Reputation: 29735
It will be much simpler with pixel shaders. otherwise I think you need multi-passes rendering or more than one texture. You can find comprehensive details here :http://www.opengl.org/resources/faq/technical/transparency.htm
Upvotes: -1
Reputation: 30449
AFAIK the blend function takes fragment colors (opposed to texture colors). So if you draw the object a second time with blending, the triangles become transparent.
What you want to accomplish could be done using multitexturing.
Upvotes: 1
Reputation: 10074
If you're trying to apply two textures to your object you really want to set two textures and use multitexturing to achieve this look. Your method is drawing the geometry twice which is a huge waste of performance.
Multitexturing will just sample from two texture units while only drawing the geometry once. You can do this with shaders (the way things really should be done) or you can still used the fixed function pipeline (see: http://bluevoid.com/opengl/sig00/advanced00/notes/node62.html)
Upvotes: 3