0

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

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

为了绘制背景,我使用一个具有 OpenGL 窗口大小的正方形,然后在这个正方形中应用 png 图像作为纹理。

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

我玩阿尔法通道,但我什么也没看到。

代码:

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

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

4

1 回答 1

9

发现了一些东西:

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

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

使用 z 剔除进行 2D 绘图的一个好的做法是先绘制关闭层,然后再将层绘制得更远。这样可以确保您编写的片段更少。

例如 :

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

但是,透明物体需要特殊的规则。

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

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

请注意,前两个函数为您提供的选项比您想象的要多

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

如果您想在最后一遍中绘制所有透明对象,例如,您可以启用深度测试,这样对象就不会绘制在您的叠加层之上,但是您禁用深度写入,因为您希望能够在其中绘制多个重叠对象层。

发挥您的创造力并学会爱上深度缓冲区:D

于 2012-10-20T19:56:50.663 回答