无法使用 VertexArrayObject 在 OpenGL 4.3 中显示纹理
Cannot show texture in OpenGL 4.3 using VertexArrayObject
从两天前开始,我就在敲这段代码。看起来创建缓冲区或纹理没有任何错误,但纹理不显示。
这是我的纹理加载代码:
struct image2d texImage = loadBMPImage(filePath);
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &(result.external->texID));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, result.external->texID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texImage.width, texImage.height, 0, GL_RGB, GL_UNSIGNED_BYTE, texImage.pixels);
free(texImage.pixels);
image2d结构就是这个
struct image2d{
unsigned int width, height;
unsigned char* pixels;
};
是的,我正在通过 glEnable()
启用 GL_TEXTURE_2D
然后我的网格是用这段代码绘制的
void MeshDraw(Mesh m, int renderType)
{
glBindVertexArray(m.external->vao);
glBindBuffer(GL_ARRAY_BUFFER, m.external->vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, VERTEX_SIZE*4, 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, VERTEX_SIZE*4, (void*)12);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m.external->ibo);
glDrawElements(GL_TRIANGLES, m.external->sizeFc * 3, GL_UNSIGNED_SHORT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
return;
}
最后是我的顶点着色器
#version 430 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 inTexCoord;
uniform mat4 transform;
out vec2 texCoord;
out vec3 outPos;
void main(void)
{
outPos = position;
gl_Position = transform * vec4(position, 1.0);
texCoord = inTexCoord;
}
这是我的片段着色器
#version 430 core
out vec4 drawColor;
in vec2 texCoord;
in vec3 outPos;
uniform sampler2D sampler;
void main(void)
{
drawColor = texture(sampler, texCoord);
//drawColor = vec4(clamp(outPos, 0.0, 1.0), 1.0);
}
如果您需要查看整个项目,我将其发布 here
如有任何帮助,我将不胜感激:)
附加代码(如果有人想看的话,也在下载中)
void initOpenGL()
{
printf("OpenGL version: %s\n",glGetString(GL_VERSION));
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glFrontFace(GL_CW);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_FRAMEBUFFER_SRGB);
return;
}
创建上下文并初始化 glew 后立即调用它。
void RenderGame(Game g)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ShaderBind(g.external->sh);
setUniformmat4(g.external->sh, "transform", TransformGetProjectedTransformation(g.external->transf));
TextureBind(g.external->texture);
MeshDraw(g.external->msh, GL_TRIANGLES);
glFlush();
glfwSwapBuffers(WindowGetHandler(g.external->window));
return;
}
这是我的渲染方法。
您的纹理不是完整的 mipmap,但您仍在使用默认的 GL_NEAREST_MIPMAP_LINEAR
缩小过滤器,因此纹理采样将失败。
你尝试设置为GL_NEAREST
,但是这个操作顺序是错误的:
glGenTextures(1, &(result.external->texID));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, result.external->texID);
在 GL 中,纹理采样器状态是纹理对象本身的一部分(现在也有单独的 sampler objects 可以覆盖该状态,但您似乎也没有使用它们),并且glTexParameteri()
在调用时影响 当前绑定的纹理对象 。我不知道当时是否绑定了某些纹理,或者根本 none - 但可以肯定的是,新纹理没有,所以它将坚持 GL_NEAREST_MIPMAP_LINEAR
的初始默认值...
解决方案看来@peppe 一直都是对的。为了一丝不苟,我使用 setuniform 调用将采样器设置为 0,它起作用了。问题是它没有按预期工作,这是因为加载位图文件的函数出错了。现在它就像一个魅力:)谢谢你们!
从两天前开始,我就在敲这段代码。看起来创建缓冲区或纹理没有任何错误,但纹理不显示。
这是我的纹理加载代码:
struct image2d texImage = loadBMPImage(filePath);
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &(result.external->texID));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, result.external->texID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texImage.width, texImage.height, 0, GL_RGB, GL_UNSIGNED_BYTE, texImage.pixels);
free(texImage.pixels);
image2d结构就是这个
struct image2d{
unsigned int width, height;
unsigned char* pixels;
};
是的,我正在通过 glEnable()
启用 GL_TEXTURE_2D然后我的网格是用这段代码绘制的
void MeshDraw(Mesh m, int renderType)
{
glBindVertexArray(m.external->vao);
glBindBuffer(GL_ARRAY_BUFFER, m.external->vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, VERTEX_SIZE*4, 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, VERTEX_SIZE*4, (void*)12);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m.external->ibo);
glDrawElements(GL_TRIANGLES, m.external->sizeFc * 3, GL_UNSIGNED_SHORT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
return;
}
最后是我的顶点着色器
#version 430 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 inTexCoord;
uniform mat4 transform;
out vec2 texCoord;
out vec3 outPos;
void main(void)
{
outPos = position;
gl_Position = transform * vec4(position, 1.0);
texCoord = inTexCoord;
}
这是我的片段着色器
#version 430 core
out vec4 drawColor;
in vec2 texCoord;
in vec3 outPos;
uniform sampler2D sampler;
void main(void)
{
drawColor = texture(sampler, texCoord);
//drawColor = vec4(clamp(outPos, 0.0, 1.0), 1.0);
}
如果您需要查看整个项目,我将其发布 here
如有任何帮助,我将不胜感激:)
附加代码(如果有人想看的话,也在下载中)
void initOpenGL()
{
printf("OpenGL version: %s\n",glGetString(GL_VERSION));
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glFrontFace(GL_CW);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_FRAMEBUFFER_SRGB);
return;
}
创建上下文并初始化 glew 后立即调用它。
void RenderGame(Game g)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ShaderBind(g.external->sh);
setUniformmat4(g.external->sh, "transform", TransformGetProjectedTransformation(g.external->transf));
TextureBind(g.external->texture);
MeshDraw(g.external->msh, GL_TRIANGLES);
glFlush();
glfwSwapBuffers(WindowGetHandler(g.external->window));
return;
}
这是我的渲染方法。
您的纹理不是完整的 mipmap,但您仍在使用默认的 GL_NEAREST_MIPMAP_LINEAR
缩小过滤器,因此纹理采样将失败。
你尝试设置为GL_NEAREST
,但是这个操作顺序是错误的:
glGenTextures(1, &(result.external->texID));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, result.external->texID);
在 GL 中,纹理采样器状态是纹理对象本身的一部分(现在也有单独的 sampler objects 可以覆盖该状态,但您似乎也没有使用它们),并且glTexParameteri()
在调用时影响 当前绑定的纹理对象 。我不知道当时是否绑定了某些纹理,或者根本 none - 但可以肯定的是,新纹理没有,所以它将坚持 GL_NEAREST_MIPMAP_LINEAR
的初始默认值...
解决方案看来@peppe 一直都是对的。为了一丝不苟,我使用 setuniform 调用将采样器设置为 0,它起作用了。问题是它没有按预期工作,这是因为加载位图文件的函数出错了。现在它就像一个魅力:)谢谢你们!