如何通过 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 中绘制内容的规范方法是:
将您依赖的每个状态设置为绘图所需的值。
然后画出来
很长一段时间 OpenGL 没有 VAO(顶点数组对象),实际上每次切换顶点缓冲区时都必须执行 glBindBuffer、glVertexAttribPointer 组合。大多数 OpenGL 驱动程序都在该代码路径中得到了很好的优化,事实上,当 VAO 被引入时,使用它们会损害性能。现在已经不是这样了,但以前是这样。
此外,您无法通过“节省”OpenGL 调用来提高性能。 OpenGL 不是 低级别的,并且在许多方面运行起来很像现代乱序执行 CPU:只要结果与将要执行的结果相同如果每个命令都已完成,则渲染它可以延迟和重新安排操作。
我正在尝试使用我自己的着色器和低级开放式 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 中绘制内容的规范方法是:
将您依赖的每个状态设置为绘图所需的值。
然后画出来
很长一段时间 OpenGL 没有 VAO(顶点数组对象),实际上每次切换顶点缓冲区时都必须执行 glBindBuffer、glVertexAttribPointer 组合。大多数 OpenGL 驱动程序都在该代码路径中得到了很好的优化,事实上,当 VAO 被引入时,使用它们会损害性能。现在已经不是这样了,但以前是这样。
此外,您无法通过“节省”OpenGL 调用来提高性能。 OpenGL 不是 低级别的,并且在许多方面运行起来很像现代乱序执行 CPU:只要结果与将要执行的结果相同如果每个命令都已完成,则渲染它可以延迟和重新安排操作。