2012-02-13 109 views
0

我想使用OpenGL移动并旋转透明的BGRA图像(文字覆盖图)。这里是代码片段我用:OpenGL:为什么复制纹理时alpha通道设置为255?

glViewport(0, 0, iWidth, iHeight); // Reset The Current Viewport 
glEnable(GL_TEXTURE_2D); 

glGenTextures(1, &arTex[0].iName); 
glBindTexture(GL_TEXTURE_2D, arTex[0].iName); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

glTexImage2D(GL_TEXTURE_2D, 0, 4, imf.iWidth, imf.iHeight, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, ib.GetData()); 

glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Note: Transparent alpha value 
glClear(GL_COLOR_BUFFER_BIT); 
glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 

glOrtho(-dAspectCanvas/2.0, dAspectCanvas/2.0, -0.5, 0.5, -1.0, 1.0); // Note: Using (-1.0; 1.0) for Z-planes 
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
glScaled(Motion.Scale.GetValue(dPosition), Motion.Scale.GetValue(dPosition), 1.0); 
glTranslated(Motion.OffsetX.GetValue(dPosition) * dAspectCanvas, Motion.OffsetY.GetValue(dPosition), 0.0); 
glRotated(Motion.Rotation.GetValue(dPosition), 0.0, 0.0, 1.0); 
glTranslated(Motion.PositionX.GetValue(dPosition) * dAspectCanvas, Motion.PositionY.GetValue(dPosition), 1.0); 

// Rotating and moving 

glBindTexture(GL_TEXTURE_2D, arTex[iTexIndex].iName); // has to be called outside glBegin/glEnd scope 

glBegin(GL_TRIANGLE_STRIP); // "Many OpenGL applications avoid quads altogether because of their inherent rasterization problems" 

glTexCoord2d(rcTextureIntersection.left, rcTextureIntersection.top); 
glVertex2d(rcVertexIntersection.left, rcVertexIntersection.top); 
glTexCoord2d(rcTextureIntersection.right, rcTextureIntersection.top); 
glVertex2d(rcVertexIntersection.right, rcVertexIntersection.top); 
glTexCoord2d(rcTextureIntersection.left, rcTextureIntersection.bottom); 
glVertex2d(rcVertexIntersection.left, rcVertexIntersection.bottom); 
glTexCoord2d(rcTextureIntersection.right, rcTextureIntersection.bottom); 
glVertex2d(rcVertexIntersection.right, rcVertexIntersection.bottom); 
glEnd(); 

glDisable(GL_TEXTURE_2D); 
glFlush(); 
glReadBuffer(GL_BACK); 
glReadPixels(0, 0, imf.iWidth, imf.iHeight, GL_BGRA_EXT, GL_UNSIGNED_BYTE, ibOut.GetData()); 

但无论我尝试在glTexImage2D,我透明的黑色图像变成一个完全不透明的黑色图像。输入BGRA图像包含字节:0,0,0,0,0 ....在旋转之后,输出图像包含0,0,0,255,0,0,0,255,0 .... A始终设置为255,我不明白为什么。

+0

“旋转后,输出图像包含0,0,0,0,0,0,0,0,0,05,0 ....”当您创建OpenGL上下文时,您是否要求帧缓存具有alpha在里面? – 2012-02-13 22:53:17

回答

0

阿尔法并不意味着“透明”。阿尔法本身并不意味着任何东西。只有当你使用这个值来做某件事时,它才会有意义。

如果要呈现对象并使用alpha控制对象的透明度,则需要激活混合和set up a proper blend mode

+0

我可以使用这些行开始混合: glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); – Kirill 2012-02-13 23:00:15

+0

@ user1207865:嗯,我希望你能阅读那个页面,并理解这些行实际上做了什么。 – 2012-02-13 23:01:32

0

您在这里面临两个问题。一个是,你没有启用混合,其效果是纹理的alpha值对透明度没有影响。

另一个问题 - 对你来说更重要的是 - 你的framebuffer(你正在绘制纹理的地方)可能没有alpha通道,因此会默认为最大值。您不需要启用混合来使纹理影响帧缓冲区alpha值(它只会替换它)。但是你需要一个带alpha通道的帧缓冲来完成这项工作。请注意,在屏幕上的帧缓冲区获取alpha缓冲区是可能的(我甚至推荐它)。但是对于图像处理来说,帧缓冲仅仅是错误的地方。您需要一个安全的环境:A Framebuffer Object

0

没有必要混合任何东西,但帧缓冲区需要使用阿尔法位设置。这是一个问题,我完全忘了wglCreateContext。

感谢您的帮助!

0

可能使用正确的alpha颜色设置glClearColor。