Формат 3d studio mesh, взгляд изнутри

Моя фотка :)
О себе.
Что здесь написать… ну мало что изменилось с момента написания прошлого урока. Разве что только то, что я поступил в Иркутский Гос. Тех. Университет, факультет кибернетики, на специальность Автоматизированные системы управления (на программиста короче:)). И я еще сильнее полюбил gamedeveloping…

Формат 3d studio mesh, взгляд изнутри.
Или как загружать модели из файлов 3ds в программу.

Введение.

Я с этого лета изучаю С++ и OpenGl (точнее в С++ я только повышал навыки))... уже столько информации впитал жуть). Причиной тому послужило то, что я пришел к выводу, что нельзя написать нормальную игру, не вникая в процесс программирования полностью. Вообще поначалу сложно было, но сейчас уже стало легче...

Ооочень большой проблемой стало нахождение обучений на русском языке, в Интернете, да и на полках книжных (... И дело не совсем в том, что книг на данную тему нет, они, безусловно, есть, но в целом везде содержание схоже, дается базис. Самой сильной проблемой (как я потом выяснил по форумам, чатам, сайтам) это является загрузка моделей из файлов, в OpenGl нет встроенных команд для этого, все вводится вручную...

Вот, например так описывается куб, состоящий из 6 граней, которые мы и описываем, причем заметьте – только точки, но есть ведь еще столько же – координаты текстур, координаты фейсов (faces coordinats):

glVertex3f( 0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, -1.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glVertex3f( 1.0f,-1.0f, -1.0f);
glVertex3f(-1.0f,-1.0f, -1.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);

куб в ogl

А если у нас модель хотя бы на 2000 verticles? ;)

Вначале заинтересовали текстовые форматы, их ведь можно легко редактировать, да и читать как-то проще)... Но это потеря времени, ресурсов... И пришел я к 3ds (3d Studio Mesh) , один из самых распространенных форматов хранения 3d сцен, казалось бы, идеальное решение?) это как бы сразу объединение с 3дмаксом... но не тут то было, инфы очень мало, да и на английском она, везде только вопросы как, да нет ответов (компания Autodesk долгое время не выпускала руководства и, потому его пробовали создать отдельные разработчики… да, и последнее такое руководство датировано … 1998 годом! Все же официальное руководство появилось, но такое ощущение, что только чтоб отвязались), хотя примеры в не достаточно полезные, это бесспорно)...
В данном уроке предполагается базовое владение программированием, на C++ или Delphi (в примерах к уроку я использовал С++ для создания программы, где для вывода изображения использовал OpenGL, так как в данной графической библиотеке проблема стоит наиболее остро).

Примечания: в конце урока будет изложено то, как настроить компиляторы C++ на работу с OpenGl, я не привожу эту информацию в начале, так как это не цель урока. Там же приведены ссылки на полезные ресурсы сети, посвященные данной тематике и файлы к уроку.

Итак, настало сказать пока нашему дорогому кубу ( или чайнику) ! :) Стандартно в OGL (OpenGl) нет встроенных возможностей загрузки файлов, иначе говоря, нам предлагается либо написать его самому, либо вводить все координаты вручную, а когда речь идет о тысячах точек (verticles) это просто безумно...

Цели урока:

  1. Понять то, как устроен формат 3d Studio Mesh.
  2. Научиться считывать информацию, содержащуюся в файлах формата 3ds и использовать ее.

Содержание:

  1. Знакомство с 3d Studio Mesh.
  2. Разработка простого приложения. Чтение модели (текстуры, геометрия)
  3. Подробнее о KEYFRAMER CHUNK. Подробности по хранению анимации.
  4. Иерархия объектов.
  5. Как легче узнать какие параметры надо прочитать?
  6. Как настроить компилятор для работы с OpenGL.
  7. Ссылки.
  8. Файлы к уроку.

Знакомимся с 3ds.

В общих чертах мы можем сказать, что 3ds файл содержит полную информацию о 3d сцене, содержащей один или более объектов. Если мы откроем файл в блокноте, что мы увидим? – ничего… лишь перемешанный текст, это потому, что все записано в шестнадцатеричном коде(hexademetrical). Внутреннее же строение файла представляет собой серии блоков называемых на английском – Chunk (кусок или участок памяти, я же буду писать: объект Chunk или просто Chunk). Что же содержится в этих блоках? Все нужное для описания сцены: имена объектов, координаты вершин (vertices coordinates), координаты наложения текстур (mapping coordinates), ключи анимации (animation keyframes) и прочее ...

У объекта chunk нелинейная структура, это значит что элементы, находящиеся по структуре внутри других, читаются только после того, как будут прочитаны (будет получен к ним доступ) элементы их содержащие. Структура имеет вид дерева, такую структуру можно наблюдать на локальных дисках компьютера. Конечно же, необязательно читать все объекты, достаточно прочитать только самые важные.

Древовидная структура

чтобы прочитать элемент 3:2 надо прочитать все в таком порядке - root,1,2,3,3:2.

Каждый chunk состоит из 4 записей:
-Identifier: это число, записанное в шестнадцатеричном формате, размером 2 байта, идентифицирующее chunk. С этой информацией мы можем немедленно узнать, нужен ли он нам. Если нам нужен chunk, мы открываем собранную в нем информацию, если нужно, в его child-элементе (элементы, находящиеся по иерархии внутри данного), однако если он бесполезен, мы пропускаем его, используя следующий параметр…
-Lengthofthechunk: еще одно число, на этот раз размером 4 байта, содержит сумму длины chunk’а и его длинны child-элементов.
-Chunkdata: это поле может иметь разную длину. Реально хранимая информация содержится здесь.

В данной таблице представлена зависимость ветвления и размера в объектах chunk:

Offset Length
0 2 Chunk identifier
2 4 Chunk length: chunk data + sub-chunks(6+n+m)
6 n Data
6+n m Sub-chunks

Иерархия и код наиболее полезных chunk’ов в файле:
MAIN CHUNK 0x4D4D
3D EDITOR CHUNK 0x3D3D
OBJECT BLOCK 0x4000
TRIANGULAR MESH 0x4100
VERTICES LIST 0x4110
FACES DESCRIPTION 0x4120
FACES MATERIAL 0x4130
MAPPING COORDINATES LIST 0x4140
SMOOTHING GROUP LIST 0x4150
LOCAL COORDINATES SYSTEM 0x4160
LIGHT 0x4600
SPOTLIGHT 0x4610
CAMERA 0x4700
MATERIAL BLOCK 0xAFFF
MATERIAL NAME 0xA000
AMBIENT COLOR 0xA010
DIFFUSE COLOR 0xA020
SPECULAR COLOR 0xA030
TEXTURE MAP 1 0xA200
BUMP MAP 0xA230
REFLECTION MAP 0xA220
[SUB CHUNKS FOR EACH MAP]
MAPPING FILENAME 0xA300
MAPPING PARAMETERS 0xA351
KEYFRAMER CHUNK 0xB000 - об особенностях и иерархии данной ветви мы поговорим позже

Важно не забывать при чтении определенного chunk’а, нужно вначале прочитать его отцов (элементов стоящих выше по иерархии). Например, для прочтения chunk’а VERTICES LIST мы должны прочитать MAIN CHUNK, 3D EDITOR CHUNK, OBJECT BLOCK и, наконец, TRIANGULAR MESH. Другие объекты, конечно, могут быть пропущены…

Так же хочу отметить, что в том случае если нам надо прочитать более одного объекта, тогда учитывая то, что создание идет через struct, мы прочитать OBJECTBLOCK еще раз и создать новый объект, используя структуру. Ориентироваться в том, что за объект нам выдал chunk можно по имени прочитанного объекта, как только имя повторилось, идем дальше, так же нужно не забывать проверять, что мы читаем, чтобы не прочитать свет, камеры, когда нам нужен mesh. В своем примере я читаю один объект.

Я предлагаю отбросить некоторые объекты в древе и оставить только ветви с информацией: "vertices", "faces", "mapping coordinates", и их отцов по дереву. Эти объекты мы используем в начальном примере:
MAIN CHUNK 0x4D4D
3D EDITOR CHUNK 0x3D3D
OBJECT BLOCK 0x4000
TRIANGULAR MESH 0x4100
VERTICES LIST 0x4110
FACES DESCRIPTION 0x4120
MAPPING COORDINATES LIST 0x4140

Таблица с более подробным описанием каждого chunk’а:

MAIN CHUNK
Identifier 0x4D4D
Length 0 + Sub-chunks length
Chunk father None
Sub chunks 3D EDITOR CHUNK
Data None
3D EDITOR CHUNK
Identifier 0x3D3D
Length 0 + sub-chunks length
Chunk father MAIN CHUNK
Sub chunks OBJECT BLOCK, MATERIAL BLOCK, KEYFRAMER CHUNK
Data None
OBJECT BLOCK
Identifier 0x4000
Length Object name length + sub-chunks length
Chunk father 3D EDITOR CHUNK
Sub chunks TRIANGULAR MESH, LIGHT, CAMERA
Data Object name
TRIANGULAR MESH
Identifier 0x4100
Length 0 + sub-chunks length
Chunk father TRIANGULAR MESH
Sub chunks None
Data Vertices number (unsigned short)
Vertices list: x1,y1,z1,x2,y2,z2 etc. (for each vertex: 3*float)
FACES DESCRIPTION
Identifier 0x4120
Length varying + sub-chunks length
Chunk father TRIANGULAR MESH
Sub chunks FACES MATERIAL
Data Polygons number (unsigned short)
Polygons list: a1,b1,c1,a2,b2,c2 etc. (for each point: 3*unsigned short)
Face flag: face options, sides visibility etc. (unsigned short)
MAPPING COORDINATES LIST
Identifier 0x4140
Length varying + sub-chunks length
Chunk father TRIANGULAR MESH
Sub chunks SMOOTHING GROUP LIST
Data Vertices number (unsigned short)
Mapping coordinates list: u1,v1,u2,v2 etc. (for each vertex: 2*float)
VERTICES LIST
Identifier 0x4110
Length varying
Chunk father TRIANGULAR MESH
Sub chunks None
Data Vertices number (unsigned short)
Vertices list: x1,y1,z1,x2,y2,z2 etc. (for each vertex: 3*float)

Разработка простого приложения.

В моем примере мы сможем считывать только один объект из файла! (то, как это исправить будет описано в следующей главе.
Итак, для начала берем файл – заготовку, содержащий объявление всех структур OpenGl (template01.zip). Я не буду останавливаться на разъяснении устройства программы, это вы сможете понять и по комментариям.
В принципе мы могли бы хранить все типы в главном исходном коде (main.cpp) программы, но лучшим решением будет расположить их в заголовочном файле (header file, main.h).

#define MAX_VERTICES 8000
#define MAX_POLYGONS 8000

Мы должны указать максимальное количество точек и полигонов, которое будит поддерживать наше приложение.
Теперь мы должны создать файл 3dsLoader.cpp (здесь и будет выполняться загрузка модели). Сюда мы вводим:

char Load3DS (obj_type_ptr p_object, char *p_filename)
{
int i;
FILE *l_file;
unsigned short l_chunk_id;
unsigned int l_chunk_length;
unsigned char l_char;
unsigned short l_qty;
unsigned short l_face_flags;

В Load3DS как параметры передаются указатель на объект структуры данных и имя файла, который надо открыть. Возвращает «0» если файл не найден, если файл найден и прочитан то «1». На самом деле для инициализации нам требуется не так уж и много переменных: счетчик i, указатель на файл *l_file и дополнительная переменная l_char для экстраполяции данных в байт формате.
Остальные переменные:
-unsignedshortl_chunk_id: идентификатор chunk’а, шестнадцатеричное значение в 2 байта.
-unsigned int l_chunk_length: длинна chunk’а, 4 байта.
-unsignedshortl_qty: дополнительный параметр, будет полезен для получения информации о параметрах читаемой информации.
-unsignedshortl_face_flags: запоминает некоторую информацию относительно текущего полигона (видим, не видим и прочее), полезен только 3d редакторов сцены, в нашем случае мы не будем с ним работать, но будем его считывать, чтобы переместиться на следующий chunk. Итак, наконец, откроем файл:

if ((l_file=fopen (p_filename, "rb"))== NULL) return 0; //Open the file
while (ftell (l_file) < filelength (fileno (l_file))) //Loop to scan the whole file
{

while здесь цикл, для прохождения по всему файлу. Функция ftell позволяет нам запрашивать позицию, а filelength возвращает значение длины файла.

fread (&l_chunk_id, 2, 1, l_file); //Read the chunk header
fread (&l_chunk_length, 4, 1, l_file); //Read the length of the chunk


Мы экстраполировали идентификатор и длину chunk’а и сохранили их в in l_chunk_id и l_chunk_length
Теперь мы должны проанализировать и использовать содержимое id:

switch (l_chunk_id)
{
case 0x4d4d:
break;

Итак, мы нашли MAINCHUNK! Замечательно!) Что же мы теперь будем делать? А ничего. По сути, он не содержит данных, нам интересны его под объекты. Если бы мы не включили его в case, мы бы его перепрыгнули! Почему? Об этом позже… А сейчас только скажем, что произойдет, если мы перепрыгнем корневой объект? Правильно, мы окажемся в конце файла… нам это надо?... нет:)

Теперь мы точно так же поступаем с the 3D EDITOR CHUNK, в нем так же нет данных. Так что давайте просто его прочитаем =) и он отправит нас к своим child-элементу… Object Block!

case 0x3d3d:
break;

Итак это Object Block, этот chunk содержит интересную информацию: имя объекта, хранимое в поле name в структуре объекта. Выход их структуры while будет по нахождению знака ’\0’ или количестве знаков бол 20. Но будьте осторожны! Мы прочитали все данные этого chunk’а, это дат нам возможность перейти на следующий.

case 0x4000:
i=0;
do
{
fread (&l_char, 1, 1, l_file);
p_object->name[i]=l_char;
i++;
}while(l_char != '\0' && i<20);
break;

И еще одна пустая ветвь, дающая доступ к chunk’ам, которые нам надо прочитать.

case 0x4100:
break;

Итак это точки (vertices)! VERTICES LIST содержит все точки объекта, для начала мы читаем значение "quantity", затем создаем цикл for, чтобы прочитать все точки. Сохраняем всю информацию внутри структуры object (она описана в заголовочном файле к main.cpp).

case 0x4110:
fread (&l_qty, sizeof (unsigned short), 1, l_file);
p_object->vertices_qty = l_qty;
printf("Number of vertices: %d\n",l_qty);
for (i=0; i<l_qty; i++)
{
fread (&p_object->vertex[i].x, sizeof(float), 1, l_file);
fread (&p_object->vertex[i].y, sizeof(float), 1, l_file);
fread (&p_object->vertex[i].z, sizeof(float), 1, l_file);
}
break;

FACESDESCRIPTION содержит перечень полигонов объекта. Чтение схоже с предыдущим.
Каждый face содержит дополнительно второе поле, содержащее информацию для 3d редакторов (видимые стороны и прочее). Мы, конечно, читаем и их, но лишь для передвижения далее…

case 0x4120:
fread (&l_qty, sizeof (unsigned short), 1, l_file);
p_object->polygons_qty = l_qty;
printf("Number of polygons: %d\n",l_qty);
for (i=0; i<l_qty; i++)
{
fread (&p_object->polygon[i].a, sizeof (unsigned short), 1, l_file);
fread (&p_object->polygon[i].b, sizeof (unsigned short), 1, l_file);
fread (&p_object->polygon[i].c, sizeof (unsigned short), 1, l_file);
fread (&l_face_flags, sizeof (unsigned short), 1, l_file);
}
break;

Последним в данном примере мы читаем MAPPING COORDINATES LIST, так же как обычно вначале читаем quantity, затемлист координат, только теперь одна очко будет иметь 2 координаты, так как наложение идет в двумерном пространстве, U и V, припоминается?)

case 0x4140:
fread (&l_qty, sizeof (unsigned short), 1, l_file);
for (i=0; i<l_qty; i++)
{
fread (&p_object->mapcoord[i].u, sizeof (float), 1, l_file);
fread (&p_object->mapcoord[i].v, sizeof (float), 1, l_file);
}
break;

Замечательно! Case – default! Это значит, что на этом рутинная работа закончена, когда у нас на пути chunks, которые нам читать не нужно нам поможет функция fseek, используя информацию из chunk_length, она переводит нас на начало следующего chunk.

default:
fseek(l_file, l_chunk_length-6, SEEK_CUR);
}
}

На этом и конец этого примера. Правда осталась только одна мелочь: давайте закроем файл и возвратим 1!

fclose (l_file); // Closes the file stream
return (1); // Returns ok
}

И вот наша модель из 3дМакса попала в наше приложение!
Вот она модель и в нашей проге и в максе!

Весь пример вы можете скачать по ссылке в конце урока. В нем так же в отдельный модуль выделена загрузка текстур, для удобства. (прим.: Данный пример основывается на примере взятом на www.spacesimulator.net)

Подробнее о KEYFRAMER CHUNK.

Эту информацию найти было особенно сложно

Таблица с подробным описанием каждого chunk’а относящегося к анимации:

KEYFRAMER
Identifier (идентификатор) 0xB000
Уровень в иерархии 1
Length (длинна) 0 + sub-chunks length
Chunk father (элемент родитель) None
Sub chunks (ветви)
Data, descripion Данные кейфреймера служат для описания движения по сцене объектов (например – куба:)), источников света и камер.
INFORMATION BLOCK
Identifier (идентификатор) 0xB001 ... 0xB007
Уровень в иерархии 2
Length (длинна) Варьируется, зависит от ветвей
Chunk father (элемент родитель) 0xB000 (Keyframer chunk)
Sub chunks (ветви)
Data, descripion Этот блок содержит ветви описывающие движение каждого отдельного объекта, камеры, источника света.
0xB001 : Ambient light information block
0xB002 : Mesh information block
0xB003 : Camera information block
0xB004 : Camera target information block
0xB005 : Omni light information block
0xB006 : Spot light target information block
0xB007 : Spot light information block
FRAMES (START, END)
Identifier (идентификатор) 0xB008
Уровень в иерархии 2
Length (длинна) 8
Chunk father (элемент родитель) 0xB000 (Keyframer chunk)
Sub chunks (ветви)
Data, descripion Состоит из двух записей: dword Start, End. Думаю его значение понятно.
OBJECT NAME, PARAMETERS AND HIERARCHY FATHER
Identifier (идентификатор) 0xB010
Уровень в иерархии 3
Length (длинна) Варьируется, зависит от ветвей
Chunk father (элемент родитель) 0xB001..0xB007 Information block
Sub chunks (ветви)
Data, descripion Состоит из следующих записей:
strz Object Name
word Flag1
* Bit 11 : Hidden
word Flag2
* Bit 0 : Show path
* Bit 1 : Animate smoothing
* Bit 4 : Object motion blur
* Bit 6 : Morph materials
word Hierarchy father, link to the parent object (-1 for none)
* подробности по иерархии подтаблицей
OBJECT PIVOT POINT
Identifier (идентификатор) 0xB013
Уровень в иерархии 3
Length (длинна) 12
Chunk father (элемент родитель) 0xB001...0xB007 Information block
Sub chunks (ветви)
Data, descripion Содержит одну запись в векторном виде: Vector Pivot point
TRACK
Identifier (идентификатор) 0xB020 ... 0xB029
Уровень в иерархии 3
Length (длинна) Варьируется, зависит от ветвей
Chunk father (элемент родитель) 0xB001..0xB007 Information block
Sub chunks (ветви)
Data, descripion Содержит множества записей:
word Flag
* Bits 0-1 : 0 = single
2 = repeat
3 = loop * Bit 3 : lock X
* Bit 4 : lock Y
* Bit 5 : lock Z * Bit 7 : unlink X
* Bit 8 : unlink Y
* Bit 9 : unlink Z dword Number of keys in this track Then, for each key:
dword Key number (position in track)
word Acceleration data present (flag)
Range:
* Bit 0 : Tension follows [-1.0, 1.0]
* Bit 1 : Continuity follows [-1.0, 1.0]
* Bit 2 : Bias follows [-1.0, 1.0]
* Bit 3 : Ease to follows [ 0.0, 1.0]
* Bit 4 : Ease from follows [ 0.0, 1.0]
n floats Acceleration data
? Track specific data Track specific data is:
0xB020 : Position track : 1 vector Position
0xB021 : Rotation track : 1 float Angle (rad)
1 vector Axis
0xB022 : Scale track : 3 floats Size
0xB023 : FOV track : 1 float Angle (degree)
0xB024 : Roll track : 1 float Angle (degree)
0xB025 : Color track :
0xB026 : Morph track : 1 strz Object name
0xB027 : Hotspot track : 1 float Angle (degree)
0xB028 : Falloff track : 1 float Angle (degree)
0xB029 : Hide track : nothing
HIERARCHY POSITION
Identifier (идентификатор) 0xB030
Уровень в иерархии 3
Length (длинна) 2
Chunk father (элемент родитель) 0xB001 ... 0xB007 Information block
Sub chunks (ветви)
Data, descripion word HierarchyПодробнее об иерархии далее, в отдельной главе.

Информация далеко не полная, подробнее об этом можно узнать из доков sdk или споcобом, который я опишу немного позже.

Иерархия объектов.

Иерархия объектов схожа с иерархией chunk`ов, то же самое дерево… но не всегда. Каждому объекту в сцене дается номер, чтобы идентифицировать его номер в иерархии. Каждый объект созданный в файле будет и в дереве иерархии. Корневому элементу дается номер «-1»(ffff). При чтении файла сохраняется номер объекта. Если он увеличивается, будет идти работа с дочерним элементом, уменьшится – мы перешли на родительский элемент.
Для примера того, как иерархия представляется, используем файл 50pman.3ds (он есть среди файлов к уроку), его по каким то причинам, по традиции используют для описания этого момента еще с момента появления формата 3ds.

Hierarchy | object name

-1 pelvis
0 chest
1 neck
2 head
1 rt uparm
4 rt lowarm
5 rt hand
1 lft uparm
7 lft lowarm
8 lft hand
0 rt thigh
10 rt shin
11 rt foot
0 lft thigh
13 lft shin
14 lft foot

50man.3ds



Для просмотра древа объектов 3ДМаксе есть Schematic View (Graph Editors->New Schematic View). Собственно в нем же и можно ее изменять. (можно поставить background image - картинку редактируемой модели и расставить все части по картинке)

Schematic View для 50pman.3ds
Schemaic view

Для того чтобы понять то почему нумерация имеет именно такой порядок нужно представить саму модель, структура здесь имеет не стандартный вид дерева, потому что главный элемент логически помещен в центр.
Использование иерархии может быть полезно, когда мы должны объединить несколько объектов в структуру, а то как они должны зависеть друг от друга читать из файла.

Как легче узнать какие параметры надо прочитать?

В уроке я не привожу примера с чтением анимации, но взамен (чтобы вы не расстраивались:)) привожу пример, который есть в sdk от autodesk.

Для начала скачайте sdk по ссылке в конце урока. Он подготовлен для работы в MSVC++, но прочитать исходники я думаю, не составит труда тем, у кого ее нет.
Запустим MAKEREL.BAT, это установит пути к директориям sdk. (Чтобы это отменить запустите CLEAN.BAT)

В папке DUMP3DS находится пример, консольное приложение, которое читает 3ds файл и выводит в консоль информацию обо всех chunk`ах, которые подверглись изменению. (Теперь, например мы можем легко узнать какие chunk`и изменяются при добавлении анимации, карт и прочее…) В папке INC содержится заголовочный файл, в котором объявляются все chunk`и, и структуры для их обработки.

dump3ds

Вообще в sdk есть интересные документы, которые еще больше могут углубить ваши знания:
3DSFTK3.DOC – содержит информацию о программе приведенной Autodesk, спецификацию всех функций, структур, переменных. Тут все довольно понятно.
3DSFTK3.DOC – информация о том как устроен формат 3ds. Здесь все довольно непонятно :)
3DSFTK3B.DOC – все о анимации. Имеет довольно странную структуру, но полезного тут много.

Как настроить компилятор для работы с OpenGL.

Многие спорят что лучше, компилятор Microsoft или Borland? Мне кажется, это так же глупо, как и спорить на эту тему о 3DMax или Maya… Мне кажется, что важное отличие первого компилятора в том, что для него больше примеров :).
В архиве GL.rar лежит папка GL и Glut32.lib.


Если:
1.У нас Borland C++ Builder:

Папку копируем в - …/Builder root/include/
2.MSVC++ (для полноценной работы, нужна версия не ниже 6)
Папку копируем в - …/Builder root/include/ . Glut32.lib копируем в -- …/Builder root/lib/
Для запуска программ могут понадобиться dll-библиотеки GLUT, это расширение OGl функций, лежит в glutdlls37beta.rar, dll нужно скопировать в …/windows/system32/.

Ссылки:

http://www.opengl.org/ - официальный сайт OpenGL, на нем можно найти много полезных ссылок.
http://www.images.autodesk.com/adsk/files/3dsftk3.zip - официальный sdk по 3ds от Autodesk.
http://www.gamedev.net/reference/
http://www.opengl.gamedev.ru/ – хорошие примеры по работе с ogl.
http://www.nehe.gamedev.net/ - прекрасные примеры, советую всем, но они на английском…
http://www.opengl.org.ru/ – целая онлайн книга по ogl. Так же можно найти много интересного, например библиотеки, руководства.
http://www.spacesimulator.net/ - игровой проект на ogl. На сайте есть немного уроков.

Советую найти OpenGL Red Book (русская версия) – 475 страниц! Это отличный учебник по OpenGL, к сожалению сайт на котором я ее брал уже не работает, но я думаю поиском пользоваться все умеют:)

И еще интересные демки, часто с исходниками, можно найти на сайте NVidia…

Файлы к уроку:

CrolLesson.rar – содержит:

/example/ - программа с исходниками, приведенная здесь, мной в качестве примера
/for_include/ - glutdlls37beta.rar и GL.rar.

Послесловие.

На этом мой урок подошел завершению, я постарался, как можно полнее изложить тему. Обе цели поставленные вначале урока считаю достигнутыми. Надеюсь, вам было интересно!
Спасибо за внимание, оставляйте свои комментарии и голосуйте. Удачи вам в ваших проектах по 3d графике!
Если оставляете критику, пожалуйста, обосновывайте, мне же важно знать, что не так…

По возникающим вопросам обращайтесь на tony89@yandex.ru, я постараюсь всем отвечать.

565 0 850 44
23
2006-11-03
Превед товарисчу с АСУ от товаристча с ПОВТ хороший урог!
2006-11-03
Где же... где же ты был полгода назад :))) Урок понравился. Спасибо.
2006-11-03
Видно,что старался...правда показалось запутанным немного... Но в целом интересно.
2006-11-03
to wiTcHer: превед товаристч конечно, спасибо) to Квор:здесь я был, да мучил glscene и разочаровывался в нем постепенно) to Ozz:Спасибо, я правдо старался... жаль люди не ценят и у меня уже -2(..
2006-11-04
мен, честно скажу, мне это не интересно, НО ты молодец! толково изложил, что даже я понял :) короче лови пятёрки... так держать!
2006-11-04
to skif : спасибо! я излагал так как понял бы сам, а я люблю когда все подробно)
2006-11-04
Люди, а как думаете, можно научиться делать игрушки. Ну вот один моделирует, другой програмирует. ???
2006-11-04
5 5
2006-11-04
to pavel nikolaev: ну не совсем понял, но обычно так и есть один умеет программировать, другой моделировать... или и то и другое но что то всегда умет лучше... to HEX: thanks)
2006-11-04
Привет! Я тоже закончил АСУ в этом году. Но программирования здесь будет не так много, в основном 1-2 курс. А потом будет моделирование в (Mat lab, Vissim и т.д.) технологических процессов. и т.д.
2006-11-05
to Silverx это я знаю, но учусь то я на программиста)
2006-11-07
очень полезный урок
2006-11-10
У меня другой метод импорта из 3dMax - я написал скрипты для макса, которые выгружают данные об объектах сцены макса в формате xml. Очень удобно на моё взгляд - удобнее чем 3ds, т.к. в 3ds нет некторых параметров, которые в max файле есть.
2006-11-12
это каких же параметров там нет, которые могут тебе понадобиться??)
2006-11-13
в принципе согласен насчёт полезных параметров - всё необходимое для разработки есть. Всё остальное врядли будет реально использоваться в программах (типа displacement map, environment map, информация о crop). Но метод всё ж другой - в чём то хуже (например в том, что нельзя взять сразу же готовый файл, а надо пропустить его через 3dMax и скрипт),а в чём то лучше (свой собственный формат, в котором можно писать только то что тебе нужно).
2006-11-13
доброго времени суток! никто случайно не видел инфу про чтение формата *.max?
2006-11-14
имхо:думаю у discreet не хватит "храбрости" опубликовать мануал по своему формату, но уверен там много общего в нем с тем же 3ds
2006-11-14
да, в формат max-файлов лучше и не пытаться лезть - он меняется от версии к версии. Я и не пытался, т.к. незачем - всё, что можно, доступно через объектную модель max-script, который к счастью слабо меняется.
2006-12-07
урок неплохой,я далек от програмированния(архитектор) но мне было интересно) 5-5
2006-12-07
4kReal - приятно слышать! - 4Dinar - если макс скриптами писать в текстовик, то это много места в итоге, соответственно больше выделять памяти.. нецелесообразно, тот же 3ds с "кучей лишнего" будет в разы менее ресурсоемок! если планируется использовать через макс hex( не уверен я что это возможно), то это не так то легко... да и принцип то тот же будет, что и я рассмотрел.
2006-12-28
полезно для моделлера прогромиста...
2007-01-06
Привет! Народ, такой вопрос возник, может кто знает… Столкнулся с такой вещью при загрузке текстур… Сначала из файла 3DS загружаются имена файлов с текстурами (секция 0xA300), а только потом вершины и треугольники (0x4110 и 0x4120 соответственно). Но дело в том, что не у каждого объекта сцены может быть текстура… И вот возникает проблема, как узнать, какому объекту сцены какая текстура соответствует? Кто с этим сталкивался и решил это, помогите…
2007-09-13
[b]Внимание![/b] для тех [b]"кто в танке"[/b] или забрел на эту страницу впервые. не пишите мне вопросов типа - напиши мне как сделать игру! не пишите - скинь свою игру(100 метров). и вообще я в создании игр [b]ушел в directX и VC++ + 3dsMax[/b], если есть по ним вопросы задавайте, лучше через аську, [b] а на вопросы по glscene я не могу отвечать[/b] так как не работаю с ним уже года 2.
RENDER.RU