350 lines
11 KiB
Java
Executable File
350 lines
11 KiB
Java
Executable File
package projectzombie.display;
|
|
|
|
import static org.lwjgl.opengl.GL11.GL_FLOAT;
|
|
import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray;
|
|
import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
|
|
|
|
import java.nio.IntBuffer;
|
|
|
|
import org.lwjgl.BufferUtils;
|
|
import org.lwjgl.glfw.GLFW;
|
|
import org.lwjgl.opengl.GL33;
|
|
|
|
import gl_engine.graphics.GraphicsHelpers;
|
|
import gl_engine.graphics.GraphicsShader;
|
|
import mainloop.task.IMainloopTask;
|
|
import projectzombie.Main;
|
|
import projectzombie.init.Resources;
|
|
import projectzombie.input.CursorEnterCallback;
|
|
import projectzombie.input.CursorPosCallback;
|
|
import projectzombie.input.JoystickCallback;
|
|
import projectzombie.input.KeyCallback;
|
|
import projectzombie.input.KeyCharCallback;
|
|
import projectzombie.input.MouseButtonCallback;
|
|
import projectzombie.input.ScrollWheelCallback;
|
|
import projectzombie.mainloop.MainloopEventHandler;
|
|
import projectzombie.menu.MenuSettings;
|
|
import projectzombie.settings.Settings;
|
|
|
|
public class DisplayWindow implements IMainloopTask
|
|
{
|
|
public static boolean fullscreen = true;
|
|
|
|
private long window;
|
|
private long monitor;
|
|
private int width;
|
|
private int height;
|
|
private boolean mouseVisibility_last = false;
|
|
public int texture_max_size;
|
|
|
|
public static int fps = 0;
|
|
|
|
public GraphicsShader environmentRenderer;
|
|
public GraphicsShader effectRenderer;
|
|
|
|
public int effect_vao;
|
|
|
|
public int glsl_mist;
|
|
public int glsl_color;
|
|
public int glsl_contrast;
|
|
public int glsl_discard_coords;
|
|
public int glsl_model;
|
|
public int glsl_camera;
|
|
public int glsl_projection;
|
|
public int glsl_projection_sun;
|
|
public int glsl_rotated;
|
|
public int glsl_billboard;
|
|
public int glsl_mode;
|
|
public int glsl_time;
|
|
|
|
public int glsl_day_low;
|
|
public int glsl_day_high;
|
|
|
|
public int glsl_lightmap_offset;
|
|
public int glsl_lightmap_size;
|
|
|
|
public int glsl_effect_time;
|
|
public int glsl_effect_red;
|
|
public int glsl_effect_vortex;
|
|
public int glsl_effect_vsnow;
|
|
public int glsl_effect_red_freq;
|
|
public int glsl_effect_chill;
|
|
|
|
public int getWidth() {
|
|
return this.width;
|
|
}
|
|
|
|
public int getHeight() {
|
|
return this.height;
|
|
}
|
|
|
|
void setWidth(int w) {
|
|
width = w;
|
|
}
|
|
|
|
void setHeight(int h) {
|
|
height = h;
|
|
}
|
|
|
|
public void init()
|
|
{
|
|
// Initialize GLFW
|
|
if(!GLFW.glfwInit()) {
|
|
throw new RuntimeException("Failed to initialize GLFW");
|
|
}
|
|
|
|
// Get the monitor size
|
|
IntBuffer w = BufferUtils.createIntBuffer(1);
|
|
IntBuffer h = BufferUtils.createIntBuffer(1);
|
|
monitor = GLFW.glfwGetPrimaryMonitor();
|
|
GLFW.glfwGetMonitorPhysicalSize(monitor, w, h);
|
|
width = w.get()*4;
|
|
height = h.get()*4;
|
|
|
|
//GLFW.glfwWindowHint(GLFW.GLFW_DOUBLEBUFFER, GLFW.GLFW_FALSE);
|
|
|
|
// Create the window
|
|
window = GraphicsHelpers.initWindow("Project Zombie", width, height, fullscreen ? monitor : 0);
|
|
|
|
// Make the context current
|
|
GLFW.glfwMakeContextCurrent(this.window);
|
|
|
|
// Set the key handlers
|
|
GLFW.glfwSetCursorPosCallback(this.window, new CursorPosCallback());
|
|
GLFW.glfwSetCharCallback(this.window, new KeyCharCallback());
|
|
GLFW.glfwSetCursorEnterCallback(this.window, new CursorEnterCallback());
|
|
GLFW.glfwSetMouseButtonCallback(this.window, new MouseButtonCallback());
|
|
GLFW.glfwSetKeyCallback(this.window, new KeyCallback());
|
|
GLFW.glfwSetJoystickCallback(JoystickCallback.JOYSTICK_CALLBACK);
|
|
GLFW.glfwSetScrollCallback(this.window, new ScrollWheelCallback());
|
|
|
|
// Make the cursor invisible
|
|
GLFW.glfwSetInputMode(this.window, GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_HIDDEN);
|
|
|
|
GLFW.glfwSwapInterval(0);
|
|
|
|
// Show the window
|
|
//GLFW.glfwShowWindow(this.window);
|
|
|
|
environmentRenderer = new GraphicsShader("/resources/shader/environmentRenderer");
|
|
environmentRenderer.use();
|
|
|
|
glsl_mist = GL33.glGetUniformLocation(environmentRenderer.program, "mist");
|
|
glsl_model = GL33.glGetUniformLocation(environmentRenderer.program, "model");
|
|
glsl_camera = GL33.glGetUniformLocation(environmentRenderer.program, "camera");
|
|
glsl_rotated = GL33.glGetUniformLocation(environmentRenderer.program, "rotated");
|
|
glsl_projection = GL33.glGetUniformLocation(environmentRenderer.program, "projection");
|
|
glsl_projection_sun = GL33.glGetUniformLocation(environmentRenderer.program, "projection_sun");
|
|
glsl_time = GL33.glGetUniformLocation(environmentRenderer.program, "time");
|
|
glsl_discard_coords = GL33.glGetUniformLocation(environmentRenderer.program, "discard_coords");
|
|
glsl_color = GL33.glGetUniformLocation(environmentRenderer.program, "color");
|
|
glsl_contrast = GL33.glGetUniformLocation(environmentRenderer.program, "contrast");
|
|
glsl_billboard = GL33.glGetUniformLocation(environmentRenderer.program, "billboard");
|
|
glsl_mode = GL33.glGetUniformLocation(environmentRenderer.program, "mode");
|
|
|
|
glsl_day_low = GL33.glGetUniformLocation(environmentRenderer.program, "lighting_day_low");
|
|
glsl_day_high = GL33.glGetUniformLocation(environmentRenderer.program, "lighting_day_high");
|
|
|
|
glsl_lightmap_offset = GL33.glGetUniformLocation(environmentRenderer.program, "lightmap_offset");
|
|
glsl_lightmap_size = GL33.glGetUniformLocation(environmentRenderer.program, "lightmap_size");
|
|
|
|
int glsl_atlas = GL33.glGetUniformLocation(environmentRenderer.program, "atlas");
|
|
int glsl_lightmap = GL33.glGetUniformLocation(environmentRenderer.program, "lightmap");
|
|
int glsl_depthmap = GL33.glGetUniformLocation(environmentRenderer.program, "depthmap");
|
|
|
|
GL33.glUniform1i(glsl_atlas, 0);
|
|
GL33.glUniform1i(glsl_lightmap, 1);
|
|
GL33.glUniform1i(glsl_depthmap, 2);
|
|
|
|
effectRenderer = new GraphicsShader("/resources/shader/effectRenderer");
|
|
effectRenderer.use();
|
|
|
|
glsl_effect_time = GL33.glGetUniformLocation(effectRenderer.program, "time");
|
|
glsl_effect_red = GL33.glGetUniformLocation(effectRenderer.program, "red");
|
|
glsl_effect_vsnow = GL33.glGetUniformLocation(effectRenderer.program, "vsnow");
|
|
glsl_effect_vortex = GL33.glGetUniformLocation(effectRenderer.program, "vortex");
|
|
glsl_effect_red_freq = GL33.glGetUniformLocation(effectRenderer.program, "red_freq");
|
|
glsl_effect_chill = GL33.glGetUniformLocation(effectRenderer.program, "chill");
|
|
|
|
//GL33.glUniform1i(GL33.glGetUniformLocation(effectRenderer.program, "shadowMap"), 2);
|
|
|
|
effect_vao = GL33.glGenVertexArrays();
|
|
GL33.glBindVertexArray(effect_vao);
|
|
|
|
int effect_vbo = GL33.glGenBuffers();
|
|
GL33.glBindBuffer(GL33.GL_ARRAY_BUFFER, effect_vbo);
|
|
GL33.glBufferData(GL33.GL_ARRAY_BUFFER, new float[] {
|
|
-1, -1,
|
|
-1, 1,
|
|
1, 1,
|
|
|
|
-1, -1,
|
|
1, -1,
|
|
1, 1,
|
|
}, GL33.GL_STATIC_DRAW);
|
|
|
|
glVertexAttribPointer(0, 2, GL_FLOAT, false, Float.BYTES * 2, 0);
|
|
glEnableVertexAttribArray(0);
|
|
|
|
int[] ptr = new int[1];
|
|
GL33.glGetIntegerv(GL33.GL_MAX_TEXTURE_SIZE, ptr);
|
|
|
|
texture_max_size = ptr[0];
|
|
System.out.println("Max texture size: " + texture_max_size);
|
|
|
|
DisplayRender.init();
|
|
}
|
|
|
|
public void render()
|
|
{
|
|
// Set the framebuffer size
|
|
int w[] = {0};
|
|
int h[] = {0};
|
|
GLFW.glfwGetFramebufferSize(this.window, w, h);
|
|
width = w[0];
|
|
height = h[0];
|
|
|
|
environmentRenderer.use();
|
|
DisplayLighting.updateLighting();
|
|
|
|
GL33.glUniform1f(glsl_mist, 0);
|
|
|
|
if(Main.player.getHydration() < 0.2) {
|
|
GL33.glUniform1f(glsl_contrast, (float)(0.2 - Main.player.getHydration()) * 1.6f);
|
|
} else {
|
|
GL33.glUniform1f(glsl_contrast, 0);
|
|
}
|
|
|
|
// Bind the texture atlas
|
|
GL33.glActiveTexture(GL33.GL_TEXTURE0);
|
|
Resources.ATLAS.bind();
|
|
|
|
// Bind the lightmap
|
|
GL33.glActiveTexture(GL33.GL_TEXTURE1);
|
|
GL33.glBindTexture(GL33.GL_TEXTURE_2D, DisplayLighting.lightmap);
|
|
|
|
// Bind the shadow depth map
|
|
GL33.glActiveTexture(GL33.GL_TEXTURE2);
|
|
GL33.glBindTexture(GL33.GL_TEXTURE_2D, DisplayRender.shadow_depth);
|
|
|
|
// Render everything
|
|
DisplayRender.render(w[0], h[0]);
|
|
|
|
// Use the effect shader
|
|
effectRenderer.use();
|
|
|
|
// Bind the shadow depth map
|
|
GL33.glActiveTexture(GL33.GL_TEXTURE0);
|
|
GL33.glBindTexture(GL33.GL_TEXTURE_2D, DisplayRender.shadow_depth);
|
|
|
|
// Send extra data to the shader
|
|
if(!Main.player.dead && Main.menu.doGameloop) {
|
|
GL33.glUniform1i(glsl_effect_time, (int)System.currentTimeMillis());
|
|
}
|
|
|
|
if(Main.player.getHydration() < 0.2) {
|
|
GL33.glUniform1f(glsl_effect_vsnow, (float)(0.2 - Main.player.getHydration()));
|
|
GL33.glUniform1f(glsl_effect_vortex, (float)(0.2 - Main.player.getHydration()) / 10);
|
|
} else {
|
|
GL33.glUniform1f(glsl_effect_vsnow, 0);
|
|
GL33.glUniform1f(glsl_effect_vortex, 0);
|
|
}
|
|
|
|
double player_health = Main.player.getHealth() / Main.player.maxHealth();
|
|
|
|
if(player_health < 0.25) {
|
|
GL33.glUniform1f(glsl_effect_red, (float)Math.min(2 * (0.25 - player_health), 0.5));
|
|
GL33.glUniform1i(glsl_effect_red_freq, 20);
|
|
} else {
|
|
GL33.glUniform1f(glsl_effect_red, 0);
|
|
}
|
|
|
|
if(Main.player.getTemperature() < 0.3) {
|
|
GL33.glUniform1f(glsl_effect_chill, (float)(0.3 - Main.player.getTemperature()) / 3 * 10);
|
|
} else {
|
|
GL33.glUniform1f(glsl_effect_chill, 0);
|
|
}
|
|
|
|
// Draw a quad to the whole screen for the effects
|
|
GL33.glBindVertexArray(effect_vao);
|
|
GL33.glDrawArrays(GL33.GL_TRIANGLES, 0, 6);
|
|
|
|
// Swap the framebuffers and poll events
|
|
GLFW.glfwSwapBuffers(window);
|
|
GLFW.glfwPollEvents();
|
|
|
|
fps += 1;
|
|
}
|
|
|
|
public void toggleFullscreen()
|
|
{
|
|
// Exit fullscreen if the window is in fullscreen
|
|
if(fullscreen)
|
|
{
|
|
fullscreen = false;
|
|
GLFW.glfwSetWindowMonitor(window, 0, 1, 1, width, height, GLFW.GLFW_DONT_CARE);
|
|
}
|
|
|
|
// Enter fullscreen if the window is windowed
|
|
else
|
|
{
|
|
// Get the monitor size
|
|
IntBuffer w = BufferUtils.createIntBuffer(1);
|
|
IntBuffer h = BufferUtils.createIntBuffer(1);
|
|
GLFW.glfwGetMonitorPhysicalSize(monitor, w, h);
|
|
width = w.get()*4;
|
|
height = h.get()*4;
|
|
|
|
// Enter fullscreen mode
|
|
fullscreen = true;
|
|
GLFW.glfwSetWindowMonitor(window, monitor, 0, 0, width, height, GLFW.GLFW_DONT_CARE);
|
|
}
|
|
|
|
// Update the settings file
|
|
Settings.update();
|
|
|
|
if(Main.menu instanceof MenuSettings) {
|
|
((MenuSettings) Main.menu).buttonFullscreen.setText(
|
|
"Fullscreen: " + (fullscreen ? "On" : "Off"));
|
|
}
|
|
}
|
|
|
|
public void setMouseVisibility(boolean status) {
|
|
if(status != mouseVisibility_last) {
|
|
mouseVisibility_last = status;
|
|
if(status) {
|
|
GLFW.glfwSetInputMode(window, GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_NORMAL);
|
|
} else {
|
|
GLFW.glfwSetInputMode(window, GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_HIDDEN);
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean shouldClose() {
|
|
return GLFW.glfwWindowShouldClose(window);
|
|
}
|
|
|
|
public void makeContextCurrent() {
|
|
GLFW.glfwMakeContextCurrent(window);
|
|
}
|
|
|
|
@Override
|
|
public boolean MainLoopDelay(long millis) {
|
|
return millis > MainloopEventHandler.MAINLOOP_EVENT_HANDLER.mspf;
|
|
}
|
|
|
|
@Override
|
|
public boolean MainLoopRepeat() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void MainLoopUpdate() {
|
|
this.render();
|
|
}
|
|
|
|
public void setTitle(String string) {
|
|
GLFW.glfwSetWindowTitle(window, string);
|
|
}
|
|
}
|