diff --git a/src/main/java/io/github/hydos/ginger/Example.java b/src/main/java/io/github/hydos/ginger/Example.java index 250a0a3..38a13c6 100644 --- a/src/main/java/io/github/hydos/ginger/Example.java +++ b/src/main/java/io/github/hydos/ginger/Example.java @@ -20,6 +20,8 @@ import io.github.hydos.ginger.engine.obj.normals.NormalMappedObjLoader; import io.github.hydos.ginger.engine.particle.ParticleMaster; import io.github.hydos.ginger.engine.particle.ParticleSystem; import io.github.hydos.ginger.engine.particle.ParticleTexture; +import io.github.hydos.ginger.engine.postProcessing.Fbo; +import io.github.hydos.ginger.engine.postProcessing.PostProcessing; import io.github.hydos.ginger.engine.renderEngine.MasterRenderer; import io.github.hydos.ginger.engine.renderEngine.models.TexturedModel; import io.github.hydos.ginger.engine.renderEngine.texture.ModelTexture; @@ -28,6 +30,8 @@ import io.github.hydos.ginger.engine.terrain.Terrain; import io.github.hydos.ginger.engine.terrain.TerrainTexture; import io.github.hydos.ginger.engine.terrain.TerrainTexturePack; import io.github.hydos.ginger.engine.utils.Loader; +import io.github.hydos.ginger.main.GingerMain; +import io.github.hydos.ginger.main.settings.Constants; public class Example { @@ -49,17 +53,19 @@ public class Example { Window.create(1200, 800, "Ginger Example", 60); + GingerMain.init(); + Window.setBackgroundColour(0.2f, 0.2f, 0.8f); - TextMaster.init(); TexturedModel tModel = ModelLoader.loadModel("stall.obj", "stallTexture.png"); tModel.getTexture().setReflectivity(1f); tModel.getTexture().setShineDamper(7f); Player entity = new Player(tModel, new Vector3f(0,0,-3),0,180f,0, new Vector3f(0.2f, 0.2f, 0.2f)); - entity.setSpeeds(0.00001f, 0.0003f); - entity.setGravity(-0.0000000001f); - entity.setJumpPower(0.00005f); + Constants.movementSpeed = 0.000005f; + Constants.turnSpeed = 0.00002f; + Constants.gravity = -0.000000000005f; + Constants.jumpPower = 0.000005f; ThirdPersonCamera camera = new ThirdPersonCamera(new Vector3f(0,0.1f,0), entity); masterRenderer = new MasterRenderer(camera); @@ -138,6 +144,9 @@ public class Example { system.setSpeedError(0); system.setScaleError(1f); + Fbo fbo = new Fbo(Window.width, Window.height, Fbo.DEPTH_RENDER_BUFFER); + PostProcessing.init(); + while(!Window.closed()) { if(Window.isUpdating()) { @@ -160,14 +169,24 @@ public class Example { dragon.increaseRotation(0,1,0); barrel.increaseRotation(0, 1, 0); + +// fbo.bindFrameBuffer(); +// masterRenderer.renderScene(entities, normalMapEntities, terrains, lights, camera, new Vector4f(0, -1, 0, 100000)); +// ParticleMaster.renderParticles(camera); +// fbo.unbindFrameBuffer(); +// PostProcessing.doPostProcessing(fbo.getColourTexture()); + masterRenderer.renderScene(entities, normalMapEntities, terrains, lights, camera, new Vector4f(0, -1, 0, 100000)); - ParticleMaster.renderParticles(camera); + masterRenderer.renderGuis(guis); TextMaster.render(); + Window.swapBuffers(); } } + PostProcessing.cleanUp(); + fbo.cleanUp(); ParticleMaster.cleanUp(); masterRenderer.cleanUp(); TextMaster.cleanUp(); diff --git a/src/main/java/io/github/hydos/ginger/engine/elements/Player.java b/src/main/java/io/github/hydos/ginger/engine/elements/Player.java index 07d7533..f7887b2 100644 --- a/src/main/java/io/github/hydos/ginger/engine/elements/Player.java +++ b/src/main/java/io/github/hydos/ginger/engine/elements/Player.java @@ -6,14 +6,15 @@ import io.github.hydos.ginger.engine.io.Window; import io.github.hydos.ginger.engine.mathEngine.vectors.Vector3f; import io.github.hydos.ginger.engine.renderEngine.models.TexturedModel; import io.github.hydos.ginger.engine.terrain.Terrain; +import io.github.hydos.ginger.main.settings.Constants; public class Player extends Entity{ - private static float RUN_SPEED = 0.3f; - private static float TURN_SPEED = 0.7f; - public static float GRAVITY = -0.04f; - private static float JUMP_POWER = 0.3f; - +// private static float RUN_SPEED = 0.3f; +// private static float TURN_SPEED = 0.7f; +// public static float GRAVITY = -0.04f; +// private static float JUMP_POWER = 0.3f; + private static float terrainHeight = 0; @@ -26,19 +27,6 @@ public class Player extends Entity{ public Player(TexturedModel model, Vector3f position, float rotX, float rotY, float rotZ, Vector3f scale) { super(model, position, rotX, rotY, rotZ, scale); } - - public void setSpeeds(float runSpeed, float turnSpeed) { - RUN_SPEED = runSpeed; - TURN_SPEED = turnSpeed; - } - - public void setJumpPower(float power) { - JUMP_POWER = power; - } - - public void setGravity(float gravity) { - GRAVITY = gravity; - } public void move(Terrain t) { checkInputs(); @@ -49,7 +37,7 @@ public class Player extends Entity{ super.increasePosition(dx, 0, dz); super.increasePosition(0, (float) (upwardsSpeed * (Window.getTime())), 0); terrainHeight = t.getHeightOfTerrain(super.getPosition().x, super.getPosition().z); - upwardsSpeed += GRAVITY * Window.getTime(); + upwardsSpeed += Constants.gravity * Window.getTime(); if(super.getPosition().y < terrainHeight) { isInAir = false; upwardsSpeed = 0; @@ -61,26 +49,26 @@ public class Player extends Entity{ private void jump() { if(!isInAir) { isInAir = true; - this.upwardsSpeed = JUMP_POWER; + this.upwardsSpeed = Constants.jumpPower; } } private void checkInputs() { if(Window.isKeyDown(GLFW.GLFW_KEY_W)) { - this.currentSpeed = RUN_SPEED; + this.currentSpeed = Constants.movementSpeed; } else if(Window.isKeyDown(GLFW.GLFW_KEY_S)) { - this.currentSpeed = -RUN_SPEED; + this.currentSpeed = -Constants.movementSpeed; }else { this.currentSpeed = 0; } if(Window.isKeyDown(GLFW.GLFW_KEY_A)) { - this.currentTurn = TURN_SPEED; + this.currentTurn = Constants.turnSpeed; } else if(Window.isKeyDown(GLFW.GLFW_KEY_D)) { - this.currentTurn = -TURN_SPEED; + this.currentTurn = -Constants.turnSpeed; } if(Window.isKeyReleased(68) || Window.isKeyReleased(65)){ this.currentTurn = 0; diff --git a/src/main/java/io/github/hydos/ginger/engine/particle/Particle.java b/src/main/java/io/github/hydos/ginger/engine/particle/Particle.java index 45e643e..af9cf2d 100644 --- a/src/main/java/io/github/hydos/ginger/engine/particle/Particle.java +++ b/src/main/java/io/github/hydos/ginger/engine/particle/Particle.java @@ -1,10 +1,10 @@ package io.github.hydos.ginger.engine.particle; -import io.github.hydos.ginger.engine.elements.Player; import io.github.hydos.ginger.engine.elements.ThirdPersonCamera; import io.github.hydos.ginger.engine.io.Window; import io.github.hydos.ginger.engine.mathEngine.vectors.Vector2f; import io.github.hydos.ginger.engine.mathEngine.vectors.Vector3f; +import io.github.hydos.ginger.main.settings.Constants; public class Particle { @@ -72,7 +72,7 @@ public class Particle { public boolean update(ThirdPersonCamera camera) { float time = (float) Window.getTime() / 1000000; - velocity.y += Player.GRAVITY * gravityEffect * time; + velocity.y += Constants.gravity * gravityEffect * time; Vector3f change = new Vector3f(velocity); change.scale((float) time); Vector3f.add(change, position, position); diff --git a/src/main/java/io/github/hydos/ginger/engine/postProcessing/ContrastChanger.java b/src/main/java/io/github/hydos/ginger/engine/postProcessing/ContrastChanger.java new file mode 100644 index 0000000..7c6cf1f --- /dev/null +++ b/src/main/java/io/github/hydos/ginger/engine/postProcessing/ContrastChanger.java @@ -0,0 +1,29 @@ +package io.github.hydos.ginger.engine.postProcessing; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL13; + +public class ContrastChanger { + + private ImageRenderer renderer; + private ContrastShader shader; + + public ContrastChanger() { + shader = new ContrastShader(); + renderer = new ImageRenderer(); + } + + public void render(int texture) { + shader.start(); + GL13.glActiveTexture(GL13.GL_TEXTURE0); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture); + renderer.renderQuad(); + shader.stop(); + } + + public void cleanUp() { + renderer.cleanUp(); + shader.cleanUp(); + } + +} diff --git a/src/main/java/io/github/hydos/ginger/engine/postProcessing/ContrastShader.java b/src/main/java/io/github/hydos/ginger/engine/postProcessing/ContrastShader.java new file mode 100644 index 0000000..86d4b32 --- /dev/null +++ b/src/main/java/io/github/hydos/ginger/engine/postProcessing/ContrastShader.java @@ -0,0 +1,23 @@ +package io.github.hydos.ginger.engine.postProcessing; + +import io.github.hydos.ginger.engine.renderEngine.shaders.ShaderProgram; + +public class ContrastShader extends ShaderProgram { + + private static final String VERTEX_FILE = "contrastVertex.glsl"; + private static final String FRAGMENT_FILE = "contrastFragment.glsl"; + + public ContrastShader() { + super(VERTEX_FILE, FRAGMENT_FILE); + } + + @Override + protected void getAllUniformLocations() { + } + + @Override + protected void bindAttributes() { + super.bindAttribute(0, "position"); + } + +} diff --git a/src/main/java/io/github/hydos/ginger/engine/postProcessing/Fbo.java b/src/main/java/io/github/hydos/ginger/engine/postProcessing/Fbo.java new file mode 100644 index 0000000..3e83b4f --- /dev/null +++ b/src/main/java/io/github/hydos/ginger/engine/postProcessing/Fbo.java @@ -0,0 +1,174 @@ +package io.github.hydos.ginger.engine.postProcessing; + +import java.nio.ByteBuffer; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; +import org.lwjgl.opengl.GL14; +import org.lwjgl.opengl.GL30; + +import io.github.hydos.ginger.engine.io.Window; + +public class Fbo { + + public static final int NONE = 0; + public static final int DEPTH_TEXTURE = 1; + public static final int DEPTH_RENDER_BUFFER = 2; + + private final int width; + private final int height; + + private int frameBuffer; + + private int colourTexture; + private int depthTexture; + + private int depthBuffer; + private int colourBuffer; + + /** + * Creates an FBO of a specified width and height, with the desired type of + * depth buffer attachment. + * + * @param width + * - the width of the FBO. + * @param height + * - the height of the FBO. + * @param depthBufferType + * - an int indicating the type of depth buffer attachment that + * this FBO should use. + */ + public Fbo(int width, int height, int depthBufferType) { + this.width = width; + this.height = height; + initialiseFrameBuffer(depthBufferType); + } + + /** + * Deletes the frame buffer and its attachments when the game closes. + */ + public void cleanUp() { + GL30.glDeleteFramebuffers(frameBuffer); + GL11.glDeleteTextures(colourTexture); + GL11.glDeleteTextures(depthTexture); + GL30.glDeleteRenderbuffers(depthBuffer); + GL30.glDeleteRenderbuffers(colourBuffer); + } + + /** + * Binds the frame buffer, setting it as the current render target. Anything + * rendered after this will be rendered to this FBO, and not to the screen. + */ + public void bindFrameBuffer() { + GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, frameBuffer); + GL11.glViewport(0, 0, width, height); + } + + /** + * Unbinds the frame buffer, setting the default frame buffer as the current + * render target. Anything rendered after this will be rendered to the + * screen, and not this FBO. + */ + public void unbindFrameBuffer() { + GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0); + GL11.glViewport(0, 0, Window.width, Window.height); + } + + /** + * Binds the current FBO to be read from (not used in tutorial 43). + */ + public void bindToRead() { + GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); + GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, frameBuffer); + GL11.glReadBuffer(GL30.GL_COLOR_ATTACHMENT0); + } + + /** + * @return The ID of the texture containing the colour buffer of the FBO. + */ + public int getColourTexture() { + return colourTexture; + } + + /** + * @return The texture containing the FBOs depth buffer. + */ + public int getDepthTexture() { + return depthTexture; + } + + /** + * Creates the FBO along with a colour buffer texture attachment, and + * possibly a depth buffer. + * + * @param type + * - the type of depth buffer attachment to be attached to the + * FBO. + */ + private void initialiseFrameBuffer(int type) { + createFrameBuffer(); + createTextureAttachment(); + if (type == DEPTH_RENDER_BUFFER) { + createDepthBufferAttachment(); + } else if (type == DEPTH_TEXTURE) { + createDepthTextureAttachment(); + } + unbindFrameBuffer(); + } + + /** + * Creates a new frame buffer object and sets the buffer to which drawing + * will occur - colour attachment 0. This is the attachment where the colour + * buffer texture is. + * + */ + private void createFrameBuffer() { + frameBuffer = GL30.glGenFramebuffers(); + GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBuffer); + GL11.glDrawBuffer(GL30.GL_COLOR_ATTACHMENT0); + } + + /** + * Creates a texture and sets it as the colour buffer attachment for this + * FBO. + */ + private void createTextureAttachment() { + colourTexture = GL11.glGenTextures(); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, colourTexture); + GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, + (ByteBuffer) null); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE); + GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL11.GL_TEXTURE_2D, colourTexture, + 0); + } + + /** + * Adds a depth buffer to the FBO in the form of a texture, which can later + * be sampled. + */ + private void createDepthTextureAttachment() { + depthTexture = GL11.glGenTextures(); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, depthTexture); + GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL14.GL_DEPTH_COMPONENT24, width, height, 0, GL11.GL_DEPTH_COMPONENT, + GL11.GL_FLOAT, (ByteBuffer) null); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); + GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL11.GL_TEXTURE_2D, depthTexture, 0); + } + + /** + * Adds a depth buffer to the FBO in the form of a render buffer. This can't + * be used for sampling in the shaders. + */ + private void createDepthBufferAttachment() { + depthBuffer = GL30.glGenRenderbuffers(); + GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBuffer); + GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL14.GL_DEPTH_COMPONENT24, width, height); + GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL30.GL_RENDERBUFFER, + depthBuffer); + } + +} diff --git a/src/main/java/io/github/hydos/ginger/engine/postProcessing/ImageRenderer.java b/src/main/java/io/github/hydos/ginger/engine/postProcessing/ImageRenderer.java new file mode 100644 index 0000000..35d66ca --- /dev/null +++ b/src/main/java/io/github/hydos/ginger/engine/postProcessing/ImageRenderer.java @@ -0,0 +1,36 @@ +package io.github.hydos.ginger.engine.postProcessing; + +import org.lwjgl.opengl.GL11; + +public class ImageRenderer { + + private Fbo fbo; + + protected ImageRenderer(int width, int height) { + this.fbo = new Fbo(width, height, Fbo.NONE); + } + + protected ImageRenderer() {} + + protected void renderQuad() { + if (fbo != null) { + fbo.bindFrameBuffer(); + } + GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); + GL11.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, 4); + if (fbo != null) { + fbo.unbindFrameBuffer(); + } + } + + protected int getOutputTexture() { + return fbo.getColourTexture(); + } + + protected void cleanUp() { + if (fbo != null) { + fbo.cleanUp(); + } + } + +} diff --git a/src/main/java/io/github/hydos/ginger/engine/postProcessing/PostProcessing.java b/src/main/java/io/github/hydos/ginger/engine/postProcessing/PostProcessing.java new file mode 100644 index 0000000..5b8a996 --- /dev/null +++ b/src/main/java/io/github/hydos/ginger/engine/postProcessing/PostProcessing.java @@ -0,0 +1,44 @@ +package io.github.hydos.ginger.engine.postProcessing; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; + +import io.github.hydos.ginger.engine.renderEngine.models.RawModel; +import io.github.hydos.ginger.engine.utils.Loader; + +public class PostProcessing { + + private static final float[] POSITIONS = { -1, 1, -1, -1, 1, 1, 1, -1 }; + private static RawModel quad; + private static ContrastChanger contrastChanger; + + public static void init(){ + quad = Loader.loadToVAO(POSITIONS, 2); + contrastChanger = new ContrastChanger(); + } + + public static void doPostProcessing(int colourTexture){ + start(); + contrastChanger.render(colourTexture); + end(); + } + + public static void cleanUp(){ + contrastChanger.cleanUp(); + } + + private static void start(){ + GL30.glBindVertexArray(quad.getVaoID()); + GL20.glEnableVertexAttribArray(0); + GL11.glDisable(GL11.GL_DEPTH_TEST); + } + + private static void end(){ + GL11.glEnable(GL11.GL_DEPTH_TEST); + GL20.glDisableVertexAttribArray(0); + GL30.glBindVertexArray(0); + } + + +} diff --git a/src/main/java/io/github/hydos/ginger/engine/terrain/Terrain.java b/src/main/java/io/github/hydos/ginger/engine/terrain/Terrain.java index ee4d45a..002cf65 100644 --- a/src/main/java/io/github/hydos/ginger/engine/terrain/Terrain.java +++ b/src/main/java/io/github/hydos/ginger/engine/terrain/Terrain.java @@ -10,11 +10,10 @@ import io.github.hydos.ginger.engine.mathEngine.vectors.Vector2f; import io.github.hydos.ginger.engine.mathEngine.vectors.Vector3f; import io.github.hydos.ginger.engine.renderEngine.models.RawModel; import io.github.hydos.ginger.engine.utils.Loader; +import io.github.hydos.ginger.main.settings.Constants; public class Terrain { - private static final float SIZE = 100; - private static final float MAX_HEIGHT = 20; private static final float MAX_PIXEL_COLOUR = 256 * 256 * 256; private float[][] heights; @@ -27,8 +26,8 @@ public class Terrain { public Terrain(float gridX, float gridZ, TerrainTexturePack texturePack, TerrainTexture blendMap, String heightMapLocation) { this.texturePack = texturePack; this.blendMap = blendMap; - this.x = gridX * SIZE; - this.z = gridZ * SIZE; + this.x = gridX * Constants.terrainSize; + this.z = gridZ * Constants.terrainSize; this.model = generateTerrain(heightMapLocation); @@ -37,7 +36,7 @@ public class Terrain { public float getHeightOfTerrain(float worldX, float worldZ) { float terrainX = worldX - this.x; float terrainZ = worldZ - this.z; - float gridSquareSize = SIZE / ((float) heights.length - 1); + float gridSquareSize = Constants.terrainSize / ((float) heights.length - 1); int gridX = (int) Math.floor(terrainX / gridSquareSize); int gridZ = (int) Math.floor(terrainZ / gridSquareSize); if(gridX >= heights.length - 1 || gridZ >= heights.length - 1 || gridX <0 || gridZ < 0) { @@ -100,11 +99,11 @@ public class Terrain { for(int i=0;i