Hi Everyone,
I've written(well, I've got the code from a tutorial) a few classes to load my own 3d models in .obj format into my programm ...
each single face of the model is a triangle
At first i thought everything would work perfect, but when I load more than just one model, there are triangles between vertices of the model where they shall NOT be...
I use vbos to display my models ...
I've tried changes and googled around for about a week but I haven't got any solution ...
Here's my code of all classes:
OBJLoader:
package the_wormhole;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import org.lwjgl.util.vector.Vector3f;
public class OBJLoader {
public static Model loadModel(File f) throws FileNotFoundException, IOException{
BufferedReader reader = new BufferedReader(new FileReader(f));
Model m = new Model();
String line;
while((line = reader.readLine()) != null){
if(line.startsWith("v ")){
float x = Float.valueOf(line.split(" ")[1]);
float y = Float.valueOf(line.split(" ")[2]);
float z = Float.valueOf(line.split(" ")[3]);
m.vertices.add(new Vector3f(x, y, z));
}else if(line.startsWith("vn ")){
float x = Float.valueOf(line.split(" ")[1]);
float y = Float.valueOf(line.split(" ")[2]);
float z = Float.valueOf(line.split(" ")[3]);
m.normals.add(new Vector3f(x, y, z));
}else if(line.startsWith("f ")){
Vector3f vertexIndices = new Vector3f(Float.valueOf(line.split(" ")[1].split("/")[0]),
Float.valueOf(line.split(" ")[2].split("/")[0]),
Float.valueOf(line.split(" ")[3].split("/")[0]));
Vector3f normalIndices = 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 Face(vertexIndices, normalIndices));
}
}
reader.close();
return m;
}
}
Model:
package the_wormhole;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import org.lwjgl.BufferUtils;
import org.lwjgl.util.vector.Vector3f;
public class Model {
public ArrayList<Vector3f> vertices = new ArrayList<Vector3f>();
public ArrayList<Vector3f> normals = new ArrayList<Vector3f>();
public ArrayList<Face> faces = new ArrayList<Face>();
private FloatBuffer verticesBuffer;
private FloatBuffer normalsBuffer;
private int verticesVBO;
private int normalsVBO;
private int nrVertices = 0;
public float x = 0, y = 0, z = 0;
public static final int X_AXIS = 0, Y_AXIS = 1, Z_AXIS = 2;
public boolean isPlainFloor = false;
public Model() {
glEnable(GL_COLOR_MATERIAL);
verticesVBO = glGenBuffers();
normalsVBO = glGenBuffers();
x = 0;
y = 0;
z = 0;
}
public ArrayList<Vector3f> getVertices() {
return vertices;
}
public ArrayList<Vector3f> getNormals() {
return normals;
}
public ArrayList<Face> getFaces() {
return faces;
}
public void prepare() {
this.nrVertices = 0;
verticesBuffer = BufferUtils.createFloatBuffer(faces.size() * 9);
for (int i = 0; i < faces.size(); i++) {
Face f = faces.get(i);
Vector3f v1 = vertices.get((int) (f.getVertexIndices()[0] - 1));
verticesBuffer.put(new float[] { v1.x, v1.y, v1.z });
Vector3f v2 = vertices.get((int) (f.getVertexIndices()[1] - 1));
verticesBuffer.put(new float[] { v2.x, v2.y, v2.z });
Vector3f v3 = vertices.get((int) (f.getVertexIndices()[2] - 1));
verticesBuffer.put(new float[] { v3.x, v3.y, v3.z });
nrVertices += 3;
}
System.out.println(faces.size() * 9);
verticesBuffer.flip();
glBindBuffer(GL_ARRAY_BUFFER, verticesVBO);
glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
normalsBuffer = BufferUtils.createFloatBuffer(faces.size() * 9);
for (int i = 0; i < faces.size(); i++) {
Face f = faces.get(i);
Vector3f v1 = normals.get((int) (f.getNormalIndices()[0] - 1));
normalsBuffer.put(new float[] { v1.x, v1.y, v1.z });
Vector3f v2 = normals.get((int) (f.getNormalIndices()[1] - 1));
normalsBuffer.put(new float[] { v2.x, v2.y, v2.z });
Vector3f v3 = normals.get((int) (f.getNormalIndices()[2] - 1));
normalsBuffer.put(new float[] { v3.x, v3.y, v3.z });
}
normalsBuffer.flip();
glBindBuffer(GL_ARRAY_BUFFER, normalsVBO);
glBufferData(GL_ARRAY_BUFFER, normalsBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
public void draw() {
if(verticesBuffer == null)
throw new IllegalStateException("prepare() not called yet");
glMaterialf(GL_FRONT, GL_SHININESS, 128f);
glBindBuffer(GL_ARRAY_BUFFER, normalsVBO);
glNormalPointer(GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, verticesVBO);
glVertexPointer(3, GL_FLOAT, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, nrVertices);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
public void move(int axis, float distance) {
if(verticesBuffer == null)
throw new IllegalStateException("prepare() not called yet");
switch (axis) {
case X_AXIS:
for(int i = 0 ; i < vertices.size() ; i ++){
Vector3f v = vertices.get(i);
v.x += distance;
x = v.x;
}
break;
case Y_AXIS:
for(int i = 0 ; i < vertices.size() ; i ++){
Vector3f v = vertices.get(i);
v.y += distance;
y = v.y;
}
break;
case Z_AXIS:
for(int i = 0 ; i < vertices.size() ; i ++){
Vector3f v = vertices.get(i);
v.z += distance;
z = v.z;
}
break;
default:
break;
}
verticesBuffer = BufferUtils.createFloatBuffer(faces.size() * 9);
for (int i = 0; i < faces.size(); i++) {
Face f = faces.get(i);
Vector3f v1 = vertices.get((int) (f.getVertexIndices()[0] - 1));
verticesBuffer.put(new float[] { v1.x, v1.y, v1.z });
Vector3f v2 = vertices.get((int) (f.getVertexIndices()[1] - 1));
verticesBuffer.put(new float[] { v2.x, v2.y, v2.z });
Vector3f v3 = vertices.get((int) (f.getVertexIndices()[2] - 1));
verticesBuffer.put(new float[] { v3.x, v3.y, v3.z });
nrVertices += 3;
}
verticesBuffer.flip();
glBindBuffer(GL_ARRAY_BUFFER, verticesVBO);
glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
public void cleanUp() {
glDeleteBuffers(verticesVBO);
glDeleteBuffers(normalsVBO);
}
}
Main Class:
package the_wormhole;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.util.glu.GLU.gluPerspective;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.FloatBuffer;
import org.lwjgl.*;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.*;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
public class WormholeMain {
private float rotationX;
private float translationX;
private float translationY;
private float translationZ;
private float rotationY;
private Vector3 walk;
private FloatBuffer fb2 = BufferUtils.createFloatBuffer(4);
private ShaderManager shaderManager;
Model m1, m2, m3, m4, m5, m6;
public WormholeMain() {
fb2.put(new float[] { -2, -2, 0, 0});
fb2.flip();
setUpDisplay();
setUp3dWorld();
walk = new Vector3(0, 0, -1);
wormhole = new Wormhole();
shaderManager = new ShaderManager();
shaderManager.loadShader(GL_VERTEX_SHADER, "shaders/vertexShader.sh");
shaderManager.loadShader(GL_FRAGMENT_SHADER, "shaders/fragmentShader.sh");
shaderManager.prepareProgram();
m1 = loadModelAndPrepare("res/right_up_floor.obj", 0, 0);
m2 = loadModelAndPrepare("res/right_up_floor.obj", 2, 0);
m3 = loadModelAndPrepare("res/right_up_floor.obj", -2, 0);
m4 = loadModelAndPrepare("res/right_up_floor.obj", 0, 2);
m5 = loadModelAndPrepare("res/right_up_floor.obj", 2, 2);
m6 = loadModelAndPrepare("res/right_up_floor.obj", -2, 2);
mainLoop();
cleanUp();
}
private void cleanUp() {
wormhole.cleanUp();
Display.destroy();
}
long thisFrame = System.currentTimeMillis(), lastFrame = System.currentTimeMillis();
float frametime;
private void mainLoop() {
lastFrame = System.currentTimeMillis();
while(!Display.isCloseRequested()){
thisFrame = System.currentTimeMillis();
frametime = (thisFrame - lastFrame) / 1000f;
lastFrame = thisFrame;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.8f, 0.8f, 0.8f, 1);
glLight(GL_LIGHT0, GL_POSITION, fb2);
applyCamera();
shaderManager.useProgram();
m1.draw();
shaderManager.useProgram0();
shaderManager.useProgram();
m2.draw();
shaderManager.useProgram0();
shaderManager.useProgram();
m3.draw();
shaderManager.useProgram0();
shaderManager.useProgram();
m4.draw();
shaderManager.useProgram0();
shaderManager.useProgram();
m5.draw();
shaderManager.useProgram0();
shaderManager.useProgram();
m6.draw();
shaderManager.useProgram0();
Display.update();
Display.sync(60);
}
}
private void setUp3dWorld() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30, 800f/600f, 0.001f, 100);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glEnable(GL_TRIANGLE_FAN);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
FloatBuffer fb1 = BufferUtils.createFloatBuffer(4);
fb1.put(new float[] { 0.05f, 0.05f, 0.05f, 1 });
fb1.flip();
glLightModel(GL_LIGHT_MODEL_AMBIENT, fb1);
glLight(GL_LIGHT0, GL_POSITION, fb2);
glRotatef(-25f, 0, 1, 0);
glRotatef(30f, 1, 0, 0);
glTranslatef(-1.5f, -2.1f, -0.55f);
}
private void setUpDisplay() {
try {
Display.setDisplayMode(new DisplayMode(800, 600));
Display.setTitle("The Wormhole");
Display.setVSyncEnabled(true);
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new WormholeMain();
}
private Model loadModelAndPrepare(String path, float xdistance, float zdistance){
Model m = null;
try {
m = OBJLoader.loadModel(new File(path));
} catch (FileNotFoundException e) {
e.printStackTrace();
return m;
} catch (IOException e) {
e.printStackTrace();
return m;
}
m.prepare();
m.move(Model.X_AXIS, xdistance);
m.move(Model.Z_AXIS, zdistance);
if(path.equals("res/plain_floor.obj"))
m.isPlainFloor = true;
return m;
}
}
Thanks for your help ...
