2012-10-20 46 views
0

我的问题是在背景图像上方或上方绘制多边形或其他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(); 
} 

怎样绘制一幅图像在背景图像???

回答

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剔除
  • glDepthMask(GL_TRUE/GL_FALSE):启用或禁用写入深度缓冲器
  • glDepthFunc可以用来定义片段如何丢弃)

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

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

如果你想画的所有的透明物体在最后一关可以例如启用深度测试,因此对象不会在上面你对你的覆盖面上绘制,但您禁用深度写入,因为你希望能够在该图层中绘制多个重叠对象。

使用你的创造力和学习爱深度缓冲:D

+0

感谢您的这个伟大的解释。 –

+0

您还可以利用模板缓冲区进行额外的遮罩。 DEPTH24_STENCIL8深度缓冲区格式可用于此目的。 – Grimmy