Fixed some volume related issues, separated options into its own menu with tabs, added a visualised collision actor (dual pass graphics required), added a player model, started shooting mechanics

This commit is contained in:
Halbear 2026-07-10 01:01:13 +01:00
parent f3aee6cb84
commit 59c5486299
24 changed files with 1538 additions and 1356 deletions

View file

@ -6,10 +6,12 @@ import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import org.tinylog.Logger;
import org.tinylog.configuration.Configuration;
import java.util.UUID;
//Halbear was here
public class Init {
public static void main(String[] args){
Configuration.set("writer.file", "ClientLog.t4jlog");
Configuration.set("writer.file", "ClientLog" + UUID.randomUUID() +".t4jlog");
Logger.info("\nLaunching New Terrain4J Powered Software!");
var GameEngine = new PrimaryRuntime(EngineConfig.getInstance().GetSoftwareName(), new GameCore());
Logger.info("Launched Terrain4J Engine");

View file

@ -12,6 +12,8 @@ import org.tinylog.Logger;
import java.io.File;
import static net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.StartMenu.GameStarted;
import static net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.StartMenu.ShowSettings;
import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.glfw.GLFWVulkan.glfwVulkanSupported;
@ -24,6 +26,9 @@ public class Window {
private int width;
private boolean displayFPS = false;
public boolean CursorLocked = false;
public boolean ForceCursorUnlock = false;
public Window(String title){
if (!glfwInit()) {
@ -40,11 +45,16 @@ public class Window {
height = vidMode.height();//Globals.getInstance().getHeight();
glfwDefaultWindowHints();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_MAXIMIZED, GLFW_FALSE);
glfwWindowHint(GLFW_ALPHA_BITS, 0);
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_FALSE);
handle = glfwCreateWindow(width, height, title, MemoryUtil.NULL, MemoryUtil.NULL);
if (glfwRawMouseMotionSupported()) {
glfwSetInputMode(handle, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
}
LockCursor();
if (handle == MemoryUtil.NULL) {
//throw new RuntimeException("Failed to create the GLFW window");
}
@ -93,6 +103,16 @@ public class Window {
else glfwSwapInterval(0);
mouseInput = new MouseListener(handle);
}
public void LockCursor(){
CursorLocked = true;
glfwSetInputMode(handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
}
public void UnlockCursor(){
CursorLocked = false;
glfwSetInputMode(handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
}
public void cleanup() {
glfwFreeCallbacks(handle);
glfwDestroyWindow(handle);
@ -111,6 +131,8 @@ public class Window {
return mouseInput;
}
public void pollEvents() {
if((!GameStarted || ShowSettings || ForceCursorUnlock) && CursorLocked) UnlockCursor();
else if (GameStarted && !ShowSettings && !CursorLocked) LockCursor();
if (keyboardInput.keySinglePress(GLFW_KEY_V)) {
SetVsync();
}

View file

@ -80,6 +80,11 @@ public class EngineConfig {
public boolean RenderCollisionMesh = true;
public float PhysicsSpeed = 1.0f;
public float MusicVolume = 1.0f;
public float SoundVolume = 1.0f;
public float WeaponVolume = 1.0f;
public float AmbientVolume = 1.0f;
public float PhysicsSpeed(){return PhysicsSpeed;}
public void SetPhysicsSpeed(float NewSpeed){PhysicsSpeed =NewSpeed;}

View file

@ -3,14 +3,54 @@ package net.halbear.Terrain4J.EngineCore.Main;
import net.halbear.Terrain4J.EngineCore.Audio.AudioManager;
import net.halbear.Terrain4J.EngineCore.Audio.AudioSource;
import net.halbear.Terrain4J.EngineCore.Audio.SoundBuffer;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import org.joml.Vector3f;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class AudioInstance {
public static final Map<String, AudioInstance> AudioInstances = new HashMap<>();
public static void ApplyUniversalVolume(){
AudioInstances.forEach((name,instance)->{
switch (instance.audioType){
case SFX:
instance.SetVolume(EngineConfig.getInstance().SoundVolume);
break;
case WEAPONS:
instance.SetVolume(EngineConfig.getInstance().WeaponVolume);
break;
case MUSIC:
instance.SetVolume(EngineConfig.getInstance().MusicVolume);
break;
case AMBIENT:
instance.SetVolume(EngineConfig.getInstance().AmbientVolume);
break;
default:
}
});
}
public enum AudioType{
SFX,
WEAPONS,
MUSIC,
AMBIENT
}
private String SourcePath;
private String BUFFER_ID = "AUDIO_INSTANCE_BUFFER";
private String SOURCE_ID = "AUDIO_INSTANCE_SOURCE";
private String InstanceName = "";
private AudioSource audioSource;
public AudioType audioType = AudioType.MUSIC;
public AudioInstance SetAudioType(AudioType type){
audioType = type;
return this;
}
public AudioInstance(String AudioSourcePath, String InstanceName, AudioManager manager, boolean loop){
SourcePath = AudioSourcePath;
@ -22,6 +62,7 @@ public class AudioInstance {
this.audioSource = new AudioSource(loop,true);
audioSource.SetBuffer(buffer.GetBufferID());
manager.AddSoundSource(SOURCE_ID,audioSource);
AudioInstances.put(InstanceName,this);
}
public AudioInstance(String AudioSourcePath,String InstanceName, AudioManager manager, float X, float Y, float Z, boolean loop){
SourcePath = AudioSourcePath;

View file

@ -25,6 +25,7 @@ import net.halbear.Terrain4J.EngineCore.Logic.Rendering.ModelLoader;
import net.halbear.Terrain4J.EngineCore.Main.Scene.*;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.Gimbal;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.LoadingScreen;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.SettingsMenu;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.StartMenu;
import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor;
import net.halbear.Terrain4J.EngineCore.Profiling.GPUProfiler;
@ -67,9 +68,11 @@ public class GameCore implements GameLogic {
private String CubeModelID = "Cube";
private ModelData MusketData;
private ModelData RevolverData;
private ModelData FlintlockData;
public ILight SkyLight;
private LoadingScreen loadingScreen;
public final StartMenu startMenu = new StartMenu();
public final SettingsMenu Settings = new SettingsMenu();
public boolean StartMenuActive = true;
public List<IMoveableActorComponent> ActorEditorComponents = new ArrayList<>();
private Vector2f DeltaPos = new Vector2f(0,0);
@ -102,45 +105,28 @@ public class GameCore implements GameLogic {
List<MaterialData> MusketMat = ModelLoader.LoadMaterials("resources/models/musket/musket_mat.json");
RevolverData = ModelLoader.LoadModel("resources/models/Revolver/Revolver.json");
List<MaterialData> RevolverMat = ModelLoader.LoadMaterials("resources/models/Revolver/Revolver_mat.json");
Item MusketItem = new Item(MusketData.ID(), 1.0f, 8);
Item RevolverItem = new Item(RevolverData.ID(), 2.0f, 6);
FlintlockData = ModelLoader.LoadModel("resources/models/Flintlock/Flintlock.json");
List<MaterialData> FlintlockMat = ModelLoader.LoadMaterials("resources/models/Flintlock/Flintlock_mat.json");
Item MusketItem = new Item(MusketData.ID(), 1.0f, 1, 10.0f);
Item RevolverItem = new Item(RevolverData.ID(), 4.0f, 6, 10.0f);
Item FlintLock = new Item(FlintlockData.ID(), 1.0f, 2, 10.0f);
scene.MusketItem = MusketItem;
scene.RevolverItem = RevolverItem;
scene.FlintLockItem = FlintLock;
boolean createOfflinePlayer = !PrimaryRuntime.Server && !ClientConnectionThread.Connected;
if(createOfflinePlayer) {
var Musket = new PlayerActor("DebugCamera","Player_Musket", MusketData.ID(), new Vector3f(0,5f,-5f)).SetCameraOffset(new Vector3f(0,1.0f,0));
Musket.SetPositionOffset(new Vector3f(0.5f,1.0f,-1.25f));
Musket.SetRotation(0,(float)Math.toRadians(180),0);
Musket.CreatePhysicsController( ConvexMesh.Box(0.5f,0.75f,0.5f),200f);
PlayerActorID = "Player_Musket";
scene.Musket = Musket;
scene.CreatePlayerController(scene.Musket);
RigidPhysicsController physicsController = (RigidPhysicsController) Musket.GetPhysicsController();
RigidBody.RigidBodyRegister.get(physicsController.RigidBodyID).LockRotation();
var Revolver = new PlayerActor("NULL","Player_Revolver", RevolverData.ID(), new Vector3f(0,5f,-5f)).SetCameraOffset(new Vector3f(0,1.0f,0));
Revolver.SetPositionOffset(new Vector3f(0.5f,1.0f,-1.25f));
Revolver.SetRotation(0,(float)Math.toRadians(180),0);
Revolver.CreatePhysicsController( ConvexMesh.Box(0.5f,0.75f,0.5f),200f);
scene.Revolver = Revolver;
PlayerActorID = "Player_Revolver";
physicsController = (RigidPhysicsController) Revolver.GetPhysicsController();
RigidBody.RigidBodyRegister.get(physicsController.RigidBodyID).LockRotation();
scene.AddActor(Musket);
scene.AddActor(Revolver);
materials.addAll(RevolverMat);
}
materials.addAll(MelonaMat);
materials.addAll(CollisionVisualisationMat);
materials.addAll(MelonaMaterial);
materials.addAll(MusketMat);
materials.addAll(RevolverMat);
materials.addAll(FlintlockMat);
models.add(MelonaData);
models.add(CollisionVisualisationData);
models.add(Melona);
models.add(MusketData);
models.add(RevolverData);
models.add(FlintlockData);
Camera camera = scene.GetCamera();
camera.SetPosition(0,0,0);
camera.SetRotation(0,0,0);
@ -180,6 +166,9 @@ public class GameCore implements GameLogic {
SpawnNewStaticActor(engineInstance, new Vector3f(x * 4f, -4 * (float) Math.random(), y * 4f), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
}
}
for(int i = 0; i < 20; i++){
SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
}
}
return new InitData(models,materials,guiTextures);
}
@ -232,11 +221,11 @@ public class GameCore implements GameLogic {
actorID,
MusketData.ID(),
new Vector3f(0, 8f, 0)
).SetCameraOffset(new Vector3f(0, 1.0f, 0));
).SetCameraOffset(new Vector3f(0, 1.85f, 0));
player.SetPositionOffset(new Vector3f(0.5f, 1.0f, -1.25f));
player.SetPositionOffset(new Vector3f(0.5f, 1.25f, -1.25f));
player.SetRotation(0, (float)Math.toRadians(180), 0);
player.CreatePhysicsController(ConvexMesh.Box(0.5f, 0.75f, 0.5f), 200f);
player.CreatePhysicsController(ConvexMesh.Box(0.6f, 1.0f, 0.6f), 200f);
player.SetServerSynced(true);
RigidPhysicsController physicsController = (RigidPhysicsController) player.GetPhysicsController();
@ -430,7 +419,8 @@ public class GameCore implements GameLogic {
loadingScreen.RenderGUI(engineInstance, frameTimeNS, this);
} else if (StartMenuActive) {
startMenu.RenderGUI(engineInstance, frameTimeNS, this);
if (startMenu.GameStarted) {
Settings.RenderGUI(engineInstance, frameTimeNS, this);
if (startMenu.GameStarted && !StartMenu.ShowSettings) {
StartMenuActive = false;
}
} else {
@ -459,6 +449,7 @@ public class GameCore implements GameLogic {
VisualisedCollisionActor.CollisionVisuals.get(i).Update();
}
for(int i = 0; i < ActorElement.ElementNames.size(); i++){
if( ActorElement.ActorElementRegistry.get(ActorElement.ElementNames.get(i)) == null) continue;
ActorElement.ActorElementRegistry.get(ActorElement.ElementNames.get(i)).UpdateModelMatrix();
}
}

View file

@ -11,6 +11,7 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import org.tinylog.Logger;
import java.io.IOException;
import java.util.ArrayList;
@ -25,6 +26,8 @@ public class Actor{
T4JLegacyCollision
}
public float Health = 100f;
public static final Map<String, Actor> Actors = new HashMap<>();
public static final List<String> ActorNames = new ArrayList<>();
protected final String ID;
@ -273,7 +276,11 @@ public class Actor{
public String GetID(){return ID;}
public String GetModelID(){return ModelID;}
public void SetModelID(String ModelID) { this.ModelID = ModelID; }
public void SetModelID(String ModelID) {
String OldID = this.ModelID;
this.ModelID = ModelID;
Logger.debug("ModelID of Actor has been Changed from [{}] to [{}]",OldID,this.ModelID);
}
public Matrix4f GetModelMatrix(){return ModelMatrix;}
public Vector3f GetPosition(){ return Position;}
public Quaternionf GetRotation(){return Rotation;}

View file

@ -79,7 +79,7 @@ public class Camera {
public void SetRotation(float x, float y, float z){Rotation.set(x,y,z);Recalculate();}
public void AddRotation(float x, float y, float z){Rotation.add(x,y,z);Recalculate(); }
public void AddRotation(float x, float y, float z){Rotation.set((float) ((Rotation.x + x)%(2*Math.PI)),(float) ((Rotation.y + y)%(2*Math.PI)),(float) ((Rotation.z + z)%(2*Math.PI)));Recalculate(); }
public void AddRotX(float x){Rotation.x += x; Recalculate();}
public void AddRotY(float y){Rotation.y += y; Recalculate();}
public void AddRotZ(float z){Rotation.z += z; Recalculate();}

View file

@ -0,0 +1,237 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs;
import imgui.ImGui;
import imgui.ImGuiViewport;
import imgui.flag.ImGuiCol;
import imgui.flag.ImGuiCond;
import imgui.flag.ImGuiStyleVar;
import imgui.flag.ImGuiWindowFlags;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Main.AudioInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.DeferredSceneRender;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
import org.tinylog.Logger;
public class SettingsMenu implements GUIOverlay {
public int[] Music = new int[]{100};
public int[] SFX = new int[]{100};
public int[] Weapons = new int[]{100};
public int[] Ambient = new int[]{100};
@Override
public void RenderGUI(EngineInstance engineInstance, long frameTimeNS, GameCore parent) {
if (!StartMenu.ShowSettings) return;
ImGuiViewport viewport = ImGui.getMainViewport();
int menuFlags = ImGuiWindowFlags.NoDecoration
| ImGuiWindowFlags.AlwaysAutoResize
| ImGuiWindowFlags.NoSavedSettings
| ImGuiWindowFlags.NoFocusOnAppearing
| ImGuiWindowFlags.NoNav
| ImGuiWindowFlags.NoMove;
float CenterX = viewport.getWorkPosX() + viewport.getWorkSizeX() / 2.0f;
float CenterY = viewport.getWorkPosY() + viewport.getWorkSizeY() / 2.0f;
ImGui.setNextWindowPos(viewport.getWorkPosX(), viewport.getWorkPosY(), ImGuiCond.Always);
ImGui.setNextWindowSize(viewport.getWorkSizeX(), viewport.getWorkSizeY());
ImGui.pushStyleColor(ImGuiCol.WindowBg, 0.08f, 0.08f, 0.1f, 1.0f);
ImGui.pushStyleVar(ImGuiStyleVar.WindowPadding, 40f, 30f);
ImGui.pushStyleVar(ImGuiStyleVar.ItemSpacing, 10f, 16f);
ImGui.pushStyleVar(ImGuiStyleVar.WindowRounding, 8f);
ImGui.begin("Start Menu", menuFlags);
ImGui.setWindowFontScale(4.0f);
if (ImGui.button("Return")) {
StartMenu.ShowSettings = false;
if(StartMenu.GameStarted){
Scene scene = (Scene) engineInstance.scene();
parent.SwitchBGM(engineInstance, scene, "resources/EngineResources/audio/music/CHILL_REGGAE_2_StealthGroover.ogg");
}
}
ImGui.sameLine();
if (ImGui.button("Main Menu")) {
StartMenu.ShowSettings = false;
StartMenu.GameStarted = false;
}
ImGui.sameLine();
ImGui.text("Settings");
ImGui.setWindowFontScale(3f);
ImGui.spacing();
if (ImGui.beginTabBar("Settings")) {
if (ImGui.beginTabItem("Audio")) {
ImGui.setWindowFontScale(4.0f);
ImGui.text("Audio Settings");
ImGui.setWindowFontScale(3f);
if (ImGui.sliderInt("Music Volume", Music, 0, 100)) {
EngineConfig.getInstance().MusicVolume = Music[0] / 100.0f;
AudioInstance.ApplyUniversalVolume();
}
if (ImGui.sliderInt("SFX Volume", SFX, 0, 100)) {
EngineConfig.getInstance().SoundVolume = SFX[0] / 100.0f;
AudioInstance.ApplyUniversalVolume();
}
if (ImGui.sliderInt("Weapon Volume", Weapons, 0, 100)) {
EngineConfig.getInstance().WeaponVolume = Weapons[0] / 100.0f;
AudioInstance.ApplyUniversalVolume();
}
if (ImGui.sliderInt("Ambient Volume", Ambient, 0, 100)) {
EngineConfig.getInstance().AmbientVolume = Ambient[0] / 100.0f;
AudioInstance.ApplyUniversalVolume();
}
if (ImGui.button("Mute")) {
EngineConfig.getInstance().MusicVolume = 0;
EngineConfig.getInstance().SoundVolume = 0;
EngineConfig.getInstance().WeaponVolume = 0;
EngineConfig.getInstance().AmbientVolume = 0;
Music[0] = 0;
SFX[0] = 0;
Weapons[0] = 0;
Ambient[0] = 0;
AudioInstance.ApplyUniversalVolume();
}
ImGui.sameLine();
if (ImGui.button("50% Volume")) {
EngineConfig.getInstance().MusicVolume = 0.5f;
EngineConfig.getInstance().SoundVolume = 0.5f;
EngineConfig.getInstance().WeaponVolume = 0.5f;
EngineConfig.getInstance().AmbientVolume = 0.5f;
Music[0] = 50;
SFX[0] = 50;
Weapons[0] = 50;
Ambient[0] = 50;
AudioInstance.ApplyUniversalVolume();
}
ImGui.sameLine();
if (ImGui.button("Max Volume")) {
EngineConfig.getInstance().MusicVolume = 1f;
EngineConfig.getInstance().SoundVolume = 1f;
EngineConfig.getInstance().WeaponVolume = 1f;
EngineConfig.getInstance().AmbientVolume = 1f;
Music[0] = 100;
SFX[0] = 100;
Weapons[0] = 100;
Ambient[0] = 100;
AudioInstance.ApplyUniversalVolume();
}
ImGui.endTabItem();
}
if (ImGui.beginTabItem("Graphics")) {
ImGui.setWindowFontScale(4.0f);
ImGui.text("Graphics Settings");
ImGui.setWindowFontScale(3f);
ImGui.text("Presets:");
if(ImGui.button("Lowest")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (0);
ForwardSceneRender.SetDualPassRendering(false);
DeferredSceneRender.SetDualPassRendering(false);
EngineConfig.getInstance().SetAlphaToCoverage(false);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("Medium")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (1);
ForwardSceneRender.SetDualPassRendering(true);
DeferredSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetAlphaToCoverage(true);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("Highest")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (4);
ForwardSceneRender.SetDualPassRendering(true);
DeferredSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetAlphaToCoverage(false);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.text("anti aliasing:");
if(ImGui.button("No AA")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (0);
}
ImGui.sameLine();
if(ImGui.button("FXAA")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (1);
}
ImGui.sameLine();
if(ImGui.button("MSAAx2")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (2);
}
ImGui.sameLine();
if(ImGui.button("MSAAx4")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (3);
}
ImGui.sameLine();
if(ImGui.button("MSAAx8")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = 4;
}
ImGui.text("pipeline:");
if(ImGui.button("Single Pass")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 500;
ForwardSceneRender.SetDualPassRendering(false);
DeferredSceneRender.SetDualPassRendering(false);
}
ImGui.sameLine();
if(ImGui.button("dual Pass")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 500;
ForwardSceneRender.SetDualPassRendering(true);
DeferredSceneRender.SetDualPassRendering(true);
}
ImGui.text("pipeline lighting method:");
if(ImGui.button("No Lighting")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 500;
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Forward);
//PrimaryRuntime.GetRenderThread().RefreshRenderer();
}
ImGui.sameLine();
if(ImGui.button("Deferred Lighting")){
Logger.debug("Enabling Deferred Rendering");
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 500;
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred);
// PrimaryRuntime.GetRenderThread().RefreshRenderer();
}
ImGui.text("Translucency rendering method:");
if(ImGui.button("Alpha Blending (translucency)")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 500;
EngineConfig.getInstance().SetAlphaToCoverage(false);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("Alpha To Coverage (Dithering)")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 500;
EngineConfig.getInstance().SetAlphaToCoverage(true);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.endTabItem();
}
ImGui.endTabBar();
}
ImGui.end();
ImGui.popStyleVar(3);
ImGui.popStyleColor();
}
}

View file

@ -22,8 +22,8 @@ import org.joml.Vector3f;
import org.tinylog.Logger;
public class StartMenu implements GUIOverlay {
public boolean GameStarted = false;
public boolean ShowSettings = false;
public static boolean GameStarted = false;
public static boolean ShowSettings = false;
public float Volume = 1.0f;
private void ApplyVolume(EngineInstance engineInstance) {
@ -35,7 +35,7 @@ public class StartMenu implements GUIOverlay {
}
@Override
public void RenderGUI(EngineInstance engineInstance, long frameTimeNS, GameCore parent) {
if (GameStarted) return;
if (GameStarted || ShowSettings) return;
ImGuiViewport viewport = ImGui.getMainViewport();
int menuFlags = ImGuiWindowFlags.NoDecoration
| ImGuiWindowFlags.AlwaysAutoResize
@ -70,39 +70,11 @@ public class StartMenu implements GUIOverlay {
if (ImGui.button("Play", buttonWidth, buttonHeight)) {
GameStarted = true;
Scene scene = (Scene) engineInstance.scene();
parent.SwitchBGM(engineInstance, scene, "resources/EngineResources/audio/music/theshiteventhefar.ogg");
parent.SwitchBGM(engineInstance, scene, "resources/EngineResources/audio/music/CHILL_REGGAE_2_StealthGroover.ogg");
}
ImGui.setCursorPosX(buttonX);
if (ImGui.button("Settings", buttonWidth, buttonHeight)) {
ShowSettings = !ShowSettings;
}
if (ShowSettings) {
ImGui.spacing();
ImGui.setCursorPosX(buttonX);
ImGui.text("Volume: " + Math.round(Volume * 100) + "%");
ImGui.setCursorPosX(buttonX);
if (ImGui.button("-", 40f, 40f)) {
Volume = Math.max(0f, Volume - 0.1f);
ApplyVolume(engineInstance);
}
ImGui.sameLine();
if (ImGui.button("+", 40f, 40f)) {
Volume = Math.min(1f, Volume + 0.1f);
ApplyVolume(engineInstance);
}
ImGui.sameLine();
if (ImGui.button("Mute", 100f, 40f)) {
Scene scene = (Scene) engineInstance.scene();
AudioInstance bgm = scene.audioInstances.get("BGM");
bgm.Pause();
}
ImGui.sameLine();
if (ImGui.button("Unmute", 130f, 40f)) {
Scene scene = (Scene) engineInstance.scene();
AudioInstance bgm = scene.audioInstances.get("BGM");
bgm.Play();
}
ShowSettings = true;
}
ImGui.setCursorPosX(buttonX);
if (ImGui.button("Quit", buttonWidth, buttonHeight)) {

View file

@ -1,5 +1,5 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene;
public record Item(String ModelID, float FireRate, int MagazineCapacity) {
public record Item(String ModelID, float FireRate, int MagazineCapacity, float Damage) {
}

View file

@ -26,7 +26,10 @@ public class PlayerActor extends Actor{
PlayerCam = Camera.CameraRegistry.get(AttachedCameraID);
super(ID, ModelID, Position);
if(!Objects.equals(ClientConnectionThread.OwnedActorID, ID) && !RenderThread.Headless && !PrimaryRuntime.Server){
PrimaryRuntime.GetEngineInstance().scene().AddActor(new ActorElement("PlayerModel" + ID, MelonaModelID, ID,new Vector3f(0,0,0)));
ActorElement newMelona = new ActorElement("PlayerModel" + ID, MelonaModelID, ID,new Vector3f(0,0,0));
newMelona.SetScale(1.3f);
newMelona.SetPositionOffset(0,-0.85f,0);
PrimaryRuntime.GetEngineInstance().scene().AddActor(newMelona);
}
}

View file

@ -22,9 +22,11 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Item;
import org.joml.Vector2f;
import org.joml.Vector3f;
import org.tinylog.Logger;
import java.util.*;
import static net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread.UpdateEntityModelID;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_A;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_D;
@ -36,6 +38,7 @@ import static org.lwjgl.glfw.GLFW.GLFW_KEY_W;
public class Scene implements IScene {
public static long LastGunFire = 0;
private static final float MOUSE_SENSITIVITY = 0.1f;
private static final float MOVEMENT_SPEED = 0.025f;
private final Map<String, Actor> Actors;
@ -65,6 +68,8 @@ public class Scene implements IScene {
public PlayerActor Revolver;
public Item MusketItem;
public Item RevolverItem;
public Item CurrentItem;
public Item FlintLockItem;
public List<String> ActiveGUIs = new ArrayList<>();
public Map<String, GUIOverlay> GUIReg = new HashMap<>();
@ -239,7 +244,7 @@ public class Scene implements IScene {
public void SetCurrentWeapon(PlayerActor Weapon) {this.CurrentWeapon = Weapon; }
public int GUI_MODE = 0;
public int GUI_MODE = 1;
@Override
public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds,PlayerActor playerActor, float MOVEMENT_SPEED, GameCore parent) {
@ -256,42 +261,44 @@ public class Scene implements IScene {
if(input.keyPressed(GLFW_KEY_ENTER)) {
parent.SpawnNewActor(engineInstance, new Vector3f( (float)(5 * Math.random()),20 + (float)(10 * Math.random()), (float)(5 * Math.random())),new Vector3f(-1f + (float)(2 * Math.random()),-1f + (float)(2 * Math.random()),-1f + (float)(2 * Math.random())),new Vector3f((float)Math.random(),(float)Math.random(),(float)Math.random()));
}
if(!ClientConnectionThread.Connected) {
if (input.keySinglePress(GLFW_KEY_R) && CurrentWeapon != Revolver) {
scene.RemoveActor(Musket);
scene.AddActor(Revolver);
playerController.SwitchActor(Revolver);
CurrentWeapon = Revolver;
playerActor = Revolver;
parent.SetPlayerActorID(Revolver.GetID());
Musket.AttachedCameraID = "NULL";
Revolver.AttachedCameraID = "DebugCamera";
Revolver.SetModelID(MusketItem.ModelID());
if(!RenderThread.Headless && !PrimaryRuntime.Server && playerActor!= null) {
if (input.keySinglePress(GLFW_KEY_M)) {
playerActor.SetModelID(MusketItem.ModelID());
UpdateEntityModelID(playerActor.ID, MusketItem.ModelID());
CurrentItem= MusketItem;
}
if (input.keySinglePress(GLFW_KEY_M) && CurrentWeapon != Musket) {
scene.RemoveActor(Revolver);
scene.AddActor(Musket);
playerController.SwitchActor(Musket);
CurrentWeapon = Musket;
playerActor = Musket;
parent.SetPlayerActorID(Musket.GetID());
Musket.AttachedCameraID = "DebugCamera";
Revolver.AttachedCameraID = "NULL";
Musket.SetModelID(RevolverItem.ModelID());
if (input.keySinglePress(GLFW_KEY_R)) {
playerActor.SetModelID(RevolverItem.ModelID());
UpdateEntityModelID(playerActor.ID, RevolverItem.ModelID());
CurrentItem= RevolverItem;
}
if (input.keySinglePress(GLFW_KEY_F)) {
playerActor.SetModelID(FlintLockItem.ModelID());
UpdateEntityModelID(playerActor.ID, FlintLockItem.ModelID());
CurrentItem= FlintLockItem;
}
}
if (input.keySinglePress(GLFW_KEY_ESCAPE)) {
parent.StartMenuActive = true;
parent.startMenu.GameStarted = false;
parent.startMenu.GameStarted = true;
StartMenu.ShowSettings = true;
parent.SwitchBGM(engineInstance, this, "resources/EngineResources/audio/music/MENUMUSIC_RetroFutureClean.ogg");
}
MouseListener mouseListener = window.getMouseInput();
if (mouseListener.isRightButtonPressed()) {
CurrentWeapon.SetPositionOffset(new Vector3f(0f,1.0f,-1.25f));
CurrentWeapon.SetPositionOffset(new Vector3f(0f,1.15f,-1.25f));
} else {
CurrentWeapon.SetPositionOffset(new Vector3f(0.5f,1.0f,-1.25f));
CurrentWeapon.SetPositionOffset(new Vector3f(0.5f,1.15f,-1.25f));
}
if(mouseListener.isRightButtonPressed()) {
if (CurrentItem != null&& playerActor != null) {
long NewTime = System.nanoTime();
float FireRate = 1000f/CurrentItem.FireRate();
if (NewTime - LastGunFire > 1_000_000f * FireRate ){
LastGunFire = NewTime;
ClientConnectionThread.FireWeapon(playerActor.ID, CurrentItem.Damage());
}
}
}
if(input.keyPressed(GLFW_KEY_1)) {
Gimbal.universalType = Gimbal.GimbalType.Move;
@ -369,10 +376,10 @@ public class Scene implements IScene {
}
LastMousePos.x = CurrentMousePos.x;
LastMousePos.y = CurrentMousePos.y;
if(MouseInput.isRightButtonPressed()){
// if(MouseInput.isRightButtonPressed()){
camera.AddRotation((float)Math.toRadians(-deltaPos.y * Multiplier),(float)Math.toRadians(-deltaPos.x * Multiplier),0);
}
// }
engineInstance.audioManager().UpdateListenerPosition(camera);
}
}

View file

@ -28,7 +28,7 @@ public class VisualisedCollisionActor extends Actor{
if(mesh != null) {
SetScale(new Vector3f(mesh.hxhyhz).mul(2.01f));
SetPosition(new Vector3f(mesh.Position.x,mesh.Position.y,mesh.Position.z));
SetPositionOffset(new Vector3f(0,-mesh.hxhyhz.y/3f,0));
SetPositionOffset(new Vector3f(0,( mesh.GetWorldAABB().minY - mesh.GetWorldAABB().maxY)/2f,0));
SetRotation(mesh.Orientation);
}
}

View file

@ -20,6 +20,8 @@ public class Packet {
public static final byte PACKET_POSSESS_ACTOR = 8;
public static final byte PACKET_DESTROY_ACTOR = 9;
public static final byte PACKET_CLIENT_INPUT = 10;
public static final byte PACKET_UPDATE_MODEL_ID = 11;
public static final byte PACKET_FIRE_WEAPON = 12;
public byte PacketTypeByte; //0 Location 1 Rotation 2 LinearVelocity 3 AngularVelocity 4 CombinedActorDownload 5 Ping 6 PosRotVelAngularVel 7 AssignUUID
public byte TargetType; //0 Actor
public byte[] Data;

View file

@ -15,6 +15,7 @@ import org.tinylog.Logger;
import java.io.*;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
@ -232,6 +233,14 @@ public class ClientConnectionThread implements Runnable{
scene.RemoveActor(actorToDestroy);
}
break;
case 11:
Logger.debug("Rebound packet received for actor [{}]", packet.TargetID);
stringdata = Packet.DecodeAsString(packet.Data);
Actor actorToChangeModelID = Actor.Actors.get(packet.TargetID);
if(actorToChangeModelID != null) {
actorToChangeModelID.SetModelID(stringdata);
}
break;
}
}
}
@ -258,6 +267,23 @@ public class ClientConnectionThread implements Runnable{
}
}
public static void FireWeapon(String ActorID, float Damage){
Packet packet = new Packet(Packet.PACKET_FIRE_WEAPON);
packet.SetTargetType((byte) 0);
packet.SetData(ByteBuffer.allocate(4).putFloat(Damage).array());
packet.SetID(ActorID);
OutGoingPacketQueue.add(packet);
}
public static void UpdateEntityModelID(String ActorID, String ModelID){
Packet packet = new Packet(Packet.PACKET_UPDATE_MODEL_ID);
packet.SetTargetType((byte) 0);
packet.SetData(ModelID.getBytes(StandardCharsets.UTF_8));
packet.SetID(ActorID);
OutGoingPacketQueue.add(packet);
Logger.debug("Sent model ID update packet for actor [{}]", ActorID);
}
public static void SendEntityUpdatePacket(Actor actor){
Packet newOutgoingPacket = new Packet((byte)6);
newOutgoingPacket.SetTargetType((byte) 0);
@ -299,6 +325,9 @@ public class ClientConnectionThread implements Runnable{
public static void WritePacket(Packet outPacket, DataOutputStream Outgoing) throws IOException {
if(Outgoing == null ) return;
if(outPacket.PacketTypeByte == Packet.PACKET_UPDATE_MODEL_ID){
Logger.debug("Sending model ID update packet for actor [{}]", outPacket.TargetID);
}
byte[] DataToSend = Packet.GetOutgoingData(outPacket);
Outgoing.write(DataToSend);
}

View file

@ -193,6 +193,13 @@ public class ServerConnectionThread implements Runnable{
// Example future data:
// forward/back/left/right/jump/yaw/pitch/sequenceNumber
break;
case Packet.PACKET_UPDATE_MODEL_ID:
if(!packet.TargetID.equals(ConnectedClients.get(packet.ClientID).OwnedActorID)) {
return;
}
Packet ReboundPacket = CreateUpdateModelIDPacket(packet.TargetID, Packet.DecodeAsString(packet.Data));
Server.OutGoingPacketQueue.add(ReboundPacket);
break;
}
}
@ -201,134 +208,6 @@ public class ServerConnectionThread implements Runnable{
}
public static void DecodePackets(EngineInstance engineInstance, GameCore gameCore, IScene scene,List<Packet> IncomingPacketQueue){
if(!IncomingPacketQueue.isEmpty()){
ListIterator<Packet> iter = IncomingPacketQueue.listIterator();
while(iter.hasNext()){
Packet packet = iter.next();
Actor Target = Actor.Actors.get(packet.TargetID);
Vector3f vector3f = new Vector3f();
String stringdata = "";
Quaternionf quaternionfdata = new Quaternionf();
Packet.DecodedMovementPacket MovementUpdate;
if(packet.PacketTypeByte >= 0 && packet.PacketTypeByte < 4 && packet.PacketTypeByte != 1){
vector3f = Packet.DecodeAsVector3f(packet.Data);
}
if(Target == null
&& packet.PacketTypeByte != Packet.PACKET_CREATE_ACTOR
&& packet.PacketTypeByte != Packet.PACKET_PING
&& packet.PacketTypeByte != Packet.PACKET_POSSESS_ACTOR) {
iter.remove();
continue;
}
switch (packet.PacketTypeByte){
case 0:
Target.SetNewPosition(vector3f);
break;
case 1:
quaternionfdata = Packet.DecodeAsQuaternation(packet.Data);
Target.SetNewRotation(quaternionfdata);
break;
case 2:
Target.SetNewVelocity(vector3f);
break;
case 3:
Target.SetNewAngularVelocity(vector3f);
break;
case 4: //"ACtorType:ModelID:x:y:z:rx:ry:rz:sx:sy:sz:hx:hy:hz:MassKG:vx:vy:vz:avx:avy:avz:posOffx:posOffy:posOffz:camOffx:camOffy:camOffz"
stringdata = Packet.DecodeAsString(packet.Data);
String[] Split = stringdata.split(":");
Vector3f Position = new Vector3f(
Float.parseFloat(Split[2]),
Float.parseFloat(Split[3]),
Float.parseFloat(Split[4])
);
Quaternionf Rotation = new Quaternionf(
Float.parseFloat(Split[5]),
Float.parseFloat(Split[6]),
Float.parseFloat(Split[7]),
Float.parseFloat(Split[8])
);
Vector3f Scale = new Vector3f(
Float.parseFloat(Split[9]),
Float.parseFloat(Split[10]),
Float.parseFloat(Split[11])
);
Vector3f CollisionBox = new Vector3f(
Float.parseFloat(Split[12]),
Float.parseFloat(Split[13]),
Float.parseFloat(Split[14])
);
float MassKG = Float.parseFloat(Split[15]);
Vector3f Velocity = new Vector3f(
Float.parseFloat(Split[16]),
Float.parseFloat(Split[17]),
Float.parseFloat(Split[18])
);
Vector3f AngularVelocity = new Vector3f(
Float.parseFloat(Split[19]),
Float.parseFloat(Split[20]),
Float.parseFloat(Split[21])
);
Vector3f PositionOffset = new Vector3f(
Float.parseFloat(Split[22]),
Float.parseFloat(Split[23]),
Float.parseFloat(Split[24])
);
Vector3f CameraOffset = new Vector3f(
Float.parseFloat(Split[25]),
Float.parseFloat(Split[26]),
Float.parseFloat(Split[27])
);
String actorType = Split[0];
String modelID = Split[1];
if(actorType.equals("PlayerActor")) {
Target = new PlayerActor("NULL", packet.TargetID, modelID, Position).SetCameraOffset(CameraOffset);
Target.SetPositionOffset(PositionOffset);
} else {
Target = new Actor(packet.TargetID, modelID, Position);
}
Target.SetNewRotation(Rotation);
Target.SetScale(Scale);
Target.CreatePhysicsController(ConvexMesh.Box(CollisionBox.x, CollisionBox.y, CollisionBox.z), MassKG);
Target.SetServerSynced(MassKG > 0.0f || actorType.equals("PlayerActor"));
Target.SetNewRotation(Rotation);
RigidPhysicsController physicsController = (RigidPhysicsController) Target.GetPhysicsController();
RigidBody.RigidBodyRegister.get(physicsController.RigidBodyID).LinearVelocity.set(Velocity);
RigidBody.RigidBodyRegister.get(physicsController.RigidBodyID).AngularVelocity.set(AngularVelocity);
if(actorType.equals("PlayerActor")){
RigidBody.RigidBodyRegister.get(physicsController.RigidBodyID).LockRotation();
}
scene.AddActor(Target);
break;
case 6:
if(!packet.TargetID.equals(ConnectedClients.get(packet.ClientID).OwnedActorID)) {
return;
}
MovementUpdate = Packet.DecodeAsMovementUpdate(packet.Data);
Target.SetNewRotation(MovementUpdate.Rotation);
Target.SetNewPosition(MovementUpdate.Position);
Target.SetNewVelocity(MovementUpdate.LinearVelocity);
Target.SetNewAngularVelocity(MovementUpdate.AngularVelocity);
break;
}
iter.remove();
}
}
}
public static Packet CreateActorPacket(Actor actor){
Packet newOutgoingPacket = new Packet(Packet.PACKET_CREATE_ACTOR);
@ -387,6 +266,14 @@ public class ServerConnectionThread implements Runnable{
if(newOutgoingPacket != null)Server.OutGoingPacketQueue.add(newOutgoingPacket);
}
public static Packet CreateUpdateModelIDPacket(String actorID, String NewModelID){
Packet packet = new Packet(Packet.PACKET_UPDATE_MODEL_ID);
packet.SetTargetType((byte) 0);
packet.SetData(NewModelID.getBytes(StandardCharsets.UTF_8));
packet.SetID(actorID);
return packet;
}
public static Packet CreateDestroyActorPacket(String actorID){
Packet packet = new Packet(Packet.PACKET_DESTROY_ACTOR);
packet.SetTargetType((byte) 0);

View file

@ -5,8 +5,10 @@ import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.ActorElement;
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene;
import net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.DefaultPipeline;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.*;
@ -22,6 +24,7 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.SwapChain.SwapChain;
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanBuffer;
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.util.shaderc.Shaderc;
@ -33,6 +36,7 @@ import java.nio.LongBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import static org.lwjgl.vulkan.VK13.*;
@ -406,6 +410,7 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
if(i < Actors.size()) {
var Actor = Actors.get(i);
if(Actor != null) {
if(Actor instanceof ActorElement &&( !((ActorElement) Actor).RenderOnTopOfPlayer && Objects.equals(((ActorElement) Actor).GetParentID(), ClientConnectionThread.OwnedActorID) || new Vector3f().set(Actor.GetPosition()).sub(instance.scene().GetCamera().GetPosition()).absolute().lengthSquared() < 4f)) continue;
VulkanModel model = modelsCache.GetModel(Actor.GetModelID());
List<VulkanMesh> VkMeshList = model.GetVkMeshList();
int MeshCount = VkMeshList.size();