在背景图像上绘制多边形

时间:2012-10-20 19:07:47

标签: opengl draw layer

我的问题是在背景图像上方或上方绘制多边形或其他一些OpenGL基元。总结不同层中的油漆,但在OpenGL中,我认为没有层。

现在我正在尝试在背景图像上绘制一个三角形和一条线。

要绘制背景,我使用带有OpenGL窗口大小的正方形,然后将png图像应用于此正方形作为纹理。

之后我尝试用不同的颜色绘制三角形和线条,但除了背景图像之外我什么都看不到。

我使用alpha通道但我什么都没看到。

代码:

void init() 
{
    // glClearColor(0.0, 0.0, 0.0, 0.0);
    glEnable(GL_DEPTH_TEST);

    // The following two lines enable semi transparent
    glEnable(GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    int width, height;
    bool hasAlpha;
    char filename[] = "prueba-luz.png";
    bool success = loadPngImage(filename, width, height, hasAlpha, &textureImage);

    if (!success) 
    {
        cout << "Unable to load png file" << endl;
        return;
    }

    cout << "Image loaded " << width << " " << height << " alpha " << hasAlpha << endl;

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    glTexImage2D(GL_TEXTURE_2D, 0, hasAlpha ? 4 : 3, width,
                height, 0, hasAlpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE,
                textureImage);

    // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}

void display(void) 
{
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Igual que GL_REPLACE pero se le puede aplicar transparencias a la textura
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glPushMatrix();

    glColor4f(1, 1, 1, 1);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBegin(GL_QUADS);
        glTexCoord2i(0,0); glVertex2i(10, -10);
        glTexCoord2i(1,0); glVertex2i(-10, -10);
        glTexCoord2i(1,1); glVertex2i(-10, 10);
        glTexCoord2i(0,1); glVertex2i(10, 10);
    glEnd();

    glPopMatrix();

    glDisable(GL_TEXTURE_2D);

    glBegin(GL_POLYGON);
        glColor4f(1.0, 1.0, 1.0, 0.8);
        glVertex3f(-1.0f, -3.0f, 0.0f);    // A
        glVertex3f( 1.0f, -3.5f, 0.0f);    // B
        glVertex3f( 0.0f,  0.5f, 0.0f);    // C
    glEnd();

    glBegin(GL_LINES);
        glColor4f( 1.0, 0.0, 0.0, 0.8 );
        glVertex2f(-8.0,  6.0);
        glVertex2f (5.0, -3.0);
    glEnd();

    glutSwapBuffers();
}

如何在背景图像上绘制一幅图像?

1 个答案:

答案 0 :(得分:9)

发现了一些事情:

  • 尝试禁用深度测试。您正在绘制Z = 0处的所有内容,并且您的应用程序肯定正在写入深度缓冲区。我不确定为什么你在这里启用深度测试,因为你绘制的所有内容都是在Z = 0。
  • 默认情况下,在启用深度测试时,将丢弃写入相同或更高Z值的所有片段。可以使用glDepthFunc更改此值(默认值GL_LESS)。这可能是您在此示例中丢弃几何体的原因。
  • 绘制2D几何图形并不意味着深度缓冲区不会受到影响。 OpenGL将使用Z = 0绘制此几何图形并将其写入深度缓冲区。

目前,除非您在不同的z位置绘制几何图形,否则您的应用程序没有理由使用深度测试。您可以在2D绘图中使用深度测试,通过为每个对象指定不同的z值来制作“图层”。

使用z-culling进行2D绘图的一个好习惯是首先绘制闭合图层,然后进一步绘制图层。这样可以确保编写更少的碎片。

例如:

  • Z = 0:绘制不透明的叠加层
  • Z = -1:绘制隐藏在叠加层后面的内容
  • Z = -2:绘制背景

但是,透明对象需要特殊规则。

您需要控制深度缓冲区。有选项:

  • glEnable/Disable(GL_DEPTH_TEST):启用或停用z-culling
  • glDepthMask(GL_TRUE/GL_FALSE):启用或禁用写入深度缓冲区
  • glDepthFunc可用于定义如何丢弃片段)

请注意,这两个第一个功能为您提供了比您想象的更多选项

  • 绘制对象时的深度剔除和深度写入
  • 深度剔除,但您的对象不会影响深度缓冲区
  • 没有深度剔除,但您的对象将写入深度缓冲区
  • 没有深度剔除,没有深度写入

如果你想在最后一次传递中绘制所有透明对象,你可以例如启用深度测试,这样就不会在你的叠加层上绘制对象,但你禁用了深度写入,因为你希望能够绘制几个重叠该层中的对象。

运用你的创造力,学会爱深度缓冲:D