OpenGL ES 2.0:纹理呈现黑色,几个小时没有分辨率:(

发布于 2024-12-27 11:01:12 字数 2123 浏览 1 评论 0原文

我会保持简单:本文末尾列出的代码在我的项目中按从上到下的顺序排列。我有一个 OGLES2.0 框架,可以完美渲染除纹理之外的所有内容。当渲染单个纹理时,我看到的只是一个尺寸正确的黑盒子。

这是我已经验证的内容:

  • 输出纹理字节(格式为 GL_ALPHA)后,很明显可以看到有零值和非零值,因此数据看起来是正确的(或者至少不是)全黑!)。

  • 纹理 ID 正确,通过在顶点着色器中使用以下内容进行验证: gl_FragColor=vec4(v_texCoord.xy,0.0,1.0); ..并观察预期的black->green->yellow->red颜色流从(0,0)->(0,1)->(可以看到 1,1)->(1,0)

  • 我的纹理具有二维能力:256 x 64,正确反映在数据数组中。

我将非常感谢您帮助确定问题所在,因为经过几个小时的谷歌搜索和刺激后,我被难住了!

glGenTextures(1, &_textureId);
GLint savedId;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &savedId);
glBindTexture(GL_TEXTURE_2D, _textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GLenum datatype = -1;
GLenum format = -1;
switch([self pixelFormat]) {
    case kGLTexturePixelFormat_RGBA8888:
        format=GL_RGBA;
        datatype=GL_UNSIGNED_BYTE;
        break;
    case kGLTexturePixelFormat_RGB565:
        format=GL_RGB;
        datatype=GL_UNSIGNED_SHORT_5_6_5;
        break;
    case kGLTexturePixelFormat_A8: // * This is current format, used for testing.
        format=GL_ALPHA;
        datatype=GL_UNSIGNED_BYTE;
        break;
    default:
        [NSException raise:NSInternalInconsistencyException format:@""];

}
glTexImage2D(GL_TEXTURE_2D, 0, format, [self pixelsWide], [self pixelsHigh], 0, format, datatype, [self data]);
glBindTexture(GL_TEXTURE_2D, savedId);
//...
GLint s_textureId = glGetUniformLocation(program, "s_texture");
//...
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, [_textureAtlas textureId]);
glUniform1i(s_textureId, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

// In vertex shader:
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
uniform sampler2D s_texture;
void main() {
    // ...
    v_texCoord = a_texCoord;
}

// In fragment shader:
varying vec2 v_texCoord;
uniform sampler2D s_texture;
void main() {
    // ...
    gl_FragColor = texture2D(s_texture, v_texCoord);
}

I'll keep it simple: The code listed at the end of this post is in top-to-bottom order within my project. I have an OGLES2.0 framework in place which renders everything except textures perfectly. When rendering a single texture all I see is a black box of the correct dimensions.

Here's what I've verified:

  • Having output the texture bytes (it's format GL_ALPHA) it's plain to see there are zero and none-zero values, so the data looks correct (or at least not all black!).

  • The texture ids are correct, verified by using the following in the vertex shader:
    gl_FragColor=vec4(v_texCoord.xy,0.0,1.0);
    ..and observing the expected black->green->yellow->red colour flow moving from (0,0)->(0,1)->(1,1)->(1,0) is seen.

  • My texture has power of two dimensions: 256 x 64, correctly reflected in the data array.

I'd be tremendously grateful for help in determining what's wrong, as after several hours of googling and prodding I'm stumped!

glGenTextures(1, &_textureId);
GLint savedId;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &savedId);
glBindTexture(GL_TEXTURE_2D, _textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GLenum datatype = -1;
GLenum format = -1;
switch([self pixelFormat]) {
    case kGLTexturePixelFormat_RGBA8888:
        format=GL_RGBA;
        datatype=GL_UNSIGNED_BYTE;
        break;
    case kGLTexturePixelFormat_RGB565:
        format=GL_RGB;
        datatype=GL_UNSIGNED_SHORT_5_6_5;
        break;
    case kGLTexturePixelFormat_A8: // * This is current format, used for testing.
        format=GL_ALPHA;
        datatype=GL_UNSIGNED_BYTE;
        break;
    default:
        [NSException raise:NSInternalInconsistencyException format:@""];

}
glTexImage2D(GL_TEXTURE_2D, 0, format, [self pixelsWide], [self pixelsHigh], 0, format, datatype, [self data]);
glBindTexture(GL_TEXTURE_2D, savedId);
//...
GLint s_textureId = glGetUniformLocation(program, "s_texture");
//...
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, [_textureAtlas textureId]);
glUniform1i(s_textureId, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

// In vertex shader:
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
uniform sampler2D s_texture;
void main() {
    // ...
    v_texCoord = a_texCoord;
}

// In fragment shader:
varying vec2 v_texCoord;
uniform sampler2D s_texture;
void main() {
    // ...
    gl_FragColor = texture2D(s_texture, v_texCoord);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

極樂鬼 2025-01-03 11:01:12

你的代码看起来不错,我必须说我希望输出颜色为黑色:由于你的纹理是 GL_ALPHA 格式,GL ES 的文档说:

GL_ALPHA 每个元素都是一个单独的 alpha 分量。 GL 对其进行转换
转换为浮点数并通过附加 0 将其组装成 RGBA 元素
红色、绿色和蓝色。

因此,如果您想将 alpha 值显示为灰度颜色,则需要指示片段着色器执行此操作:

gl_FragColor = texture2D(s_texture, v_texCoord).aaaa;

这将在所有红色、绿色、红色和 alpha 通道中复制 alpha 值。

如果您希望输出 Alpha 通道保持 1.0(不透明),那么您需要:

gl_FragColor = vec4( texture2D(s_texture, v_texCoord).aaa, 1.0 );

Your code looks fine, and I must say that I expect the output color to be black : as your texture is of GL_ALPHA format, the documentation of GL ES says :

GL_ALPHA Each element is a single alpha component. The GL converts it
to floating point and assembles it into an RGBA element by attaching 0
for red, green, and blue.

So if you want to display your alpha value as a greyscale color, you'll need to instruct your fragment shader to do so :

gl_FragColor = texture2D(s_texture, v_texCoord).aaaa;

This will duplicate the alpha value in all red, green, red and alpha channels.

If you want your output alpha channel to remain 1.0 (opaque), then you'll want :

gl_FragColor = vec4( texture2D(s_texture, v_texCoord).aaa, 1.0 );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文