如何在OpenGL上使用C ++解析.obj文件(例如使用libobj或其他库)?

时间:2011-11-16 19:17:39

标签: opengl blender

我正在尝试使用libobj来解析从Blender导出的.obj文件。 网站http://people.cs.kuleuven.be/~ares.lagae/libobj/index.htmllibobj来自http://en.wikipedia.org/wiki/Wavefront_Object_file_format的地方 描述了.obj文件格式的细节。 libobj网站 有一个关于如何解析顶点的例子,我在其中详细阐述过 以下代码。

但是我不确定如何解析面和渲染 他们在OpenGL中。我是否必须使用顶点列表或服务器端缓冲区对象? 如何扩展下面的代码以使其正确渲染面部?

#include <GL/glut.h>
#include <obj.hpp>
#include <iostream>

    void geometric_vertex_callback(obj::float_type x, obj::float_type y, obj::float_type z)
    {
      std::cout << "v " << x << " " << y << " " << z << "\n";
      glVertex3f(x, y, z);
    }

    void display() {
      glClear(GL_COLOR_BUFFER_BIT);
      obj::obj_parser obj_parser;
      obj_parser.geometric_vertex_callback(geometric_vertex_callback);
      std::cout << std::endl;
      glLoadIdentity();
      gluLookAt(1.0f, 1.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
      glColor3f(1.0f, 1.0f, 1.0f);
      glBegin(GL_POINTS);
      obj_parser.parse("./cube.obj");
      glEnd();
      glFlush();

    }

    void reshape(int h, int w) {

      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(-8.0f, 8.0f, -8.0f, 8.0f, -10.0f, 10.0f);
      glViewport(0, 0, w, h);
      glMatrixMode(GL_MODELVIEW);

    }

    int main(int argc, char **argv) {
      glutInit(&argc, argv);
      glutInitDisplayMode(GLUT_RGB);
      glutCreateWindow("cube");
      glutDisplayFunc(display);
      glutReshapeFunc(reshape);
      glutMainLoop();
      return 0;
    }

编译:{{1​​}}

2 个答案:

答案 0 :(得分:3)

检查参考文献(http://people.cs.kuleuven.be/~ares.lagae/libobj/obj-0.1/doc/html/classobj_1_1obj__parser.html)。您可以使用多个回调来渲染几何体。

.OBJ是一种非常简单直接的格式。我认为编写解析器并不困难,这可能是一种有趣的学习体验。

答案 1 :(得分:2)

我知道这不是你要问的问题,因为你想使用libobj,但我发现自己学习如何做一些事情比使用预制的库要好得多。我实际上刚刚为我的程序完成了一个简单的.obj阅读器。我会在这里发布它以帮助你入门。

请注意,它包含一些特定于我的实现的代码(即我如何处理我的顶点缓冲区等),它仍然只处理包含单个对象的目标文件。但是希望这会让你走上正轨。

另外,我按照我在网上发现的一个教程(不记得哪个),所以我不能全力以赴。

private class Face{
    public int[] v;
    public int[] vt;
    public int[] vn;

    public Face(){
        v = new int[3];
        vt = new int[3];
        vn = new int[3];
        for(int i = 0; i < 3; i++){
            v[i] = vt[i] = vn[i] = -1;
        }
    }
}

public void readObjFile(String fileName){
    Reader r;
    try{
        r = new FileReader(fileName);

        BufferedReader reader = new BufferedReader(r);
        String line = null;
        int lineNo = 0;
        float[] floatTemp = new float[3];
        int[] intTemp = new int[3];

        ArrayList<Face> faces = new ArrayList<Face>();
        ArrayList<Vector3> v = new ArrayList<Vector3>();
        ArrayList<Vector2> vt = new ArrayList<Vector2>();
        ArrayList<Vector3> vn = new ArrayList<Vector3>();

        while((line = reader.readLine()) != null){
            ++lineNo;

            String[] elements = line.split("\\s+");

            if(elements.length > 0){
                if(elements[0].equals("v")){
                    if(elements.length < 4){
                        System.out.println("Something is wrong with the obj loading");
                    }
                    else{
                        //mVertexBuffer.addVertex(new Vector3(Float.parseFloat(elements[1]), Float.parseFloat(elements[2]),Float.parseFloat(elements[3])));
                        v.add(new Vector3(Float.parseFloat(elements[1]), Float.parseFloat(elements[2]),Float.parseFloat(elements[3])));
                    }
                }
                else if(elements[0].equals("vt")){
                    if(elements.length < 3){
                        System.out.println("Something is wrong with the obj loading");
                    }
                    else{
                        //mVertexBuffer.addTextureCoord(new Vector2(Float.parseFloat(elements[1]), Float.parseFloat(elements[2])));
                        vt.add(new Vector2(Float.parseFloat(elements[1]), 1.0f - Float.parseFloat(elements[2])));
                    }
                }
                else if(elements[0].equals("vn"))
                {
                    if(elements.length < 4){
                        System.out.println("Something is wrong with the obj loading");
                    }
                    else{
                        //mVertexBuffer.addVertex(new Vector3(Float.parseFloat(elements[1]), Float.parseFloat(elements[2]),Float.parseFloat(elements[3])));
                        vn.add(new Vector3(Float.parseFloat(elements[1]), Float.parseFloat(elements[2]),Float.parseFloat(elements[3])));
                    }
                }
                else if(elements[0].equals("f")){
                    if(elements.length != 4){
                        System.out.println("Something is wrong with the obj loading");
                    }
                    else{
                        //if(mIndexBuffer == null){
                        //  mIndexBuffer = new IndexBuffer(mGl);
                        //}

                        Face newFace = new Face();

                        for (int i = 1; i < 4; i++) {
                            String seg = elements[i];

                            if(seg.indexOf("/") > 0) 
                            {
                                String[] faceOrder = seg.split("/");

                                if (faceOrder.length > 0) {
                                    //mIndexBuffer.addIndex(Integer.valueOf(faceOrder[0]) - 1);
                                    newFace.v[i - 1] = Integer.valueOf(faceOrder[0]) - 1;
                                }

                                if (faceOrder.length > 1) {
                                    if(faceOrder[1].length() > 0){
                                        //f.uvIndices.add(Integer.valueOf(faceOrder[1]));
                                        newFace.vt[i - 1] = Integer.valueOf(faceOrder[1]) - 1;
                                    }
                                }

                                if (faceOrder.length > 2) {
                                    //f.normalIndices.add(Integer.valueOf(faceOrder[2]));
                                    newFace.vn[i - 1] = Integer.valueOf(faceOrder[2]) - 1;
                                }
                            }
                            else 
                            {
                                if (seg.length() > 0) {
                                    //mIndexBuffer.addIndex(Integer.valueOf(seg) - 1);
                                    newFace.v[i - 1] = Integer.valueOf(seg) - 1;
                                }
                            }
                        }

                        faces.add(newFace);
                    }
                }
            }
        }

        // Now do post process
        for(int i = 0; i < faces.size(); i++){
            mVertexBuffer.addVertex(v.get(faces.get(i).v[0]));
            mVertexBuffer.addVertex(v.get(faces.get(i).v[1]));
            mVertexBuffer.addVertex(v.get(faces.get(i).v[2]));
            if(vt.size() > 0){
                mVertexBuffer.addTextureCoord(vt.get(faces.get(i).vt[0]));
                mVertexBuffer.addTextureCoord(vt.get(faces.get(i).vt[1]));
                mVertexBuffer.addTextureCoord(vt.get(faces.get(i).vt[2]));
            }
        }
    }
    catch(IOException e){
        e.printStackTrace();
    }
}