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 17package com.badlogic.gdx.tests.g3d; 18 19import com.badlogic.gdx.Gdx; 20import com.badlogic.gdx.Input.Buttons; 21import com.badlogic.gdx.Input.Keys; 22import com.badlogic.gdx.graphics.Camera; 23import com.badlogic.gdx.graphics.Color; 24import com.badlogic.gdx.graphics.g3d.Environment; 25import com.badlogic.gdx.graphics.g3d.Model; 26import com.badlogic.gdx.graphics.g3d.ModelBatch; 27import com.badlogic.gdx.graphics.g3d.ModelInstance; 28import com.badlogic.gdx.graphics.g3d.Renderable; 29import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute; 30import com.badlogic.gdx.graphics.g3d.attributes.DirectionalLightsAttribute; 31import com.badlogic.gdx.graphics.g3d.attributes.PointLightsAttribute; 32import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight; 33import com.badlogic.gdx.graphics.g3d.environment.PointLight; 34import com.badlogic.gdx.graphics.g3d.model.Animation; 35import com.badlogic.gdx.graphics.g3d.shaders.DefaultShader; 36import com.badlogic.gdx.graphics.g3d.shaders.DefaultShader.Config; 37import com.badlogic.gdx.graphics.g3d.utils.AnimationController; 38import com.badlogic.gdx.graphics.g3d.utils.DefaultShaderProvider; 39import com.badlogic.gdx.graphics.g3d.utils.ShaderProvider; 40import com.badlogic.gdx.graphics.profiling.GLProfiler; 41import com.badlogic.gdx.graphics.profiling.GL20Profiler; 42import com.badlogic.gdx.graphics.profiling.GL30Profiler; 43import com.badlogic.gdx.math.MathUtils; 44import com.badlogic.gdx.math.Matrix4; 45import com.badlogic.gdx.math.Quaternion; 46import com.badlogic.gdx.math.Vector3; 47import com.badlogic.gdx.math.collision.BoundingBox; 48import com.badlogic.gdx.scenes.scene2d.Actor; 49import com.badlogic.gdx.scenes.scene2d.ui.CheckBox; 50import com.badlogic.gdx.scenes.scene2d.ui.Label; 51import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; 52import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.ChangeEvent; 53import com.badlogic.gdx.utils.Array; 54import com.badlogic.gdx.utils.ObjectMap; 55import com.badlogic.gdx.utils.StringBuilder; 56 57/** @author Daniel Holderbaum */ 58public class Benchmark3DTest extends BaseG3dHudTest { 59 60 protected Environment environment; 61 62 protected Label vertexCountLabel, textureBindsLabel, shaderSwitchesLabel, drawCallsLabel, glCallsLabel, 63 lightsLabel; 64 65 protected CheckBox lightingCheckBox, lightsCheckBox; 66 67 protected boolean lighting; 68 69 @Override 70 public void create () { 71 super.create(); 72 73 GLProfiler.enable(); 74 75 randomizeLights(); 76 77 cam.position.set(10, 10, 10); 78 cam.lookAt(0, 0, 0); 79 cam.update(); 80 showAxes = true; 81 lighting = true; 82 83 vertexCountLabel = new Label("Vertices: 999", skin); 84 vertexCountLabel.setPosition(0, fpsLabel.getTop()); 85 hud.addActor(vertexCountLabel); 86 87 textureBindsLabel = new Label("Texture bindings: 999", skin); 88 textureBindsLabel.setPosition(0, vertexCountLabel.getTop()); 89 hud.addActor(textureBindsLabel); 90 91 shaderSwitchesLabel = new Label("Shader switches: 999", skin); 92 shaderSwitchesLabel.setPosition(0, textureBindsLabel.getTop()); 93 hud.addActor(shaderSwitchesLabel); 94 95 drawCallsLabel = new Label("Draw calls: 999", skin); 96 drawCallsLabel.setPosition(0, shaderSwitchesLabel.getTop()); 97 hud.addActor(drawCallsLabel); 98 99 glCallsLabel = new Label("GL calls: 999", skin); 100 glCallsLabel.setPosition(0, drawCallsLabel.getTop()); 101 hud.addActor(glCallsLabel); 102 103 lightsLabel = new Label("Lights: 999", skin); 104 lightsLabel.setPosition(0, glCallsLabel.getTop()); 105 hud.addActor(lightsLabel); 106 107 lightingCheckBox = new CheckBox("Lighting", skin); 108 lightingCheckBox.setChecked(lighting); 109 lightingCheckBox.addListener(new ChangeListener() { 110 @Override 111 public void changed (ChangeEvent event, Actor actor) { 112 lighting = lightingCheckBox.isChecked(); 113 } 114 }); 115 lightingCheckBox.setPosition(hudWidth - lightingCheckBox.getWidth(), gridCheckBox.getTop()); 116 hud.addActor(lightingCheckBox); 117 118 lightsCheckBox = new CheckBox("Randomize lights", skin); 119 lightsCheckBox.setChecked(false); 120 lightsCheckBox.addListener(new ChangeListener() { 121 @Override 122 public void changed (ChangeEvent event, Actor actor) { 123 lightsCheckBox.setChecked(false); 124 randomizeLights(); 125 } 126 }); 127 lightsCheckBox.setPosition(hudWidth - lightsCheckBox.getWidth(), lightingCheckBox.getTop()); 128 hud.addActor(lightsCheckBox); 129 130 moveCheckBox.remove(); 131 rotateCheckBox.remove(); 132 } 133 134 protected void randomizeLights () { 135 int pointLights = MathUtils.random(5); 136 int directionalLights = MathUtils.random(5); 137 138 DefaultShader.Config config = new Config(); 139 config.numDirectionalLights = directionalLights; 140 config.numPointLights = pointLights; 141 config.numSpotLights = 0; 142 143 modelBatch.dispose(); 144 modelBatch = new ModelBatch(new DefaultShaderProvider(config)); 145 146 environment = new Environment(); 147 environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1.f)); 148 149 for (int i = 0; i < pointLights; i++) { 150 environment.add(new PointLight().set(randomColor(), randomPosition(), MathUtils.random(10f))); 151 } 152 153 for (int i = 0; i < directionalLights; i++) { 154 environment.add(new DirectionalLight().set(randomColor(), randomPosition())); 155 } 156 } 157 158 protected Color randomColor () { 159 return new Color(MathUtils.random(1.0f), MathUtils.random(1.0f), MathUtils.random(1.0f), MathUtils.random(1.0f)); 160 } 161 162 protected Vector3 randomPosition () { 163 return new Vector3(MathUtils.random(-10f, 10f), MathUtils.random(-10f, 10f), MathUtils.random(-10f, 10f)); 164 } 165 166 private final Vector3 tmpV = new Vector3(); 167 private final Quaternion tmpQ = new Quaternion(); 168 private final BoundingBox bounds = new BoundingBox(); 169 170 protected void getStatus (final StringBuilder stringBuilder) { 171 stringBuilder.setLength(0); 172 stringBuilder.append("GL calls: "); 173 stringBuilder.append(GLProfiler.calls); 174 glCallsLabel.setText(stringBuilder); 175 176 stringBuilder.setLength(0); 177 stringBuilder.append("Draw calls: "); 178 stringBuilder.append(GLProfiler.drawCalls); 179 drawCallsLabel.setText(stringBuilder); 180 181 stringBuilder.setLength(0); 182 stringBuilder.append("Shader switches: "); 183 stringBuilder.append(GLProfiler.shaderSwitches); 184 shaderSwitchesLabel.setText(stringBuilder); 185 186 stringBuilder.setLength(0); 187 stringBuilder.append("Texture bindings: "); 188 stringBuilder.append(GLProfiler.textureBindings); 189 textureBindsLabel.setText(stringBuilder); 190 191 stringBuilder.setLength(0); 192 stringBuilder.append("Vertices: "); 193 stringBuilder.append(GLProfiler.vertexCount.total); 194 vertexCountLabel.setText(stringBuilder); 195 196 DirectionalLightsAttribute dirLights = (DirectionalLightsAttribute)environment.get(DirectionalLightsAttribute.Type); 197 PointLightsAttribute pointLights = (PointLightsAttribute)environment.get(PointLightsAttribute.Type); 198 199 stringBuilder.setLength(0); 200 stringBuilder.append("Lights: "); 201 202 stringBuilder.append((dirLights == null ? 0 : dirLights.lights.size) + (pointLights == null ? 0 : pointLights.lights.size)); 203 stringBuilder.append(", Directional: "); 204 stringBuilder.append(dirLights == null ? 0 : dirLights.lights.size); 205 stringBuilder.append(", Point: "); 206 stringBuilder.append(pointLights == null ? 0 : pointLights.lights.size); 207 lightsLabel.setText(stringBuilder); 208 209 GLProfiler.reset(); 210 211 stringBuilder.setLength(0); 212 super.getStatus(stringBuilder); 213 } 214 215 @Override 216 protected void render (ModelBatch batch, Array<ModelInstance> instances) { 217 if (lighting) { 218 batch.render(instances, environment); 219 } else { 220 batch.render(instances); 221 } 222 } 223 224 protected String currentlyLoading; 225 226 @Override 227 protected void onModelClicked (final String name) { 228 if (name == null) return; 229 230 currentlyLoading = "data/" + name; 231 assets.load(currentlyLoading, Model.class); 232 loading = true; 233 } 234 235 @Override 236 protected void onLoaded () { 237 if (currentlyLoading == null || currentlyLoading.length() == 0) return; 238 239 final ModelInstance instance = new ModelInstance(assets.get(currentlyLoading, Model.class)); 240 instance.transform = new Matrix4().idt(); 241 instance.transform.setToTranslation(MathUtils.random(-10, 10), MathUtils.random(-10, 10), MathUtils.random(-10, 10)); 242 instance.transform.rotate(Vector3.X, MathUtils.random(-180, 180)); 243 instance.transform.rotate(Vector3.Y, MathUtils.random(-180, 180)); 244 instance.transform.rotate(Vector3.Z, MathUtils.random(-180, 180)); 245 instances.add(instance); 246 } 247 248 @Override 249 public boolean keyUp (int keycode) { 250 if (keycode == Keys.SPACE || keycode == Keys.MENU) { 251 onLoaded(); 252 } 253 return super.keyUp(keycode); 254 } 255 256 @Override 257 public boolean touchUp (int screenX, int screenY, int pointer, int button) { 258 onModelClicked(models[MathUtils.random(models.length-1)]); 259 return false; 260 } 261 262 @Override 263 public void dispose () { 264 super.dispose(); 265 GLProfiler.disable(); 266 } 267 268}