当前位置: 首页 > 知识库问答 >
问题:

Java LWJGL渲染。obj正确

赫连瑾瑜
2023-03-14

在我的主类下面,我试图从搅拌机渲染一个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)

主要类:

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);
         }
    }
}

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;
    }
}

类别模型:

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(){

    }
}

类面:

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

共有1个答案

邢博文
2023-03-14

你的程序中有几个输入错误。

首先,在OBJLoader类中

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

其次,在面孔课上

public Faces(Vector3f vertex, Vector3f normal) 
{
    this.Vertex = vertex;
    this.normals = normals;
}

将“normals”变量设置为自身,而不是构造函数中的Vector3f,将其更改为此。

    this.normals = normal;
 类似资料:
  • 对于使用Box2DDebugRenderer进行渲染Box2D调试,我有一些问题。我有两个正交摄像机,一个用于渲染世界(名为Cam),另一个用于HUD(healthBar,Armor,…)(名为hudCam)。 我试图渲染: > b2dr。渲染(世界,凸轮组合)- 我找不到一种方法来渲染Box2D完全像凸轮,看到所有机构的边缘。 如果有人理解我的问题,请帮助我! 谢谢。

  • 我有一个MathJax演示,可以在在线演示中查看。 在这个演示中,我在一个div中有一些Tex标记,由MathJax完美渲染。 但是,如果我通过单击按钮,然后单击按钮,以编程方式将一些Tex标记添加到上面的div中,那么它会导致重复渲染以前渲染的Math标记。这可以在以下视频中看到:数学被重复渲染 当点击按钮时,我所做的就是调用以下方法。divElement是通过编程向其添加Tex标记的div。

  • 每当我运行这个,窗口就会弹出,我看到这个。(当我运行游戏时,我看到了这一点) 如果您简单地创建一个新的Java项目,导入OpenGL、GLFW和LWJGL以及本机,然后复制代码,就可以重新创建它(删除包)

  • 我在GeoServer中正确显示国家边界时遇到问题,您可以从下面的链接(意大利地图)中看到。 http://trideg.server.de/tridec/wms?service=WMS 问题出现在边缘非常锋利的国家边界上(我假设),例如阿尔巴尼亚的形状正确地显示: http://trideg.server.de/tridec/wms?service=WMS 我从naturalearthdata.

  • 我看不到子组件内部的文本。子级呈现为大小为0x0且为空。 那是由路由器引起的吗? 这是我的代码: App.js: REPODetails.js: 这是child committersCard.js: 我用的是4号路由器。

  • 在控制台上获取以下第一行: 35026:1978749]CoreText注意:客户端请求的名称“.SFNS-Regular”,它将获得Times-Roman而不是预期的字体。所有系统UI字体访问都应通过适当的API,如CTFontCreateUIFontForLanguage()或[NSFont systemFontOfSize:]。2021 06月09日00:00:46.808 java[350