Hallo Community,
Ich versuche jetzt schon seit eingen Tagen einen .obj Modelloader zu schreiben, dazu benutze ich LWJGL als OpenGL libary, aber wenn ich es render bleibt der Screen schwarz.
Die Klassen zum importieren der Objekt-Dateien habe ich mit hilfe von Tutorials auf YouTube geschrieben und sehen wie folgt aus.
Tutorial von thebennybox
(#16 3D Game Engine Tutorial: Mesh Loading (OBJ) - YouTube)
Tutorial von The Coding Universe
(#24 LWJGL 3D Models - LWJGL Tutorials - YouTube)
ModelLoader.java: Lädt die Objekt-Datei und speichert die Inhalte in der IndexModel instance ab.
MeshFace.java: Struktur Klasse für die Faces der Objekt-Datei
IndexModel.java
GameTemplate.java: Klasse wo die Grafik gerendert wird.
Ich dachte erst das liegt daran das ich die Vertexkoordinaten falsch lade und habe andere Möglichkeiten ausprobiert das lief aber noch schlechter da sich das Programm immer aufgehängt hat oder Exceptions bekommen habe.
Habe auch schon versucht bei Google nach einer Lösung zu suchen habe aber nichts gefunden, daher das die meisten Loader immer unterschiedlich sind.
Ich hoffe Ihr könnt mir Helfen, fals ihr noch mehr Informationen braucht dann sagt bescheid.
Mit freundlichen Gruß
Shadownight
Ich versuche jetzt schon seit eingen Tagen einen .obj Modelloader zu schreiben, dazu benutze ich LWJGL als OpenGL libary, aber wenn ich es render bleibt der Screen schwarz.
Die Klassen zum importieren der Objekt-Dateien habe ich mit hilfe von Tutorials auf YouTube geschrieben und sehen wie folgt aus.
Tutorial von thebennybox
(#16 3D Game Engine Tutorial: Mesh Loading (OBJ) - YouTube)
Tutorial von The Coding Universe
(#24 LWJGL 3D Models - LWJGL Tutorials - YouTube)
ModelLoader.java: Lädt die Objekt-Datei und speichert die Inhalte in der IndexModel instance ab.
Java:
package model;
import java.util.*;
import java.io.*;
import util.Util;
import graphics.*;
import math.*;
public class ModelLoader {
private ArrayList<Vector3f> positions;
private ArrayList<Vector3f> normals;
private ArrayList<Vector2f> texcoords;
private ArrayList<MeshFace> indices;
private ArrayList<Integer> bindices;
private ArrayList<Vertex> vertices;
boolean hasTexCoords = false;
boolean hasNormals = false;
public ModelLoader(){
}
public IndexModel LoadObjModelData(String file)
{
IndexModel m = new IndexModel();
String[] splittArray = file.split("\\.");
String ext = splittArray[splittArray.length - 1];
if(!ext.equals("obj")){
System.err.println("Filetype not supported please check if it is an .obj file!");
}
try {
BufferedReader reader = new BufferedReader(new FileReader("./resource/models/revolver/" + file));
String line;
while((line = reader.readLine()) != null){
String[] tokens = line.split(" ");
tokens = Util.removeEmptyStrings(tokens);
if(tokens[0] == null || tokens[0].equals("#") || tokens[0].equals("g"))
continue;
if(tokens[0].equals("v")){
m.VertexPositions.add(new Vector3f(Float.valueOf(tokens[1]),
Float.valueOf(tokens[2]),
Float.valueOf(tokens[3])));
}
else if(tokens[0].equals("vn"))
{
m.VertexNormals.add(new Vector3f(Float.valueOf(tokens[1]),
Float.valueOf(tokens[2]),
Float.valueOf(tokens[3])));
}
else if(tokens[0].equals("vt")){
m.VertexTexCoords.add(new Vector2f(Float.valueOf(tokens[1]),
Float.valueOf(tokens[2])));
}
else if(tokens[0].equals("f")){
Vector3f vertexindex = new Vector3f(Float.valueOf(line.split(" ")[1].split("/")[0]),
Float.valueOf(line.split(" ")[2].split("/")[0]),
Float.valueOf(line.split(" ")[3].split("/")[0]));
Vector2f textureindex = new Vector2f(Float.valueOf(line.split(" ")[1].split("/")[1]),
Float.valueOf(line.split(" ")[2].split("/")[1]));
Vector3f normalindex = new Vector3f(Float.valueOf(line.split(" ")[1].split("/")[2]),
Float.valueOf(line.split(" ")[2].split("/")[2]),
Float.valueOf(line.split(" ")[3].split("/")[2]));
m.faces.add(new MeshFace(vertexindex, normalindex, textureindex));
}
}
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return m;
}
public ArrayList<Integer> getIndices(IndexModel value){
IndexModel m = new IndexModel();
HashMap<MeshFace, Integer> resultIndexMap = new HashMap<MeshFace, Integer>();
for(int i=0; i < value.faces.size(); i++)
{
MeshFace currentIndex = value.faces.get(i);
Integer modelVertexIndex = resultIndexMap.get(currentIndex);
if(modelVertexIndex == null)
{
modelVertexIndex = value.getVertexPositions().size();
resultIndexMap.put(currentIndex, modelVertexIndex);
m.getIndices().add(modelVertexIndex);
}
}
return m.getIndices();
}
}
MeshFace.java: Struktur Klasse für die Faces der Objekt-Datei
Java:
public Vector3f vertexIndex;
public Vector3f normalIndex;
public Vector2f textureIndex;
public MeshFace(Vector3f _vertex, Vector3f _normals, Vector2f _texture){
this.vertexIndex = _vertex;
this.normalIndex = _normals;
this.textureIndex = _texture;
}
public Vector3f getVertexIndex() {
return vertexIndex;
}
public Vector3f getNormalIndex() {
return normalIndex;
}
public Vector2f getTextureIndex() {
return textureIndex;
}
IndexModel.java
Java:
package render;
import java.util.*;
import graphics.*;
import util.Util;
import math.*;
import model.*;
public class RenderMesh {
private ArrayList<Vertex> vertices;
private ArrayList<Integer> indices;
private ModelLoader modelLoader;
private IndexModel model;
private RenderBuffer graphicBuffer;
public RenderMesh()
{
vertices = new ArrayList<Vertex>();
indices = new ArrayList<Integer>();
}
public RenderBuffer renderMesh(String type, String fileName){
modelLoader = new ModelLoader(); //Create a instance aof the ModelLoader class
model = modelLoader.LoadObjModelData(fileName); //Loading the model object
for(MeshFace face : model.faces)
{
//Getting the vertex positions
Vector3f v1 = model.getVertexPositions().get((int) face.vertexIndex.getX() -1);
Vector3f v2 = model.getVertexPositions().get((int) face.vertexIndex.getY() -1);
Vector3f v3 = model.getVertexPositions().get((int) face.vertexIndex.getZ() -1);
//Getting the vertex normals
Vector3f n1 = model.getVertexNormals().get((int) face.getNormalIndex().getX() -1);
Vector3f n2 = model.getVertexNormals().get((int) face.getNormalIndex().getY() -1);
Vector3f n3 = model.getVertexNormals().get((int) face.getNormalIndex().getZ() -1);
//Getting the texture coordinates
Vector2f t1 = model.getVertexTexCoords().get((int) face.getTextureIndex().getX() -1);
Vector2f t2 = model.getVertexTexCoords().get((int) face.getTextureIndex().getY() -1);
//Filling array list with data
vertices.add(new Vertex(new Vector3f(v1.getX(), v1.getY(), v1.getZ()), new Vector2f(0, 0), new Vector3f(n1.getX(), n1.getY(), n1.getZ())));
vertices.add(new Vertex(new Vector3f(v2.getX(), v2.getY(), v2.getZ()), new Vector2f(0, 0), new Vector3f(n2.getX(), n2.getY(), n2.getZ())));
vertices.add(new Vertex(new Vector3f(v3.getX(), v3.getY(), v1.getZ()), new Vector2f(0, 0), new Vector3f(n3.getX(), n3.getY(), n3.getZ())));
}
//Readout and fill the index array with data
for(int i=0; i < modelLoader.getIndices(model).size(); i++)
{
//Filling the indices with data
indices.add(modelLoader.getIndices(model).get(i));
}
//Creating a vertex array for our data
Vertex[] vertexData = new Vertex[vertices.size()];
vertices.toArray(vertexData);
//Creating an index array for our data
Integer[] indexData = new Integer[indices.size()];
indices.toArray(indexData);
graphicBuffer = new RenderBuffer(vertexData, Util.toIntArray(indexData));
return graphicBuffer;
}
GameTemplate.java: Klasse wo die Grafik gerendert wird.
Java:
package core;
import java.io.FileNotFoundException;
import java.io.IOException;
import graphics.*;
import math.*;
import util.*;
import model.*;
import render.*;
public class GameTemplate {
private RenderBuffer mesh;
private RenderMesh model;
private Transform transform;
private Camera camera;
private Shader shader;
public GameTemplate() throws FileNotFoundException, IOException
{
camera = new Camera();
transform = new Transform();
model = new RenderMesh();
mesh = model.renderMesh("obj", "Revolver.obj");
Transform.setProjection(70f, Window.getWidth(), Window.getHeight(), 0.1f, 1000);
Transform.setCamera(camera);
}
public void input()
{
camera.input();
}
float temp = 0.0f;
public void update()
{
temp += Time.getDelta();
}
public void render()
{
OpenGL.setClearColor(Transform.getCamera().getPos().div(2048f).abs());
mesh.Render();
}
}
Ich dachte erst das liegt daran das ich die Vertexkoordinaten falsch lade und habe andere Möglichkeiten ausprobiert das lief aber noch schlechter da sich das Programm immer aufgehängt hat oder Exceptions bekommen habe.
Habe auch schon versucht bei Google nach einer Lösung zu suchen habe aber nichts gefunden, daher das die meisten Loader immer unterschiedlich sind.
Ich hoffe Ihr könnt mir Helfen, fals ihr noch mehr Informationen braucht dann sagt bescheid.
Mit freundlichen Gruß
Shadownight