【问题标题】:Drawing the alpha channel correctly in OpenGl在 OpenGL 中正确绘制 alpha 通道
【发布时间】:2010-06-23 21:19:15
【问题描述】:

加载图像后,我将每个通道的各个字节加载到一个无符号字符数组中。它被传递给一个函数,该函数将其作为纹理投影到四边形上。除了显示为背景颜色的 alpha 通道之外,一切似乎都正常工作。我正在使用 OpenGL 来绘制图像。我会从添加分层机制中受益吗?还有,怎样才能达到我想要的透明效果呢?

注意:这是我感觉需要更改的代码:

void SetUpView()
{
    // Set color and depth clear value
    glClearDepth(1.f);
    glClearColor(1.f, 0.f, 0.f, 0.f);

    // Enable Z-buffer read and write
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);
    glDepthMask(GL_TRUE);

    glEnable (GL_BLEND); 
    glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

    // Setup a perspective projection
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(90.f, 1.f, 1.f, 500.f);
};

另外,这里是渲染四边形的代码。

void DrawTexturedRect(RectBounds *Verts, Image *Texture)
{
    glBindTexture(GL_TEXTURE_2D, GetTextureID(Texture));

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glPixelZoom(1, -1);

    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(Verts->corners[0].x, Verts->corners[0].y, Verts->corners[0].z);

    glTexCoord2f(1.0, 1.0);
    glVertex3f(Verts->corners[1].x, Verts->corners[1].y, Verts->corners[1].z);

    glTexCoord2f(1.0, 0.0);
    glVertex3f(Verts->corners[2].x, Verts->corners[2].y, Verts->corners[2].z);

    glTexCoord2f(0.0, 0.0);
    glVertex3f(Verts->corners[3].x, Verts->corners[3].y, Verts->corners[3].z);
    glEnd();
};

Image 类包含一个使用 OpenIL 获得的无符号字符数组。

相关代码:

loaded = ilLoadImage(filename.c_str());
ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);

unsigned char *bytes = ilGetData();

//NewImage is an instance of an Image. This is returned and passed to the above function.
NewImage->data = bytes;

【问题讨论】:

  • 数据不足。您没有显示纹理加载例程,也没有显示实际的渲染例程。
  • 好的,我试着清除渲染循环中发生的事情。
  • 另外,你如何设置 OpenGL?您确定您完全请求 alpha 通道(例如,如果使用 glut,则为像素格式,如果使用 glut,则为 GLUT_RGBA)?
  • 我不确定这是否是您所说的,但在首次加载纹理时会发生这种情况。 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Texture->GetWidth(), Texture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, Texture->data);

标签: c++ opengl alpha


【解决方案1】:

在绘制任何透明之前,您应该调用:

glDepthMask(false);

然后:

glDepthMask(true);

另外,所有透明对象必须在所有不透明对象之后绘制。

【讨论】:

    【解决方案2】:

    glClearColor(1.f, 0.f, 0.f, 0.f);

    我假设这是 RGBA 默认值,而您将红色设置为 1.0。

    如何更好地解释您要完成的工作?

    【讨论】:

    • 看到光标周围的红色框了吗?在 Paint.Net 中,什么都没有。它应该是 alpha 通道。
    【解决方案3】:

    试试:

    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    

    编辑:我知道那是什么样子的。看起来您正在绘制光标后的蓝色方块(其 Z 顺序位置位于光标后面)。 Alpha 混合时,您必须以正确的从后到前的 Z 顺序绘制事物,否则您会看到像您看到的错误。

    【讨论】:

    • 谢谢,但我仍然得到相同的效果。应该调用一次,还是每帧调用一次?
    猜你喜欢
    • 2014-01-18
    • 2011-02-06
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    相关资源
    最近更新 更多