diff --git a/src/ve/ucv/ciens/ccg/nxtar/components/GeometryComponent.java b/src/ve/ucv/ciens/ccg/nxtar/components/GeometryComponent.java new file mode 100644 index 0000000..1ca65a1 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/components/GeometryComponent.java @@ -0,0 +1,50 @@ +/* + * 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.math.Quaternion; +import com.badlogic.gdx.math.Vector3; + +public class GeometryComponent extends Component { + public Vector3 position; + public Quaternion rotation; + public Vector3 scaling; + + public GeometryComponent(){ + this.position = new Vector3(); + this.rotation = new Quaternion(new Vector3(1.0f, 0.0f, 0.0f), 0.0f); + this.scaling = new Vector3(1.0f, 1.0f, 1.0f); + } + + public GeometryComponent(Vector3 position){ + this.position = new Vector3(position); + this.rotation = new Quaternion(new Vector3(1.0f, 0.0f, 0.0f), 0.0f); + this.scaling = new Vector3(1.0f, 1.0f, 1.0f); + } + + public GeometryComponent(Quaternion rotation){ + this.position = new Vector3(); + this.rotation = new Quaternion(rotation); + this.scaling = new Vector3(1.0f, 1.0f, 1.0f); + } + + public GeometryComponent(Vector3 position, Quaternion rotation, Vector3 scaling){ + this.position = new Vector3(position); + this.rotation = new Quaternion(rotation); + this.scaling = new Vector3(scaling); + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/components/PositionComponent.java b/src/ve/ucv/ciens/ccg/nxtar/entities/EntityCreatorBase.java similarity index 61% rename from src/ve/ucv/ciens/ccg/nxtar/components/PositionComponent.java rename to src/ve/ucv/ciens/ccg/nxtar/entities/EntityCreatorBase.java index 3283512..a5a8fa0 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/components/PositionComponent.java +++ b/src/ve/ucv/ciens/ccg/nxtar/entities/EntityCreatorBase.java @@ -13,20 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ve.ucv.ciens.ccg.nxtar.components; +package ve.ucv.ciens.ccg.nxtar.entities; -import com.artemis.Component; -import com.badlogic.gdx.math.Vector3; +import com.artemis.World; -public class PositionComponent extends Component { - public Vector3 position; +public abstract class EntityCreatorBase { + protected World world; - public PositionComponent(){ - this.position = new Vector3(); + public void setWorld(World world) throws IllegalArgumentException{ + if(world == null) + throw new IllegalArgumentException("World cannot be null."); + + this.world = world; } - public PositionComponent(Vector3 position){ - this.position = new Vector3(); - this.position.set(position); - } + public abstract void createAllEntities(); + + public abstract void dispose(); } diff --git a/src/ve/ucv/ciens/ccg/nxtar/entities/TestGameEntityCreator.java b/src/ve/ucv/ciens/ccg/nxtar/entities/TestGameEntityCreator.java new file mode 100644 index 0000000..7a593f7 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/entities/TestGameEntityCreator.java @@ -0,0 +1,131 @@ +/* + * 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.entities; + +import ve.ucv.ciens.ccg.nxtar.components.ModelComponent; +import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent; +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 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.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.math.Quaternion; +import com.badlogic.gdx.math.Vector3; + +public class TestGameEntityCreator extends EntityCreatorBase { + private static final String TAG = "TEST_ENTITY_CREATOR"; + private static final String CLASS_NAME = TestGameEntityCreator.class.getSimpleName(); + + private MeshBuilder builder; + private Mesh sphereMesh; + private Mesh cubeMesh; + private Mesh capsuleMesh; + private CustomShaderBase singleLightPhongShader; + + @Override + public void createAllEntities() { + Entity sphere; + Entity cube; + Entity capsule1; + Entity capsule2; + + Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Started."); + + // Create the sphere. + 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); + builder.sphere(1.0f, 1.0f, 1.0f, 10, 10); + }sphereMesh = builder.end(); + + // Create the cube. + 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(0.2f, 0.5f, 1.0f, 1.0f); + builder.box(0.5f, 0.5f, 0.5f); + }cubeMesh = builder.end(); + + // Create the capsule. + 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); + builder.capsule(0.25f, 0.5f, 10); + }capsuleMesh = builder.end(); + + // Load the phong shader. + Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Loading the phong shader."); + try{ + singleLightPhongShader = new SingleLightPhongShader().loadShader(); + }catch(ShaderFailedToLoadException se){ + Gdx.app.error(TAG, CLASS_NAME + ".InGameState(): " + se.getMessage()); + Gdx.app.exit(); + } + + // Create the entities. + Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Creating the enitites."); + sphere = world.createEntity(); + sphere.addComponent(new GeometryComponent(new Vector3(0.5f, 0.5f, 0.0f))); + sphere.addComponent(new ModelComponent(sphereMesh)); + sphere.addComponent(new ShaderComponent(singleLightPhongShader)); + + cube = world.createEntity(); + cube.addComponent(new GeometryComponent(new Vector3(-0.5f, -0.5f, 0.0f), new Quaternion(new Vector3(1.0f, 1.0f, 0.0f), 0.0f), new Vector3(1.0f, 1.0f, 1.0f))); + cube.addComponent(new ModelComponent(cubeMesh)); + cube.addComponent(new ShaderComponent(singleLightPhongShader)); + + capsule1 = world.createEntity(); + capsule1.addComponent(new GeometryComponent(new Vector3(-0.5f, 0.5f, 0.0f), new Quaternion(new Vector3(1.0f, 0.0f, 0.0f), 0.0f), new Vector3(1.5f, 1.0f, 1.0f))); + capsule1.addComponent(new ModelComponent(capsuleMesh)); + capsule1.addComponent(new ShaderComponent(singleLightPhongShader)); + + capsule2 = world.createEntity(); + capsule2.addComponent(new GeometryComponent(new Vector3(0.5f, -0.5f, 0.0f), new Quaternion(new Vector3(0.0f, 1.0f, 0.0f), 0.0f), new Vector3(1.0f, 1.5f, 1.0f))); + capsule2.addComponent(new ModelComponent(capsuleMesh)); + capsule2.addComponent(new ShaderComponent(singleLightPhongShader)); + + // Add the entities to the world. + Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Adding entities to the world."); + sphere.addToWorld(); + cube.addToWorld(); + capsule1.addToWorld(); + capsule2.addToWorld(); + + Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Finished."); + } + + @Override + public void dispose() { + if(singleLightPhongShader != null && singleLightPhongShader.getShaderProgram() != null) + singleLightPhongShader.getShaderProgram().dispose(); + + if(sphereMesh != null) + sphereMesh.dispose(); + + if(cubeMesh != null) + cubeMesh.dispose(); + + if(capsuleMesh != null) + capsuleMesh.dispose(); + } + +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java b/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java index 0b6f3fc..0017dff 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java +++ b/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java @@ -19,25 +19,21 @@ import ve.ucv.ciens.ccg.networkdata.MotorEvent; import ve.ucv.ciens.ccg.networkdata.MotorEvent.motor_t; import ve.ucv.ciens.ccg.nxtar.NxtARCore; import ve.ucv.ciens.ccg.nxtar.NxtARCore.game_states_t; -import ve.ucv.ciens.ccg.nxtar.components.ModelComponent; -import ve.ucv.ciens.ccg.nxtar.components.PositionComponent; -import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent; -import ve.ucv.ciens.ccg.nxtar.exceptions.ShaderFailedToLoadException; -import ve.ucv.ciens.ccg.nxtar.graphics.shaders.SingleLightPhongShader; +import ve.ucv.ciens.ccg.nxtar.entities.EntityCreatorBase; +import ve.ucv.ciens.ccg.nxtar.entities.TestGameEntityCreator; +import ve.ucv.ciens.ccg.nxtar.graphics.RenderParameters; import ve.ucv.ciens.ccg.nxtar.interfaces.CVProcessor.CVMarkerData; 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.RenderSystem; +import ve.ucv.ciens.ccg.nxtar.systems.RenderingSystem; import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants; -import com.artemis.Entity; import com.artemis.World; 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.GL20; -import com.badlogic.gdx.graphics.Mesh; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.PerspectiveCamera; import com.badlogic.gdx.graphics.Pixmap; @@ -45,12 +41,8 @@ import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture.TextureFilter; import com.badlogic.gdx.graphics.Texture.TextureWrap; -import com.badlogic.gdx.graphics.VertexAttribute; -import com.badlogic.gdx.graphics.VertexAttributes; -import com.badlogic.gdx.graphics.VertexAttributes.Usage; import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.graphics.g3d.utils.MeshBuilder; import com.badlogic.gdx.graphics.glutils.FrameBuffer; import com.badlogic.gdx.graphics.glutils.ShaderProgram; import com.badlogic.gdx.math.Vector2; @@ -73,6 +65,7 @@ public class InGameState extends BaseState{ // Game objects. private World gameWorld; + private EntityCreatorBase entityCreator; // Cameras. private OrthographicCamera camera; @@ -95,9 +88,6 @@ public class InGameState extends BaseState{ private Sprite headB; private Sprite headC; - private MeshBuilder builder; - private Mesh mesh; - // Button touch helper fields. private boolean[] motorButtonsTouched; private int[] motorButtonsPointers; @@ -177,28 +167,13 @@ public class InGameState extends BaseState{ camera3D = null; frameBufferSprite = null; - 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); - builder.sphere(1.0f, 1.0f, 1.0f, 10, 10); - }mesh = builder.end(); - - // Set up Artemis. + // Set up the game world. gameWorld = new World(); + entityCreator = new TestGameEntityCreator(); + entityCreator.setWorld(gameWorld); - // TODO: Separate entity creation from the state class. - Entity e = gameWorld.createEntity(); - e.addComponent(new PositionComponent(new Vector3(0.5f, 0.5f, 0.0f))); - e.addComponent(new ModelComponent(mesh)); - try{ - e.addComponent(new ShaderComponent(new SingleLightPhongShader().loadShader())); - }catch(ShaderFailedToLoadException se){ - Gdx.app.error(TAG, CLASS_NAME + ".InGameState(): " + se.getMessage()); - Gdx.app.exit(); - } - e.addToWorld(); - - gameWorld.setSystem(new RenderSystem(), true); + entityCreator.createAllEntities(); + gameWorld.setSystem(new RenderingSystem(), true); gameWorld.initialize(); } @@ -249,8 +224,6 @@ public class InGameState extends BaseState{ camera3D.far = 100.0f; camera3D.lookAt(0.0f, 0.0f, 0.0f); camera3D.update(); - - gameWorld.getSystem(RenderSystem.class).setCamera(camera3D); } // Apply the undistortion method if the camera has been calibrated already. @@ -285,7 +258,9 @@ public class InGameState extends BaseState{ Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); // Render the current state of the game. - gameWorld.getSystem(RenderSystem.class).process(); + RenderParameters.setModelViewProjectionMatrix(camera3D.combined); + RenderParameters.setEyePosition(camera3D.position); + gameWorld.getSystem(RenderingSystem.class).process(); Gdx.gl.glDisable(GL20.GL_DEPTH_TEST); }frameBuffer.end(); @@ -354,6 +329,9 @@ public class InGameState extends BaseState{ @Override public void dispose(){ + if(entityCreator != null) + entityCreator.dispose(); + if(videoFrameTexture != null) videoFrameTexture.dispose(); @@ -370,9 +348,6 @@ public class InGameState extends BaseState{ if(frameBuffer != null) frameBuffer.dispose(); - - if(mesh != null) - mesh.dispose(); } /*;;;;;;;;;;;;;;;;;; diff --git a/src/ve/ucv/ciens/ccg/nxtar/systems/RenderSystem.java b/src/ve/ucv/ciens/ccg/nxtar/systems/RenderingSystem.java similarity index 67% rename from src/ve/ucv/ciens/ccg/nxtar/systems/RenderSystem.java rename to src/ve/ucv/ciens/ccg/nxtar/systems/RenderingSystem.java index 6b14287..28b48ff 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/systems/RenderSystem.java +++ b/src/ve/ucv/ciens/ccg/nxtar/systems/RenderingSystem.java @@ -15,8 +15,8 @@ */ package ve.ucv.ciens.ccg.nxtar.systems; +import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent; import ve.ucv.ciens.ccg.nxtar.components.ModelComponent; -import ve.ucv.ciens.ccg.nxtar.components.PositionComponent; import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent; import ve.ucv.ciens.ccg.nxtar.graphics.LightSource; import ve.ucv.ciens.ccg.nxtar.graphics.RenderParameters; @@ -28,54 +28,50 @@ 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.math.Matrix4; import com.badlogic.gdx.math.Vector3; -public class RenderSystem extends EntityProcessingSystem { - @Mapper ComponentMapper positionMapper; +public class RenderingSystem extends EntityProcessingSystem { + @Mapper ComponentMapper geometryMapper; @Mapper ComponentMapper shaderMapper; @Mapper ComponentMapper modelMapper; - private PerspectiveCamera camera; private Matrix4 translationMatrix; + private Matrix4 rotationMatrix; + private Matrix4 scalingMatrix; + private Matrix4 combinedTransformationMatrix; @SuppressWarnings("unchecked") - public RenderSystem() { - super(Aspect.getAspectForAll(PositionComponent.class, ShaderComponent.class, ModelComponent.class)); + public RenderingSystem() { + super(Aspect.getAspectForAll(GeometryComponent.class, ShaderComponent.class, ModelComponent.class)); - camera = null; RenderParameters.setLightSource1(new LightSource(new Vector3(2.0f, 2.0f, 4.0f), new Color(0.0f, 0.1f, 0.2f, 1.0f), new Color(1.0f, 1.0f, 1.0f, 1.0f), new Color(1.0f, 0.8f, 0.0f, 1.0f), 50.0f)); - } - public void setCamera(PerspectiveCamera camera) throws IllegalArgumentException { - if(camera == null) - throw new IllegalArgumentException("Camera should not be null."); - - this.camera = camera; translationMatrix = new Matrix4().setToTranslation(0.0f, 0.0f, 0.0f); + rotationMatrix = new Matrix4().setToRotation(1.0f, 0.0f, 0.0f, 0.0f); + scalingMatrix = new Matrix4().setToScaling(0.0f, 0.0f, 0.0f); + combinedTransformationMatrix = new Matrix4(); } @Override protected void process(Entity e) { - PositionComponent positionComponent; + GeometryComponent geometryComponent; ShaderComponent shaderComponent; ModelComponent modelComponent; - // If no camera has been assigned then skip this frame. - if(camera == null) - return; - - // Get the necesary components. - positionComponent = positionMapper.get(e); + // Get the necessary components. + geometryComponent = geometryMapper.get(e); modelComponent = modelMapper.get(e); shaderComponent = shaderMapper.get(e); + // Calculate the geometric transformation for this entity. + translationMatrix.setToTranslation(geometryComponent.position); + rotationMatrix.rotate(geometryComponent.rotation); + scalingMatrix.setToScaling(geometryComponent.scaling); + combinedTransformationMatrix.idt().mul(scalingMatrix).mul(rotationMatrix).mul(translationMatrix); + // Set up the global rendering parameters for this frame. - translationMatrix.setToTranslation(positionComponent.position); - RenderParameters.setTransformationMatrix(translationMatrix); - RenderParameters.setModelViewProjectionMatrix(camera.combined); - RenderParameters.setEyePosition(camera.position); + RenderParameters.setTransformationMatrix(combinedTransformationMatrix); // Render this entity. shaderComponent.shader.getShaderProgram().begin();{