OpenGL中RGB与BGRA原始图像混合问题排查:代码未实现混合
Fixing OpenGL Blend Issue Between RGB Background and BGRA Foreground
Hey there! I see you're getting started with OpenGL and running into trouble blending an RGB background texture with a BGRA foreground OSD. Let's break down the issues in your code and fix them step by step.
Key Problems in Your Current Code
- You're only drawing one quad, using the last bound texture: You create two textures but only render a single quad. Since you bound
texture[1](the OSD) last, OpenGL uses that for the quad—so the background texture never gets drawn at all, hence no blending. - Missing proper draw order for blending: To blend foreground over background, you need to draw the background first, then draw the foreground on top with blending enabled.
- Minor note on buffer mode: Using
GLUT_SINGLE(single buffering) can cause flickering; switching to double buffering is more reliable for interactive apps.
Fixed Code with Explanations
Here's the updated display function with fixes marked:
void display() { GLuint texture[2]; int width = 960; int height = 540; unsigned char *osd_raw = loadFile("./osd.raw"); unsigned char *video_raw = loadFile("./video.raw"); glClearColor(0.1, 0.1, 0.1, 0.0); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glGenTextures(2, texture); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // --- Draw Background (RGB Video Texture) --- glBindTexture(GL_TEXTURE_2D, texture[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, video_raw); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Render background quad glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3f(-1, -1, 0); glTexCoord2f(0, 1); glVertex3f(-1, 1, 0); glTexCoord2f(1, 1); glVertex3f(1, 1, 0); glTexCoord2f(1, 0); glVertex3f(1, -1, 0); glEnd(); // --- Draw Foreground (BGRA OSD Texture) --- glBindTexture(GL_TEXTURE_2D, texture[1]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, osd_raw); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Render foreground quad (blending is already enabled) glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3f(-1, -1, 0); glTexCoord2f(0, 1); glVertex3f(-1, 1, 0); glTexCoord2f(1, 1); glVertex3f(1, 1, 0); glTexCoord2f(1, 0); glVertex3f(1, -1, 0); glEnd(); // Cleanup: Delete textures to avoid memory leaks (important for repeated calls!) glDeleteTextures(2, texture); // Free your loaded image data too, assuming loadFile uses malloc free(osd_raw); free(video_raw); // Switch to double buffering for smoother rendering glutSwapBuffers(); // glFlush(); // Replace with glutSwapBuffers when using GLUT_DOUBLE } int main(int argc, char** argv) { glutInit(&argc, argv); // Change to GLUT_DOUBLE for double buffering glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitWindowSize(960, 540); glutInitWindowPosition(0, 0); glutCreateWindow("glut test"); glutDisplayFunc(display); glutMainLoop(); return 0; }
Additional Checks to Ensure Blending Works
- Verify OSD alpha channel: Make sure your
osd.rawBGRA data has non-255 alpha values where you want transparency. If all alpha values are 255 (fully opaque), the OSD will cover the background completely, and you won't see blending. - Confirm
loadFileworks correctly: Ensure yourloadFilefunction is reading the full image data (width * height * channels bytes) without corruption. For RGB, that's 9605403 bytes; for BGRA, that's 9605404 bytes. - Texture internal format consistency: For the BGRA texture, you can use
GL_BGRAas the internal format instead ofGL_RGBAfor better performance (matches the input format), butGL_RGBAwill still work as OpenGL will convert it.
内容的提问来源于stack exchange,提问作者Rajesh Gopu
相关产品推荐
相关产品推荐

