GL11.glDrawElements不起作用

时间:2017-10-30 22:48:38

标签: opengl lwjgl

首先,我使用的是LWJGL 3和OpenGL 3.2

我试图使用"指数"使用GL11.glDrawElements函数,但窗口中没有任何渲染。

缓冲区生成代码(不是真的使用指示,但我认为它仍然可以工作):

public void updateBuffers(Game game, int positionsAttrib, int texCoordsAttrib) { // positionsAttrib and texCoordsAttrib are pointer to shader program attribs

    FloatBuffer positionsBuffer = null;
    FloatBuffer texCoordsBuffer = null;

    IntBuffer indicesBuffer = null;

    try {

        this.vertexCount = this.tiles.size() * 4;

        positionsBuffer = MemoryUtil.memAllocFloat( this.tiles.size() * 3 * 4 );
        texCoordsBuffer = MemoryUtil.memAllocFloat( this.tiles.size() * 2 * 4 );
        indicesBuffer = MemoryUtil.memAllocInt( this.vertexCount );

        int i = 0;

        for ( Entry<TilePosition, Tile> tilesEntry : this.tiles.entrySet() ) {

            TilePosition tilePosition = tilesEntry.getKey();
            Tile tile = tilesEntry.getValue();
            String tileTextureIdentifier = tile.getTextureIdentifier();
            TextureDefinition tileTextureDefinition = game.getTexturesManager().getTextureDefinition("tiles");
            Rectangle tileTextureRectangle = tileTextureDefinition.getTilePosition( tileTextureIdentifier );

            if ( tileTextureRectangle == null ) continue;

            positionsBuffer.put( tilePosition.getX() ).put( tilePosition.getY() + 1 ).put( 0 );
            positionsBuffer.put( tilePosition.getX() + 1 ).put( tilePosition.getY() + 1 ).put( 0 );
            positionsBuffer.put( tilePosition.getX() + 1 ).put( tilePosition.getY() ).put( 0 );
            positionsBuffer.put( tilePosition.getX() ).put( tilePosition.getY() ).put( 0 );

            texCoordsBuffer.put( tileTextureRectangle.x ).put( tileTextureRectangle.y );
            texCoordsBuffer.put( tileTextureRectangle.x + tileTextureRectangle.width ).put( tileTextureRectangle.y );
            texCoordsBuffer.put( tileTextureRectangle.x + tileTextureRectangle.width ).put( tileTextureRectangle.y + tileTextureRectangle.height );
            texCoordsBuffer.put( tileTextureRectangle.x ).put( tileTextureRectangle.y + tileTextureRectangle.height );

            indicesBuffer.put( i ).put( i + 1 ).put( i + 2 ).put( i + 3 );

            i += 4;

        }

        positionsBuffer.flip();
        texCoordsBuffer.flip();
        indicesBuffer.flip();

        this.vao.bind(); // vbo and vao are class VertexBufferObject and VertexArrayObject which save internal id of buffers and most usefull functions

        this.positionsVbo.bind( GL15.GL_ARRAY_BUFFER );
        VertexBufferObject.uploadData( GL15.GL_ARRAY_BUFFER, positionsBuffer, GL15.GL_STATIC_DRAW );
        ShaderProgram.pointVertexAttribute( positionsAttrib, 3, 0, 0 );

        this.texCoordsVbo.bind( GL15.GL_ARRAY_BUFFER );
        VertexBufferObject.uploadData( GL15.GL_ARRAY_BUFFER, texCoordsBuffer, GL15.GL_STATIC_DRAW );
        ShaderProgram.pointVertexAttribute( texCoordsAttrib, 2, 0, 0 );

        this.indicesVbo.bind( GL15.GL_ELEMENT_ARRAY_BUFFER );
        VertexBufferObject.uploadData( GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW );

        VertexArrayObject.unbind();

    } finally {

        if ( positionsBuffer != null ) MemoryUtil.memFree( positionsBuffer );
        if ( texCoordsBuffer != null ) MemoryUtil.memFree( texCoordsBuffer );
        if ( indicesBuffer != null ) MemoryUtil.memFree( indicesBuffer );

    }

}

使用过的着色器程序:

// scene.vs :

#version 330 // edit : I have to change this line because of OpenGL used version

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

out vec2 outTexCoord;

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;

void main() {

    mat4 mvp = projection * view * model;
    gl_Position = mvp * vec4( position, 1.0 );

    outTexCoord = texCoord;

}

// scene.fs :

#version 330

in vec2 outTexCoord;

out vec4 fragColor;

uniform sampler2D textureSampler;

void main() {

    vec3 vertexColor = vec3( 1.0, 1.0, 1.0 );

    vec4 textureColor = texture( textureSampler, outTexCoord );
    fragColor = vec4( vertexColor, 1.0 ) * textureColor;

}

渲染功能:

private void beginRender(Game game, int positionsAttrib, int texCoordsAttrib) {

    Texture texture = game.getTexturesManager().getTextureDefinition("tiles").getTexture();
    GL13.glActiveTexture( GL13.GL_TEXTURE0 );
    texture.bind();

    this.vao.bind();

    ShaderProgram.enableVertexAttribute( positionsAttrib );
    ShaderProgram.enableVertexAttribute( texCoordsAttrib );

}

private void endRender(Game game, int positionsAttrib, int texCoordsAttrib) {

    ShaderProgram.disableVertexAttribute( positionsAttrib );
    ShaderProgram.disableVertexAttribute( texCoordsAttrib );

    VertexArrayObject.unbind();

    Texture.unbind();

}

// render is called by render loop between clear and swapbuffer GL functions
public void render(Game game, int positionsAttrib, int texCoordsAttrib) {

    this.beginRender( game, positionsAttrib, texCoordsAttrib );

    GL11.glDrawElements( GL11.GL_QUADS, this.vertexCount, GL11.GL_UNSIGNED_INT, 0 );

    this.endRender( game, positionsAttrib, texCoordsAttrib );

}

我不确定它是否非常清楚,尤其是我的近似英语..

1 个答案:

答案 0 :(得分:2)

您没有明确说明它,但看起来您正在使用核心配置文件(如您所愿)。但是,如果是这样,GL_QUADS将无法使用,您的绘制调用只会导致GL_INVALID_ENUM错误。

作为旁注:既然你说你使用的是OpenGL 4.5,我强烈建议你在开发过程中使用OpenGL的debug output功能,它会更容易发现和解释任何GL错误,并可能进一步提供有用的表现提示。