Комментарии:
So everything was working fine in the prior tutorial, and if I put the vertices and stuff in manually all works well, but for some reason the stall model is not loading what so ever. I'm not getting any errors, it just isn't there. I was wondering if anyone could help me with this? I'm willing to email the code to see if maybe I screwed something up.
ОтветитьWill you please help me solve this error:
Java.lang.NumberFormatException : empty string
I really need some help here.
Thank you
HERE IS THE CLASS DONT WRITE IT BY YOURSELF TOO MUCH WORK:
public static Mesh loadObj(String filename, MeshLoader loader) {
FileReader fr = null;
try {
fr = new FileReader(new File("rsc/models/"+filename+".obj"));
} catch(FileNotFoundException e) {
e.printStackTrace();
}
BufferedReader reader = new BufferedReader(fr);
String line;
List<Vector3f> vertices = new ArrayList<>();
List<Vector3f> normals = new ArrayList<>();
List<Vector2f> textures = new ArrayList<>();
List<Integer> indices = new ArrayList<>();
float[] verticesArray = null;
float[] normalsArray = null;
float[] texturesArray = null;
int[] indicesArray = null;
try {
while(true) {
line = reader.readLine();
String[] currentLine = line.split(" ");
if(line.startsWith("v ")) {
Vector3f vertex = new Vector3f(Float.parseFloat(currentLine[1]), Float.parseFloat(currentLine[2]), Float.parseFloat(currentLine[3]));
vertices.add(vertex);
} else if(line.startsWith("vt ")) {
Vector2f texture = new Vector2f(Float.parseFloat(currentLine[1]), Float.parseFloat(currentLine[2]));
textures.add(texture);
} else if(line.startsWith("vn ")) {
Vector3f normal = new Vector3f(Float.parseFloat(currentLine[1]), Float.parseFloat(currentLine[2]), Float.parseFloat(currentLine[3]));
normals.add(normal);
} else if(line.startsWith("f ")) {
texturesArray = new float[vertices.size()*2];
normalsArray = new float[normals.size()*3];
break;
}
}
while(line!=null) {
if(!line.startsWith("f ")) {
line = reader.readLine();
continue;
}
String[] currentLine = line.split(" ");
String[] vertex1 = currentLine[1].split("/");
String[] vertex2 = currentLine[2].split("/");
String[] vertex3 = currentLine[3].split("/");
processVertex(vertex1, indices, textures, normals, texturesArray, normalsArray);
processVertex(vertex2, indices, textures, normals, texturesArray, normalsArray);
processVertex(vertex3, indices, textures, normals, texturesArray, normalsArray);
line = reader.readLine();
}
reader.close();
} catch(Exception e) {
e.printStackTrace();
}
verticesArray = new float[vertices.size()*3];
indicesArray = new int[indices.size()];
int vertexPointer = 0;
for(Vector3f vertex: vertices) {
verticesArray[vertexPointer++] = vertex.x;
verticesArray[vertexPointer++] = vertex.y;
verticesArray[vertexPointer++] = vertex.z;
}
for(int i = 0; i < indices.size(); i++) {
indicesArray[i] = indices.get(i);
}
return loader.loadToVao(verticesArray, texturesArray, indicesArray);
}
private static void processVertex(String[] vertexData, List<Integer> indices, List<Vector2f> textures, List<Vector3f> normals, float[] textureArray, float[] normalsArray) {
int currentVertexPointer = Integer.parseInt(vertexData[0]);
indices.add(currentVertexPointer);
Vector2f currentTex = textures.get(Integer.parseInt(vertexData[1])-1);
textureArray[currentVertexPointer*2] = currentTex.x;
textureArray[currentVertexPointer*2+1] = 1 - currentTex.y;
Vector3f currentNorm = normals.get(Integer.parseInt(vertexData[2]) -1);
normalsArray[currentVertexPointer*3] = currentNorm.x;
normalsArray[currentVertexPointer*3+1] = currentNorm.y;
normalsArray[currentVertexPointer*3+2] = currentNorm.z;
}
Will that work with objects with sharp corners, because in that case vertices need mutiple normals.
ОтветитьWhile I think the code for loading the OBJ is working well, I have a problem where my OBJ file has multiple textures and I have no idea how to do multiple textures in a single model :/
Ответитьi get a array out of bounds error pls help
java.lang.ArrayIndexOutOfBoundsException: 1
at renderEngine.OBJLoader.loadObjModel(OBJLoader.java:41)
at engineTester.MainGameLoop.main(MainGameLoop.java:27)
Exception in thread "main" java.lang.NullPointerException
at renderEngine.Loader.storeDataInFloatBuffer(Loader.java:100)
at renderEngine.Loader.storeDataInAttributeList(Loader.java:74)
at renderEngine.Loader.loadToVAO(Loader.java:32)
at renderEngine.OBJLoader.loadObjModel(OBJLoader.java:92)
at engineTester.MainGameLoop.main(MainGameLoop.java:27)
I am getting an OutOfBoundsException in the line with the "Vector2f currentTex = textures.get(...)"
Edit: Nevermind, I had a small brackets-error _: D
Im having an issue, any method from the entity class isn't working.
ОтветитьHow to Fix here?
java.lang.NumberFormatException: For input string: " "
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:470)
at java.lang.Integer.parseInt(Integer.java:499)
at RenderEngine.OBJLoader.processVertex(OBJLoader.java:88)
at RenderEngine.OBJLoader.loadOBJModel(OBJLoader.java:63)
at EngineTester.MainGameLoop.main(MainGameLoop.java:25)
last night I watched 9 episodes of your tutorial. this night I had weird dreams, about code and openGL but without sense. when I woke up I was indisposed and threw up 2 times. what did you do to me?
ОтветитьSo ive done everything so far and it all seemed to work but my program doesnt display the model, there are no errors, my screen just shows up green? any help would be appreciated
Ответитьhey dude, can i use your OBJ File Loader code in my 3D Render?
ОтветитьJust cause you know something doesn’t make you a good teacher
ОтветитьIn my case model has end up orbiting the center of the world, instead of spinning in place.
ОтветитьI tried a lot to load a 3d model for a jet plane, but it didn't work. Someone can help me if they have a pilot model that works with the classes in the video. @ThinMatrix Help Me Plz
ОтветитьIs there any way to make a program that rips from direct x games
ОтветитьI know that the serie is 5 years old, but I'm following it with the same LWJGL version, and for those who'd like to import some more complex model the function isn't going to work. Indeed, it will only work for a particular case where each vertice is only mapped to one place on the texture, which is not always the case (imagine 2 cubes next to each other, they share 4 vertices with different colors mapped to them). So here is my version of the code, which is definitely less perfomant because I got to get rid of the index buffer (kinda), but it will work for almost all 3d models you'll import :)
package renderEngine;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import models.RawModel;
import org.lwjgl.util.vector.Vector2f;
import org.lwjgl.util.vector.Vector3f;
public class OBJLoader {
public static RawModel loadObjModel(String fileName, Loader loader) {
FileReader fr = null;
try {
fr = new FileReader(new File("res/" + fileName + ".obj"));
} catch (FileNotFoundException e) {
System.err.println("Couldn't load file!");
e.printStackTrace();
}
BufferedReader reader = new BufferedReader(fr);
String line;
List<Vector3f> rawvertices = new ArrayList<Vector3f>();
List<Vector2f> rawtextures = new ArrayList<Vector2f>();
List<Vector3f> rawnormals = new ArrayList<Vector3f>();
List<Integer> rawindices = new ArrayList<Integer>();
float[] verticesArray = null;
float[] normalsArray = null;
float[] textureArray = null;
int[] indicesArray = null;
try {
while (true) {
line = reader.readLine();
if(line == null)
break;
String[] currentLine = line.split(" ");
if (line.startsWith("v ")) {
Vector3f vertex = new Vector3f(Float.parseFloat(currentLine[1]),
Float.parseFloat(currentLine[2]), Float.parseFloat(currentLine[3]));
rawvertices.add(vertex);
} else if (line.startsWith("vt ")) {
Vector2f texture = new Vector2f(Float.parseFloat(currentLine[1]),
Float.parseFloat(currentLine[2]));
rawtextures.add(texture);
} else if (line.startsWith("vn ")) {
Vector3f normal = new Vector3f(Float.parseFloat(currentLine[1]),
Float.parseFloat(currentLine[2]), Float.parseFloat(currentLine[3]));
rawnormals.add(normal);
} else if (line.startsWith("f ")) {
String[] vertex1 = currentLine[1].split("/");
String[] vertex2 = currentLine[2].split("/");
String[] vertex3 = currentLine[3].split("/");
rawindices.add(Integer.parseInt(vertex1[0]));
rawindices.add(Integer.parseInt(vertex1[1]));
rawindices.add(Integer.parseInt(vertex1[2]));
rawindices.add(Integer.parseInt(vertex2[0]));
rawindices.add(Integer.parseInt(vertex2[1]));
rawindices.add(Integer.parseInt(vertex2[2]));
rawindices.add(Integer.parseInt(vertex3[0]));
rawindices.add(Integer.parseInt(vertex3[1]));
rawindices.add(Integer.parseInt(vertex3[2]));
}
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
verticesArray = new float[rawindices.size()];
int vertI = 0;
indicesArray = new int[rawindices.size()/3];
int indiceI = 0;
textureArray = new float[(rawindices.size()/3) * 2];
int texI = 0;
normalsArray = new float[rawindices.size()]; // * 3 / 3
int normI = 0;
for(int i = 0; i < rawindices.size();i+=0) {
Vector3f coord = rawvertices.get(rawindices.get(i++)-1);
Vector2f tex = rawtextures.get(rawindices.get(i++)-1);
Vector3f norm = rawnormals.get(rawindices.get(i++)-1);
indicesArray[indiceI] = indiceI;
indiceI++;
verticesArray[vertI++] = coord.x;
verticesArray[vertI++] = coord.y;
verticesArray[vertI++] = coord.z;
textureArray[texI++] = tex.x;
textureArray[texI++] = tex.y;
normalsArray[normI++] = norm.x;
normalsArray[normI++] = norm.y;
normalsArray[normI++] = norm.z;
}
return loader.loadToVAO(verticesArray, indicesArray, textureArray);
}
}
i knoiw this was six years ago, but is there any way to find his code for this? ive been trying for 2 days to fix this and have reqtched the video about 30 times someone pls help me is there any code still?
ОтветитьAwesome work teaching great stuff. Kudos for that.
I have been having trouble understanding the handling of .OBJ files having multiple objects (o) and groups (g) parameters.
errr... is it available use in android studio? thanks
ОтветитьMy object is not textured, why????
ОтветитьFor those facing problem that only half object is rendered on screen. This is because ur object is in 2 parts and have f's at different positions. So what u can do is opean ur object file in text editor and arrange the v , vt, vf and f in proper order where all f's are at last and ofc save it
ОтветитьWhen I try to run the program all I see is a red screen. I tried looking back through the video but as far as I can tell the code is the same, but I could be missing something.
ОтветитьI realize this is an old video but for anyone who is watching this: just download an OBJ loader for java from the internet. Loading an OBJ file is such a common task that surely there is an implementation you can use on the internet. No need to go through the hassle of writing your own.
ОтветитьSo far none of the dropbox links working. I don't know if it's just today, or whether those files are removed! Can you please provide new link?
ОтветитьI`m from 2021
Thanks for tutorials
If anyone is getting an error where the front of the model is invisible, go to tutorial 8 and check the renderer class
ОтветитьIve been following everything correctly but in tutorial 8 the last thing I was able to do was move the square before the quad of course, and no it claims there is no problems and it runs but. I can ever see the model or texture anymore. Just a green background
ОтветитьUsing blender 2.82 my grassy cube looks wrong with the texture of some of the triangles on the faces being messed up. However your stall model and texture works so it’s not the code.
These are my export settings
Objects as objects = true
With -Z = forward
Y = up
Write normals = true
Include UVs = true
Triangulate Faces = true
Note that the OBJ loader is half-broken and does not load some models correctly, including models exported from recent versions of Blender.
ОтветитьDoes anyone know how to edit the loader so that It can handle seems?
ОтветитьCan you tell me the source code?
ОтветитьThank you for clarifying. I had the wrong perception of the f part. Struggled with objs for 2 days...
ОтветитьWhat if the object has more than one image as texture? So its not in one file
ОтветитьHey. I'm getting indexOutOfBounds exception when loading an obj ? (it worked for two other)
ОтветитьI was following along this tutorial and i had a problem with the texture with the stall model (the color was weird) so then i asked on his discord and got the solution:
Change this
Vector2f texture = new Vector2f((float) Float.valueOf(currentLine[1]),
(float) Float.valueOf(currentLine[2]));
to
Vector2f texture = new Vector2f((float) Float.valueOf(currentLine[1]),
1.0f - (float) Float.valueOf(currentLine[2]));
if it helps people out there then ur welcome
Some one has a sample about OpenGL ES Java for Android?
ОтветитьIf you have missing triangle, that mean blender save .obj as rectangles, not as triangle.
To fix that you need to after line:
processVertex(vertex3,indicies,textures,normals,textureArray,normalsArray);
add this:
if(currentLine.length==5) {
String[] vertex4 = currentLine[4].split("/");
processVertex(vertex1, indicies, textures, normals, textureArray, normalsArray);
processVertex(vertex3, indicies, textures, normals, textureArray, normalsArray);
processVertex(vertex4, indicies, textures, normals, textureArray, normalsArray);
}
EDIT: As it turns out, I was completely wrong. The Stanford Dragon KILLED my argument. Not really, but random array access is a definite killer when it comes to linked lists, which isn't a problem when it comes to a simple(r) chunk builder. I'll leave my old comment here just for completeness. You could probably do some two-pass to know how much to initialize each array to.
------------------------------------------------------
The use of ArrayLists can lead to slowdowns when it comes to large model files, use a LinkedList instead. This will remove the need for resizing an array, meaning speed is constant rather than somewhat of an O(n^2). I found this out the hard way when generating Minecraft-esque chunks. I believe that you can still use the same for each loop, as that gets an iterator (so it's still fast).
Edit: I just realized that the process vertex function has a somewhat random array access. I'll leave it to someone else to find out if the cost of resizing an array or if the cost of traversing through a LinkedList takes more time (or if it doesn't really matter).
How do I use the .mtl file for my materials?
I have a tree withe leaves and trunk having different uv textures. Is it possible to include them so I won't need to put everything on a single image?
Hello, I have a problem and that is that instead of me loading the model, it appears as a sphere with the textures, could you help me???
ОтветитьException in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 18 out of bounds for length 18
at models.OBJLoader.processVertex(OBJLoader.java:96)
at models.OBJLoader.loadObjModel(OBJLoader.java:66)
at Main.main(Main.java:17)
Edit: Fixed it but some triangles are missing
this code here fixes the need for triangle objs (it can load quads, really any number of triangles per face). ModelData is just a struct of vertices, indices, and normals. The path is a path relative to your assets dir. so src/main/resources/assets/test.obj would map to assets/test.obj.: ```
import org.joml.Vector2f;
import org.joml.Vector3f;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class OBJParser {
public static ModelData parseOBJ(String path) {
try (InputStream stream = OBJParser.class.getResourceAsStream(path)) {
return parseOBJ(stream);
} catch (Exception e) {
throw new IllegalStateException("Failed to parse OBJ file: " + path, e);
}
}
public static ModelData parseOBJ(InputStream stream) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String currentLine;
List<Vector3f> vertices = new ArrayList<>();
List<Vector2f> texCoords = new ArrayList<>();
List<Vector3f> normals = new ArrayList<>();
List<Integer> indices = new ArrayList<>();
float[] verticesArray;
float[] texCoordsArray = null;
float[] normalsArray = null;
int[] indicesArray;
boolean initializedArrays = false;
while ((currentLine = reader.readLine()) != null) {
String[] tokens = currentLine.split(" ");
if (currentLine.startsWith("v ")) {
Vector3f vertex = new Vector3f(Float.parseFloat(tokens[1]), Float.parseFloat(tokens[2]), Float.parseFloat(tokens[3]));
vertices.add(vertex);
} else if (currentLine.startsWith("vt ")) {
Vector2f texCoord = new Vector2f(Float.parseFloat(tokens[1]), Float.parseFloat(tokens[2]));
texCoords.add(texCoord);
} else if (currentLine.startsWith("vn ")) {
Vector3f normal = new Vector3f(Float.parseFloat(tokens[1]), Float.parseFloat(tokens[2]), Float.parseFloat(tokens[3]));
normals.add(normal);
} else if (currentLine.startsWith("f ")) {
if (!initializedArrays) {
texCoordsArray = new float[vertices.size() * 2];
normalsArray = new float[vertices.size() * 3];
initializedArrays = true;
}
List<String[]> verticesList = new ArrayList<>();
for (String token : tokens) {
if (!token.startsWith("f")) {
verticesList.add(token.split("/"));
}
}
for (int i = 0; i < verticesList.size(); i++) {
String[] currentVertex = verticesList.get(i);
if (i == 0) {
String[] vertex1 = verticesList.get(1);
String[] vertex2 = verticesList.get(2);
processVertex(currentVertex, indices, texCoords, normals, texCoordsArray, normalsArray);
processVertex(vertex1, indices, texCoords, normals, texCoordsArray, normalsArray);
processVertex(vertex2, indices, texCoords, normals, texCoordsArray, normalsArray);
} else if (i % 3 == 0) {
String[] vertex1 = verticesList.get(i - 1);
String[] vertex2 = verticesList.get(i - 3);
processVertex(vertex2, indices, texCoords, normals, texCoordsArray, normalsArray);
processVertex(vertex1, indices, texCoords, normals, texCoordsArray, normalsArray);
processVertex(currentVertex, indices, texCoords, normals, texCoordsArray, normalsArray);
}
}
}
}
reader.close();
verticesArray = new float[vertices.size() * 3];
indicesArray = new int[indices.size()];
int vertexPointer = 0;
for (Vector3f vertex : vertices) {
verticesArray[vertexPointer++] = vertex.x;
verticesArray[vertexPointer++] = vertex.y;
verticesArray[vertexPointer++] = vertex.z;
}
for (int i = 0; i < indices.size(); i++) {
indicesArray[i] = indices.get(i);
}
return new ModelData(verticesArray, texCoordsArray, indicesArray);
}
public static void processVertex(String[] data, List<Integer> indices,
List<Vector2f> texCoords, List<Vector3f> normals, float[] texCoordsArray,
float[] normalsArray) {
int currentVertexPointer = Integer.parseInt(data[0]) - 1;
indices.add(currentVertexPointer);
Vector2f currentTexCoord = texCoords.get(Integer.parseInt(data[1]) - 1);
texCoordsArray[currentVertexPointer * 2] = currentTexCoord.x;
texCoordsArray[currentVertexPointer * 2 + 1] = 1 - currentTexCoord.y;
Vector3f currentNormal = normals.get(Integer.parseInt(data[2]) - 1);
normalsArray[currentVertexPointer * 3] = currentNormal.x;
normalsArray[currentVertexPointer * 3 + 1] = currentNormal.y;
normalsArray[currentVertexPointer * 3 + 2] = currentNormal.z;
}
public static record ModelData(float[] vertices, float[] textureCoords, int[] indices) {}
}
```
what blender version you're using in this video?
ОтветитьHey there's anyone who knows why when I run my projects it shows empty???
ОтветитьI can’t even catch up on these tutorials.
Ответить