initial Commit
This commit is contained in:
parent
fb15ff8f06
commit
82db1f9321
65 changed files with 1616 additions and 0 deletions
11
src/main/java/net/halbear/Executable/Init.java
Normal file
11
src/main/java/net/halbear/Executable/Init.java
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package net.halbear.Executable;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||
|
||||
public class Init {
|
||||
public static void main(String[] args){
|
||||
var GameEngine = new PrimaryRuntime("Terrain4J", new GameCore());
|
||||
GameEngine.run();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Display;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
|
||||
public class Render {
|
||||
public Render(EngineInstance engineInstance) {
|
||||
|
||||
}
|
||||
public void cleanup() {
|
||||
|
||||
}
|
||||
public void render(EngineInstance engineInstance) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Display;
|
||||
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.vulkan.VK;
|
||||
import org.lwjgl.vulkan.VkApplicationInfo;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static org.lwjgl.vulkan.VK14.VK_API_VERSION_1_4;
|
||||
|
||||
public class VulkanInstance {
|
||||
public VulkanInstance(boolean validate){
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
ByteBuffer appShortName = stack.UTF8("Terrain4J");
|
||||
var appInfo = VkApplicationInfo.calloc(stack).sType$Default().pApplicationName(appShortName).applicationVersion(1).pEngineName(appShortName).engineVersion(3).apiVersion(VK_API_VERSION_1_4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Display;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput;
|
||||
import net.halbear.Terrain4J.EngineCore.Input.MouseListener;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Globals;
|
||||
import org.lwjgl.glfw.GLFWVidMode;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
import static org.lwjgl.glfw.GLFWVulkan.glfwVulkanSupported;
|
||||
|
||||
public class Window {
|
||||
private final long handle;
|
||||
private final KeyboardInput keyboardInput;
|
||||
private final MouseListener mouseInput;
|
||||
private int height;
|
||||
private int width;
|
||||
private boolean displayFPS = true;
|
||||
|
||||
public Window(String title){
|
||||
if (!glfwInit()) {
|
||||
throw new RuntimeException("Unable to initialize GLFW");
|
||||
}
|
||||
if (!glfwVulkanSupported()) {
|
||||
throw new RuntimeException("Cannot find a compatible Vulkan installable client driver (ICD)");
|
||||
}
|
||||
GLFWVidMode vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
||||
if (vidMode == null) {
|
||||
throw new RuntimeException("Error getting primary monitor");
|
||||
}
|
||||
width = vidMode.width(); //Globals.getInstance().getWidth();
|
||||
height = vidMode.height();//Globals.getInstance().getHeight();
|
||||
|
||||
glfwDefaultWindowHints();
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
glfwWindowHint(GLFW_MAXIMIZED, GLFW_FALSE);
|
||||
|
||||
handle = glfwCreateWindow(width, height, title, MemoryUtil.NULL, MemoryUtil.NULL);
|
||||
if (handle == MemoryUtil.NULL) {
|
||||
//throw new RuntimeException("Failed to create the GLFW window");
|
||||
}
|
||||
keyboardInput = new KeyboardInput(handle);
|
||||
|
||||
glfwSetFramebufferSizeCallback(handle, (window, w, h) -> {
|
||||
width = w;
|
||||
height = h;
|
||||
});
|
||||
|
||||
glfwMakeContextCurrent(handle);
|
||||
if (Globals.VSYNC) glfwSwapInterval(1);
|
||||
else glfwSwapInterval(0);
|
||||
mouseInput = new MouseListener(handle);
|
||||
}
|
||||
public void cleanup() {
|
||||
glfwFreeCallbacks(handle);
|
||||
glfwDestroyWindow(handle);
|
||||
glfwTerminate();
|
||||
}
|
||||
public long getHandle(){
|
||||
return handle;
|
||||
}
|
||||
public int getHeight(){return height;}
|
||||
public int getWidth(){return width;}
|
||||
public KeyboardInput getKeyboardInput(){
|
||||
return keyboardInput;
|
||||
}
|
||||
public MouseListener getMouseInput(){
|
||||
return mouseInput;
|
||||
}
|
||||
public void pollEvents() {
|
||||
if (displayFPS) glfwSetWindowTitle(handle, "Terrain 4J Engine - FPS: " + Globals.FrameRate_PRIMARYTHREAD + " TPS: " + Globals.TPS + " RenderFPS: " + Globals.FrameRate_RENDER + " VSYNC: " + Globals.VSYNC);
|
||||
if (keyboardInput.keySinglePress(GLFW_KEY_V)) {
|
||||
SetVsync();
|
||||
}
|
||||
keyboardInput.input();
|
||||
mouseInput.input();
|
||||
Globals.RENDERFRAMES++;
|
||||
}
|
||||
public void SetVsync(){
|
||||
if (Globals.VSYNC) {
|
||||
glfwSwapInterval(0);
|
||||
Globals.VSYNC = false;
|
||||
}
|
||||
else {
|
||||
glfwSwapInterval(1);
|
||||
Globals.VSYNC = true;
|
||||
}
|
||||
}
|
||||
public void setShouldClose() {
|
||||
glfwSetWindowShouldClose(handle, true);
|
||||
}
|
||||
public boolean shouldClose() {
|
||||
//return false;
|
||||
return glfwWindowShouldClose(handle);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Input;
|
||||
|
||||
import org.lwjgl.glfw.GLFWCharCallbackI;
|
||||
import org.lwjgl.glfw.GLFWKeyCallback;
|
||||
import org.lwjgl.glfw.GLFWKeyCallbackI;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
|
||||
public class KeyboardInput {
|
||||
|
||||
private long window;
|
||||
public List<Integer> keysPressed = new ArrayList<>();
|
||||
public List<Integer> keysSinglePressed = new ArrayList<>();
|
||||
|
||||
public KeyboardInput(long Window){
|
||||
window = Window;
|
||||
glfwSetKeyCallback(window, this::KeyCallback);
|
||||
}
|
||||
public void input() {
|
||||
glfwPollEvents();
|
||||
}
|
||||
public void KeyCallback(long Window, int key, int scancode, int action, int mods){
|
||||
if (!keysPressed.contains(key) && action == GLFW_PRESS){
|
||||
keysPressed.add(key);
|
||||
} else if (keysPressed.contains(key) && action == GLFW_RELEASE){
|
||||
if (keysPressed.indexOf(key) >= 0 && keysPressed.indexOf(key) <keysPressed.size()){
|
||||
keysPressed.remove(keysPressed.indexOf(key));
|
||||
}
|
||||
}
|
||||
if (keysSinglePressed.contains(key)&& action == GLFW_RELEASE) keysSinglePressed.remove(keysSinglePressed.indexOf(key));
|
||||
}
|
||||
public boolean keyPressed(int keyCode) {
|
||||
if (keysPressed.contains(keyCode)) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
public boolean keySinglePress(int keyCode) {
|
||||
if (keysPressed.contains(keyCode)) {
|
||||
if (keysSinglePressed.contains(keyCode)) return false;
|
||||
else {
|
||||
keysSinglePressed.add(keyCode);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCharCallBack(GLFWCharCallbackI charCallback) {
|
||||
glfwSetCharCallback(window, charCallback);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Input;
|
||||
|
||||
import org.joml.Vector2f;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
|
||||
public class MouseListener {
|
||||
private final Vector2f currentPos;
|
||||
private final Vector2f deltaPos;
|
||||
private final Vector2f previousPos;
|
||||
private boolean FocusWindow;
|
||||
private boolean leftButtonPressed;
|
||||
private boolean rightButtonPressed;
|
||||
private boolean middleButtonPressed;
|
||||
public MouseListener(long window) {
|
||||
previousPos = new Vector2f(-1,-1);
|
||||
currentPos = new Vector2f();
|
||||
deltaPos = new Vector2f();
|
||||
leftButtonPressed = false;
|
||||
rightButtonPressed = false;
|
||||
FocusWindow = false;
|
||||
glfwSetCursorPosCallback(window, (handle, xpos, ypos) -> {
|
||||
currentPos.x = (float) xpos;
|
||||
currentPos.y = (float) ypos;
|
||||
});
|
||||
glfwSetCursorEnterCallback(window, (handle, entered) -> FocusWindow = entered);
|
||||
glfwSetMouseButtonCallback(window, (handle, button, action, mode) -> {
|
||||
leftButtonPressed = button == GLFW_MOUSE_BUTTON_1 && action == GLFW_PRESS;
|
||||
rightButtonPressed = button == GLFW_MOUSE_BUTTON_2 && action == GLFW_PRESS;
|
||||
middleButtonPressed = button == GLFW_MOUSE_BUTTON_3 && action == GLFW_PRESS;
|
||||
});
|
||||
}
|
||||
public Vector2f getCurrentPos() {
|
||||
return currentPos;
|
||||
}
|
||||
public Vector2f getDeltaPos() {
|
||||
return deltaPos;
|
||||
}
|
||||
public void input() {
|
||||
deltaPos.x = 0;
|
||||
deltaPos.y = 0;
|
||||
if (previousPos.x >= 0 && previousPos.y >= 0 && FocusWindow) {
|
||||
deltaPos.x = currentPos.x - previousPos.x;
|
||||
deltaPos.y = currentPos.y - previousPos.y;
|
||||
}
|
||||
previousPos.x = currentPos.x;
|
||||
previousPos.y = currentPos.y;
|
||||
}
|
||||
public boolean isLeftButtonPressed() {
|
||||
return leftButtonPressed;
|
||||
}
|
||||
public boolean isRightButtonPressed() {
|
||||
return rightButtonPressed;
|
||||
}
|
||||
public boolean isMiddleButtonPressed() {
|
||||
return rightButtonPressed;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene;
|
||||
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
||||
|
||||
public record EngineInstance(Window window, Scene scene) {
|
||||
public void cleanup(){
|
||||
window.cleanup();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic;
|
||||
|
||||
public interface GameLogic {
|
||||
void cleanup();
|
||||
void Initialise(EngineInstance engineInstance);
|
||||
void Input(EngineInstance engineInstance, long diffMS);
|
||||
void Update(EngineInstance engineInstance, long diffMS);
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class Globals {
|
||||
private static final long DEFAULT_ACCURACY = 0;
|
||||
private static final int DEFAULT_TICKRATE = 60;
|
||||
private static final int DEFAULT_WIDTH = 640;
|
||||
private static final int DEFAULT_HEIGHT = 480;
|
||||
private static final String FILENAME = "terrain4j.properties";
|
||||
private static Globals instance;
|
||||
private long accuracy;
|
||||
private int TickRate;
|
||||
private int Width;
|
||||
private int Height;
|
||||
public static int FrameRate_PRIMARYTHREAD =0;
|
||||
public static int TPS =0;
|
||||
public static int FrameRate_MAINENGINETHREAD =0;
|
||||
public static int FrameRate_RENDER =0;
|
||||
public static int RENDERFRAMES =0;
|
||||
public static boolean VSYNC = false;
|
||||
|
||||
|
||||
private Globals() {
|
||||
var EngineConfig = new Properties();
|
||||
Path path = Paths.get("");
|
||||
InputStream stream = Globals.class.getResourceAsStream(path.toAbsolutePath().toString() + "/" + FILENAME);
|
||||
boolean SuccessfulLoad = false;
|
||||
if (stream != null) {
|
||||
try {
|
||||
EngineConfig.load(stream);
|
||||
SuccessfulLoad = true;
|
||||
} catch (IOException excp) {
|
||||
System.out.println(excp.getMessage());
|
||||
}
|
||||
}
|
||||
if (SuccessfulLoad){
|
||||
accuracy = Long.parseLong(EngineConfig.getOrDefault("frame_accuracy", DEFAULT_ACCURACY).toString());
|
||||
TickRate = Integer.parseInt(EngineConfig.getOrDefault("main_tick_rate", DEFAULT_TICKRATE).toString());
|
||||
Width = Integer.parseInt(EngineConfig.getOrDefault("display_width", DEFAULT_TICKRATE).toString());
|
||||
Height = Integer.parseInt(EngineConfig.getOrDefault("display_height", DEFAULT_TICKRATE).toString());
|
||||
VSYNC = Boolean.parseBoolean(EngineConfig.getOrDefault("vsync", false).toString());
|
||||
try {
|
||||
assert stream != null;
|
||||
stream.close();
|
||||
} catch(IOException excp) {
|
||||
System.out.println(excp.getMessage());
|
||||
}
|
||||
} else{
|
||||
try {
|
||||
EngineConfig.setProperty("frame_accuracy", "0");
|
||||
EngineConfig.setProperty("main_tick_rate", "60");
|
||||
EngineConfig.setProperty("display_width", "640");
|
||||
EngineConfig.setProperty("display_height", "480");
|
||||
EngineConfig.setProperty("vsync", "false");
|
||||
EngineConfig.store(new FileWriter(path.toAbsolutePath().toString() + "/" + FILENAME), "created new properties file");
|
||||
} catch (IOException excp2) {
|
||||
System.out.println(excp2.getMessage());
|
||||
}
|
||||
accuracy = DEFAULT_ACCURACY;
|
||||
TickRate = DEFAULT_TICKRATE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static synchronized Globals getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new Globals();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
public int getWidth(){
|
||||
return Width;
|
||||
}
|
||||
public int getHeight(){
|
||||
return Height;
|
||||
}
|
||||
public long getAccuracy() {
|
||||
return accuracy;
|
||||
}
|
||||
public int getTickRate() {
|
||||
return TickRate;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.GameLogic;
|
||||
|
||||
public class GameCore implements GameLogic {
|
||||
@Override
|
||||
public void cleanup() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Initialise(EngineInstance engineInstance) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Input(EngineInstance engineInstance, long diffMS) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Update(EngineInstance engineInstance, long diffMS) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Display.Render;
|
||||
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Globals;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.GameLogic;
|
||||
|
||||
public class PrimaryRuntime {
|
||||
private final EngineInstance engineInstance;
|
||||
private final GameLogic gameLogic;
|
||||
private final Render render;
|
||||
private Window window;
|
||||
private int Frames = 0;
|
||||
private int TickFrames = 0;
|
||||
|
||||
public PrimaryRuntime(String windowTitle, GameLogic appLogic) {
|
||||
this.gameLogic = appLogic;
|
||||
window = new Window(windowTitle);
|
||||
engineInstance = new EngineInstance(window, new Scene(window));
|
||||
render = new Render(engineInstance);
|
||||
gameLogic.Initialise(engineInstance);
|
||||
}
|
||||
private void cleanup() {
|
||||
gameLogic.cleanup();
|
||||
render.cleanup();
|
||||
engineInstance.cleanup();
|
||||
}
|
||||
public EngineInstance getEngineInstance() {
|
||||
return engineInstance;
|
||||
}
|
||||
public void run(){
|
||||
long InitialTime = System.nanoTime();
|
||||
long updateTime = InitialTime;
|
||||
double FrameDiff =0;
|
||||
double TickDiff =0;
|
||||
double SecondCounter =0;
|
||||
double tickDiff = 0;
|
||||
while (!window.shouldClose()){
|
||||
long now = System.nanoTime();
|
||||
tickDiff = now - InitialTime;
|
||||
FrameDiff += tickDiff;
|
||||
TickDiff += tickDiff;
|
||||
SecondCounter += tickDiff;
|
||||
if (FrameDiff >= Globals.getInstance().getAccuracy()){
|
||||
window.pollEvents();
|
||||
gameLogic.Input(engineInstance, (now - InitialTime)/ 1000000);
|
||||
Frames++;
|
||||
if (TickDiff/1000 >= (double) 1000000 / (double)Globals.getInstance().getTickRate()) {
|
||||
TickFrames++;
|
||||
long nsTimeDiff = now - updateTime;
|
||||
gameLogic.Update(engineInstance, nsTimeDiff / 1000000);
|
||||
updateTime = now;
|
||||
TickDiff = 0;
|
||||
}
|
||||
if (SecondCounter >= 1000000000){
|
||||
SecondCounter = 0;
|
||||
System.out.println("FPS: " + Frames + " Ticks: " + TickFrames);
|
||||
Globals.FrameRate_PRIMARYTHREAD = Frames;
|
||||
Globals.FrameRate_RENDER = Globals.RENDERFRAMES;
|
||||
Globals.TPS = TickFrames;
|
||||
Frames = 0;
|
||||
TickFrames = 0;
|
||||
Globals.RENDERFRAMES = 0;
|
||||
}
|
||||
render.render(engineInstance);
|
||||
FrameDiff = 0;
|
||||
}
|
||||
InitialTime = now;
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
||||
|
||||
public class Scene {
|
||||
public Scene(Window window) {
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue