From b7367427f630a2a0db76285d77d05755b223bee0 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 12 May 2014 11:37:58 -0430 Subject: [PATCH] Successfully incorporated Artemis. --- .../ccg/nxtar/components/ModelComponent.java | 27 ++++++ .../nxtar/components/PositionComponent.java | 32 +++++++ .../ccg/nxtar/components/ShaderComponent.java | 31 +++++++ .../ShaderFailedToLoadException.java | 24 ++++++ .../ciens/ccg/nxtar/graphics/LightSource.java | 58 ++++++++++++- .../ccg/nxtar/graphics/RenderParameters.java | 75 ++++++++++++++++ .../graphics/shaders/CustomShaderBase.java | 32 +++++++ .../shaders/SingleLightPhongShader.java | 58 +++++++++++++ .../ciens/ccg/nxtar/states/InGameState.java | 51 ++++++----- .../ciens/ccg/nxtar/systems/RenderSystem.java | 86 +++++++++++++++++++ 10 files changed, 448 insertions(+), 26 deletions(-) create mode 100644 src/ve/ucv/ciens/ccg/nxtar/components/ModelComponent.java create mode 100644 src/ve/ucv/ciens/ccg/nxtar/components/PositionComponent.java create mode 100644 src/ve/ucv/ciens/ccg/nxtar/components/ShaderComponent.java create mode 100644 src/ve/ucv/ciens/ccg/nxtar/exceptions/ShaderFailedToLoadException.java create mode 100644 src/ve/ucv/ciens/ccg/nxtar/graphics/RenderParameters.java create mode 100644 src/ve/ucv/ciens/ccg/nxtar/graphics/shaders/CustomShaderBase.java create mode 100644 src/ve/ucv/ciens/ccg/nxtar/graphics/shaders/SingleLightPhongShader.java create mode 100644 src/ve/ucv/ciens/ccg/nxtar/systems/RenderSystem.java 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..e3e6208 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/components/ModelComponent.java @@ -0,0 +1,27 @@ +/* + * 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.Mesh; + +public class ModelComponent extends Component { + public Mesh model; + + public ModelComponent(Mesh model){ + this.model = model; + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/components/PositionComponent.java b/src/ve/ucv/ciens/ccg/nxtar/components/PositionComponent.java new file mode 100644 index 0000000..3283512 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/components/PositionComponent.java @@ -0,0 +1,32 @@ +/* + * 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.Vector3; + +public class PositionComponent extends Component { + public Vector3 position; + + public PositionComponent(){ + this.position = new Vector3(); + } + + public PositionComponent(Vector3 position){ + this.position = new Vector3(); + this.position.set(position); + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/components/ShaderComponent.java b/src/ve/ucv/ciens/ccg/nxtar/components/ShaderComponent.java new file mode 100644 index 0000000..af0bdbc --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/components/ShaderComponent.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 ShaderComponent extends Component { + public CustomShaderBase shader; + + public ShaderComponent(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/exceptions/ShaderFailedToLoadException.java b/src/ve/ucv/ciens/ccg/nxtar/exceptions/ShaderFailedToLoadException.java new file mode 100644 index 0000000..c8ca5f3 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/exceptions/ShaderFailedToLoadException.java @@ -0,0 +1,24 @@ +/* + * 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.exceptions; + +public class ShaderFailedToLoadException extends Exception { + private static final long serialVersionUID = 9989L; + + public ShaderFailedToLoadException(String msg){ + super(msg); + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/graphics/LightSource.java b/src/ve/ucv/ciens/ccg/nxtar/graphics/LightSource.java index 5eb5521..d7dab46 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/graphics/LightSource.java +++ b/src/ve/ucv/ciens/ccg/nxtar/graphics/LightSource.java @@ -19,7 +19,7 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.math.Vector3; /** - *

A 3D point or directional light source.

+ *

A 3D light source.

*/ public class LightSource{ private Vector3 position; @@ -28,23 +28,54 @@ public class LightSource{ private Color specularColor; private float shinyness; + /** + *

Creates a default white light source positioned at (0,0,0).

+ */ public LightSource(){ position = new Vector3(0.0f, 0.0f, 0.0f); ambientColor = new Color(0.15f, 0.15f, 0.15f, 1.0f); diffuseColor = new Color(1.0f, 1.0f, 1.0f, 1.0f); + specularColor = new Color(1.0f, 1.0f, 1.0f, 1.0f); ambientColor = new Color(1.0f, 1.0f, 1.0f, 1.0f); shinyness = 10.0f; } + /** + *

Creates a white light source at the specified position.

+ * + * @param position The location of the light source. + */ public LightSource(Vector3 position){ + this.position = new Vector3(); + this.position.set(position); ambientColor = new Color(0.15f, 0.15f, 0.15f, 1.0f); diffuseColor = new Color(1.0f, 1.0f, 1.0f, 1.0f); + specularColor = new Color(1.0f, 1.0f, 1.0f, 1.0f); ambientColor = new Color(1.0f, 1.0f, 1.0f, 1.0f); shinyness = 10.0f; } - public LightSource(Vector3 position, Color ambientColor, Color diffuseColor, Color specularColor, float shinyness){ + /** + *

Creates a custom light source.

+ * + * @param position The location of the light source. + * @param ambientColor + * @param diffuseColor + * @param specularColor + * @param shinyness The shinyness component. Must be between (0.0, 128.0]. + * @throws IllegalArgumentException When shinyness is outside the valid range. + */ + public LightSource(Vector3 position, Color ambientColor, Color diffuseColor, Color specularColor, float shinyness) throws IllegalArgumentException { + if(shinyness <= 0.0 || shinyness > 128.0) + throw new IllegalArgumentException("Shinyness must be between (0.0, 128.0]."); + + this.position = new Vector3(); + this.ambientColor = new Color(); + this.diffuseColor = new Color(); + this.ambientColor = new Color(); + this.specularColor = new Color(); + this.position.set(position); this.ambientColor.set(ambientColor); this.diffuseColor.set(diffuseColor); @@ -52,6 +83,24 @@ public class LightSource{ this.shinyness = shinyness; } + public LightSource(LightSource light){ + this.position = new Vector3(); + this.ambientColor = new Color(); + this.diffuseColor = new Color(); + this.ambientColor = new Color(); + this.specularColor = new Color(); + + set(light); + } + + public void set(LightSource light){ + this.position.set(light.getPosition()); + this.ambientColor.set(light.getAmbientColor()); + this.diffuseColor.set(light.getDiffuseColor()); + this.specularColor.set(light.getSpecularColor()); + this.shinyness = light.shinyness; + } + public void setPosition(float x, float y, float z){ position.set(x, y, z); } @@ -84,7 +133,10 @@ public class LightSource{ this.specularColor.set(specularColor); } - public void setShinyness(float shinyness){ + public void setShinyness(float shinyness) throws IllegalArgumentException { + if(shinyness <= 0.0 || shinyness > 128.0) + throw new IllegalArgumentException("Shinyness must be between (0.0, 128.0]."); + this.shinyness = shinyness; } diff --git a/src/ve/ucv/ciens/ccg/nxtar/graphics/RenderParameters.java b/src/ve/ucv/ciens/ccg/nxtar/graphics/RenderParameters.java new file mode 100644 index 0000000..12fd477 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/graphics/RenderParameters.java @@ -0,0 +1,75 @@ +/* + * 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; + +import com.badlogic.gdx.math.Matrix4; +import com.badlogic.gdx.math.Vector3; + +public abstract class RenderParameters { + private static Matrix4 modelViewProjection; + private static Matrix4 geometricTransformation; + private static Vector3 eyePosition; + private static LightSource lightSource1; + private static LightSource lightSource2; + + static{ + modelViewProjection = new Matrix4(); + geometricTransformation = new Matrix4(); + eyePosition = new Vector3(0.0f, 0.0f, 1.4142f); + lightSource1 = new LightSource(); + lightSource2 = new LightSource(); + } + + public static synchronized void setModelViewProjectionMatrix(Matrix4 modelViewMatrix){ + modelViewProjection.set(modelViewMatrix); + } + + public static synchronized void setTransformationMatrix(Matrix4 transformationMatrix){ + geometricTransformation.set(transformationMatrix); + } + + public static synchronized void setEyePosition(Vector3 newEyePostition){ + eyePosition.set(newEyePostition); + } + + public static synchronized void setLightSource1(LightSource newLightSource1){ + lightSource1.set(newLightSource1); + } + + public static synchronized void setLightSource2(LightSource newLightSource2){ + lightSource2.set(newLightSource2); + } + + public static synchronized Matrix4 getModelViewProjectionMatrix(){ + return modelViewProjection; + } + + public static synchronized Matrix4 getTransformationMatrix(){ + return geometricTransformation; + } + + public static synchronized Vector3 getEyePosition(){ + return eyePosition; + } + + public static synchronized LightSource getLightSource1(){ + return lightSource1; + } + + public static synchronized LightSource getLightSource2(){ + return lightSource2; + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/graphics/shaders/CustomShaderBase.java b/src/ve/ucv/ciens/ccg/nxtar/graphics/shaders/CustomShaderBase.java new file mode 100644 index 0000000..648fb22 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/graphics/shaders/CustomShaderBase.java @@ -0,0 +1,32 @@ +/* + * 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 ve.ucv.ciens.ccg.nxtar.exceptions.ShaderFailedToLoadException; + +import com.badlogic.gdx.graphics.glutils.ShaderProgram; + +public abstract class CustomShaderBase{ + protected ShaderProgram shaderProgram; + + public abstract CustomShaderBase loadShader() throws ShaderFailedToLoadException; + + public abstract void setUniforms(); + + public ShaderProgram getShaderProgram(){ + return this.shaderProgram; + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/graphics/shaders/SingleLightPhongShader.java b/src/ve/ucv/ciens/ccg/nxtar/graphics/shaders/SingleLightPhongShader.java new file mode 100644 index 0000000..66dcd54 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/graphics/shaders/SingleLightPhongShader.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.graphics.shaders; + +import ve.ucv.ciens.ccg.nxtar.exceptions.ShaderFailedToLoadException; +import ve.ucv.ciens.ccg.nxtar.graphics.LightSource; +import ve.ucv.ciens.ccg.nxtar.graphics.RenderParameters; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.glutils.ShaderProgram; + +public class SingleLightPhongShader extends CustomShaderBase{ + private static String VERTEX_SHADER_PATH = "shaders/singleDiffuseLight/singleDiffuseLight_vert.glsl"; + private static String FRAGMENT_SHADER_PATH = "shaders/singleDiffuseLight/singleDiffuseLight_frag.glsl"; + + @Override + public SingleLightPhongShader loadShader() throws ShaderFailedToLoadException{ + shaderProgram = new ShaderProgram(Gdx.files.internal(VERTEX_SHADER_PATH), Gdx.files.internal(FRAGMENT_SHADER_PATH)); + + if(!shaderProgram.isCompiled()){ + throw new ShaderFailedToLoadException("SingleLightPerPixelPhongShader failed to load.\n" + shaderProgram.getLog()); + } + + return this; + } + + @Override + public void setUniforms(){ + LightSource light = RenderParameters.getLightSource1(); + float[] diffuseColor = {light.getDiffuseColor().r, light.getDiffuseColor().g, light.getDiffuseColor().b, light.getDiffuseColor().a}; + float[] ambientColor = {light.getAmbientColor().r, light.getAmbientColor().g, light.getAmbientColor().b, light.getAmbientColor().a}; + float[] specularColor = {light.getSpecularColor().r, light.getSpecularColor().g, light.getSpecularColor().b, light.getSpecularColor().a}; + float[] position = {light.getPosition().x, light.getPosition().y, light.getPosition().z, 0.0f}; + float[] shinyness = {light.getShinyness()}; + + shaderProgram.setUniformMatrix("u_projTrans", RenderParameters.getModelViewProjectionMatrix()); + shaderProgram.setUniformMatrix("u_geomTrans", RenderParameters.getTransformationMatrix()); + shaderProgram.setUniform4fv("u_lightPos", position, 0, 4); + shaderProgram.setUniform4fv("u_lightDiffuse", diffuseColor, 0, 4); + shaderProgram.setUniform4fv("u_specular", specularColor, 0, 4); + shaderProgram.setUniform4fv("u_ambient", ambientColor, 0, 4); + shaderProgram.setUniform1fv("u_shiny", shinyness, 0, 1); + shaderProgram.setUniformf("u_cameraPos", RenderParameters.getEyePosition()); + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java b/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java index a731ca3..0b6f3fc 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java +++ b/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java @@ -19,11 +19,18 @@ 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.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.utils.ProjectConstants; +import com.artemis.Entity; import com.artemis.World; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; @@ -90,7 +97,6 @@ public class InGameState extends BaseState{ private MeshBuilder builder; private Mesh mesh; - private ShaderProgram meshShader; // Button touch helper fields. private boolean[] motorButtonsTouched; @@ -177,22 +183,30 @@ public class InGameState extends BaseState{ builder.sphere(1.0f, 1.0f, 1.0f, 10, 10); }mesh = builder.end(); - meshShader = new ShaderProgram(Gdx.files.internal("shaders/singleDiffuseLight/singleDiffuseLight_vert.glsl"), Gdx.files.internal("shaders/singleDiffuseLight/singleDiffuseLight_frag.glsl")); - if(!meshShader.isCompiled()){ - Gdx.app.error(TAG, CLASS_NAME + ".InGameState(): " + meshShader.getLog()); - Gdx.app.exit(); - } - // Set up Artemis. gameWorld = new World(); - // TODO: Create entities and systems. + + // 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); + gameWorld.initialize(); } /*;;;;;;;;;;;;;;;;;;;;;; ; BASE STATE METHODS ; ;;;;;;;;;;;;;;;;;;;;;;*/ - + @Override public void render(float delta){ int w, h; @@ -235,6 +249,8 @@ 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. @@ -262,22 +278,14 @@ public class InGameState extends BaseState{ renderableVideoFrame.setOrigin(renderableVideoFrame.getWidth() / 2, renderableVideoFrame.getHeight() / 2); renderableVideoFrame.setPosition(0, 0); + // Set the 3D frame buffer for rendering. frameBuffer.begin();{ Gdx.gl.glEnable(GL20.GL_DEPTH_TEST); Gdx.gl.glClearColor(1, 1, 1, 0); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); - // TODO: Call rendering system. - // TODO: Move hardcoded uniforms to objects. - meshShader.begin();{ - meshShader.setUniformMatrix("u_projTrans", camera3D.combined); - meshShader.setUniform4fv("u_lightPos", new float[] {2.0f, 2.0f, 4.0f, 0.0f}, 0, 4); - meshShader.setUniform4fv("u_lightDiffuse", new float[] {1.0f, 1.0f, 1.0f, 1.0f}, 0, 4); - meshShader.setUniform4fv("u_ambient", new float[] {0.0f, 0.1f, 0.2f, 1.0f}, 0, 4); - meshShader.setUniform1fv("u_shiny", new float[] {50.0f}, 0, 1); - meshShader.setUniformf("u_cameraPos", camera3D.position); - mesh.render(meshShader, GL20.GL_TRIANGLES); - }meshShader.end(); + // Render the current state of the game. + gameWorld.getSystem(RenderSystem.class).process(); Gdx.gl.glDisable(GL20.GL_DEPTH_TEST); }frameBuffer.end(); @@ -363,9 +371,6 @@ public class InGameState extends BaseState{ if(frameBuffer != null) frameBuffer.dispose(); - if(meshShader != null) - meshShader.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/RenderSystem.java new file mode 100644 index 0000000..6b14287 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/systems/RenderSystem.java @@ -0,0 +1,86 @@ +/* + * 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 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; + +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.math.Matrix4; +import com.badlogic.gdx.math.Vector3; + +public class RenderSystem extends EntityProcessingSystem { + @Mapper ComponentMapper positionMapper; + @Mapper ComponentMapper shaderMapper; + @Mapper ComponentMapper modelMapper; + + private PerspectiveCamera camera; + private Matrix4 translationMatrix; + + @SuppressWarnings("unchecked") + public RenderSystem() { + super(Aspect.getAspectForAll(PositionComponent.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); + } + + @Override + protected void process(Entity e) { + PositionComponent positionComponent; + 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); + modelComponent = modelMapper.get(e); + shaderComponent = shaderMapper.get(e); + + // Set up the global rendering parameters for this frame. + translationMatrix.setToTranslation(positionComponent.position); + RenderParameters.setTransformationMatrix(translationMatrix); + RenderParameters.setModelViewProjectionMatrix(camera.combined); + RenderParameters.setEyePosition(camera.position); + + // Render this entity. + shaderComponent.shader.getShaderProgram().begin();{ + shaderComponent.shader.setUniforms(); + modelComponent.model.render(shaderComponent.shader.getShaderProgram(), GL20.GL_TRIANGLES); + }shaderComponent.shader.getShaderProgram().end(); + } +}