2012-03-09 15 views
6

Chociaż mam podstawową wiedzę o OpenGL, dopiero zaczynam od libgdx.libgdx: SpriteBatch nie jest wyświetlany z PerspectiveCamera

Moje pytanie brzmi: dlaczego, posiadanie tego samego kodu, ale tylko przejście z OrthographicCamera na PerspectiveCamera powoduje, że nie wyświetla się już żadnego z moich SpriteBatches?

Oto kod używam: render() metoda

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();   
} 

i::

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();   
} 

Teraz, jeśli w moim resize (int width metoda

create() , int height) metoda Ustawiam kamerę tak:

public void resize(int width, int height) { 
     float aspectRatio = (float) width/(float) height; 
     camera = new OrthographicCamera(cameraViewHeight * aspectRatio, cameraViewHeight); 

uzyskać to:

enter image description here

Ale jeśli zmienię typ kamery:

public void resize(int width, int height) { 
    float aspectRatio = (float) width/(float) height; 
    camera = new PerspectiveCamera(64, cameraViewHeight * aspectRatio, cameraViewHeight); 
}  

uzyskać to:

enter image description here

Powód pytam jest ponieważ bardzo podobała mi się wbudowana w libgdx zdolność do rysowania tekstu (czcionki) w OpenGL. Ale w swoich przykładach używają SpriteBatch, które prowadzą do instancji Font, a także zawsze używają Ortho Camera. Chciałbym wiedzieć, czy funkcja SpriteBatch i rysowanie czcionek działa z PerspectiveCamera.

+0

Przy użyciu PerspectiveCamera myślę [Naklejka] (http://code.google.com/p/libgdx-users/wiki/Decals) i klasy DecalBatch są tym, co autorzy libgdx zamierzali użyć. – Sundae

+0

Kod zawiera zbyt długie wiersze (przewijanie kodu w poziomie nie jest fajne) (również w odpowiedzi) –

+0

przy okazji, myślę, że można po prostu użyć 2 kamer - wszystko, co robią, to ukrywanie "przerażających" obliczeń macierzowych za "prostymi" abstrakcje. –

Odpowiedz

4

No, ok, ja go rozwiązać:

Krótka odpowiedź:

SpriteBatch wykorzystuje OrthogonalPerspective wewnętrznie. Jeśli używasz PerspectiveCamera, musisz przekazać niestandardową macierz widoku do SpriteBatch. Można to zrobić w metodzie zmiany rozmiaru (...):

@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); 
} 

I wtedy nie trzeba robić nic innego z macierzy projekcji tego Sprite (chyba, że ​​chcesz zmienić sposób ikonki są wyświetlane na ekranie):

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

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

Długa odpowiedź: ponieważ mój ostatecznym celem było, aby móc korzystać z SpriteBatch do rysowania tekstu, podczas gdy z powyższej modyfikacji do mojego kodu mogę zrobić, że w tym sensie, że zarówno tekst na ikonki a siatka z teksturą jest teraz widoczna, zauważyłem, że jeśli nie określę koloru wierzchołków mojej siatki, to te wierzchołki będą miały kolor, którego używam dla tekstu. Innymi słowy, z zadeklarowaną siecią teksturowaną zadeklarowaną w ten sposób:

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}); 

również posiadającą ten kod w moim renderowaniu (...metoda) sprawi, że siatka czerwono barwione:

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

Rozwiązaniem tego problemu jest ustawienie kolorów na wierzchołkach sieci Mesh jest od samego początku:

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}); 
Powiązane problemy