OpenGL着色器没有传递正确的纹理坐标

Posted

技术标签:

【中文标题】OpenGL着色器没有传递正确的纹理坐标【英文标题】:OpenGL shader not passing correct texture coordinates 【发布时间】:2014-10-26 00:47:42 【问题描述】:

在我的 OpenGL 应用程序中测试了一些东西后,我知道我的纹理没有正确加载,因为纹理坐标无法从顶点着色器到片段着色器(或者至少它们都作为 (0,0 )。我就是不知道为什么。

这是我对正方形的位置、索引和纹理坐标:

private static final float[] VERTICES = 
    -0.5f,  0.5f, 0f,
    -0.5f, -0.5f, 0,
     0.5f, -0.5f, 0f,
     0.5f,  0.5f, 0f
;

private static final int[] INDICES = 
    0, 1, 2,
    3, 0, 2
;

private static final float[] TEXTURE_COORDINATES = 
    0.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,
    1.0f, 0.0f
;

这是我如何将纹理坐标插入到索引 1 处的 vao 中。为简洁起见,我不会展示我的 vao 加载器的其他部分,因为它们处于正常工作状态。

int vboTexCoordID = GL15.glGenBuffers();
ModelManager.recordVBO(vboTexCoordID);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboTexCoordID);

FloatBuffer texCoordBuffer = BufferUtils.createFloatBuffer(texCoord.length);
verticesBuffer.put(texCoord);
verticesBuffer.flip();

GL15.glBufferData(GL15.GL_ARRAY_BUFFER, texCoordBuffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(1,2,GL11.GL_FLOAT, false,  0,0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

这是我的渲染方法:

    model.getShader().start(); // this calls GL20.glUseProgram()
    GL30.glBindVertexArray(model.getVaoID());
    GL20.glEnableVertexAttribArray(0);
    GL20.glEnableVertexAttribArray(1);
    GL13.glActiveTexture(GL13.GL_TEXTURE0);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, model.getTexId());
    GL11.glDrawElements(GL11.GL_TRIANGLES, model.getVerticesCount(), GL11.GL_UNSIGNED_INT,0);
    GL20.glDisableVertexAttribArray(0);
    GL20.glDisableVertexAttribArray(1);
    GL30.glBindVertexArray(0);
    model.getShader().stop();

最后是 mt 顶点着色器和片段着色器:

#version 330 core

in vec3 position;
in vec2 texCoords;

out vec2 pass_texCoords;

void main(void)

    gl_Position = vec4(position.x, position.y, position.z, 1.0);
    pass_texCoords = texCoords;


片段:

#version 330 core

in vec2 pass_texCoords;

out vec4 out_Color;

uniform sampler2D textureSampler;

void main(void)

    out_Color = texture(textureSampler, pass_texCoords);


【问题讨论】:

你怎么知道texCoords属性的位置是1? 因为那是我放的地方。 【参考方案1】:

你永远不会向texCoordBuffer添加数据:

FloatBuffer texCoordBuffer = BufferUtils.createFloatBuffer(texCoord.length);
verticesBuffer.put(texCoord);
verticesBuffer.flip();

GL15.glBufferData(GL15.GL_ARRAY_BUFFER, texCoordBuffer, GL15.GL_STATIC_DRAW);

当您调用glBufferData()texCoordBuffer 为空,因为您将纹理坐标存储在verticesBuffer 中。您需要将其更改为:

FloatBuffer texCoordBuffer = BufferUtils.createFloatBuffer(texCoord.length);
texCoordBuffer.put(texCoord);
texCoordBuffer.flip();

GL15.glBufferData(GL15.GL_ARRAY_BUFFER, texCoordBuffer, GL15.GL_STATIC_DRAW);

您还需要确保用于顶点属性的位置与顶点着色器匹配。最简单的方法是在顶点着色器代码中使用layout 指令:

layout(location=0) in vec3 position;
layout(location=1) in vec2 texCoords;

这指定顶点着色器将从属性 0 读取位置,从属性 1 读取纹理坐标。

【讨论】:

谢谢!我复制并粘贴并忘记更改所有内容。我可能应该停止这样做......

以上是关于OpenGL着色器没有传递正确的纹理坐标的主要内容,如果未能解决你的问题,请参考以下文章

传递给片段着色器的纹理坐标全部为 0

OpenGL:如何将多个纹理传递给具有一个变量的着色器?

OpenGL:只模糊纹理的一部分;可以使用顶点着色器加速吗?

顶点纹理获取(在顶点着色器中读取纹理)

OpenGL/C++:将多个纹理传递给一个着色器的问题

OpenGL 计算着色器中的样本深度缓冲区