Java LWJGL 正确渲染 .obj
Java LWJGL rendering .obj correctly
在我的主要 class 下方,我试图从 blender .obj 文件中渲染一个 obj,然后将其重新格式化为(据推测)为我的渲染工作它给出了错误。我该如何解决这个问题?
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at flow_control.MainLoop.render(MainLoop.java:85)
at flow_control.MainLoop.main(MainLoop.java:45)
主要class:
package flow_control;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.util.glu.GLU;
import org.lwjgl.util.vector.Vector3f;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;
import static org.lwjgl.opengl.GL11.*;
public class MainLoop {
MainLoop(){
camera = new Camera(this);
loadTextures();
}
private static final int WIDTH = 1280
private static final int HEIGHT = 700;
boolean[] keys = new boolean[256];
Camera camera;
Texture TexFloor;
Texture TexWhite;
Model m = null;
public static void main(String[] args) {
System.out.println("S");
try {
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
MainLoop game = new MainLoop();
game.load();
game.loadTextures();
while(!Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
game.update();
game.render();
Display.update();
Display.sync(60);
}
Display.destroy();
System.exit(0);
}
private void loadTextures(){
try{
TexFloor = TextureLoader.getTexture("JPG", ResourceLoader.getResourceAsStream("res/floor.jpg"));
}catch(FileNotFoundException e) {
System.err.println("Could not find textures");
e.printStackTrace();
}catch(IOException e){
System.err.println("IO problem");
e.printStackTrace();
}
}
public void render() {
clearScreen();
camera.translatePostion();
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(0, 0, 0);
glTexCoord2f(128/8, 0);
glVertex3f(500, 0, 0);
glTexCoord2f(128/8, 128/8);
glVertex3f(500, 0, 500);
glTexCoord2f(0, 128/8);
glVertex3f(0, 0, 500);
glEnd();
glBegin(GL_TRIANGLES);
for (Faces face : m.faces) {
//error occurs on the line below
Vector3f n1 = m.normals.get((int) face.normals.x - 1);
glNormal3f(n1.x, n1.y, n1.z);
Vector3f v1 = m.vertices.get((int) face.Vertex.x - 1);
glNormal3f(v1.x, v1.y, v1.z);
Vector3f n2 = m.normals.get((int) face.normals.y - 1);
glNormal3f(n2.x, n2.y, n2.z);
Vector3f v2 = m.vertices.get((int) face.Vertex.y - 1);
glNormal3f(v2.x, v2.y, v2.z);
Vector3f n3 = m.normals.get((int) face.normals.z - 1);
glNormal3f(n3.x, n3.y, n3.z);
Vector3f v3 = m.vertices.get((int) face.Vertex.z - 1);
glNormal3f(v3.x, v3.y, v3.z);
}
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
TexFloor.bind();
}
public void load() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLU.gluPerspective((float) 100, WIDTH/HEIGHT, 0.001f, 1000);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
try{
m = OBJLoader.loadModel(new File("res/tree.obj"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void clearScreen() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
}
public void update() {
mapKeys();
camera.update();
}
private void mapKeys(){
for(int i=0;i<keys.length; i++) {
keys[i] = Keyboard.isKeyDown(i);
}
}
}
Class OBJLoader:
package flow_control;
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){
//parse object
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 Faces(vertexIndices, normalIndices));
}
}
reader.close();
return m;
}
}
Class 型号:
package flow_control;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.util.vector.Vector3f;
public class Model {
public List<Vector3f> vertices = new ArrayList<Vector3f>();
public List<Vector3f> normals = new ArrayList<Vector3f>();
public List<Faces> faces = new ArrayList<Faces>();
public Model(){
}
}
Class 面孔:
package flow_control;
import org.lwjgl.util.vector.Vector3f;
public class Faces {
public Vector3f Vertex = new Vector3f();
public Vector3f normals = new Vector3f();
public Faces(Vector3f vertex, Vector3f normal) {
this.Vertex = vertex;
this.normals = normals;
}
}
抱歉,如果其中一些内容过多,我知道第 85 行出现错误,但我似乎无法弄清楚如何修复它。
OBJ 文件示例(精简):
# Blender v2.74 (sub 0) OBJ File: ''
# www.blender.org
mtllib tree.mtl
o Mesh_default
v -0.163260 2.023340 -0.247879
v 0.163260 2.023340 -0.247878
v 0.163260 2.023340 0.247879
f 35//34 39//40 36//35
f 36//35 40//39 37//36
f 38//37 34//41 41//38
vn -0.259900 0.445500 -0.856700
vn 0.087800 0.445500 -0.891000
vn -0.422000 0.445500 -0.789600
你的程序中有几个错别字。
首先, 在您的 OBJLoader class
else if (line.startsWith("vm "))
它正在 OBJ 文件中查找以 "vm " 开头但您的 obj 文件使用 "vn " 的行。只需更改它,数组将不再为空。
vn -0.259900 0.445500 -0.856700
vn 0.087800 0.445500 -0.891000
vn -0.422000 0.445500 -0.789600
其次,在人脸class
public Faces(Vector3f vertex, Vector3f normal)
{
this.Vertex = vertex;
this.normals = normals;
}
您正在将 "normals" 变量设置为等于自身而不是构造函数中的 Vector3f,请将其更改为此。
this.normals = normal;
在我的主要 class 下方,我试图从 blender .obj 文件中渲染一个 obj,然后将其重新格式化为(据推测)为我的渲染工作它给出了错误。我该如何解决这个问题?
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at flow_control.MainLoop.render(MainLoop.java:85)
at flow_control.MainLoop.main(MainLoop.java:45)
主要class:
package flow_control;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.util.glu.GLU;
import org.lwjgl.util.vector.Vector3f;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;
import static org.lwjgl.opengl.GL11.*;
public class MainLoop {
MainLoop(){
camera = new Camera(this);
loadTextures();
}
private static final int WIDTH = 1280
private static final int HEIGHT = 700;
boolean[] keys = new boolean[256];
Camera camera;
Texture TexFloor;
Texture TexWhite;
Model m = null;
public static void main(String[] args) {
System.out.println("S");
try {
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
MainLoop game = new MainLoop();
game.load();
game.loadTextures();
while(!Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
game.update();
game.render();
Display.update();
Display.sync(60);
}
Display.destroy();
System.exit(0);
}
private void loadTextures(){
try{
TexFloor = TextureLoader.getTexture("JPG", ResourceLoader.getResourceAsStream("res/floor.jpg"));
}catch(FileNotFoundException e) {
System.err.println("Could not find textures");
e.printStackTrace();
}catch(IOException e){
System.err.println("IO problem");
e.printStackTrace();
}
}
public void render() {
clearScreen();
camera.translatePostion();
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(0, 0, 0);
glTexCoord2f(128/8, 0);
glVertex3f(500, 0, 0);
glTexCoord2f(128/8, 128/8);
glVertex3f(500, 0, 500);
glTexCoord2f(0, 128/8);
glVertex3f(0, 0, 500);
glEnd();
glBegin(GL_TRIANGLES);
for (Faces face : m.faces) {
//error occurs on the line below
Vector3f n1 = m.normals.get((int) face.normals.x - 1);
glNormal3f(n1.x, n1.y, n1.z);
Vector3f v1 = m.vertices.get((int) face.Vertex.x - 1);
glNormal3f(v1.x, v1.y, v1.z);
Vector3f n2 = m.normals.get((int) face.normals.y - 1);
glNormal3f(n2.x, n2.y, n2.z);
Vector3f v2 = m.vertices.get((int) face.Vertex.y - 1);
glNormal3f(v2.x, v2.y, v2.z);
Vector3f n3 = m.normals.get((int) face.normals.z - 1);
glNormal3f(n3.x, n3.y, n3.z);
Vector3f v3 = m.vertices.get((int) face.Vertex.z - 1);
glNormal3f(v3.x, v3.y, v3.z);
}
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
TexFloor.bind();
}
public void load() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLU.gluPerspective((float) 100, WIDTH/HEIGHT, 0.001f, 1000);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
try{
m = OBJLoader.loadModel(new File("res/tree.obj"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void clearScreen() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
}
public void update() {
mapKeys();
camera.update();
}
private void mapKeys(){
for(int i=0;i<keys.length; i++) {
keys[i] = Keyboard.isKeyDown(i);
}
}
}
Class OBJLoader:
package flow_control;
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){
//parse object
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 Faces(vertexIndices, normalIndices));
}
}
reader.close();
return m;
}
}
Class 型号:
package flow_control;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.util.vector.Vector3f;
public class Model {
public List<Vector3f> vertices = new ArrayList<Vector3f>();
public List<Vector3f> normals = new ArrayList<Vector3f>();
public List<Faces> faces = new ArrayList<Faces>();
public Model(){
}
}
Class 面孔:
package flow_control;
import org.lwjgl.util.vector.Vector3f;
public class Faces {
public Vector3f Vertex = new Vector3f();
public Vector3f normals = new Vector3f();
public Faces(Vector3f vertex, Vector3f normal) {
this.Vertex = vertex;
this.normals = normals;
}
}
抱歉,如果其中一些内容过多,我知道第 85 行出现错误,但我似乎无法弄清楚如何修复它。
OBJ 文件示例(精简):
# Blender v2.74 (sub 0) OBJ File: ''
# www.blender.org
mtllib tree.mtl
o Mesh_default
v -0.163260 2.023340 -0.247879
v 0.163260 2.023340 -0.247878
v 0.163260 2.023340 0.247879
f 35//34 39//40 36//35
f 36//35 40//39 37//36
f 38//37 34//41 41//38
vn -0.259900 0.445500 -0.856700
vn 0.087800 0.445500 -0.891000
vn -0.422000 0.445500 -0.789600
你的程序中有几个错别字。
首先, 在您的 OBJLoader class
else if (line.startsWith("vm "))
它正在 OBJ 文件中查找以 "vm " 开头但您的 obj 文件使用 "vn " 的行。只需更改它,数组将不再为空。
vn -0.259900 0.445500 -0.856700
vn 0.087800 0.445500 -0.891000
vn -0.422000 0.445500 -0.789600
其次,在人脸class
public Faces(Vector3f vertex, Vector3f normal)
{
this.Vertex = vertex;
this.normals = normals;
}
您正在将 "normals" 变量设置为等于自身而不是构造函数中的 Vector3f,请将其更改为此。
this.normals = normal;