JREGC

Главная | Регистрация | Вход Приветствую Вас Инопланетяне | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: wawe  
Форум » PROGRAMMING CATEGORY » Уроки LWJGL » Загрузка OBJ моделей.
Загрузка OBJ моделей.
waweДата: Среда, 24.07.2013, 22:01 | Сообщение # 1
Просто человек...
Группа: Администраторы
Сообщений: 50
Награды: 3
Статус: Offline
В этом уроке вы сможете самостоятельно загрузить OBJ модель!
Что такое OBJ?
OBJ — это формат файлов описания геометрии, разработанный в Wavefront Technologies для их анимационного пакета Advanced Visualizer.

Простой OBJ файл начинается с комментариев "#" наша программа на них никак не будет реагировать.
Далее программа читает вершины, в файле OBJ это символ "v. После этого символа идут некие трехмерные координаты.
Они описывают геометрию модели.
После вершин в формате OBJ еще есть нормали, тоже состоят их трехмерных координат. Они нужны для правильного освещения модели и правильного наложения текстур через шейдеры и т.д.
Потом, если в файле OBJ предусмотрено наложение текстур - появляется символ "vt".
Он описывает текстурные координаты модели.
Еще есть vp, но он нам не нужен.
Далее самое главное в формате OBJ, это цифры, которые начинаются после "f ".
Символ "f" строит нам геометрию из кусков: "v", "vt", "vn".
Посмотрим пример:

Код
#Каментарый.
#вершины.
v  -1.968504 0.000000 1.968504     [1]
v  1.968504 0.000000 1.968504      [2]
v  -1.968504 0.000000 -1.968504    [3]
v  1.968504 0.000000 -1.968504     [4]
v  -1.968504 3.937008 1.968504     [5]
v  1.968504 3.937008 1.968504      [6]
v  -1.968504 3.937008 -1.968504    [7]
v  1.968504 3.937008 -1.968504     [8]

#текстурные координаты, да, здесь три координаты(для трехмерных текстур!), по умолчанию третья координата равна 0.
vt  0.000000 0.000000 0.000000     [1]
vt  1.000000 0.000000 0.000000     [2]
vt  0.000000 1.000000 0.000000     [3]
vt  1.000000 1.000000 0.000000     [4]
vt  0.000000 0.000000 0.000000     [5]
vt  1.000000 0.000000 0.000000     [6]
vt  0.000000 1.000000 0.000000     [7]
vt  1.000000 1.000000 0.000000     [8]
vt  0.000000 0.000000 0.000000     [9]
vt  1.000000 0.000000 0.000000     [10]
vt  0.000000 1.000000 0.000000     [11]
vt  1.000000 1.000000 0.000000     [12]

#нормали, тоже три координаты!
vn  0.000000 -2.000000 -0.000000   [1]
vn  0.000000 -1.000000 -0.000000   [2]
vn  0.000000 -1.000000 -0.000000   [3]
vn  0.000000 -2.000000 -0.000000   [4]
vn  0.000000 2.000000 -0.000000    [5]
vn  0.000000 1.000000 -0.000000    [6]
vn  0.000000 1.000000 -0.000000    [7]
vn  0.000000 2.000000 -0.000000    [8]

#грани или "фейсы".
# v/vt/vn v/vt/vn v/vt/vn
f 1/10/1 3/12/3 4/11/4
f 4/11/4 2/9/2 1/10/1
f 5/9/5 6/10/6 8/12/8
f 8/12/8 7/11/7 5/9/5
f 1/5/1 2/6/2 6/8/6
f 6/8/6 5/7/5 1/5/1
f 2/1/2 4/2/4 8/4/8
f 8/4/8 6/3/6 2/1/2
f 4/5/4 3/6/3 7/8/7
f 7/8/7 8/7/8 4/5/4
f 3/1/3 1/2/1 5/4/5
f 5/4/5 7/3/7 3/1/3


Посмотрим на первую строчку, которая начинается с "f "
f 1/10/1 3/12/3 4/11/4
"1/10/1" означает следующее:
первое число 1 - это вершина с индексом [1].
второе число 10 - это текстурные координаты с индексом [10].
третье число 1 - это нормали с индексом [1].
в итоге получаем:
v  -1.968504 0.000000 1.968504     [1]
vt  1.000000 0.000000 0.000000     [10]
vn  0.000000 -2.000000 -0.000000   [1]
И так три раза.
Эти данные, по которой строится вся геометрия, будет читать наша программа!
Начнем?

Код
public final class Model
{
           // список вершин.
           public List<Vector3f> vertex;
           // список текстурных координат.
           public List<Vector3f> texture;
           // список нормалей
           public List<Vector3f> normal;
           // список фейсов.
           public List<Face> face;

           public Model()
           {
               this.vertex = new ArrayList<>();
               this.texture = new ArrayList<>();
               this.normal = new ArrayList<>();
               this.face = new ArrayList<>();
           }
}

public final class Face
{
// это класс Face, который хранит данные о вершинах, коорд. текстур, и нормалей.
           public Vector3f vertex;
           public Vector3f texture;
           public Vector3f normal;

           public Face(Vector3f vertex, Vector3f texture, Vector3f normal)
           {
               this.vertex = new Vector3f();
               this.vertex = vertex;
               this.texture = new Vector3f();
               this.texture = texture;
               this.normal = new Vector3f();
               this.normal = normal;
           }
}

public final class OBJLoader
{
        private OBJLoader()
        {
        }

        // Метод, загружающий модель.
        public static Model loadModel(File file, Model model) throws FileNotFoundException, IOException
        {
            Model m = model;
            String line;
            boolean v = false;
            boolean vn = false;
            boolean vt = false;
            Vector3f vertexIndices = null;
            Vector3f textureIndices = null;
            Vector3f normalIndices = null;
            // Буфер чтения с файла "file". Закрывается автоматически, когда прочитал весь файл.
            try (BufferedReader reader = new BufferedReader(new FileReader(file)))
            {
                // Цикл читает файл, если не пуст.
                while ((line = reader.readLine()) != null)
                {
                    // Если первая строка начинается с mtllib...
                    if (line.startsWith("mtllib "))
                    {
                        // думайте сами.
                    }
                    // Если строка начинается с "v ".
                    if (line.startsWith("v "))
                    {
                        v = true;
                        // Читаем...
                        // Координаты X...
                        float x = Float.valueOf(line.split(" ")[1]);
                        // Y...
                        float y = Float.valueOf(line.split(" ")[2]);
                        // и Z.
                        float z = Float.valueOf(line.split(" ")[3]);
                        // Добавляем в список vertex трехмерный вектор с координатами.
                        m.vertex.add(new Vector3f(x, y, z));
                    }
                    else if (line.startsWith("vn "))
                    {
                        vn = true;
                        // нормали.
                        float x3 = Float.valueOf(line.split(" ")[1]);
                        float y3 = Float.valueOf(line.split(" ")[2]);
                        float z3 = Float.valueOf(line.split(" ")[3]);
                        // Add.
                        m.normal.add(new Vector3f(x3, y3, z3));
                    }
                    else if (line.startsWith("vt "))
                    {
                        //... Далее...
                        vt = true;
                        float x2 = Float.valueOf(line.split(" ")[1]);
                        float y2 = Float.valueOf(line.split(" ")[2]);
                        m.texture.add(new Vector3f(x2, y2, 0.0F));
                    }
                    else if (line.startsWith("f "))
                    {
                        if (v)
                        {
                            // Если программа прочитала вершины, это означает,     
                            // что у нас есть вершины! И их нужно построить! То есть, мы дллжны их добавить в список...
                            vertexIndices = new Vector3f(Float.valueOf(
                       line.split(" ")[1].split("/")[0]),
                       Float.valueOf(line.split(" ")[2].split("/")[0]),
                       Float.valueOf(line.split(" ")[3].split("/")[0]));
                        }
                        if (vt)
                        {
                            // Если программа прочитала текстурные координаты.
                            textureIndices = new Vector3f(Float.valueOf(
                       line.split(" ")[1].split("/")[1]),
                       Float.valueOf(line.split(" ")[2].split("/")[1]),
                       Float.valueOf(line.split(" ")[3].split("/")[1]));
                        }
                        if (vn)
                        {
                            // И нормали. Добавляем их в список, если программа их прочитала!
                            normalIndices = new Vector3f(
                       Float.valueOf(line.split(" ")[1].split("/")[2]),
                       Float.valueOf(line.split(" ")[2].split("/")[2]),
                       Float.valueOf(line.split(" ")[3].split("/")[2]));
                        }
                        // добавляем эту кучу в список face.
                        model.face.add(new Face(vertexIndices, textureIndices, normalIndices));
                    }
                }
            }
            // Возвращает Model.
            return m;
        }
}


Далее, чтобы нарисовать наш OBJ, нужно пройтись по всем спискам.

Код
// Этот код ДОЛЖЕН ВЫПОЛНЯТЬСЯ ВСЕГО ОДИН РАЗ.
               // Создаем Объект "Bunny". Загружаем файл.
               try
               {
                   bunny = OBJLoader.loadModel(new File("resource/engine/models/bunny.obj"), new Model());
               }
               catch (FileNotFoundException ex)
               {
                   Logger.getLogger(SimpleProgram.class.getName()).log(Level.SEVERE, null, ex);
               }
               catch (IOException ex)
               {
                   Logger.getLogger(SimpleProgram.class.getName()).log(Level.SEVERE, null, ex);
               }
               // Создаем список.
               bunnyList = GL11.glGenLists(1); // 1 - ID.
               GL11.glNewList(bunnyList, GL11.GL_COMPILE);
               GL11.glPushMatrix();
               GL11.glScalef(50.5F, 50.5F, 50.5F);
               // Рисуем треугольниками.
               GL11.glBegin(GL11.GL_TRIANGLES);
               for (Face face : bunny.face)
               {
                   // Задаем нормали...
                   Vector3f n1 = bunny.normal.get((int) face.normal.x - 1);
                   GL11.glNormal3f(n1.x, n1.y, n1.z);
                   Vector3f n2 = bunny.normal.get((int) face.normal.y - 1);
                   GL11.glNormal3f(n2.x, n2.y, n2.z);
                   Vector3f n3 = bunny.normal.get((int) face.normal.z - 1);
                   GL11.glNormal3f(n3.x, n3.y, n3.z);

                   // Задаем текстурные координаты...
                   Vector3f vt1 = bunny.texture.get((int) face.texture.x - 1);
                   GL11.glTexCoord2f(vt1.x, vt1.y);
                   Vector3f vt2 = bunny.texture.get((int) face.texture.y - 1);
                   GL11.glTexCoord2f(vt2.x, vt2.y);
                   Vector3f vt3 = bunny.texture.get((int) face.texture.z - 1);
                   GL11.glNormal3f(vt3.x, vt3.y, vt3.z);

                   // Рисуем!
                   Vector3f v1 = bunny.vertex.get((int) face.vertex.x - 1);
                   GL11.glVertex3f(v1.x, v1.y, v1.z);
                   Vector3f v2 = bunny.vertex.get((int) face.vertex.y - 1);
                   GL11.glVertex3f(v2.x, v2.y, v2.z);
                   Vector3f v3 = bunny.vertex.get((int) face.vertex.z - 1);
                   GL11.glVertex3f(v3.x, v3.y, v3.z);
               }
               // Конец.
               GL11.glEnd();
               GL11.glPopMatrix();
               GL11.glEndList();


Чтобы нарисовать модель:
GL11.glCallList(bunnyList);
А когда вы закрывается приложение, всегда удаляйте свой мусор.
GL11.glDeleteLists(bunnyList, 1); // 1 - ID.
Вот и все. В этой программе есть недостатки:
не умеет накладывать программно текстуры на модель.
Надеюсь вам помогла эта информация, если что-то не так, как вы хотели, задавайте вопросы мне.
bunny.obj
http://rghost.ru/47071480

Добавлено (24.07.2013, 22:01)
---------------------------------------------
j

 
set16384Дата: Суббота, 07.12.2013, 10:43 | Сообщение # 2
Рядовой
Группа: Пользователи
Сообщений: 1
Награды: 0
Репутация: 0
Статус: Offline
Доброго времени суток. А вы бы не могли выложить полный исходный код в архиве, я не могу понять как собрать, выше указанный, скрипт
 
iXNomadДата: Воскресенье, 29.12.2013, 20:03 | Сообщение # 3
Рядовой
Группа: Пользователи
Сообщений: 7
Награды: 1
Репутация: 0
Статус: Offline
Перезалей 3D модель :'(
 
Форум » PROGRAMMING CATEGORY » Уроки LWJGL » Загрузка OBJ моделей.
  • Страница 1 из 1
  • 1
Поиск:

Copyright MyCorp © 2024
Используются технологии uCoz