如何通过 libGDX 正确使用 open gl 调用

How to properly use open gl calls with libGDX

我正在尝试使用我自己的着色器和低级开放式 gl 方法来渲染地形。 但游戏的其他部分使用 SpriteBatch 和其他 GDXlib 渲染 类.

我的地形 openGL 代码可以正确渲染,直到我调用:

spriteBatch.draw(...);

或类似的东西:

stage.draw();

调用之后,我的 openGL 代码就不再绘制了。没有错误,只是屏幕上没有任何内容。 但是 SpriteBatch 工作正常。

很久以后,我发现我需要打电话给

glEnableVertexAttribArray(...);    

Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, posVertexBufferLoc);
Gdx.gl.glVertexAttribPointer(positionAttribLoc, 4, GL20.GL_FLOAT, false, 0, 0);

我需要在调用之前先调用它 -> glDrawArrays(...);

每次使用 glDraw 之前...,-> 每一帧

如果我不调用第一个,则不会呈现任何内容。

如果我不调用第二个,它会在错误的位置呈现。

看起来每次我使用 GDXlib 类 进行渲染时,它都会以某种方式弄乱我的属性。

初始化代码:

shaderProgram = new ShaderProgram(baseVertexShader, baseFragmentShader);
if (!shaderProgram.isCompiled()) {
    Gdx.app.error("TerrainRenderer - Cannot compile shader", shaderProgram.getLog());
}

shaderProgram.begin();

//vertexBuffers
vertexBuffer = BufferUtils.newFloatBuffer(quadPosVertices.length);
vertexBuffer.put(quadPosVertices);
vertexBuffer.rewind();
//VBOs
//generate buffers
posVertexBufferLoc = Gdx.gl.glGenBuffer();
//pass data into buffers
Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, posVertexBufferLoc);
Gdx.gl.glBufferData(GL20.GL_ARRAY_BUFFER, vertexBuffer.capacity()*4, vertexBuffer, GL20.GL_STATIC_DRAW);
//attributes
//locations
positionAttribLoc = shaderProgram.getAttributeLocation("position");
//attributes specifications
Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, posVertexBufferLoc);
Gdx.gl.glVertexAttribPointer(positionAttribLoc, 4, GL20.GL_FLOAT, false, 0, 0);
//enabling attributes
shaderProgram.enableVertexAttribute(positionAttribLoc);
//end shader
shaderProgram.end();
Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0); //unbind

抽奖代码:

Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, posVertexBufferLoc);
Gdx.gl.glVertexAttribPointer(positionAttribLoc, 4, GL20.GL_FLOAT, false, 0, 0);

shaderProgram.enableVertexAttribute(positionAttribLoc);

shaderProgram.begin();
Gdx.gl.glDrawArrays(GL20.GL_TRIANGLES, 0, 6);
shaderProgram.end();
Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0);

那么在 GDXlib 类 中使用 openGL 方法的正确方法是什么? 我真的需要每帧都调用那些属性函数吗?

OpenGL 是一个状态机。当 libGDX 使用 OpenGL 做某事时,它不可避免地会将 OpenGL 上下文的状态更改为不同的状态。

在 OpenGL 中绘制内容的规范方法是:

  1. 将您依赖的每个状态设置为绘图所需的值。

  2. 然后画出来

很长一段时间 OpenGL 没有 VAO(顶点数组对象),实际上每次切换顶点缓冲区时都必须执行 glBindBuffer、glVertexAttribPointer 组合。大多数 OpenGL 驱动程序都在该代码路径中得到了很好的优化,事实上,当 VAO 被引入时,使用它们会损害性能。现在已经不是这样了,但以前是这样。

此外,您无法通过“节省”OpenGL 调用来提高性能。 OpenGL 不是 低级别的,并且在许多方面运行起来很像现代乱序执行 CPU:只要结果与将要执行的结果相同如果每个命令都已完成,则渲染它可以延迟和重新安排操作。