From fe151b84ccabb4313ac9eb8895c402ff785c31be Mon Sep 17 00:00:00 2001 From: hYdos Date: Sun, 23 Feb 2020 08:20:31 +1000 Subject: [PATCH] stuff which involves some rewriting --- .../java/io/github/hydos/ginger/Example.java | 2 +- .../github/hydos/ginger/engine/io/Window.java | 2 +- .../hydos/ginger/engine/obj/ModelData.java | 6 + .../ginger/engine/obj/OBJFileLoader.java | 224 +++++++----------- .../postprocessing/ContrastChanger.java | 1 - .../ginger/engine/render/texture/Image.java | 5 - .../io/github/hydos/ginger/Example.class | Bin 11125 -> 11125 bytes .../hydos/ginger/engine/io/Window.class | Bin 7613 -> 7613 bytes .../hydos/ginger/engine/obj/ModelData.class | Bin 1006 -> 1150 bytes .../ginger/engine/obj/OBJFileLoader.class | Bin 7530 -> 1902 bytes .../postProcessing/ContrastChanger.class | Bin 1267 -> 1149 bytes 11 files changed, 89 insertions(+), 151 deletions(-) diff --git a/src/main/java/io/github/hydos/ginger/Example.java b/src/main/java/io/github/hydos/ginger/Example.java index 5b41d7f..469e07e 100644 --- a/src/main/java/io/github/hydos/ginger/Example.java +++ b/src/main/java/io/github/hydos/ginger/Example.java @@ -54,7 +54,7 @@ public class Example { public void main(String[] args) { - Window.create(2000, 1200, "Ginger Example", 60); + Window.create(800, 1200, "Ginger Example", 60); GingerMain.init(); diff --git a/src/main/java/io/github/hydos/ginger/engine/io/Window.java b/src/main/java/io/github/hydos/ginger/engine/io/Window.java index e44bd09..74f5ad0 100644 --- a/src/main/java/io/github/hydos/ginger/engine/io/Window.java +++ b/src/main/java/io/github/hydos/ginger/engine/io/Window.java @@ -58,7 +58,7 @@ public class Window { GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 3); GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE); GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, GL11.GL_TRUE); - GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, GLFW.GLFW_FALSE); + GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, GLFW.GLFW_TRUE); GLFWVidMode vidmode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor()); diff --git a/src/main/java/io/github/hydos/ginger/engine/obj/ModelData.java b/src/main/java/io/github/hydos/ginger/engine/obj/ModelData.java index a492d9d..bea9569 100644 --- a/src/main/java/io/github/hydos/ginger/engine/obj/ModelData.java +++ b/src/main/java/io/github/hydos/ginger/engine/obj/ModelData.java @@ -1,5 +1,7 @@ package io.github.hydos.ginger.engine.obj; +import org.lwjgl.assimp.AIScene; + public class ModelData { private float[] vertices; @@ -17,6 +19,10 @@ public class ModelData { this.furthestPoint = furthestPoint; } + public ModelData(AIScene scene) { + + } + public float[] getVertices() { return vertices; } diff --git a/src/main/java/io/github/hydos/ginger/engine/obj/OBJFileLoader.java b/src/main/java/io/github/hydos/ginger/engine/obj/OBJFileLoader.java index 7999480..31ef57d 100644 --- a/src/main/java/io/github/hydos/ginger/engine/obj/OBJFileLoader.java +++ b/src/main/java/io/github/hydos/ginger/engine/obj/OBJFileLoader.java @@ -1,155 +1,93 @@ package io.github.hydos.ginger.engine.obj; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.List; +import static org.lwjgl.assimp.Assimp.aiGetErrorString; +import static org.lwjgl.assimp.Assimp.aiImportFileEx; +import static org.lwjgl.assimp.Assimp.aiProcess_JoinIdenticalVertices; +import static org.lwjgl.assimp.Assimp.aiProcess_Triangulate; +import static org.lwjgl.system.MemoryUtil.NULL; +import static org.lwjgl.system.MemoryUtil.memAddress; +import static org.lwjgl.system.MemoryUtil.memCopy; +import static org.lwjgl.system.MemoryUtil.memUTF8; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import org.lwjgl.assimp.AIFile; +import org.lwjgl.assimp.AIFileCloseProc; +import org.lwjgl.assimp.AIFileCloseProcI; +import org.lwjgl.assimp.AIFileIO; +import org.lwjgl.assimp.AIFileOpenProc; +import org.lwjgl.assimp.AIFileOpenProcI; +import org.lwjgl.assimp.AIFileReadProc; +import org.lwjgl.assimp.AIFileReadProcI; +import org.lwjgl.assimp.AIFileSeek; +import org.lwjgl.assimp.AIFileSeekI; +import org.lwjgl.assimp.AIFileTellProc; +import org.lwjgl.assimp.AIFileTellProcI; +import org.lwjgl.assimp.AIScene; +import org.lwjgl.assimp.Assimp; + +import io.github.hydos.ginger.engine.render.tools.IOUtil; -import io.github.hydos.ginger.engine.math.vectors.Vector2f; -import io.github.hydos.ginger.engine.math.vectors.Vector3f; public class OBJFileLoader { private static final String RES_LOC = "/models/"; public static ModelData loadOBJ(String objFileName) { - String objFile = RES_LOC + objFileName; - System.out.println(objFile); - InputStreamReader isr = new InputStreamReader(Class.class.getResourceAsStream(objFile)); - BufferedReader reader = new BufferedReader(isr); - String line; - List vertices = new ArrayList(); - List textures = new ArrayList(); - List normals = new ArrayList(); - List indices = new ArrayList(); - try { - while (true) { - line = reader.readLine(); - if (line.startsWith("v ")) { - String[] currentLine = line.split(" "); - Vector3f vertex = new Vector3f(Float.valueOf(currentLine[1]), - Float.valueOf(currentLine[2]), - Float.valueOf(currentLine[3])); - Vertex newVertex = new Vertex(vertices.size(), vertex); - vertices.add(newVertex); - - } else if (line.startsWith("vt ")) { - String[] currentLine = line.split(" "); - Vector2f texture = new Vector2f(Float.valueOf(currentLine[1]), - Float.valueOf(currentLine[2])); - textures.add(texture); - } else if (line.startsWith("vn ")) { - String[] currentLine = line.split(" "); - Vector3f normal = new Vector3f(Float.valueOf(currentLine[1]), - Float.valueOf(currentLine[2]), - Float.valueOf(currentLine[3])); - normals.add(normal); - } else if (line.startsWith("f ")) { - break; - } - } - while (line != null && line.startsWith("f ")) { - String[] currentLine = line.split(" "); - String[] vertex1 = currentLine[1].split("/"); - String[] vertex2 = currentLine[2].split("/"); - String[] vertex3 = currentLine[3].split("/"); - processVertex(vertex1, vertices, indices); - processVertex(vertex2, vertices, indices); - processVertex(vertex3, vertices, indices); - line = reader.readLine(); - } - reader.close(); - } catch (IOException e) { - System.err.println("Error reading the file"); - } - removeUnusedVertices(vertices); - float[] verticesArray = new float[vertices.size() * 3]; - float[] texturesArray = new float[vertices.size() * 2]; - float[] normalsArray = new float[vertices.size() * 3]; - float furthest = convertDataToArrays(vertices, textures, normals, verticesArray, - texturesArray, normalsArray); - int[] indicesArray = convertIndicesListToArray(indices); - ModelData data = new ModelData(verticesArray, texturesArray, normalsArray, indicesArray, - furthest); - return data; - } - - private static void processVertex(String[] vertex, List vertices, List indices) { - int index = Integer.parseInt(vertex[0]) - 1; - Vertex currentVertex = vertices.get(index); - int textureIndex = Integer.parseInt(vertex[1]) - 1; - int normalIndex = Integer.parseInt(vertex[2]) - 1; - if (!currentVertex.isSet()) { - currentVertex.setTextureIndex(textureIndex); - currentVertex.setNormalIndex(normalIndex); - indices.add(index); - } else { - dealWithAlreadyProcessedVertex(currentVertex, textureIndex, normalIndex, indices, - vertices); - } - } - - private static int[] convertIndicesListToArray(List indices) { - int[] indicesArray = new int[indices.size()]; - for (int i = 0; i < indicesArray.length; i++) { - indicesArray[i] = indices.get(i); - } - return indicesArray; - } - - private static float convertDataToArrays(List vertices, List textures, - List normals, float[] verticesArray, float[] texturesArray, - float[] normalsArray) { - float furthestPoint = 0; - for (int i = 0; i < vertices.size(); i++) { - Vertex currentVertex = vertices.get(i); - if (currentVertex.getLength() > furthestPoint) { - furthestPoint = currentVertex.getLength(); - } - Vector3f position = currentVertex.getPosition(); - Vector2f textureCoord = textures.get(currentVertex.getTextureIndex()); - Vector3f normalVector = normals.get(currentVertex.getNormalIndex()); - verticesArray[i * 3] = position.x; - verticesArray[i * 3 + 1] = position.y; - verticesArray[i * 3 + 2] = position.z; - texturesArray[i * 2] = textureCoord.x; - texturesArray[i * 2 + 1] = 1 - textureCoord.y; - normalsArray[i * 3] = normalVector.x; - normalsArray[i * 3 + 1] = normalVector.y; - normalsArray[i * 3 + 2] = normalVector.z; - } - return furthestPoint; - } - - private static void dealWithAlreadyProcessedVertex(Vertex previousVertex, int newTextureIndex, - int newNormalIndex, List indices, List vertices) { - if (previousVertex.hasSameTextureAndNormal(newTextureIndex, newNormalIndex)) { - indices.add(previousVertex.getIndex()); - } else { - Vertex anotherVertex = previousVertex.getDuplicateVertex(); - if (anotherVertex != null) { - dealWithAlreadyProcessedVertex(anotherVertex, newTextureIndex, newNormalIndex, - indices, vertices); - } else { - Vertex duplicateVertex = new Vertex(vertices.size(), previousVertex.getPosition()); - duplicateVertex.setTextureIndex(newTextureIndex); - duplicateVertex.setNormalIndex(newNormalIndex); - previousVertex.setDuplicateVertex(duplicateVertex); - vertices.add(duplicateVertex); - indices.add(duplicateVertex.getIndex()); - } - - } - } - - private static void removeUnusedVertices(List vertices){ - for(Vertex vertex:vertices){ - if(!vertex.isSet()){ - vertex.setTextureIndex(0); - vertex.setNormalIndex(0); - } - } + AIFileIO fileIo = AIFileIO.create(); + AIFileOpenProcI fileOpenProc = new AIFileOpenProc() { + public long invoke(long pFileIO, long fileName, long openMode) { + AIFile aiFile = AIFile.create(); + final ByteBuffer data; + String fileNameUtf8 = memUTF8(fileName); + try { + data = IOUtil.ioResourceToByteBuffer(fileNameUtf8, 8192); + } catch (IOException e) { + throw new RuntimeException("Could not open file: " + fileNameUtf8); + } + AIFileReadProcI fileReadProc = new AIFileReadProc() { + public long invoke(long pFile, long pBuffer, long size, long count) { + long max = Math.min(data.remaining(), size * count); + memCopy(memAddress(data) + data.position(), pBuffer, max); + return max; + } + }; + AIFileSeekI fileSeekProc = new AIFileSeek() { + public int invoke(long pFile, long offset, int origin) { + if (origin == Assimp.aiOrigin_CUR) { + data.position(data.position() + (int) offset); + } else if (origin == Assimp.aiOrigin_SET) { + data.position((int) offset); + } else if (origin == Assimp.aiOrigin_END) { + data.position(data.limit() + (int) offset); + } + return 0; + } + }; + AIFileTellProcI fileTellProc = new AIFileTellProc() { + public long invoke(long pFile) { + return data.limit(); + } + }; + aiFile.ReadProc(fileReadProc); + aiFile.SeekProc(fileSeekProc); + aiFile.FileSizeProc(fileTellProc); + return aiFile.address(); + } + }; + AIFileCloseProcI fileCloseProc = new AIFileCloseProc() { + public void invoke(long pFileIO, long pFile) { + /* Nothing to do */ + } + }; + fileIo.set(fileOpenProc, fileCloseProc, NULL); + AIScene scene = aiImportFileEx(RES_LOC+objFileName, + aiProcess_JoinIdenticalVertices | aiProcess_Triangulate, fileIo); + if (scene == null) { + throw new IllegalStateException(aiGetErrorString()); + } + return new ModelData(scene); } } \ No newline at end of file diff --git a/src/main/java/io/github/hydos/ginger/engine/postprocessing/ContrastChanger.java b/src/main/java/io/github/hydos/ginger/engine/postprocessing/ContrastChanger.java index 943306f..da891d0 100644 --- a/src/main/java/io/github/hydos/ginger/engine/postprocessing/ContrastChanger.java +++ b/src/main/java/io/github/hydos/ginger/engine/postprocessing/ContrastChanger.java @@ -16,7 +16,6 @@ public class ContrastChanger { public void render(int texture) { shader.start(); GL13.glActiveTexture(GL13.GL_TEXTURE0); - System.out.println(texture); GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture); renderer.renderQuad(); shader.stop(); diff --git a/src/main/java/io/github/hydos/ginger/engine/render/texture/Image.java b/src/main/java/io/github/hydos/ginger/engine/render/texture/Image.java index 0e302e9..318eeac 100644 --- a/src/main/java/io/github/hydos/ginger/engine/render/texture/Image.java +++ b/src/main/java/io/github/hydos/ginger/engine/render/texture/Image.java @@ -35,11 +35,6 @@ public class Image { throw new RuntimeException("Failed to read image information: " + stbi_failure_reason()); } -// System.out.println("Image width: " + w.get(0)); -// System.out.println("Image height: " + h.get(0)); -// System.out.println("Image components: " + comp.get(0)); -// System.out.println("Image HDR: " + stbi_is_hdr_from_memory(imageBuffer)); - // Decode the image img = stbi_load_from_memory(imageBuffer, w, h, comp, 0); if (img == null) { diff --git a/target/classes/io/github/hydos/ginger/Example.class b/target/classes/io/github/hydos/ginger/Example.class index efb30447ecce12204af7febbdda29204493777c2..09cbe879ccf31f8dacae9bc4cf6281cf228da360 100644 GIT binary patch delta 15 Wcmeww_BCunzA_WD!sbF{77hS6Sp`u5 delta 15 Wcmeww_BCunzA_X0h0TS^EF1tkl?DX> diff --git a/target/classes/io/github/hydos/ginger/engine/io/Window.class b/target/classes/io/github/hydos/ginger/engine/io/Window.class index efd9fc27eeb59e36ba3e2a6d189294244a62624c..e44d3a935e52419c94cfe29df2ab83c79256febd 100644 GIT binary patch delta 14 WcmdmMz1MofBVk6C&5wm|aRLA_QU)gg delta 14 WcmdmMz1MofBVk77&5wm|aRLA_Oa>+Z diff --git a/target/classes/io/github/hydos/ginger/engine/obj/ModelData.class b/target/classes/io/github/hydos/ginger/engine/obj/ModelData.class index b1cd75936675b86fc04e924b9215a4166905cab9..ad34bf9693fda9a400d9242e64d9e72d9b11cd8e 100644 GIT binary patch delta 369 zcmaFI{*Oc8)W2Q(7#J8#81&c~m>3zfCmS+qZ?slnbduHZ$uCOR&neGJ&(TjTF3!v? z(0B9FNOFM%#ejxLFvtPUe-6AX$hyMg}#Y>^GpSJXTqCpsX>oilj1D gSq%ow$pt`Jb*!>lz>r(ZtRkz8RaOV+3MK|!061kbEdT%j delta 226 zcmeyz@s3^K)W2Q(7#J8#7_`|Lm>3zfCmS+qZ?slnoV0$vL~~Oq$qS8HMj*)wlvM!Ij10;^**2i8 sBvx4!pzL9wtSnYpRR*<5EGm+USS8gNG$z}!sK}~fmDL1V&cvVv04zWk>;M1& diff --git a/target/classes/io/github/hydos/ginger/engine/obj/OBJFileLoader.class b/target/classes/io/github/hydos/ginger/engine/obj/OBJFileLoader.class index 917714b9158352cc0eaf4c5dd293ce3dc633e55c..d1d330ff74427319210f96f86c3d18cbacb63cc2 100644 GIT binary patch literal 1902 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 JUwG8z{|77FyZQhC diff --git a/target/classes/io/github/hydos/ginger/engine/postProcessing/ContrastChanger.class b/target/classes/io/github/hydos/ginger/engine/postProcessing/ContrastChanger.class index 09a91252634ed0eda4147c38aa710106eed4a83c..48531c418c7b01a709ab2745e787c9a4862761d0 100644 GIT binary patch delta 298 zcmYL^-AV#c9K?V7L2K*DTFoWh2o$8UY}>x<%ZnhWi(VrH5v^|Ou4jmSjR=Gg>7obd zEqaEoiv~A{fjP|l|7Yf$ui5Y1!pG0sJFv%zhi!5CblVzr&h3WJ8cmONi}LWU8~5*f z-F`g0xgO}axJnYk2AgT%EW2BVI8B_AD{m*gbQ<}#VISY8Ks$YKo*#SI0@RzY1Y=f; zwF&iL?lYRODk~h*$|l<*ZP_e|tIUW4Jc<}f!lJw~H9{(ygju4zNJ`o4>JyfrYH?oP m*;JFhxVg?j)^PaWP{7enMGaNGG@7Ow-GKSOREr}io8w>FG%33P delta 421 zcmZvV%Sr-a6vzMHO!4J7nkHIm2?dc_Hd%J{Qkq=^7lqNP&49z8j59XPbXoNbF|X0a z2$2>&K=06^Hwao6ed?l3960d5oZtB#`*Qi-eqLSyWN=8q5#$~&Q=NR7yLTauBt?S2 z*OaeiNt1O|s@+{#N=w8dmI!#mwg`gNLEJE;6SJXPHOo}wR#w0=RwyKbz(28wG-e2B zyMLkS0@kojkzp{yR3+`EscOfP(N=U-la8wCw1^FC5_nXt)X?i^%B^La3c+Z+Qc0W( z2w+>p4g>h#<-oL!y9P5H{>1+ivC+ h2O1b3LW@J_{vXr}p4B3t4C2MKBaZ}WnK>K|egR@&RF?n%