Put the OpenGL to work
This commit is contained in:
@@ -5,12 +5,14 @@ package com.bartlomiejpluta.samplegame;
|
|||||||
|
|
||||||
import com.bartlomiejpluta.samplegame.core.engine.GameEngine;
|
import com.bartlomiejpluta.samplegame.core.engine.GameEngine;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.ApplicationArguments;
|
import org.springframework.boot.ApplicationArguments;
|
||||||
import org.springframework.boot.ApplicationRunner;
|
import org.springframework.boot.ApplicationRunner;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
public class App implements ApplicationRunner {
|
public class App implements ApplicationRunner {
|
||||||
@@ -18,6 +20,7 @@ public class App implements ApplicationRunner {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(ApplicationArguments args) {
|
public void run(ApplicationArguments args) {
|
||||||
|
log.info("Starting game engine");
|
||||||
gameEngine.start();
|
gameEngine.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,23 @@
|
|||||||
package com.bartlomiejpluta.samplegame.core.engine;
|
package com.bartlomiejpluta.samplegame.core.engine;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.samplegame.core.logic.GameLogic;
|
||||||
import com.bartlomiejpluta.samplegame.core.thread.ThreadManager;
|
import com.bartlomiejpluta.samplegame.core.thread.ThreadManager;
|
||||||
import com.bartlomiejpluta.samplegame.core.time.ChronoMeter;
|
import com.bartlomiejpluta.samplegame.core.time.ChronoMeter;
|
||||||
import com.bartlomiejpluta.samplegame.core.ui.Window;
|
import com.bartlomiejpluta.samplegame.core.ui.Window;
|
||||||
import com.bartlomiejpluta.samplegame.core.ui.WindowManager;
|
import com.bartlomiejpluta.samplegame.core.ui.WindowManager;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class DefaultGameEngine implements GameEngine {
|
public class DefaultGameEngine implements GameEngine {
|
||||||
|
private static final String THREAD_NAME = "Game Main Thread";
|
||||||
|
|
||||||
private final WindowManager windowManager;
|
private final WindowManager windowManager;
|
||||||
private final ThreadManager threadManager;
|
private final ThreadManager threadManager;
|
||||||
|
private final GameLogic logic;
|
||||||
|
|
||||||
private final Thread thread;
|
private final Thread thread;
|
||||||
private final Window window;
|
private final Window window;
|
||||||
@@ -23,16 +29,17 @@ public class DefaultGameEngine implements GameEngine {
|
|||||||
@Autowired
|
@Autowired
|
||||||
public DefaultGameEngine(WindowManager windowManager,
|
public DefaultGameEngine(WindowManager windowManager,
|
||||||
ThreadManager threadManager,
|
ThreadManager threadManager,
|
||||||
|
GameLogic logic,
|
||||||
@Value("${app.window.title}") String title,
|
@Value("${app.window.title}") String title,
|
||||||
@Value("${app.window.width}") int width,
|
@Value("${app.window.width}") int width,
|
||||||
@Value("${app.window.height}") int height,
|
@Value("${app.window.height}") int height,
|
||||||
@Value("${app.core.targetUps}") int targetUps) {
|
@Value("${app.core.targetUps}") int targetUps) {
|
||||||
this.windowManager = windowManager;
|
this.windowManager = windowManager;
|
||||||
this.threadManager = threadManager;
|
this.threadManager = threadManager;
|
||||||
|
this.logic = logic;
|
||||||
|
|
||||||
this.window = windowManager.createWindow(title, width, height);
|
this.window = windowManager.createWindow(title, width, height);
|
||||||
this.thread = threadManager.createThread(this::run);
|
this.thread = threadManager.createThread(THREAD_NAME, this::run);
|
||||||
this.chrono = new ChronoMeter();
|
this.chrono = new ChronoMeter();
|
||||||
this.targetUps = targetUps;
|
this.targetUps = targetUps;
|
||||||
}
|
}
|
||||||
@@ -47,11 +54,14 @@ public class DefaultGameEngine implements GameEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
|
log.info("Initializing game engine");
|
||||||
window.init();
|
window.init();
|
||||||
chrono.init();
|
chrono.init();
|
||||||
|
logic.init(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loop() {
|
private void loop() {
|
||||||
|
log.info("Starting game loop");
|
||||||
running = true;
|
running = true;
|
||||||
var dt = 0.0f;
|
var dt = 0.0f;
|
||||||
var accumulator = 0.0f;
|
var accumulator = 0.0f;
|
||||||
@@ -73,19 +83,20 @@ public class DefaultGameEngine implements GameEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void input() {
|
private void input() {
|
||||||
|
logic.input(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void update(float dt) {
|
private void update(float dt) {
|
||||||
|
logic.update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void render() {
|
private void render() {
|
||||||
window.update();
|
window.update();
|
||||||
|
logic.render(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanUp() {
|
private void cleanUp() {
|
||||||
|
logic.cleanUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ public class AppException extends RuntimeException {
|
|||||||
public AppException() {
|
public AppException() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppException(String message) {
|
public AppException(String message, Object... args) {
|
||||||
super(message);
|
super(String.format(message, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppException(String message, Throwable cause) {
|
public AppException(String message, Throwable cause) {
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.bartlomiejpluta.samplegame.core.gl.render;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.samplegame.core.ui.Window;
|
||||||
|
import com.bartlomiejpluta.samplegame.core.gl.shader.manager.ShaderManager;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.lwjgl.system.MemoryStack;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import static org.lwjgl.opengl.GL15.*;
|
||||||
|
import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray;
|
||||||
|
import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
|
||||||
|
import static org.lwjgl.opengl.GL30.glBindVertexArray;
|
||||||
|
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
|
public class DefaultRenderer implements Renderer {
|
||||||
|
private final ShaderManager shaderManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
log.info("Initializing renderer");
|
||||||
|
shaderManager.createShader("default", "/shaders/default.vs", "/shaders/default.fs");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(Window window) {
|
||||||
|
clear();
|
||||||
|
updateViewport(window);
|
||||||
|
|
||||||
|
shaderManager.selectShader("default").useSelectedShader();
|
||||||
|
|
||||||
|
// here the objects will be rendered with the default shader
|
||||||
|
|
||||||
|
shaderManager.detachCurrentShader();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clear() {
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateViewport(Window window) {
|
||||||
|
if(window.isResized()) {
|
||||||
|
glViewport(0, 0, window.getWidth(), window.getHeight());
|
||||||
|
window.setResized(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanUp() {
|
||||||
|
shaderManager.cleanUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.bartlomiejpluta.samplegame.core.gl.render;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.samplegame.core.ui.Window;
|
||||||
|
|
||||||
|
public interface Renderer {
|
||||||
|
void init();
|
||||||
|
|
||||||
|
void render(Window window);
|
||||||
|
|
||||||
|
void cleanUp();
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
package com.bartlomiejpluta.samplegame.core.gl.shader.manager;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.samplegame.core.util.res.ResourcesManager;
|
||||||
|
import com.bartlomiejpluta.samplegame.core.gl.shader.program.ShaderProgram;
|
||||||
|
import com.bartlomiejpluta.samplegame.core.gl.shader.uniform.Uniform;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.joml.Matrix3f;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
|
public class DefaultShaderManager implements ShaderManager {
|
||||||
|
private final ResourcesManager resourcesManager;
|
||||||
|
private final Map<String, ShaderProgram> shaders = new HashMap<>();
|
||||||
|
private ShaderProgram current;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager createShader(String programName, String vertexShaderFilename, String fragmentShaderFilename) {
|
||||||
|
log.info("Creating {} shader", programName);
|
||||||
|
var vertexShaderCode = resourcesManager.loadResourceAsString(vertexShaderFilename);
|
||||||
|
var fragmentShaderCode = resourcesManager.loadResourceAsString(fragmentShaderFilename);
|
||||||
|
var program = ShaderProgram.compile(vertexShaderCode, fragmentShaderCode);
|
||||||
|
|
||||||
|
shaders.put(programName, program);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager selectShader(String programName) {
|
||||||
|
current = shaders.get(programName);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager useSelectedShader() {
|
||||||
|
current.use();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager detachCurrentShader() {
|
||||||
|
current.detach();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager createUniform(String uniformName) {
|
||||||
|
current.createUniform(uniformName);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager createUniform(String uniformName, Uniform uniform) {
|
||||||
|
current.createUniform(uniformName, uniform);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager createUniforms(String uniformName, int size) {
|
||||||
|
current.createUniforms(uniformName, size);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager createUniforms(String uniformName, int size, Uniform uniform) {
|
||||||
|
current.createUniforms(uniformName, size, uniform);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager setUniform(String uniformName, int value) {
|
||||||
|
current.setUniform(uniformName, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager setUniform(String uniformName, float value) {
|
||||||
|
current.setUniform(uniformName, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager setUniform(String uniformName, Vector3f value) {
|
||||||
|
current.setUniform(uniformName, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager setUniform(String uniformName, Vector4f value) {
|
||||||
|
current.setUniform(uniformName, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager setUniform(String uniformName, Matrix3f value) {
|
||||||
|
current.setUniform(uniformName, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager setUniform(String uniformName, Matrix4f value) {
|
||||||
|
current.setUniform(uniformName, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager setUniform(String uniformName, Uniform uniform) {
|
||||||
|
current.setUniform(uniformName, uniform);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager setUniform(String uniformName, int index, Uniform uniform) {
|
||||||
|
current.setUniform(uniformName, index, uniform);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShaderManager setUniforms(String uniformName, Uniform[] uniforms) {
|
||||||
|
current.setUniforms(uniformName, uniforms);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanUp() {
|
||||||
|
shaders.forEach((name, program) -> program.cleanUp());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.bartlomiejpluta.samplegame.core.gl.shader.manager;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.samplegame.core.gl.shader.uniform.Uniform;
|
||||||
|
import org.joml.Matrix3f;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
|
||||||
|
public interface ShaderManager {
|
||||||
|
ShaderManager createShader(String programName, String vertexShaderFilename, String fragmentShaderFilename);
|
||||||
|
|
||||||
|
ShaderManager selectShader(String programName);
|
||||||
|
|
||||||
|
ShaderManager useSelectedShader();
|
||||||
|
|
||||||
|
ShaderManager detachCurrentShader();
|
||||||
|
|
||||||
|
ShaderManager createUniform(String uniformName);
|
||||||
|
|
||||||
|
|
||||||
|
ShaderManager createUniform(String uniformName, Uniform uniform);
|
||||||
|
|
||||||
|
|
||||||
|
ShaderManager createUniforms(String uniformName, int size);
|
||||||
|
|
||||||
|
|
||||||
|
ShaderManager createUniforms(String uniformName, int size, Uniform uniform);
|
||||||
|
|
||||||
|
|
||||||
|
ShaderManager setUniform(String uniformName, int value);
|
||||||
|
|
||||||
|
|
||||||
|
ShaderManager setUniform(String uniformName, float value);
|
||||||
|
|
||||||
|
|
||||||
|
ShaderManager setUniform(String uniformName, Vector3f value);
|
||||||
|
|
||||||
|
|
||||||
|
ShaderManager setUniform(String uniformName, Vector4f value);
|
||||||
|
|
||||||
|
|
||||||
|
ShaderManager setUniform(String uniformName, Matrix3f value);
|
||||||
|
|
||||||
|
|
||||||
|
ShaderManager setUniform(String uniformName, Matrix4f value);
|
||||||
|
|
||||||
|
|
||||||
|
ShaderManager setUniform(String uniformName, Uniform uniform);
|
||||||
|
|
||||||
|
|
||||||
|
ShaderManager setUniform(String uniformName, int index, Uniform uniform);
|
||||||
|
|
||||||
|
|
||||||
|
ShaderManager setUniforms(String uniformName, Uniform[] uniforms);
|
||||||
|
|
||||||
|
void cleanUp();
|
||||||
|
}
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
package com.bartlomiejpluta.samplegame.core.gl.shader.program;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.samplegame.core.error.AppException;
|
||||||
|
import com.bartlomiejpluta.samplegame.core.gl.shader.uniform.Uniform;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.joml.Matrix3f;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
import org.lwjgl.system.MemoryStack;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static java.lang.String.format;
|
||||||
|
import static org.lwjgl.opengl.GL20.*;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class ShaderProgram {
|
||||||
|
private final int programId;
|
||||||
|
private final int vertexShaderId;
|
||||||
|
private final int fragmentShaderId;
|
||||||
|
private final Map<String, Integer> uniforms = new HashMap<>();
|
||||||
|
|
||||||
|
private ShaderProgram(String vertexShaderCode, String fragmentShaderCode) {
|
||||||
|
this.programId = glCreateProgram();
|
||||||
|
|
||||||
|
if(this.programId == 0) {
|
||||||
|
throw new AppException("Could not create shader program");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.vertexShaderId = createShader(vertexShaderCode, GL_VERTEX_SHADER);
|
||||||
|
this.fragmentShaderId = createShader(fragmentShaderCode, GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
|
linkProgram();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int createShader(String shaderCode, int shaderType) {
|
||||||
|
int shaderId = glCreateShader(shaderType);
|
||||||
|
if(shaderId == 0) {
|
||||||
|
throw new AppException("Could not create shader of type: %s", shaderType);
|
||||||
|
}
|
||||||
|
|
||||||
|
glShaderSource(shaderId, shaderCode);
|
||||||
|
glCompileShader(shaderId);
|
||||||
|
|
||||||
|
if(glGetShaderi(shaderId, GL_COMPILE_STATUS) == 0) {
|
||||||
|
throw new AppException("Could not compile shader code: %s", glGetShaderInfoLog(shaderId, 1024));
|
||||||
|
}
|
||||||
|
|
||||||
|
glAttachShader(programId, shaderId);
|
||||||
|
|
||||||
|
return shaderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void linkProgram() {
|
||||||
|
glLinkProgram(programId);
|
||||||
|
if(glGetProgrami(programId, GL_LINK_STATUS) == 0) {
|
||||||
|
throw new AppException("Could not link shader program: %s", glGetProgramInfoLog(programId, 1024));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(vertexShaderId != 0) {
|
||||||
|
glDetachShader(programId, vertexShaderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fragmentShaderId != 0) {
|
||||||
|
glDetachShader(programId, fragmentShaderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
glValidateProgram(programId);
|
||||||
|
if(glGetProgrami(programId, GL_VALIDATE_STATUS) == 0) {
|
||||||
|
log.warn("Program validation failed: {}", glGetProgramInfoLog(programId, 1024));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createUniform(String uniformName) {
|
||||||
|
int location = glGetUniformLocation(programId, uniformName);
|
||||||
|
|
||||||
|
if(location < 0) {
|
||||||
|
throw new AppException("Could not find uniform: %s", uniformName);
|
||||||
|
}
|
||||||
|
|
||||||
|
uniforms.put(uniformName, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createUniform(String uniformName, Uniform uniform) {
|
||||||
|
uniform.createUniform(this, uniformName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createUniforms(String uniformName, int size) {
|
||||||
|
for(int i=0; i<size; ++i) {
|
||||||
|
createUniform(format("%s[%d]", uniformName, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createUniforms(String uniformName, int size, Uniform uniform) {
|
||||||
|
for(int i=0; i<size; ++i) {
|
||||||
|
createUniform(format("%s[%d]", uniformName, i), uniform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUniform(String uniformName, int value) {
|
||||||
|
glUniform1i(uniforms.get(uniformName), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUniform(String uniformName, float value) {
|
||||||
|
glUniform1f(uniforms.get(uniformName), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUniform(String uniformName, Vector3f value) {
|
||||||
|
glUniform3f(uniforms.get(uniformName), value.x, value.y, value.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUniform(String uniformName, Vector4f value) {
|
||||||
|
glUniform4f(uniforms.get(uniformName), value.x, value.y, value.z, value.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUniform(String uniformName, Matrix3f value) {
|
||||||
|
try(var stack = MemoryStack.stackPush()) {
|
||||||
|
var buffer = stack.mallocFloat(3 * 3);
|
||||||
|
value.get(buffer);
|
||||||
|
glUniformMatrix4fv(uniforms.get(uniformName), false, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUniform(String uniformName, Matrix4f value) {
|
||||||
|
try(var stack = MemoryStack.stackPush()) {
|
||||||
|
var buffer = stack.mallocFloat(4 * 4);
|
||||||
|
value.get(buffer);
|
||||||
|
glUniformMatrix4fv(uniforms.get(uniformName), false, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUniform(String uniformName, Uniform uniform) {
|
||||||
|
uniform.setUniform(this, uniformName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUniform(String uniformName, int index, Uniform uniform) {
|
||||||
|
setUniform(format("%s[%d]", uniformName, index), uniform);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUniforms(String uniformName, Uniform[] uniforms) {
|
||||||
|
var size = uniforms != null ? uniforms.length : 0;
|
||||||
|
for(int i=0; i<size; ++i) {
|
||||||
|
setUniform(format("%s[%d]", uniformName, i), uniforms[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void use() {
|
||||||
|
glUseProgram(programId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void detach() {
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanUp() {
|
||||||
|
glUseProgram(0);
|
||||||
|
|
||||||
|
if(programId != 0) {
|
||||||
|
glDeleteProgram(programId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ShaderProgram compile(String vertexShaderCode, String fragmentShaderCode) {
|
||||||
|
return new ShaderProgram(vertexShaderCode, fragmentShaderCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.bartlomiejpluta.samplegame.core.gl.shader.uniform;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.samplegame.core.gl.shader.program.ShaderProgram;
|
||||||
|
|
||||||
|
public interface Uniform {
|
||||||
|
void createUniform(ShaderProgram shaderProgram, String uniformName);
|
||||||
|
|
||||||
|
void setUniform(ShaderProgram shaderProgram, String uniformName);
|
||||||
|
}
|
||||||
15
app/src/main/java/com/bartlomiejpluta/samplegame/core/logic/GameLogic.java
Executable file
15
app/src/main/java/com/bartlomiejpluta/samplegame/core/logic/GameLogic.java
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
package com.bartlomiejpluta.samplegame.core.logic;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.samplegame.core.ui.Window;
|
||||||
|
|
||||||
|
public interface GameLogic {
|
||||||
|
void init(Window window);
|
||||||
|
|
||||||
|
void input(Window window);
|
||||||
|
|
||||||
|
void update(float dt);
|
||||||
|
|
||||||
|
void render(Window window);
|
||||||
|
|
||||||
|
void cleanUp();
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class ThreadManager {
|
public class ThreadManager {
|
||||||
public Thread createThread(Runnable runnable) {
|
public Thread createThread(String name, Runnable runnable) {
|
||||||
return new Thread(runnable);
|
return new Thread(runnable, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package com.bartlomiejpluta.samplegame.core.ui;
|
|||||||
import com.bartlomiejpluta.samplegame.core.error.AppException;
|
import com.bartlomiejpluta.samplegame.core.error.AppException;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||||
import org.lwjgl.glfw.GLFWVidMode;
|
import org.lwjgl.glfw.GLFWVidMode;
|
||||||
import org.lwjgl.opengl.GL;
|
import org.lwjgl.opengl.GL;
|
||||||
@@ -15,9 +17,16 @@ import static org.lwjgl.system.MemoryUtil.NULL;
|
|||||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public class Window {
|
public class Window {
|
||||||
private final String title;
|
private final String title;
|
||||||
private int width;
|
|
||||||
private int height;
|
|
||||||
private long windowHandle;
|
private long windowHandle;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private int width;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private int height;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
private boolean resized;
|
private boolean resized;
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
@@ -102,6 +111,6 @@ public class Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Window create(String title, int width, int height) {
|
public static Window create(String title, int width, int height) {
|
||||||
return new Window(title, width, height, -1, false);
|
return new Window(title, -1, width, height, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.bartlomiejpluta.samplegame.core.util.res;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.samplegame.core.error.AppException;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ResourcesManager {
|
||||||
|
public String loadResourceAsString(String fileName) {
|
||||||
|
try (InputStream in = ResourcesManager.class.getResourceAsStream(fileName);
|
||||||
|
Scanner scanner = new Scanner(in, java.nio.charset.StandardCharsets.UTF_8.name())) {
|
||||||
|
return scanner.useDelimiter("\\A").next();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new AppException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.bartlomiejpluta.samplegame.game.logic;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.samplegame.core.gl.render.Renderer;
|
||||||
|
import com.bartlomiejpluta.samplegame.core.logic.GameLogic;
|
||||||
|
import com.bartlomiejpluta.samplegame.core.ui.Window;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
|
public class DefaultGameLogic implements GameLogic {
|
||||||
|
private final Renderer renderer;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Window window) {
|
||||||
|
log.info("Initializing game logic");
|
||||||
|
renderer.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void input(Window window) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(float dt) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(Window window) {
|
||||||
|
renderer.render(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanUp() {
|
||||||
|
renderer.cleanUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
8
app/src/main/resources/shaders/default.fs
Executable file
8
app/src/main/resources/shaders/default.fs
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
fragColor = vec4(0.0, 0.5, 0.5, 1.0);
|
||||||
|
}
|
||||||
8
app/src/main/resources/shaders/default.vs
Executable file
8
app/src/main/resources/shaders/default.vs
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
layout(location=0) in vec3 position;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(position, 1.0);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user