我使用SpriteBatch绘制纹理,使用ShapeRenderer绘制一些形状。
这是我在演员中的代码
@Override
public void draw(Batch batch, float parentAlpha) {
batch.end();
Gdx.gl.glEnable(GL20.GL_ARRAY_BUFFER_BINDING);
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
shapeRenderer.begin(ShapeType.Filled);
//change color
shapeRenderer.setColor(color);
shapeRenderer.rect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
shapeRenderer.end();
Gdx.gl.glDisable(GL20.GL_BLEND);
batch.begin();
}
并在屏幕上调用stage.draw()
@Override
public void render(float delta) {
Gdx.gl20.glClearColor(0, 0, 0, 0);
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
Gdx.gl20.glEnable(GL20.GL_TEXTURE_2D);
stage.act(delta);
stage.draw();
//......
}
它工作但不可预测地抛出异常:
STACK_TRACE=java.lang.IllegalStateException: SpriteBatch.end must be called before begin.
at com.badlogic.gdx.graphics.g2d.SpriteBatch.begin(SpriteBatch.java:164)
at com.badlogic.gdx.scenes.scene2d.Stage.draw(Stage.java:127)
at c.i.a.a(AbstractCardRoomRenderer.java:3078)
at c.i.s.a(TLMNCardRoomRenderer.java:1158)
at c.j.e.render(GameScreen.java:22)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(AndroidGraphics.java:422)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1522)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1239)
编辑:有关我正在做的更多详情:
我想要的是画一个形状。因为舞台的批次正在绘制所以我必须结束它以进行形状绘制。我的代码仍然可以工作,但有时候,另一个演员,我认为,使用stage的批处理来绘制其他内容。它使舞台开始批量生产。所以它在开始和结束之间发生冲突。
例如,actor绘制方法:
batch.end();
//drawing shapes
batch.begin() (somewhere else) <--- I think this code is call when stage call draw on other actor
//drawing completed
batch.begin()
编辑: 如果其他人&#39;答案不适合你,请考虑我的解决方法我在下面发布答案。
答案 0 :(得分:9)
@Override
public void draw(Batch batch, float parentAlpha) {
batch.end(); <--
Gdx.gl.glEnable(GL20.GL_ARRAY_BUFFER_BINDING);
../// other code
shapeRenderer.end();
Gdx.gl.glDisable(GL20.GL_BLEND);
batch.begin(); <--
我认为错误在于您在batch.end ()
尝试更改订单之前调用bacth.begin ();
public void draw (Batch batch, float parentAlpha)
答案 1 :(得分:3)
如果在打开新渲染器之前没有关闭所有渲染器,您将获得一个没有前一个渲染器的视图
spriteBatch.begin()
... // render Textures
shapeRenderer.begin()
... // render Shapes
shapeRenderer.close()
spriteBatch.close()
这会导致屏幕没有你的spriteBatch-Textures --- 您已经通过将代码用于此
来解决了这个问题 @Override
public void draw(Batch batch, float parentAlpha) {
batch.end(); // close A
...
shapeRenderer.begin(ShapeType.Filled); // open B
...
shapeRenderer.end(); // close B
batch.begin(); // open A
}
但是在第一个batch.end()中你的代码无法找到任何可以关闭的打开的spriteBatch,因此你得到一个IllegalStateException
你必须致电
batch.begin()在使用end() - 方法之前一次 (但要注意,你不应该每一帧都开始批处理)
我建议解决此问题的最简单的解决方案如下:
class MyActor{
private boolean firstDraw = true;
@Override
public void draw(Batch batch, float parentAlpha) {
if(firstDraw)
{
batch.begin();
firstDraw=false;
}
batch.end();
Gdx.gl.glEnable(GL20.GL_ARRAY_BUFFER_BINDING);
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
shapeRenderer.begin(ShapeType.Filled);
//change color
shapeRenderer.setColor(color);
shapeRenderer.rect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
shapeRenderer.end();
Gdx.gl.glDisable(GL20.GL_BLEND);
batch.begin();
}
...
}
答案 2 :(得分:0)
就像Angel * 2所说,你的错误来自于.begin之前调用.end。使用多个绘图批次是完全可能的并且经常使用,但您必须按顺序使用它们并正确地开始/结束它们。以下代码有效:
spriteBatch.begin();
spriteBatch.draw(..);
//more draw calls for this spritebatch
spriteBatch.end();
shapeRenderer.begin(..);
shapeRenderer.line(..);
//more draw calls for shaperenderer go here
shapeRenderer.end();
anotherSpriteBatch.begin();
anotherSpriteBatch.draw(..);
anotherSpriteBatch.end();
//You can also use the same batch again.
shapeRenderer.begin(..);
shapeRenderer.circle(..);
shapeRenderer.close();
答案 3 :(得分:0)
我知道这是我的老问题,但我可以看到还有新人使用libgdx也面临这个错误。所以我发布我的解决方法作为答案:
问题在于
之间存在某些中断batch.begin()
和
batch.end()
舞台绘图时
因此,如果您使用Stage来管理批次,那么try-catch可以节省您的时间:
@Override
public void render(float delta) {
try {
stage.act(delta)
stage.draw()
} catch (Exception ex) {
if(stage.batch.isDrawing)
stage.batch.end()
}
}
**这只是绕过框架中的一些意外错误(例如glyphlayout)的一种解决方法,它应该在下一帧中正常工作。如果您的代码或资源中存在任何实际问题,您的渲染代码将最终出现在catch {}
中