diff --git a/res/cube.blend b/res/cube.blend new file mode 100644 index 0000000..805b355 Binary files /dev/null and b/res/cube.blend differ diff --git a/res/cube.mtl b/res/cube.mtl new file mode 100644 index 0000000..2e61731 --- /dev/null +++ b/res/cube.mtl @@ -0,0 +1,12 @@ +# Blender MTL File: 'cube.blend' +# Material Count: 1 + +newmtl Material +Ns 323.999994 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 diff --git a/res/cube.obj b/res/cube.obj new file mode 100644 index 0000000..78064b5 --- /dev/null +++ b/res/cube.obj @@ -0,0 +1,46 @@ +# Blender v2.82 (sub 7) OBJ File: 'cube.blend' +# www.blender.org +mtllib cube.mtl +o Cube +v 1.000000 1.000000 -1.000000 +v 1.000000 -1.000000 -1.000000 +v 1.000000 1.000000 1.000000 +v 1.000000 -1.000000 1.000000 +v -1.000000 1.000000 -1.000000 +v -1.000000 -1.000000 -1.000000 +v -1.000000 1.000000 1.000000 +v -1.000000 -1.000000 1.000000 +vt 0.875000 0.500000 +vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.375000 1.000000 +vt 0.375000 0.750000 +vt 0.625000 0.000000 +vt 0.375000 0.250000 +vt 0.375000 0.000000 +vt 0.375000 0.500000 +vt 0.125000 0.750000 +vt 0.125000 0.500000 +vt 0.625000 0.250000 +vt 0.875000 0.750000 +vt 0.625000 1.000000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 -1.0000 0.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +usemtl Material +s off +f 5/1/1 3/2/1 1/3/1 +f 3/2/2 8/4/2 4/5/2 +f 7/6/3 6/7/3 8/8/3 +f 2/9/4 8/10/4 6/11/4 +f 1/3/5 4/5/5 2/9/5 +f 5/12/6 2/9/6 6/7/6 +f 5/1/1 7/13/1 3/2/1 +f 3/2/2 7/14/2 8/4/2 +f 7/6/3 5/12/3 6/7/3 +f 2/9/4 4/5/4 8/10/4 +f 1/3/5 3/2/5 4/5/5 +f 5/12/6 1/3/6 2/9/6 diff --git a/src/engineTester/MainGameLoop.java b/src/engineTester/MainGameLoop.java index da496fe..95aabf7 100644 --- a/src/engineTester/MainGameLoop.java +++ b/src/engineTester/MainGameLoop.java @@ -1,8 +1,14 @@ package engineTester; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + import javax.vecmath.Vector3f; +import org.lwjgl.openvr.Texture; + import entities.Camera; import entities.Entity; import entities.Light; @@ -11,6 +17,7 @@ import models.TexturedModel; import renderEngine.DisplayManager; import renderEngine.DisplayManagerDraw; import renderEngine.Loader; +import renderEngine.MasterRenderer; import renderEngine.OBJLoader; import renderEngine.Renderer; import shaders.StaticShader; @@ -36,41 +43,46 @@ public class MainGameLoop { DisplayManager manager = new DisplayManager(); Loader loader = new Loader(); manager.init(); - StaticShader shader = new StaticShader(); - Renderer renderer = new Renderer(shader); - RawModel model = OBJLoader.loadObjModel("dragon", loader); - - ModelTexture texture = new ModelTexture(loader.loadTexture("white")); - - TexturedModel staticModel = new TexturedModel(model, texture); + RawModel model = OBJLoader.loadObjModel("cube", loader); + TexturedModel cubeModel = new TexturedModel(model, new ModelTexture(loader.loadTexture("tree_sample"))); + ModelTexture texture = cubeModel.getTexture(); texture.setShineDamper(10); texture.setReflectivity(1); - Entity entity = new Entity(staticModel, new Vector3f(0,0,-25), new Vector3f(0,0,0), 1); Light light = new Light(new Vector3f(0,0,-20), new Vector3f(1,1,1)); Camera camera = new Camera(); + List allCubes = new ArrayList(); + Random random = new Random(); + + for (int iii=0; iii<2000; iii++) { + float x = random.nextFloat() * 300 - 150; + float y = random.nextFloat() * 300 - 150; + float z = random.nextFloat() * -300; + allCubes.add(new Entity(cubeModel, new Vector3f(x,y,z), + new Vector3f(random.nextFloat()*3.14f,random.nextFloat()*3.14f,0), 1)); + } + + MasterRenderer renderer = new MasterRenderer(); manager.setDrawer(new DisplayManagerDraw() { @Override public void draw() { //entity.increasePosition(0.0f, 0, -0.01f); //entity.increaseRotation(0, 0, 0.01f); - entity.increaseRotation(0.01f, 0.02f, 0.0f); + //entity.increaseRotation(0.01f, 0.02f, 0.0f); camera.move(); - renderer.prepare(); - shader.start(); - shader.loadLight(light); - shader.loadViewMatrix(camera); - renderer.render(entity, shader); - shader.stop(); + for (Entity cube : allCubes) { + renderer.processEntity(cube); + } + renderer.render(light, camera); } }); manager.loop(); - shader.cleanUp(); + renderer.cleanUp(); loader.cleanUp(); manager.unInit(); } diff --git a/src/entities/Camera.java b/src/entities/Camera.java index 7d64c63..b4a568f 100644 --- a/src/entities/Camera.java +++ b/src/entities/Camera.java @@ -14,17 +14,17 @@ public class Camera { } public void move() { - if (DisplayManager.isKeyDown('z')) { - position.x -= 0.02f; + if (DisplayManager.isKeyDown('w')) { + position.z -= 0.8f; } if (DisplayManager.isKeyDown('s')) { - position.x += 0.02f; + position.z += 0.8f; } if (DisplayManager.isKeyDown('d')) { - position.y -= 0.02f; + position.x += 0.8f; } - if (DisplayManager.isKeyDown('q')) { - position.y += 0.02f; + if (DisplayManager.isKeyDown('a')) { + position.x -= 0.8f; } } diff --git a/src/renderEngine/DisplayManager.java b/src/renderEngine/DisplayManager.java index b0c3205..a3a9127 100644 --- a/src/renderEngine/DisplayManager.java +++ b/src/renderEngine/DisplayManager.java @@ -104,6 +104,8 @@ public class DisplayManager { private static boolean valueZ = false; private static boolean valueQ = false; private static boolean valueD = false; + private static boolean valueA = false; + private static boolean valueW = false; public static boolean isKeyDown(char value) { if (value == 's') { return valueS; @@ -117,6 +119,12 @@ public class DisplayManager { if (value == 'd') { return valueD; } + if (value == 'w') { + return valueW; + } + if (value == 'a') { + return valueA; + } return false; } @@ -180,6 +188,24 @@ public class DisplayManager { valueD = false; } } + if ( key == GLFW_KEY_A ) { + if (action == GLFW_PRESS ) { + System.out.println("Key A is pressed"); + valueA = true; + } else if (action == GLFW_RELEASE ) { + System.out.println("Key A is release"); + valueA = false; + } + } + if ( key == GLFW_KEY_W ) { + if (action == GLFW_PRESS ) { + System.out.println("Key W is pressed"); + valueW = true; + } else if (action == GLFW_RELEASE ) { + System.out.println("Key W is release"); + valueW = false; + } + } }); // Get the thread stack and push a new frame diff --git a/src/renderEngine/MasterRenderer.java b/src/renderEngine/MasterRenderer.java new file mode 100644 index 0000000..abae0d1 --- /dev/null +++ b/src/renderEngine/MasterRenderer.java @@ -0,0 +1,45 @@ +package renderEngine; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import entities.Camera; +import entities.Entity; +import entities.Light; +import models.TexturedModel; +import shaders.StaticShader; + +public class MasterRenderer { + private StaticShader shader = new StaticShader(); + private Renderer renderer = new Renderer(shader); + + private Map> entities = new HashMap>(); + + public void render(Light sun, Camera camera) { + renderer.prepare(); + shader.start(); + shader.loadLight(sun); + shader.loadViewMatrix(camera); + renderer.render(entities); + shader.stop(); + entities.clear(); + } + + public void processEntity(Entity entity) { + TexturedModel entityModel = entity.getModel(); + List batch = entities.get(entityModel); + if (batch != null) { + batch.add(entity); + } else { + List newBatch = new ArrayList(); + newBatch.add(entity); + entities.put(entityModel, newBatch); + } + } + + public void cleanUp () { + shader.cleanUp(); + } +} diff --git a/src/renderEngine/Renderer.java b/src/renderEngine/Renderer.java index db0b014..02cb074 100644 --- a/src/renderEngine/Renderer.java +++ b/src/renderEngine/Renderer.java @@ -1,5 +1,8 @@ package renderEngine; +import java.util.List; +import java.util.Map; + import javax.vecmath.Matrix4f; import javax.vecmath.Vector2f; @@ -28,8 +31,11 @@ public class Renderer { private static final float NEAR_PLANE = 0.1f; private static final float FAR_PLANE = 10000; - private Matrix4f projectionMatrix; + private Matrix4f projectionMatrix; + private StaticShader shader; + public Renderer(StaticShader shader) { + this.shader = shader; createProjectionMatrix(); shader.start(); shader.loadProjectionMatrix(projectionMatrix); @@ -37,30 +43,50 @@ public class Renderer { } public void prepare() { + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glEnable(GL11.GL_BACK); GL11.glEnable(GL11.GL_DEPTH_TEST); GL11.glClearColor(1, 0, 0, 1); GL11.glClear(GL11.GL_COLOR_BUFFER_BIT|GL11.GL_DEPTH_BUFFER_BIT); } - public void render(Entity entity, StaticShader shader) { - TexturedModel texturedModel = entity.getModel(); - RawModel rawModel = texturedModel.getRawModel(); + public void render(Map> entities) { + for (TexturedModel model:entities.keySet()) { + prepareTexturedModel(model); + List batch = entities.get(model); + for (Entity entity:batch) { + prepareInstance(entity); + GL11.glDrawElements(GL11.GL_TRIANGLES, model.getRawModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0); + } + unbindTexturedModel(); + } + } + + private void prepareTexturedModel(TexturedModel model) { + RawModel rawModel = model.getRawModel(); GL30.glBindVertexArray(rawModel.getVaoID()); GL20.glEnableVertexAttribArray(0); GL20.glEnableVertexAttribArray(1); GL20.glEnableVertexAttribArray(2); - Matrix4f transformationMatrix = Maths.createTransformationMatrix(entity.getPosition(), entity.getRotation(), entity.getScale()); - shader.loadTransformationMatrix(transformationMatrix); - ModelTexture texture = texturedModel.getTexture(); + ModelTexture texture = model.getTexture(); shader.loadShineVariable(texture.getShineDamper(), texture.getReflectivity()); GL13.glActiveTexture(GL13.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, texturedModel.getTexture().getTexturedID()); - GL11.glDrawElements(GL11.GL_TRIANGLES, rawModel.getVertexCount(), GL11.GL_UNSIGNED_INT, 0); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, model.getTexture().getTexturedID()); + } + + private void unbindTexturedModel() { GL20.glDisableVertexAttribArray(0); GL20.glDisableVertexAttribArray(1); GL20.glDisableVertexAttribArray(2); GL30.glBindVertexArray(0); + } + + private void prepareInstance(Entity entity) { + Matrix4f transformationMatrix = Maths.createTransformationMatrix(entity.getPosition(), entity.getRotation(), entity.getScale()); + shader.loadTransformationMatrix(transformationMatrix); + } + private void createProjectionMatrix() { //float aspectRatio = (float) Display.getWidth() / (float) Display.getHeight(); diff --git a/src/shaders/fragmentShader.txt b/src/shaders/fragmentShader.txt index 1aa8cf7..325900b 100644 --- a/src/shaders/fragmentShader.txt +++ b/src/shaders/fragmentShader.txt @@ -19,7 +19,8 @@ void main(void) { vec3 unitLightVector = normalize(toLightVector); float nDot1 = dot(unitNormal, unitLightVector); - float brightness = max(nDot1, 0.0); + // the 0.2 represent the anbiant lightning ==> maybe set an uniform for this + float brightness = max(nDot1, 0.2); vec3 diffuse = brightness * lightColour; vec3 unitVectorToCamera = normalize(toCameraVector);