Skip to content

Instantly share code, notes, and snippets.

@Zeitheron
Created January 2, 2020 16:07
Show Gist options
  • Save Zeitheron/5941be95e8fc0ccc1dddfe8938f5bd81 to your computer and use it in GitHub Desktop.
Save Zeitheron/5941be95e8fc0ccc1dddfe8938f5bd81 to your computer and use it in GitHub Desktop.
package com.zeitheron.thaumicadditions.client.models.base;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Vector2f;
import org.lwjgl.util.vector.Vector3f;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import static org.lwjgl.opengl.GL11.*;
public class OBJLoader
{
public int createDisplayList(Obj model)
{
int displayList = GL11.glGenLists(1);
GL11.glNewList(displayList, GL_COMPILE);
{
this.render(model);
}
GL11.glEndList();
return displayList;
}
/**
* Renders a given <code>Obj</code> file.
*
* @param model the <code>Obj</code> file to be rendered
*/
public void render(Obj model)
{
GL11.glMaterialf(GL_FRONT, GL_SHININESS, 120);
GL11.glBegin(GL_TRIANGLES);
{
for(Obj.Face face : model.getFaces())
{
Vector3f[] normals = new Vector3f[]{
model.getNormals().get(face.getNormals()[0] - 1),
model.getNormals().get(face.getNormals()[1] - 1),
model.getNormals().get(face.getNormals()[2] - 1)
};
Vector2f[] texCoords = new Vector2f[]{
model.getTextureCoordinates().get(face.getTextureCoords()[0] - 1),
model.getTextureCoordinates().get(face.getTextureCoords()[1] - 1),
model.getTextureCoordinates().get(face.getTextureCoords()[2] - 1)
};
Vector3f[] vertices = new Vector3f[]{
model.getVertices().get(face.getVertices()[0] - 1),
model.getVertices().get(face.getVertices()[1] - 1),
model.getVertices().get(face.getVertices()[2] - 1)
};
{
GL11.glNormal3f(normals[0].getX(), normals[0].getY(), normals[0].getZ());
GL11.glTexCoord2f(texCoords[0].getX(), texCoords[0].getY());
GL11.glVertex3f(vertices[0].getX(), vertices[0].getY(), vertices[0].getZ());
GL11.glNormal3f(normals[1].getX(), normals[1].getY(), normals[1].getZ());
GL11.glTexCoord2f(texCoords[1].getX(), texCoords[1].getY());
GL11.glVertex3f(vertices[1].getX(), vertices[1].getY(), vertices[1].getZ());
GL11.glNormal3f(normals[2].getX(), normals[2].getY(), normals[2].getZ());
GL11.glTexCoord2f(texCoords[2].getX(), texCoords[2].getY());
GL11.glVertex3f(vertices[2].getX(), vertices[2].getY(), vertices[2].getZ());
}
}
}
GL11.glEnd();
}
/**
* @param file the file to be loaded
* @return the loaded <code>Obj</code>
* @throws java.io.FileNotFoundException thrown if the Obj file is not found
*/
public Obj loadModel(File file) throws FileNotFoundException
{
return this.loadModel(new Scanner(file));
}
/**
* @param stream the stream to be loaded
* @return the loaded <code>Obj</code>
*/
public Obj loadModel(InputStream stream)
{
return this.loadModel(new Scanner(stream));
}
/**
* @param sc the <code>Obj</code> to be loaded
* @return the loaded <code>Obj</code>
*/
public Obj loadModel(Scanner sc)
{
Obj model = new Obj();
while(sc.hasNextLine())
{
String ln = sc.nextLine();
if(ln == null || ln.equals("") || ln.startsWith("#"))
{
} else
{
String[] split = ln.split(" ");
switch(split[0])
{
case "v":
model.getVertices().add(new Vector3f(
Float.parseFloat(split[1]),
Float.parseFloat(split[2]),
Float.parseFloat(split[3])
));
break;
case "vn":
model.getNormals().add(new Vector3f(
Float.parseFloat(split[1]),
Float.parseFloat(split[2]),
Float.parseFloat(split[3])
));
break;
case "vt":
model.getTextureCoordinates().add(new Vector2f(
Float.parseFloat(split[1]),
Float.parseFloat(split[2])
));
break;
case "f":
model.getFaces().add(new Obj.Face(
new int[]{
Integer.parseInt(split[1].split("/")[0]),
Integer.parseInt(split[2].split("/")[0]),
Integer.parseInt(split[3].split("/")[0])
},
new int[]{
Integer.parseInt(split[1].split("/")[1]),
Integer.parseInt(split[2].split("/")[1]),
Integer.parseInt(split[3].split("/")[1])
},
new int[]{
Integer.parseInt(split[1].split("/")[2]),
Integer.parseInt(split[2].split("/")[2]),
Integer.parseInt(split[3].split("/")[2])
}
));
break;
case "s":
model.setSmoothShadingEnabled(!ln.contains("off"));
break;
default:
break;
}
}
}
sc.close();
return model;
}
public static class Obj
extends Object
{
private final List<Vector3f> vertices;
private final List<Vector2f> textureCoords;
private final List<Vector3f> normals;
private final List<Face> faces;
private boolean enableSmoothShading;
public Obj(List<Vector3f> vertices, List<Vector2f> textureCoords,
List<Vector3f> normals, List<Face> faces, boolean enableSmoothShading)
{
super();
this.vertices = vertices;
this.textureCoords = textureCoords;
this.normals = normals;
this.faces = faces;
this.enableSmoothShading = enableSmoothShading;
}
public Obj()
{
this(new ArrayList<Vector3f>(), new ArrayList<Vector2f>(),
new ArrayList<Vector3f>(), new ArrayList<Face>(), true);
}
public void enableStates()
{
if(this.isSmoothShadingEnabled())
{
GL11.glShadeModel(GL_SMOOTH);
} else
{
GL11.glShadeModel(GL_FLAT);
}
}
public boolean hasTextureCoordinates()
{
return this.getTextureCoordinates().size() > 0;
}
public boolean hasNormals()
{
return this.getNormals().size() > 0;
}
public List<Vector3f> getVertices()
{
return this.vertices;
}
public List<Vector2f> getTextureCoordinates()
{
return this.textureCoords;
}
public List<Vector3f> getNormals()
{
return this.normals;
}
public List<Face> getFaces()
{
return this.faces;
}
public boolean isSmoothShadingEnabled()
{
return this.enableSmoothShading;
}
public void setSmoothShadingEnabled(boolean isSmoothShadingEnabled)
{
this.enableSmoothShading = isSmoothShadingEnabled;
}
public static class Face
extends Object
{
private final int[] vertexIndices;
private final int[] normalIndices;
private final int[] textureCoordinateIndices;
public boolean hasNormals()
{
return this.normalIndices != null;
}
public boolean hasTextureCoords()
{
return this.textureCoordinateIndices != null;
}
public int[] getVertices()
{
return this.vertexIndices;
}
public int[] getTextureCoords()
{
return this.textureCoordinateIndices;
}
public int[] getNormals()
{
return this.normalIndices;
}
public Face(int[] vertexIndices, int[] textureCoordinateIndices,
int[] normalIndices)
{
super();
this.vertexIndices = vertexIndices;
this.normalIndices = normalIndices;
this.textureCoordinateIndices = textureCoordinateIndices;
}
@Override
public String toString()
{
return String.format("Face[vertexIndices%s normalIndices%s textureCoordinateIndices%s]",
Arrays.toString(vertexIndices), Arrays.toString(normalIndices), Arrays.toString(textureCoordinateIndices));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment