Работа с моделями объектов в формате 3ds
Для работы с готовыми трехмерными объектами в формате 3ds воспользуемся соответствующей библиотекой, которая позволяет загружать и накладывать текстуру на объект.
Стоит отметить, что данная библиотека работает с объектами сложной структуры как с единым объектом и не позволяет работать с составными частями объекта, например, использовать скелетную анимацию объекта.
Впрочем, данное обстоятельство можно обойти, если загружать объект как составной из нескольких файлов и группировать его программно.
Тем не менее, для знакомства с основами использования 3ds файлов в ПО ввиду своей простоты будем ее использовать в образовательных целях.
Описание 3ds файла можно найти например на странице http://en.wikipedia.org/wiki/.3ds.
В общем случае 3ds файл создается в трехмерном графическом редакторе, например, 3DMax, бесплатную версию которого можно скачать здесь.
Пример:
#include <windows.h>
#include <glut.h>
#include "main3ds.h"
#include "texture.h"
#include "3dsloader.h"
int screen_width=640;
int screen_height=480;
double rotation_x=0, rotation_x_increment=0.2;
double rotation_y=0, rotation_y_increment=0.1;
double rotation_z=0, rotation_z_increment=0.05;
int filling=1; //0=OFF 1=ON
obj_type object;
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glViewport(0,0,screen_width,screen_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,10.0f,10000.0f);
glEnable(GL_DEPTH_TEST);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_TEXTURE_2D);
Load3DS (&object,"spaceship.3ds");
object.id_texture=LoadBitmap("spaceshiptexture.bmp");
if (object.id_texture==-1)
{
exit (0);
}
}
void resize (int width, int height)
{
screen_width=width;
screen_height=height;
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0,0,screen_width,screen_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,10.0f,10000.0f);
glutPostRedisplay ();
}
void keyboard (unsigned char key, int x, int y)
{
switch (key)
{
case ' ':
rotation_x_increment=0;
rotation_y_increment=0;
rotation_z_increment=0;
break;
case 'r': case 'R':
if (filling==0)
{
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
filling=1;
}
else
{
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
filling=0;
}
break;
}
}
void keyboard_s (int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_UP:
rotation_x_increment = rotation_x_increment +0.005;
break;
case GLUT_KEY_DOWN:
rotation_x_increment = rotation_x_increment -0.005;
break;
case GLUT_KEY_LEFT:
rotation_y_increment = rotation_y_increment +0.005;
break;
case GLUT_KEY_RIGHT:
rotation_y_increment = rotation_y_increment -0.005;
break;
}
}
void display(void)
{
int l_index;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0,0.0,-300);
rotation_x = rotation_x + rotation_x_increment;
rotation_y = rotation_y + rotation_y_increment;
rotation_z = rotation_z + rotation_z_increment;
if (rotation_x > 359) rotation_x = 0;
if (rotation_y > 359) rotation_y = 0;
if (rotation_z > 359) rotation_z = 0;
glRotatef(rotation_x,1.0,0.0,0.0);
glRotatef(rotation_y,0.0,1.0,0.0);
glRotatef(rotation_z,0.0,0.0,1.0);
glBindTexture(GL_TEXTURE_2D, object.id_texture);
glBegin(GL_TRIANGLES);
for (l_index=0;l_index<object.polygons_qty;l_index++)
{
//----------------- FIRST VERTEX -----------------
// Texture coordinates of the first vertex
glTexCoord2f( object.mapcoord[ object.polygon[l_index].a ].u,
object.mapcoord[ object.polygon[l_index].a ].v);
// Coordinates of the first vertex
glVertex3f( object.vertex[ object.polygon[l_index].a ].x,
object.vertex[ object.polygon[l_index].a ].y,
object.vertex[ object.polygon[l_index].a ].z); //Vertex definition
//----------------- SECOND VERTEX -----------------
// Texture coordinates of the second vertex
glTexCoord2f( object.mapcoord[ object.polygon[l_index].b ].u,
object.mapcoord[ object.polygon[l_index].b ].v);
// Coordinates of the second vertex
glVertex3f( object.vertex[ object.polygon[l_index].b ].x,
object.vertex[ object.polygon[l_index].b ].y,
object.vertex[ object.polygon[l_index].b ].z);
//----------------- THIRD VERTEX -----------------
// Texture coordinates of the third vertex
glTexCoord2f( object.mapcoord[ object.polygon[l_index].c ].u,
object.mapcoord[ object.polygon[l_index].c ].v);
// Coordinates of the Third vertex
glVertex3f( object.vertex[ object.polygon[l_index].c ].x,
object.vertex[ object.polygon[l_index].c ].y,
object.vertex[ object.polygon[l_index].c ].z);
}
glEnd();
glFlush();
glutSwapBuffers();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(screen_width,screen_height);
glutInitWindowPosition(0,0);
glutCreateWindow("3ds");
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc (resize);
glutKeyboardFunc (keyboard);
glutSpecialFunc (keyboard_s);
init();
glutMainLoop();
return(0);
}
В свойствах проекта (Alt+F7) установитеConfiguration Properties-> С/С++ -> Precompiled Header -> Create/Use precompiled header = Not Using Precompiled Headers