it renders but not properly
BIN
resources/EngineResources/Texture/DefaultTexture.png
Normal file
|
After Width: | Height: | Size: 925 B |
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"id": "cube",
|
||||
"meshes": [
|
||||
{
|
||||
"id": "cubemtl_0",
|
||||
"material_id": "cube-mat-1",
|
||||
"offset_vtx": 0,
|
||||
"vtx_size": 480,
|
||||
"offset_idx": 0,
|
||||
"idx_size": 144
|
||||
}
|
||||
],
|
||||
"vtx_path": "resources/models/cube/cube.vtx",
|
||||
"idx_path": "resources/models/cube/cube.idx"
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
[
|
||||
{
|
||||
"id": "cube-mat-0",
|
||||
"texture_path": "",
|
||||
"diffuse_color": {
|
||||
"x": 0.6,
|
||||
"y": 0.6,
|
||||
"z": 0.6,
|
||||
"w": 1.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "cube-mat-1",
|
||||
"texture_path": "resources/models/cube/cube.png",
|
||||
"diffuse_color": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0,
|
||||
"w": 1.0
|
||||
}
|
||||
}
|
||||
]
|
||||
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 153 KiB |
15
resources/models/cube/cube.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"ID": "cube",
|
||||
"Meshes": [
|
||||
{
|
||||
"ID": "cubemtl_0",
|
||||
"MaterialID": "cube-mat-1",
|
||||
"OffsetVertex": 0,
|
||||
"VertexSize": 480,
|
||||
"OffsetIndex": 0,
|
||||
"IndexSize": 144
|
||||
}
|
||||
],
|
||||
"VertexPath": "resources/models/cube/cube.vtx",
|
||||
"IndexPath": "resources/models/cube/cube.idx"
|
||||
}
|
||||
BIN
resources/models/cube/cube.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
22
resources/models/cube/cube_mat.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
[
|
||||
{
|
||||
"ID": "cube-mat-0",
|
||||
"TexturePath": "",
|
||||
"DiffuseColour": {
|
||||
"X": 0.6,
|
||||
"Y": 0.6,
|
||||
"Z": 0.6,
|
||||
"W": 1.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "cube-mat-1",
|
||||
"TexturePath": "resources/models/cube/cube.png",
|
||||
"DiffuseColour": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0,
|
||||
"w": 1.0
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec3 inPos;
|
||||
layout(location = 1) in vec2 intTextCoords;
|
||||
layout(location = 1) in vec2 inTextCoords;
|
||||
layout(location = 0) out vec2 outTextCoords;
|
||||
|
||||
|
||||
|
|
@ -16,5 +16,5 @@ layout(push_constant) uniform pc{
|
|||
void main()
|
||||
{
|
||||
gl_Position = projUniform.matrix * push_constants.modelMatrix * vec4(inPos,1);
|
||||
outTextCoords = intTextCoords;
|
||||
outTextCoords = inTextCoords;
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import static org.lwjgl.stb.STBImage.stbi_load;
|
|||
|
||||
public class GLFWImageParser {
|
||||
|
||||
private ByteBuffer image;
|
||||
private final ByteBuffer image;
|
||||
private int GLFW_Width, GLFW_Height, ImageChannels;
|
||||
|
||||
GLFWImageParser(int width, int height, ByteBuffer image, int ImageChannels) {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class EngineConfig {
|
|||
private String PhysicalDeviceName;
|
||||
private int RequestedImages;
|
||||
private String IconPath = "/WindowResources/Icon/";
|
||||
private String DefaultTexturePath = "Resources/EngineResources/Texture/DefaultTexture.png";
|
||||
private String DefaultTexturePath = "resources/EngineResources/Texture/DefaultTexture.png";
|
||||
private String IconName = "ProgramIcon.png";
|
||||
private float FOV = 60f;
|
||||
private float zFarPlane;
|
||||
|
|
|
|||
|
|
@ -22,11 +22,12 @@ public class ModelLoader { // Model Utility class kinda like a model version of
|
|||
var Result = new ArrayList<MaterialData>();
|
||||
try{
|
||||
String content = new String(Files.readAllBytes(Paths.get(Path)));
|
||||
var gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||
var gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
|
||||
Result.addAll(Arrays.asList(gson.fromJson(content,MaterialData[].class)));
|
||||
}catch(Exception e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
Logger.debug("Loaded Material Data: [{}]",Result.toString());
|
||||
return Result;
|
||||
}
|
||||
public static ModelData LoadModel(String Path){
|
||||
|
|
@ -34,11 +35,12 @@ public class ModelLoader { // Model Utility class kinda like a model version of
|
|||
ModelData Result;
|
||||
try{
|
||||
String content = new String(Files.readAllBytes(Paths.get(Path)));
|
||||
var gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||
var gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
|
||||
Result = gson.fromJson(content,ModelData.class);
|
||||
}catch(Exception e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
Logger.debug("Loaded Model Data: [{}]",Result.toString());
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,10 @@ public class GameCore implements GameLogic {
|
|||
ModelData SloopModel = ModelLoader.LoadModel("resources/Models/Cube/cube.json");
|
||||
models.add(SloopModel);
|
||||
Logger.trace(SloopModel.ID());
|
||||
Actor SloopActor = new Actor("CubeEntity",SloopModel.ID(),new Vector3f(0.0f,0.0f,-20.0f));
|
||||
Actor SloopActor = new Actor("CubeEntity",SloopModel.ID(),new Vector3f(0.0f,0.0f,-10.0f));
|
||||
angles.add(34F);
|
||||
Velocities.add(new Vector3f(0,0,0));
|
||||
CubeActors.add(SloopActor);
|
||||
scene.AddActor(SloopActor);
|
||||
|
||||
List<MaterialData> materials = new ArrayList<>(ModelLoader.LoadMaterials("resources/Models/Cube/cube_mat.json"));
|
||||
|
|
|
|||
|
|
@ -3,23 +3,38 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline;
|
|||
import net.halbear.Terrain4J.EngineCore.Display.GLFWImageParser;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.ImageSrc;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import static org.lwjgl.stb.STBImage.stbi_image_free;
|
||||
import static org.lwjgl.stb.STBImage.stbi_load;
|
||||
import static org.lwjgl.stb.STBImage.*;
|
||||
|
||||
public class GraphUtils {
|
||||
private GraphUtils(){ }
|
||||
|
||||
public static void CleanImageData(ImageSrc imageSrc){
|
||||
Logger.debug("Loading Image Data [{}]",imageSrc.data());
|
||||
stbi_image_free(imageSrc.data());
|
||||
}
|
||||
|
||||
public static ImageSrc LoadImage(String Filename) throws IOException{
|
||||
GLFWImageParser image = GLFWImageParser.LoadImage(Filename);
|
||||
return new ImageSrc(image.GetImage(), image.GetWidth(), image.GetHeight(), image.GetChannels());
|
||||
Logger.debug("Loading Image [{}]",Filename);
|
||||
ImageSrc newImage;
|
||||
ByteBuffer image;
|
||||
try (MemoryStack MemStack = MemoryStack.stackPush()) {
|
||||
IntBuffer channels = MemStack.mallocInt(1);
|
||||
IntBuffer width = MemStack.mallocInt(1);
|
||||
IntBuffer height = MemStack.mallocInt(1);
|
||||
image = stbi_load(Filename, width, height, channels, 4);
|
||||
if (image == null) {
|
||||
Logger.error("Could not load or find image inputted.");
|
||||
throw new IOException("Image file [" + Filename + "] not loaded: " + stbi_failure_reason());
|
||||
}
|
||||
newImage = new ImageSrc(image, width.get(0), height.get(0), channels.get(0));
|
||||
}
|
||||
Logger.debug("Loaded Buffer [{}]",image);
|
||||
return newImage ;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import org.tinylog.Logger;
|
|||
import org.w3c.dom.Text;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
|
|
@ -49,16 +50,18 @@ public class MaterialsCache {
|
|||
String TexturePath = Material.TexturePath();
|
||||
boolean ValidTexture = TexturePath != null && !TexturePath.isEmpty();
|
||||
if(ValidTexture){
|
||||
Logger.debug("Loading Texture [{}]",TexturePath);
|
||||
textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB);
|
||||
}
|
||||
VulkanMaterial newMaterial = new VulkanMaterial(Material.ID());
|
||||
MaterialsMap.put(newMaterial.ID(), newMaterial);
|
||||
Logger.trace(Material.toString());
|
||||
Material.DiffuseColour().get(Offset, data);
|
||||
Logger.debug("Set Diffuse Colour -> [{}]",Material.DiffuseColour());
|
||||
data.putInt(Offset + VulkanUtils.VEC4_SIZE, ValidTexture ? 1 : 0);
|
||||
data.putInt(Offset + VulkanUtils.VEC4_SIZE + VulkanUtils.INT_SIZE, textureCache.GetPosition(TexturePath));
|
||||
//pad data because the minimum size of data in the shader layout is a multiple of Vec4,
|
||||
// compensate with 2 more bytes as we only need 6 currently
|
||||
// compensate with 2 more as we only need 6 currently
|
||||
data.putInt(Offset + VulkanUtils.VEC4_SIZE + VulkanUtils.INT_SIZE * 2,0);
|
||||
data.putInt(Offset + VulkanUtils.VEC4_SIZE + VulkanUtils.INT_SIZE * 3,0);
|
||||
Offset += MATERIAL_SIZE;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel;
|
||||
|
||||
public record MeshData(String ID, String MaterialID, int offsetVertex, int VertexSize, int OffsetIndex, int IndexSize) {
|
||||
public record MeshData(String ID, String MaterialID, int OffsetVertex, int VertexSize, int OffsetIndex, int IndexSize) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
public record ModelData(String ID, List<MeshData> Meshes, String vertexPath, String indexPath) {
|
||||
public record ModelData(String ID, List<MeshData> Meshes, String VertexPath, String IndexPath) {
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Queues.Que
|
|||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.DataInputStream;
|
||||
|
|
@ -39,9 +40,9 @@ public class ModelsCache {
|
|||
ModelsMap.put(VKModel.GetID(), VKModel);
|
||||
|
||||
DataInputStream VertexInput = new DataInputStream(new BufferedInputStream(
|
||||
new FileInputStream(modelData.vertexPath())));
|
||||
new FileInputStream(modelData.VertexPath())));
|
||||
DataInputStream IndicesInput = new DataInputStream(new BufferedInputStream(
|
||||
new FileInputStream(modelData.indexPath())));
|
||||
new FileInputStream(modelData.IndexPath())));
|
||||
|
||||
for (MeshData meshData : modelData.Meshes()) {
|
||||
TransferBuffer VerticesBuffers = CreateVerticesBuffer(VkCtx, meshData,VertexInput);
|
||||
|
|
@ -50,6 +51,7 @@ public class ModelsCache {
|
|||
StagingBufferList.add(IndicesBuffers.SrcBuffer());
|
||||
VerticesBuffers.RecordTransferCommand(Command);
|
||||
IndicesBuffers.RecordTransferCommand(Command);
|
||||
Logger.debug("Creating new Vulkan Mesh -> ID=[{}] MaterialID=[{}]",meshData.ID(),meshData.MaterialID());
|
||||
VulkanMesh VkMesh = new VulkanMesh(meshData.ID(), VerticesBuffers.DstBuffer(), IndicesBuffers.DstBuffer(),
|
||||
meshData.IndexSize() / VulkanUtils.INT_SIZE, meshData.MaterialID());
|
||||
VKModel.GetVkMeshList().add(VkMesh);
|
||||
|
|
@ -66,17 +68,24 @@ public class ModelsCache {
|
|||
}
|
||||
|
||||
private static TransferBuffer CreateVerticesBuffer(VulkanContext VkCtx, MeshData meshData, DataInputStream VertexStream) throws IOException {
|
||||
|
||||
Logger.debug("Creating Vertices Transfer Buffer, Mesh Data -> ID=[{}] VertexSize=[{}]",meshData.ID(),meshData.VertexSize());
|
||||
int BufferSize = meshData.VertexSize();
|
||||
var SrcBuffer = new VulkanBuffer(VkCtx,BufferSize,
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
var DstBuffer = new VulkanBuffer(VkCtx, BufferSize,
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
|
||||
if (BufferSize <= 0) {
|
||||
Logger.error("Computed buffer allocation size cannot be 0. SrcBuffer -> [{}] DstBuffer -> [{}]",SrcBuffer,DstBuffer);
|
||||
throw new RuntimeException("Computed buffer allocation size cannot be 0. SrcBuffer -> ["+SrcBuffer+"] DstBuffer -> ["+DstBuffer+"]");
|
||||
}
|
||||
long MappedMemory = SrcBuffer.MapMemory(VkCtx);
|
||||
FloatBuffer data = MemoryUtil.memFloatBuffer(MappedMemory, (int) SrcBuffer.GetRequestedSize());
|
||||
|
||||
int ValuesToRead = meshData.VertexSize()/VulkanUtils.FLOAT_SIZE;
|
||||
if (ValuesToRead <= 0) {
|
||||
Logger.error("Cannot allocate vertex buffer: Model mesh has 0 or negative vertices! Vertex Stream -> [{}]",VertexStream);
|
||||
throw new RuntimeException("Cannot allocate vertex buffer: Model mesh has 0 or negative vertices! Vertex Stream -> [{"+VertexStream+"]");
|
||||
}
|
||||
while(ValuesToRead > 0){
|
||||
data.put(VertexStream.readFloat());
|
||||
ValuesToRead--;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,14 @@ public class VulkanBuffer {
|
|||
AllocationSize = MemoryAllocation.allocationSize();
|
||||
Memory = LongPointer.get(0);
|
||||
pointerBuffer = MemoryUtil.memAllocPointer(1);
|
||||
|
||||
if (Buffer == 0) {
|
||||
Logger.error("Vulkan crash blocked: Native bufferHandle cannot be 0!");
|
||||
throw new IllegalArgumentException("Vulkan crash blocked: Native bufferHandle cannot be 0!");
|
||||
}
|
||||
if (Memory == 0) {
|
||||
Logger.error("Vulkan crash blocked: Native memoryHandle cannot be 0! Device out of memory or allocation failed.");
|
||||
throw new IllegalArgumentException("Vulkan crash blocked: Native memoryHandle cannot be 0! Device out of memory or allocation failed.");
|
||||
}
|
||||
vkCheck(vkBindBufferMemory(device.FetchVulkanDevice(),Buffer,Memory,0),"Failed to Bind Vulkan Memory Buffer");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ vkValidated=true
|
|||
vsync=false
|
||||
#Vsync images
|
||||
RequestedImages=3
|
||||
DefaultTexturePath=Resources/EngineResources/Texture/DefaultTexture.png
|
||||
DefaultTexturePath=resources/EngineResources/Texture/DefaultTexture.png
|
||||
#This is the name of the GPU you want the engine to use
|
||||
PhysicalDeviceName=
|
||||
|
||||
|
|
|
|||