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

LWJGL的显示问题

潘楚
2023-03-14

编辑:我已经回答了这个问题,代码已经被更改,所以它是可用的,请在您自己的项目中随意使用代码。你好,利亚姆

我目前正在LWJGL中进行3D模型渲染,我遇到了一个问题,当我运行程序时,显示会出现,并且一切都与模型无关。我测试了3D空间代码,绘制了一些随机点,我可以看到它们并四处走动,所以我的3D空间代码正在工作,但模型代码不行。

我的问题如下:我的显示代码有问题吗?还是我的模型加载代码有问题?下面是我的源代码(很抱歉,代码太长了,但我无法缩短)。

主要游戏主题:

public class GameThread implements Runnable {

private boolean running;
private Camera cam = new Camera(0, 0, 0, 0, 0.25f, 25, new int[] {Keyboard.KEY_W, Keyboard.KEY_S, Keyboard.KEY_A, Keyboard.KEY_D});
private Model testModel;

@Override
public void run() 
{
    initialize();

    while(running)
    {
        if(Display.isCloseRequested())
            tryClose();

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        tick();
        Display.update();
    }

    close();
}

private void initialize()
{
    try
    {
        Display.setTitle("Test Game");
        Display.setDisplayMode(new DisplayMode(1280, 768));
        Display.setVSyncEnabled(true);
        Display.create();

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective((float) 30, 1024f / 768f, 0.001f, 100);
        glMatrixMode(GL_MODELVIEW);

        glEnable(GL_DEPTH_TEST);
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);
        glEnable(GL_ALPHA_TEST);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

        testModel = new Model(this.getClass().getClassLoader().getResource("res\\untitled.obj"), new Vector3f(0, 0, 0), new Vector3f(0, 0, 0));
        cam.setPosition(new Vector3f(0, 0, -10));

        running = true;
    }
    catch(Exception e)
    {
        Display.destroy();
        e.printStackTrace();
        System.exit(1);
    }
}

private void tick()
{   
    cam.update();

    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    testModel.draw();
}

private void tryClose()
{
    running = false;
}

private void close()
{
    Display.destroy();
}

模型加载/渲染代码:

public class Model {

private HashMap<String, ModelGroup> groups = new HashMap<String, ModelGroup>();
private Vector3f position, rotation;

public Model(URL modelLocation, Vector3f position, Vector3f rotation)
{
    this.setPosition(position);
    this.setRotation(rotation);

    try
    {
        BufferedReader in = new BufferedReader(new InputStreamReader(modelLocation.openStream()));

        String line;
        ModelGroup group = new ModelGroup("default");

        while((line = in.readLine()) != null)
        {
            if(line.startsWith("g "))
            {
                String newGroupName = (new StringTokenizer(line)).nextToken();

                if(newGroupName.equals(group.getGroupName()))
                    continue;

                groups.put(group.getGroupName(), group);
                group = new ModelGroup(newGroupName);
            }
            else if(line.startsWith("v "))
            {
                StringTokenizer vertices = new StringTokenizer(line);

                vertices.nextToken(); // Skips 'v'

                float x, y, z, w = 1;

                x = Float.valueOf(vertices.nextToken());
                y = Float.valueOf(vertices.nextToken());
                z = Float.valueOf(vertices.nextToken());

                if(vertices.hasMoreTokens())
                    w = Float.valueOf(vertices.nextToken());
                else
                    w = 1;

                group.addVertice(new Vector4f(x, y, z, w));                 
            }
            else if(line.startsWith("vn "))
            {
                StringTokenizer normalVertices = new StringTokenizer(line);

                normalVertices.nextToken(); // Skips 'vn'

                float x, y, z;

                x = Float.valueOf(normalVertices.nextToken());
                y = Float.valueOf(normalVertices.nextToken());
                z = Float.valueOf(normalVertices.nextToken());

                group.addNormal(new Vector3f(x, y, z));
            }
            else if(line.startsWith("vt "))
            {
                StringTokenizer textureVertices = new StringTokenizer(line);

                textureVertices.nextToken(); // Skips 'vt'

                float u, v, w;

                u = Float.valueOf(textureVertices.nextToken());

                if(textureVertices.hasMoreTokens())
                    v = Float.valueOf(textureVertices.nextToken());
                else
                    v = 0;

                if(textureVertices.hasMoreTokens())
                    w = Float.valueOf(textureVertices.nextToken());
                else
                    w = 0;

                group.addTextureCoordinate(new Vector3f(u, v, w));
            }
            else if(line.startsWith("f "))
            {
                StringTokenizer token = new StringTokenizer(line.replace('f', ' '));
                String[] indices = new String[token.countTokens()];

                int polygon_type = (indices.length == 3 ? GL_TRIANGLES : GL_QUADS);

                for(int i = 0; i < indices.length; i++)
                    indices[i] = token.nextToken();

                int mode = 0;

                if(line.contains("//"))
                    mode = 3;

                if(mode != 3)
                    if(indices[0].split("/").length == 2)
                        mode = 1;
                    else if(indices[0].split("/").length == 3)
                        mode = 2;

                if(mode == 0)
                {
                    Vector4f vertices = new Vector4f();
                    vertices.set(Float.valueOf(indices[0]), Float.valueOf(indices[1]), Float.valueOf(indices[2]), (indices.length == 4 ? Float.valueOf(indices[3]) : -1));

                    group.addFace(new ModelFace(vertices).setPolygonType(polygon_type));
                }
                else if(mode == 1)
                {
                    float x, y, z, vw;
                    float u, v, tw;

                    x = Float.valueOf(indices[0].split("/")[0]);
                    y = Float.valueOf(indices[1].split("/")[0]);
                    z = Float.valueOf(indices[2].split("/")[0]);

                    if(indices.length == 4)
                        vw = Float.valueOf(indices[3].split("/")[0]);
                    else
                        vw = -1;

                    u = Float.valueOf(indices[0].split("/")[1]);
                    v = Float.valueOf(indices[1].split("/")[1]);
                    tw = Float.valueOf(indices[2].split("/")[1]);

                    group.addFace(new ModelFace(new Vector4f(x, y, z, vw), new Vector3f(u, v, tw), new Vector3f(-1, 0, 0)).setPolygonType(polygon_type));
                }
                else if(mode == 2)
                {
                    float vx, vy, vz, vw;
                    float u, v, tw;
                    float nx, ny, nz;

                    vx = Float.valueOf(indices[0].split("/")[0]);
                    vy = Float.valueOf(indices[1].split("/")[0]);
                    vz = Float.valueOf(indices[2].split("/")[0]);

                    if(indices.length == 4)
                        vw = Float.valueOf(indices[3].split("/")[0]);
                    else
                        vw = -1;

                    u = Float.valueOf(indices[0].split("/")[1]);
                    v = Float.valueOf(indices[1].split("/")[1]);
                    tw = Float.valueOf(indices[2].split("/")[1]);

                    nx = Float.valueOf(indices[0].split("/")[2]);
                    ny = Float.valueOf(indices[1].split("/")[2]);
                    nz = Float.valueOf(indices[2].split("/")[2]);

                    group.addFace(new ModelFace(new Vector4f(vx, vy, vz, vw), new Vector3f(u, v, tw), new Vector3f(nx, ny, nz)).setPolygonType(polygon_type));
                }
                else if(mode == 3)
                {
                    float vx, vy, vz, vw;
                    float nx, ny, nz;

                    System.out.println(indices[0]);

                    vx = Float.valueOf(indices[0].split("//")[0]);
                    vy = Float.valueOf(indices[1].split("//")[0]);
                    vz = Float.valueOf(indices[2].split("//")[0]);

                    if(indices.length == 4)
                        vw = Float.valueOf(indices[3].split("//")[0]);
                    else
                        vw = -1;

                    nx = Float.valueOf(indices[0].split("//")[1]);
                    ny = Float.valueOf(indices[1].split("//")[1]);
                    nz = Float.valueOf(indices[2].split("//")[1]);

                    group.addFace(new ModelFace(new Vector4f(vx, vy, vz, vw), new Vector3f(-1, 0, 0), new Vector3f(nx, ny, nz)).setPolygonType(polygon_type));
                }
            }
        }

        groups.put(group.getGroupName(), group);
        in.close();
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}   

public Vector3f getPosition() {
    return position;
}

public void setPosition(Vector3f position) {
    this.position = position;
}

public Vector3f getRotation() {
    return rotation;
}

public void setRotation(Vector3f rotation) {
    this.rotation = rotation;
}

public void draw()
{
    ArrayList<ModelGroup> groups = new ArrayList<ModelGroup>(this.groups.values());

    for(int i = 0; i < groups.size(); i++)
        drawGroup(groups.get(i).getGroupName());
}

public void drawGroup(String name)
{
    ModelGroup group = groups.get(name);

    if(group == null)
        return;

    glPushMatrix();
    {
        glRotatef(rotation.x, 1, 0, 0);
        glRotatef(rotation.y, 0, 1, 0);
        glRotatef(rotation.z, 0, 0, 1);
        glTranslatef(position.x, position.y, position.z);

        for(ModelFace face : group.getFaces())
        {
            glBegin(face.getPolygonType());
            {
                for(int id = 0; id < 3; id++)
                {
                    Vector4f vertex = group.getVertices().get(face.getVerticeIndex(id));
                    glVertex4f(vertex.x, vertex.y, vertex.z, vertex.w);

                    if(face.hasTextureCoordinates())
                    {
                        Vector3f textureCoordinate = group.getTextureCoordinates().get(face.getTextureCoordinateIndex(id));
                        glTexCoord3f(textureCoordinate.x, textureCoordinate.y, textureCoordinate.z);
                    }

                    if(face.hasNormals())
                    {
                        Vector3f normal = group.getNormals().get(face.getNormalIndex(id));
                        glNormal3f(normal.x, normal.y, normal.z);
                    }
                }

                if(face.getPolygonType() == GL_QUADS)
                {
                    Vector4f vertex = group.getVertices().get(face.getVerticeIndex(3));
                    glVertex4f(vertex.x, vertex.y, vertex.z, vertex.w);
                }
            }
            glEnd();
        }
    }
    glPopMatrix();
}

//====================================================================================================//

private class ModelGroup
{
    private final String groupName;

    private ArrayList<Vector4f> vertices = new ArrayList<Vector4f>();
    private ArrayList<Vector3f> normals = new ArrayList<Vector3f>();
    private ArrayList<Vector3f> textureCoordinates = new ArrayList<Vector3f>();
    private ArrayList<ModelFace> faces = new ArrayList<ModelFace>();

    public ModelGroup(String name) {
        this.groupName = name;
    }

    public String getGroupName() {
        return this.groupName;
    }

    public void addVertice(Vector4f vertice) {
        this.vertices.add(vertice);
    }

    public ArrayList<Vector4f> getVertices() {
        return this.vertices;
    }

    public void addNormal(Vector3f normal) {
        this.normals.add(normal);
    }

    public ArrayList<Vector3f> getNormals() {
        return this.normals;
    }

    public void addTextureCoordinate(Vector3f coordinate) {
        this.textureCoordinates.add(coordinate);
    }

    public ArrayList<Vector3f> getTextureCoordinates() {
        return this.textureCoordinates;
    }

    public void addFace(ModelFace face) {
        this.faces.add(face);
    }

    public ArrayList<ModelFace> getFaces() {
        return this.faces;
    }
}

private class ModelFace {

    private Vector4f vertices;
    private Vector3f textureCoordinates, normals;
    private int POLYGON_TYPE = 0;

    private boolean hasTextureCoords = true, hasNormals = true;

    public ModelFace(Vector4f vertices) {
        this(vertices, new Vector3f(-1, 0, 0), new Vector3f(-1, 0, 0));
    }

    public ModelFace(Vector4f vertices, Vector3f textureCoordinates, Vector3f normals)
    {
        this.vertices = vertices;
        this.textureCoordinates = textureCoordinates;
        this.normals = normals;

        if(this.textureCoordinates.x == -1)
            this.hasTextureCoords = false;

        if(this.normals.x == -1)
            this.hasNormals = false;
    }

    public boolean hasTextureCoordinates() {
        return this.hasTextureCoords;
    }

    public boolean hasNormals() {
        return this.hasNormals;
    }

    public int getVerticeIndex(int id)
    {
        if(id == 0)
            return (int)vertices.x - 1;
        else if(id == 1)
            return (int)vertices.y - 1;
        else if(id == 2)
            return (int)vertices.z - 1;
        else if(id == 3)
            return (int)vertices.w - 1;
        else
            return -1;
    }

    public int getTextureCoordinateIndex(int id)
    {
        if(id == 0)
            return (int)textureCoordinates.x - 1;
        else if(id == 1)
            return (int)textureCoordinates.y - 1;
        else if(id == 2)
            return (int)textureCoordinates.z - 1;
        else
            return -1;
    }

    public int getNormalIndex(int id)
    {
        if(id == 0)
            return (int)textureCoordinates.x - 1;
        else if(id == 1)
            return (int)textureCoordinates.y - 1;
        else if(id == 2)
            return (int)textureCoordinates.z - 1;
        else
            return -1;
    }

    public ModelFace setPolygonType(int type) {
        this.POLYGON_TYPE = type;
        return this;
    }

    public int getPolygonType() {
        return this.POLYGON_TYPE;
    }
}
}

谢谢,利亚姆。

共有1个答案

章安宜
2023-03-14

好的,我解决了这个问题。

它位于模型构造函数代码中,当 while 循环完成时,它没有将最后一个组添加到列表中。这意味着,如果只有一个组(或没有组),则不会将其添加到列表中,也不会呈现。

我已经更改了问题中的模型代码,因此它是可用的,请随时在您的项目中使用它

亲切的问候,利亚姆

 类似资料:
  • 我创建了一个JFrame,其中包含一个JSplitPane,它在左侧包含一个画布,在右侧包含一个JPanel。画布包含LWJGL显示,而JPanel中几乎没有JTextFields。问题是,当我按下LWJGL显示器上的鼠标按钮时,我无法再将文本写入JTextFields。当我最小化应用程序并将其返回时,它会一直工作,直到我再次按下显示器。 为什么我会遇到这个问题?我怎么能修好它? 注意:我可以专注

  • 有问题显示纹理在我的3D框在LWJGL使用光滑。早些时候我犯了一个错误: BasicShader类: BasicVertex.vs basicfragment.fs

  • 我已将 LWJGL 安装到 Java 项目中,但无法导入 Display 类。 给出无法解决的错误。 DisplayMode和其他类也丢失。我在broswer里找不到他们。

  • 我今天下载了LWJGL3,发现它几乎完全重写了。我查阅了一个关于如何创建窗口的教程,但我仍然有创建窗口的问题。 代码运行时没有问题:控制台中没有错误,但窗口没有显示!

  • 我最近发现了如何使用LWJGL和OpenGL渲染3D立方体,我非常激动,我渲染了2000个立方体,并有效地冻结了我的计算机。我听说过诸如显示列表和VBO之类的东西,但即使在谷歌搜索之后,我也不知道如何使用它们。 目前,我有 渲染我的立方体。调用只是渲染一个立方体 其中cap是顶部纹理,side是侧面纹理。 我真正需要的帮助是弄清楚如何使我的代码VBO和/或显示列表兼容,以提高性能。我还认为,如果可

  • 对于一个大学项目,我们需要在Java的5人小组中制作一个游戏。当我们用3D第一人称编写游戏时,我想使用lwjgl。我在运行Ubuntu的家用计算机上编写了一个测试程序。然而,我把它带到了uni,并试图在ArchLinux的机器上运行它,当试图调用Display.create()方法时,它抛出了一个异常。 这是堆栈跟踪: 无法创建可绘制组织。lwjgl。LWJGLException:X Error-