glTexImage2D 不起作用,但将 FragColor 设置为 vec4(1.0, 0, 0, 1.0) 会给我红色图像

glTexImage2D won't work, but setting FragColor to vec4(1.0, 0, 0, 1.0) gives me red image

本文关键字:图像 红色 但将 不起作用 FragColor 设置 vec4 glTexImage2D      更新时间:2023-10-16

我正在尝试使用OpenGL的纹理单元将图像写入屏幕。如您所见,我将 0 写入 tex Sampler2D,因为我使用的是第 0 个纹理单元。我还把顶点和纹理做成矩形。我检查了gl错误,没有。我还将 FragColor 更改为vec4(1.0, 0, 0, 1.0);,我确实看到了一个红色图像,这意味着我的坐标很严格。

这是我的代码:

static unsigned char * d = new unsigned char[640*360*4];
const GLfloat vertices_textures[20] = {
//vertices            //positions
-1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 0.0f};
if (this->firstRun)
{
int i;
for (i = 0; i < 640*360*4; ++i)
{
d[i] = 255;
}
program = std::make_unique<Program>();
Shader vertexShader(ShaderType::Vertex);
vertexShader.load_from_string(vertexShaderSource);
program->attach_shader(vertexShader);
Shader fragmentShader(ShaderType::Fragment);
fragmentShader.load_from_string(fragmentShaderSource);
program->attach_shader(fragmentShader);
program->link();
vextexInLocation = glGetAttribLocation(program->get_id(), "aPos");
textureInLocation = glGetAttribLocation(program->get_id(), "aTexCoord");
glGenVertexArrays(1, &vertexArrayObject);
glBindVertexArray(vertexArrayObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_textures), vertices_textures, GL_STATIC_DRAW);
glVertexAttribPointer(vextexInLocation, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *)0);
glEnableVertexAttribArray(vextexInLocation);
glVertexAttribPointer(textureInLocation, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(textureInLocation);

glActiveTexture(GL_TEXTURE0);
texLocation = glGetUniformLocation(program->get_id(), "tex");
program->use();
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 640, 360, 0,  GL_RED, GL_UNSIGNED_BYTE, d);
firstRun = false;
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUniform1i(texLocation, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_id);
glBindVertexArray(vertexArrayObject);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

这是我的着色器:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}

#version 330 core
out vec4 FragColor;
in vec2 TexCoord;
uniform sampler2D tex;
void main()
{
FragColor = texture(tex, TexCoord);
}

您无法"看到"图像,因为纹理不完整。

请参阅 OpenGL 4.6 API 兼容性配置文件规范;8.17 纹理完整性;第 306 页

如果一致地定义了利用纹理进行纹理应用所需的所有纹理图像和纹理参数,则称纹理是完整的

。除非满足以下任何条件,否则纹理是完整的:

  • 缩小滤镜需要一个 mipmap(既不NEAREST也不LINEAR(,并且纹理不是 mipmap 完整的。

GL_TEXTURE_MIN_FILTER的初始值为GL_NEAREST_MIPMAP_LINEAR。如果你不改变它,你不创建mipmap,那么纹理就不是"完整的",不会被"显示"。请参阅glTexParameter

将缩小筛选器设置为GL_NEARESTGL_LINEAR

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

或通过glGenerateMipmap(GL_TEXTURE_2D)生成 mipmap 来解决问题。