作为黑四元组被回报的纹理

时间:2017-09-26 14:19:31

标签: java textures lwjgl opengl-3

我一直在尝试遵循code中指定的this tutorial on OpenGL3+ textures,但我的结果是黑色而不是纹理。

enter image description here

我正在使用stbimage将纹理使用的图像加载到直接的ByteBuffer中,并且可以保证缓冲区中的RGB数据至少不均匀 - 所以它不可能是这样。 / p>

我通常不喜欢转码,但此时我还没有看到其他许多事情。这是我的java代码和着色器:

GL是指向LWJGL3 1 中所有GL ##功能的接口。

ShaderProgram将所有着色器特定内容包装到一个漂亮的黑盒中,该黑盒在第一次调用use(GL)时从附加的着色器生成着色器程序,然后重新使用该程序。这适用于渲染彩色三角形,所以我排除了那里的任何错误。

Util.checkError(GL, boolean);检查自上次执行以来累积的任何OpenGL错误,如果未设置布尔值则抛出运行时异常(如果设置则静默写入日志)。

渲染代码,update(GL,long)每帧运行一次

private static final ResourceAPI res = API.get(ResourceAPI.class);

Image lwjgl32;

ShaderProgram prog = new ShaderProgram();
int vbo, vao, ebo;
int texture;

@Override
public void init(GL gl) {

    try {
        prog.attach(res.get("shaders/texDemo.vert", ShaderSource.class));
        prog.attach(res.get("shaders/texDemo.frag", ShaderSource.class));
        lwjgl32 = res.get("textures/lwjgl32.png", Image.class);
    } catch(ResourceException e) {
        throw new RuntimeException(e);
    }

    float[] vertices = {
        // positions          // colors           // texture coords
         0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right
         0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right
        -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
        -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // top left 
    };

    int[] indices = {
        0, 1, 3, // first triangle
        1, 2, 3  // second triangle
    };

    vao = gl.glGenVertexArrays();
    vbo = gl.glGenBuffers();
    ebo = gl.glGenBuffers();

    gl.glBindVertexArray(vao);

    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo);
    gl.glBufferData(GL.GL_ARRAY_BUFFER, vertices, GL.GL_STATIC_DRAW);

    gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, ebo);
    gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indices, GL.GL_STATIC_DRAW);

    gl.glVertexAttribPointer(0, 3, GL.GL_FLOAT, false, 8 * Float.BYTES, 0);
    gl.glEnableVertexAttribArray(0);

    gl.glVertexAttribPointer(1, 3, GL.GL_FLOAT, false, 8 * Float.BYTES, 3 * Float.BYTES);
    gl.glEnableVertexAttribArray(0);

    gl.glVertexAttribPointer(2, 2, GL.GL_FLOAT, false, 8 * Float.BYTES, 6 * Float.BYTES);
    gl.glEnableVertexAttribArray(0);

    texture = gl.glGenTextures();
    gl.glBindTexture(GL.GL_TEXTURE_2D, texture);

    gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
    gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);

    gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
    gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);

    gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, lwjgl32.getWidth(), lwjgl32.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, lwjgl32.getImageData());
    gl.glGenerateMipmap(GL.GL_TEXTURE_2D);

    prog.use(gl);
    gl.glUniform1i(gl.glGetUniformLocation(prog.getId(gl), "texture"), 0);

    Util.checkError(gl, false);
}

@Override
protected void update(GL gl, long deltaFrame) {
    gl.glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    gl.glClear(GL.GL_COLOR_BUFFER_BIT);

    gl.glActiveTexture(GL.GL_TEXTURE0);
    gl.glBindTexture(GL.GL_TEXTURE_2D, texture);

    prog.use(gl);
    gl.glBindVertexArray(vao);
    gl.glDrawElements(GL.GL_TRIANGLES, 6, GL.GL_UNSIGNED_INT, 0);
}

@Override
public void clean(GL gl) {
    gl.glDeleteVertexArrays(vao);
    gl.glDeleteBuffers(vbo);
    gl.glDeleteBuffers(ebo);

    ShaderProgram.clearUse(gl);
    prog.dispose(gl);
}

顶点着色器

#version 330 core

layout (location = 0) in vec3 in_position;
layout (location = 1) in vec3 in_color;
layout (location = 2) in vec2 in_texCoord;

out vec3 color;
out vec2 texCoord;

void main() {
    gl_Position = vec4(in_position, 1.0);

    color = in_color;
    texCoord = vec2(in_texCoord.x, in_texCoord.y);
}

片段着色器

#version 330 core

out vec4 frag_colour;

in vec3 color;
in vec2 texCoord;

uniform sampler2D texture;

void main() {
    frag_colour = texture(texture, texCoord) * vec4(color, 1.0);
}

1 我将LWJGL3的GL ##静态类包装到单个接口和实现中,因此我可以使用一堆有状态的方法来执行诸如识别上下文之类的内容。我也尽力从界面中删除非核心功能,所以我甚至不想尝试使用已弃用的东西

2 个答案:

答案 0 :(得分:2)

您只能启用索引为0的顶点属性,但这3次。

像这样调整你的代码:

gl.glVertexAttribPointer(0, 3, GL.GL_FLOAT, false, 8 * Float.BYTES, 0);
gl.glEnableVertexAttribArray(0);

gl.glVertexAttribPointer(1, 3, GL.GL_FLOAT, false, 8 * Float.BYTES, 3 * Float.BYTES);
gl.glEnableVertexAttribArray(1); // <-------

gl.glVertexAttribPointer(2, 2, GL.GL_FLOAT, false, 8 * Float.BYTES, 6 * Float.BYTES);
gl.glEnableVertexAttribArray(2); // <------

答案 1 :(得分:0)

仅仅查看代码很难分辨,但黑色四边形表示片段着色器中的这一行:

frag_colour = texture(texture, texCoord) * vec4(color, 1.0);

计算结果为0.这意味着纹理没有被正确读取/绑定,纹理坐标关闭或颜色是零向量。确保正确加载纹理图像(文件存在,具有宽度和高度等)并具有正确的格式。我通常用来调试着色器的是将每个参数设置为一个颜色,以便在它具有正确值时给出提示:

frag_colour = vec4(color, 1.0); //Makes sure the color is right

frag_colour = texture(texture, texCoord); //Makes sure the texture is loaded and bound

如果这不能提供足够的信息,甚至更详细:

frag_colour = vec4(color.x, color.x, color.x, 1.0);

frag_colour = vec4(texCoord.x, texCoord.x, texCoord.x, 1.0);