Home | History | Annotate | Download | only in tests
      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