1 /******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.tests; 18 19 import com.badlogic.gdx.Gdx; 20 import com.badlogic.gdx.graphics.GL20; 21 import com.badlogic.gdx.graphics.Mesh; 22 import com.badlogic.gdx.graphics.OrthographicCamera; 23 import com.badlogic.gdx.graphics.Pixmap.Format; 24 import com.badlogic.gdx.graphics.Texture; 25 import com.badlogic.gdx.graphics.VertexAttribute; 26 import com.badlogic.gdx.graphics.VertexAttributes.Usage; 27 import com.badlogic.gdx.graphics.glutils.FloatFrameBuffer; 28 import com.badlogic.gdx.graphics.glutils.FrameBuffer; 29 import com.badlogic.gdx.graphics.glutils.ShaderProgram; 30 import com.badlogic.gdx.math.Vector3; 31 import com.badlogic.gdx.tests.utils.GdxTest; 32 33 public class FloatTextureTest extends GdxTest { 34 FrameBuffer fb; 35 FloatFrameBuffer ffb; 36 ShaderProgram fbshader, shader; 37 Texture texture; 38 Mesh quad, screenQuad; 39 OrthographicCamera screenCamera; 40 41 @Override 42 public void create () { 43 fb = new FrameBuffer(Format.RGBA8888, 200, 100, false); 44 ffb = new FloatFrameBuffer(200, 100, false); 45 46 // @off 47 String vertexShader = 48 "attribute vec4 a_position; " 49 + "varying vec2 v_position; " 50 + "void main(){ " 51 + " v_position = a_position.xy; " 52 + " gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0); " 53 + "}"; 54 55 String fragmentShader = 56 "#ifdef GL_ES\n" 57 + "precision mediump float;\n" 58 + "#endif\n" + "uniform vec3 u_color;" 59 + "uniform vec2 u_viewport; " 60 + "void main(void){ " 61 + " vec2 uv = gl_FragCoord.xy/u_viewport; " 62 + " float res = mix(0.0, 0.0001, uv.x); " // <--- // regular (non-float) texture loses precision here, res == 0 for every fragment 63 + " gl_FragColor = vec4(u_color, res); " 64 + "}"; 65 66 fbshader = new ShaderProgram(vertexShader, fragmentShader); 67 68 vertexShader = 69 "attribute vec4 a_position; " 70 + "attribute vec4 a_color; " 71 + "attribute vec2 a_texCoords; " 72 + "uniform mat4 u_worldView; " 73 + "varying vec4 v_color; " 74 + "varying vec2 v_texCoords; " 75 + "void main() " 76 + "{ " 77 + " v_color = a_color; " 78 + " v_texCoords = a_texCoords; " 79 + " gl_Position = u_worldView * a_position; " 80 + "}"; 81 82 fragmentShader = 83 "#ifdef GL_ES\n" 84 + "precision mediump float;\n" 85 + "#endif\n" 86 + "varying vec2 v_texCoords; " 87 + "uniform sampler2D u_fbtex, u_ffbtex; " 88 + "vec4 getValue(vec4 col) {" 89 + " if (col.a > 0.00005)" 90 + " return vec4(col.rgb, 1.0);" 91 + " else" 92 + " return vec4(0.0, 0.0, 0.0, 1.0);" 93 + "}" 94 + "void main() " 95 + "{ " 96 + " if (v_texCoords.y < 0.45)" 97 + " gl_FragColor = getValue(texture2D(u_fbtex, v_texCoords)); " 98 + " else if (v_texCoords.y > 0.55)" 99 + " gl_FragColor = getValue(texture2D(u_ffbtex, v_texCoords)); " 100 + "}"; 101 // @on 102 103 shader = new ShaderProgram(vertexShader, fragmentShader); 104 createQuad(); 105 106 screenCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); 107 createScreenQuad(); 108 } 109 110 public void render () { 111 Gdx.gl20.glViewport(0, 0, Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight()); 112 Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT); 113 114 fb.begin(); 115 fbshader.begin(); 116 fbshader.setUniformf("u_viewport", fb.getWidth(), fb.getHeight()); 117 fbshader.setUniformf("u_color", 0.0f, 1.0f, 0.0f); 118 quad.render(fbshader, GL20.GL_TRIANGLES); 119 fbshader.end(); 120 fb.end(); 121 122 ffb.begin(); 123 fbshader.begin(); 124 fbshader.setUniformf("u_viewport", ffb.getWidth(), ffb.getHeight()); 125 fbshader.setUniformf("u_color", 1.0f, 0.0f, 0.0f); 126 quad.render(fbshader, GL20.GL_TRIANGLES); 127 fbshader.end(); 128 ffb.end(); 129 130 shader.begin(); 131 fb.getColorBufferTexture().bind(0); 132 ffb.getColorBufferTexture().bind(1); 133 shader.setUniformMatrix("u_worldView", screenCamera.combined); 134 shader.setUniformi("u_fbtex", 0); 135 shader.setUniformi("u_ffbtex", 1); 136 screenQuad.render(shader, GL20.GL_TRIANGLES); 137 shader.end(); 138 } 139 140 private void createQuad () { 141 if (quad != null) return; 142 quad = new Mesh(true, 4, 6, new VertexAttribute(Usage.Position, 3, "a_position"), new VertexAttribute(Usage.ColorUnpacked, 4, 143 "a_color"), new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords")); 144 145 quad.setVertices(new float[] {-1, -1, 0, 1, 1, 1, 1, 0, 1, 1, -1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, -1, 1, 0, 146 1, 1, 1, 1, 0, 0}); 147 quad.setIndices(new short[] {0, 1, 2, 2, 3, 0}); 148 } 149 150 private void createScreenQuad () { 151 if (screenQuad != null) return; 152 screenQuad = new Mesh(true, 4, 6, new VertexAttribute(Usage.Position, 3, "a_position"), new VertexAttribute(Usage.ColorUnpacked, 4, 153 "a_color"), new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords")); 154 155 Vector3 vec0 = new Vector3(0, 0, 0); 156 screenCamera.unproject(vec0); 157 Vector3 vec1 = new Vector3(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), 0); 158 screenCamera.unproject(vec1); 159 screenQuad.setVertices(new float[] {vec0.x, vec0.y, 0, 1, 1, 1, 1, 0, 1, vec1.x, vec0.y, 0, 1, 1, 1, 1, 1, 1, vec1.x, 160 vec1.y, 0, 1, 1, 1, 1, 1, 0, vec0.x, vec1.y, 0, 1, 1, 1, 1, 0, 0}); 161 screenQuad.setIndices(new short[] {0, 1, 2, 2, 3, 0}); 162 } 163 } 164