2012-03-09 48 views
6

Si bien tengo los conocimientos básicos de OpenGL recién estoy comenzando con libgdx.libgdx: SpriteBatch no se muestra con PerspectiveCamera

Mi pregunta es: ¿por qué tener exactamente el mismo código pero solo cambiar de OrthographicCamera a PerspectiveCamera tiene el efecto de no mostrar ninguno de mis SpriteBatches?

Aquí está el código que utilizo:

el método 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();   
} 

y el método 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();   
} 

Ahora, si en mi cambio de tamaño (anchura int , int altura) método configuré la cámara como sigue:

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

me sale esto:

enter image description here

Pero si cambio el tipo de cámara:

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

me sale esto:

enter image description here

La razón por la que estoy pidiendo es porque realmente me gustó la capacidad de libgdx de dibujar texto (fuente) en OpenGL. Pero en sus ejemplos usan un SpriteBatch que dirigen a la instancia de Font, y también siempre usan Ortho Camera. Me gustaría saber si SpriteBatch y la funcionalidad de dibujo de fuentes funcionan con PerspectiveCamera.

+0

Cuando se utiliza el PerspectiveCamera creo que el [Etiqueta] (http://code.google.com/p/libgdx-users/wiki/Decals) y las clases DecalBatch son lo que los autores de libgdx quisieron que usáramos. – Sundae

+0

El código contiene líneas demasiado largas (el código de desplazamiento horizontal no es genial) (también en la respuesta) –

+0

por cierto, supongo que puede usar simplemente 2 cámaras: todo lo que hace es ocultar cálculos de matriz "de miedo" detrás de "simple" abstracciones –

Respuesta

4

Pues bien, lo solucioné:

Respuesta corta:

SpriteBatch utiliza un OrthogonalPerspective internamente. Si usa PerspectiveCamera, debe pasar una matriz de vista personalizada al SpriteBatch. Puede hacerlo en el método de cambio de tamaño (...):

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

Y entonces no hay necesidad de hacer cualquier otra cosa con matriz de proyección de que el sprite (a menos que desee cambiar cómo se muestra el sprite en la pantalla):

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

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

respuesta larga: ya que mi objetivo final iba a ser capaz de utilizar una SpriteBatch para dibujar texto, mientras que con la modificación anterior a mi código que pueda hacer eso, en el sentido de que tanto el texto en el sprite y la malla con la textura ahora es visible, me he dado cuenta de que si no especifico un color para los vértices de mi malla, dichos vértices obtendrán el color que uso para el texto. En otras palabras, con una malla texturizada declarada como tal:

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

que también tiene este código en mi procesamiento (...) Método hará que la malla roja teñida:

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

La solución a esto es establecer los colores de los vértices de la malla desde el principio:

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