纹理渲染不正确 (OpenGL)

Texture renders incorrectly (OpenGL)

我一直在尝试渲染 8x8 纹理。我使用了 2 个教程中的代码,但纹理渲染不正确。现在我有这个初始化代码:

int shaderProgram,fragmentShader,vertexShader,texture,elementBuffer,vertexBuffer, vertexArray;

public Texture2D(String texturePath_, String vertexShader_,String fragmentShader_)
{
    vertexArray=GL30.glGenVertexArrays();
    GL30.glBindVertexArray(vertexArray);
    String[] vertexshader=Utilities.loadShaderFile(vertexShader_,getClass());
    String[] fragmentshader=Utilities.loadShaderFile(fragmentShader_,getClass());
    if(vertexshader==null)
        throw new NullPointerException("The vertex shader is null");
    if(fragmentshader==null)
        throw new NullPointerException("The fragment shader is null");
    vertexShader=GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
    GL20.glShaderSource(vertexShader,vertexshader);
    GL20.glCompileShader(vertexShader);
    Utilities.showShaderCompileLog(vertexShader);

    fragmentShader=GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
    GL20.glShaderSource(fragmentShader,fragmentshader);
    GL20.glCompileShader(fragmentShader);
    Utilities.showShaderCompileLog(fragmentShader);

    shaderProgram= GL20.glCreateProgram();
    GL20.glAttachShader(shaderProgram,fragmentShader);
    GL20.glAttachShader(shaderProgram,vertexShader);

    GL30.glBindFragDataLocation(shaderProgram,0,"fragcolor");
    GL20.glLinkProgram(shaderProgram);
    GL20.glUseProgram(shaderProgram);
    texture= GL11.glGenTextures();
    GL11.glBindTexture(GL11.GL_TEXTURE_2D,texture);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_WRAP_S, GL13.GL_CLAMP_TO_BORDER);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_WRAP_T,GL13.GL_CLAMP_TO_BORDER);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_MIN_FILTER,GL11.GL_LINEAR);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_MAG_FILTER,GL11.GL_LINEAR);

    ByteBuffer image;
    FloatBuffer verteces;
    IntBuffer imagewidth,imageheight, positions,imagechannels;
    try(MemoryStack memoryStack=MemoryStack.stackPush())
    {
        imageheight=memoryStack.mallocInt(1);
        imagewidth=memoryStack.mallocInt(1);
        positions=memoryStack.mallocInt(6);
        imagechannels=memoryStack.mallocInt(1);
        image= STBImage.stbi_load(texturePath_,imagewidth,imageheight,imagechannels,0);
        if(image==null) throw new NullPointerException("Failed to load image");
        verteces=memoryStack.mallocFloat(28);
    }
    positions.put(0).put(1).put(2).put(2).put(3).put(0).flip();
    int width=imagewidth.get();
    int height=imageheight.get();
    GL11.glTexImage2D(GL11.GL_TEXTURE_2D,0,GL11.GL_RGBA,width,height,0,GL11.GL_RGBA,GL11.GL_UNSIGNED_BYTE,image);


    elementBuffer=GL15.glGenBuffers();
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,elementBuffer);
    GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER,positions,GL15.GL_STATIC_DRAW);
    float x1=0f, x2=1f;
    float y1=1f,y2=-1f;

    verteces.put(x1).put(y1).put(1).put(1).put(1).put(0).put(0);
    verteces.put(x1).put(y2).put(1).put(1).put(1).put(1).put(0);
    verteces.put(x2).put(y2).put(1).put(1).put(1).put(1).put(1);
    verteces.put(x2).put(y1).put(1).put(1).put(1).put(0).put(1).flip();

    vertexBuffer=GL15.glGenBuffers();
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,vertexBuffer);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER,verteces,GL15.GL_STATIC_DRAW);
    int uniform=GL20.glGetUniformLocation(shaderProgram,"texture_image");
    GL20.glUniform1i(uniform,0);
    int position=GL20.glGetAttribLocation(shaderProgram,"position");
    GL20.glEnableVertexAttribArray(position);
    GL20.glVertexAttribPointer(position,2,GL11.GL_FLOAT,false,0,0);
    int color=GL20.glGetAttribLocation(shaderProgram,"color");
    GL20.glEnableVertexAttribArray(color);
    GL20.glVertexAttribPointer(color,3,GL11.GL_FLOAT,false,7*Float.BYTES, 2 * Float.BYTES);
    int textureST=GL20.glGetAttribLocation(shaderProgram,"textureCoord");
    GL20.glEnableVertexAttribArray(textureST);
    GL20.glVertexAttribPointer(textureST,3,GL11.GL_FLOAT,false,7*Float.BYTES,  5 * Float.BYTES);
    Utilities.showErrors(1);
}

结果是:

但我想要纹理占据所有区域。着色器编译正常,没有 GL 错误。 如果我将值更改为教程中的值:

verteces.put(-1f).put(1f).put(1).put(1).put(1).put(0).put(0);
verteces.put(1f).put(1f).put(1).put(1).put(1).put(1).put(0);
verteces.put(1f).put(-1f).put(1).put(1).put(1).put(1).put(1);
verteces.put(-1f).put(-1f).put(1).put(1).put(1).put(0).put(1).flip();

我得到:

教程:https://open.gl/textures and https://github.com/SilverTiger/lwjgl3-tutorial/wiki/Textures

我使用的是配置文件 3.0 和着色器版本 300 ES。纹理格式为PNG。

顶点属性布局:

GL20.glVertexAttribPointer(position,2,GL11.GL_FLOAT,false,0,0);
GL20.glVertexAttribPointer(color,3,GL11.GL_FLOAT,false,7*Float.BYTES, 2 * Float.BYTES);
GL20.glVertexAttribPointer(textureST,3,GL11.GL_FLOAT,false,7*Float.BYTES,  5 * Float.BYTES);

看起来不正确。它有多个问题:

  • 纹理坐标尝试从数组中读取 3 个浮点数。结合步幅,您的最后一个顶点将在 VBO 之外读取。很可能纹理坐标应该只读取 2 个浮点数。
  • 使用的浮点数总数 (2+3+3=8) 不适合每个顶点仅给出 7 个浮点数的数据。这在纹理坐标只读取两个浮点数时得到解决。
  • 位置的步幅看起来不对。 0 表示所有位置都紧密排列。基本上,位置使用 VBO 中的前 8 个浮点数。如果您查看它们:{-1, 1, 1, 1, 1, 0, 0, 1},那么这正是您所看到的几何图形。幸运的是它首先起作用了。解决方案:将位置布局更改为: GL20.glVertexAttribPointer(position,2,GL11.GL_FLOAT,false,7*Float.BYTES,0);