libgdx:SpriteBatch não exibido com PerspectiveCamera
-
10-12-2019 - |
Pergunta
Embora eu tenha o conhecimento básico de OpenGL, estou apenas começando com libgdx.
Minha pergunta é:por que, ter exatamente o mesmo código, mas apenas mudar de OrthographicCamera para PerspectiveCamera tem o efeito de não exibir mais nenhum dos meus SpriteBatches?
Aqui está o código que eu uso:
o 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();
}
e o 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();
}
Agora, se no meu método resize(int width, int height) eu configurar a câmera assim:
public void resize(int width, int height) {
float aspectRatio = (float) width / (float) height;
camera = new OrthographicCamera(cameraViewHeight * aspectRatio, cameraViewHeight);
Eu entendi isso:
Mas se eu mudar o tipo de câmera:
public void resize(int width, int height) {
float aspectRatio = (float) width / (float) height;
camera = new PerspectiveCamera(64, cameraViewHeight * aspectRatio, cameraViewHeight);
}
Eu entendi isso:
A razão pela qual estou perguntando é porque eu realmente gostei da capacidade integrada do libgdx de desenhar texto (fonte) em OpenGL.Mas em seus exemplos eles usam um SpriteBatch que direcionam para a instância Font e também sempre usam Ortho Camera.Gostaria de saber se a funcionalidade de desenho SpriteBatch e Font funciona com PerspectiveCamera.
Solução
Bem, ok, resolvi:
Resposta curta:
SpriteBatch usa um OrthogonalPerspective internamente.Se você usar PerspectiveCamera, precisará passar uma matriz de visualização personalizada para o SpriteBatch.Você pode fazer isso no método 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);
}
E então não há necessidade de fazer mais nada com a matriz de projeção daquele sprite (a menos que você queira alterar a forma como o sprite é exibido na tela):
public void render() {
GLCommon gl = Gdx.gl;
camera.update();
camera.apply(Gdx.gl10);
//this is no longer needed:
//spriteBatch.setProjectionMatrix(camera.combined);
//...
Resposta longa:já que meu objetivo final era poder usar um SpriteBatch para desenhar texto, enquanto com a modificação mencionada acima em meu código eu posso fazer isso, no sentido de que tanto o texto no sprite quanto a malha com a textura agora estão visíveis, Percebi que se eu não especificar uma cor para os vértices da minha malha, esses vértices receberão a cor que uso para o texto.Em outras palavras, com uma malha texturizada declarada assim:
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});
também ter esse código no meu método render(...) deixará a malha vermelha:
font.setColor(Color.RED);
spriteBatch.draw(textureSpriteBatch, 0, 0);
font.draw(spriteBatch, (int)fps+" fps", 0, 100);
A solução para isso é definir cores nos vértices da sua malha desde o início:
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});