Collision & Engine refactor
This commit is contained in:
parent
f135d99d74
commit
6b51c9b680
261 changed files with 5439 additions and 185169 deletions
|
|
@ -41,9 +41,15 @@ public class AudioManager {
|
|||
}
|
||||
|
||||
public void AddSoundBuffer(String name, SoundBuffer soundBuffer){
|
||||
if(this.SoundBufferMap.containsKey(name)){
|
||||
SoundBufferMap.get(name).CleanUp();
|
||||
}
|
||||
this.SoundBufferMap.put(name,soundBuffer);
|
||||
}
|
||||
public void AddSoundSource(String name, AudioSource source){
|
||||
if(this.SoundSourceMap.containsKey(name)){
|
||||
SoundSourceMap.get(name).CleanUp();
|
||||
}
|
||||
this.SoundSourceMap.put(name,source);
|
||||
}
|
||||
public void CleanUp(){
|
||||
|
|
|
|||
|
|
@ -121,12 +121,13 @@ public class Render {
|
|||
|
||||
List<GuiTexture> guiTextures = initData.GuiTextures();
|
||||
String[] SkyBoxTextures = new String[]{
|
||||
"resources/EngineResources/SkyBoxTextures/skySide.png",
|
||||
"resources/EngineResources/SkyBoxTextures/skySide.png",
|
||||
"resources/EngineResources/SkyBoxTextures/SkyTop.png",
|
||||
"resources/EngineResources/SkyBoxTextures/SkyTop.png",
|
||||
"resources/EngineResources/SkyBoxTextures/skySide.png",
|
||||
"resources/EngineResources/SkyBoxTextures/skySide.png"
|
||||
"resources/EngineResources/SkyBoxTextures/autumn_field_pureskyRight.png",
|
||||
"resources/EngineResources/SkyBoxTextures/autumn_field_pureskyLeft.png",
|
||||
"resources/EngineResources/SkyBoxTextures/autumn_field_pureskyUp.png",
|
||||
"resources/EngineResources/SkyBoxTextures/autumn_field_pureskyDown.png",
|
||||
"resources/EngineResources/SkyBoxTextures/autumn_field_pureskyFront.png",
|
||||
"resources/EngineResources/SkyBoxTextures/autumn_field_pureskyBack.png",
|
||||
|
||||
};
|
||||
textureCache.AddCubeMapTexture(RendererContext, DeferredSceneRender.SkyBoxID,SkyBoxTextures,VK_FORMAT_R8G8B8A8_SRGB);
|
||||
if(guiTextures != null){
|
||||
|
|
@ -184,6 +185,7 @@ public class Render {
|
|||
CommandPools[i].cleanup(RendererContext);
|
||||
}
|
||||
Logger.debug("Command pools cleaned up");
|
||||
VulkanUtils.CleanUpRemaining(RendererContext.GetDevice());
|
||||
RendererContext.cleanup();
|
||||
}
|
||||
public void DeferredRender(EngineInstance engineInstance){
|
||||
|
|
@ -212,6 +214,7 @@ public class Render {
|
|||
Submit(CommandBuffer, CurrentFrame, ImageIndex);
|
||||
Resize = swapChain.PresentImage(PresentQueue, RenderCompleteSemaphores[ImageIndex],ImageIndex);
|
||||
CurrentFrame = (CurrentFrame + 1) % VulkanUtils.MAX_IN_FLIGHT;
|
||||
VulkanUtils.ProcessDeferredDeletionQueue(RendererContext.GetDevice());
|
||||
}
|
||||
|
||||
public void ForwardRender(EngineInstance engineInstance){
|
||||
|
|
@ -237,15 +240,12 @@ public class Render {
|
|||
Submit(CommandBuffer, CurrentFrame, ImageIndex);
|
||||
Resize = swapChain.PresentImage(PresentQueue, RenderCompleteSemaphores[ImageIndex],ImageIndex);
|
||||
CurrentFrame = (CurrentFrame + 1) % VulkanUtils.MAX_IN_FLIGHT;
|
||||
VulkanUtils.ProcessDeferredDeletionQueue(RendererContext.GetDevice());
|
||||
}
|
||||
|
||||
public void render(EngineInstance engineInstance){
|
||||
if(Deferred) DeferredRender(engineInstance);
|
||||
else ForwardRender(engineInstance);
|
||||
// if(LastGamma != EngineConfig.getInstance().GetGamma()){
|
||||
// vkDeviceWaitIdle(RendererContext.GetDevice().FetchVulkanDevice());
|
||||
// PrimaryRuntime.GetRenderThread().RefreshRenderer();
|
||||
// }
|
||||
}
|
||||
|
||||
private void resize(EngineInstance engineInstance){
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic.Collision;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CollisionManager {
|
||||
public static Map<String,CollisionMesh> CollisionMeshes = new HashMap<>();
|
||||
public static Map<String,List<String>> CollisionChunks = new HashMap<>();
|
||||
public static int ChunkWidth = 64;
|
||||
|
||||
public static void AddNewMesh(CollisionMesh mesh){
|
||||
CollisionMeshes.put(mesh.ID, mesh);
|
||||
Vector3f WorldPos = new Vector3f(mesh.WorldPosition).div(ChunkWidth);
|
||||
WorldPos.x = (int)Math.floor(WorldPos.x);
|
||||
WorldPos.y = (int)Math.floor(WorldPos.y);
|
||||
WorldPos.z = (int)Math.floor(WorldPos.z);
|
||||
String ChunkPosition = WorldPos.x + ":" + WorldPos.y + ":" + WorldPos.z;
|
||||
if(!CollisionChunks.containsKey(ChunkPosition)){
|
||||
List<String> newStrList = new ArrayList<>();
|
||||
CollisionChunks.put(ChunkPosition, newStrList);
|
||||
}
|
||||
CollisionChunks.get(ChunkPosition).add(mesh.ID);
|
||||
}
|
||||
|
||||
public static List<CollisionMesh> GetAllCollisionMeshes(){return CollisionMeshes.values().stream().toList();}
|
||||
|
||||
public static void UpdateCollisionChunks(){
|
||||
Map<String,List<String>> newMap = new HashMap<>();
|
||||
List<CollisionMesh> meshes = GetAllCollisionMeshes();
|
||||
for(int i = 0; i < meshes.size(); i++){
|
||||
Vector3f WorldPos = new Vector3f(meshes.get(i).WorldPosition).div(ChunkWidth);
|
||||
WorldPos.x = (int)Math.floor(WorldPos.x);
|
||||
WorldPos.y = (int)Math.floor(WorldPos.y);
|
||||
WorldPos.z = (int)Math.floor(WorldPos.z);
|
||||
String ChunkPosition = WorldPos.x + ":" + WorldPos.y + ":" + WorldPos.z;
|
||||
if(!newMap.containsKey(ChunkPosition)){
|
||||
List<String> newStrList = new ArrayList<>();
|
||||
newMap.put(ChunkPosition, newStrList);
|
||||
}
|
||||
newMap.get(ChunkPosition).add(meshes.get(i).ID);
|
||||
|
||||
}
|
||||
CollisionChunks.clear();
|
||||
CollisionChunks.putAll(newMap);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic.Collision;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Util.Maths.T4Math;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VertexBufferStructure;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.MeshData;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.VulkanMesh;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.VulkanModel;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.joml.Intersectionf;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
import java.util.*;
|
||||
|
||||
public class CollisionMesh {
|
||||
public final List<CollisionPoly> Polygons;
|
||||
public Vector3f TopLeftFront = new Vector3f(0,0,0);
|
||||
public Vector3f BottomRightBack = new Vector3f(0,0,0);
|
||||
public Vector3f WorldPosition = new Vector3f(0,0,0);
|
||||
public Quaternionf Rotation;
|
||||
public Vector3f Scale;
|
||||
public final String ID;
|
||||
public CollisionMesh(String ID){
|
||||
this.ID = ID;
|
||||
Polygons = new ArrayList<>();
|
||||
CollisionManager.AddNewMesh(this);
|
||||
}
|
||||
|
||||
public CollisionMesh SetWorldPosition(Vector3f newPos){
|
||||
this.WorldPosition = new Vector3f(newPos);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void SetScaleTransform(Vector3f Scale){
|
||||
this.Scale = new Vector3f(Scale);
|
||||
}
|
||||
|
||||
public void SetRotationTransform(Quaternionf quaternionf){
|
||||
this.Rotation = new Quaternionf(quaternionf);
|
||||
}
|
||||
|
||||
public void GenerateCollisionMeshFromVulkanModel(ModelData vkModel) throws IOException {
|
||||
Polygons.clear();
|
||||
DataInputStream VertexInput = new DataInputStream(new BufferedInputStream(
|
||||
new FileInputStream(vkModel.VertexPath())));
|
||||
DataInputStream IndexInput = new DataInputStream(new BufferedInputStream(
|
||||
new FileInputStream(vkModel.IndexPath())));
|
||||
List<float[]> Vertices = new ArrayList<>();
|
||||
int totalFloatCount = 0;
|
||||
|
||||
for (MeshData meshData : vkModel.Meshes()) {
|
||||
int floatsToRead = meshData.VertexSize() / VulkanUtils.FLOAT_SIZE;
|
||||
float[] meshFloats = new float[floatsToRead];
|
||||
for (int i = 0; i < floatsToRead; i++) {
|
||||
meshFloats[i] = VertexInput.readFloat();
|
||||
}
|
||||
Vertices.add(meshFloats);
|
||||
totalFloatCount += floatsToRead;
|
||||
}
|
||||
|
||||
float[] FullMeshFloatArr = new float[totalFloatCount];
|
||||
int iterator = 0;
|
||||
for (float[] meshFloats : Vertices) {
|
||||
System.arraycopy(meshFloats, 0, FullMeshFloatArr, iterator, meshFloats.length);
|
||||
iterator += meshFloats.length;
|
||||
}
|
||||
List<int[]> Indices = new ArrayList<>();
|
||||
int IndexCount = 0;
|
||||
int vertexOffset = 0;
|
||||
int vertexStride = 14; // Your stride configuration
|
||||
for (MeshData meshData : vkModel.Meshes()) {
|
||||
int intsToRead = meshData.IndexSize() / VulkanUtils.INT_SIZE;
|
||||
int[] meshIndices = new int[intsToRead];
|
||||
for (int i = 0; i < intsToRead; i++) {
|
||||
meshIndices[i] = IndexInput.readInt() + vertexOffset;
|
||||
}
|
||||
Indices.add(meshIndices);
|
||||
IndexCount += intsToRead;
|
||||
int meshVertexCount = (meshData.VertexSize() / VulkanUtils.FLOAT_SIZE) / vertexStride;
|
||||
vertexOffset += meshVertexCount;
|
||||
}
|
||||
int[] FullMeshIndexArr = new int[IndexCount];
|
||||
iterator = 0;
|
||||
for (int[] meshIndices : Indices) {
|
||||
System.arraycopy(meshIndices, 0, FullMeshIndexArr, iterator, meshIndices.length);
|
||||
iterator += meshIndices.length;
|
||||
}
|
||||
for(int i = 0; i < IndexCount/(3); i++){
|
||||
Vector3f[] points = new Vector3f[3];
|
||||
for(int j = 0; j < 3; j++){
|
||||
int Start = (i * 3) + j;
|
||||
int elementOffset = FullMeshIndexArr[Start] * vertexStride;
|
||||
points[j] = new Vector3f(
|
||||
(FullMeshFloatArr[elementOffset]),
|
||||
(FullMeshFloatArr[elementOffset + 1]),
|
||||
(FullMeshFloatArr[elementOffset + 2])
|
||||
);
|
||||
}
|
||||
AddNewCollisionPoly(points[0],points[1],points[2]);
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckAABbounds(Vector3f v1, Vector3f v2, Vector3f v3){
|
||||
float Bottom = Math.min(Math.min(v3.y, v1.y), Math.min(v3.y, v2.y));
|
||||
float Left = Math.min(Math.min(v3.x, v1.x), Math.min(v3.x, v2.x));
|
||||
float back = Math.min(Math.min(v3.z, v1.z), Math.min(v3.z, v2.z));
|
||||
float Top = Math.max(Math.max(v3.y, v1.y), Math.max(v3.y, v2.y));
|
||||
float Right = Math.max(Math.max(v3.x, v1.x), Math.max(v3.x, v2.x));
|
||||
float Front = Math.max(Math.max(v3.z, v1.z), Math.max(v3.z, v2.z));
|
||||
TopLeftFront.x = Math.min(TopLeftFront.x, Left);
|
||||
TopLeftFront.y = Math.max(TopLeftFront.y, Top);
|
||||
TopLeftFront.z = Math.max(TopLeftFront.z, Front);
|
||||
BottomRightBack.x = Math.max(BottomRightBack.x, Right);
|
||||
BottomRightBack.y = Math.min(BottomRightBack.y, Bottom);
|
||||
BottomRightBack.z = Math.min(BottomRightBack.z, back);
|
||||
}
|
||||
|
||||
public void AddNewCollisionPoly(Vector3f v1, Vector3f v2, Vector3f v3){
|
||||
CollisionPoly newPoly = new CollisionPoly(v1,v2,v3,new Vector3f(0,0,0));
|
||||
newPoly.CalculateCentre();
|
||||
Polygons.add(newPoly);
|
||||
CheckAABbounds(v1,v2,v3);
|
||||
}
|
||||
|
||||
public boolean CheckAABCollision(Vector3f Origin, Vector3f Sensor){
|
||||
Vector3f LineDirection = new Vector3f(Sensor).sub(Origin);
|
||||
Vector2f Result = new Vector2f();
|
||||
return Intersectionf.intersectRayAab(Origin, LineDirection,BottomRightBack,TopLeftFront,Result) && Result.x <= 1.0f && Result.y >= 0.0f;
|
||||
}
|
||||
|
||||
public boolean SimpleCheckCollision(Vector3f Origin, Vector3f Sensor){
|
||||
Vector3f LineDirection = new Vector3f(Sensor).sub(Origin);
|
||||
Vector2f Result = new Vector2f(0,0);
|
||||
if(Intersectionf.intersectRayAab(Origin, LineDirection,BottomRightBack,TopLeftFront,Result) && Result.x <= 1.0f && Result.y >= 0.0f){
|
||||
for(int i = 0; i < Polygons.size(); i++){
|
||||
CollisionPoly polygon = Polygons.get(i);
|
||||
if(T4Math.Math3D.DoesLineCollideWithPoly(Origin,Sensor,new Vector3f[]{polygon.v1(),polygon.v2(),polygon.v3()})){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public CollisionPoly[] GetAllPolygons(){
|
||||
int Rows = Polygons.size();
|
||||
CollisionPoly[] PolygonArr = new CollisionPoly[Rows * 3];
|
||||
for(int row = 0; row < Rows; row++){
|
||||
PolygonArr[row] = Polygons.get(row).TransformScale(Scale).TransformRotation(Rotation).TransformPosition(WorldPosition);
|
||||
}
|
||||
return PolygonArr;
|
||||
}
|
||||
|
||||
public Vector3f[] GetAllVertices(){
|
||||
int Rows = Polygons.size();
|
||||
Vector3f[] Vertices = new Vector3f[Rows * 3];
|
||||
for(int row = 0; row < Rows; row++){
|
||||
int StartPos = row * 3;
|
||||
CollisionPoly poly = Polygons.get(row).TransformScale(Scale).TransformRotation(Rotation).TransformPosition(WorldPosition);
|
||||
Vertices[StartPos] = new Vector3f(poly.v1().x,poly.v1().y,poly.v1().z);
|
||||
Vertices[StartPos + 1] = new Vector3f(poly.v2().x,poly.v2().y,poly.v2().z);
|
||||
Vertices[StartPos + 2] = new Vector3f(poly.v3().x,poly.v3().y,poly.v3().z);
|
||||
}
|
||||
return Vertices;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic.Collision;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Util.Maths.T4Math;
|
||||
import org.joml.Math;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public record CollisionPoly(Vector3f v1, Vector3f v2, Vector3f v3, Vector3f Centre) {
|
||||
public Vector3f CalculateCentre(){
|
||||
float x = v1.x + v2.x + v3.x;
|
||||
float y = v1.y + v2.y + v3.y;
|
||||
float z = v1.z + v2.z + v3.z;
|
||||
x/=3f;
|
||||
y/=3f;
|
||||
z/=3f;
|
||||
Centre.set(new Vector3f(x,y,z));
|
||||
return Centre;
|
||||
}
|
||||
public CollisionPoly TransformRotation(Quaternionf quaternionf){
|
||||
if(quaternionf == null ) return this;
|
||||
Vector3f newV1 = new Vector3f(v1);
|
||||
newV1.rotate(quaternionf);
|
||||
Vector3f newV2 = new Vector3f(v2);
|
||||
newV2.rotate(quaternionf);
|
||||
Vector3f newV3 = new Vector3f(v3);
|
||||
newV3.rotate(quaternionf);
|
||||
CollisionPoly newPoly = new CollisionPoly(newV1,newV2,newV3,new Vector3f());
|
||||
newPoly.CalculateCentre();
|
||||
return newPoly;
|
||||
}
|
||||
public CollisionPoly TransformScale(Vector3f Scale){
|
||||
if(Scale == null ) return this;
|
||||
Vector3f newV1 = new Vector3f(v1);
|
||||
newV1.mul(Scale);
|
||||
Vector3f newV2 = new Vector3f(v2);
|
||||
newV2.mul(Scale);
|
||||
Vector3f newV3 = new Vector3f(v3);
|
||||
newV3.mul(Scale);
|
||||
CollisionPoly newPoly = new CollisionPoly(newV1,newV2,newV3,new Vector3f());
|
||||
newPoly.CalculateCentre();
|
||||
return newPoly;
|
||||
}
|
||||
public CollisionPoly TransformPosition(Vector3f Position){
|
||||
if(Position == null ) return this;
|
||||
Vector3f newV1 = new Vector3f(v1);
|
||||
newV1.add(Position);
|
||||
Vector3f newV2 = new Vector3f(v2);
|
||||
newV2.add(Position);
|
||||
Vector3f newV3 = new Vector3f(v3);
|
||||
newV3.add(Position);
|
||||
CollisionPoly newPoly = new CollisionPoly(newV1,newV2,newV3,new Vector3f());
|
||||
newPoly.CalculateCentre();
|
||||
return newPoly;
|
||||
}
|
||||
public static CollisionPoly TransformPosition(Vector3f Position, CollisionPoly OriginalPoly){
|
||||
Vector3f newV1 = new Vector3f(OriginalPoly.v1).add(Position);
|
||||
Vector3f newV2 = new Vector3f(OriginalPoly.v2).add(Position);
|
||||
Vector3f newV3 = new Vector3f(OriginalPoly.v3).add(Position);
|
||||
CollisionPoly newPoly = new CollisionPoly(newV1,newV2,newV3,new Vector3f());
|
||||
newPoly.CalculateCentre();
|
||||
return newPoly;
|
||||
}
|
||||
public Vector3f CalculateNormal(){
|
||||
Vector3f U = new Vector3f(v2.sub(v1));
|
||||
Vector3f V = new Vector3f(v3.sub(v1));
|
||||
|
||||
Vector3f N = new Vector3f(U.mul(V));
|
||||
float Nx = (U.x * V.z) - (U.z * V.y);
|
||||
float Ny = (U.z * V.x) - (U.x * V.z);
|
||||
float Nz = (U.x * V.y) - (U.y * V.x);
|
||||
|
||||
float Length = (float) Math.sqrt(T4Math.Square(Nx)+T4Math.Square(Ny)+T4Math.Square(Nz));
|
||||
return new Vector3f(Nx/Length, Ny/Length, Nz/Length);
|
||||
}
|
||||
}
|
||||
|
|
@ -57,6 +57,7 @@ public class EngineConfig {
|
|||
private String IconPath = "/WindowResources/Icon/";
|
||||
private String DefaultTexturePath = "resources/EngineResources/Texture/NoTexture.png";
|
||||
private String IconName = "ProgramIcon.png";
|
||||
private String LoadingScreenLocation = "resources/EngineResources/Texture/Terrain4JTitleImage.png";
|
||||
private float FOV = 60f;
|
||||
private float zFarPlane;
|
||||
private float zNearPlane;
|
||||
|
|
@ -76,7 +77,17 @@ public class EngineConfig {
|
|||
public int ShadowMapSize = 16;
|
||||
public float Gamma = 0.8545f;
|
||||
public int MaxVulkanCrashesAllowed = 10;
|
||||
public boolean RenderCollisionMesh = true;
|
||||
|
||||
public boolean RenderCollisionMeshes(){
|
||||
return RenderCollisionMesh;
|
||||
}
|
||||
public void SetRenderCollisionMesh(boolean RenderCollisionMesh){
|
||||
this.RenderCollisionMesh = RenderCollisionMesh;
|
||||
}
|
||||
|
||||
public String GetLoadingScreenImageLocation(){return LoadingScreenLocation;}
|
||||
public void SetLoadingScreenImageLocation(String location){this.LoadingScreenLocation = location;}
|
||||
public int GetMaxVulkanCrashes(){return MaxVulkanCrashesAllowed;}
|
||||
public void SetShadowMapSize(int ShadowSize){this.ShadowMapSize = ShadowSize;}
|
||||
public int GetShadowMapSize(){return ShadowMapSize;}
|
||||
|
|
@ -199,6 +210,7 @@ public class EngineConfig {
|
|||
}
|
||||
if(SuccessfulLoad) {
|
||||
IconName = (EngineConfigVar.getOrDefault("Software_Icon", "ProgramIcon.png").toString());
|
||||
LoadingScreenLocation = (EngineConfigVar.getOrDefault("LoadingScreenLocation", LoadingScreenLocation).toString());
|
||||
IconPath = (EngineConfigVar.getOrDefault("Software_Icon_Path", "/WindowResources/Icon/").toString());
|
||||
CapMainToTickRate = Boolean.parseBoolean(EngineConfigVar.getOrDefault("cap_main_to_tickrate", true).toString());
|
||||
CapFastToTickRate = Boolean.parseBoolean(EngineConfigVar.getOrDefault("cap_fast_to_tickrate", true).toString());
|
||||
|
|
@ -278,6 +290,7 @@ public class EngineConfig {
|
|||
EngineConfigVar.setProperty("DefaultTexturePath",DefaultTexturePath);
|
||||
EngineConfigVar.setProperty("MaxDescriptors","1000");
|
||||
EngineConfigVar.setProperty("anti_alias_mode","1");
|
||||
EngineConfigVar.setProperty("LoadingScreenLocation",LoadingScreenLocation);
|
||||
EngineConfigVar.store(new FileWriter(path.toAbsolutePath().toString() + "/" + FILENAME), "created new properties file");
|
||||
Logger.debug("Wrote New Config File [{}]", ConfigFile.getAbsolutePath());
|
||||
} catch (IOException excp2) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
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 org.joml.Vector3f;
|
||||
|
||||
public class AudioInstance {
|
||||
private String SourcePath;
|
||||
private String BUFFER_ID = "AUDIO_INSTANCE_BUFFER";
|
||||
private String SOURCE_ID = "AUDIO_INSTANCE_SOURCE";
|
||||
private String InstanceName = "";
|
||||
private AudioSource audioSource;
|
||||
|
||||
public AudioInstance(String AudioSourcePath, String InstanceName, AudioManager manager, boolean loop){
|
||||
SourcePath = AudioSourcePath;
|
||||
BUFFER_ID = "AUDIO_INSTANCE_" + InstanceName + "_BUFFER";
|
||||
SOURCE_ID = "AUDIO_INSTANCE_" + InstanceName + "_SOURCE";
|
||||
this.InstanceName = InstanceName;
|
||||
SoundBuffer buffer = new SoundBuffer(AudioSourcePath);
|
||||
manager.AddSoundBuffer(BUFFER_ID, buffer);
|
||||
AudioSource audioSource = new AudioSource(loop,true);
|
||||
audioSource.SetBuffer(buffer.GetBufferID());
|
||||
manager.AddSoundSource(SOURCE_ID,audioSource);
|
||||
}
|
||||
public AudioInstance(String AudioSourcePath,String InstanceName, AudioManager manager, float X, float Y, float Z, boolean loop){
|
||||
SourcePath = AudioSourcePath;
|
||||
BUFFER_ID = "AUDIO_INSTANCE_" + InstanceName + "_BUFFER";
|
||||
SOURCE_ID = "AUDIO_INSTANCE_" + InstanceName + "_SOURCE";
|
||||
this.InstanceName = InstanceName;
|
||||
SoundBuffer buffer = new SoundBuffer(AudioSourcePath);
|
||||
manager.AddSoundBuffer(BUFFER_ID, buffer);
|
||||
AudioSource audioSource = new AudioSource(loop,false);
|
||||
audioSource.SetPosition(new Vector3f(X,Y,Z));
|
||||
audioSource.SetBuffer(buffer.GetBufferID());
|
||||
manager.AddSoundSource(SOURCE_ID,audioSource);
|
||||
}
|
||||
public void ChangePath(String AudioSourcePath, AudioManager manager){
|
||||
SourcePath = AudioSourcePath;
|
||||
SoundBuffer buffer = new SoundBuffer(AudioSourcePath);
|
||||
manager.AddSoundBuffer(BUFFER_ID, buffer);
|
||||
audioSource.SetBuffer(buffer.GetBufferID());
|
||||
}
|
||||
public AudioInstance Play(){
|
||||
audioSource.Play();
|
||||
return this;
|
||||
}
|
||||
public String GetBufferID(){return BUFFER_ID;}
|
||||
public String GetSourceID(){return SOURCE_ID;}
|
||||
public String GetInstanceName(){return InstanceName;}
|
||||
public String GetSourcePath(){return SourcePath;}
|
||||
public AudioSource GetAudioSource(){return audioSource;}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -12,12 +12,15 @@ import net.halbear.Terrain4J.EngineCore.Audio.SoundListener;
|
|||
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
||||
import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput;
|
||||
import net.halbear.Terrain4J.EngineCore.Input.MouseListener;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Collision.CollisionMesh;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.GameLogic;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.InitData;
|
||||
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.PerformanceOverlay;
|
||||
import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor;
|
||||
import net.halbear.Terrain4J.EngineCore.Profiling.GPUProfiler;
|
||||
|
|
@ -30,6 +33,7 @@ import org.joml.Vector3f;
|
|||
import org.lwjgl.openal.AL11;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -39,23 +43,10 @@ public class GameCore implements GameLogic {
|
|||
|
||||
private static final float MOUSE_SENSITIVITY = 0.1f;
|
||||
private static final float MOVEMENT_SPEED = 0.025f;
|
||||
public static boolean LoadingLevel = false;
|
||||
|
||||
private static final String SOUND_BUFFER_MUSIC = "music-sound-buffer";
|
||||
private static final String SOUND_BUFFER_PLAYER = "player-sound-buffer";
|
||||
private static final String SOUND_SOURCE_MUSIC = "music-sound-source";
|
||||
private static final String SOUND_SOURCE_PLAYER = "player-sound-source";
|
||||
|
||||
private final Vector3f rotatingAngle = new Vector3f(0, 1, 0);
|
||||
private float angle = 180;
|
||||
private List<Float> angles = new ArrayList<>();
|
||||
private List<Vector3f> rotatingAngles = new ArrayList<>();
|
||||
private List<Vector3f> Velocities = new ArrayList<>();
|
||||
private Actor CubeActor;
|
||||
public List<Actor> CubeActors = new ArrayList<>();
|
||||
public List<JackOfAllTradesActor> entities = new ArrayList<>();
|
||||
public List<ParticleActor> particleActors = new ArrayList<>();
|
||||
private Vector2f LastMousePos = new Vector2f(0,0);
|
||||
private int Ticks = 0;
|
||||
private int GUI_MODE = 0;
|
||||
private GuiTexture guiTexture;
|
||||
public List<String[]> PerformanceMetrics = new ArrayList<>();
|
||||
|
|
@ -67,8 +58,14 @@ public class GameCore implements GameLogic {
|
|||
public long CoolDown = 1000;
|
||||
public ModelData MusicParticle;
|
||||
public ModelData radio;
|
||||
public ModelData MelonaData;
|
||||
public ILight SkyLight;
|
||||
private LoadingScreen loadingScreen;
|
||||
public List<IMoveableActorComponent> ActorEditorComponents = new ArrayList<>();
|
||||
private Gimbal gimbal;
|
||||
private Vector2f DeltaPos = new Vector2f(0,0);
|
||||
|
||||
public Vector2f GetDeltaPos(){return DeltaPos;}
|
||||
@Override
|
||||
public void cleanup() {
|
||||
|
||||
|
|
@ -78,92 +75,43 @@ public class GameCore implements GameLogic {
|
|||
public InitData Initialise(EngineInstance engineInstance) {
|
||||
IScene scene = engineInstance.scene();
|
||||
List<ModelData> models = new ArrayList<>();
|
||||
MusicParticle = ModelLoader.LoadModel("resources/models/MusicParticle/MusicParticle.json");
|
||||
List<MaterialData> MusicParticleMat = ModelLoader.LoadMaterials("resources/models/MusicParticle/MusicParticle_mat.json");
|
||||
ModelData SponzaData = ModelLoader.LoadModel("resources/models/Forest/forest.json");
|
||||
List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Forest/forest_mat.json");
|
||||
radio = ModelLoader.LoadModel("resources/models/radio/radio.json");
|
||||
List<MaterialData> SponzaMaterial2 = ModelLoader.LoadMaterials("resources/models/radio/radio_mat.json");
|
||||
// ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
|
||||
// List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
|
||||
// ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
|
||||
// List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json");
|
||||
scene.AddActor(new Actor("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)));
|
||||
// scene.AddActor(new Actor("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)));
|
||||
|
||||
MelonaData = ModelLoader.LoadModel("resources/models/melona/melona.json");
|
||||
List<MaterialData> MelonaDataMat = ModelLoader.LoadMaterials("resources/models/melona/melona_mat.json");
|
||||
var Melona = new Actor("Melona", MelonaData.ID(), new Vector3f(0,0f,-5f)).SetRotation(0,(float)Math.toRadians(180),0);
|
||||
CollisionMesh mesh = new CollisionMesh("Super Collision Mesh");
|
||||
mesh.AddNewCollisionPoly(new Vector3f(-100,-5,0),new Vector3f(-100,-5,-100),new Vector3f(0,-5,-100));
|
||||
mesh.AddNewCollisionPoly(new Vector3f(0,-5,0),new Vector3f(0,-5,-100),new Vector3f(-100,-5,0));
|
||||
try {
|
||||
Melona.GenerateCollisionMesh(MelonaData);
|
||||
} catch(IOException e){
|
||||
Logger.error("Could Not Generate Collison Mesh [{}]",e);
|
||||
}
|
||||
scene.AddActor(Melona);
|
||||
ActorEditorComponents.add(new EditorActorComponent(Melona,new Vector3f(0,0f,-5f),new Vector3f(1.0f,1.8f,1.0f)));
|
||||
CubeActors.forEach(scene::AddActor);
|
||||
|
||||
List<MaterialData> materials = new ArrayList<>();
|
||||
materials.addAll(SponzaMaterial);
|
||||
materials.addAll(MusicParticleMat);
|
||||
// materials.addAll(SponzaMaterial1);
|
||||
materials.addAll(SponzaMaterial2);
|
||||
// models.add(SponzaData1);
|
||||
models.add(SponzaData);
|
||||
models.add(MusicParticle);
|
||||
models.add(radio);
|
||||
materials.addAll(MelonaDataMat);
|
||||
models.add(MelonaData);
|
||||
Camera camera = scene.GetCamera();
|
||||
scene.AddCameraFrame("Default", new CameraFrame(new Vector3f(-120.10f,136.83f,-62.63f),new Vector3f(-1.90f,78.09f,0),scene.GetCamera().GetFOV(),"Second"));
|
||||
scene.AddCameraFrame("Second", new CameraFrame(new Vector3f(-40.26f,141.08f,-72.12f),new Vector3f(-2.40f,143,0.0f),scene.GetCamera().GetFOV(),"Third"));
|
||||
scene.AddCameraFrame("Third", new CameraFrame(new Vector3f(10.85f,149.56f,-14.10f),new Vector3f(2.5f,36.37f,0.00f),scene.GetCamera().GetFOV(),"Fourth"));
|
||||
scene.AddCameraFrame("Fourth", new CameraFrame(new Vector3f(40.0f, 155.0f, -42.0f),new Vector3f(10,90,0),scene.GetCamera().GetFOV(),"Fifth"));
|
||||
scene.AddCameraFrame("Fifth", new CameraFrame(new Vector3f(64.92f,158.06f,-35.25f),new Vector3f(-11.20f,156.5f,0.0f),scene.GetCamera().GetFOV(),"Sixth"));
|
||||
scene.AddCameraFrame("Sixth", new CameraFrame(new Vector3f(94.52f,172.54f,47.57f),new Vector3f(4.3f,329.27f,0.0f),scene.GetCamera().GetFOV(),"NO_FRAME"));
|
||||
camera.SetPosition(40.0f, 155.0f, -42.0f);
|
||||
//camera.SetPosition(0,0,0);
|
||||
camera.SetRotation((float) Math.toRadians(10.0f), (float) Math.toRadians(-90.0f),0);
|
||||
//camera.SetRotation(0,0,0);
|
||||
camera.SetPosition(0,0,0);
|
||||
camera.SetRotation(0,0,0);
|
||||
|
||||
var LoadingScreenTexture = new GuiTexture(EngineConfig.getInstance().GetLoadingScreenImageLocation());
|
||||
loadingScreen = new LoadingScreen(LoadingScreenTexture);
|
||||
|
||||
guiTexture = new GuiTexture("resources/EngineResources/Texture/Billy.png");
|
||||
Logger.debug("GUI TEXTURE CREATED, ID->[{}], PATH->[{}]",guiTexture.ID(),guiTexture.TexturePath());
|
||||
|
||||
List<GuiTexture> guiTextures = new ArrayList<>();
|
||||
guiTextures.add(LoadingScreenTexture);
|
||||
guiTextures.add(guiTexture);
|
||||
|
||||
scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f);
|
||||
scene.GetLightingManager().SetAmbientLightIntensity(1.5f);
|
||||
scene.GetLightingManager().SetAmbientLightIntensity(0.4f);
|
||||
|
||||
SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.0f), true, 10.00f);
|
||||
SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 10.00f);
|
||||
|
||||
|
||||
List<ILight> lights = new ArrayList<>();
|
||||
//lights.add(new Light(new Vector3f(2.9f,2.75f,1.5f),new Vector3f(0.35f,2.69f,-2.11f),false,3.0f));
|
||||
//lights.add(new Light(new Vector3f(3.0f,2.5f,0.75f),new Vector3f(2.65f,1.57f,-3.31f),false,0.5f));
|
||||
|
||||
/*lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f),false,300000.0f+ (float)(Math.random() * 10000.0)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f),false,70000.0f + (float)(Math.random() * 15000.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f),false,70000.0f + (float)(Math.random() * 15000.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f),false,70000.0f + (float)(Math.random() * 15000.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858),false,70000.0f + (float)(Math.random() * 15000.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136),false,70000.0f + (float)(Math.random() * 15000.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880),false,70000.0f + (float)(Math.random() * 15000.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405),false,70000.0f + (float)(Math.random() * 15000.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825),false,70000.0f + (float)(Math.random() * 15000.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378),false,70000.0f + (float)(Math.random() * 15000.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430),false,70000.0f + (float)(Math.random() * 15000.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826),false,70000.0f + (float)(Math.random() * 15000.0f)));
|
||||
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2076, 410, 1272),false,10000.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2446, 465, 2303),false,10000.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-842, 410, -1141),false,10000.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-207, 410, -1830),false,10000.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(899, 460, -2015),false,10000.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1775, 460, -3448),false,10000.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1800, 460, -4154),false,10000.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -387),false,10000.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1198, 410, -964),false,10000.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1778, 410, -1502),false,10000.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2692, 333, -2109),false,10000.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2849, 333, -1724),false,10000.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2019, 410, -729),false,10000.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -389),false,10000.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1337, 410, 122),false,10000.0f));
|
||||
|
||||
|
||||
lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375),false,50000.0f));
|
||||
*/
|
||||
|
||||
lights.add(new Light(new Vector3f(3.0f,2.75f,0.0f),new Vector3f(35.0f, 150.0f, -42.0f),false,100.0f));
|
||||
lights.add(new Light(new Vector3f(0.0f,3.0f,0.0f),new Vector3f(40.0f, 155.0f, -35.0f),false,20.0f));
|
||||
lights.add(SkyLight);
|
||||
|
||||
ILight[] lightArr = new ILight[lights.size()];
|
||||
|
|
@ -171,29 +119,29 @@ public class GameCore implements GameLogic {
|
|||
scene.GetLightingManager().AddLights(lightArr);
|
||||
|
||||
InitiateAudio(engineInstance);
|
||||
|
||||
for(int i = 0; i < ActorEditorComponents.size(); i++){
|
||||
ActorEditorComponents.get(i).UpdateAll();
|
||||
}
|
||||
return new InitData(models,materials,guiTextures);
|
||||
}
|
||||
|
||||
public void SpawnNewActorEditorComponent(EngineInstance engineInstance){
|
||||
var scene = engineInstance.scene();
|
||||
var Melona = new Actor("Melona" + scene.GetActors().size(), MelonaData.ID(), new Vector3f(scene.GetCamera().GetPosition())).SetRotation(new Vector3f(scene.GetCamera().GetRotation()));
|
||||
try {
|
||||
Melona.GenerateCollisionMesh(MelonaData);
|
||||
} catch(IOException e){
|
||||
Logger.error("Could Not Generate Collison Mesh [{}]",e);
|
||||
}
|
||||
scene.AddActor(Melona);
|
||||
ActorEditorComponents.add(new EditorActorComponent(Melona,new Vector3f(scene.GetCamera().GetPosition()),new Vector3f(1.0f,1.8f,1.0f)));
|
||||
}
|
||||
|
||||
private void InitiateAudio(EngineInstance engineInstance){
|
||||
AudioManager audioManager = engineInstance.audioManager();
|
||||
Camera camera = engineInstance.scene().GetCamera();
|
||||
audioManager.SetAttenuationModel(AL11.AL_EXPONENT_DISTANCE);
|
||||
audioManager.SetListener(new SoundListener(camera.GetPosition()));
|
||||
|
||||
SoundBuffer buffer = new SoundBuffer("resources/EngineResources/audio/sounds/youusedtocallmeonyourcellphone.ogg");
|
||||
audioManager.AddSoundBuffer(SOUND_BUFFER_PLAYER, buffer);
|
||||
AudioSource playerAudioSource = new AudioSource(true,false);
|
||||
playerAudioSource.SetPosition(new Vector3f(40.0f, 155.0f, -42.0f));
|
||||
playerAudioSource.SetBuffer(buffer.GetBufferID());
|
||||
audioManager.AddSoundSource(SOUND_SOURCE_PLAYER,playerAudioSource);
|
||||
//playerAudioSource.Play();
|
||||
buffer = new SoundBuffer("resources/EngineResources/audio/music/chimken_wing.ogg");
|
||||
audioManager.AddSoundBuffer(SOUND_BUFFER_MUSIC,buffer);
|
||||
AudioSource source = new AudioSource(true, true);
|
||||
source.SetBuffer(buffer.GetBufferID());
|
||||
audioManager.AddSoundSource(SOUND_SOURCE_MUSIC,source);
|
||||
//source.Play();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -218,6 +166,7 @@ public class GameCore implements GameLogic {
|
|||
|
||||
camera.AddRotation((float)Math.toRadians(-deltaPos.y * Multiplier),(float)Math.toRadians(-deltaPos.x * Multiplier),0);
|
||||
}
|
||||
DeltaPos = new Vector2f(deltaPos);
|
||||
engineInstance.audioManager().UpdateListenerPosition(camera);
|
||||
}
|
||||
|
||||
|
|
@ -247,14 +196,17 @@ public class GameCore implements GameLogic {
|
|||
KeyboardInput input = window.getKeyboardInput();
|
||||
float MovementDist = (float)(FrameDiffNanoSeconds / 1000000L) * MOVEMENT_SPEED;
|
||||
Camera camera = scene.GetCamera();
|
||||
if(input.keyPressed(GLFW_KEY_1)){
|
||||
GUI_MODE = 0;
|
||||
if(input.keyPressed(GLFW_KEY_F3)){
|
||||
GUI_MODE = (GUI_MODE + 1) % 2;
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_2)){
|
||||
GUI_MODE = 1;
|
||||
if(input.keyPressed(GLFW_KEY_1)) {
|
||||
Gimbal.universalType = Gimbal.GimbalType.Move;
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_3)){
|
||||
GUI_MODE = 2;
|
||||
if(input.keyPressed(GLFW_KEY_2)) {
|
||||
Gimbal.universalType = Gimbal.GimbalType.Resize;
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_3)) {
|
||||
Gimbal.universalType = Gimbal.GimbalType.Rotate;
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_W)){
|
||||
camera.MoveForward(MovementDist);
|
||||
|
|
@ -294,28 +246,20 @@ public class GameCore implements GameLogic {
|
|||
| ImGuiWindowFlags.NoNav
|
||||
| ImGuiWindowFlags.NoMove;
|
||||
ImGui.newFrame();
|
||||
if(GUI_MODE == 0){
|
||||
PerformanceOverlay overlay = new PerformanceOverlay();
|
||||
overlay.RenderGUI(engineInstance,frameTimeNS,this);
|
||||
} else if (GUI_MODE == 1){
|
||||
|
||||
ImGui.setNextWindowPos(0,0, ImGuiCond.Always);
|
||||
ImGui.setNextWindowSize(500,500);
|
||||
ImGui.begin("Test Window");
|
||||
ImGui.image(PrimaryRuntime.GetRenderThread().GetRenderer().GetGuiTexture(guiTexture.ID()),300,300);
|
||||
Logger.debug(PrimaryRuntime.GetRenderThread().GetRenderer().GetGuiTexture(guiTexture.ID()));
|
||||
ImGui.end();
|
||||
} else if (GUI_MODE == 2){
|
||||
}
|
||||
if (ChangeGraphicsSettings){
|
||||
ImGuiViewport viewport = ImGui.getMainViewport();
|
||||
float CenterX = viewport.getWorkPosX() + viewport.getWorkSizeX() / 2.0f;
|
||||
float CenterY = viewport.getWorkPosY() + viewport.getWorkSizeY() / 2.0f;
|
||||
ImGui.setNextWindowPos(CenterX,CenterY, ImGuiCond.Always,0.5f,0.5f);
|
||||
ImGui.begin("change notification",windowFlags);
|
||||
ImGui.setWindowFontScale(4.0f);
|
||||
ImGui.text("APPLYING GRAPHICS SETTINGS...");
|
||||
ImGui.end();
|
||||
if(LoadingLevel){
|
||||
loadingScreen.RenderGUI(engineInstance,frameTimeNS,this);
|
||||
} else {
|
||||
engineInstance.scene().RenderGUIs(engineInstance, frameTimeNS, this);
|
||||
if (ChangeGraphicsSettings) {
|
||||
ImGuiViewport viewport = ImGui.getMainViewport();
|
||||
float CenterX = viewport.getWorkPosX() + viewport.getWorkSizeX() / 2.0f;
|
||||
float CenterY = viewport.getWorkPosY() + viewport.getWorkSizeY() / 2.0f;
|
||||
ImGui.setNextWindowPos(CenterX, CenterY, ImGuiCond.Always, 0.5f, 0.5f);
|
||||
ImGui.begin("change notification", windowFlags);
|
||||
ImGui.setWindowFontScale(4.0f);
|
||||
ImGui.text("APPLYING GRAPHICS SETTINGS...");
|
||||
ImGui.end();
|
||||
}
|
||||
}
|
||||
ImGui.endFrame();
|
||||
ImGui.render();
|
||||
|
|
@ -325,26 +269,10 @@ public class GameCore implements GameLogic {
|
|||
|
||||
@Override
|
||||
public void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
float DeltaTime = (float)(FrameDiffNanoSeconds/16000000.0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void UpdateFastThread(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
float DeltaTime = (float)(FrameDiffNanoSeconds/16000000.0);
|
||||
for(int i = 0; i < angles.size(); i++) {
|
||||
angles.set(i, (angles.get(i) + 1.0f* DeltaTime) % 360);
|
||||
CubeActors.get(i).GetRotation().identity().rotateAxis((float) EngineConfig.DegToRad * angles.get(i), rotatingAngles.get(i));
|
||||
CubeActors.get(i).GetPosition().add((Velocities.get(i).x/100.0f) * DeltaTime,(Velocities.get(i).y/100.0f) * DeltaTime,(Velocities.get(i).z/100.0f) * DeltaTime);
|
||||
CubeActors.get(i).UpdateModelMatrix();
|
||||
}
|
||||
Ticks++;
|
||||
if(Ticks == 1000){
|
||||
// engineInstance.scene().StartCameraTrack("Default","Second",24000);
|
||||
}
|
||||
for(int i = 0; i < entities.size(); i++){
|
||||
JackOfAllTradesActor entity = entities.get(i);
|
||||
entity.tick(engineInstance.scene());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ public class PrimaryRuntime {
|
|||
}
|
||||
|
||||
public void PrimaryRuntimeInputUpdate(long nsTimeDiff){
|
||||
gameLogic.Input(PrimaryRuntime.GetEngineInstance(), (nsTimeDiff));
|
||||
gameLogic.CameraInput(PrimaryRuntime.GetEngineInstance(), (nsTimeDiff));
|
||||
}
|
||||
|
||||
|
|
@ -139,6 +140,7 @@ public class PrimaryRuntime {
|
|||
}
|
||||
ShutDownStart = System.nanoTime();
|
||||
Logger.debug("Closing Software of name [{}]",EngineConfig.getInstance().GetSoftwareName());
|
||||
FastThread.KillThread();
|
||||
PrimaryThread.KillThread();
|
||||
DrawingThread.KillThread();
|
||||
cleanup();
|
||||
|
|
@ -158,11 +160,18 @@ public class PrimaryRuntime {
|
|||
if (ThreadsOpen > 0 || VulkanContext.VulkanLayersOpen > -1) {
|
||||
Logger.debug("Waiting to close Primary Thread, making sure vulkan has shut down properly first and Engine Threads are closed\nThreads Open:[{}]\nVulkan Layers Open:[{}]", ThreadsOpen, VulkanContext.VulkanLayersOpen < 0 ? "All processes closed and vulkan instance removed" : VulkanContext.VulkanLayersOpen);
|
||||
while ((ThreadsOpen > 0 || VulkanContext.VulkanLayersOpen > 0) && VulkanContext.VulkanLayersOpen > -1 && !CanClose) {
|
||||
if (!DrawingThread.FetchThread().isAlive() && !PrimaryThread.FetchThread().isAlive() && ThreadsOpen >0){
|
||||
if (!DrawingThread.FetchThread().isAlive() && !PrimaryThread.FetchThread().isAlive() && !FastThread.FetchThread().isAlive() && ThreadsOpen >0){
|
||||
break;
|
||||
}
|
||||
if(FastThread.FetchThread().isAlive()){
|
||||
FastThread.FetchThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
while(FastThread.FetchThread().isAlive()){
|
||||
FastTickThread.running = false;
|
||||
FastThread.FetchThread().interrupt();
|
||||
}
|
||||
Logger.debug("Closing Primary Thread, Thread: [{}]",Thread.currentThread().toString());
|
||||
double ShutDownTime = Math.floor(((double)(System.nanoTime() - ShutDownStart)/1000000.0)*1000.0)/1000.0;
|
||||
Logger.info("Successful stable Shut Down of Terrain4J in [{}] MilliSeconds", ShutDownTime);
|
||||
|
|
|
|||
|
|
@ -1,43 +1,83 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Collision.CollisionMesh;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class Actor{
|
||||
private final String ID;
|
||||
private final String ModelID;
|
||||
private final Matrix4f ModelMatrix;
|
||||
private final Vector3f Position;
|
||||
private final Quaternionf Rotation;
|
||||
private float Scale;
|
||||
private CollisionMesh collisionMesh;
|
||||
private Vector3f Scale;
|
||||
|
||||
public CollisionMesh GetCollisionMesh(){
|
||||
return collisionMesh;
|
||||
}
|
||||
|
||||
public Actor(String ID, String ModelID, Vector3f Position){
|
||||
this.ID = ID;
|
||||
this.ModelID = ModelID;
|
||||
this.Position = Position;
|
||||
Scale = 1f;
|
||||
Scale = new Vector3f(1f,1f,1f);
|
||||
Rotation = new Quaternionf();
|
||||
ModelMatrix = new Matrix4f();
|
||||
UpdateModelMatrix();
|
||||
}
|
||||
|
||||
public void ResetRotation(){
|
||||
public Actor GenerateCollisionMesh(ModelData modelData) throws IOException {
|
||||
collisionMesh = new CollisionMesh(ID + "_COLLISION_MESH");
|
||||
collisionMesh.GenerateCollisionMeshFromVulkanModel(modelData);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Actor ResetRotation(){
|
||||
Rotation.x = 0;
|
||||
Rotation.y = 0;
|
||||
Rotation.z = 0;
|
||||
Rotation.w = 1.0f;
|
||||
return this;
|
||||
}
|
||||
|
||||
public final void SetPosition(float x, float y, float z){
|
||||
public Actor SetRotation(Vector3f rot){
|
||||
Rotation.rotateX(rot.x);
|
||||
Rotation.rotateY(rot.y);
|
||||
Rotation.rotateZ(rot.z);
|
||||
UpdateModelMatrix();
|
||||
return this;
|
||||
}
|
||||
public Actor SetRotation(float x, float y, float z){
|
||||
Rotation.rotateX(x);
|
||||
Rotation.rotateY(y);
|
||||
Rotation.rotateZ(z);
|
||||
UpdateModelMatrix();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Actor SetPosition(float x, float y, float z){
|
||||
Position.x = x;
|
||||
Position.y = y;
|
||||
Position.z = z;
|
||||
UpdateModelMatrix();
|
||||
return this;
|
||||
}
|
||||
public Actor SetScale(float x, float y, float z){
|
||||
Scale.x = x;
|
||||
Scale.y = y;
|
||||
Scale.z = z;
|
||||
UpdateModelMatrix();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Actor SetScale(float Scale){
|
||||
this.Scale = Scale;
|
||||
this.Scale = new Vector3f(Scale,Scale,Scale);
|
||||
UpdateModelMatrix();
|
||||
return this;
|
||||
}
|
||||
|
|
@ -51,5 +91,5 @@ public class Actor{
|
|||
public Matrix4f GetModelMatrix(){return ModelMatrix;}
|
||||
public Vector3f GetPosition(){ return Position;}
|
||||
public Quaternionf GetRotation(){return Rotation;}
|
||||
public float GetScale(){return Scale;}
|
||||
public Vector3f GetScale(){return Scale;}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,118 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.Gimbal;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public class EditorActorComponent implements IMoveableActorComponent{
|
||||
public static int ActorComponentCount = 0;
|
||||
private Gimbal ActorGimbal;
|
||||
private Actor actor;
|
||||
private Vector3f Position;
|
||||
private Vector3f ActorDimensions;
|
||||
private String ID = "ActorComponent";
|
||||
|
||||
public EditorActorComponent(Actor actor, Vector3f Position, Vector3f Dimensions){
|
||||
ID = actor.GetID() + "_COMPONENT" + ActorComponentCount;
|
||||
this.Position = new Vector3f(Position);
|
||||
this.actor = actor;
|
||||
this.ActorDimensions = new Vector3f(Dimensions);
|
||||
ActorGimbal = new Gimbal(Position, new Vector3f(1.0f,1.0f,1.0f),this).SetID(ID);
|
||||
ActorComponentCount++;
|
||||
UpdateAll();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void UpdateAll() {
|
||||
actor.GetPosition().set(Position.x,Position.y,Position.z);
|
||||
if(actor.GetCollisionMesh() != null) {
|
||||
actor.GetCollisionMesh().SetWorldPosition(new Vector3f(Position.x,Position.y,Position.z));
|
||||
actor.GetCollisionMesh().SetRotationTransform(actor.GetRotation());
|
||||
actor.GetCollisionMesh().SetScaleTransform(actor.GetScale());
|
||||
}
|
||||
ActorGimbal.SetPosition(new Vector3f(Position.x, Position.y + ActorDimensions.y/2, Position.z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Actor GetActor() {
|
||||
return actor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SetActor(Actor actor) {
|
||||
this.actor = actor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void AddPosition(Vector3f addedPos) {
|
||||
Vector3f Pos = actor.GetPosition();
|
||||
actor.SetPosition(Pos.x + addedPos.x, Pos.y + addedPos.y, Pos.z + addedPos.z);
|
||||
Position = new Vector3f(actor.GetPosition());
|
||||
UpdateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void AddRotation(Vector3f addedRot) {
|
||||
actor.SetRotation( addedRot.x, addedRot.y, addedRot.z);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void AddScale(Vector3f addedScale) {
|
||||
Vector3f scale = actor.GetScale();
|
||||
actor.SetScale(scale.x + addedScale.x, scale.y + addedScale.y, scale.z + addedScale.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f GetPosition() {
|
||||
return Position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Gimbal GetActorGimbal() {
|
||||
return ActorGimbal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SetActorGimbal(Gimbal gimbal) {
|
||||
this.ActorGimbal = gimbal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SetPosition(float x, float y, float z) {
|
||||
this.Position = new Vector3f(x,y,z);
|
||||
UpdateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SetPosition(Vector3f Position) {
|
||||
this.Position = new Vector3f(Position);
|
||||
UpdateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SetActorDimensions(float x, float y, float z) {
|
||||
ActorDimensions = new Vector3f(x,y,z);
|
||||
UpdateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f GetActorDimensions() {
|
||||
return ActorDimensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SetActorScale(float scale) {
|
||||
actor.SetScale(scale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void SetActorScale(Vector3f scale) {
|
||||
actor.SetScale(scale.x,scale.y,scale.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f GetActorScale() {
|
||||
return actor.GetScale();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,308 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs;
|
||||
|
||||
import imgui.ImDrawList;
|
||||
import imgui.ImGui;
|
||||
import imgui.ImVec2;
|
||||
import imgui.flag.ImGuiCol;
|
||||
import imgui.flag.ImGuiWindowFlags;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Collision.CollisionManager;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Collision.CollisionMesh;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Collision.CollisionPoly;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.IMoveableActorComponent;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Util.Maths.T4Math;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Gimbal implements GUIOverlay {
|
||||
private IMoveableActorComponent parent;
|
||||
public static Map<String, Gimbal> gimbalMap = new HashMap<>();
|
||||
public static GimbalType universalType = GimbalType.Move;
|
||||
private static Vector2f LastMousePos;
|
||||
private static Vector2f MouseDiff = new Vector2f(0,0);
|
||||
|
||||
|
||||
public static void RenderGimbals(EngineInstance engineInstance, long FrameTimeNS, GameCore parent){
|
||||
Vector2f CurrentMousePos = new Vector2f(engineInstance.window().getMouseInput().getCurrentPos());
|
||||
if(LastMousePos != null) MouseDiff = new Vector2f(CurrentMousePos).sub(LastMousePos);
|
||||
LastMousePos = new Vector2f(CurrentMousePos);
|
||||
List<Gimbal> gimbals = gimbalMap.values().stream().toList();
|
||||
|
||||
int winWidth = engineInstance.window().getWidth();
|
||||
int winHeight = engineInstance.window().getHeight();
|
||||
|
||||
ImGui.setNextWindowPos(0, 0);
|
||||
ImGui.setNextWindowSize(winWidth, winHeight);
|
||||
|
||||
int flags = ImGuiWindowFlags.NoTitleBar |
|
||||
ImGuiWindowFlags.NoBringToFrontOnFocus |
|
||||
ImGuiWindowFlags.NoResize |
|
||||
ImGuiWindowFlags.NoMove |
|
||||
ImGuiWindowFlags.NoScrollbar |
|
||||
ImGuiWindowFlags.NoBackground |
|
||||
ImGuiWindowFlags.NoSavedSettings;
|
||||
|
||||
ImGui.begin("WorldSpaceUIOverlay", flags);
|
||||
ImGui.getStyle().setAntiAliasedLines(true);
|
||||
if(EngineConfig.getInstance().RenderCollisionMesh){
|
||||
List<CollisionMesh> meshes = CollisionManager.GetAllCollisionMeshes();
|
||||
for(int i = 0; i < meshes.size(); i++){
|
||||
CollisionMesh mesh = meshes.get(i);
|
||||
CollisionPoly[] polygons = mesh.GetAllPolygons();
|
||||
for(int j = 0; j < polygons.length; j++){
|
||||
DrawCollisionPolygon(engineInstance.scene().GetCamera().GetViewMatrix(), engineInstance.scene().GetProjection().GetProjectionMatrix(),winWidth,winHeight,polygons[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < gimbals.size(); i++){
|
||||
gimbals.get(i).DrawGimbalInWorld(engineInstance.scene().GetCamera().GetViewMatrix(), engineInstance.scene().GetProjection().GetProjectionMatrix(),winWidth,winHeight);
|
||||
}
|
||||
ImGui.end();
|
||||
}
|
||||
|
||||
public enum GimbalType{
|
||||
Move,
|
||||
Resize,
|
||||
Rotate
|
||||
}
|
||||
|
||||
private Vector3f Position = new Vector3f(0,0,0);
|
||||
private Vector3f GimbalArmLengths = new Vector3f(1.0f,1.0f,1.0f);
|
||||
private String ID = "Gimbal";
|
||||
public Gimbal(Vector3f pos, Vector3f GimbalArmLengths, IMoveableActorComponent parent){
|
||||
this.parent = parent;
|
||||
Position = new Vector3f(pos);
|
||||
this.GimbalArmLengths = new Vector3f(GimbalArmLengths);
|
||||
}
|
||||
public Gimbal SetID(String IDIn){
|
||||
this.ID = IDIn;
|
||||
gimbalMap.put(ID, this);
|
||||
return this;
|
||||
}
|
||||
public Gimbal SetGimbalType(GimbalType type){
|
||||
universalType = type;
|
||||
return this;
|
||||
}
|
||||
public void SetPosition(Vector3f vector3f){
|
||||
Position = new Vector3f(vector3f);
|
||||
}
|
||||
public void SetArmLengths(Vector3f gimbalArmLengths){
|
||||
GimbalArmLengths = new Vector3f(gimbalArmLengths);
|
||||
}
|
||||
@Override
|
||||
public void RenderGUI(EngineInstance engineInstance, long FrameTimeNS, GameCore parent) {
|
||||
Vector2f CurrentMousePos = new Vector2f(engineInstance.window().getMouseInput().getCurrentPos());
|
||||
if(LastMousePos != null) MouseDiff = new Vector2f(CurrentMousePos).sub(LastMousePos);
|
||||
LastMousePos = new Vector2f(CurrentMousePos);
|
||||
DrawGimbalInWorld(engineInstance.scene().GetCamera().GetViewMatrix(), engineInstance.scene().GetProjection().GetProjectionMatrix(),engineInstance.window().getWidth(),engineInstance.window().getHeight());
|
||||
}
|
||||
|
||||
public static void DrawCollisionPolygon(Matrix4f viewMatrix, Matrix4f projMatrix, int winWidth, int winHeight, CollisionPoly polygon){
|
||||
if(polygon == null || polygon.v1() == null || polygon.v2() == null || polygon.v3() == null) return;
|
||||
Vector3f v1 = T4Math.Math3D.GetScreenCoordFromWorldSpace(polygon.v1(), viewMatrix, projMatrix, winWidth, winHeight);
|
||||
Vector3f v2 = T4Math.Math3D.GetScreenCoordFromWorldSpace(polygon.v2(), viewMatrix, projMatrix, winWidth, winHeight);
|
||||
Vector3f v3 = T4Math.Math3D.GetScreenCoordFromWorldSpace(polygon.v3(), viewMatrix, projMatrix, winWidth, winHeight);
|
||||
if(v1 == null || v2 == null || v3 == null) return;
|
||||
ImDrawList drawList = ImGui.getBackgroundDrawList();
|
||||
int colour = ImGui.getColorU32(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
drawList.addLine(v1.x, v1.y, v2.x, v2.y, colour, 1f);
|
||||
drawList.addLine(v2.x, v2.y, v3.x, v3.y, colour, 1f);
|
||||
drawList.addLine(v3.x, v3.y, v1.x, v1.y, colour, 1f);
|
||||
colour = ImGui.getColorU32(0.0f, 0.4f, 1.0f, 0.3f);
|
||||
drawList.addTriangleFilled(
|
||||
new ImVec2(v1.x,v1.y),
|
||||
new ImVec2(v2.x,v2.y),
|
||||
new ImVec2(v3.x,v3.y)
|
||||
,colour);
|
||||
}
|
||||
|
||||
public void DrawGimbalInWorld(Matrix4f viewMatrix, Matrix4f projMatrix, int winWidth, int winHeight) {
|
||||
Vector3f CentrePoint = new Vector3f(Position);
|
||||
Vector3f XCPoint = new Vector3f(Position.x + (GimbalArmLengths.x/2.5f),Position.y,Position.z);
|
||||
Vector3f YCPoint = new Vector3f(Position.x,Position.y + (GimbalArmLengths.y/2.5f),Position.z);
|
||||
Vector3f ZCPoint = new Vector3f(Position.x,Position.y,Position.z + (GimbalArmLengths.z/2.5f));
|
||||
Vector3f ZYPoint = new Vector3f(Position.x,Position.y + (GimbalArmLengths.y/2.5f),Position.z + (GimbalArmLengths.z/2.5f));
|
||||
Vector3f XPoint = new Vector3f(Position.x + GimbalArmLengths.x,Position.y,Position.z);
|
||||
Vector3f XYPoint = new Vector3f(Position.x + (GimbalArmLengths.x/2.5f),Position.y+ (GimbalArmLengths.y/2.5f),Position.z);
|
||||
Vector3f XZPoint = new Vector3f(Position.x + (GimbalArmLengths.x/2.5f),Position.y,Position.z + (GimbalArmLengths.z/2.5f));
|
||||
Vector3f YPoint = new Vector3f(Position.x,Position.y + GimbalArmLengths.y,Position.z);
|
||||
Vector3f ZPoint = new Vector3f(Position.x,Position.y,Position.z + GimbalArmLengths.z);
|
||||
|
||||
Vector3f CentreScreenPos = T4Math.Math3D.GetScreenCoordFromWorldSpace(CentrePoint, viewMatrix, projMatrix, winWidth, winHeight);
|
||||
Vector3f XCScreenPos = T4Math.Math3D.GetScreenCoordFromWorldSpace(XCPoint, viewMatrix, projMatrix, winWidth, winHeight);
|
||||
Vector3f YCScreenPos = T4Math.Math3D.GetScreenCoordFromWorldSpace(YCPoint, viewMatrix, projMatrix, winWidth, winHeight);
|
||||
Vector3f ZCScreenPos = T4Math.Math3D.GetScreenCoordFromWorldSpace(ZCPoint, viewMatrix, projMatrix, winWidth, winHeight);
|
||||
Vector3f ZYScreenPos = T4Math.Math3D.GetScreenCoordFromWorldSpace(ZYPoint, viewMatrix, projMatrix, winWidth, winHeight);
|
||||
Vector3f XYScreenPos = T4Math.Math3D.GetScreenCoordFromWorldSpace(XYPoint, viewMatrix, projMatrix, winWidth, winHeight);
|
||||
Vector3f XZScreenPos = T4Math.Math3D.GetScreenCoordFromWorldSpace(XZPoint, viewMatrix, projMatrix, winWidth, winHeight);
|
||||
Vector3f XPointScreenPos = T4Math.Math3D.GetScreenCoordFromWorldSpace(XPoint, viewMatrix, projMatrix, winWidth, winHeight);
|
||||
Vector3f YPointScreenPos = T4Math.Math3D.GetScreenCoordFromWorldSpace(YPoint, viewMatrix, projMatrix, winWidth, winHeight);
|
||||
Vector3f ZPointScreenPos = T4Math.Math3D.GetScreenCoordFromWorldSpace(ZPoint, viewMatrix, projMatrix, winWidth, winHeight);
|
||||
|
||||
if (CentreScreenPos == null) return;
|
||||
ImDrawList drawList = ImGui.getBackgroundDrawList();
|
||||
float thickness = 5.0f;
|
||||
float ButtonMultiplier = 6.0f;
|
||||
float buttonWidth = thickness * ButtonMultiplier;
|
||||
float buttonHeight = thickness * ButtonMultiplier;
|
||||
int color = ImGui.getColorU32(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
ImGui.pushStyleColor(ImGuiCol.Button, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
ImGui.pushStyleColor(ImGuiCol.ButtonHovered, 1.0f, 1.0f, 1.0f, 0.2f);
|
||||
ImGui.pushStyleColor(ImGuiCol.ButtonActive, 1.0f, 1.0f, 1.0f, 0.4f);
|
||||
if(XPointScreenPos != null) {
|
||||
drawList.addLine(CentreScreenPos.x, CentreScreenPos.y, XPointScreenPos.x, XPointScreenPos.y, color, thickness);
|
||||
float adjustedX = XPointScreenPos.x - (buttonWidth / 2.0f);
|
||||
float adjustedY = XPointScreenPos.y - (buttonHeight / 2.0f);
|
||||
ImGui.setCursorScreenPos(adjustedX, adjustedY);
|
||||
ImGui.button("X##" + ID, buttonWidth, buttonHeight);
|
||||
switch(universalType) {
|
||||
case Rotate:
|
||||
ImVec2 Right = new ImVec2(XPointScreenPos.x, XPointScreenPos.y).plus(new ImVec2(thickness * ButtonMultiplier/2.0f,0));
|
||||
ImVec2 Left = new ImVec2(XPointScreenPos.x, XPointScreenPos.y).minus(new ImVec2(thickness * ButtonMultiplier/2.0f,0));
|
||||
ImVec2 Bottom = new ImVec2(XPointScreenPos.x, XPointScreenPos.y).minus(new ImVec2(0,thickness * ButtonMultiplier/2.0f));
|
||||
ImVec2 Top = new ImVec2(XPointScreenPos.x, XPointScreenPos.y).plus(new ImVec2(0,thickness * ButtonMultiplier/2.0f));
|
||||
drawList.addQuadFilled(Left,Top,Right,Bottom,color);
|
||||
break;
|
||||
case Resize:
|
||||
drawList.addRectFilled(XPointScreenPos.x- (thickness * ButtonMultiplier/2.0f), XPointScreenPos.y- (thickness * ButtonMultiplier/2.0f), XPointScreenPos.x+ (thickness * ButtonMultiplier/2.0f), XPointScreenPos.y + (thickness * ButtonMultiplier/2.0f), color);
|
||||
break;
|
||||
case Move:
|
||||
default:
|
||||
drawList.addCircleFilled(XPointScreenPos.x, XPointScreenPos.y, thickness * ButtonMultiplier/2.0f, color);
|
||||
break;
|
||||
}
|
||||
if (ImGui.isItemActive()) {
|
||||
switch(universalType) {
|
||||
case Rotate:
|
||||
parent.AddRotation(new Vector3f(0,(float) ((MouseDiff.x + MouseDiff.y) / (float) (winWidth / 10.0f)),0));
|
||||
break;
|
||||
case Resize:
|
||||
parent.AddScale(new Vector3f((MouseDiff.x + MouseDiff.y) / (float) (winWidth / 10.0f), 0, 0));
|
||||
break;
|
||||
case Move:
|
||||
default:
|
||||
parent.AddPosition(new Vector3f((MouseDiff.x + MouseDiff.y) / (float) (winWidth / 10.0f), 0, 0));
|
||||
break;
|
||||
}
|
||||
parent.UpdateAll();
|
||||
}
|
||||
}
|
||||
color = ImGui.getColorU32(1.0f, 0.0f, 0.0f, 0.4f);
|
||||
if(XYScreenPos != null && YCScreenPos != null && XCScreenPos != null) {
|
||||
drawList.addConvexPolyFilled(new ImVec2[]{
|
||||
new ImVec2(CentreScreenPos.x,CentreScreenPos.y),
|
||||
new ImVec2(XCScreenPos.x,XCScreenPos.y),
|
||||
new ImVec2(XYScreenPos.x,XYScreenPos.y),
|
||||
new ImVec2(YCScreenPos.x,YCScreenPos.y),
|
||||
},4,color);
|
||||
}
|
||||
color = ImGui.getColorU32(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
if(YPointScreenPos != null) {
|
||||
drawList.addLine(CentreScreenPos.x, CentreScreenPos.y, YPointScreenPos.x, YPointScreenPos.y, color, thickness);
|
||||
float adjustedX = YPointScreenPos.x - (buttonWidth / 2.0f);
|
||||
float adjustedY = YPointScreenPos.y - (buttonHeight / 2.0f);
|
||||
ImGui.setCursorScreenPos(adjustedX, adjustedY);
|
||||
ImGui.button("Y##" + ID, buttonWidth, buttonHeight);
|
||||
switch(universalType) {
|
||||
case Rotate:
|
||||
|
||||
ImVec2 Right = new ImVec2(YPointScreenPos.x, YPointScreenPos.y).plus(new ImVec2(thickness * ButtonMultiplier/2.0f,0));
|
||||
ImVec2 Left = new ImVec2(YPointScreenPos.x, YPointScreenPos.y).minus(new ImVec2(thickness * ButtonMultiplier/2.0f,0));
|
||||
ImVec2 Bottom = new ImVec2(YPointScreenPos.x, YPointScreenPos.y).minus(new ImVec2(0,thickness * ButtonMultiplier/2.0f));
|
||||
ImVec2 Top = new ImVec2(YPointScreenPos.x, YPointScreenPos.y).plus(new ImVec2(0,thickness * ButtonMultiplier/2.0f));
|
||||
drawList.addQuadFilled(Left,Top,Right,Bottom,color);
|
||||
break;
|
||||
case Resize:
|
||||
drawList.addRectFilled(YPointScreenPos.x- (thickness * ButtonMultiplier/2.0f), YPointScreenPos.y- (thickness * ButtonMultiplier/2.0f), YPointScreenPos.x+ (thickness * ButtonMultiplier/2.0f), YPointScreenPos.y + (thickness * ButtonMultiplier/2.0f), color);
|
||||
break;
|
||||
case Move:
|
||||
default:
|
||||
drawList.addCircleFilled(YPointScreenPos.x, YPointScreenPos.y, thickness * ButtonMultiplier/2.0f, color);
|
||||
break;
|
||||
}
|
||||
if (ImGui.isItemActive()) {
|
||||
switch(universalType) {
|
||||
case Rotate:
|
||||
parent.AddRotation(new Vector3f((float) ((MouseDiff.x + MouseDiff.y) / (float) (winWidth / 10.0f)),0,0));
|
||||
|
||||
break;
|
||||
case Resize:
|
||||
parent.AddScale(new Vector3f(0, (MouseDiff.x + MouseDiff.y) / (float) (winWidth / 10.0f), 0));
|
||||
break;
|
||||
case Move:
|
||||
default:
|
||||
parent.AddPosition(new Vector3f(0,-(MouseDiff.y)/(float)(winHeight/10.0f), 0));
|
||||
break;
|
||||
}
|
||||
parent.UpdateAll();
|
||||
}
|
||||
}
|
||||
color = ImGui.getColorU32(0.0f, 1.0f, 0.0f, 0.4f);
|
||||
if(XZScreenPos != null && ZCScreenPos != null && XCScreenPos != null) {
|
||||
drawList.addConvexPolyFilled(new ImVec2[]{
|
||||
new ImVec2(CentreScreenPos.x,CentreScreenPos.y),
|
||||
new ImVec2(XCScreenPos.x,XCScreenPos.y),
|
||||
new ImVec2(XZScreenPos.x,XZScreenPos.y),
|
||||
new ImVec2(ZCScreenPos.x,ZCScreenPos.y),
|
||||
},4,color);
|
||||
}
|
||||
color = ImGui.getColorU32(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
if(ZPointScreenPos != null) {
|
||||
drawList.addLine(CentreScreenPos.x, CentreScreenPos.y, ZPointScreenPos.x, ZPointScreenPos.y, color, thickness);
|
||||
float adjustedX = ZPointScreenPos.x - (buttonWidth / 2.0f);
|
||||
float adjustedY = ZPointScreenPos.y - (buttonHeight / 2.0f);
|
||||
ImGui.setCursorScreenPos(adjustedX, adjustedY);
|
||||
ImGui.button("Z##" + ID, buttonWidth, buttonHeight);
|
||||
switch(universalType) {
|
||||
case Rotate:
|
||||
ImVec2 Right = new ImVec2(ZPointScreenPos.x, ZPointScreenPos.y).plus(new ImVec2(thickness * ButtonMultiplier/2.0f,0));
|
||||
ImVec2 Left = new ImVec2(ZPointScreenPos.x, ZPointScreenPos.y).minus(new ImVec2(thickness * ButtonMultiplier/2.0f,0));
|
||||
ImVec2 Bottom = new ImVec2(ZPointScreenPos.x, ZPointScreenPos.y).minus(new ImVec2(0,thickness * ButtonMultiplier/2.0f));
|
||||
ImVec2 Top = new ImVec2(ZPointScreenPos.x, ZPointScreenPos.y).plus(new ImVec2(0,thickness * ButtonMultiplier/2.0f));
|
||||
drawList.addQuadFilled(Left,Top,Right,Bottom,color);
|
||||
break;
|
||||
case Resize:
|
||||
drawList.addRectFilled(ZPointScreenPos.x- (thickness * ButtonMultiplier/2.0f), ZPointScreenPos.y- (thickness * ButtonMultiplier/2.0f), ZPointScreenPos.x+ (thickness * ButtonMultiplier/2.0f), ZPointScreenPos.y + (thickness * ButtonMultiplier/2.0f), color);
|
||||
break;
|
||||
case Move:
|
||||
default:
|
||||
drawList.addCircleFilled(ZPointScreenPos.x, ZPointScreenPos.y, thickness * ButtonMultiplier/2.0f, color);
|
||||
break;
|
||||
}
|
||||
if (ImGui.isItemActive()) {
|
||||
switch(universalType) {
|
||||
case Rotate:
|
||||
parent.AddRotation(new Vector3f(0,0,(float) ((MouseDiff.x + MouseDiff.y) / (float) (winWidth / 10.0f))));
|
||||
break;
|
||||
case Resize:
|
||||
parent.AddScale(new Vector3f( 0, 0,(MouseDiff.x + MouseDiff.y) / (float) (winWidth / 10.0f)));
|
||||
break;
|
||||
case Move:
|
||||
default:
|
||||
parent.AddPosition(new Vector3f(0,0, (-MouseDiff.x + MouseDiff.y)/(float)(winWidth/10.0f)));
|
||||
break;
|
||||
}
|
||||
parent.UpdateAll();
|
||||
}
|
||||
}
|
||||
color = ImGui.getColorU32(0.0f, 0.0f, 1.0f, 0.4f);
|
||||
if(ZYScreenPos != null && YCScreenPos != null && ZCScreenPos != null) {
|
||||
drawList.addConvexPolyFilled(new ImVec2[]{
|
||||
new ImVec2(CentreScreenPos.x,CentreScreenPos.y),
|
||||
new ImVec2(ZCScreenPos.x,ZCScreenPos.y),
|
||||
new ImVec2(ZYScreenPos.x,ZYScreenPos.y),
|
||||
new ImVec2(YCScreenPos.x,YCScreenPos.y),
|
||||
},4,color);
|
||||
}
|
||||
ImGui.popStyleColor(3);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
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.ImGuiWindowFlags;
|
||||
import imgui.type.ImFloat;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
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.Vulkan.GUI.GuiTexture;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.DeferredSceneRender;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
|
||||
import org.joml.Vector3f;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
public class LoadingScreen implements GUIOverlay {
|
||||
private final ImFloat GammaValue = new ImFloat(0.8545f);
|
||||
private final GuiTexture LoadingTexture;
|
||||
public LoadingScreen(GuiTexture LoadingScreenTexture){
|
||||
LoadingTexture = LoadingScreenTexture;
|
||||
}
|
||||
@Override
|
||||
public void RenderGUI(EngineInstance engineInstance, long frameTimeNS, GameCore parent) {
|
||||
int windowFlags = ImGuiWindowFlags.NoDecoration
|
||||
| ImGuiWindowFlags.AlwaysAutoResize
|
||||
| ImGuiWindowFlags.NoSavedSettings
|
||||
| ImGuiWindowFlags.NoFocusOnAppearing
|
||||
| ImGuiWindowFlags.NoNav
|
||||
| ImGuiWindowFlags.NoMove;
|
||||
ImGuiViewport viewport = ImGui.getMainViewport();
|
||||
float CenterX = viewport.getWorkPosX() + viewport.getWorkSizeX() / 2.0f;
|
||||
float CenterY = viewport.getWorkPosY() + viewport.getWorkSizeY() / 2.0f;
|
||||
ImGui.setNextWindowPos(0,0, ImGuiCond.Always);
|
||||
ImGui.setNextWindowSize(viewport.getWorkSizeX(),viewport.getWorkSizeY());
|
||||
ImGui.pushStyleColor(ImGuiCol.WindowBg, 0,0.1f,0.5f,1.0f);
|
||||
ImGui.begin("Loading Screen BG",windowFlags);
|
||||
ImGui.end();
|
||||
ImGui.setNextWindowPos(CenterX,CenterY, ImGuiCond.Always,0.5f,0.5f);
|
||||
ImGui.pushStyleColor(ImGuiCol.WindowBg, 0,0.1f,0.5f,0.0f);
|
||||
ImGui.begin("Loading Screen",windowFlags);
|
||||
ImGui.image(PrimaryRuntime.GetRenderThread().GetRenderer().GetGuiTexture(LoadingTexture.ID()),viewport.getWorkSizeX() / 2.0f,viewport.getWorkSizeY() / 2.0f);
|
||||
ImGui.end();
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,6 @@ import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
|||
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.JackOfAllTradesActor;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.DeferredSceneRender;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
|
||||
import org.joml.Vector3f;
|
||||
|
|
@ -148,10 +147,8 @@ public class PerformanceOverlay implements GUIOverlay {
|
|||
}
|
||||
ImGui.separator();
|
||||
ImGui.text("Level Tools:");
|
||||
if(ImGui.button("Spawn Radio")){
|
||||
JackOfAllTradesActor newJackentity = new JackOfAllTradesActor("Radio" + parent.entities.size(), parent.radio.ID(), new Vector3f(engineInstance.scene().GetCamera().GetPosition()),parent.MusicParticle).SetAudio(engineInstance, "resources/EngineResources/audio/sounds/youusedtocallmeonyourcellphone.ogg").SetScale(0.01f);
|
||||
parent.entities.add(newJackentity);
|
||||
engineInstance.scene().AddActor(newJackentity);
|
||||
if(ImGui.button("Spawn Melona")){
|
||||
parent.SpawnNewActorEditorComponent(engineInstance);
|
||||
}
|
||||
if(parent.PerformanceMetrics.size() > 0) {
|
||||
ImGui.text(" ");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs;
|
||||
import imgui.ImDrawList;
|
||||
import imgui.ImGui;
|
||||
import imgui.ImVec2;
|
||||
import imgui.flag.ImGuiCol;
|
||||
import imgui.flag.ImGuiMouseButton;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.*;
|
||||
|
||||
import static net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.T4ImGuiUtil.IsPointInPolygon;
|
||||
|
||||
public class T4ImGui {
|
||||
public static boolean polygonButton(String id, ImVec2[] Vertices) {
|
||||
ImGui.pushID(id);
|
||||
ImVec2 MousePos = ImGui.getMousePos();
|
||||
ImDrawList DrawList = ImGui.getWindowDrawList();
|
||||
boolean isHovered = IsPointInPolygon(MousePos, Vertices) && ImGui.isWindowHovered();
|
||||
boolean isActive = isHovered && ImGui.isMouseDown(ImGuiMouseButton.Left);
|
||||
boolean isClicked = isHovered && ImGui.isMouseReleased(ImGuiMouseButton.Left);
|
||||
int Colour;
|
||||
if (isActive) {
|
||||
Colour = ImGui.getColorU32(ImGuiCol.ButtonActive);
|
||||
} else if (isHovered) {
|
||||
Colour = ImGui.getColorU32(ImGuiCol.ButtonHovered);
|
||||
} else {
|
||||
Colour = ImGui.getColorU32(ImGuiCol.Button);
|
||||
}
|
||||
DrawList.addConvexPolyFilled(Vertices, Vertices.length, Colour);
|
||||
int BorderColour = ImGui.getColorU32(ImGuiCol.Border);
|
||||
DrawList.addPolyline(Vertices, Vertices.length, BorderColour, 0, 1.0f);
|
||||
ImGui.popID();
|
||||
return isClicked;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs;
|
||||
|
||||
import imgui.ImDrawList;
|
||||
import imgui.ImGui;
|
||||
import imgui.ImVec2;
|
||||
import imgui.flag.ImGuiCol;
|
||||
import imgui.flag.ImGuiMouseButton;
|
||||
|
||||
public class T4ImGuiUtil {
|
||||
public static boolean IsPointInPolygon(ImVec2 point, ImVec2[] polygon) {
|
||||
boolean inside = false;
|
||||
int numVertices = polygon.length;
|
||||
for (int i = 0, j = numVertices - 1; i < numVertices; j = i++) {
|
||||
if (((polygon[i].y > point.y) != (polygon[j].y > point.y)) &&
|
||||
(point.x < (polygon[j].x - polygon[i].x) * (point.y - polygon[i].y) / (polygon[j].y - polygon[i].y) + polygon[i].x)) {
|
||||
inside = !inside;
|
||||
}
|
||||
}
|
||||
return inside;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.Gimbal;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public interface IMoveableActorComponent {
|
||||
public void UpdateAll();
|
||||
public Actor GetActor();
|
||||
public void SetActor(Actor actor);
|
||||
public void AddPosition(Vector3f addedPos);
|
||||
public void AddRotation(Vector3f addedRot);
|
||||
public void AddScale(Vector3f addedScale);
|
||||
public Vector3f GetPosition();
|
||||
public Gimbal GetActorGimbal();
|
||||
public void SetActorGimbal(Gimbal gimbal);
|
||||
public void SetPosition(float x, float y, float z);
|
||||
public void SetPosition(Vector3f Position);
|
||||
public void SetActorDimensions(float x, float y, float z);
|
||||
public Vector3f GetActorDimensions();
|
||||
public void SetActorScale(float scale);
|
||||
public void SetActorScale(Vector3f scale);
|
||||
public Vector3f GetActorScale();
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package net.halbear.Terrain4J.EngineCore.Main.Scene;
|
|||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.SkyBox;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DynamicMesh.DynamicTerrainMesh;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -21,7 +22,7 @@ public interface IScene {
|
|||
public List<Actor> GetActors();
|
||||
public Project3D GetProjection();
|
||||
public void RemoveAllActors();
|
||||
public void RemoveActor(Actor actor);
|
||||
public Actor RemoveActor(Actor actor);
|
||||
public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds);
|
||||
public void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds);
|
||||
public void UpdateFastThread(EngineInstance engineInstance, long FrameDiffNanoSeconds);
|
||||
|
|
@ -34,4 +35,6 @@ public interface IScene {
|
|||
public ISceneLightingManager GetLightingManager();
|
||||
public SkyBox GetSkyBox();
|
||||
public void SetSkyBox(SkyBox skyBox);
|
||||
public DynamicTerrainMesh GetTerrainMesh();
|
||||
public void CreateTerrainMesh();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,66 +0,0 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene;
|
||||
|
||||
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.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class JackOfAllTradesActor extends Actor {
|
||||
|
||||
private ModelData Particle;
|
||||
private List<ParticleActor> particleActors = new ArrayList<>();
|
||||
private String SOUND_ID_BUFFER;
|
||||
private String SOUND_ID_PLAYER;
|
||||
private AudioSource playerAudioSource;
|
||||
|
||||
public JackOfAllTradesActor(String ID, String ModelID, Vector3f Position, ModelData Particle){
|
||||
super(ID,ModelID,Position);
|
||||
SOUND_ID_BUFFER = ID + "_AUDIO_BUFFER";
|
||||
SOUND_ID_PLAYER = ID+"_AUDIO_PLAYER";
|
||||
this.Particle = Particle;
|
||||
}
|
||||
public JackOfAllTradesActor SetScale(float scale){
|
||||
super.SetScale(scale);
|
||||
return this;
|
||||
}
|
||||
public JackOfAllTradesActor SetAudio(EngineInstance engineInstance, String AudioFile){
|
||||
AudioManager audioManager = engineInstance.audioManager();
|
||||
SoundBuffer buffer = new SoundBuffer(AudioFile);
|
||||
audioManager.AddSoundBuffer(SOUND_ID_BUFFER, buffer);
|
||||
playerAudioSource = new AudioSource(true,false);
|
||||
playerAudioSource.SetPosition(new Vector3f(GetPosition()));
|
||||
playerAudioSource.SetBuffer(buffer.GetBufferID());
|
||||
audioManager.AddSoundSource(SOUND_ID_PLAYER,playerAudioSource);
|
||||
PlayAudio();
|
||||
return this;
|
||||
}
|
||||
public JackOfAllTradesActor PlayAudio(){
|
||||
playerAudioSource.Play();
|
||||
return this;
|
||||
}
|
||||
|
||||
public void tick(IScene scene){
|
||||
List<Integer> ParticlesToDelete = new ArrayList<>();
|
||||
if((int)(Math.random() * 20) == 0){
|
||||
ParticleActor particle = new ParticleActor("particle" + particleActors.size(), Particle.ID(), new Vector3f(GetPosition()),new Vector3f(1,1,1),0,new Vector3f(-1f + (float)Math.random() * 2,-1f + (float)Math.random() * 2,-1f + (float)Math.random() * 2),0.0005f,5000);
|
||||
particleActors.add(particle);
|
||||
scene.AddActor(particle);
|
||||
}
|
||||
for(int i = 0; i < particleActors.size(); i++){
|
||||
particleActors.get(i).TickUpdate();
|
||||
if(particleActors.get(i).TicksLeft() <= 0){
|
||||
scene.RemoveActor(particleActors.get(i));
|
||||
ParticlesToDelete.add(i);
|
||||
}
|
||||
}
|
||||
for(int i = ParticlesToDelete.size() - 1; i >= 0; i--){
|
||||
particleActors.remove((int)ParticlesToDelete.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,8 +6,12 @@ import net.halbear.Terrain4J.EngineCore.Input.MouseListener;
|
|||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.SkyBox;
|
||||
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.GUIs.Gimbal;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.PerformanceOverlay;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DynamicMesh.DynamicTerrainMesh;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
|
|
@ -27,7 +31,8 @@ public class Scene implements IScene {
|
|||
|
||||
private static final float MOUSE_SENSITIVITY = 0.1f;
|
||||
private static final float MOVEMENT_SPEED = 0.025f;
|
||||
private final List<Actor> Actors;
|
||||
private final Map<String, Actor> Actors;
|
||||
private final List<String> ActiveActors;
|
||||
private final Map<String, CameraFrame> CameraFrames;
|
||||
private final Project3D Projection;
|
||||
private final Camera camera;
|
||||
|
|
@ -40,6 +45,8 @@ public class Scene implements IScene {
|
|||
private Vector2f LastMousePos = new Vector2f(0,0);
|
||||
private final ISceneLightingManager lightingManager;
|
||||
private SkyBox skyBox;
|
||||
private Map<String,AudioInstance> audioInstances;
|
||||
private DynamicTerrainMesh terrainMesh;
|
||||
|
||||
public List<String> ActiveGUIs = new ArrayList<>();
|
||||
public Map<String, GUIOverlay> GUIReg = new HashMap<>();
|
||||
|
|
@ -48,11 +55,30 @@ public class Scene implements IScene {
|
|||
this.skyBox = skyBox;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicTerrainMesh GetTerrainMesh() {
|
||||
return terrainMesh;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void CreateTerrainMesh() {
|
||||
int Width = 32;
|
||||
int Height = 32;
|
||||
float[] Heights = new float[Width * Height];
|
||||
for(int i = 0; i < Heights.length; i++){
|
||||
Heights[i] = 3 * (float)Math.random();
|
||||
}
|
||||
terrainMesh = new DynamicTerrainMesh(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext().GetDevice(), Heights, Width, Height);
|
||||
}
|
||||
|
||||
public SkyBox GetSkyBox(){return skyBox;}
|
||||
|
||||
public Scene(Window window) {
|
||||
// CreateTerrainMesh();
|
||||
lightingManager = new SceneLightingManager(1000,new Vector3f(1f,1f,1f), 0.5f);
|
||||
Actors = new ArrayList<>();
|
||||
Actors = new HashMap<>();
|
||||
audioInstances = new HashMap<>();
|
||||
ActiveActors = new ArrayList<>();
|
||||
CameraFrames = new HashMap<>();
|
||||
var EngConfig = EngineConfig.getInstance();
|
||||
camera = new Camera();
|
||||
|
|
@ -122,11 +148,11 @@ public class Scene implements IScene {
|
|||
public void SetActiveCameraFrame(String frameName){SetCameraFrame = frameName;}
|
||||
public String GetActiveCameraFrame(){return ActiveCameraFrame;}
|
||||
public Camera GetCamera(){return camera;}
|
||||
public void AddActor(Actor NewActor){Actors.add(NewActor);}
|
||||
public List<Actor> GetActors(){return Actors;}
|
||||
public void AddActor(Actor NewActor){Actors.put(NewActor.GetID(), NewActor);}
|
||||
public List<Actor> GetActors(){return Actors.values().stream().toList();}
|
||||
public Project3D GetProjection(){return Projection;}
|
||||
public void RemoveAllActors(){Actors.clear();}
|
||||
public void RemoveActor(Actor actor){Actors.removeIf(Actor->Actor.GetID().equals(actor.GetID()));}
|
||||
public Actor RemoveActor(Actor actor){return Actors.remove(actor.GetID());}
|
||||
|
||||
public void SetUpAudio(EngineInstance engineInstance){
|
||||
|
||||
|
|
@ -195,8 +221,9 @@ public class Scene implements IScene {
|
|||
@Override
|
||||
public void RenderGUIs(EngineInstance engineInstance, long frameTimeNS, GameCore parent) {
|
||||
List<String> ActiveGuis = new ArrayList<>(ActiveGUIs);
|
||||
Gimbal.RenderGimbals(engineInstance,frameTimeNS,parent);
|
||||
ActiveGuis.forEach(gui->{
|
||||
if(GUIReg.containsKey(gui)){
|
||||
if(GUIReg.containsKey(gui) && !GUIReg.get(gui).getClass().equals(Gimbal.class)){
|
||||
GUIReg.get(gui).RenderGUI(engineInstance,frameTimeNS,parent);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene;
|
||||
|
||||
public class SceneLoadData {
|
||||
|
||||
}
|
||||
|
|
@ -1,8 +1,137 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Util.Maths;
|
||||
|
||||
import imgui.ImVec2;
|
||||
import org.joml.*;
|
||||
|
||||
import java.lang.Math;
|
||||
|
||||
public class T4Math {
|
||||
public static double Log2(int n){
|
||||
return Math.log(n) / Math.log(n);
|
||||
}
|
||||
public static double Square(double n){return n*n;}
|
||||
|
||||
public static class Math2D {
|
||||
public static boolean IsPointInPolygon(Vector2f point, Vector2f[] polygon) {
|
||||
boolean inside = false;
|
||||
int numVertices = polygon.length;
|
||||
for (int i = 0, j = numVertices - 1; i < numVertices; j = i++) {
|
||||
if (((polygon[i].y > point.y) != (polygon[j].y > point.y)) &&
|
||||
(point.x < (polygon[j].x - polygon[i].x) * (point.y - polygon[i].y) / (polygon[j].y - polygon[i].y) + polygon[i].x)) {
|
||||
inside = !inside;
|
||||
}
|
||||
}
|
||||
return inside;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Math3D {
|
||||
public static float epsilon = 1e-6f;
|
||||
|
||||
public static boolean DoesLineCollideWithPoly(Vector3f Origin, Vector3f Point, Vector3f[] Vertices){
|
||||
Vector3f LineDirection = new Vector3f(Point).sub(Origin);
|
||||
float Test = Intersectionf.intersectRayTriangle(Origin,LineDirection,
|
||||
Vertices[0],Vertices[1],Vertices[2], epsilon);
|
||||
return(Test >= 0.0f && Test <= 1.0f);
|
||||
}
|
||||
|
||||
public static boolean ComplexLinePolyCollisionCheck(Vector3f Origin, Vector3f Point, Vector3f[] Vertices){
|
||||
Vector3f LineDirection = new Vector3f(Point).sub(Origin);
|
||||
float Test = Intersectionf.intersectRayTriangle(Origin,LineDirection,
|
||||
Vertices[0],Vertices[1],Vertices[2], epsilon);
|
||||
if(Test >= 0.0f && Test <= 1.0f) return true;
|
||||
|
||||
Vector3f edge1 = new Vector3f(Vertices[1]).sub(Vertices[0]);
|
||||
Vector3f edge2 = new Vector3f(Vertices[2]).sub(Vertices[0]);
|
||||
Vector3f normal = new Vector3f(edge1).cross(edge2).normalize();
|
||||
Vector3f pAFromV0 = new Vector3f(Origin).sub(Vertices[0]);
|
||||
Vector3f pBFromV0 = new Vector3f(Point).sub(Vertices[0]);
|
||||
boolean pAOnPlane = Math.abs(pAFromV0.dot(normal)) < epsilon;
|
||||
boolean pBOnPlane = Math.abs(pBFromV0.dot(normal)) < epsilon;
|
||||
|
||||
if (pAOnPlane && pBOnPlane) {
|
||||
if (Intersectionf.testPointInTriangle(Origin.x,Origin.y,Origin.z,
|
||||
Vertices[0].x,Vertices[0].y,Vertices[0].z,
|
||||
Vertices[1].x,Vertices[1].y,Vertices[1].z,
|
||||
Vertices[2].x,Vertices[2].y,Vertices[2].z) ||
|
||||
Intersectionf.testPointInTriangle(Point.x,Point.y,Point.z,
|
||||
Vertices[0].x,Vertices[0].y,Vertices[0].z,
|
||||
Vertices[1].x,Vertices[1].y,Vertices[1].z,
|
||||
Vertices[2].x,Vertices[2].y,Vertices[2].z)) {
|
||||
return true;
|
||||
}
|
||||
if (Intersectionf.testLineSegmentTriangle(Origin, Point, Vertices[0], Vertices[1],Vertices[2], epsilon)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Vector3f LineCollisionPointWithPoly(Vector3f Origin, Vector3f Point, Vector3f[] Vertices){
|
||||
Vector3f LineDirection = new Vector3f(Point).sub(Origin);
|
||||
float Test = Intersectionf.intersectRayTriangle(Origin,LineDirection,
|
||||
Vertices[0],Vertices[1],Vertices[2], epsilon);
|
||||
if (Test >= 0.0f && Test <= 1.0f) {
|
||||
return new Vector3f(LineDirection).mul(Test).add(Origin);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean DoesInfiniteLineCollideWithPoly(Vector3f LinePoint, Vector3f LineDirection, Vector3f[] Vertices){
|
||||
//forward test
|
||||
float Test = Intersectionf.intersectRayTriangle(LinePoint,LineDirection,
|
||||
Vertices[0],Vertices[1],Vertices[2], epsilon);
|
||||
if(Test >= 0.0f){
|
||||
return true;
|
||||
}
|
||||
//backward test
|
||||
Test = Intersectionf.intersectRayTriangle(LinePoint,new Vector3f(LineDirection.mul(-1f)),
|
||||
Vertices[0],Vertices[1],Vertices[2], epsilon);
|
||||
return Test >= 0.0f;
|
||||
}
|
||||
|
||||
public static Vector3f RayCastCollisionWithPolygon(Vector3f LinePoint, Vector3f LineDirection, Vector3f[] Vertices){
|
||||
//forward test
|
||||
float Test = Intersectionf.intersectRayTriangle(LinePoint,LineDirection,
|
||||
Vertices[0],Vertices[1],Vertices[2], epsilon);
|
||||
if(Test >= 0.0f){
|
||||
return new Vector3f(LineDirection).mul(Test).add(LinePoint);
|
||||
}
|
||||
//backward test
|
||||
Test = Intersectionf.intersectRayTriangle(LinePoint,new Vector3f(LineDirection.mul(-1f)),
|
||||
Vertices[0],Vertices[1],Vertices[2], epsilon);
|
||||
if(Test >= 0.0f){
|
||||
return new Vector3f(LineDirection).mul(-Test).add(LinePoint);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Vector3f CalculateNormal(Vector3f v1, Vector3f v2, Vector3f v3) {
|
||||
Vector3f U = new Vector3f(v2.sub(v1));
|
||||
Vector3f V = new Vector3f(v3.sub(v1));
|
||||
|
||||
Vector3f N = new Vector3f(U.mul(V));
|
||||
float Nx = (U.x * V.z) - (U.z * V.y);
|
||||
float Ny = (U.z * V.x) - (U.x * V.z);
|
||||
float Nz = (U.x * V.y) - (U.y * V.x);
|
||||
|
||||
float Length = (float) org.joml.Math.sqrt(T4Math.Square(Nx) + T4Math.Square(Ny) + T4Math.Square(Nz));
|
||||
return new Vector3f(Nx / Length, Ny / Length, Nz / Length);
|
||||
}
|
||||
|
||||
public static Vector3f GetScreenCoordFromWorldSpace(Vector3f worldPos, Matrix4f viewMatrix, Matrix4f projMatrix, int windowWidth, int windowHeight) {
|
||||
Matrix4f viewProj = new Matrix4f(projMatrix).mul(viewMatrix);
|
||||
Vector4f clipSpacePos = new Vector4f(worldPos, 1.0f).mul(viewProj);
|
||||
if (clipSpacePos.w <= 0.0f) {
|
||||
return null;
|
||||
}
|
||||
float ndcX = clipSpacePos.x / clipSpacePos.w;
|
||||
float ndcY = clipSpacePos.y / clipSpacePos.w;
|
||||
float ndcZ = clipSpacePos.z / clipSpacePos.w;
|
||||
if (ndcZ < -1.0f || ndcZ > 1.0f) return null;
|
||||
float screenX = ((ndcX + 1.0f) / 2.0f) * windowWidth;
|
||||
float screenY = ((1.0f - ndcY) / 2.0f) * windowHeight;
|
||||
return new Vector3f(screenX, screenY, ndcZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ public class EngineThread implements Runnable{
|
|||
Logger.debug("{} Thread Started",ThreadName);
|
||||
EngineAccuracy = EngineConfig.getInstance().getAccuracy();
|
||||
OriginalAccuracy = EngineAccuracy;
|
||||
while (running){
|
||||
while (running && !PrimaryRuntime.CanClose){
|
||||
long now = System.nanoTime();
|
||||
FrameTimes[0] = now - InitialTime;
|
||||
FrameTimes[1] += FrameTimes[0];
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ public class FastTickThread extends EngineThread {
|
|||
|
||||
@Override
|
||||
public void TickEvent(long nsTimeDiff){
|
||||
gameLogic.Input(PrimaryRuntime.GetEngineInstance(), (nsTimeDiff));
|
||||
gameLogic.UpdateFastThread(PrimaryRuntime.GetEngineInstance(), nsTimeDiff);
|
||||
}
|
||||
@Override
|
||||
|
|
@ -38,7 +37,7 @@ public class FastTickThread extends EngineThread {
|
|||
if (CappedToTickRate){
|
||||
TickThreshold = (double) 1000000000 / (double) TickRate;
|
||||
} else{
|
||||
TickThreshold = 0;
|
||||
TickThreshold = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DynamicMesh;
|
||||
|
||||
public class DeferredResource {
|
||||
public final long bufferHandle;
|
||||
public final long memoryHandle;
|
||||
public int framesLeft;
|
||||
|
||||
public DeferredResource(long bufferHandle, long memoryHandle, int framesLeft) {
|
||||
this.bufferHandle = bufferHandle;
|
||||
this.memoryHandle = memoryHandle;
|
||||
this.framesLeft = framesLeft;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DynamicMesh;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.vulkan.VkBufferCopy;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
|
||||
import static org.lwjgl.system.MemoryUtil.memByteBuffer;
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
|
||||
public class DynamicTerrainMesh {
|
||||
private final Device device;
|
||||
private long VertexBuffer;
|
||||
private long VertexBufferMemoryAlloc;
|
||||
private long IndexBuffer;
|
||||
private long IndexBufferMemoryAlloc;
|
||||
|
||||
private int VertexCount;
|
||||
private int IndexCount;
|
||||
private boolean IsDirty = true;
|
||||
|
||||
private float[] Positions;
|
||||
private float[] MaterialWeights;
|
||||
private int[] Indices;
|
||||
|
||||
public DynamicTerrainMesh(Device device, float[] InitialHeights, int Width, int Height){
|
||||
this.device = device;
|
||||
GenerateMeshGeometry(InitialHeights, Width, Height);
|
||||
InitVulkanBuffers();
|
||||
}
|
||||
|
||||
private void InitVulkanBuffers(){
|
||||
long VertexSize = (long) Positions.length * 4 + (long) MaterialWeights.length * 4;
|
||||
long IndexSize = (long)Indices.length * 4;
|
||||
LongBuffer longBuffer = LongBuffer.allocate(1);
|
||||
VertexBuffer = VulkanUtils.CreateBuffer(device, VertexSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, longBuffer);
|
||||
VertexBufferMemoryAlloc = longBuffer.get(0);
|
||||
IndexBuffer = VulkanUtils.CreateBuffer(device, IndexSize,
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, longBuffer);
|
||||
IndexBufferMemoryAlloc = longBuffer.get(0);
|
||||
}
|
||||
|
||||
private void GenerateMeshGeometry(float[] Heights, int w, int h){
|
||||
this.VertexCount = w * h;
|
||||
this.Positions = new float[VertexCount * 3];
|
||||
this.MaterialWeights = new float[VertexCount * 4];
|
||||
|
||||
for(int row = 0; row < h; row++){
|
||||
for(int column = 0; column < w; column++){
|
||||
int Index = row * w + column;
|
||||
|
||||
Positions[Index * 3] = column;
|
||||
Positions[Index * 3 + 1] = Heights[Index];
|
||||
Positions[Index * 3 + 2] = row;
|
||||
|
||||
MaterialWeights[Index * 4] = 1.0f; // Grass
|
||||
MaterialWeights[Index * 4 + 1] = 0.0f; // Rock
|
||||
MaterialWeights[Index * 4 + 2] = 0.0f; // Sand
|
||||
MaterialWeights[Index * 4 + 3] = 0.0f; // Mud
|
||||
}
|
||||
}
|
||||
|
||||
this.IndexCount = (w - 1) * (h - 1) * 6;
|
||||
this.Indices = new int[IndexCount];
|
||||
int CellPtr = 0;
|
||||
for (int row = 0; row < h - 1; row++) {
|
||||
for (int col = 0; col < w - 1; col++) {
|
||||
int TopLeft = row * w + col;
|
||||
int TopRight = TopLeft + 1;
|
||||
int BottomLeft = (row + 1) * w + col;
|
||||
int BottomRight = BottomLeft + 1;
|
||||
|
||||
Indices[CellPtr++] = TopLeft;
|
||||
Indices[CellPtr++] = BottomLeft;
|
||||
Indices[CellPtr++] = TopRight;
|
||||
Indices[CellPtr++] = TopRight;
|
||||
Indices[CellPtr++] = BottomLeft;
|
||||
Indices[CellPtr++] = BottomRight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateVertexRuntimeData(int index, float newHeight, float[] weights) {
|
||||
this.Positions[index * 3 + 1] = newHeight;
|
||||
System.arraycopy(weights, 0, this.MaterialWeights, index * 4, 4);
|
||||
this.IsDirty = true;
|
||||
}
|
||||
|
||||
public void StreamUpdatesToGPU(CommandBuffer cmdBuffer) {
|
||||
if (!IsDirty) return;
|
||||
|
||||
long vSize = (long) Positions.length * 4 + (long) MaterialWeights.length * 4;
|
||||
|
||||
long stagingBuffer;
|
||||
long stagingBufferMemory;
|
||||
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
LongBuffer pBuffer = stack.mallocLong(1);
|
||||
stagingBuffer = VulkanUtils.CreateBuffer(device, vSize,
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, pBuffer);
|
||||
stagingBufferMemory = pBuffer.get(0);
|
||||
|
||||
PointerBuffer pData = stack.pointers(VK_NULL_HANDLE);
|
||||
vkMapMemory(device.FetchVulkanDevice(), stagingBufferMemory, 0, vSize, 0, pData);
|
||||
long dataAddr = pData.get(0);
|
||||
|
||||
ByteBuffer buffer = memByteBuffer(dataAddr, (int) vSize);
|
||||
FloatBuffer floatBuffer = buffer.asFloatBuffer();
|
||||
|
||||
for (int i = 0; i < VertexCount; i++) {
|
||||
floatBuffer.put(Positions, i * 3, 3);
|
||||
floatBuffer.put(MaterialWeights, i * 4, 4);
|
||||
}
|
||||
|
||||
vkUnmapMemory(device.FetchVulkanDevice(), stagingBufferMemory);
|
||||
|
||||
VkBufferCopy.Buffer copyRegion = VkBufferCopy.calloc(1, stack)
|
||||
.srcOffset(0)
|
||||
.dstOffset(0)
|
||||
.size(vSize);
|
||||
|
||||
vkCmdCopyBuffer(cmdBuffer.GetVulkanCommandBuffer(), stagingBuffer, VertexBuffer, copyRegion);
|
||||
|
||||
this.IsDirty = false;
|
||||
|
||||
VulkanUtils.QueueForDeletion(stagingBuffer, stagingBufferMemory);
|
||||
}
|
||||
}
|
||||
|
||||
public long GetVertexBuffer() { return VertexBuffer; }
|
||||
public long GetIndexBuffer() { return IndexBuffer; }
|
||||
public int GetIndexCount() { return IndexCount; }
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo;
|
||||
import org.lwjgl.vulkan.VkVertexInputAttributeDescription;
|
||||
import org.lwjgl.vulkan.VkVertexInputBindingDescription;
|
||||
|
||||
import static org.lwjgl.vulkan.VK10.VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
import static org.lwjgl.vulkan.VK10.VK_FORMAT_R32G32_SFLOAT;
|
||||
import static org.lwjgl.vulkan.VK13.VK_FORMAT_R32G32B32_SFLOAT;
|
||||
import static org.lwjgl.vulkan.VK13.VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
|
||||
public class TerrainMeshVertexBufferStructure {
|
||||
public static final int TEXT_COORD_COMPONENTS = 2;
|
||||
public static final int NORMAL_COMPONENTS = 3;
|
||||
private static final int NUMBER_OF_ATTRIBUTES = 2;
|
||||
private final int POSITION_COMPONENTS = 3;
|
||||
|
||||
private final VkPipelineVertexInputStateCreateInfo VertexInput;
|
||||
private final VkVertexInputAttributeDescription.Buffer VertexInputAttributes;
|
||||
private final VkVertexInputBindingDescription.Buffer VertexInputBindings;
|
||||
|
||||
public TerrainMeshVertexBufferStructure(){
|
||||
VertexInputAttributes = VkVertexInputAttributeDescription.calloc(NUMBER_OF_ATTRIBUTES);
|
||||
VertexInputBindings = VkVertexInputBindingDescription.calloc(1);
|
||||
VertexInput = VkPipelineVertexInputStateCreateInfo.calloc();
|
||||
|
||||
int i =0;
|
||||
int Offset = 0;
|
||||
//vertex position
|
||||
VertexInputAttributes.get(i)
|
||||
.binding(0)
|
||||
.location(0)
|
||||
.format(VK_FORMAT_R32G32B32_SFLOAT)
|
||||
.offset(Offset);
|
||||
i++;
|
||||
Offset += POSITION_COMPONENTS * VulkanUtils.FLOAT_SIZE;
|
||||
//Material Weight Parameters
|
||||
VertexInputAttributes.get(i)
|
||||
.binding(0)
|
||||
.location(1)
|
||||
.format(VK_FORMAT_R32G32B32A32_SFLOAT)
|
||||
.offset(Offset);
|
||||
|
||||
int Stride = 7 * VulkanUtils.FLOAT_SIZE;
|
||||
VertexInputBindings.get(0)
|
||||
.binding(0)
|
||||
.stride(Stride)
|
||||
.inputRate(VK_VERTEX_INPUT_RATE_VERTEX);
|
||||
VertexInput
|
||||
.sType$Default()
|
||||
.pVertexAttributeDescriptions(VertexInputAttributes)
|
||||
.pVertexBindingDescriptions(VertexInputBindings);
|
||||
}
|
||||
public void cleanup(){
|
||||
VertexInput.free();
|
||||
VertexInputAttributes.free();
|
||||
}
|
||||
|
||||
public VkPipelineVertexInputStateCreateInfo getVertexInput(){
|
||||
return VertexInput;
|
||||
}
|
||||
}
|
||||
|
|
@ -13,12 +13,24 @@ public class VertexBufferStructure {
|
|||
public static final int TEXT_COORD_COMPONENTS = 2;
|
||||
public static final int NORMAL_COMPONENTS = 3;
|
||||
private static final int NUMBER_OF_ATTRIBUTES = 5;
|
||||
private final int POSITION_COMPONENTS = 3;
|
||||
private static final int POSITION_COMPONENTS = 3;
|
||||
public static int VertexInputSize = 5 * VulkanUtils.FLOAT_SIZE;
|
||||
|
||||
private final VkPipelineVertexInputStateCreateInfo VertexInput;
|
||||
private final VkVertexInputAttributeDescription.Buffer VertexInputAttributes;
|
||||
private final VkVertexInputBindingDescription.Buffer VertexInputBindings;
|
||||
|
||||
public static int GetVertexInputSize(){
|
||||
int Offset = 0;
|
||||
Offset += POSITION_COMPONENTS * VulkanUtils.FLOAT_SIZE;
|
||||
Offset += NORMAL_COMPONENTS * VulkanUtils.FLOAT_SIZE;
|
||||
Offset += NORMAL_COMPONENTS * VulkanUtils.FLOAT_SIZE;
|
||||
Offset += NORMAL_COMPONENTS * VulkanUtils.FLOAT_SIZE;
|
||||
Offset += TEXT_COORD_COMPONENTS * VulkanUtils.FLOAT_SIZE;
|
||||
VertexInputSize = Offset;
|
||||
return VertexInputSize;
|
||||
}
|
||||
|
||||
public VertexBufferStructure(){
|
||||
VertexInputAttributes = VkVertexInputAttributeDescription.calloc(NUMBER_OF_ATTRIBUTES);
|
||||
VertexInputBindings = VkVertexInputBindingDescription.calloc(1);
|
||||
|
|
|
|||
|
|
@ -7,10 +7,15 @@ public class ModelBinaryData {
|
|||
private final DataOutputStream IndexOutput;
|
||||
private final String VertexFilePath;
|
||||
private final DataOutputStream VertexOutput;
|
||||
private final String CollisionVertexFilePath;
|
||||
private final DataOutputStream CollisionVertexOutput;
|
||||
private int IndexOffset;
|
||||
private int CollisionOffset;
|
||||
private int VertexOffset;
|
||||
|
||||
public ModelBinaryData(String ModelPath) throws FileNotFoundException{
|
||||
CollisionVertexFilePath = ModelPath.substring(0,ModelPath.lastIndexOf('.')) + ".colmesh";
|
||||
CollisionVertexOutput = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(CollisionVertexFilePath)));
|
||||
VertexFilePath = ModelPath.substring(0,ModelPath.lastIndexOf('.')) + ".vtx";
|
||||
VertexOutput = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(VertexFilePath)));
|
||||
IndexFilePath= ModelPath.substring(0,ModelPath.lastIndexOf('.')) + ".idx";
|
||||
|
|
@ -28,8 +33,12 @@ public class ModelBinaryData {
|
|||
public String GetVertexFilePath(){return VertexFilePath;}
|
||||
public int GetVertexOffset(){return VertexOffset;}
|
||||
public DataOutputStream GetVertexOutput(){return VertexOutput;}
|
||||
public String GetCollisionVertexFilePath(){return CollisionVertexFilePath;}
|
||||
public int GetCollisionVertexOffset(){return CollisionOffset;}
|
||||
public DataOutputStream GetCollisionVertexOutput(){return CollisionVertexOutput;}
|
||||
public void IncrementIndexOffset(int Increment){
|
||||
IndexOffset+=Increment;
|
||||
}
|
||||
public void IncrementVertexOffset(int Increment){VertexOffset+=Increment;}
|
||||
public void IncrementCollisionVertexOffset(int Increment){VertexOffset+=Increment;}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,9 +74,7 @@ public class ModelsCache {
|
|||
try (MemoryStack MemStack = MemoryStack.stackPush()) {
|
||||
LongBuffer pBuffers = MemStack.longs(vkBufferHandle);
|
||||
LongBuffer pOffsets = MemStack.longs(0);
|
||||
|
||||
vkCmdBindVertexBuffers(commandHandle, 0, pBuffers, pOffsets);
|
||||
|
||||
vkCmdDraw(commandHandle, 36, 1, 0, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel;
|
||||
|
||||
public class ProceduralMesh {
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
|||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DynamicMesh.DynamicTerrainMesh;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.DefaultPipeline;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.*;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Pipeline;
|
||||
|
|
@ -30,6 +31,8 @@ import java.nio.ByteBuffer;
|
|||
import java.nio.LongBuffer;
|
||||
import java.util.*;
|
||||
|
||||
import static org.lwjgl.system.MemoryUtil.memAllocLong;
|
||||
import static org.lwjgl.system.MemoryUtil.memFree;
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
||||
|
|
@ -297,6 +300,10 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
|||
|
||||
public void Render(EngineInstance engineInstance,VulkanContext vulkanContext, CommandBuffer commandBuffer, ModelsCache modelsCache,MaterialsCache materialsCache, int CurrentFrame){
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
|
||||
// DynamicTerrainMesh terrainMesh = engineInstance.scene().GetTerrainMesh();
|
||||
// terrainMesh.StreamUpdatesToGPU(commandBuffer);
|
||||
|
||||
VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer();
|
||||
|
||||
List<Attachment> attachments = MRTAttachments.GetColourAttachments();
|
||||
|
|
@ -338,6 +345,20 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
|||
|
||||
VulkanUtils.CopyMatrixToBuffer(vulkanContext, BufferViewMatrices[CurrentFrame],engineInstance.scene().GetCamera().GetViewMatrix(), 0); // here
|
||||
|
||||
/* LongBuffer vBuffers = memAllocLong(1).put(0, terrainMesh.GetVertexBuffer());
|
||||
LongBuffer offsets = memAllocLong(1).put(0, 0L);
|
||||
|
||||
vkCmdBindVertexBuffers(commandBuffer.GetVulkanCommandBuffer(), 0, vBuffers, offsets);
|
||||
vkCmdBindIndexBuffer(commandBuffer.GetVulkanCommandBuffer(), terrainMesh.GetIndexBuffer(), 0, VK_INDEX_TYPE_UINT32);
|
||||
|
||||
// Draw the procedural geometry primitives
|
||||
vkCmdDrawIndexed(commandBuffer.GetVulkanCommandBuffer(), terrainMesh.GetIndexCount(), 1, 0, 0, 0);
|
||||
|
||||
memFree(vBuffers);
|
||||
memFree(offsets);
|
||||
*/
|
||||
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, DualPassRendering ? VkPipelineOpaque.GetVulkanPipeline() : VkPipeline.GetVulkanPipeline());
|
||||
|
||||
DescriptorAllocator descriptorAllocator = vulkanContext.GetDescriptorAllocator();
|
||||
LongBuffer DescriptorSets = MemStack.mallocLong(4)
|
||||
.put(0,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_PRJ).GetVkDescriptorSet())
|
||||
|
|
@ -370,8 +391,6 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
|||
if(DualPassRendering) {
|
||||
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineTranslucent.GetVulkanPipeline());
|
||||
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineTranslucent.GetVulkanPipelineLayout(), 0, DescriptorSets, null);
|
||||
//vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineOpaque.GetVulkanPipeline());
|
||||
//vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineOpaque.GetVulkanPipelineLayout(), 0, DescriptorSets, null);
|
||||
} else{
|
||||
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipeline.GetVulkanPipeline());
|
||||
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null);
|
||||
|
|
@ -500,7 +519,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
|||
AttachmentInfoDepth.free();
|
||||
MRTAttachments.CleanUp(VkCtx);
|
||||
AttachmentInfoColour.free();
|
||||
MemoryUtil.memFree(PushConstBuffer);
|
||||
memFree(PushConstBuffer);
|
||||
ClearValueDepth.free();
|
||||
ClearValueColour.free();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Util;
|
|||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DynamicMesh.DeferredResource;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorAllocator;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSet;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSetLayout;
|
||||
|
|
@ -15,10 +16,10 @@ import org.tinylog.Logger;
|
|||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
|
||||
|
|
@ -37,12 +38,103 @@ public class VulkanUtils {
|
|||
public static final int VEC2_SIZE = 2 * FLOAT_SIZE;
|
||||
public static final int SHORT_LENGTH = 2;
|
||||
|
||||
private static final List<DeferredResource> DeletionQueue = new ArrayList<>();
|
||||
|
||||
public static void QueueForDeletion(long bufferHandle, long memoryHandle) {
|
||||
synchronized (DeletionQueue) {
|
||||
DeletionQueue.add(new DeferredResource(bufferHandle, memoryHandle, MAX_IN_FLIGHT));
|
||||
}
|
||||
}
|
||||
|
||||
public static void ProcessDeferredDeletionQueue(Device device) {
|
||||
VkDevice vkDevice = device.FetchVulkanDevice();
|
||||
|
||||
synchronized (DeletionQueue) {
|
||||
Iterator<DeferredResource> iterator = DeletionQueue.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
DeferredResource resource = iterator.next();
|
||||
resource.framesLeft--;
|
||||
if (resource.framesLeft <= 0) {
|
||||
if (resource.bufferHandle != VK_NULL_HANDLE) {
|
||||
vkDestroyBuffer(vkDevice, resource.bufferHandle, null);
|
||||
}
|
||||
if (resource.memoryHandle != VK_NULL_HANDLE) {
|
||||
vkFreeMemory(vkDevice, resource.memoryHandle, null);
|
||||
}
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void CleanUpRemaining(Device device) {
|
||||
VkDevice vkDevice = device.FetchVulkanDevice();
|
||||
synchronized (DeletionQueue) {
|
||||
for (DeferredResource resource : DeletionQueue) {
|
||||
vkDestroyBuffer(vkDevice, resource.bufferHandle, null);
|
||||
vkFreeMemory(vkDevice, resource.memoryHandle, null);
|
||||
}
|
||||
DeletionQueue.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static void CopyMatrixToBuffer(VulkanContext VkCtx, VulkanBuffer VkBuffer, Matrix4f matrix, int Offset){
|
||||
long MappedMemory = VkBuffer.MapMemory(VkCtx);
|
||||
ByteBuffer matrixBuffer = MemoryUtil.memByteBuffer(MappedMemory, (int)VkBuffer.GetRequestedSize());
|
||||
matrix.get(Offset, matrixBuffer);
|
||||
VkBuffer.UnMapMemory(VkCtx);
|
||||
}
|
||||
|
||||
public static long CreateBuffer(Device device, long size, int usage, int requirementsMask, LongBuffer pMemoryOut) {
|
||||
VkDevice vkDevice = device.FetchVulkanDevice();
|
||||
long bufferHandle;
|
||||
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
VkBufferCreateInfo bufferInfo = VkBufferCreateInfo.calloc(stack)
|
||||
.sType(VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO)
|
||||
.size(size)
|
||||
.usage(usage)
|
||||
.sharingMode(VK_SHARING_MODE_EXCLUSIVE);
|
||||
|
||||
LongBuffer pBuffer = stack.mallocLong(1);
|
||||
int err = vkCreateBuffer(vkDevice, bufferInfo, null, pBuffer);
|
||||
if (err != VK_SUCCESS) {
|
||||
throw new RuntimeException("Failed to create Vulkan buffer. Error code: " + err);
|
||||
}
|
||||
bufferHandle = pBuffer.get(0);
|
||||
|
||||
VkMemoryRequirements memRequirements = VkMemoryRequirements.calloc(stack);
|
||||
vkGetBufferMemoryRequirements(vkDevice, bufferHandle, memRequirements);
|
||||
|
||||
VkMemoryAllocateInfo allocInfo = VkMemoryAllocateInfo.calloc(stack)
|
||||
.sType(VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO)
|
||||
.allocationSize(memRequirements.size())
|
||||
.memoryTypeIndex(findMemoryType(device, memRequirements.memoryTypeBits(), requirementsMask));
|
||||
|
||||
int allocErr = vkAllocateMemory(vkDevice, allocInfo, null, pMemoryOut);
|
||||
if (allocErr != VK_SUCCESS) {
|
||||
throw new RuntimeException("Failed to allocate Vulkan buffer memory. Error code: " + allocErr);
|
||||
}
|
||||
|
||||
vkBindBufferMemory(vkDevice, bufferHandle, pMemoryOut.get(0), 0);
|
||||
}
|
||||
|
||||
return bufferHandle;
|
||||
}
|
||||
|
||||
private static int findMemoryType(Device device, int typeFilter, int properties) {
|
||||
VkPhysicalDeviceMemoryProperties memProperties = VkPhysicalDeviceMemoryProperties.calloc();
|
||||
vkGetPhysicalDeviceMemoryProperties(device.FetchVulkanDevice().getPhysicalDevice(), memProperties);
|
||||
|
||||
for (int i = 0; i < memProperties.memoryTypeCount(); i++) {
|
||||
if ((typeFilter & (1 << i)) != 0 &&
|
||||
(memProperties.memoryTypes(i).propertyFlags() & properties) == properties) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Failed to find suitable memory type for buffer allocation!");
|
||||
}
|
||||
|
||||
public static VulkanBuffer CreateRawVertexAttrBuffer(VulkanContext VkCtx, long BufferSize) {
|
||||
return new VulkanBuffer(
|
||||
VkCtx,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue