如何渲染 GL_ALPHA 纹理?

Posted

技术标签:

【中文标题】如何渲染 GL_ALPHA 纹理?【英文标题】:How do I render a GL_ALPHA texture? 【发布时间】:2011-12-15 23:00:31 【问题描述】:

我正在尝试使用 FTGL 字体库来创建纹理映射字体并将其渲染到屏幕上。该库以GL_ALPHA 格式创建一个纹理来保存字体字形,然后当您告诉它渲染一个字符串时,它会通过glBegin(GL_QUADS) 并渲染每个字形,这正是您所期望的。

唯一的问题是,我没有收到任何文本。在一种情况下,我得到纯黑框而不是文本,在另一种情况下,我什么也得不到。我已经在 gDEBugger 下运行了代码,以确保纹理被正确上传和设置,并且一切正常,但我仍然没有看到任何输出。

我已经尝试了明显的东西。事先调用glColor 尝试设置文本颜色没有任何作用。也没有尝试确保 alpha 混合能够正常工作,如下所示:

glEnable(GL_ALPHA_TEST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

有人知道我缺少什么,以便正确显示从GL_ALPHA 纹理到屏幕的渲染吗?

【问题讨论】:

"库创建 GL_ALPHA 格式的纹理来保存字体字形" 真的吗?它不允许您选择要使用的格式吗?如果没有,那很不幸,因为 GL 3.1 核心及更高版本不再具有 GL_ALPHA 纹理。 @Nicol:是的,真的,那又怎样?我不知道任何显卡的驱动程序只实现核心而忽略向后兼容性。这将是一个非常愚蠢的举动,制造商知道这一点。 MacOSX 10.7 没有实现兼容性。您可以选择 2.1 或 3.2 core。即使忽略它依赖于已删除内容的事实,它仍然应该为您提供一些关于您想要的格式的选项。因为它们使用 GL_ALPHA,所以您必须付出大量努力才能使其适用于纹理环境和颜色(见下文)。如果他们只是像大多数人所期望的那样使用 GL_INTENSITY,您可以只使用 GL_MODULATE 和 GL_ONEGL_ONE_MINUS_SRC_ALPHA 的混合模式。 【参考方案1】:

在检查了 FTGL 的代码后,很明显该 API 旨在完成文本呈现本身。您应该调用它的渲染函数,这将在内部进行 OpenGL 调用。

换句话说,FTGL 的设计目的不是将字体加载到纹理中,然后给您该纹理对象并让您自己绘制字形。这并不意味着您不能,API 不会帮助您做到这一点。

您变黑的原因是因为GL_ALPHA 纹理在访问时为 RGB 组件返回零。由于您在纹理环境中使用了GL_MODULATE,因此它将用颜色的 RGB 部分乘以零。

要按您的意愿行事,您需要将GL_TEXTURE_ENV_MODE 设置为GL_COMBINE 而不是GL_MODULATE。这意味着您需要使用combine environment mode,这并不简单。几乎一出现着色器就放弃了着色器的固定功能,我已经很长时间没有接触过组合器了。因此,请采取一粒盐。下面是对环境代码应该是什么样子的猜测:

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);

您要做的是生成一种颜色,其中 RGB 部分来自glColor,Alpha 部分来自纹理。你就是这样做的。

在英文中,第一行说纹理环境模式是“combine”,它激活了一个更复杂的操作模式。接下来的三行指定如何生成颜色的 RGB 部分。 GL_COMBINE_RGB 设置为 GL_REPLACE 意味着源 RGB 值 0 将是输出 RGB 的值。将GL_SRC0_RGB 设置为GL_PRIMARY_COLOR 意味着源RGB 值0 是原色,即顶点处理生成的颜色(即:除非您使用照明,否则这正是您使用glColor 传递的颜色)。将GL_OPERAND0_RGB 设置为GL_SRC_COLOR 意味着按原样获取颜色(您可以执行一些特殊操作,例如获取1 - the color 或其他)。

接下来的 3 行设置了输出颜色的 alpha 部分的来源。 GL_COMBINE_ALPHA 设置为 GL_REPLACE 意味着源 alpha 值 0(不同于源 RGB 值 0)将是输出 alpha。将GL_SRC0_ALPHA设置为GL_TEXTURE意味着源alpha值0来自当前纹理单元的纹理。将GL_OPERAND0_ALPHA 设置为GL_SRC_ALPHA 意味着按原样获取alpha(和以前一样,您可以在此处对alpha 应用一些变换)。

或者,如果您的 OpenGL 实现有 ARB_texture_swizzle 可用,您可以设置一个 swizzle 掩码以有效地将 GL_ALPHA 格式转换为 GL_INTENSITY。然后你可以使用GL_MODULATE 作为你的GL_TEXTURE_ENV_MODE。但是,您必须确保您的混合模式是glBlendMode(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)。这是必要的,因为GL_MODULATE 会将颜色乘以 alpha。如果您使用 GL_SRC_ALPHA 而不是 GL_ONE,您将执行乘以 alpha 两次(一次在纹理环境阶段,一次在混合阶段)。

【讨论】:

am 调用它的渲染函数并让它在内部进行 OpenGL 调用。它只是不太正确地渲染事物。我昨晚花了几个小时,今天早上在它的代码中闲逛(一次糟糕的经历,因为我绝不是 C++ 人!)只是试图正确设置纹理,因为我有一个边缘情况它没有不能正确处理。我确实计划将渲染移至基于着色器的代码,但首先我想确保它在固定功能中正常工作,因为该库是为固定功能设计的,这让我很理智检查。

以上是关于如何渲染 GL_ALPHA 纹理?的主要内容,如果未能解决你的问题,请参考以下文章

FreeType - 纹理图集 - 为什么我的文字渲染为四边形?

OpenGL中怎么使用压缩纹理?

如何渲染多个纹理?

渲染场景阴影纹理(纹理烘焙)

如何使用 WebGL 异步加载图像、创建纹理、渲染和保存图像?

如何在 Xcode 中渲染具有半透明纹理的 3D 模型?