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 * Copyright 2010 Mario Zechner (contact@badlogicgames.com), Nathan Sweet (admin@esotericsoftware.com) 18 * 19 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the 20 * License. You may obtain a copy of the License at 21 * 22 * http://www.apache.org/licenses/LICENSE-2.0 23 * 24 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" 25 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language 26 * governing permissions and limitations under the License. 27 */ 28 29 package com.badlogic.gdx.tests; 30 31 import com.badlogic.gdx.Gdx; 32 import com.badlogic.gdx.Graphics; 33 import com.badlogic.gdx.graphics.Color; 34 import com.badlogic.gdx.graphics.GL20; 35 import com.badlogic.gdx.graphics.Mesh; 36 import com.badlogic.gdx.graphics.Pixmap.Format; 37 import com.badlogic.gdx.graphics.Texture; 38 import com.badlogic.gdx.graphics.VertexAttribute; 39 import com.badlogic.gdx.graphics.VertexAttributes.Usage; 40 import com.badlogic.gdx.graphics.g2d.SpriteBatch; 41 import com.badlogic.gdx.graphics.glutils.FrameBuffer; 42 import com.badlogic.gdx.graphics.glutils.ShaderProgram; 43 import com.badlogic.gdx.tests.utils.GdxTest; 44 45 /** 46 * Draws a triangle and a trapezoid. The trapezoid is intersection between two triangles, one stencil 47 * and the triangle shown on left. 48 */ 49 public class FrameBufferTest extends GdxTest { 50 FrameBuffer stencilFrameBuffer; 51 FrameBuffer frameBuffer; 52 Mesh mesh; 53 54 Mesh stencilMesh; 55 ShaderProgram meshShader; 56 Texture texture; 57 SpriteBatch spriteBatch; 58 59 @Override render()60 public void render () { 61 frameBuffer.begin(); 62 Gdx.gl20.glViewport(0, 0, frameBuffer.getWidth(), frameBuffer.getHeight()); 63 Gdx.gl20.glClearColor(0f, 1f, 0f, 1); 64 Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT); 65 Gdx.gl20.glEnable(GL20.GL_TEXTURE_2D); 66 texture.bind(); 67 meshShader.begin(); 68 meshShader.setUniformi("u_texture", 0); 69 mesh.render(meshShader, GL20.GL_TRIANGLES); 70 meshShader.end(); 71 frameBuffer.end(); 72 73 stencilFrameBuffer.begin(); 74 Gdx.gl20.glViewport(0, 0, frameBuffer.getWidth(), frameBuffer.getHeight()); 75 Gdx.gl20.glClearColor(1f, 1f, 0f, 1); 76 Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_STENCIL_BUFFER_BIT); 77 Gdx.gl20.glEnable(GL20.GL_TEXTURE_2D); 78 79 Gdx.gl20.glEnable(GL20.GL_STENCIL_TEST); 80 81 Gdx.gl20.glColorMask(false, false, false, false); 82 Gdx.gl20.glDepthMask(false); 83 Gdx.gl20.glStencilFunc(GL20.GL_NEVER, 1, 0xFF); 84 Gdx.gl20.glStencilOp(GL20.GL_REPLACE, GL20.GL_KEEP, GL20.GL_KEEP); 85 86 Gdx.gl20.glStencilMask(0xFF); 87 Gdx.gl20.glClear(GL20.GL_STENCIL_BUFFER_BIT); 88 89 meshShader.begin(); 90 stencilMesh.render(meshShader, GL20.GL_TRIANGLES); 91 meshShader.end(); 92 93 Gdx.gl20.glColorMask(true, true, true, true); 94 Gdx.gl20.glDepthMask(true); 95 Gdx.gl20.glStencilMask(0x00); 96 Gdx.gl20.glStencilFunc(GL20.GL_EQUAL, 1, 0xFF); 97 98 meshShader.begin(); 99 mesh.render(meshShader, GL20.GL_TRIANGLES); 100 meshShader.end(); 101 102 Gdx.gl20.glDisable(GL20.GL_STENCIL_TEST); 103 stencilFrameBuffer.end(); 104 105 Gdx.gl20.glViewport(0, 0, Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight()); 106 Gdx.gl20.glClearColor(0.2f, 0.2f, 0.2f, 1); 107 Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT); 108 109 spriteBatch.begin(); 110 spriteBatch.draw(frameBuffer.getColorBufferTexture(), 0, 0, 256, 256, 0, 0, frameBuffer.getColorBufferTexture().getWidth(), 111 frameBuffer.getColorBufferTexture().getHeight(), false, true); 112 113 spriteBatch.draw(stencilFrameBuffer.getColorBufferTexture(), 256, 256, 256, 256, 0, 0, frameBuffer.getColorBufferTexture() 114 .getWidth(), frameBuffer.getColorBufferTexture().getHeight(), false, true); 115 spriteBatch.end(); 116 } 117 118 @Override create()119 public void create () { 120 mesh = new Mesh(true, 3, 0, new VertexAttribute(Usage.Position, 3, "a_Position"), new VertexAttribute(Usage.ColorPacked, 4, 121 "a_Color"), new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords")); 122 float c1 = Color.toFloatBits(255, 0, 0, 255); 123 float c2 = Color.toFloatBits(255, 0, 0, 255); 124 float c3 = Color.toFloatBits(0, 0, 255, 255); 125 126 mesh.setVertices(new float[] {-0.5f, -0.5f, 0, c1, 0, 0, 0.5f, -0.5f, 0, c2, 1, 0, 0, 0.5f, 0, c3, 0.5f, 1}); 127 128 stencilMesh = new Mesh(true, 3, 0, new VertexAttribute(Usage.Position, 3, "a_Position"), new VertexAttribute( 129 Usage.ColorPacked, 4, "a_Color"), new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords")); 130 stencilMesh.setVertices(new float[] {-0.5f, 0.5f, 0, c1, 0, 0, 0.5f, 0.5f, 0, c2, 1, 0, 0, -0.5f, 0, c3, 0.5f, 1}); 131 132 texture = new Texture(Gdx.files.internal("data/badlogic.jpg")); 133 134 spriteBatch = new SpriteBatch(); 135 frameBuffer = new FrameBuffer(Format.RGB565, 128, 128, false); 136 stencilFrameBuffer = new FrameBuffer(Format.RGB565, 128, 128, false, true); 137 createShader(Gdx.graphics); 138 } 139 createShader(Graphics graphics)140 private void createShader (Graphics graphics) { 141 String vertexShader = "attribute vec4 a_Position; \n" + "attribute vec4 a_Color;\n" + "attribute vec2 a_texCoords;\n" 142 + "varying vec4 v_Color;" + "varying vec2 v_texCoords; \n" + 143 144 "void main() \n" + "{ \n" + " v_Color = a_Color;" 145 + " v_texCoords = a_texCoords;\n" + " gl_Position = a_Position; \n" + "} \n"; 146 String fragmentShader = "#ifdef GL_ES\n" + "precision mediump float;\n" + "#endif\n" + "varying vec4 v_Color;\n" 147 + "varying vec2 v_texCoords; \n" + "uniform sampler2D u_texture;\n" + 148 149 "void main() \n" + "{ \n" 150 + " gl_FragColor = v_Color * texture2D(u_texture, v_texCoords);\n" + "}"; 151 152 meshShader = new ShaderProgram(vertexShader, fragmentShader); 153 if (meshShader.isCompiled() == false) throw new IllegalStateException(meshShader.getLog()); 154 } 155 156 @Override dispose()157 public void dispose () { 158 mesh.dispose(); 159 texture.dispose(); 160 frameBuffer.dispose(); 161 stencilFrameBuffer.dispose(); 162 stencilMesh.dispose(); 163 spriteBatch.dispose(); 164 meshShader.dispose(); 165 } 166 167 } 168