纹理渲染不正确(OpenGL)

时间:2018-01-15 07:28:56

标签: java opengl java-8 lwjgl

我一直试图渲染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);
}

结果是:enter image description here

但我喜欢纹理占据所有区域。着色器编译正常,没有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();

我得到:enter image description here

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

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

1 个答案:

答案 0 :(得分:1)

顶点属性布局:

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);