diff --git a/libs/gdx-sources.jar b/libs/gdx-sources.jar deleted file mode 100644 index 2171134..0000000 Binary files a/libs/gdx-sources.jar and /dev/null differ diff --git a/libs/gdx.jar b/libs/gdx.jar deleted file mode 100644 index d1ac693..0000000 Binary files a/libs/gdx.jar and /dev/null differ diff --git a/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java b/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java index 62ec6ce..315e89d 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java +++ b/src/ve/ucv/ciens/ccg/nxtar/NxtARCore.java @@ -17,7 +17,7 @@ package ve.ucv.ciens.ccg.nxtar; import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor; import ve.ucv.ciens.ccg.nxtar.interfaces.ApplicationEventsListener; -import ve.ucv.ciens.ccg.nxtar.interfaces.AndroidFunctionalityWrapper; +import ve.ucv.ciens.ccg.nxtar.interfaces.ActionResolver; import ve.ucv.ciens.ccg.nxtar.network.RobotControlThread; import ve.ucv.ciens.ccg.nxtar.network.SensorReportThread; import ve.ucv.ciens.ccg.nxtar.network.ServiceDiscoveryThread; @@ -121,7 +121,7 @@ public class NxtARCore extends Game implements ApplicationEventsListener{ /** *

Wrapper around the Operating System methods.

*/ - private AndroidFunctionalityWrapper osFunction; + private ActionResolver osFunction; // Networking related fields. /** @@ -206,7 +206,7 @@ public class NxtARCore extends Game implements ApplicationEventsListener{ // Check if the concrete application implements all required interfaces. try{ - this.osFunction = (AndroidFunctionalityWrapper)concreteApp; + this.osFunction = (ActionResolver)concreteApp; }catch(ClassCastException cc){ Gdx.app.debug(TAG, CLASS_NAME + ".Main() :: concreteApp does not implement the Toaster interface. Toasting disabled."); this.osFunction = null; diff --git a/src/ve/ucv/ciens/ccg/nxtar/components/AnimationComponent.java b/src/ve/ucv/ciens/ccg/nxtar/components/AnimationComponent.java new file mode 100644 index 0000000..36e6ea9 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/components/AnimationComponent.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2014 Miguel Angel Astor Romero + * + * 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 ve.ucv.ciens.ccg.nxtar.components; + +import java.util.LinkedList; +import java.util.List; + +import com.artemis.Component; +import com.badlogic.gdx.graphics.g3d.ModelInstance; +import com.badlogic.gdx.graphics.g3d.utils.AnimationController; + +public class AnimationComponent extends Component { + public AnimationController controller; + public List animationsIds; + public int current; + public int next; + public boolean loop; + + public AnimationComponent(ModelInstance instance) throws IllegalArgumentException{ + this(instance, -1, false); + } + + public AnimationComponent(ModelInstance instance, int next) throws IllegalArgumentException{ + this(instance, next, false); + } + + public AnimationComponent(ModelInstance instance, int next, boolean loop) throws IllegalArgumentException{ + if(instance == null) + throw new IllegalArgumentException("Instance is null."); + else if(next < 0) + throw new IllegalArgumentException("Next is less than 0."); + else if(next > instance.animations.size) + throw new IllegalArgumentException("Next is greater than the number of animations for this model."); + + controller = new AnimationController(instance); + animationsIds = new LinkedList(); + current = -1; + this.next = next; + this.loop = loop; + + for(int i = 0; i < instance.animations.size; i++){ + animationsIds.add(instance.animations.get(i).id); + } + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/components/CustomShaderComponent.java b/src/ve/ucv/ciens/ccg/nxtar/components/CustomShaderComponent.java new file mode 100644 index 0000000..e66e879 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/components/CustomShaderComponent.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2014 Miguel Angel Astor Romero + * + * 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 ve.ucv.ciens.ccg.nxtar.components; + +import ve.ucv.ciens.ccg.nxtar.graphics.shaders.CustomShaderBase; + +import com.artemis.Component; + +public class CustomShaderComponent extends Component { + public CustomShaderBase shader; + + public CustomShaderComponent(CustomShaderBase shader) throws IllegalArgumentException{ + if(shader == null) + throw new IllegalArgumentException("Shader cannot be null."); + + this.shader = shader; + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/components/EnvironmentComponent.java b/src/ve/ucv/ciens/ccg/nxtar/components/EnvironmentComponent.java new file mode 100644 index 0000000..dfea86c --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/components/EnvironmentComponent.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2014 Miguel Angel Astor Romero + * + * 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 ve.ucv.ciens.ccg.nxtar.components; + +import com.artemis.Component; +import com.badlogic.gdx.graphics.g3d.Environment; + +public class EnvironmentComponent extends Component { + public Environment environment; + + public EnvironmentComponent(Environment environment) throws IllegalArgumentException{ + if(environment == null) + throw new IllegalArgumentException("Environment is null."); + + this.environment = environment; + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/components/ModelComponent.java b/src/ve/ucv/ciens/ccg/nxtar/components/ModelComponent.java new file mode 100644 index 0000000..e630fca --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/components/ModelComponent.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2014 Miguel Angel Astor Romero + * + * 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 ve.ucv.ciens.ccg.nxtar.components; + +import com.artemis.Component; +import com.badlogic.gdx.graphics.g3d.Model; +import com.badlogic.gdx.graphics.g3d.ModelInstance; + +public class ModelComponent extends Component { + public ModelInstance instance; + + public ModelComponent(Model model) throws IllegalArgumentException{ + if(model == null) + throw new IllegalArgumentException("Model is null."); + + this.instance = new ModelInstance(model); + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/components/ShaderComponent.java b/src/ve/ucv/ciens/ccg/nxtar/components/ShaderComponent.java index af0bdbc..2b5c80e 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/components/ShaderComponent.java +++ b/src/ve/ucv/ciens/ccg/nxtar/components/ShaderComponent.java @@ -15,16 +15,15 @@ */ package ve.ucv.ciens.ccg.nxtar.components; -import ve.ucv.ciens.ccg.nxtar.graphics.shaders.CustomShaderBase; - import com.artemis.Component; +import com.badlogic.gdx.graphics.g3d.Shader; -public class ShaderComponent extends Component { - public CustomShaderBase shader; +public class ShaderComponent extends Component{ + public Shader shader; - public ShaderComponent(CustomShaderBase shader) throws IllegalArgumentException{ + public ShaderComponent(Shader shader) throws IllegalArgumentException{ if(shader == null) - throw new IllegalArgumentException("Shader cannot be null."); + throw new IllegalArgumentException("Shader is null."); this.shader = shader; } diff --git a/src/ve/ucv/ciens/ccg/nxtar/entities/MarkerTestEntityCreator.java b/src/ve/ucv/ciens/ccg/nxtar/entities/MarkerTestEntityCreator.java index be01c0b..d9ee15f 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/entities/MarkerTestEntityCreator.java +++ b/src/ve/ucv/ciens/ccg/nxtar/entities/MarkerTestEntityCreator.java @@ -15,79 +15,113 @@ */ package ve.ucv.ciens.ccg.nxtar.entities; +import ve.ucv.ciens.ccg.nxtar.components.AnimationComponent; +import ve.ucv.ciens.ccg.nxtar.components.EnvironmentComponent; import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent; import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent; -import ve.ucv.ciens.ccg.nxtar.components.MeshComponent; +import ve.ucv.ciens.ccg.nxtar.components.ModelComponent; import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent; -import ve.ucv.ciens.ccg.nxtar.exceptions.ShaderFailedToLoadException; -import ve.ucv.ciens.ccg.nxtar.graphics.shaders.CustomShaderBase; -import ve.ucv.ciens.ccg.nxtar.graphics.shaders.SingleLightPhongShader; +import ve.ucv.ciens.ccg.nxtar.graphics.shaders.SingleLightPerPixelShader; import com.artemis.Entity; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.Mesh; +import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.VertexAttribute; import com.badlogic.gdx.graphics.VertexAttributes; import com.badlogic.gdx.graphics.VertexAttributes.Usage; -import com.badlogic.gdx.graphics.g3d.utils.MeshBuilder; +import com.badlogic.gdx.graphics.g3d.Environment; +import com.badlogic.gdx.graphics.g3d.Material; +import com.badlogic.gdx.graphics.g3d.Model; +import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute; +import com.badlogic.gdx.graphics.g3d.attributes.FloatAttribute; +import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight; +import com.badlogic.gdx.graphics.g3d.loader.G3dModelLoader; +import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder; import com.badlogic.gdx.math.Matrix3; import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.utils.JsonReader; public class MarkerTestEntityCreator extends EntityCreatorBase { private static final String TAG = "MARKER_TEST_ENTITY_CREATOR"; private static final String CLASS_NAME = MarkerTestEntityCreator.class.getSimpleName(); - private Mesh markerMesh; - private CustomShaderBase phongShader; + private Model bombModel; + private Model animatedModel; + private Model boxModel; + private SingleLightPerPixelShader ppShader; @Override public void createAllEntities() { - MeshBuilder builder; - Matrix3 identity = new Matrix3().idt(); - Entity marker; + ModelBuilder builder; + Entity bomb, box, anim; + G3dModelLoader loader; + Environment environment; + Material material; // Create mesh. Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Creating the meshes."); - builder = new MeshBuilder(); - builder.begin(new VertexAttributes(new VertexAttribute(Usage.Position, 3, "a_position"), new VertexAttribute(Usage.Normal, 3, "a_normal"), new VertexAttribute(Usage.Color, 4, "a_color")), GL20.GL_TRIANGLES);{ - builder.setColor(1.0f, 1.0f, 1.0f, 1.0f); - Vector3 v00 = new Vector3(-0.5f, -0.5f, 0.0f); - Vector3 v10 = new Vector3(-0.5f, 0.5f, 0.0f); - Vector3 v11 = new Vector3( 0.5f, 0.5f, 0.0f); - Vector3 v01 = new Vector3( 0.5f, -0.5f, 0.0f); - Vector3 n = new Vector3(0.0f, 1.0f, 0.0f); - builder.patch(v00, v10, v11, v01, n, 10, 10); - }markerMesh = builder.end(); - // Load the phong shader. - Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Loading the phong shader."); - try{ - phongShader = new SingleLightPhongShader().loadShader(); - }catch(ShaderFailedToLoadException se){ - Gdx.app.error(TAG, CLASS_NAME + ".InGameState(): " + se.getMessage()); - Gdx.app.exit(); - } + loader = new G3dModelLoader(new JsonReader()); + + bombModel = loader.loadModel(Gdx.files.internal("models/Bomb_test_2.g3dj")); + animatedModel = loader.loadModel(Gdx.files.internal("models/cube.g3dj")); + + material = new Material(new FloatAttribute(FloatAttribute.Shininess, 50.0f), new ColorAttribute(ColorAttribute.Diffuse, 1.0f, 1.0f, 1.0f, 1.0f), new ColorAttribute(ColorAttribute.Specular, 1.0f, 1.0f, 1.0f, 1.0f)); + + builder = new ModelBuilder(); + boxModel = builder.createBox(0.5f, 0.5f, 6.0f, material, new VertexAttributes(new VertexAttribute(Usage.Position, 3, "a_position"), new VertexAttribute(Usage.Normal, 3, "a_normal"), new VertexAttribute(Usage.Color, 4, "a_color")).getMask()); + + // Load the shader. + ppShader = new SingleLightPerPixelShader(); + ppShader.init(); + + environment = new Environment(); + environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.3f, 0.3f, 0.3f, 1.0f)); + environment.add(new DirectionalLight().set(new Color(1, 1, 1, 1), new Vector3(1, 0, 0.5f))); // Create the entities. Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Creating the enitites."); - marker = world.createEntity(); - marker.addComponent(new GeometryComponent(new Vector3(0.0f, 0.0f, 0.0f), identity, new Vector3(1.0f, 1.0f, 1.0f))); - marker.addComponent(new MeshComponent(markerMesh)); - marker.addComponent(new ShaderComponent(phongShader)); - marker.addComponent(new MarkerCodeComponent(213)); + bomb = world.createEntity(); + bomb.addComponent(new GeometryComponent(new Vector3(0.0f, 0.0f, 0.0f), new Matrix3().idt(), new Vector3(1.0f, 1.0f, 1.0f))); + bomb.addComponent(new ModelComponent(bombModel)); + bomb.addComponent(new EnvironmentComponent(environment)); + bomb.addComponent(new ShaderComponent(ppShader)); + bomb.addComponent(new MarkerCodeComponent(1023)); + + anim = world.createEntity(); + anim.addComponent(new GeometryComponent(new Vector3(0.0f, 0.0f, 0.0f), new Matrix3().idt(), new Vector3(0.25f, 0.25f, -0.25f))); + anim.addComponent(new ModelComponent(animatedModel)); + anim.addComponent(new AnimationComponent(anim.getComponent(ModelComponent.class).instance, 0, true)); + anim.addComponent(new EnvironmentComponent(environment)); + anim.addComponent(new MarkerCodeComponent(89)); + anim.addComponent(new ShaderComponent(ppShader)); + + box = world.createEntity(); + box.addComponent(new GeometryComponent(new Vector3(-1.0f, 0.0f, 0.0f), new Matrix3().idt(), new Vector3(1.0f, 1.0f, 1.0f))); + box.addComponent(new ModelComponent(boxModel)); + box.addComponent(new ShaderComponent(ppShader)); + box.addComponent(new EnvironmentComponent(environment)); // Add the entities to the world. Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Adding entities to the world."); - marker.addToWorld(); + //sphere.addToWorld(); + bomb.addToWorld(); + anim.addToWorld(); + box.addToWorld(); } @Override public void dispose() { - if(phongShader != null && phongShader.getShaderProgram() != null) - phongShader.getShaderProgram().dispose(); + if(boxModel != null) + boxModel.dispose(); - if(markerMesh != null) - markerMesh.dispose(); + if(animatedModel != null) + animatedModel.dispose(); + + if(bombModel != null) + bombModel.dispose(); + + if(ppShader != null) + ppShader.dispose(); } } diff --git a/src/ve/ucv/ciens/ccg/nxtar/entities/TestGameEntityCreator.java b/src/ve/ucv/ciens/ccg/nxtar/entities/TestGameEntityCreator.java index 9b069a4..b3842fc 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/entities/TestGameEntityCreator.java +++ b/src/ve/ucv/ciens/ccg/nxtar/entities/TestGameEntityCreator.java @@ -17,7 +17,7 @@ package ve.ucv.ciens.ccg.nxtar.entities; import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent; import ve.ucv.ciens.ccg.nxtar.components.MeshComponent; -import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent; +import ve.ucv.ciens.ccg.nxtar.components.CustomShaderComponent; import ve.ucv.ciens.ccg.nxtar.exceptions.ShaderFailedToLoadException; import ve.ucv.ciens.ccg.nxtar.graphics.shaders.CustomShaderBase; import ve.ucv.ciens.ccg.nxtar.graphics.shaders.SingleLightPhongShader; @@ -89,22 +89,22 @@ public class TestGameEntityCreator extends EntityCreatorBase { sphere = world.createEntity(); sphere.addComponent(new GeometryComponent(new Vector3(0.5f, 0.5f, 0.0f), identity, new Vector3(1.0f, 1.0f, 1.0f))); sphere.addComponent(new MeshComponent(sphereMesh)); - sphere.addComponent(new ShaderComponent(singleLightPhongShader)); + sphere.addComponent(new CustomShaderComponent(singleLightPhongShader)); cube = world.createEntity(); cube.addComponent(new GeometryComponent(new Vector3(-0.5f, -0.5f, 0.0f), identity, new Vector3(1.0f, 1.0f, 1.0f))); cube.addComponent(new MeshComponent(cubeMesh)); - cube.addComponent(new ShaderComponent(singleLightPhongShader)); + cube.addComponent(new CustomShaderComponent(singleLightPhongShader)); capsule1 = world.createEntity(); capsule1.addComponent(new GeometryComponent(new Vector3(-0.5f, 0.5f, 0.0f), identity, new Vector3(1.5f, 1.0f, 1.0f))); capsule1.addComponent(new MeshComponent(capsuleMesh)); - capsule1.addComponent(new ShaderComponent(singleLightPhongShader)); + capsule1.addComponent(new CustomShaderComponent(singleLightPhongShader)); capsule2 = world.createEntity(); capsule2.addComponent(new GeometryComponent(new Vector3(0.5f, -0.5f, 0.0f), identity, new Vector3(1.0f, 1.5f, 1.0f))); capsule2.addComponent(new MeshComponent(capsuleMesh)); - capsule2.addComponent(new ShaderComponent(singleLightPhongShader)); + capsule2.addComponent(new CustomShaderComponent(singleLightPhongShader)); // Add the entities to the world. Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Adding entities to the world."); diff --git a/src/ve/ucv/ciens/ccg/nxtar/graphics/shaders/SingleLightPerPixelShader.java b/src/ve/ucv/ciens/ccg/nxtar/graphics/shaders/SingleLightPerPixelShader.java new file mode 100644 index 0000000..b123837 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/graphics/shaders/SingleLightPerPixelShader.java @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2014 Miguel Angel Astor Romero + * + * 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 ve.ucv.ciens.ccg.nxtar.graphics.shaders; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Camera; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.VertexAttributes; +import com.badlogic.gdx.graphics.g3d.Renderable; +import com.badlogic.gdx.graphics.g3d.Shader; +import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute; +import com.badlogic.gdx.graphics.g3d.attributes.FloatAttribute; +import com.badlogic.gdx.graphics.g3d.utils.RenderContext; +import com.badlogic.gdx.graphics.glutils.ShaderProgram; +import com.badlogic.gdx.math.Matrix4; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.utils.GdxRuntimeException; + +public class SingleLightPerPixelShader implements Shader{ + private static final int MAX_NUM_BONES = 4; + private static final Matrix4 IDENTITY = new Matrix4(); + private static final String VERTEX_SHADER_PATH = "shaders/directionalPerPixelSingleLight/directionalPerPixel_vert.glsl"; + private static final String FRAGMENT_SHADER_PATH = "shaders/directionalPerPixelSingleLight/directionalPerPixel_frag.glsl"; + private static final String INCLUDE_SKINNING = "#define SKINNING\n"; + + private ShaderProgram skinningProgram; + private ShaderProgram baseProgram; + private Camera camera; + private RenderContext context; + private Matrix4 normalMatrix; + + // Uniform locations. + private int[] u_geomTrans; + private int[] u_projTrans; + private int[] u_lightPos; + private int[] u_lightDiffuse; + private int[] u_specular; + private int[] u_ambient; + private int[] u_shiny; + private int[] u_cameraPos; + private int[] u_materialDiffuse; + private int[] u_normalMatrix; + private int[] u_bones; + + public SingleLightPerPixelShader(){ + skinningProgram = null; + baseProgram = null; + camera = null; + context = null; + } + + @Override + public void init() throws GdxRuntimeException{ + normalMatrix = new Matrix4().idt(); + u_bones = new int[MAX_NUM_BONES]; + + // Compile the shader. + String vertexCode = Gdx.files.internal(VERTEX_SHADER_PATH).readString(); + String fragmentCode = Gdx.files.internal(FRAGMENT_SHADER_PATH).readString(); + + skinningProgram = new ShaderProgram(INCLUDE_SKINNING + vertexCode, fragmentCode); + baseProgram = new ShaderProgram(vertexCode, fragmentCode); + + if(!skinningProgram.isCompiled()) + throw new GdxRuntimeException(skinningProgram.getLog()); + + if(!baseProgram.isCompiled()) + throw new GdxRuntimeException(skinningProgram.getLog()); + + // Create uniform locations. + u_projTrans = new int[2]; + u_geomTrans = new int[2]; + u_lightPos = new int[2]; + u_lightDiffuse = new int[2]; + u_specular = new int[2]; + u_ambient = new int[2]; + u_shiny = new int[2]; + u_cameraPos = new int[2]; + u_materialDiffuse = new int[2]; + u_normalMatrix = new int[2]; + + // Cache uniform locations. + u_projTrans [0] = skinningProgram.getUniformLocation("u_projTrans"); + u_geomTrans [0] = skinningProgram.getUniformLocation("u_geomTrans"); + u_lightPos [0] = skinningProgram.getUniformLocation("u_lightPos"); + u_lightDiffuse [0] = skinningProgram.getUniformLocation("u_lightDiffuse"); + u_specular [0] = skinningProgram.getUniformLocation("u_specular"); + u_ambient [0] = skinningProgram.getUniformLocation("u_ambient"); + u_shiny [0] = skinningProgram.getUniformLocation("u_shiny"); + u_cameraPos [0] = skinningProgram.getUniformLocation("u_cameraPos"); + u_materialDiffuse [0] = skinningProgram.getUniformLocation("u_materialDiffuse"); + u_normalMatrix [0] = skinningProgram.getUniformLocation("u_normalMatrix"); + + u_projTrans [1] = baseProgram.getUniformLocation("u_projTrans"); + u_geomTrans [1] = baseProgram.getUniformLocation("u_geomTrans"); + u_lightPos [1] = baseProgram.getUniformLocation("u_lightPos"); + u_lightDiffuse [1] = baseProgram.getUniformLocation("u_lightDiffuse"); + u_specular [1] = baseProgram.getUniformLocation("u_specular"); + u_ambient [1] = baseProgram.getUniformLocation("u_ambient"); + u_shiny [1] = baseProgram.getUniformLocation("u_shiny"); + u_cameraPos [1] = baseProgram.getUniformLocation("u_cameraPos"); + u_materialDiffuse [1] = baseProgram.getUniformLocation("u_materialDiffuse"); + u_normalMatrix [1] = baseProgram.getUniformLocation("u_normalMatrix"); + + for(int i = 0; i < MAX_NUM_BONES; i++){ + u_bones[i] = skinningProgram.getUniformLocation("u_bone" + Integer.toString(i)); + } + } + + @Override + public void dispose(){ + if(skinningProgram != null) skinningProgram.dispose(); + if(baseProgram != null) baseProgram.dispose(); + } + + @Override + public int compareTo(Shader other){ + return 0; + } + + @Override + public boolean canRender(Renderable renderable){ + // Check for all needed lighting and material attributes. + if(renderable.environment.directionalLights.size < 1) + return false; + + if(!renderable.environment.has(ColorAttribute.AmbientLight)) + return false; + + if(!renderable.material.has(ColorAttribute.Diffuse)) + return false; + + if(!renderable.material.has(ColorAttribute.Specular)) + return false; + + if(!renderable.material.has(FloatAttribute.Shininess)) + return false; + + return true; + } + + @Override + public void begin(Camera camera, RenderContext context) throws GdxRuntimeException{ + if(this.camera != null || this.context != null) + throw new GdxRuntimeException("Called begin twice before calling end."); + + this.camera = camera; + this.context = context; + + // Set render context. + this.context.setDepthTest(GL20.GL_LEQUAL); + this.context.setDepthMask(true); + } + + @Override + public void render(Renderable renderable){ + ShaderProgram program; + int index; + boolean bonesEnabled; + + // Get material colors. + Vector3 lightPosition = renderable.environment.directionalLights.get(0).direction; + Color diffuseLightColor = renderable.environment.directionalLights.get(0).color; + Color diffuseColor = ((ColorAttribute)renderable.material.get(ColorAttribute.Diffuse)).color; + Color specularColor = ((ColorAttribute)renderable.material.get(ColorAttribute.Specular)).color; + Color ambientColor = ((ColorAttribute)renderable.environment.get(ColorAttribute.AmbientLight)).color; + float shininess = ((FloatAttribute)renderable.material.get(FloatAttribute.Shininess)).value; + + if(renderable.mesh.getVertexAttribute(VertexAttributes.Usage.BoneWeight) != null){ + program = skinningProgram; + index = 0; + bonesEnabled = true; + }else{ + program = baseProgram; + index = 1; + bonesEnabled = false; + } + + program.begin(); + + // Set camera dependant uniforms. + program.setUniformMatrix(u_projTrans[index], this.camera.combined); + program.setUniformf(u_cameraPos[index], this.camera.position); + + // Set model dependant uniforms. + program.setUniformMatrix(u_geomTrans[index], renderable.worldTransform); + program.setUniformMatrix(u_normalMatrix[index], normalMatrix.idt().mul(renderable.worldTransform).inv().tra()); + program.setUniformf(u_lightPos[index], lightPosition); + program.setUniformf(u_lightDiffuse[index], diffuseLightColor); + program.setUniformf(u_materialDiffuse[index], diffuseColor); + program.setUniformf(u_specular[index], specularColor); + program.setUniformf(u_ambient[index], ambientColor); + program.setUniformf(u_shiny[index], shininess); + + // Set the bones uniforms. + if(bonesEnabled){ + for(int i = 0; i < MAX_NUM_BONES; i++){ + if(renderable.bones != null && i < renderable.bones.length && renderable.bones[i] != null) + skinningProgram.setUniformMatrix(u_bones[i], renderable.bones[i]); + else + skinningProgram.setUniformMatrix(u_bones[i], IDENTITY); + } + } + + renderable.mesh.render(program, renderable.primitiveType, renderable.meshPartOffset, renderable.meshPartSize); + + program.end(); + } + + @Override + public void end(){ + this.camera = null; + this.context = null; + } + +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/interfaces/AndroidFunctionalityWrapper.java b/src/ve/ucv/ciens/ccg/nxtar/interfaces/ActionResolver.java similarity index 94% rename from src/ve/ucv/ciens/ccg/nxtar/interfaces/AndroidFunctionalityWrapper.java rename to src/ve/ucv/ciens/ccg/nxtar/interfaces/ActionResolver.java index d233374..13f874f 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/interfaces/AndroidFunctionalityWrapper.java +++ b/src/ve/ucv/ciens/ccg/nxtar/interfaces/ActionResolver.java @@ -15,7 +15,7 @@ */ package ve.ucv.ciens.ccg.nxtar.interfaces; -public interface AndroidFunctionalityWrapper{ +public interface ActionResolver{ public void showShortToast(String msg); public void showLongToast(String msg); public void enableMulticast(); diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/CameraCalibrationState.java b/src/ve/ucv/ciens/ccg/nxtar/states/CameraCalibrationState.java index b27b0f8..42bbdd1 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/states/CameraCalibrationState.java +++ b/src/ve/ucv/ciens/ccg/nxtar/states/CameraCalibrationState.java @@ -40,6 +40,7 @@ import com.badlogic.gdx.graphics.g2d.NinePatch; import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter; import com.badlogic.gdx.graphics.glutils.ShaderProgram; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; @@ -93,6 +94,7 @@ public class CameraCalibrationState extends BaseState{ public CameraCalibrationState(final NxtARCore core){ TextButtonStyle tbs; FreeTypeFontGenerator generator; + FreeTypeFontParameter param; this.core = core; frameMonitor = VideoFrameMonitor.getInstance(); @@ -124,8 +126,12 @@ public class CameraCalibrationState extends BaseState{ // Set up the sampling button. // Create the font. + param = new FreeTypeFontParameter(); + param.characters = ProjectConstants.FONT_CHARS; + param.size = ProjectConstants.MENU_BUTTON_FONT_SIZE; + param.flip = false; generator = new FreeTypeFontGenerator(Gdx.files.internal("data/fonts/d-puntillas-B-to-tiptoe.ttf")); - font = generator.generateFont(ProjectConstants.MENU_BUTTON_FONT_SIZE, ProjectConstants.FONT_CHARS, false); + font = generator.generateFont(param); generator.dispose(); // Load the textures. diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java b/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java index 81a0073..1c55957 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java +++ b/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java @@ -22,10 +22,12 @@ import ve.ucv.ciens.ccg.nxtar.NxtARCore.game_states_t; import ve.ucv.ciens.ccg.nxtar.entities.EntityCreatorBase; import ve.ucv.ciens.ccg.nxtar.entities.MarkerTestEntityCreator; import ve.ucv.ciens.ccg.nxtar.graphics.CustomPerspectiveCamera; +import ve.ucv.ciens.ccg.nxtar.graphics.LightSource; import ve.ucv.ciens.ccg.nxtar.graphics.RenderParameters; import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.MarkerData; import ve.ucv.ciens.ccg.nxtar.network.monitors.MotorEventQueue; import ve.ucv.ciens.ccg.nxtar.network.monitors.VideoFrameMonitor; +import ve.ucv.ciens.ccg.nxtar.systems.AnimationSystem; import ve.ucv.ciens.ccg.nxtar.systems.MarkerPositioningSystem; import ve.ucv.ciens.ccg.nxtar.systems.MarkerRenderingSystem; import ve.ucv.ciens.ccg.nxtar.systems.ObjectRenderingSystem; @@ -36,6 +38,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; import com.badlogic.gdx.controllers.Controller; import com.badlogic.gdx.controllers.mappings.Ouya; +import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Pixmap; @@ -45,6 +48,7 @@ import com.badlogic.gdx.graphics.Texture.TextureFilter; import com.badlogic.gdx.graphics.Texture.TextureWrap; import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.graphics.g3d.ModelBatch; import com.badlogic.gdx.graphics.glutils.FrameBuffer; import com.badlogic.gdx.graphics.glutils.ShaderProgram; import com.badlogic.gdx.math.Matrix4; @@ -52,58 +56,66 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector3; public class InGameState extends BaseState{ - private static final String TAG = "IN_GAME_STATE"; - private static final String CLASS_NAME = InGameState.class.getSimpleName(); - private static final String BACKGROUND_SHADER_PATH = "shaders/bckg/bckg"; - private static final float NEAR = 0.01f; - private static final float FAR = 100.0f; - private static final float FAR_PLUS_NEAR = FAR + NEAR; - private static final float FAR_LESS_NEAR = FAR - NEAR; + private static final String TAG = "IN_GAME_STATE"; + private static final String CLASS_NAME = InGameState.class.getSimpleName(); + private static final String BACKGROUND_SHADER_PATH = "shaders/bckg/bckg"; + private static final float NEAR = 0.01f; + private static final float FAR = 100.0f; + private static final float FAR_PLUS_NEAR = FAR + NEAR; + private static final float FAR_LESS_NEAR = FAR - NEAR; + private static final Vector3 LIGHT_POSITION = new Vector3(2.0f, 2.0f, 4.0f); + private static final Color AMBIENT_COLOR = new Color(0.0f, 0.1f, 0.3f, 1.0f); + private static final Color DIFFUSE_COLOR = new Color(1.0f, 1.0f, 1.0f, 1.0f); + private static final Color SPECULAR_COLOR = new Color(1.0f, 0.8f, 0.0f, 1.0f); + private static final float SHINYNESS = 50.0f; // Background related fields. - private float uScaling[]; - protected Sprite background; - private Texture backgroundTexture; - private ShaderProgram backgroundShader; + private float uScaling[]; + protected Sprite background; + private Texture backgroundTexture; + private ShaderProgram backgroundShader; // 3D rendering fields. - private Matrix4 projectionMatrix; - private FrameBuffer frameBuffer; - private Sprite frameBufferSprite; + private ModelBatch modelBatch; + private Matrix4 projectionMatrix; + private FrameBuffer frameBuffer; + private Sprite frameBufferSprite; - // Game objects. - private World gameWorld; - private EntityCreatorBase entityCreator; + // Game world objects. + private World gameWorld; + private EntityCreatorBase entityCreator; + private MarkerRenderingSystem markerRenderingSystem; + private ObjectRenderingSystem objectRenderingSystem; // Cameras. - private OrthographicCamera unitaryOrthoCamera; - private OrthographicCamera pixelPerfectOrthoCamera; - private CustomPerspectiveCamera perspectiveCamera; + private OrthographicCamera unitaryOrthoCamera; + private OrthographicCamera pixelPerfectOrthoCamera; + private CustomPerspectiveCamera perspectiveCamera; // Video stream graphics. - private Texture videoFrameTexture; - private Sprite renderableVideoFrame; - private Pixmap videoFrame; + private Texture videoFrameTexture; + private Sprite renderableVideoFrame; + private Pixmap videoFrame; // Interface buttons. - private Texture buttonTexture; - private Texture buttonTexture2; - private Sprite motorA; - private Sprite motorB; - private Sprite motorC; - private Sprite motorD; - private Sprite headA; - private Sprite headB; - private Sprite headC; + private Texture buttonTexture; + private Texture buttonTexture2; + private Sprite motorA; + private Sprite motorB; + private Sprite motorC; + private Sprite motorD; + private Sprite headA; + private Sprite headB; + private Sprite headC; // Button touch helper fields. - private boolean[] motorButtonsTouched; - private int[] motorButtonsPointers; - private boolean[] motorGamepadButtonPressed; + private boolean[] motorButtonsTouched; + private int[] motorButtonsPointers; + private boolean[] motorGamepadButtonPressed; // Monitors. - private VideoFrameMonitor frameMonitor; - private MotorEventQueue queue; + private VideoFrameMonitor frameMonitor; + private MotorEventQueue queue; public InGameState(final NxtARCore core){ this.core = core; @@ -171,19 +183,28 @@ public class InGameState extends BaseState{ uScaling[1] = Gdx.graphics.getHeight() > Gdx.graphics.getWidth() ? 16.0f : 9.0f; // Set up the 3D rendering. + modelBatch = new ModelBatch(); projectionMatrix = new Matrix4().idt(); frameBuffer = null; perspectiveCamera = null; frameBufferSprite = null; + RenderParameters.setLightSource1(new LightSource(LIGHT_POSITION, AMBIENT_COLOR, DIFFUSE_COLOR, SPECULAR_COLOR, SHINYNESS)); // Set up the game world. gameWorld = new World(); + entityCreator = new MarkerTestEntityCreator(); entityCreator.setWorld(gameWorld); entityCreator.createAllEntities(); + gameWorld.setSystem(new MarkerPositioningSystem()); - gameWorld.setSystem(new MarkerRenderingSystem(), true); - gameWorld.setSystem(new ObjectRenderingSystem(), true); + gameWorld.setSystem(new AnimationSystem()); + + markerRenderingSystem = new MarkerRenderingSystem(modelBatch); + objectRenderingSystem = new ObjectRenderingSystem(modelBatch); + gameWorld.setSystem(markerRenderingSystem, true); + gameWorld.setSystem(objectRenderingSystem, true); + gameWorld.initialize(); } @@ -232,11 +253,6 @@ public class InGameState extends BaseState{ perspectiveCamera.update(); } - // Apply the undistortion method if the camera has been calibrated already. - /*if(core.cvProc.isCameraCalibrated()){ - frame = core.cvProc.undistortFrame(frame); - }*/ - // Attempt to find the markers in the current video frame. data = core.cvProc.findMarkersInFrame(frame); @@ -265,10 +281,9 @@ public class InGameState extends BaseState{ // Set the 3D frame buffer for rendering. frameBuffer.begin();{ // Set OpenGL state. - Gdx.gl.glDisable(GL20.GL_CULL_FACE); - Gdx.gl.glEnable(GL20.GL_DEPTH_TEST); Gdx.gl.glClearColor(0, 0, 0, 0); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); + Gdx.gl.glDisable(GL20.GL_TEXTURE_2D); // Build the projection matrix. focalPointX = core.cvProc.getFocalPointX(); @@ -302,11 +317,13 @@ public class InGameState extends BaseState{ RenderParameters.setEyePosition(perspectiveCamera.position); // Call rendering systems. - gameWorld.getSystem(MarkerRenderingSystem.class).setMarkerData(data); - gameWorld.getSystem(MarkerRenderingSystem.class).process(); - gameWorld.getSystem(ObjectRenderingSystem.class).process(); + markerRenderingSystem.begin(perspectiveCamera, data); + markerRenderingSystem.process(); + markerRenderingSystem.end(); - Gdx.gl.glDisable(GL20.GL_DEPTH_TEST); + objectRenderingSystem.begin(perspectiveCamera); + objectRenderingSystem.process(); + objectRenderingSystem.end(); }frameBuffer.end(); // Set the frame buffer object texture to a renderable sprite. @@ -375,6 +392,9 @@ public class InGameState extends BaseState{ @Override public void dispose(){ + if(modelBatch != null) + modelBatch.dispose(); + if(entityCreator != null) entityCreator.dispose(); diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/MainMenuStateBase.java b/src/ve/ucv/ciens/ccg/nxtar/states/MainMenuStateBase.java index 7f3b5b9..db558f4 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/states/MainMenuStateBase.java +++ b/src/ve/ucv/ciens/ccg/nxtar/states/MainMenuStateBase.java @@ -1,318 +1,324 @@ -/* - * Copyright (C) 2014 Miguel Angel Astor Romero - * - * 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 ve.ucv.ciens.ccg.nxtar.states; - -import ve.ucv.ciens.ccg.nxtar.NxtARCore.game_states_t; -import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Input; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.OrthographicCamera; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.Texture.TextureFilter; -import com.badlogic.gdx.graphics.Texture.TextureWrap; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.NinePatch; -import com.badlogic.gdx.graphics.g2d.Sprite; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.math.Vector3; -import com.badlogic.gdx.scenes.scene2d.ui.TextButton; -import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle; -import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable; - -public abstract class MainMenuStateBase extends BaseState{ - protected static final String TAG = "MAIN_MENU"; - private static final String CLASS_NAME = MainMenuStateBase.class.getSimpleName(); - private static final String SHADER_PATH = "shaders/bckg/bckg"; - - protected final int NUM_MENU_BUTTONS = 2; - - // Helper fields. - protected boolean clientConnected; - private float u_scaling[]; - - // Buttons and other gui components. - protected TextButton startButton; - protected Rectangle startButtonBBox; - protected Sprite clientConnectedLedOn; - protected Sprite clientConnectedLedOff; - - protected TextButton calibrationButton; - protected Rectangle calibrationButtonBBox; - protected Sprite cameraCalibratedLedOn; - protected Sprite cameraCalibratedLedOff; - - protected Sprite background; - - // Graphic data for the start button. - private Texture menuButtonEnabledTexture; - private Texture menuButtonDisabledTexture; - private Texture menuButtonPressedTexture; - private NinePatch menuButtonEnabled9p; - private NinePatch menuButtonDisabled9p; - private NinePatch menuButtonPressed9p; - private BitmapFont font; - - // Other graphics. - private Texture cameraCalibratedLedOffTexture; - private Texture cameraCalibratedLedOnTexture; - private Texture clientConnectedLedOffTexture; - private Texture clientConnectedLedOnTexture; - private Texture backgroundTexture; - private ShaderProgram backgroundShader; - - // Button touch helper fields. - protected boolean startButtonTouched; - protected int startButtonTouchPointer; - protected boolean calibrationButtonTouched; - protected int calibrationButtonTouchPointer; - - public MainMenuStateBase(){ - TextureRegion region; - TextButtonStyle tbs; - FreeTypeFontGenerator generator; - - this.pixelPerfectCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); - - // Create the start button background. - menuButtonEnabledTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Yellow.png")); - menuButtonEnabled9p = new NinePatch(new TextureRegion(menuButtonEnabledTexture, 0, 0, menuButtonEnabledTexture.getWidth(), menuButtonEnabledTexture.getHeight()), 49, 49, 45, 45); - - menuButtonDisabledTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Cyan.png")); - menuButtonDisabled9p = new NinePatch(new TextureRegion(menuButtonDisabledTexture, 0, 0, menuButtonDisabledTexture.getWidth(), menuButtonDisabledTexture.getHeight()), 49, 49, 45, 45); - - menuButtonPressedTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Blue.png")); - menuButtonPressed9p = new NinePatch(new TextureRegion(menuButtonPressedTexture, 0, 0, menuButtonPressedTexture.getWidth(), menuButtonPressedTexture.getHeight()), 49, 49, 45, 45); - - // Create the start button font. - generator = new FreeTypeFontGenerator(Gdx.files.internal("data/fonts/d-puntillas-B-to-tiptoe.ttf")); - font = generator.generateFont(ProjectConstants.MENU_BUTTON_FONT_SIZE, ProjectConstants.FONT_CHARS, false); - generator.dispose(); - - // Create the start button. - tbs = new TextButtonStyle(); - tbs.font = font; - tbs.up = new NinePatchDrawable(menuButtonEnabled9p); - tbs.checked = new NinePatchDrawable(menuButtonPressed9p); - tbs.disabled = new NinePatchDrawable(menuButtonDisabled9p); - tbs.disabledFontColor = new Color(0, 0, 0, 1); - - startButton = new TextButton("Start server", tbs); - startButton.setText("Start game"); - startButton.setDisabled(true); - startButtonBBox = new Rectangle(0, 0, startButton.getWidth(), startButton.getHeight()); - - // Create the calibration button. - calibrationButton = new TextButton("Calibrate camera", tbs); - calibrationButton.setText("Calibrate camera"); - calibrationButton.setDisabled(true); - calibrationButtonBBox = new Rectangle(0, 0, calibrationButton.getWidth(), calibrationButton.getHeight()); - - // Create the connection leds. - clientConnectedLedOnTexture = new Texture("data/gfx/gui/Anonymous_Button_Green.png"); - region = new TextureRegion(clientConnectedLedOnTexture); - clientConnectedLedOn = new Sprite(region); - - clientConnectedLedOffTexture = new Texture("data/gfx/gui/Anonymous_Button_Red.png"); - region = new TextureRegion(clientConnectedLedOffTexture); - clientConnectedLedOff = new Sprite(region); - - cameraCalibratedLedOnTexture = new Texture("data/gfx/gui/Anonymous_Button_Green.png"); - region = new TextureRegion(cameraCalibratedLedOnTexture); - cameraCalibratedLedOn = new Sprite(region); - - cameraCalibratedLedOffTexture = new Texture("data/gfx/gui/Anonymous_Button_Red.png"); - region = new TextureRegion(cameraCalibratedLedOffTexture); - cameraCalibratedLedOff = new Sprite(region); - - // Set up the background. - backgroundTexture = new Texture(Gdx.files.internal("data/gfx/textures/tile_aqua.png")); - backgroundTexture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat); - backgroundTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear); - region = new TextureRegion(backgroundTexture); - background = new Sprite(backgroundTexture); - background.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); - background.setPosition(-(Gdx.graphics.getWidth() / 2), -(Gdx.graphics.getHeight() / 2)); - - backgroundShader = new ShaderProgram(Gdx.files.internal(SHADER_PATH + "_vert.glsl"), Gdx.files.internal(SHADER_PATH + "_frag.glsl")); - if(!backgroundShader.isCompiled()){ - Gdx.app.error(TAG, CLASS_NAME + ".MainMenuStateBase() :: Failed to compile the background shader."); - Gdx.app.error(TAG, CLASS_NAME + backgroundShader.getLog()); - backgroundShader = null; - } - - u_scaling = new float[2]; - u_scaling[0] = Gdx.graphics.getWidth() > Gdx.graphics.getHeight() ? 16.0f : 9.0f; - u_scaling[1] = Gdx.graphics.getHeight() > Gdx.graphics.getWidth() ? 16.0f : 9.0f; - - - win2world = new Vector3(0.0f, 0.0f, 0.0f); - touchPointWorldCoords = new Vector2(); - startButtonTouched = false; - startButtonTouchPointer = -1; - calibrationButtonTouched = false; - calibrationButtonTouchPointer = -1; - - clientConnected = false; - stateActive = false; - } - - @Override - public abstract void render(float delta); - - @Override - public void resize(int width, int height){ } - - @Override - public void show(){ } - @Override - public void hide(){ } - - @Override - public void pause(){ } - - @Override - public void resume(){ } - - @Override - public void dispose(){ - menuButtonEnabledTexture.dispose(); - menuButtonDisabledTexture.dispose(); - menuButtonPressedTexture.dispose(); - clientConnectedLedOnTexture.dispose(); - clientConnectedLedOffTexture.dispose(); - cameraCalibratedLedOnTexture.dispose(); - cameraCalibratedLedOffTexture.dispose(); - backgroundTexture.dispose(); - if(backgroundShader != null) backgroundShader.dispose(); - font.dispose(); - } - - protected void drawBackground(SpriteBatch batch){ - if(backgroundShader != null){ - batch.setShader(backgroundShader); - backgroundShader.setUniform2fv("u_scaling", u_scaling, 0, 2); - } - background.draw(batch); - if(backgroundShader != null) batch.setShader(null); - } - - @Override - public void onStateSet(){ - stateActive = true; - Gdx.input.setInputProcessor(this); - Gdx.input.setCatchBackKey(true); - Gdx.input.setCatchMenuKey(true); - } - - @Override - public void onStateUnset(){ - stateActive = false; - Gdx.input.setInputProcessor(null); - Gdx.input.setCatchBackKey(false); - Gdx.input.setCatchMenuKey(false); - } - - public void onClientConnected(){ - clientConnected = true; - startButton.setDisabled(false); - calibrationButton.setDisabled(false); - } - - /*;;;;;;;;;;;;;;;;;;;;;;;;;; - ; INPUT LISTENER METHODS ; - ;;;;;;;;;;;;;;;;;;;;;;;;;;*/ - - @Override - public boolean touchDown(int screenX, int screenY, int pointer, int button){ - unprojectTouch(screenX, screenY); - - Gdx.app.log(TAG, CLASS_NAME + String.format(".touchDown(%d, %d, %d, %d)", screenX, screenY, pointer, button)); - Gdx.app.log(TAG, CLASS_NAME + String.format(".touchDown() :: Unprojected touch point: (%f, %f)", touchPointWorldCoords.x, touchPointWorldCoords.y)); - - if(!startButton.isDisabled() && startButtonBBox.contains(touchPointWorldCoords) && !calibrationButtonTouched){ - startButton.setChecked(true); - startButtonTouched = true; - startButtonTouchPointer = pointer; - Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Start button pressed."); - }else if(!calibrationButton.isDisabled() && calibrationButtonBBox.contains(touchPointWorldCoords) && !startButtonTouched){ - calibrationButton.setChecked(true); - calibrationButtonTouched = true; - calibrationButtonTouchPointer = pointer; - Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Calibration button pressed."); - } - - return true; - } - - @Override - public boolean touchUp(int screenX, int screenY, int pointer, int button){ - unprojectTouch(screenX, screenY); - - Gdx.app.log(TAG, CLASS_NAME + String.format(".touchUp(%d, %d, %d, %d)", screenX, screenY, pointer, button)); - Gdx.app.log(TAG, CLASS_NAME + String.format(".touchUp() :: Unprojected touch point: (%f, %f)", touchPointWorldCoords.x, touchPointWorldCoords.y)); - - if(!startButton.isDisabled() && startButtonBBox.contains(touchPointWorldCoords) && startButtonTouched){ - startButton.setChecked(false); - startButtonTouched = false; - startButtonTouchPointer = -1; - core.nextState = game_states_t.IN_GAME; - Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Start button released."); - }else if(!calibrationButton.isDisabled() && calibrationButtonBBox.contains(touchPointWorldCoords) && calibrationButtonTouched){ - calibrationButton.setChecked(false); - calibrationButtonTouched = false; - calibrationButtonTouchPointer = -1; - core.nextState = game_states_t.CALIBRATION; - Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Calibration button released."); - } - - return true; - } - - @Override - public boolean touchDragged(int screenX, int screenY, int pointer){ - unprojectTouch(screenX, screenY); - - if(!startButton.isDisabled() && startButtonTouched && pointer == startButtonTouchPointer && !startButtonBBox.contains(touchPointWorldCoords)){ - startButtonTouchPointer = -1; - startButtonTouched = false; - startButton.setChecked(false); - Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Start button released."); - }else if(!calibrationButton.isDisabled() && calibrationButtonTouched && pointer == calibrationButtonTouchPointer && !calibrationButtonBBox.contains(touchPointWorldCoords)){ - calibrationButtonTouchPointer = -1; - calibrationButtonTouched = false; - calibrationButton.setChecked(false); - Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Start button released."); - } - - return true; - } - - @Override - public boolean keyDown(int keycode){ - if(keycode == Input.Keys.BACK){ - // Ignore. - return true; - } - return false; - } -} +/* + * Copyright (C) 2014 Miguel Angel Astor Romero + * + * 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 ve.ucv.ciens.ccg.nxtar.states; + +import ve.ucv.ciens.ccg.nxtar.NxtARCore.game_states_t; +import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.Texture.TextureFilter; +import com.badlogic.gdx.graphics.Texture.TextureWrap; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.NinePatch; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter; +import com.badlogic.gdx.graphics.glutils.ShaderProgram; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle; +import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable; + +public abstract class MainMenuStateBase extends BaseState{ + protected static final String TAG = "MAIN_MENU"; + private static final String CLASS_NAME = MainMenuStateBase.class.getSimpleName(); + private static final String SHADER_PATH = "shaders/bckg/bckg"; + + protected final int NUM_MENU_BUTTONS = 2; + + // Helper fields. + protected boolean clientConnected; + private float u_scaling[]; + + // Buttons and other gui components. + protected TextButton startButton; + protected Rectangle startButtonBBox; + protected Sprite clientConnectedLedOn; + protected Sprite clientConnectedLedOff; + + protected TextButton calibrationButton; + protected Rectangle calibrationButtonBBox; + protected Sprite cameraCalibratedLedOn; + protected Sprite cameraCalibratedLedOff; + + protected Sprite background; + + // Graphic data for the start button. + private Texture menuButtonEnabledTexture; + private Texture menuButtonDisabledTexture; + private Texture menuButtonPressedTexture; + private NinePatch menuButtonEnabled9p; + private NinePatch menuButtonDisabled9p; + private NinePatch menuButtonPressed9p; + private BitmapFont font; + + // Other graphics. + private Texture cameraCalibratedLedOffTexture; + private Texture cameraCalibratedLedOnTexture; + private Texture clientConnectedLedOffTexture; + private Texture clientConnectedLedOnTexture; + private Texture backgroundTexture; + private ShaderProgram backgroundShader; + + // Button touch helper fields. + protected boolean startButtonTouched; + protected int startButtonTouchPointer; + protected boolean calibrationButtonTouched; + protected int calibrationButtonTouchPointer; + + public MainMenuStateBase(){ + TextureRegion region; + TextButtonStyle tbs; + FreeTypeFontGenerator generator; + FreeTypeFontParameter param; + + this.pixelPerfectCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + + // Create the start button background. + menuButtonEnabledTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Yellow.png")); + menuButtonEnabled9p = new NinePatch(new TextureRegion(menuButtonEnabledTexture, 0, 0, menuButtonEnabledTexture.getWidth(), menuButtonEnabledTexture.getHeight()), 49, 49, 45, 45); + + menuButtonDisabledTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Cyan.png")); + menuButtonDisabled9p = new NinePatch(new TextureRegion(menuButtonDisabledTexture, 0, 0, menuButtonDisabledTexture.getWidth(), menuButtonDisabledTexture.getHeight()), 49, 49, 45, 45); + + menuButtonPressedTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Blue.png")); + menuButtonPressed9p = new NinePatch(new TextureRegion(menuButtonPressedTexture, 0, 0, menuButtonPressedTexture.getWidth(), menuButtonPressedTexture.getHeight()), 49, 49, 45, 45); + + // Create the start button font. + param = new FreeTypeFontParameter(); + param.characters = ProjectConstants.FONT_CHARS; + param.size = ProjectConstants.MENU_BUTTON_FONT_SIZE; + param.flip = false; + generator = new FreeTypeFontGenerator(Gdx.files.internal("data/fonts/d-puntillas-B-to-tiptoe.ttf")); + font = generator.generateFont(param); + generator.dispose(); + + // Create the start button. + tbs = new TextButtonStyle(); + tbs.font = font; + tbs.up = new NinePatchDrawable(menuButtonEnabled9p); + tbs.checked = new NinePatchDrawable(menuButtonPressed9p); + tbs.disabled = new NinePatchDrawable(menuButtonDisabled9p); + tbs.disabledFontColor = new Color(0, 0, 0, 1); + + startButton = new TextButton("Start server", tbs); + startButton.setText("Start game"); + startButton.setDisabled(true); + startButtonBBox = new Rectangle(0, 0, startButton.getWidth(), startButton.getHeight()); + + // Create the calibration button. + calibrationButton = new TextButton("Calibrate camera", tbs); + calibrationButton.setText("Calibrate camera"); + calibrationButton.setDisabled(true); + calibrationButtonBBox = new Rectangle(0, 0, calibrationButton.getWidth(), calibrationButton.getHeight()); + + // Create the connection leds. + clientConnectedLedOnTexture = new Texture("data/gfx/gui/Anonymous_Button_Green.png"); + region = new TextureRegion(clientConnectedLedOnTexture); + clientConnectedLedOn = new Sprite(region); + + clientConnectedLedOffTexture = new Texture("data/gfx/gui/Anonymous_Button_Red.png"); + region = new TextureRegion(clientConnectedLedOffTexture); + clientConnectedLedOff = new Sprite(region); + + cameraCalibratedLedOnTexture = new Texture("data/gfx/gui/Anonymous_Button_Green.png"); + region = new TextureRegion(cameraCalibratedLedOnTexture); + cameraCalibratedLedOn = new Sprite(region); + + cameraCalibratedLedOffTexture = new Texture("data/gfx/gui/Anonymous_Button_Red.png"); + region = new TextureRegion(cameraCalibratedLedOffTexture); + cameraCalibratedLedOff = new Sprite(region); + + // Set up the background. + backgroundTexture = new Texture(Gdx.files.internal("data/gfx/textures/tile_aqua.png")); + backgroundTexture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat); + backgroundTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear); + region = new TextureRegion(backgroundTexture); + background = new Sprite(backgroundTexture); + background.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + background.setPosition(-(Gdx.graphics.getWidth() / 2), -(Gdx.graphics.getHeight() / 2)); + + backgroundShader = new ShaderProgram(Gdx.files.internal(SHADER_PATH + "_vert.glsl"), Gdx.files.internal(SHADER_PATH + "_frag.glsl")); + if(!backgroundShader.isCompiled()){ + Gdx.app.error(TAG, CLASS_NAME + ".MainMenuStateBase() :: Failed to compile the background shader."); + Gdx.app.error(TAG, CLASS_NAME + backgroundShader.getLog()); + backgroundShader = null; + } + + u_scaling = new float[2]; + u_scaling[0] = Gdx.graphics.getWidth() > Gdx.graphics.getHeight() ? 16.0f : 9.0f; + u_scaling[1] = Gdx.graphics.getHeight() > Gdx.graphics.getWidth() ? 16.0f : 9.0f; + + + win2world = new Vector3(0.0f, 0.0f, 0.0f); + touchPointWorldCoords = new Vector2(); + startButtonTouched = false; + startButtonTouchPointer = -1; + calibrationButtonTouched = false; + calibrationButtonTouchPointer = -1; + + clientConnected = false; + stateActive = false; + } + + @Override + public abstract void render(float delta); + + @Override + public void resize(int width, int height){ } + + @Override + public void show(){ } + @Override + public void hide(){ } + + @Override + public void pause(){ } + + @Override + public void resume(){ } + + @Override + public void dispose(){ + menuButtonEnabledTexture.dispose(); + menuButtonDisabledTexture.dispose(); + menuButtonPressedTexture.dispose(); + clientConnectedLedOnTexture.dispose(); + clientConnectedLedOffTexture.dispose(); + cameraCalibratedLedOnTexture.dispose(); + cameraCalibratedLedOffTexture.dispose(); + backgroundTexture.dispose(); + if(backgroundShader != null) backgroundShader.dispose(); + font.dispose(); + } + + protected void drawBackground(SpriteBatch batch){ + if(backgroundShader != null){ + batch.setShader(backgroundShader); + backgroundShader.setUniform2fv("u_scaling", u_scaling, 0, 2); + } + background.draw(batch); + if(backgroundShader != null) batch.setShader(null); + } + + @Override + public void onStateSet(){ + stateActive = true; + Gdx.input.setInputProcessor(this); + Gdx.input.setCatchBackKey(true); + Gdx.input.setCatchMenuKey(true); + } + + @Override + public void onStateUnset(){ + stateActive = false; + Gdx.input.setInputProcessor(null); + Gdx.input.setCatchBackKey(false); + Gdx.input.setCatchMenuKey(false); + } + + public void onClientConnected(){ + clientConnected = true; + startButton.setDisabled(false); + calibrationButton.setDisabled(false); + } + + /*;;;;;;;;;;;;;;;;;;;;;;;;;; + ; INPUT LISTENER METHODS ; + ;;;;;;;;;;;;;;;;;;;;;;;;;;*/ + + @Override + public boolean touchDown(int screenX, int screenY, int pointer, int button){ + unprojectTouch(screenX, screenY); + + Gdx.app.log(TAG, CLASS_NAME + String.format(".touchDown(%d, %d, %d, %d)", screenX, screenY, pointer, button)); + Gdx.app.log(TAG, CLASS_NAME + String.format(".touchDown() :: Unprojected touch point: (%f, %f)", touchPointWorldCoords.x, touchPointWorldCoords.y)); + + if(!startButton.isDisabled() && startButtonBBox.contains(touchPointWorldCoords) && !calibrationButtonTouched){ + startButton.setChecked(true); + startButtonTouched = true; + startButtonTouchPointer = pointer; + Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Start button pressed."); + }else if(!calibrationButton.isDisabled() && calibrationButtonBBox.contains(touchPointWorldCoords) && !startButtonTouched){ + calibrationButton.setChecked(true); + calibrationButtonTouched = true; + calibrationButtonTouchPointer = pointer; + Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Calibration button pressed."); + } + + return true; + } + + @Override + public boolean touchUp(int screenX, int screenY, int pointer, int button){ + unprojectTouch(screenX, screenY); + + Gdx.app.log(TAG, CLASS_NAME + String.format(".touchUp(%d, %d, %d, %d)", screenX, screenY, pointer, button)); + Gdx.app.log(TAG, CLASS_NAME + String.format(".touchUp() :: Unprojected touch point: (%f, %f)", touchPointWorldCoords.x, touchPointWorldCoords.y)); + + if(!startButton.isDisabled() && startButtonBBox.contains(touchPointWorldCoords) && startButtonTouched){ + startButton.setChecked(false); + startButtonTouched = false; + startButtonTouchPointer = -1; + core.nextState = game_states_t.IN_GAME; + Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Start button released."); + }else if(!calibrationButton.isDisabled() && calibrationButtonBBox.contains(touchPointWorldCoords) && calibrationButtonTouched){ + calibrationButton.setChecked(false); + calibrationButtonTouched = false; + calibrationButtonTouchPointer = -1; + core.nextState = game_states_t.CALIBRATION; + Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Calibration button released."); + } + + return true; + } + + @Override + public boolean touchDragged(int screenX, int screenY, int pointer){ + unprojectTouch(screenX, screenY); + + if(!startButton.isDisabled() && startButtonTouched && pointer == startButtonTouchPointer && !startButtonBBox.contains(touchPointWorldCoords)){ + startButtonTouchPointer = -1; + startButtonTouched = false; + startButton.setChecked(false); + Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Start button released."); + }else if(!calibrationButton.isDisabled() && calibrationButtonTouched && pointer == calibrationButtonTouchPointer && !calibrationButtonBBox.contains(touchPointWorldCoords)){ + calibrationButtonTouchPointer = -1; + calibrationButtonTouched = false; + calibrationButton.setChecked(false); + Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Start button released."); + } + + return true; + } + + @Override + public boolean keyDown(int keycode){ + if(keycode == Input.Keys.BACK){ + // Ignore. + return true; + } + return false; + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/OuyaMainMenuState.java b/src/ve/ucv/ciens/ccg/nxtar/states/OuyaMainMenuState.java index 838b634..223c3a8 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/states/OuyaMainMenuState.java +++ b/src/ve/ucv/ciens/ccg/nxtar/states/OuyaMainMenuState.java @@ -21,7 +21,7 @@ import ve.ucv.ciens.ccg.nxtar.NxtARCore.game_states_t; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.controllers.Controller; import com.badlogic.gdx.controllers.mappings.Ouya; -import com.badlogic.gdx.graphics.GL10; +import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.graphics.g2d.TextureRegion; @@ -66,7 +66,7 @@ public class OuyaMainMenuState extends MainMenuStateBase{ @Override public void render(float delta) { Gdx.gl.glClearColor(1, 1, 1, 1); - Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); core.batch.setProjectionMatrix(pixelPerfectCamera.combined); core.batch.begin();{ diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/TabletMainMenuState.java b/src/ve/ucv/ciens/ccg/nxtar/states/TabletMainMenuState.java index 61afb16..84ebb63 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/states/TabletMainMenuState.java +++ b/src/ve/ucv/ciens/ccg/nxtar/states/TabletMainMenuState.java @@ -18,7 +18,7 @@ package ve.ucv.ciens.ccg.nxtar.states; import ve.ucv.ciens.ccg.nxtar.NxtARCore; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL10; +import com.badlogic.gdx.graphics.GL20; public class TabletMainMenuState extends MainMenuStateBase{ @@ -46,7 +46,7 @@ public class TabletMainMenuState extends MainMenuStateBase{ @Override public void render(float delta){ Gdx.gl.glClearColor(1, 1, 1, 1); - Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); core.batch.setProjectionMatrix(pixelPerfectCamera.combined); core.batch.begin();{ diff --git a/src/ve/ucv/ciens/ccg/nxtar/systems/AnimationSystem.java b/src/ve/ucv/ciens/ccg/nxtar/systems/AnimationSystem.java new file mode 100644 index 0000000..5e2f2a0 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/systems/AnimationSystem.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 Miguel Angel Astor Romero + * + * 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 ve.ucv.ciens.ccg.nxtar.systems; + +import ve.ucv.ciens.ccg.nxtar.components.AnimationComponent; + +import com.artemis.Aspect; +import com.artemis.ComponentMapper; +import com.artemis.Entity; +import com.artemis.annotations.Mapper; +import com.artemis.systems.EntityProcessingSystem; +import com.badlogic.gdx.Gdx; + +public class AnimationSystem extends EntityProcessingSystem { + @Mapper ComponentMapper animationMapper; + + @SuppressWarnings("unchecked") + public AnimationSystem(){ + super(Aspect.getAspectForAll(AnimationComponent.class)); + } + + @Override + protected void process(Entity e) { + AnimationComponent animation = animationMapper.get(e); + + if(animation.current != animation.next && animation.next >= 0 && animation.next < animation.animationsIds.size()){ + if(animation.loop) + animation.controller.setAnimation(animation.animationsIds.get(animation.next), -1); + else + animation.controller.setAnimation(animation.animationsIds.get(animation.next)); + } + + animation.controller.update(Gdx.graphics.getDeltaTime()); + } + +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/systems/CollisionDetectionSystem.java b/src/ve/ucv/ciens/ccg/nxtar/systems/CollisionDetectionSystem.java new file mode 100644 index 0000000..c53eaaa --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/systems/CollisionDetectionSystem.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2014 Miguel Angel Astor Romero + * + * 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 ve.ucv.ciens.ccg.nxtar.systems; + +import ve.ucv.ciens.ccg.nxtar.components.ModelComponent; + +import com.artemis.Aspect; +import com.artemis.Entity; +import com.artemis.systems.EntityProcessingSystem; + +public class CollisionDetectionSystem extends EntityProcessingSystem { + + @SuppressWarnings("unchecked") + public CollisionDetectionSystem(){ + super(Aspect.getAspectForAll(ModelComponent.class)); + } + + @Override + protected void process(Entity e) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerPositioningSystem.java b/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerPositioningSystem.java index f544007..bfde1da 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerPositioningSystem.java +++ b/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerPositioningSystem.java @@ -62,17 +62,16 @@ public class MarkerPositioningSystem extends EntityProcessingSystem { Gdx.app.log(TAG, CLASS_NAME + ".process(): Processing markers."); for(int i = 0; i < ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS; i++){ if(markers.markerCodes[i] != 1){ + Gdx.app.log(TAG, CLASS_NAME + ".process(): Checking marker code: " + Integer.toString(markers.markerCodes[i])); + Gdx.app.log(TAG, CLASS_NAME + ".process(): This entity's code is: " + Integer.toString(marker.code)); if(markers.markerCodes[i] == marker.code){ Gdx.app.log(TAG, CLASS_NAME + ".process(): Processing marker code " + Integer.toString(markers.markerCodes[i]) + "."); geometry.position.set(markers.translationVectors[i]); geometry.rotation.set(markers.rotationMatrices[i]); - break; } }else{ Gdx.app.log(TAG, CLASS_NAME + ".process(): Skipping marker number " + Integer.toString(i) + "."); } } - - markers = null; } } diff --git a/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerRenderingSystem.java b/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerRenderingSystem.java index 2f72ac8..d2058bc 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerRenderingSystem.java +++ b/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerRenderingSystem.java @@ -1,10 +1,25 @@ +/* + * Copyright (C) 2014 Miguel Angel Astor Romero + * + * 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 ve.ucv.ciens.ccg.nxtar.systems; +import ve.ucv.ciens.ccg.nxtar.components.EnvironmentComponent; import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent; import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent; -import ve.ucv.ciens.ccg.nxtar.components.MeshComponent; +import ve.ucv.ciens.ccg.nxtar.components.ModelComponent; import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent; -import ve.ucv.ciens.ccg.nxtar.graphics.RenderParameters; import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.MarkerData; import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants; @@ -14,16 +29,18 @@ import com.artemis.Entity; import com.artemis.annotations.Mapper; import com.artemis.systems.EntityProcessingSystem; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.PerspectiveCamera; +import com.badlogic.gdx.graphics.g3d.ModelBatch; import com.badlogic.gdx.math.Matrix4; public class MarkerRenderingSystem extends EntityProcessingSystem { - @Mapper ComponentMapper markerMapper; - @Mapper ComponentMapper geometryMapper; - @Mapper ComponentMapper shaderMapper; - @Mapper ComponentMapper meshMapper; + @Mapper ComponentMapper markerMapper; + @Mapper ComponentMapper geometryMapper; + @Mapper ComponentMapper modelMapper; + @Mapper ComponentMapper environmentMapper; + @Mapper ComponentMapper shaderMapper; - private static final String TAG = "MARKER_RENDERING_SYSTEM"; + private static final String TAG = "MODEL_BATCH_MARKER_RENDERING_SYSTEM"; private static final String CLASS_NAME = MarkerRenderingSystem.class.getSimpleName(); /** @@ -41,43 +58,59 @@ public class MarkerRenderingSystem extends EntityProcessingSystem { */ private Matrix4 scalingMatrix; - /** - *

The total transformation to be applied to an entity.

- */ - private Matrix4 combinedTransformationMatrix; + private MarkerData markers; - MarkerData markers; + private PerspectiveCamera camera; + + private ModelBatch batch; @SuppressWarnings("unchecked") - public MarkerRenderingSystem(){ - super(Aspect.getAspectForAll(MarkerCodeComponent.class, GeometryComponent.class, ShaderComponent.class, MeshComponent.class)); + public MarkerRenderingSystem(ModelBatch batch){ + super(Aspect.getAspectForAll(MarkerCodeComponent.class, GeometryComponent.class, ShaderComponent.class, EnvironmentComponent.class, ModelComponent.class)); - markers = null; + markers = null; + camera = null; + this.batch = batch; translationMatrix = new Matrix4().setToTranslation(0.0f, 0.0f, 0.0f); - rotationMatrix = new Matrix4().idt(); - scalingMatrix = new Matrix4().setToScaling(0.0f, 0.0f, 0.0f); - combinedTransformationMatrix = new Matrix4(); + rotationMatrix = new Matrix4().idt(); + scalingMatrix = new Matrix4().setToScaling(0.0f, 0.0f, 0.0f); } - public void setMarkerData(MarkerData markers){ + public void begin(PerspectiveCamera camera, MarkerData markers) throws RuntimeException{ + if(this.camera != null) + throw new RuntimeException("Begin called twice without calling end."); + + if(this.markers != null) + throw new RuntimeException("Begin called twice without calling end."); + this.markers = markers; + this.camera = camera; + batch.begin(camera); + } + + public void end(){ + batch.end(); + camera = null; + markers = null; } @Override protected void process(Entity e) { - MarkerCodeComponent marker; - GeometryComponent geometry; - ShaderComponent shaderComp; - MeshComponent meshComp; + MarkerCodeComponent marker; + GeometryComponent geometry; + EnvironmentComponent environment; + ModelComponent model; + ShaderComponent shader; - if(markers == null) + if(markers == null || camera == null) return; Gdx.app.log(TAG, CLASS_NAME + ".process(): Getting components."); - marker = markerMapper.get(e); - geometry = geometryMapper.get(e); - shaderComp = shaderMapper.get(e); - meshComp = meshMapper.get(e); + marker = markerMapper.get(e); + geometry = geometryMapper.get(e); + model = modelMapper.get(e); + environment = environmentMapper.get(e); + shader = shaderMapper.get(e); Gdx.app.log(TAG, CLASS_NAME + ".process(): Processing markers."); for(int i = 0; i < ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS; i++){ @@ -87,41 +120,39 @@ public class MarkerRenderingSystem extends EntityProcessingSystem { // Set the geometric transformations. translationMatrix.setToTranslation(geometry.position); - rotationMatrix.val[0] = geometry.rotation.val[0]; - rotationMatrix.val[1] = geometry.rotation.val[1]; - rotationMatrix.val[2] = geometry.rotation.val[2]; - rotationMatrix.val[3] = 0; - rotationMatrix.val[4] = geometry.rotation.val[3]; - rotationMatrix.val[5] = geometry.rotation.val[4]; - rotationMatrix.val[6] = geometry.rotation.val[5]; - rotationMatrix.val[7] = 0; - rotationMatrix.val[8] = geometry.rotation.val[6]; - rotationMatrix.val[9] = geometry.rotation.val[7]; - rotationMatrix.val[10] = geometry.rotation.val[8]; - rotationMatrix.val[11] = 0; - rotationMatrix.val[12] = 0; - rotationMatrix.val[13] = 0; - rotationMatrix.val[14] = 0; - rotationMatrix.val[15] = 1; + rotationMatrix.val[Matrix4.M00] = geometry.rotation.val[0]; + rotationMatrix.val[Matrix4.M10] = geometry.rotation.val[1]; + rotationMatrix.val[Matrix4.M20] = geometry.rotation.val[2]; + rotationMatrix.val[Matrix4.M30] = 0; + + rotationMatrix.val[Matrix4.M01] = geometry.rotation.val[3]; + rotationMatrix.val[Matrix4.M11] = geometry.rotation.val[4]; + rotationMatrix.val[Matrix4.M21] = geometry.rotation.val[5]; + rotationMatrix.val[Matrix4.M31] = 0; + + rotationMatrix.val[Matrix4.M02] = geometry.rotation.val[6]; + rotationMatrix.val[Matrix4.M12] = geometry.rotation.val[7]; + rotationMatrix.val[Matrix4.M22] = geometry.rotation.val[8]; + rotationMatrix.val[Matrix4.M32] = 0; + + rotationMatrix.val[Matrix4.M03] = 0; + rotationMatrix.val[Matrix4.M13] = 0; + rotationMatrix.val[Matrix4.M23] = 0; + rotationMatrix.val[Matrix4.M33] = 1; scalingMatrix.setToScaling(geometry.scaling); - combinedTransformationMatrix.idt().mul(translationMatrix).mul(rotationMatrix).mul(scalingMatrix); - RenderParameters.setTransformationMatrix(combinedTransformationMatrix); + + // Apply the geometric transformations to the model. + model.instance.transform.idt().mul(translationMatrix).mul(rotationMatrix).mul(scalingMatrix); + model.instance.calculateTransforms(); // Render the marker; - shaderComp.shader.getShaderProgram().begin();{ - shaderComp.shader.setUniforms(); - meshComp.model.render(shaderComp.shader.getShaderProgram(), GL20.GL_TRIANGLES); - }shaderComp.shader.getShaderProgram().end(); - - break; + batch.render(model.instance, environment.environment, shader.shader); } }else{ Gdx.app.log(TAG, CLASS_NAME + ".process(): Skipping marker number " + Integer.toString(i) + "."); } } - - markers = null; } } diff --git a/src/ve/ucv/ciens/ccg/nxtar/systems/ObjectRenderingSystem.java b/src/ve/ucv/ciens/ccg/nxtar/systems/ObjectRenderingSystem.java index 6d0b9d3..63a7d2b 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/systems/ObjectRenderingSystem.java +++ b/src/ve/ucv/ciens/ccg/nxtar/systems/ObjectRenderingSystem.java @@ -15,37 +15,30 @@ */ package ve.ucv.ciens.ccg.nxtar.systems; +import ve.ucv.ciens.ccg.nxtar.components.EnvironmentComponent; import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent; import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent; -import ve.ucv.ciens.ccg.nxtar.components.MeshComponent; +import ve.ucv.ciens.ccg.nxtar.components.ModelComponent; import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent; -import ve.ucv.ciens.ccg.nxtar.graphics.LightSource; -import ve.ucv.ciens.ccg.nxtar.graphics.RenderParameters; import com.artemis.Aspect; import com.artemis.ComponentMapper; import com.artemis.Entity; import com.artemis.annotations.Mapper; import com.artemis.systems.EntityProcessingSystem; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.PerspectiveCamera; +import com.badlogic.gdx.graphics.g3d.ModelBatch; import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Vector3; /** *

Entity processing system in charge of rendering 3D objects using OpenGL. The * entities to be rendered must have a geometry, shader and mesh component associated.

*/ public class ObjectRenderingSystem extends EntityProcessingSystem { - @Mapper ComponentMapper geometryMapper; - @Mapper ComponentMapper shaderMapper; - @Mapper ComponentMapper modelMapper; - - private static final Vector3 LIGHT_POSITION = new Vector3(2.0f, 2.0f, 4.0f); - private static final Color AMBIENT_COLOR = new Color(0.0f, 0.1f, 0.2f, 1.0f); - private static final Color DIFFUSE_COLOR = new Color(1.0f, 1.0f, 1.0f, 1.0f); - private static final Color SPECULAR_COLOR = new Color(1.0f, 0.8f, 0.0f, 1.0f); - private static final float SHINYNESS = 50.0f; + @Mapper ComponentMapper geometryMapper; + @Mapper ComponentMapper shaderMapper; + @Mapper ComponentMapper modelMapper; + @Mapper ComponentMapper environmentMapper; /** *

A matrix representing 3D translations.

@@ -62,21 +55,32 @@ public class ObjectRenderingSystem extends EntityProcessingSystem { */ private Matrix4 scalingMatrix; - /** - *

The total transformation to be applied to an entity.

- */ - private Matrix4 combinedTransformationMatrix; + private PerspectiveCamera camera; + + private ModelBatch batch; @SuppressWarnings("unchecked") - public ObjectRenderingSystem() { - super(Aspect.getAspectForAll(GeometryComponent.class, ShaderComponent.class, MeshComponent.class).exclude(MarkerCodeComponent.class)); - - RenderParameters.setLightSource1(new LightSource(LIGHT_POSITION, AMBIENT_COLOR, DIFFUSE_COLOR, SPECULAR_COLOR, SHINYNESS)); + public ObjectRenderingSystem(ModelBatch batch) { + super(Aspect.getAspectForAll(GeometryComponent.class, ShaderComponent.class, ModelComponent.class, EnvironmentComponent.class).exclude(MarkerCodeComponent.class)); + camera = null; + this.batch = batch; translationMatrix = new Matrix4().setToTranslation(0.0f, 0.0f, 0.0f); - rotationMatrix = new Matrix4().idt(); - scalingMatrix = new Matrix4().setToScaling(0.0f, 0.0f, 0.0f); - combinedTransformationMatrix = new Matrix4(); + rotationMatrix = new Matrix4().idt(); + scalingMatrix = new Matrix4().setToScaling(0.0f, 0.0f, 0.0f); + } + + public void begin(PerspectiveCamera camera) throws RuntimeException{ + if(this.camera != null) + throw new RuntimeException("Begin called twice without calling end."); + + this.camera = camera; + batch.begin(camera); + } + + public void end(){ + batch.end(); + camera = null; } /** @@ -87,28 +91,25 @@ public class ObjectRenderingSystem extends EntityProcessingSystem { */ @Override protected void process(Entity e) { - GeometryComponent geometryComponent; - ShaderComponent shaderComponent; - MeshComponent meshComponent; + EnvironmentComponent environment; + GeometryComponent geometryComponent; + ShaderComponent shaderComponent; + ModelComponent modelComponent; // Get the necessary components. geometryComponent = geometryMapper.get(e); - meshComponent = modelMapper.get(e); - shaderComponent = shaderMapper.get(e); + modelComponent = modelMapper.get(e); + shaderComponent = shaderMapper.get(e); + environment = environmentMapper.get(e); // Calculate the geometric transformation for this entity. translationMatrix.setToTranslation(geometryComponent.position); rotationMatrix.set(geometryComponent.rotation); scalingMatrix.setToScaling(geometryComponent.scaling); - combinedTransformationMatrix.idt().mul(translationMatrix).mul(rotationMatrix).mul(scalingMatrix); - - // Set up the global rendering parameters for this frame. - RenderParameters.setTransformationMatrix(combinedTransformationMatrix); + modelComponent.instance.transform.idt().mul(translationMatrix).mul(rotationMatrix).mul(scalingMatrix); + modelComponent.instance.calculateTransforms(); // Render this entity. - shaderComponent.shader.getShaderProgram().begin();{ - shaderComponent.shader.setUniforms(); - meshComponent.model.render(shaderComponent.shader.getShaderProgram(), GL20.GL_TRIANGLES); - }shaderComponent.shader.getShaderProgram().end(); + batch.render(modelComponent.instance, environment.environment, shaderComponent.shader); } }