libgdx: 透视相机下 SpriteBatch 不显示

8

虽然我有OpenGL的基础知识,但我刚开始使用libgdx。

我的问题是:为什么只需将代码从OrthographicCamera切换到PerspectiveCamera,就会导致不再显示任何SpriteBatches?

这是我使用的代码:

create()方法:

public void create() {
    textureMesh = new Texture(Gdx.files.internal("data/texMeshTest.png"));
    textureSpriteBatch = new Texture(Gdx.files.internal("data/texSpriteBatchTest.png"));

    squareMesh = new Mesh(true, 4, 4, 
            new VertexAttribute(Usage.Position, 3, "a_position")
            ,new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords")

    );

    squareMesh.setVertices(new float[] {
            squareXInitial, squareYInitial, squareZInitial,             0,1,    //lower left
            squareXInitial+squareSize, squareYInitial, squareZInitial,  1,1,    //lower right
            squareXInitial, squareYInitial+squareSize, squareZInitial,  0,0,    //upper left
            squareXInitial+squareSize, squareYInitial+squareSize, squareZInitial,1,0});  //upper right 

    squareMesh.setIndices(new short[] { 0, 1, 2, 3});

    spriteBatch = new SpriteBatch();        
}

以及render()方法:

public void render() {
    GLCommon gl = Gdx.gl;

    camera.update();
    camera.apply(Gdx.gl10);
    spriteBatch.setProjectionMatrix(camera.combined);

    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    gl.glEnable(GL10.GL_DEPTH_TEST);

    gl.glEnable(GL10.GL_TEXTURE_2D);
    textureMesh.bind();
    squareMesh.render(GL10.GL_TRIANGLE_STRIP, 0, 4);

    spriteBatch.begin();
    spriteBatch.draw(textureSpriteBatch, -10, 0);
    spriteBatch.end();        
}

现在,如果我在我的resize(int width, int height)方法中这样设置摄像头:
   public void resize(int width, int height) {
        float aspectRatio = (float) width / (float) height;
        camera = new OrthographicCamera(cameraViewHeight * aspectRatio, cameraViewHeight);

我得到了这个:

在此输入图片描述

但如果我改变相机类型:
public void resize(int width, int height) {
    float aspectRatio = (float) width / (float) height;
    camera = new PerspectiveCamera(64, cameraViewHeight * aspectRatio, cameraViewHeight);
}       

我的问题是这样的:

enter image description here

我之所以问这个问题,是因为我非常喜欢libgdx内置的在OpenGL中绘制文本(字体)的功能。但是在它们的示例中,他们使用SpriteBatch将其路径到Font实例,并且始终使用正交相机。我想知道SpriteBatch和Font绘制功能是否与PerspectiveCamera兼容。


当使用PerspectiveCamera时,我认为Decal和DecalBatch类是libgdx作者想让我们使用的。 - Sundae
代码包含过长的行(水平滚动代码并不酷)
(答案中也是如此)
- Display Name
顺便说一句,我猜你可以简单地使用两个摄像头——它们所做的就是将“可怕”的矩阵计算隐藏在“简单”的抽象背后。 - Display Name
1个回答

4

好的,没问题,我来翻译一下:

简短回答:

SpriteBatch 内部使用正交透视。如果您使用 PerspectiveCamera,则需要向 SpriteBatch 传递自定义视图矩阵。您可以在 resize(...) 方法中执行此操作:

@Override
public void resize(int width, int height) {
    float aspectRatio = (float) width / (float) height;
    camera = new PerspectiveCamera(64, cameraViewHeight * aspectRatio, cameraViewHeight);
    viewMatrix = new Matrix4();
    viewMatrix.setToOrtho2D(0, 0,width, height);
    spriteBatch.setProjectionMatrix(viewMatrix);
}

然后就不需要对该精灵的投影矩阵进行任何其他操作了(除非您想更改精灵在屏幕上的显示方式):

public void render() {
    GLCommon gl = Gdx.gl;

    camera.update();
    camera.apply(Gdx.gl10);
    //this is no longer needed:
    //spriteBatch.setProjectionMatrix(camera.combined);
    //...

长话短说:我的最终目标是使用SpriteBatch来绘制文本,虽然通过以上修改代码我能够做到这一点,也就是说,精灵上的文本和纹理网格都显示出来了,但我发现,如果我不为网格的顶点指定颜色,则该顶点将获得我用于文本的颜色。换句话说,像这样声明一个纹理网格:

 squareMesh = new Mesh(true, 4, 4, 
            new VertexAttribute(Usage.Position, 3, "a_position")
            ,new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords")

    );

    squareMesh.setVertices(new float[] {
            squareXInitial, squareYInitial, squareZInitial,             0,1,    //lower left
            squareXInitial+squareSize, squareYInitial, squareZInitial,  1,1,    //lower right
            squareXInitial, squareYInitial+squareSize, squareZInitial,  0,0,    //upper left
            squareXInitial+squareSize, squareYInitial+squareSize, squareZInitial,1,0});  //upper right 

    squareMesh.setIndices(new short[] { 0, 1, 2, 3});

在我的render(...)方法中加入以下代码将使网格呈现红色:

font.setColor(Color.RED);
spriteBatch.draw(textureSpriteBatch, 0, 0);
font.draw(spriteBatch, (int)fps+" fps", 0, 100);

这个问题的解决方法是从一开始就在网格顶点上设置颜色:
squareMesh = new Mesh(true, 4, 4, 
        new VertexAttribute(Usage.Position, 3, "a_position")
        ,new VertexAttribute(Usage.ColorPacked, 4, "a_color")
        ,new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords")

);

squareMesh.setVertices(new float[] {
        squareXInitial, squareYInitial, squareZInitial,                         Color.toFloatBits(255, 255, 255, 255),  0,1,    //lower left
        squareXInitial+squareSize, squareYInitial, squareZInitial,              Color.toFloatBits(255, 255, 255, 255),  1,1,    //lower right
        squareXInitial, squareYInitial+squareSize, squareZInitial,              Color.toFloatBits(255, 255, 255, 255),  0,0,    //upper left
        squareXInitial+squareSize, squareYInitial+squareSize, squareZInitial,   Color.toFloatBits(255, 255, 255, 255),  1,0});  //upper right 

squareMesh.setIndices(new short[] { 0, 1, 2, 3});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接