Opengl:使用单通道纹理作为Alpha通道来显示文本

2023-11-23

我想做的是将纹理从单通道数据数组加载到硬件中,并使用它的 Alpha 通道将文本绘制到对象上。我正在使用opengl 4。

如果我尝试使用 4 通道 RGBA 纹理来执行此操作,它工作得非常好,但无论出于何种原因,当我尝试在单个通道中加载时,我只会得到一个乱码图像,而且我不明白为什么。 我通过将一系列字形的纹理位图数据与以下代码组合成单个纹理来创建纹理:

int texture_height = max_height * new_font->num_glyphs;
int texture_width = max_width;

new_texture->datasize = texture_width * texture_height;
unsigned char* full_texture = new unsigned char[new_texture->datasize];

// prefill texture as transparent
for (unsigned int j = 0; j < new_texture->datasize; j++)
    full_texture[j] = 0;

for (unsigned int i = 0; i < glyph_textures.size(); i++) {
    // set height offset for glyph
    new_font->glyphs[i].height_offset = max_height * i;
    for (unsigned int j = 0; j < new_font->glyphs[i].height; j++) {
        int full_disp = (new_font->glyphs[i].height_offset + j) * texture_width;
        int bit_disp = j * new_font->glyphs[i].width;
        for (unsigned int k = 0; k < new_font->glyphs[i].width; k++) {
            full_texture[(full_disp + k)] =
                    glyph_textures[i][bit_disp + k];
        }
    }
}

然后我加载纹理数据调用:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->x, texture->y, 0, GL_RED, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(full_texture));

我的片段着色器执行以下代码:

#version 330

uniform sampler2D texture;

in vec2 texcoord;
in vec4 pass_colour;

out vec4 out_colour;

void main()
{
float temp = texture2D(texture, texcoord).r;
out_colour = vec4(pass_colour[0], pass_colour[1], pass_colour[2], temp);
}

我得到的图像可以看出是从纹理生成的,但它严重扭曲,我不确定为什么。顺便说一句,我正在使用 GL_RED,因为 GL_ALPHA 已从 Opengl 4 中删除。 真正让我困惑的是,为什么当我从字形生成 4 RGBA 纹理然后使用它的 alpha 通道时效果很好?


glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->x, texture->y, 0, GL_RED, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(full_texture));

这在技术上是合法的,但是never一个好主意。

首先,你需要了解第三个参数是什么glTexImage2D是。这就是实际情况图像格式的纹理。您不是用一个通道创建纹理;而是用一个通道创建纹理。你正在创建一个纹理four渠道。

接下来,您需要了解最后三个参数的作用。这些是像素传输参数;它们描述了您提供给 OpenGL 的像素数据是什么样的。

该命令的意思是,“创建一个 4 通道纹理,然后将一些数据上传到just红色通道。该数据存储为无符号字节数组。”仅将数据上传到some纹理的通道在技术上是合法的,但几乎不是一个好主意。如果您要创建单通道纹理,则应该使用单通道纹理。这意味着正确的图像格式。

接下来,事情变得更加混乱:

new_texture->datasize = texture_width * texture_height*4;

您对“*4”的使用强烈表明您正在创建四通道像素数据。但您只上传单通道数据。你的其余计算与此一致;你似乎从未填写过任何数据通行证full_texture[texture_width * texture_height]。所以你分配的内存可能比你需要的多。

最后一件事:always使用大小的内部格式。永远不要只使用GL_RGBA; use GL_RGBA8 or GL_RGBA4管他呢。不要让司机选择并希望它能给你一个好的选择。

所以,正确的上传应该是这样的:

glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, texture->x, texture->y, 0, GL_RED, GL_UNSIGNED_BYTE, full_texture);

仅供参考:reinterpret_cast是不必要的;即使在 C++ 中,指针也可以隐式转换为void*.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Opengl:使用单通道纹理作为Alpha通道来显示文本 的相关文章

随机推荐

  • 如何删除 django(python) 元组中多余的“,”

    我在使用 django 构建 id 列表时遇到一个问题 如果我选择 1 个以上的 id 就可以了 但如果我只选择一个 它会在列表中产生额外的 testa tuple k id for k in queryset values id prin
  • 使用 pthread 在 C 中生成随机数的最正确方法是什么

    我有多个线程同时运行 每个线程都必须生成随机数 我想了解是否有可遵循的模式 了解在主线程中使用 srand 初始化随机生成器是否正确 或者每个线程是否必须初始化自己的随机生成器 看来 rand srand 尚未设计为与线程一起使用 我想知道
  • 为什么 MRO 中的类以这种方式排序?

    我的 Python MRO 有问题 对于这段代码 class F pass class G pass class H pass class E G H pass class D E F pass class C E G pass class
  • 如何在thymeleaf中设置css文件的背景url?

    我有一个 thymeleaf 模板 其中没有导入 CSS 文件 并且想使用以下命令为 body 元素声明 style 属性background image url image jpg 具有相对图像 URL 的属性 我想加载 URL 而不包含
  • 将 wstring 转换为 UTF-8 编码的字符串

    我需要在 wstring 和 string 之间进行转换 我发现 使用 codecvt 方面应该可以解决问题 但它似乎不适用于 utf 8 语言环境 我的想法是 当我将utf 8编码的文件读取到字符时 一个utf 8字符被读入两个普通字符
  • Angular 2:多个 HTTP 服务

    我们在项目中使用 Angular 2 到目前为止我们使用in memory web api在我们开发中的数据服务中 应用程序模块 ts imports HttpModule InMemoryWebApiModule forRoot Mock
  • 如何验证我的组织是否签署了受信任的 Windows 二进制文件?

    这是一个后续问题问题 1072540 WinVerifyTrust 检查特定签名 我想写一个 C 函数 让我们调用它TrustedByUs形式 bool TrustedByUs std string pathToBinary std str
  • 单个 WCF 服务中的多个基地址

    我有一个环境 同一服务器上托管的多个站点将使用单个服务进行调用 例如 http domain1 com Api Service svc http domain2 com Api Service svc Api 应用程序已在每个站点中设置为虚
  • Testflight 中的应用程序与 iPhone 4s 和 5 不兼容

    我的应用程序即将完成 而且我试飞就现在 问题是我无法让它在 iPhone 4s 和 iPhone 5 上运行 部署目标设置为 8 0 并且它在 iPhone 4s 模拟器上完美运行 当我的测试人员打开 TestFlight 时 他们可以看到
  • Delphi中带有数值的$是什么意思

    在 Delphi 中 当我看到这样的命令时 这意味着什么 char 23 在这种情况下 美元符号意味着什么 美元符号代表后面的是十六进制值 ShowMessage 字符 23 显示
  • 检索维基百科页面的另一种语言

    任务 我们有维基百科英文页面 需要检索俄语的相同页面地址 我知道语义网解决方案 使用 DbPedia 的简单查询 但我很好奇是否有传统的解决方案 我在中问过同样的问题语义溢出网站Toby Inkster 建议解析的地方http en wik
  • 我可以在 Mobile Safari 上使用 user-css 覆盖 CSS 吗?

    我正在尝试修改网站的CSShttp www baomoi com为了我的祖母 我想修改 CSS 以便于她更容易阅读并使其更加简约 我尝试过使用 JavaScript 书签 javascript function if 20 document
  • 通过计算引擎的简单查询,Google 云数据存储速度缓慢(>800 毫秒)

    当我尝试从 微型 计算引擎查询 Google Cloud Datastore 时 通常需要 gt 800 毫秒才能获得回复 我得到的最好的是 450 毫秒 最差的是 gt 3 秒 我的印象是延迟应该低得多 比如 20 80 毫秒 所以我猜我
  • JavaScript 错误:左侧赋值无效

    在 Acrobat XI 中使用 JavaScript 由于某种原因 我不断收到以下错误 invalid assignment left hand side at 9 line 10 我的代码非常简单 在 AFAICT 上看起来很不错 请检
  • VS2015 Update 1 bug,或者糟糕的C++:为什么友元类不能访问其友元的受保护析构函数?

    以下似乎是 ZeroC ICE 在自动生成的代码中采用的模式 在我看来 这是他们现在为其工具的许多版本制作单例 不知道为什么 的一种方式 各种编译器都没有问题 直到今天我发现 Visual Studio 2015 Update 1 VS 版
  • 告诉 abcPdf 缩放 html 以适合单个 pdf 页面

    我正在使用 abcPdf 将 HTML 报告转换为 pdf 文件 pdf 必须是单个横向 A4 页面 您知道是否有任何方法可以告诉 abcPdf 缩放 HTML 页面以适合 pdf 中的单个页面 我尝试使用放大 方法 它会缩放内容 但仍然将
  • 如何将内核文件 CUDA 与主 .cpp 文件分开

    当我在同一文件 mainFunc cu 中使用 kernelAdd 函数和 main 函数构建代码时 一切正常 但是当我将 kernelAdd cu 文件中的 kernelAdd 函数与 main cpp 文件中的主文件分开时 它会出现两个
  • 二维数组到对象 (JavaScript)

    我有一个数组 其中包含大量二维数组 var myArray 2260146 2334221 copy 1226218 2334231 copy 2230932 1 copy 2230933 1 copy 2230934 1 copy 我需要
  • Java 正则表达式 1=1

    我需要寻找 java 正则表达式模式 该模式查找格式为 1 1 的输入字符串 其中 的前缀应与后缀具有相同的位数 另外 这里前缀和后缀值应该相同 例如 1 1 11 11 223 223 1 2 3 22 33 22 等值不应与模式匹配 我
  • Opengl:使用单通道纹理作为Alpha通道来显示文本

    我想做的是将纹理从单通道数据数组加载到硬件中 并使用它的 Alpha 通道将文本绘制到对象上 我正在使用opengl 4 如果我尝试使用 4 通道 RGBA 纹理来执行此操作 它工作得非常好 但无论出于何种原因 当我尝试在单个通道中加载时