【问题标题】:LWJGL - Texture Only Shows Solid ColorLWJGL - 纹理只显示纯色
【发布时间】:2014-04-26 00:15:55
【问题描述】:

由于某种原因,当我尝试使用 LWJGL 渲染纹理时,纹理仅呈现为纯色。我不认为纹理加载有问题(我使用的是 Slick Util 库),因为纹理的颜色似乎是图像中的主要颜色。

模型类:

public class Model {

private FloatBuffer vertices, uvValues;
private int vertexID, uvID;
private int vertexAttrib, uvAttrib;

private Texture tex;
private ByteBuffer texData;
private int textureID;
private int textureLocation;

private Matrix4f modelMatrix;
private FloatBuffer modelBuffer;
private int modelMatrixLocation;

public Model(float[] verts, float[] uvs, int modelLocation, String texPath, int texLocation){
    vertices = createBuffer(verts);
    vertexAttrib = 0;
    vertexID = createVBO(vertices, vertexAttrib, 3);

    tex = TextureUtils.loadTexturePNG(texPath);
    texData = createBuffer(tex);
    textureID = bindTextureData(tex, texData);
    textureLocation = texLocation;

    uvValues = createBuffer(uvs);
    uvAttrib = 1;
    uvID = createVBO(uvValues, uvAttrib, 2);

    modelMatrix = new Matrix4f();
    modelMatrixLocation = modelLocation;
    modelBuffer = createBuffer(modelMatrix);
}

private static FloatBuffer createBuffer(float[] vals){
    FloatBuffer buffer = BufferUtils.createFloatBuffer(vals.length);
    buffer.put(vals);
    buffer.flip();

    return buffer;
}

private static FloatBuffer createBuffer(Matrix4f mat){
    FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
    mat.store(buffer);
    buffer.flip();

    return buffer;
}

private static ByteBuffer createBuffer(Texture tex){
    ByteBuffer buffer = BufferUtils.createByteBuffer(tex.getTextureData().length);
    buffer.put(tex.getTextureData());
    buffer.flip();

    return buffer;
}

private static int bindTextureData(Texture tex, ByteBuffer data){
    int id = glGenTextures();
    glBindTexture(GL_TEXTURE_2D, id);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (int) tex.getWidth(), (int) tex.getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glBindTexture(GL_TEXTURE_2D, 0);

    return id;
}

private static int createVBO(FloatBuffer buffer, int location, int vectorSize){
    int id = glGenBuffers();

    glEnableVertexAttribArray(location);
    glBindBuffer(GL_ARRAY_BUFFER, id);
    glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
    glVertexAttribPointer(location, vectorSize, GL_FLOAT, false, 0, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDisableVertexAttribArray(location);

    return id;
}

private void bind(){
    glUniformMatrix4(modelMatrixLocation, false, modelBuffer);

    tex.bind();
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textureID);
    glUniform1i(textureLocation, 0);

    glEnableVertexAttribArray(vertexAttrib);
    glBindBuffer(GL_ARRAY_BUFFER, vertexID);
    glVertexAttribPointer(vertexAttrib, 3, GL_FLOAT, false, 0, 0);

    glEnableVertexAttribArray(uvAttrib);
    glBindBuffer(GL_ARRAY_BUFFER, uvID);
    glVertexAttribPointer(uvAttrib, 2, GL_FLOAT, false, 0, 0);
}

private void unbind(){
    glDisableVertexAttribArray(uvAttrib);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDisableVertexAttribArray(vertexAttrib);

    glBindTexture(GL_TEXTURE_2D, 0);
}

public void render(){
    bind();

    glDrawArrays(GL_TRIANGLES, 0, vertices.capacity() / 3);

    unbind();
}

}

模型初始化代码:

        model = new Model(new float[]{
        -1, -1, -3,
        1, -1, -3,
        1, 1, -3
    }, new float[]{
        0.0f, 0.0f,
        1.0f, 0.0f,
        1.0f, 1.0f
    }, program.getUniformLocation("model_matrix"), "res/tex/testTex.png", program.getUniformLocation("texture_sampler"));

顶点着色器:

#version 330 core

 layout(location = 0) in vec3 position_modelspace;

layout(location = 1) in vec2 vertex_UV;

uniform mat4 model_matrix;
uniform mat4 view_matrix;
uniform mat4 projection_matrix;

out vec2 UV;

void main(){
vec4 vertex_MVP = projection_matrix * view_matrix * model_matrix * vec4(position_modelspace, 1.0);
gl_Position = vertex_MVP;

UV = vertex_UV;
}

片段着色器:

#version 330 core

uniform sampler2D texture_sampler;

in vec2 UV;

out vec3 color;

void main(){
color = texture(texture_sampler, UV).rgb;
}

我不太确定问题出在哪里。纹理加载没有任何问题,我已经查看了很多其他类似问题的问题,但我还没有找到解决这个问题的问题。

【问题讨论】:

  • 这个Texture 类的实现是什么样的,为什么要绑定它设置活动的纹理图像单元?我希望看到tex 对象与glBindTexture (...) 同时绑定,事实上我怀疑他们做同样的事情。
  • 我正在使用 Slick Util 库的 Texture 类。我删除了 tex.bind(),但没有任何区别。
  • 我不认为它会,但流浪绑定似乎很奇怪。此外,您的 createVBO (...) 方法做了一些多余的事情,例如启用立即禁用属性指针。仅在您调用glDrawArrays (...) 时,启用或禁用指针才真正重要。该状态不会影响其他任何东西。同样,将 VBO 绑定到 GL_ARRAY_BUFFER 也没有什么坏处。除非您使用基于非 VBO 的顶点数组,否则不需要绑定 0
  • 我查看了代码,并没有发现问题。我们可以尝试缩小对您有用的问题。第一个实验:从片段着色器输出一个固定的颜色。将着色器中的代码行更改为color = vec3(1.0, 1.0, 0.0);。看到黄色三角形了吗?如果是,请将其更改为color = vec3(UV, 0.0);。三角形现在是否显示红色/绿色/黄色渐变?这将告诉我们几何体是否正确渲染,以及纹理坐标是否成功到达片段着色器。
  • 第二次不行!出于某种原因,UV 坐标似乎没有到达着色器。

标签: opengl glsl lwjgl texture-mapping opengl-3


【解决方案1】:

也许添加glEnable(GL_TEXTURE_2D); 可能会解决问题

【讨论】:

  • GL_TEXTURE_... 启用 需要用于固定功能管道,并且在使用着色器时无效。在核心配置文件 GL 中,调用它只会导致错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多