diff --git a/src/main/java/com/github/hydos/ginger/VulkanLitecraft.java b/src/main/java/com/github/hydos/ginger/VulkanLitecraft.java index 9517c4f..9e0ce5d 100644 --- a/src/main/java/com/github/hydos/ginger/VulkanLitecraft.java +++ b/src/main/java/com/github/hydos/ginger/VulkanLitecraft.java @@ -1,6 +1,7 @@ package com.github.hydos.ginger; import static java.util.stream.Collectors.toSet; +import static org.lwjgl.assimp.Assimp.*; import static org.lwjgl.glfw.GLFW.*; import static org.lwjgl.glfw.GLFWVulkan.*; import static org.lwjgl.stb.STBImage.*; @@ -11,6 +12,7 @@ import static org.lwjgl.vulkan.KHRSurface.*; import static org.lwjgl.vulkan.KHRSwapchain.*; import static org.lwjgl.vulkan.VK10.*; +import java.io.File; import java.lang.Math; import java.net.*; import java.nio.*; @@ -25,9 +27,9 @@ import org.lwjgl.vulkan.*; import com.github.hydos.ginger.engine.common.info.RenderAPI; import com.github.hydos.ginger.engine.common.io.Window; -import com.github.hydos.ginger.engine.common.obj.*; import com.github.hydos.ginger.engine.vulkan.misc.*; -import com.github.hydos.ginger.engine.vulkan.model.VKVertex; +import com.github.hydos.ginger.engine.vulkan.misc.ModelLoader.Model; +import com.github.hydos.ginger.engine.vulkan.pipelines.VKPipelineManager; import com.github.hydos.ginger.engine.vulkan.swapchain.VKSwapchainManager; public class VulkanLitecraft { @@ -122,6 +124,66 @@ public class VulkanLitecraft { } } + public static class Vertex { + + private static final int SIZEOF = (3 + 3 + 2) * Float.BYTES; + private static final int OFFSETOF_POS = 0; + private static final int OFFSETOF_COLOR = 3 * Float.BYTES; + private static final int OFFSETOF_TEXTCOORDS = (3 + 3) * Float.BYTES; + + private Vector3fc pos; + private Vector3fc color; + private Vector2fc texCoords; + + public Vertex(Vector3fc pos, Vector3fc color, Vector2fc texCoords) { + this.pos = pos; + this.color = color; + this.texCoords = texCoords; + } + + public static VkVertexInputBindingDescription.Buffer getBindingDescription() { + + VkVertexInputBindingDescription.Buffer bindingDescription = + VkVertexInputBindingDescription.callocStack(1); + + bindingDescription.binding(0); + bindingDescription.stride(Vertex.SIZEOF); + bindingDescription.inputRate(VK_VERTEX_INPUT_RATE_VERTEX); + + return bindingDescription; + } + + public static VkVertexInputAttributeDescription.Buffer getAttributeDescriptions() { + + VkVertexInputAttributeDescription.Buffer attributeDescriptions = + VkVertexInputAttributeDescription.callocStack(3); + + // Position + VkVertexInputAttributeDescription posDescription = attributeDescriptions.get(0); + posDescription.binding(0); + posDescription.location(0); + posDescription.format(VK_FORMAT_R32G32B32_SFLOAT); + posDescription.offset(OFFSETOF_POS); + + // Color + VkVertexInputAttributeDescription colorDescription = attributeDescriptions.get(1); + colorDescription.binding(0); + colorDescription.location(1); + colorDescription.format(VK_FORMAT_R32G32B32_SFLOAT); + colorDescription.offset(OFFSETOF_COLOR); + + // Texture coordinates + VkVertexInputAttributeDescription texCoordsDescription = attributeDescriptions.get(2); + texCoordsDescription.binding(0); + texCoordsDescription.location(2); + texCoordsDescription.format(VK_FORMAT_R32G32_SFLOAT); + texCoordsDescription.offset(OFFSETOF_TEXTCOORDS); + + return attributeDescriptions.rewind(); + } + + } + // ======= FIELDS ======= // private VkInstance instance; @@ -165,7 +227,7 @@ public class VulkanLitecraft { private static long textureImageView; private static long textureSampler; - private VKVertex[] vertices; + private Vertex[] vertices; public static int[] indices; private static long vertexBuffer; private long vertexBufferMemory; @@ -1145,23 +1207,27 @@ public class VulkanLitecraft { private void loadModel() { - Mesh optimisedMesh = ModelLoader.getCubeMesh(); + File modelFile = new File(ClassLoader.getSystemClassLoader().getResource("models/chalet.obj").getFile()); - final int vertexCount = optimisedMesh.vertices.length; + Model model = ModelLoader.loadModel(modelFile, aiProcess_FlipUVs | aiProcess_DropNormals); - vertices = new VKVertex[vertexCount]; + final int vertexCount = model.positions.size(); + + vertices = new Vertex[vertexCount]; final Vector3fc color = new Vector3f(1.0f, 1.0f, 1.0f); for(int i = 0;i < vertexCount;i++) { - System.out.println(optimisedMesh.positions.get(i)); - vertices[i] = new VKVertex(optimisedMesh.positions.get(i), color, optimisedMesh.texCoords.get(i)); + vertices[i] = new Vertex( + model.positions.get(i), + color, + model.texCoords.get(i)); } - indices = new int[optimisedMesh.indices.length]; + indices = new int[model.indices.size()]; for(int i = 0;i < indices.length;i++) { - indices[i] = optimisedMesh.indices.length; + indices[i] = model.indices.get(i); } } @@ -1169,7 +1235,7 @@ public class VulkanLitecraft { try(MemoryStack stack = stackPush()) { - long bufferSize = VKVertex.SIZEOF * vertices.length; + long bufferSize = Vertex.SIZEOF * vertices.length; LongBuffer pBuffer = stack.mallocLong(1); LongBuffer pBufferMemory = stack.mallocLong(1); @@ -1452,8 +1518,8 @@ public class VulkanLitecraft { } } - private void memcpy(ByteBuffer buffer, VKVertex[] vertices) { - for(VKVertex vertex : vertices) { + private void memcpy(ByteBuffer buffer, Vertex[] vertices) { + for(Vertex vertex : vertices) { buffer.putFloat(vertex.pos.x()); buffer.putFloat(vertex.pos.y()); buffer.putFloat(vertex.pos.z()); diff --git a/src/main/java/com/github/hydos/ginger/engine/common/obj/Mesh.java b/src/main/java/com/github/hydos/ginger/engine/common/obj/Mesh.java index 73b130d..29f4c37 100644 --- a/src/main/java/com/github/hydos/ginger/engine/common/obj/Mesh.java +++ b/src/main/java/com/github/hydos/ginger/engine/common/obj/Mesh.java @@ -2,11 +2,12 @@ package com.github.hydos.ginger.engine.common.obj; public class Mesh { - public float[] vertices; - public float[] textureCoords; - public float[] normals; - public int[] indices; - public float furthestPoint; + private float[] vertices; + private float[] textureCoords; + private float[] normals; + private int[] indices; + private float furthestPoint; + public Vertex[] vkVertices;//may not be set only used for vulkan public Mesh(float[] vertices, float[] textureCoords, float[] normals, int[] indices, float furthestPoint) @@ -18,9 +19,6 @@ public class Mesh this.furthestPoint = furthestPoint; } - public Mesh() - {} - public float getFurthestPoint() { return furthestPoint; } diff --git a/src/main/java/com/github/hydos/ginger/engine/common/obj/ModelLoader.java b/src/main/java/com/github/hydos/ginger/engine/common/obj/ModelLoader.java index d2cd7b0..e0b14ca 100644 --- a/src/main/java/com/github/hydos/ginger/engine/common/obj/ModelLoader.java +++ b/src/main/java/com/github/hydos/ginger/engine/common/obj/ModelLoader.java @@ -1,7 +1,5 @@ package com.github.hydos.ginger.engine.common.obj; -import org.joml.*; - import com.github.hydos.ginger.engine.common.obj.shapes.StaticCube; import com.github.hydos.ginger.engine.opengl.render.models.GLTexturedModel; import com.github.hydos.ginger.engine.opengl.render.texture.ModelTexture; @@ -30,48 +28,4 @@ public class ModelLoader Mesh data = OBJFileLoader.loadModel(meshPath); return data; } - - public static OptimisedMesh getCubeOptimisedMesh() - { - return optimiseModel(StaticCube.getCube()); - } - - private static OptimisedMesh optimiseModel(Mesh cube) - { - OptimisedMesh mesh = new OptimisedMesh(); - Vector3f position = new Vector3f(); - int index = 1; - for(float f: cube.getVertices()) { - if(index == 1) { - position.x = f; - }if(index == 2) { - position.y = f; - }if (index == 3) { - position.z = f; - mesh.positions.add(position); - position = new Vector3f(); - index = 1; - } - if(index == 1 || index == 2) { - index++; - } - } - index = 1; - Vector2f texCoord = new Vector2f(); - for(float f: cube.getTextureCoords()) { - if(index == 1) { - texCoord.x = f; - index++; - }else { - texCoord.y = f; - mesh.texCoords.add(texCoord); - index = 1; - } - } - for(float f: cube.getIndices()) { - mesh.indices.add((int)f); - } - //optimised meshes don't have normals... yet - return mesh; - } } diff --git a/src/main/java/com/github/hydos/ginger/engine/common/obj/OBJFileLoader.java b/src/main/java/com/github/hydos/ginger/engine/common/obj/OBJFileLoader.java index 5443855..a2cb7d2 100644 --- a/src/main/java/com/github/hydos/ginger/engine/common/obj/OBJFileLoader.java +++ b/src/main/java/com/github/hydos/ginger/engine/common/obj/OBJFileLoader.java @@ -78,6 +78,7 @@ public class OBJFileLoader j++; } Mesh mesh = new Mesh(verticies, textureCoords, new float[normals.sizeof()], indicesList, i); + mesh.vkVertices = vertexList; return mesh; } } \ No newline at end of file diff --git a/src/main/java/com/github/hydos/ginger/engine/common/obj/OptimisedMesh.java b/src/main/java/com/github/hydos/ginger/engine/common/obj/OptimisedMesh.java deleted file mode 100644 index 626f53a..0000000 --- a/src/main/java/com/github/hydos/ginger/engine/common/obj/OptimisedMesh.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.github.hydos.ginger.engine.common.obj; - -import java.util.*; - -import org.joml.*; - -/** - * the ginger 2 standard model (currently only in vulkan) conversion tools will be made later - * @author hydos - * - */ -public class OptimisedMesh -{ - - public List positions; - public List texCoords; - public List indices; - - public OptimisedMesh() { - this.positions = new ArrayList<>(); - this.texCoords = new ArrayList<>(); - this.indices = new ArrayList<>(); - } - -} diff --git a/src/main/java/com/github/hydos/ginger/engine/vulkan/misc/ModelLoader.java b/src/main/java/com/github/hydos/ginger/engine/vulkan/misc/ModelLoader.java new file mode 100644 index 0000000..b2b8f45 --- /dev/null +++ b/src/main/java/com/github/hydos/ginger/engine/vulkan/misc/ModelLoader.java @@ -0,0 +1,134 @@ +package com.github.hydos.ginger.engine.vulkan.misc; + +import org.joml.Vector2f; +import org.joml.Vector2fc; +import org.joml.Vector3f; +import org.joml.Vector3fc; +import org.lwjgl.PointerBuffer; +import org.lwjgl.assimp.*; + +import java.io.File; +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import static java.util.Objects.requireNonNull; +import static org.lwjgl.assimp.Assimp.*; + +@Deprecated +public class ModelLoader { + + public static Model loadModel(File file, int flags) { + + try(AIScene scene = aiImportFile(file.getAbsolutePath(), flags)) { + + Logger logger = Logger.getLogger(ModelLoader.class.getSimpleName()); + + logger.info("Loading model " + file.getPath() + "..."); + + if(scene == null || scene.mRootNode() == null) { + throw new RuntimeException("Could not load model: " + aiGetErrorString()); + } + + Model model = new Model(); + + long startTime = System.nanoTime(); + + processNode(scene.mRootNode(), scene, model); + + logger.info("Model loaded in " + ((System.nanoTime() - startTime) / 1e6) + "ms"); + + return model; + } + } + + private static void processNode(AINode node, AIScene scene, Model model) { + + if(node.mMeshes() != null) { + processNodeMeshes(scene, node, model); + } + + if(node.mChildren() != null) { + + PointerBuffer children = node.mChildren(); + + for(int i = 0;i < node.mNumChildren();i++) { + processNode(AINode.create(children.get(i)), scene, model); + } + + } + + } + + private static void processNodeMeshes(AIScene scene, AINode node, Model model) { + + PointerBuffer pMeshes = scene.mMeshes(); + IntBuffer meshIndices = node.mMeshes(); + + for(int i = 0;i < meshIndices.capacity();i++) { + AIMesh mesh = AIMesh.create(pMeshes.get(meshIndices.get(i))); + processMesh(scene, mesh, model); + } + + } + + private static void processMesh(AIScene scene, AIMesh mesh, Model model) { + + processPositions(mesh, model.positions); + processTexCoords(mesh, model.texCoords); + + processIndices(mesh, model.indices); + } + + private static void processPositions(AIMesh mesh, List positions) { + + AIVector3D.Buffer vertices = requireNonNull(mesh.mVertices()); + + for(int i = 0;i < vertices.capacity();i++) { + AIVector3D position = vertices.get(i); + positions.add(new Vector3f(position.x(), position.y(), position.z())); + } + + } + + private static void processTexCoords(AIMesh mesh, List texCoords) { + + AIVector3D.Buffer aiTexCoords = requireNonNull(mesh.mTextureCoords(0)); + + for(int i = 0;i < aiTexCoords.capacity();i++) { + final AIVector3D coords = aiTexCoords.get(i); + texCoords.add(new Vector2f(coords.x(), coords.y())); + } + + } + + private static void processIndices(AIMesh mesh, List indices) { + + AIFace.Buffer aiFaces = mesh.mFaces(); + + for(int i = 0;i < mesh.mNumFaces();i++) { + AIFace face = aiFaces.get(i); + IntBuffer pIndices = face.mIndices(); + for(int j = 0;j < face.mNumIndices();j++) { + indices.add(pIndices.get(j)); + } + } + + } + + public static class Model { + + public final List positions; + public final List texCoords; + public final List indices; + + public Model() { + this.positions = new ArrayList<>(); + this.texCoords = new ArrayList<>(); + this.indices = new ArrayList<>(); + } + } + + +} diff --git a/src/main/java/com/github/hydos/ginger/engine/vulkan/model/VKVertex.java b/src/main/java/com/github/hydos/ginger/engine/vulkan/model/VKVertex.java deleted file mode 100644 index dc9a12c..0000000 --- a/src/main/java/com/github/hydos/ginger/engine/vulkan/model/VKVertex.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.github.hydos.ginger.engine.vulkan.model; - -import static org.lwjgl.vulkan.VK10.*; - -import org.joml.*; -import org.lwjgl.vulkan.*; - -public class VKVertex -{ - - public static final int SIZEOF = (3 + 3 + 2) * Float.BYTES; - public static final int OFFSETOF_POS = 0; - public static final int OFFSETOF_COLOR = 3 * Float.BYTES; - public static final int OFFSETOF_TEXTCOORDS = (3 + 3) * Float.BYTES; - - public Vector3fc pos; - public Vector3fc color; - public Vector2fc texCoords; - - public VKVertex(Vector3fc pos, Vector3fc color, Vector2fc texCoords) { - this.pos = pos; - this.color = color; - this.texCoords = texCoords; - } - - public static VkVertexInputBindingDescription.Buffer getBindingDescription() { - - VkVertexInputBindingDescription.Buffer bindingDescription = - VkVertexInputBindingDescription.callocStack(1); - - bindingDescription.binding(0); - bindingDescription.stride(VKVertex.SIZEOF); - bindingDescription.inputRate(VK_VERTEX_INPUT_RATE_VERTEX); - - return bindingDescription; - } - - public static VkVertexInputAttributeDescription.Buffer getAttributeDescriptions() { - - VkVertexInputAttributeDescription.Buffer attributeDescriptions = - VkVertexInputAttributeDescription.callocStack(3); - - // Position - VkVertexInputAttributeDescription posDescription = attributeDescriptions.get(0); - posDescription.binding(0); - posDescription.location(0); - posDescription.format(VK_FORMAT_R32G32B32_SFLOAT); - posDescription.offset(OFFSETOF_POS); - - // Color - VkVertexInputAttributeDescription colorDescription = attributeDescriptions.get(1); - colorDescription.binding(0); - colorDescription.location(1); - colorDescription.format(VK_FORMAT_R32G32B32_SFLOAT); - colorDescription.offset(OFFSETOF_COLOR); - - // Texture coordinates - VkVertexInputAttributeDescription texCoordsDescription = attributeDescriptions.get(2); - texCoordsDescription.binding(0); - texCoordsDescription.location(2); - texCoordsDescription.format(VK_FORMAT_R32G32_SFLOAT); - texCoordsDescription.offset(OFFSETOF_TEXTCOORDS); - - return attributeDescriptions.rewind(); - } - -} diff --git a/src/main/java/com/github/hydos/ginger/engine/vulkan/pipelines/VKPipelineManager.java b/src/main/java/com/github/hydos/ginger/engine/vulkan/pipelines/VKPipelineManager.java index da37970..65ccfe8 100644 --- a/src/main/java/com/github/hydos/ginger/engine/vulkan/pipelines/VKPipelineManager.java +++ b/src/main/java/com/github/hydos/ginger/engine/vulkan/pipelines/VKPipelineManager.java @@ -9,7 +9,7 @@ import org.lwjgl.system.MemoryStack; import org.lwjgl.vulkan.*; import com.github.hydos.ginger.VulkanLitecraft; -import com.github.hydos.ginger.engine.vulkan.model.VKVertex; +import com.github.hydos.ginger.VulkanLitecraft.VulkanDemoGinger2.Vertex; import com.github.hydos.ginger.engine.vulkan.shaders.*; import com.github.hydos.ginger.engine.vulkan.shaders.VKShaderUtils.SPIRV; @@ -47,8 +47,8 @@ public class VKPipelineManager VkPipelineVertexInputStateCreateInfo vertexInputInfo = VkPipelineVertexInputStateCreateInfo.callocStack(stack); vertexInputInfo.sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO); - vertexInputInfo.pVertexBindingDescriptions(VKVertex.getBindingDescription()); - vertexInputInfo.pVertexAttributeDescriptions(VKVertex.getAttributeDescriptions()); + vertexInputInfo.pVertexBindingDescriptions(Vertex.getBindingDescription()); + vertexInputInfo.pVertexAttributeDescriptions(Vertex.getAttributeDescriptions()); // ASSEMBLY STAGE