Как мне проанализировать файлы .obj с C ++ в OpenGL (например, с помощью libobj или другой библиотеки)? - PullRequest
2 голосов
/ 16 ноября 2011

Я пытаюсь использовать libobj для анализа файла .obj, экспортированного из Blender.На веб-сайте http://people.cs.kuleuven.be/~ares.lagae/libobj/index.html я получил libobj, а 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;
    }

Скомпилировать с: g++ -Wall -o main main.cpp -lGL -lGLU -lglut -lobj

Ответы [ 2 ]

3 голосов
/ 16 ноября 2011

Проверьте ссылку (http://people.cs.kuleuven.be/~ares.lagae/libobj/obj-0.1/doc/html/classobj_1_1obj__parser.html). Существует несколько обратных вызовов, которые вы можете использовать для визуализации вашей геометрии.

.OBJ - довольно простой и понятный формат. Я думаю, что не так уж сложно написать парсер иэто может быть интересным опытом обучения.

2 голосов
/ 17 ноября 2011

Я знаю, что это не совсем тот вопрос, который вы задавали, поскольку вы хотите использовать 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();
    }
}
...