I am currently designing a game engine, and I have come across a problem in my images in that the alpha value in the images is not being rendered. I am currently using an OpenGL system where each texture object has buffers for vertex, colour and texture coordinates, which are bound and drawn together in the drawRect: method. Although alpha will blend the overall image, I want the colour used to blend into the texture, as it is currently acting as a 'backing' for the texture, becoming visible in the areas of the texture that have alpha. When the colour isn't used when drawing, any alpha areas just appear white.
Here is the image with alpha that I wan't to render (as a test), and this is how it appears:
Here is my code:
Part of my texture object class:
if (width2 == 2 && height2 == 2) {
// Allocate the texture. Apples storage method curre开发者_JS百科ntly does not work for GL_TEXTURE_2D. REVISIT CODE TO INTEGRATE IT!
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &myTextureName);
glBindTexture(GL_TEXTURE_2D, myTextureName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, myData);
//glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT ,GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB,myTextureName, 0);
type = Normal_Texture;
CDMeshVertexesCreateRectangle(1, 1, texture);
}
else {
// The extension GL_TEXTURE_RECTANGLE_ARB can be used for non-power of two textures, but it is slower than GL_TEXTURE_2D and
// not supported by all graphics cards.
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glGenTextures(1, &myTextureName);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, myTextureName);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, myData);
//glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT ,GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB,myTextureName, 0);
type = Rectangular_Texture;
CDMeshVertexesCreateRectangle(width, height, texture);
}
The code run for rendering inside the object:
glEnableClientState(GL_VERTEX_ARRAY); // Activate vertex coordinates array
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexPointer(vertexStride, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glColorPointer(colorStride, GL_FLOAT, 0, 0);
// Enable client states for drawing the various arrays
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(texType);
// Bind buffer and use the VBO's to draw
glBindBuffer(GL_ARRAY_BUFFER, texBuffer);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
glBindTexture(texType, texID);
//render
glDrawArrays(renderStyle, 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY); // Deactivate vertex coordinates array
glDisableClientState(GL_COLOR_ARRAY);
// Disale client states as were done with them.
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(texType);
Additional settings used for rendering:
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glShadeModel(GL_FLAT);
Any suggestions on how it can be done?
UPDATE 2 I have edited the gltexEnv() function to use GL_MODULATE instead of GL_BLEND. This has no affect on the problem I am having, although i am going to continue using GL_MODULATE for alpha blending.
UPDATE 3 To explain what i exactly need, I want to mainly be able to display images with the colour pointer provided blending the texture, rather than this colour being filled behind the texture, like it currently is. The texture data is being set correctly, and I have gone through many steps to narrow the problem down. Here is an example image of the problem:
I'm will need to do that too for my app, once I get there :/.
I can't test this right now, but I know that your blend function is the key - right now you are directly blending the texture onto the surface with alpha. Try changing your blend function. I've used these in the past: glBlendFunc (GL_ONE, GL_ONE); or glBlendFunc (GL_SRC_ALPHA, GL_ONE);
There is a wiki entry for texture combiners: http://www.opengl.org/wiki/Texture_Combiners
I kept looking through examples and other peoples problems on the Stack Overflow website, and bumped into this example: Link
Using the following code from this example, before drawing the texture blended the colour pointer with the texture:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
This is now the result:
精彩评论