【问题标题】:How to blend RGB & BGRA raw images by opengl?如何通过opengl混合RGB和BGRA原始图像?
【发布时间】:2018-05-29 09:04:41
【问题描述】:

我对 OpenGL 很陌生

尝试混合 RGB 和 BGRA 原始图像。

  • RGB 是背景图片
  • RGBA 是前景图像

以下来源仅获得输出“osd_raw”图像。混合没有发生。

在下面的代码中加载 2 个原始图像。 创建 2 个纹理并与之绑定。 使用 glBlendFunc 进行混合。 输出没有得到混合。

请告诉我哪里出错了。

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

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

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

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

    glFlush();
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);

    glutInitWindowSize(960, 540);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("glut test");

    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}

【问题讨论】:

    标签: opengl freeglut blending


    【解决方案1】:

    首先,请注意,使用glBegin/glEnd 序列绘图已被弃用超过 10 年。 阅读Fixed Function Pipeline 并查看Vertex Specification,了解最先进的渲染方式。


    如果要混合 2 个纹理,则必须绑定第一个纹理并使用正确的纹理坐标属性集绘制四边形。 之后,您必须绑定第二个纹理并再次绘制四边形,并启用混合(请参阅Blending):

    glDisable( GL_BLEND);
    
    glBindTexture(GL_TEXTURE_2D, texture[0]);
    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();
    
    glEnable( GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    glBindTexture(GL_TEXTURE_2D, texture[1]);
    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();
    

    进一步注意,Depth Test 必须被禁用或设置为例如GL_LEQUAL,绘制第二个四边形时。否则第二个四边形将被深度测试丢弃。

    既然混合函数是glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);,当然第二个纹理的一些alpha通道必须小于1.0。

    【讨论】:

      【解决方案2】:

      根据Rabbid76,修改后的&以下是供参考的工作源。

       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);
      
              glDisable(GL_BLEND);
      
              glBindTexture(GL_TEXTURE_2D, texture[0]);
              glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, 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);
      
              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();
      
              glEnable( GL_BLEND);
              glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      
              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);
      
              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();
      
              glFlush();
          }
      

      【讨论】:

        猜你喜欢
        • 2012-01-11
        • 2018-03-17
        • 2016-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-29
        相关资源
        最近更新 更多