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.InputMultiplexer; 21 import com.badlogic.gdx.graphics.Color; 22 import com.badlogic.gdx.graphics.GL20; 23 import com.badlogic.gdx.graphics.Mesh; 24 import com.badlogic.gdx.graphics.PerspectiveCamera; 25 import com.badlogic.gdx.graphics.Pixmap.Format; 26 import com.badlogic.gdx.graphics.Texture; 27 import com.badlogic.gdx.graphics.Texture.TextureFilter; 28 import com.badlogic.gdx.graphics.VertexAttribute; 29 import com.badlogic.gdx.graphics.VertexAttributes.Usage; 30 import com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer20; 31 import com.badlogic.gdx.graphics.glutils.ShaderProgram; 32 import com.badlogic.gdx.math.Matrix4; 33 import com.badlogic.gdx.math.Vector3; 34 import com.badlogic.gdx.scenes.scene2d.InputEvent; 35 import com.badlogic.gdx.scenes.scene2d.Stage; 36 import com.badlogic.gdx.scenes.scene2d.ui.Label; 37 import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle; 38 import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; 39 import com.badlogic.gdx.scenes.scene2d.ui.SelectBox.SelectBoxStyle; 40 import com.badlogic.gdx.scenes.scene2d.ui.Skin; 41 import com.badlogic.gdx.scenes.scene2d.ui.Table; 42 import com.badlogic.gdx.scenes.scene2d.ui.TextButton; 43 import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle; 44 import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; 45 import com.badlogic.gdx.tests.utils.GdxTest; 46 import com.badlogic.gdx.tests.utils.PerspectiveCamController; 47 import com.badlogic.gdx.utils.GdxRuntimeException; 48 49 public class ProjectiveTextureTest extends GdxTest { 50 51 PerspectiveCamera cam; 52 PerspectiveCamera projector; 53 Texture texture; 54 Mesh plane; 55 Matrix4 planeTrans = new Matrix4(); 56 Matrix4 cubeTrans = new Matrix4(); 57 Matrix4 modelNormal = new Matrix4(); 58 ShaderProgram projTexShader; 59 Stage ui; 60 Skin skin; 61 InputMultiplexer multiplexer = new InputMultiplexer(); 62 PerspectiveCamController controller; 63 ImmediateModeRenderer20 renderer; 64 65 float angle = 0; 66 private SelectBox camera; 67 private Label fps; 68 69 @Override create()70 public void create () { 71 setupScene(); 72 setupUI(); 73 setupShaders(); 74 75 multiplexer.addProcessor(ui); 76 multiplexer.addProcessor(controller); 77 Gdx.input.setInputProcessor(multiplexer); 78 79 // renderer = new ImmediateModeRenderer20(false, true, 0); 80 } 81 setupScene()82 public void setupScene () { 83 plane = new Mesh(true, 4, 6, new VertexAttribute(Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE), new VertexAttribute( 84 Usage.Normal, 3, ShaderProgram.NORMAL_ATTRIBUTE)); 85 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}); 86 plane.setIndices(new short[] {3, 2, 1, 1, 0, 3}); 87 88 texture = new Texture(Gdx.files.internal("data/badlogic.jpg"), Format.RGB565, true); 89 texture.setFilter(TextureFilter.MipMap, TextureFilter.Nearest); 90 91 cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); 92 cam.position.set(0, 5, 10); 93 cam.lookAt(0, 0, 0); 94 cam.update(); 95 controller = new PerspectiveCamController(cam); 96 97 projector = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); 98 projector.position.set(2, 3, 2); 99 projector.lookAt(0, 0, 0); 100 projector.normalizeUp(); 101 projector.update(); 102 } 103 setupUI()104 public void setupUI () { 105 ui = new Stage(); 106 skin = new Skin(Gdx.files.internal("data/uiskin.json")); 107 TextButton reload = new TextButton("Reload Shaders", skin.get(TextButtonStyle.class)); 108 camera = new SelectBox(skin.get(SelectBoxStyle.class)); 109 camera.setItems("Camera", "Light"); 110 fps = new Label("fps: ", skin.get(LabelStyle.class)); 111 112 Table table = new Table(); 113 table.setFillParent(true); 114 table.top().padTop(15); 115 table.add(reload).spaceRight(5); 116 table.add(camera).spaceRight(5); 117 table.add(fps); 118 ui.addActor(table); 119 120 reload.addListener(new ClickListener() { 121 public void clicked (InputEvent event, float x, float y) { 122 ShaderProgram prog = new ShaderProgram(Gdx.files.internal("data/shaders/projtex-vert.glsl").readString(), Gdx.files 123 .internal("data/shaders/projtex-frag.glsl").readString()); 124 if (prog.isCompiled() == false) { 125 Gdx.app.log("GLSL ERROR", "Couldn't reload shaders:\n" + prog.getLog()); 126 } else { 127 projTexShader.dispose(); 128 projTexShader = prog; 129 } 130 } 131 }); 132 } 133 setupShaders()134 public void setupShaders () { 135 ShaderProgram.pedantic = false; 136 projTexShader = new ShaderProgram(Gdx.files.internal("data/shaders/projtex-vert.glsl").readString(), Gdx.files.internal( 137 "data/shaders/projtex-frag.glsl").readString()); 138 if (!projTexShader.isCompiled()) throw new GdxRuntimeException("Couldn't compile shader: " + projTexShader.getLog()); 139 } 140 141 @Override render()142 public void render () { 143 Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); 144 Gdx.gl.glEnable(GL20.GL_DEPTH_TEST); 145 146 angle += Gdx.graphics.getDeltaTime() * 20.0f; 147 cubeTrans.setToRotation(Vector3.Y, angle); 148 149 cam.update(); 150 projector.update(); 151 152 texture.bind(); 153 projTexShader.begin(); 154 155 if (camera.getSelectedIndex() == 0) { 156 renderMesh(projTexShader, cam.combined, projector.combined, planeTrans, plane, Color.WHITE); 157 /* 158 * TODO: Fix method rendering renderMesh(projTexShader, cam.combined, projector.combined, cubeTrans, cube, Color.WHITE); 159 */ 160 } else { 161 renderMesh(projTexShader, projector.combined, projector.combined, planeTrans, plane, Color.WHITE); 162 /* 163 * TODO: Fix method rendering renderMesh(projTexShader, projector.combined, projector.combined, cubeTrans, cube, 164 * Color.WHITE); 165 */ 166 } 167 168 projTexShader.end(); 169 170 fps.setText("fps: " + Gdx.graphics.getFramesPerSecond()); 171 ui.act(); 172 ui.draw(); 173 } 174 175 Vector3 position = new Vector3(); 176 renderMesh(ShaderProgram shader, Matrix4 cam, Matrix4 projector, Matrix4 model, Mesh mesh, Color color)177 private void renderMesh (ShaderProgram shader, Matrix4 cam, Matrix4 projector, Matrix4 model, Mesh mesh, Color color) { 178 position.set(this.projector.position); 179 modelNormal.set(model).toNormalMatrix(); 180 181 shader.setUniformMatrix("u_camera", cam); 182 shader.setUniformMatrix("u_projector", projector); 183 shader.setUniformf("u_projectorPos", position.x, position.y, position.z); 184 shader.setUniformMatrix("u_model", model); 185 shader.setUniformMatrix("u_modelNormal", modelNormal); 186 shader.setUniformf("u_color", color.r, color.g, color.b); 187 shader.setUniformi("u_texture", 0); 188 mesh.render(shader, GL20.GL_TRIANGLES); 189 } 190 191 @Override dispose()192 public void dispose () { 193 texture.dispose(); 194 plane.dispose(); 195 projTexShader.dispose(); 196 ui.dispose(); 197 skin.dispose(); 198 // renderer.dispose(); 199 } 200 } 201