/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* 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.
******************************************************************************/
/*
* Copyright 2010 Mario Zechner (contact@badlogicgames.com), Nathan Sweet (admin@esotericsoftware.com)
*
* 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.badlogic.gdx.tests;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Graphics;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.tests.utils.GdxTest;
/**
* Draws a triangle and a trapezoid. The trapezoid is intersection between two triangles, one stencil
* and the triangle shown on left.
*/
public class FrameBufferTest extends GdxTest {
FrameBuffer stencilFrameBuffer;
FrameBuffer frameBuffer;
Mesh mesh;
Mesh stencilMesh;
ShaderProgram meshShader;
Texture texture;
SpriteBatch spriteBatch;
@Override
public void render () {
frameBuffer.begin();
Gdx.gl20.glViewport(0, 0, frameBuffer.getWidth(), frameBuffer.getHeight());
Gdx.gl20.glClearColor(0f, 1f, 0f, 1);
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl20.glEnable(GL20.GL_TEXTURE_2D);
texture.bind();
meshShader.begin();
meshShader.setUniformi("u_texture", 0);
mesh.render(meshShader, GL20.GL_TRIANGLES);
meshShader.end();
frameBuffer.end();
stencilFrameBuffer.begin();
Gdx.gl20.glViewport(0, 0, frameBuffer.getWidth(), frameBuffer.getHeight());
Gdx.gl20.glClearColor(1f, 1f, 0f, 1);
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_STENCIL_BUFFER_BIT);
Gdx.gl20.glEnable(GL20.GL_TEXTURE_2D);
Gdx.gl20.glEnable(GL20.GL_STENCIL_TEST);
Gdx.gl20.glColorMask(false, false, false, false);
Gdx.gl20.glDepthMask(false);
Gdx.gl20.glStencilFunc(GL20.GL_NEVER, 1, 0xFF);
Gdx.gl20.glStencilOp(GL20.GL_REPLACE, GL20.GL_KEEP, GL20.GL_KEEP);
Gdx.gl20.glStencilMask(0xFF);
Gdx.gl20.glClear(GL20.GL_STENCIL_BUFFER_BIT);
meshShader.begin();
stencilMesh.render(meshShader, GL20.GL_TRIANGLES);
meshShader.end();
Gdx.gl20.glColorMask(true, true, true, true);
Gdx.gl20.glDepthMask(true);
Gdx.gl20.glStencilMask(0x00);
Gdx.gl20.glStencilFunc(GL20.GL_EQUAL, 1, 0xFF);
meshShader.begin();
mesh.render(meshShader, GL20.GL_TRIANGLES);
meshShader.end();
Gdx.gl20.glDisable(GL20.GL_STENCIL_TEST);
stencilFrameBuffer.end();
Gdx.gl20.glViewport(0, 0, Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight());
Gdx.gl20.glClearColor(0.2f, 0.2f, 0.2f, 1);
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
spriteBatch.begin();
spriteBatch.draw(frameBuffer.getColorBufferTexture(), 0, 0, 256, 256, 0, 0, frameBuffer.getColorBufferTexture().getWidth(),
frameBuffer.getColorBufferTexture().getHeight(), false, true);
spriteBatch.draw(stencilFrameBuffer.getColorBufferTexture(), 256, 256, 256, 256, 0, 0, frameBuffer.getColorBufferTexture()
.getWidth(), frameBuffer.getColorBufferTexture().getHeight(), false, true);
spriteBatch.end();
}
@Override
public void create () {
mesh = new Mesh(true, 3, 0, new VertexAttribute(Usage.Position, 3, "a_Position"), new VertexAttribute(Usage.ColorPacked, 4,
"a_Color"), new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords"));
float c1 = Color.toFloatBits(255, 0, 0, 255);
float c2 = Color.toFloatBits(255, 0, 0, 255);
float c3 = Color.toFloatBits(0, 0, 255, 255);
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});
stencilMesh = new Mesh(true, 3, 0, new VertexAttribute(Usage.Position, 3, "a_Position"), new VertexAttribute(
Usage.ColorPacked, 4, "a_Color"), new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords"));
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});
texture = new Texture(Gdx.files.internal("data/badlogic.jpg"));
spriteBatch = new SpriteBatch();
frameBuffer = new FrameBuffer(Format.RGB565, 128, 128, false);
stencilFrameBuffer = new FrameBuffer(Format.RGB565, 128, 128, false, true);
createShader(Gdx.graphics);
}
private void createShader (Graphics graphics) {
String vertexShader = "attribute vec4 a_Position; \n" + "attribute vec4 a_Color;\n" + "attribute vec2 a_texCoords;\n"
+ "varying vec4 v_Color;" + "varying vec2 v_texCoords; \n" +
"void main() \n" + "{ \n" + " v_Color = a_Color;"
+ " v_texCoords = a_texCoords;\n" + " gl_Position = a_Position; \n" + "} \n";
String fragmentShader = "#ifdef GL_ES\n" + "precision mediump float;\n" + "#endif\n" + "varying vec4 v_Color;\n"
+ "varying vec2 v_texCoords; \n" + "uniform sampler2D u_texture;\n" +
"void main() \n" + "{ \n"
+ " gl_FragColor = v_Color * texture2D(u_texture, v_texCoords);\n" + "}";
meshShader = new ShaderProgram(vertexShader, fragmentShader);
if (meshShader.isCompiled() == false) throw new IllegalStateException(meshShader.getLog());
}
@Override
public void dispose () {
mesh.dispose();
texture.dispose();
frameBuffer.dispose();
stencilFrameBuffer.dispose();
stencilMesh.dispose();
spriteBatch.dispose();
meshShader.dispose();
}
}