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 модель :'(
|
|
| |