java - LibGDX: dibujar en FrameBuffer no funciona
opengl (5)
Así que estoy tratando de crear botones personalizados, para lo cual necesito combinar diferentes partes del fondo del botón. Para hacer esto, pensé que usar FrameBuffer funcionaría, pero no dio resultados viables. Por lo tanto, traté de probar mi método de dibujo FrameBuffer, escribiendo un método de prueba simple, que devuelve una textura que se dibuja en la pantalla en cada llamada de render (). Este método está aquí (tenga en cuenta que es un método de prueba, por lo que puede estar un poco mal optimizado):
private Texture test()
{
BitmapFont f = ReverseBlade.fontTitle;
f.setColor(Color.LIGHT_GRAY);
FrameBuffer fbo = new FrameBuffer(Format.RGBA8888, (int)f.getBounds("Hi").width, (int)f.getBounds("Hi").height, false);
Batch b = ReverseBlade.batch;
OrthographicCamera c = new OrthographicCamera(fbo.getWidth(), fbo.getHeight());
c.setToOrtho(false);
c.update();
b.setProjectionMatrix(c.combined);
fbo.begin();
b.begin();
f.draw(b, "Hi", 0, 0);
b.end();
fbo.end();
Texture t = fbo.getColorBufferTexture();
fbo.dispose();
b.setProjectionMatrix(ReverseBlade.camera.combined);
return t;
}
Sin embargo, no se muestra nada. La pantalla está oscura ... Lo he intentado sin la cámara y muchas otras variaciones que ya no puedo recordar. ¿Qué estoy haciendo mal?
Half Solution Lo que terminé teniendo que hacer es crear un nuevo objeto Matrix4 para FrameBuffer de esta manera:
Matrix4 m = new Matrix4();
m.setToOrtho2D(0, 0, fbo.getWidth(), fbo.getHeight());
batch.setProjectionMatrix(m);
Sin embargo, esto hace que todo lo que se dibuja esté al revés, así:
Creo que la llamada fbo.dispose()
está destruyendo más de lo que quieres.
Consulte la fuente y observe dónde destruye la textura de color, que es el resultado de getColorBufferTexture()
.
Creo que esto podría considerarse un error en Libgdx. La textura del color generalmente es algo que debería tener una vida útil muy diferente a la del FBO, por lo que limpiar la textura parece demasiado agresivo. Sin embargo, tratar de descubrir qué casos limpiar la textura es probablemente complicado ...
Entonces, siguiendo lo que agregué con Half Solution, todo lo que tuve que hacer fue crear un nuevo objeto Sprite con la textura del FBo y call flip (falso, verdadero).
Puede ser que esto sea una solución alternativa para eliminar () el framebuffer y mantener viva la textura. Yo hago lo siguiente:
public class TextureSaveFBO extends FrameBuffer {
static final Texture DUMMY = new Texture(1, 1, Format.RGB565) {
public void dispose() {
};
};
public TextureSaveFBO(Format format, int width, int height,
boolean hasDepth) {
super(format, width, height, hasDepth);
}
@Override
public void dispose() {
// prevents the real texture of dispose()
Texture t = colorTexture;
colorTexture = DUMMY;
super.dispose();
colorTexture = t;
}
}
Solo una precisión:
OrthographicCamera c = new OrthographicCamera(fbo.getWidth(), fbo.getHeight());
c.setToOrtho(false);
Esto es potencialmente dañino a menos que sepa lo que está haciendo: c.setOrtho(false)
hace lo siguiente:
Establece esta cámara en una proyección ortográfica usando una ventana gráfica que se ajusta a la resolución de la pantalla, centrada en (Gdx.graphics.getWidth () / 2, Gdx.graphics.getHeight () / 2), con el eje y apuntando hacia arriba o hacia abajo.
Entonces, incluso si especificó en el constructor de OrthographicCamera que desea que la ventana gráfica sea del tamaño del búfer de cuadros, está sobreescribiendo eso con la siguiente llamada a una ventana gráfica que cubre el tamaño de la pantalla y centrada en el centro de la pantalla.
Probablemente deberías:
camera.setToOrtho(false, fbo.getWidth(), fbo.getHeight());
Problema resuelto desde LibGDX 1.6.5.
Ahora es posible anular el método disposeColorBuffer para no eliminar la textura procesada.