/*******************************************************************************
* 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.
******************************************************************************/
package com.badlogic.gdx.tests;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer20;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox;
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox.SelectBoxStyle;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.tests.utils.GdxTest;
import com.badlogic.gdx.tests.utils.PerspectiveCamController;
import com.badlogic.gdx.utils.GdxRuntimeException;
public class ProjectiveTextureTest extends GdxTest {
PerspectiveCamera cam;
PerspectiveCamera projector;
Texture texture;
Mesh plane;
Matrix4 planeTrans = new Matrix4();
Matrix4 cubeTrans = new Matrix4();
Matrix4 modelNormal = new Matrix4();
ShaderProgram projTexShader;
Stage ui;
Skin skin;
InputMultiplexer multiplexer = new InputMultiplexer();
PerspectiveCamController controller;
ImmediateModeRenderer20 renderer;
float angle = 0;
private SelectBox camera;
private Label fps;
@Override
public void create () {
setupScene();
setupUI();
setupShaders();
multiplexer.addProcessor(ui);
multiplexer.addProcessor(controller);
Gdx.input.setInputProcessor(multiplexer);
// renderer = new ImmediateModeRenderer20(false, true, 0);
}
public void setupScene () {
plane = new Mesh(true, 4, 6, new VertexAttribute(Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE), new VertexAttribute(
Usage.Normal, 3, ShaderProgram.NORMAL_ATTRIBUTE));
plane.setVertices(new float[] {-10, -1, 10, 0, 1, 0, 10, -1, 10, 0, 1, 0, 10, -1, -10, 0, 1, 0, -10, -1, -10, 0, 1, 0});
plane.setIndices(new short[] {3, 2, 1, 1, 0, 3});
texture = new Texture(Gdx.files.internal("data/badlogic.jpg"), Format.RGB565, true);
texture.setFilter(TextureFilter.MipMap, TextureFilter.Nearest);
cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
cam.position.set(0, 5, 10);
cam.lookAt(0, 0, 0);
cam.update();
controller = new PerspectiveCamController(cam);
projector = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
projector.position.set(2, 3, 2);
projector.lookAt(0, 0, 0);
projector.normalizeUp();
projector.update();
}
public void setupUI () {
ui = new Stage();
skin = new Skin(Gdx.files.internal("data/uiskin.json"));
TextButton reload = new TextButton("Reload Shaders", skin.get(TextButtonStyle.class));
camera = new SelectBox(skin.get(SelectBoxStyle.class));
camera.setItems("Camera", "Light");
fps = new Label("fps: ", skin.get(LabelStyle.class));
Table table = new Table();
table.setFillParent(true);
table.top().padTop(15);
table.add(reload).spaceRight(5);
table.add(camera).spaceRight(5);
table.add(fps);
ui.addActor(table);
reload.addListener(new ClickListener() {
public void clicked (InputEvent event, float x, float y) {
ShaderProgram prog = new ShaderProgram(Gdx.files.internal("data/shaders/projtex-vert.glsl").readString(), Gdx.files
.internal("data/shaders/projtex-frag.glsl").readString());
if (prog.isCompiled() == false) {
Gdx.app.log("GLSL ERROR", "Couldn't reload shaders:\n" + prog.getLog());
} else {
projTexShader.dispose();
projTexShader = prog;
}
}
});
}
public void setupShaders () {
ShaderProgram.pedantic = false;
projTexShader = new ShaderProgram(Gdx.files.internal("data/shaders/projtex-vert.glsl").readString(), Gdx.files.internal(
"data/shaders/projtex-frag.glsl").readString());
if (!projTexShader.isCompiled()) throw new GdxRuntimeException("Couldn't compile shader: " + projTexShader.getLog());
}
@Override
public void render () {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
angle += Gdx.graphics.getDeltaTime() * 20.0f;
cubeTrans.setToRotation(Vector3.Y, angle);
cam.update();
projector.update();
texture.bind();
projTexShader.begin();
if (camera.getSelectedIndex() == 0) {
renderMesh(projTexShader, cam.combined, projector.combined, planeTrans, plane, Color.WHITE);
/*
* TODO: Fix method rendering renderMesh(projTexShader, cam.combined, projector.combined, cubeTrans, cube, Color.WHITE);
*/
} else {
renderMesh(projTexShader, projector.combined, projector.combined, planeTrans, plane, Color.WHITE);
/*
* TODO: Fix method rendering renderMesh(projTexShader, projector.combined, projector.combined, cubeTrans, cube,
* Color.WHITE);
*/
}
projTexShader.end();
fps.setText("fps: " + Gdx.graphics.getFramesPerSecond());
ui.act();
ui.draw();
}
Vector3 position = new Vector3();
private void renderMesh (ShaderProgram shader, Matrix4 cam, Matrix4 projector, Matrix4 model, Mesh mesh, Color color) {
position.set(this.projector.position);
modelNormal.set(model).toNormalMatrix();
shader.setUniformMatrix("u_camera", cam);
shader.setUniformMatrix("u_projector", projector);
shader.setUniformf("u_projectorPos", position.x, position.y, position.z);
shader.setUniformMatrix("u_model", model);
shader.setUniformMatrix("u_modelNormal", modelNormal);
shader.setUniformf("u_color", color.r, color.g, color.b);
shader.setUniformi("u_texture", 0);
mesh.render(shader, GL20.GL_TRIANGLES);
}
@Override
public void dispose () {
texture.dispose();
plane.dispose();
projTexShader.dispose();
ui.dispose();
skin.dispose();
// renderer.dispose();
}
}