我正在设计一个sprite类,并且如果没有纹理加载,我只想显示一种颜色。

这是我的顶点着色器

#version 330 core
layout (location = 0) in vec4 vertex; // <vec2 pos, vec2 tex>

out vec2 vs_tex_coords;

uniform mat4 model;
uniform mat4 projection;

void main()
{
    vs_tex_coords = vertex.zw;
    gl_Position = projection * model * vec4(vertex.xy, 0.0, 1.0);
}

和片段着色器:
#version 330 core

in vec2 vs_tex_coords;

out vec4 fs_color;

uniform sampler2D image;
uniform vec3 sprite_color;

void main()
{
    fs_color = vec4(sprite_color, 1.0) * texture(image, vs_tex_coords);
}

我的问题是,如果不绑定(bind)纹理,它将仅显示黑色 Sprite 。我认为问题在于片段着色器中的纹理函数返回0,然后拧紧所有公式。

有没有办法知道sampler2D是否未初始化或为null,而仅返回sprite_color?

解决方案:

解决的办法是生成一个空的1x1纹理并将其绑定(bind)。为此,您必须创建一个4个字符的数组,为255(对于RGBA),并为glTexImage2D函数提供1x1的大小,以确保将创建1x1纹理。
Texture::Texture()
{
    glGenTextures(1, &ID);

    GLubyte data[] = { 255, 255, 255, 255 };

    glBindTexture(GL_TEXTURE_2D, ID);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);

    size.x = 1;
    size.y = 1;
}

最佳答案

采样器不能为“空”。有效的纹理必须绑定(bind)到每个采样器引用的纹理单元,以使渲染具有明确定义的行为。

但这并不意味着您必须阅读绑定(bind)在那里的纹理。使用uniform值告诉着色器是否从纹理读取是完全有效的。

但是您仍然必须在此绑定(bind)一个简单的1x1纹理。确实,您可以在采样器上使用textureSize。如果它是1x1纹理,则不要理会它。请注意,这可能比使用uniform慢。

10-07 12:35