Libgdx 如何在一个屏幕上使用SpriteBatch和ShaperEnder?
我正在使用SpriteBatch绘制纹理,ShaperEnder绘制一些形状 这是我的演员代码Libgdx 如何在一个屏幕上使用SpriteBatch和ShaperEnder?,libgdx,Libgdx,我正在使用SpriteBatch绘制纹理,ShaperEnder绘制一些形状 这是我的演员代码 @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_AL
@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)
编辑:有关我正在做的更多详细信息:
我想要的是画一个形状。因为舞台的批次正在绘制,所以我必须结束它以绘制形状。我的代码仍然有效,但有时,另一个演员,我认为,使用阶段的批处理来绘制其他东西。它使舞台开始批量生产。因此,开始和结束之间存在冲突
例如,参与者绘制方法:
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()
batch.end();
//绘图形状
batch.begin()(其他地方)@Override
公共作废提取(批处理、浮动parentAlpha){
batch.end();就像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();
如果在打开新渲染器之前未关闭所有渲染器,则将获得一个没有先前渲染器的视图
spriteBatch.begin()
... // render Textures
shapeRenderer.begin()
... // render Shapes
shapeRenderer.close()
spriteBatch.close()
这将导致屏幕上没有spriteBatch纹理---
您已经通过使用代码解决了此问题
@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
}
但是在第一批.end()中,您的代码无法找到任何可以关闭的打开的spriteBatch,因此您会得到一个非法状态异常
你必须打电话
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();
}
...
}
我知道这是我的老问题,但我可以看到使用libgdx的新用户也面临着这个错误。因此我将我的解决方法作为一个答案发布:
问题是,两者之间有某种突破
batch.begin()
及
当舞台画
因此,如果您使用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{}中,draw方法在actor中。我想要的是end stage的批处理(绘制某些内容)为了绘制一个形状,然后稍后再开始。我的代码仍然有效,但有时,另一个参与者,我认为,使用stage的批处理来绘制其他内容。它使stage开始其批处理。因此,begin和end.batch.end()…batch.begin()(某处)…batch.begin()之间存在冲突所有其他答案都是错误的,因为他们没有注意到您的代码在演员的绘图方法中,但哇,如果这不是一个丑陋的黑客行为的话。您最初的问题几乎肯定是因为错过了对batch.end()
的调用或额外调用了batch.begin())
。您在原始问题中发布的实际代码不会是罪魁祸首。LibGDX不会进行任何异步绘制。@Tenfour04事实上,我的代码的问题是因为旧版本GlyphLayout已经修复。它打破了stage的draw方法中的循环,因此stage无法调用batch.end()
调用批处理.begin()时,所有错误都发生了。
下一帧
batch.end()
@Override
public void render(float delta) {
try {
stage.act(delta)
stage.draw()
} catch (Exception ex) {
if(stage.batch.isDrawing)
stage.batch.end()
}
}