/******************************************************************************* * Copyright 2019 metaphore * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.crashinvaders.vfx.framebuffer; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.glutils.ShaderProgram; import com.badlogic.gdx.utils.Disposable; import com.crashinvaders.vfx.utils.ViewportQuadMesh; /** * Simple renderer that is capable of drawing * {@link VfxFrameBuffer}'s texture onto the screen or into another buffer. * <p> * This is a lightweight {@link com.badlogic.gdx.graphics.g2d.SpriteBatch} replacement for the library's needs. */ public class VfxFrameBufferRenderer implements Disposable { private final ViewportQuadMesh mesh; private final ShaderProgram shader; public VfxFrameBufferRenderer() { mesh = new ViewportQuadMesh(); shader = new ShaderProgram( "#ifdef GL_ES\n" + " #define PRECISION mediump\n" + " precision PRECISION float;\n" + "#else\n" + " #define PRECISION\n" + "#endif\n" + "attribute vec4 a_position;\n" + "attribute vec2 a_texCoord0;\n" + "varying vec2 v_texCoords;\n" + "void main() {\n" + " v_texCoords = a_texCoord0;\n" + " gl_Position = a_position;\n" + "}", "#ifdef GL_ES\n" + " #define PRECISION mediump\n" + " precision PRECISION float;\n" + "#else\n" + " #define PRECISION\n" + "#endif\n" + "varying vec2 v_texCoords;\n" + "uniform sampler2D u_texture0;\n" + "void main() {\n" + " gl_FragColor = texture2D(u_texture0, v_texCoords);\n" + "}" ); rebind(); } @Override public void dispose() { shader.dispose(); mesh.dispose(); } public void rebind() { shader.begin(); shader.setUniformi("u_texture0", 0); shader.end(); } public void renderToScreen(VfxFrameBuffer srcBuf) { renderToScreen(srcBuf.getTexture()); } public void renderToScreen(Texture srcTexture) { renderToScreen(srcTexture, 0, 0, Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight()); } public void renderToScreen(VfxFrameBuffer srcBuf, int x, int y, int width, int height) { renderToScreen(srcBuf.getTexture(), x, y, width, height); } public void renderToScreen(Texture srcTexture, int x, int y, int width, int height) { srcTexture.bind(0); // Update viewport to fit the area specified. Gdx.graphics.getGL20().glViewport(x, y, width, height); shader.begin(); mesh.render(shader); shader.end(); } public void renderToFbo(VfxFrameBuffer srcBuf, VfxFrameBuffer dstBuf) { renderToFbo(srcBuf.getTexture(), dstBuf); } public void renderToFbo(Texture srcTexture, VfxFrameBuffer dstBuf) { srcTexture.bind(0); // Viewport will be set from VfxFrameBuffer#begin() method. dstBuf.begin(); shader.begin(); mesh.render(shader); shader.end(); dstBuf.end(); } public ViewportQuadMesh getMesh() { return mesh; } }