Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle window resizes correctly #44

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 17 additions & 14 deletions src/org/dhsdev/flowerknight/FlowerKnight.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public static void init() {
// Set up GLFW. Errors should be checked here later.
glfwInit();

glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

// macOS needs to request a forward profile for a later
// version of OpenGL explicitly. Version 3.3, to be specific.
if (GetOSType.getOSType() == OSType.MACOS) {
Expand All @@ -55,6 +57,19 @@ public static void init() {

Shader.getSpotlightShader().registerUniform("time");

// Register width and height for every shader
for (var shader : new Shader[] {
Shader.getGameShader(),
Shader.getSpotlightShader(),
Shader.getTrivialShader(),
}) {
shader.registerUniform("width");
shader.registerUniform("height");
}

// Update shaders here after all uniforms have been registered
window.updateShadersOnResize(window.width(), window.height());

TextureAtlas.loadAllTextures();

}
Expand All @@ -68,23 +83,11 @@ public static void mainloop() {
// While it's open, clear screen and check for events.
while (window.isOpen()) {

Shader.getSpotlightShader().bind();
Shader.getSpotlightShader().setUniform("time", (float) glfwGetTime());

Camera.updateShaders();
window.updateNeededShaders();

GameObject.updateAll();

window.clear();

// Iterate and draw all renderable object
for (Renderable renderable : Renderable.renderables) {
renderable.draw();
}


// Render everything to screen at once
window.displayAllUpdates();
window.redraw();

window.callEventHandlers();

Expand Down
95 changes: 92 additions & 3 deletions src/org/dhsdev/flowerknight/gl/Window.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.dhsdev.flowerknight.gl;

import org.dhsdev.flowerknight.game.Camera;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;

import java.util.Objects;
Expand Down Expand Up @@ -29,9 +31,6 @@ public class Window {
*/
public Window(int samples) {

// Right now the window is non-resizable.
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);

// Hint MSAA
glfwWindowHint(GLFW_SAMPLES, samples);

Expand All @@ -42,13 +41,27 @@ public Window(int samples) {
// Don't ask me what the two NULLs are for. I have no clue.
handle = glfwCreateWindow(screenWidth, screenHeight, "FlowerKnight", NULL, NULL);

width = screenWidth;
height = screenHeight;

glfwMakeContextCurrent(handle);
GL.createCapabilities();

// Enable MSAA
glEnable(GL_MULTISAMPLE);

glfwShowWindow(handle);

// We want the window to immediately render as it is resized - the images
// will scale correctly, but the spotlight shader will freeze and the
// will not remain a square.
glfwSetWindowSizeCallback(handle, (long window, int width, int height) -> {
// Update the shaders and render.
updateShadersOnResize(width, height);
updateNeededShaders();
redraw();
});

}

/**
Expand Down Expand Up @@ -89,4 +102,80 @@ public void delete() {
glfwDestroyWindow(handle);
}

/**
* Update shader uniforms when the window gets resized.
* @param width the new window width
* @param height the new window height
*/
public void updateShadersOnResize(float width, float height) {

this.width = width;
this.height = height;

// Update width and height for every shader
for (var shader : new Shader[] {
Shader.getGameShader(),
Shader.getSpotlightShader(),
Shader.getTrivialShader(),
}) {
shader.bind();
shader.setUniform("width" , width);
shader.setUniform("height", height);
}

}

/**
* Window width
*/
private float width;

/**
* Get width
*/
public float width() {
return width;
}

/**
* Window height
*/
private float height;

/**
* Get height
*/
public float height() {
return height;
}

/**
* Render everything.
*/
public void redraw() {

this.clear();

// Iterate and draw all renderable object
for (Renderable renderable : Renderable.renderables) {
renderable.draw();
}

// Render everything to screen at once
this.displayAllUpdates();

}

/**
* Update the spotlight annd camera shaders which change with every tick.
*/
public void updateNeededShaders() {

Shader.getSpotlightShader().bind();
Shader.getSpotlightShader().setUniform("time", (float) glfwGetTime());

Camera.updateShaders();

}

}
13 changes: 13 additions & 0 deletions src/shader/game_vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,24 @@ layout (location=1) in vec2 texCoord;
uniform vec2 cameraLoc;
uniform float zoom;

// For a full explanation of these variables, see trivial_vert.glsl
uniform float width, height;

out vec2 outTexCoord;

void main() {

gl_Position = vec4(position, 1.0);

gl_Position.xy -= cameraLoc; // Update with camera position
gl_Position.xy /= zoom;

if (width < height) {
gl_Position.y *= (width / height);
} else {
gl_Position.x *= (height / width);
}

outTexCoord = texCoord;

}
15 changes: 15 additions & 0 deletions src/shader/trivial_vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,22 @@ layout (location=1) in vec2 texCoord;

out vec2 outTexCoord;

uniform float width, height;

void main() {

gl_Position = vec4(position, 1.0);

// Width and height are the width and height of the window. We want to have
// everything rendered in a square, so everything is rendered in the largest
// square possible. To do this, we scale the larger coordinate space down to
// the smaller one.
if (width < height) {
gl_Position.y *= (width / height);
} else {
gl_Position.x *= (height / width);
}

outTexCoord = texCoord;

}