2012-03-09 16 views
6

Anche se ho le conoscenze di base di OpenGL, sto iniziando solo con libgdx.libgdx: SpriteBatch non visualizzato con PerspectiveCamera

La mia domanda è: perché, avere lo stesso codice ma passare da OrthographicCamera a PerspectiveCamera ha l'effetto di non visualizzare più nessuno dei miei SpriteBatch?

Ecco il codice che uso:

il creare() Metodo:

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

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

Ora, se nel mio ridimensionamento (larghezza int , altezza int) metodo ho impostato la fotocamera in questo modo:

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

ottengo questo:

enter image description here

Ma se cambio il tipo di telecamera:

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

ottengo questo:

enter image description here

Il motivo che mi sto chiedendo è perché mi è veramente piaciuta la capacità di libgdx di disegnare testo (font) in OpenGL. Ma nei loro esempi usano uno SpriteBatch che indirizzano all'istanza Font, e usano sempre anche Ortho Camera. Mi piacerebbe sapere se le funzionalità di disegno di SpriteBatch e Font funzionano con PerspectiveCamera.

+0

Quando si utilizza il PerspectiveCamera credo che il [Decal] (http://code.google.com/p/libgdx-users/wiki/Decals) e le classi DecalBatch sono ciò che gli autori di libgdx intendevano usarci. – Sundae

+0

Il codice contiene troppe righe (il codice di scorrimento orizzontalmente non è bello) (anche nella risposta) –

+0

a proposito, suppongo che tu possa semplicemente usare 2 telecamere - tutto ciò che fanno è nascondere i calcoli a matrice "spaventoso" dietro "semplice" astrazioni. –

risposta

4

Beh, ok, ho risolto:

Risposta breve:

SpriteBatch utilizza un OrthogonalPerspective internamente. Se usi PerspectiveCamera devi passare una matrice di visualizzazione personalizzata a SpriteBatch. Si può fare nel metodo di ridimensionamento (...):

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

E poi non c'è bisogno di fare qualsiasi altra cosa con matrice di proiezione che di sprite (a meno che non si desidera cambiare il modo lo sprite viene visualizzata sullo schermo):

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

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

risposta lunga: dal momento che il mio obiettivo finale è stato quello di essere in grado di utilizzare uno SpriteBatch per disegnare il testo, mentre con le summenzionate modifiche al mio codice posso farlo, nel senso che sia il testo sul sprite e la mesh con la texture ora è visibile, ho notato che se non specifichi un colore per i vertici della mia mesh, detti vertici otterranno il colore che uso per il testo. In altre parole, con una mesh strutturata dichiarata in questo modo:

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

anche avere questo codice nel mio rendering (...metodo) farà la maglia rossa tinta:

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

La correzione a questo è di impostare i colori su vertici del tuo maglia fin dall'inizio:

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