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
我正在尝试使用 OpenGL 的纹理单元将图像写入屏幕。如您所见,我将 0 写入 tex Sampler2D,因为我正在使用第 0 个纹理单元。我还将顶点和纹理作为矩形。我检查了 gl 错误,有 none。我也把 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);
}
您不能 "see" 图像,因为纹理不是完整的 mipmap。
参见 OpenGL 4.6 API Compatibility Profile Specification; 8.17 Texture Completeness; page 306
A texture is said to be complete if all the texture images and texture parameters required to utilize the texture for texture application are consistently defined.
... a texture is complete unless any of the following conditions hold true:
- The minification filter requires a mipmap (is neither
NEAREST
nor LINEAR
), and the texture is not mipmap complete.
GL_TEXTURE_MIN_FILTER
的初始值为GL_NEAREST_MIPMAP_LINEAR
。如果您不更改它并且不创建 mipmap,则纹理不是 "complete",也不会是 "shown"。参见 glTexParameter
。
将缩小过滤器设置为 GL_NEAREST
或 GL_LINEAR
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
或通过glGenerateMipmap(GL_TEXTURE_2D)
生成mipmap来解决问题。
我正在尝试使用 OpenGL 的纹理单元将图像写入屏幕。如您所见,我将 0 写入 tex Sampler2D,因为我正在使用第 0 个纹理单元。我还将顶点和纹理作为矩形。我检查了 gl 错误,有 none。我也把 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);
}
您不能 "see" 图像,因为纹理不是完整的 mipmap。
参见 OpenGL 4.6 API Compatibility Profile Specification; 8.17 Texture Completeness; page 306
A texture is said to be complete if all the texture images and texture parameters required to utilize the texture for texture application are consistently defined.
... a texture is complete unless any of the following conditions hold true:
- The minification filter requires a mipmap (is neither
NEAREST
norLINEAR
), and the texture is not mipmap complete.
GL_TEXTURE_MIN_FILTER
的初始值为GL_NEAREST_MIPMAP_LINEAR
。如果您不更改它并且不创建 mipmap,则纹理不是 "complete",也不会是 "shown"。参见 glTexParameter
。
将缩小过滤器设置为 GL_NEAREST
或 GL_LINEAR
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
或通过glGenerateMipmap(GL_TEXTURE_2D)
生成mipmap来解决问题。