Renderer optimizations

This commit is contained in:
Sebastian 2023-08-11 20:28:43 +02:00
parent bf2b169563
commit 5912ac5a7c
3 changed files with 80 additions and 18 deletions

View File

@ -112,8 +112,6 @@ public class Engine {
// Set the clear color // Set the clear color
glClearColor(1.0f, 0.0f, 0.0f, 0.0f); glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
StaticShader shader = new StaticShader();
Camera camera = new Camera(); Camera camera = new Camera();
glfwSetKeyCallback(window, glfwKeyCallback = new GLFWKeyCallback() { glfwSetKeyCallback(window, glfwKeyCallback = new GLFWKeyCallback() {
@Override @Override
@ -138,7 +136,7 @@ public class Engine {
} }
}); });
Renderer renderer = new Renderer(shader);
Light light = new Light(new Vector3f(0,0,-20), new Vector3f(1,1,1)); Light light = new Light(new Vector3f(0,0,-20), new Vector3f(1,1,1));
RawModel model = OBJLoader.loadOBJModel("dragon", loader); RawModel model = OBJLoader.loadOBJModel("dragon", loader);
ModelTexture modelTexture = new ModelTexture(loader.loadTexture("white")); ModelTexture modelTexture = new ModelTexture(loader.loadTexture("white"));
@ -146,21 +144,18 @@ public class Engine {
Entity entity = new Entity(texturedModel, new Vector3f(0,0,-50), 0,0,0,1); Entity entity = new Entity(texturedModel, new Vector3f(0,0,-50), 0,0,0,1);
// Run the rendering loop until the user has attempted to close // Run the rendering loop until the user has attempted to close
// the window or has pressed the ESCAPE key. // the window or has pressed the ESCAPE key.
MasterRenderer renderer = new MasterRenderer();
while ( !glfwWindowShouldClose(window) ) { while ( !glfwWindowShouldClose(window) ) {
entity.increaseRotation(0,1,0); entity.increaseRotation(0,1,0);
renderer.prepare(); renderer.processEntity(entity);
shader.start(); renderer.render(light, camera);
shader.loadLight(light);
shader.loadViewMatrix(camera);
renderer.render(entity, shader);
shader.stop();
glfwSwapBuffers(window); // swap the color buffers glfwSwapBuffers(window); // swap the color buffers
// Poll for window events. The key callback above will only be // Poll for window events. The key callback above will only be
// invoked during this call. // invoked during this call.
glfwPollEvents(); glfwPollEvents();
} }
shader.cleanUp(); renderer.cleanUp();
loader.cleanUp(); loader.cleanUp();
} }

View File

@ -0,0 +1,45 @@
package core.engine;
import core.engine.entity.Camera;
import core.engine.entity.Entity;
import core.engine.entity.Light;
import core.engine.model.TexturedModel;
import core.engine.shader.StaticShader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MasterRenderer {
private StaticShader shader = new StaticShader();
private Renderer renderer = new Renderer(shader);
private Map<TexturedModel, List<Entity>> entities = new HashMap<>();
public void render(Light light, Camera camera) {
renderer.prepare();
shader.start();
shader.loadLight(light);
shader.loadViewMatrix(camera);
renderer.render(entities);
shader.stop();
entities.clear();
}
public void processEntity(Entity entity) {
TexturedModel entityModel = entity.getModel();
List<Entity> batch = entities.get(entityModel);
if(batch != null) {
batch.add(entity);
} else {
List<Entity> newBatch = new ArrayList<>();
newBatch.add(entity);
entities.put(entityModel, newBatch);
}
}
public void cleanUp() {
shader.cleanUp();
}
}

View File

@ -4,6 +4,7 @@ import core.engine.entity.Entity;
import core.engine.model.RawModel; import core.engine.model.RawModel;
import core.engine.model.TexturedModel; import core.engine.model.TexturedModel;
import core.engine.shader.StaticShader; import core.engine.shader.StaticShader;
import core.engine.textures.ModelTexture;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13; import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
@ -11,6 +12,9 @@ import org.lwjgl.opengl.GL30;
import utils.MatrixGraphicUtils; import utils.MatrixGraphicUtils;
import utils.vectors.Matrix4f; import utils.vectors.Matrix4f;
import java.util.List;
import java.util.Map;
import static org.lwjgl.opengl.GL11C.*; import static org.lwjgl.opengl.GL11C.*;
public class Renderer { public class Renderer {
@ -18,8 +22,10 @@ public class Renderer {
private static final float NEAR_PLEANE = 0.1f; private static final float NEAR_PLEANE = 0.1f;
private static final float FAR_PLANE = 1000; private static final float FAR_PLANE = 1000;
private Matrix4f projectionMatrix; private Matrix4f projectionMatrix;
private StaticShader shader;
public Renderer(StaticShader shader) { public Renderer(StaticShader shader) {
this.shader = shader;
GL11.glEnable(GL11.GL_CULL_FACE); GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glCullFace(GL11.GL_BACK); GL11.glCullFace(GL11.GL_BACK);
createProjectionMatrix(); createProjectionMatrix();
@ -34,25 +40,41 @@ public class Renderer {
GL11.glClearColor(5,195,221,1); GL11.glClearColor(5,195,221,1);
} }
public void render(Entity entity, StaticShader shader) { public void render(Map<TexturedModel, List<Entity>> entities) {
TexturedModel texturedModel = entity.getModel(); for(TexturedModel model: entities.keySet()) {
RawModel rawModel = texturedModel.getRawModel(); prepareTexturedModel(model);
List<Entity> 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()); GL30.glBindVertexArray(rawModel.getVaoID());
GL20.glEnableVertexAttribArray(0); GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1); GL20.glEnableVertexAttribArray(1);
GL20.glEnableVertexAttribArray(2); GL20.glEnableVertexAttribArray(2);
Matrix4f transformationMatrix = MatrixGraphicUtils.createTransformationMatrix(entity.getPosition(), entity.getRotX(),
entity.getRotY(), entity.getRotZ(), entity.getScale());
shader.loadTransformationMatrix(transformationMatrix);
GL13.glActiveTexture(GL13.GL_TEXTURE0); GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texturedModel.getModelTexture().getTextureID()); GL11.glBindTexture(GL11.GL_TEXTURE_2D, model.getModelTexture().getTextureID());
GL11.glDrawElements(GL11.GL_TRIANGLES, rawModel.getVertexCount(), GL11.GL_UNSIGNED_INT, 0); }
private void unbindTexturedModel() {
GL20.glDisableVertexAttribArray(0); GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1); GL20.glDisableVertexAttribArray(1);
GL20.glDisableVertexAttribArray(2); GL20.glDisableVertexAttribArray(2);
GL30.glBindVertexArray(0); GL30.glBindVertexArray(0);
} }
private void prepareInstance(Entity entity) {
Matrix4f transformationMatrix = MatrixGraphicUtils.createTransformationMatrix(entity.getPosition(), entity.getRotX(),
entity.getRotY(), entity.getRotZ(), entity.getScale());
shader.loadTransformationMatrix(transformationMatrix);
}
private void createProjectionMatrix() { private void createProjectionMatrix() {
float aspectRatio = (float) Engine.WINDOW_WIDTH / (float) Engine.WINDOW_HEIGHT; float aspectRatio = (float) Engine.WINDOW_WIDTH / (float) Engine.WINDOW_HEIGHT;
float y_scale = (float) ((1f / Math.tan(Math.toRadians(FOV / 2f))) * aspectRatio); float y_scale = (float) ((1f / Math.tan(Math.toRadians(FOV / 2f))) * aspectRatio);