Box2D灯光在scene2d actor之间渲染

时间:2016-03-22 14:18:31

标签: java opengl libgdx box2d scene2d

DUMB QUETION,但我无法删除..我已经解决了问题,我是个白痴......:D

我有演员的Libgdx scene2d舞台。我需要在actor之间渲染Box2D Lights (v.4.4),所以结构看起来像这样:

演员,演员,光明,光明,演员

我的舞台渲染:

Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
super.render();

stage.act();
stage.draw();

我的Box2D代码:

rayHandler = new RayHandler(world);
rayHandler.setShadows(false);

Box2D更新(我有一个调试矩阵,因为物理世界以世界坐标(米)呈现,然后我将它缩放到像素):

public void updateWorld(float deltaTime) {
world.step(deltaTime, 7, 7);

// i know that this is not optimized to be called on every frame
debugMatrix = new Matrix4(stage.getCamera().combined.cpy());
debugMatrix.scale(ratio, ratio, 1);

rayHandler.setCombinedMatrix(debugMatrix);
rayHandler.updateAndRender();
}

光明:

new PointLight(rayHandler, 128, null, 10, 0, 3);

好的,现在我就是这样做的:我有一个有一些演员的小组。我有另一个拥有UI的组,绘制在第一组之上。我在第一组绘图完成后立即调用updateWorld(),因此灯光将位于第一组的顶部,而位于第二组的后面。这是一个快速说明:

  

开始绘制舞台

     

演员组

     
      
  • 演员

  •   
  • 演员

  •   
  • 演员

  •   
     

调用Box2D渲染(我们在这里显示灯光)

     

UI组

     
      
  • UI Actor面板

  •   
  • UI Actor面板

  •   
  • UI Actor面板

  •   
     

结束舞台的绘制

结果如此(非常丑陋):

enter image description here

现在,如果我在舞台完成绘图后调用updateWorld()(不在演员之间),它的外观如下:

Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
super.render();

stage.act();
stage.draw();

updateWorld(deltaTime);

enter image description here

它看起来应该是它的外观,但它涵盖了舞台和UI。

现在,我们回到起点 - 再次在actor组之后调用updateWorld(),同时舞台渲染。我们修改了阶段批量的投影矩阵:

debugMatrix = new Matrix4(stage.getCamera().combined.cpy());
debugMatrix.scale(ratio, ratio, 1);

// this line was added
stage.getBatch().setProjectionMatrix(debugMatrix.cpy());

rayHandler.setCombinedMatrix(debugMatrix);
rayHandler.updateAndRender();

结果(光线仍然很酷,但场景2d坏了 - 来自UI的所有演员都不见了):

enter image description here

我已经测试了很多东西(我一直试图找到解决方案3天):

  • 我改变了投影和变换矩阵;

  • 更改矩阵,绘制灯光并恢复之前的矩阵;

  • 使用不同的相机和舞台和灯光的视频进行测试;

  • 还有很多其他的东西,包括舞台绘图,灯光批次和矩阵

我认为LibGDX在绘制舞台时会以某种方式改变OpenGL绘图。我不知道该怎么做,我不完全确定OpenGL是如何工作的。我如何让灯光看起来不错(比如屏幕截图2和3)?

更新 我知道我可以制作两个不同的阶段并在它们之间绘制灯光 - 这样就可以了,但我的结构要复杂得多(我只是简单地解释它)...所以我不能那样(或者我将需要4-5个不同的阶段,这是一个可怕的解决方案)

请不要提出不能解决问题的解决方案。 我不能使用着色器用于灯光,多个阶段,轻物体的导出图像等等...... 我需要解决这个问题:)

4 个答案:

答案 0 :(得分:1)

你的问题可能是因为你的AfterDrawListener每个给定演员的一个孩子被召唤一次(我假设你正在使用第六个锤子的修改过的scene2d)。无论如何,尝试检查后绘制事件是否来自同一个对象。

答案 1 :(得分:0)

我认为使用着色器可以提供更低级别的控制,我从未使用过box2d灯,但使用着色器的结果非常令人满意,完全可控并且还有优化空间。

答案 2 :(得分:0)

由于我不确定你想要达到的目的,只需要澄清一些:

  • 每次你绘制box2dlights光线处理程序时,实际上你在你之前绘制的上方绘制了一个黑色方块。这个黑色方块在特定区域是透明的(这些是"灯")。
  • 因此,如果您绘制多个光层,上层将使它们下面的层变暗
  • Box2dlights使用OpenGl着色器将这些黑色方块混合在场景上方。您还可以在此处实现自己的着色器
  • 因为这个,这里最有用的方法是只使用一个首先绘制的光层"游戏"演员,但低于你的用户界面

答案 3 :(得分:0)

感谢您的提问。 我也搜寻了答案,似乎找到了

public void draw (Batch batch, float parentAlpha)
     {
         batch.end ();
         rayHandler.updateAndRender ();
         batch.begin ();
     }