Russian Qt Forum
Май 17, 2024, 15:29 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Модель из 3dmax_ в Open GL  (Прочитано 6618 раз)
Witcher000
Гость
« : Ноябрь 20, 2009, 01:42 »

Такой вот вопрос :
возможно ли экспортировать модель, сделанную в 3d studio max_ (расширение .max) в open gl на  qt 4.0.0 ?
Если да, то существуют ли вообще плагины для 3д макса_, которые бы хоть как-то это рреализовывали?

Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #1 : Ноябрь 20, 2009, 04:59 »

Код:
в open gl на  qt 4.0.0

я пока не слышал чтобы в OpenGL оговаривался свой собственный формат файлов модели - это API для рисования примитивов и т.д.

Экспортите модель из макса в 3DS или OBJ - и пользуйтесь готовыми библиотеками загрузки изображений из этих открытых форматов 3D моделей, а потом отрисовывайте операторами OpenGL
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Ноябрь 20, 2009, 11:31 »

Экспортите модель из макса в 3DS или OBJ
Совершенно верно, в .max файле очень много чего + он нестабилен, меняется от версии к версии. Перегоняйте в файл модели
Записан
ieroglif
Гость
« Ответ #3 : Январь 10, 2010, 16:31 »

класс для загрузки и отрисовки из 3ds файла. (в него умеет сохранять макс без проблем)
класс глючный (не уверен в корректной работе нормалей) и выполняет только базовые функции отрисовки полигонов (без цветов и материалов). класс QGLVector - обычный, хранит в себе 3 координаты. В общем, думаю, можно оттолкнуться и  использовать для написания своего кода.

Код:
//QGLMesh.h

#ifndef QGLMESH_H
#define QGLMESH_H

#include "glheaders.h"
#include <QMap>
#include "qglvector.h"

// --- List of define to allow the loading of 3ds file --- //
// --- CHUNK PRIMAIRE --- //
#define MAIN3DS 0x4D4D
// --- MAIN CHUNKS --- //
#define EDIT3DS 0x3D3D
// --- EDIT3DS --- //
#define EDIT_MATERIAL 0xAFFF
#define EDIT_OBJECT 0x4000
// --- MATERIAL DEFINITION --- //
#define MATERIAL_NAME 0xA000
#define MATERIAL_AMBIENT 0xA010
#define MATERIAL_DIFFUSE 0xA020
#define MATERIAL_SPECULAR 0xA030
#define MATERIAL_TEXTURE 0xA200
#define TEXTURE_NAME 0xA300
#define U_COORDS 0xA356
#define V_COORDS 0xA354
#define U_COORDS_OFFSET 0xA358
#define V_COORDS_OFFSET 0xA35A
#define TEXT_ROTATION_ANGLE 0xA35C
#define COLOR_RGB 0x0011
// --- MESH EDITION --- //
#define OBJECT 0x4000
#define OBJ_TRIMESH 0x4100
#define TRI_VERTEX 0x4110
#define TRI_FACE 0x4120
#define MATERIAL_MAP_INFO 0x4130
#define MAP_COORDS 0x4140
#define LOCAL_MATRIX 0x4160
// --- CAMERA & LIGHT --- //
#define CAMERA 0x4700
#define LIGHT 0x4600
#define SPOT_LIGHT 0x4610

#include <QObject>
#include <QString>

//Basic Classes:
//Required for representing the loaded model
class vertex{
public:
float x,y,z;
};
//MapCoord - for storing texture mapping coords
class mapcoord{
public:
float u,v;
};

//The three ints for the polygon
//represent the no.s(or rank) of it's 3 vertices
class polygon{
public:
int a,b,c;
vertex normal;
};

class object{
public:
char name[20];
int numVerts,numPolys;
vertex v[3000];
polygon p[3000];
mapcoord m[3000];
};

class QGLMesh
{
public:
    QGLMesh();
~QGLMesh();
void Load(QString fileName);
void Draw();
GLint listNum;
bool smoth;
private:
object *obj;
void CalcNormal(vertex p1,vertex p2, vertex p3, vertex *res);
GLfloat vertexes[3000];
GLfloat normales[3000];
GLint smoth_normales[3000];
QMap<QGLVector,QGLVector> smooth_normales_map;
int numVertex;
};

//QGLMesh.cpp

#include "qglmesh.h"
#include <math.h>
#include <QFile>

QGLMesh::QGLMesh()
{
obj = new object();
numVertex = 0;
smoth = false;
}

QGLMesh::~QGLMesh()
{
delete obj;
}

void QGLMesh::Draw()
{
glNormalPointer(GL_FLOAT,0,normales);
if ( smoth ) glNormalPointer(GL_FLOAT,0,smoth_normales);
glVertexPointer(3,GL_FLOAT,0,vertexes);
glDrawArrays(GL_TRIANGLES,0,numVertex);
}

void QGLMesh::Load(QString fileName)
{
char temp; //Temporary char for reading name of object
short chunkID,readsize; //Stores ID of current chunk.
int chunkLength;
short useless;

QFile f(fileName);
f.open(QIODevice::ReadOnly);

int i;
f.seek(0);
f.read((char*)&chunkID,2);
if ( chunkID != MAIN3DS ) {
return;
}
f.read((char*)&readsize,4);
while ( f.pos() < readsize ) {
f.read((char*)&chunkID,2);
f.read((char*)&chunkLength,4);
switch (chunkID)
{
case MAIN3DS: //Skip these chunks
break;
case EDIT3DS:
break;
case EDIT_OBJECT: //Chunk containing name
for(i=0;i<20;i++)
{
temp = f.read(1).at(0);
// obj->name[i]=temp;
if(temp == '\0')break;
}
break;
case 0x3f80: //Skip again
break;
case OBJ_TRIMESH:
break;
case TRI_VERTEX: //Chunk with num of vertices followed by their coordinates
f.read((char*)&i,2);
obj->numVerts = i;
for (i=0; i<obj->numVerts; i++)
{
f.read((char*)&obj->v[i].x,4);
f.read((char*)&obj->v[i].y,4);
f.read((char*)&obj->v[i].z,4);
}
break;
case TRI_FACE: //Chunk with numPolys and the indices
f.read((char*)&obj->numPolys,2);
for (i=0; i<obj->numPolys; i++)
{
f.read((char*)&obj->p[i].a,2);
f.read((char*)&obj->p[i].b,2);
f.read((char*)&obj->p[i].c,2);
f.read((char*)&useless,2);
}
break;
case MAP_COORDS: //Chunk with texture coords
f.read((char*)&useless,2);
for (i=0; i<obj->numVerts; i++)
{
f.read((char*)&obj->m[i].u,4);
f.read((char*)&obj->m[i].v,4);
}
break;
default:
f.seek(f.pos()+chunkLength-6);
}
}
f.close();

for (i=0;i<obj->numPolys;i++)
{
CalcNormal( obj->v[ obj->p[i].a ], obj->v[ obj->p[i].b ], obj->v[ obj->p[i].c ], &obj->p[i].normal );
}

int vc = 0;
int nc = 0;
//QGLVector ver,nor;
QMap< QGLVector, QGLVector > norms;
for ( int i=0; i<obj->numPolys; i++ ) {
normales[nc] = obj->p[i].normal.x;
nc++;
normales[nc] = obj->p[i].normal.y;
nc++;
normales[nc] = obj->p[i].normal.z;
nc++;
vertexes[vc] = obj->v[ obj->p[i].a ].x;
vc++;
vertexes[vc] = obj->v[ obj->p[i].a ].y;
vc++;
vertexes[vc] = obj->v[ obj->p[i].a ].z;
vc++;
numVertex++;

norms.insertMulti(QGLVector(obj->v[ obj->p[i].a ].x,obj->v[ obj->p[i].a ].y,obj->v[ obj->p[i].a ].z),QGLVector(obj->p[i].normal.x,obj->p[i].normal.y,obj->p[i].normal.z));

normales[nc] = obj->p[i].normal.x;
nc++;
normales[nc] = obj->p[i].normal.y;
nc++;
normales[nc] = obj->p[i].normal.z;
nc++;
vertexes[vc] = obj->v[ obj->p[i].b ].x;
vc++;
vertexes[vc] = obj->v[ obj->p[i].b ].y;
vc++;
vertexes[vc] = obj->v[ obj->p[i].b ].z;
vc++;
numVertex++;

norms.insertMulti(QGLVector(obj->v[ obj->p[i].b ].x,obj->v[ obj->p[i].b ].y,obj->v[ obj->p[i].b ].z),QGLVector(obj->p[i].normal.x,obj->p[i].normal.y,obj->p[i].normal.z));

normales[nc] = obj->p[i].normal.x;
nc++;
normales[nc] = obj->p[i].normal.y;
nc++;
normales[nc] = obj->p[i].normal.z;
nc++;
vertexes[vc] = obj->v[ obj->p[i].c ].x;
vc++;
vertexes[vc] = obj->v[ obj->p[i].c ].y;
vc++;
vertexes[vc] = obj->v[ obj->p[i].c ].z;
vc++;
numVertex++;

norms.insertMulti(QGLVector(obj->v[ obj->p[i].c ].x,obj->v[ obj->p[i].c ].y,obj->v[ obj->p[i].c ].z),QGLVector(obj->p[i].normal.x,obj->p[i].normal.y,obj->p[i].normal.z));

}

QGLVector vert,cnorm;
QList< QGLVector > vert_normales;

smooth_normales_map.clear();
for ( int i=0; i<numVertex-3; i=i+3 ) {
vert.x = vertexes[i];
vert.y = vertexes[i+1];
vert.z = vertexes[i+2];

vert_normales.clear();
vert_normales = norms.values(vert);

int cnt = 1;
cnorm.load(0,0,0);
for ( int j=0; j<vert_normales.size();j++) {
cnt++;
cnorm.x = cnorm.x + vert_normales.at(j).x;
cnorm.y = cnorm.y + vert_normales.at(j).y;
cnorm.z = cnorm.z + vert_normales.at(j).z;
}
cnorm.x /= cnt;
cnorm.y /= cnt;
cnorm.z /= cnt;
smooth_normales_map.insert(vert,cnorm);
}

for ( int i=0; i<numVertex-3; i=i+3 ) {
vert.x = vertexes[i];
vert.y = vertexes[i+1];
vert.z = vertexes[i+2];
smoth_normales[i] = smooth_normales_map[ vert ].x;
smoth_normales[i+1] = smooth_normales_map[ vert ].y;
smoth_normales[i+2] = smooth_normales_map[ vert ].z;
}

}

void QGLMesh::CalcNormal(vertex p1,vertex p2, vertex p3, vertex *res)
{
vertex v1, v2;
float length, ilength;

v1.x = p2.x - p1.x;
v1.y = p2.y - p1.y;
v1.z = p2.z - p1.z;

v2.x = p3.x - p1.x;
v2.y = p3.y - p1.y;
v2.z = p3.z - p1.z;

res->x = v1.y*v2.z - v1.z*v2.y;
res->y = v1.z*v2.x - v1.x*v2.z;
res->z = v1.x*v2.y - v1.y*v2.x;

length = res->x*res->x + res->y*res->y + res->z*res->z;
length = sqrtf(length); // извлечение корня - это очень плохо

ilength = 1/length;

res->x *= ilength;
res->y *= ilength;
res->z *= ilength;
}


Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Январь 10, 2010, 16:45 »

класс для загрузки и отрисовки из 3ds файла. (в него умеет сохранять макс без проблем)
класс глючный (не уверен в корректной работе нормалей) и выполняет только базовые функции отрисовки полигонов (без цветов и материалов). класс QGLVector - обычный, хранит в себе 3 координаты. В общем, думаю, можно оттолкнуться и  использовать для написания своего кода.
Вопрос: сколько строк (в %) было использовано для повторения операций над всеми 3-мя компонентами (x, y, z)?
Технику-то подтянуть надо.
Записан
ieroglif
Гость
« Ответ #5 : Январь 10, 2010, 22:29 »

класс для загрузки и отрисовки из 3ds файла. (в него умеет сохранять макс без проблем)
класс глючный (не уверен в корректной работе нормалей) и выполняет только базовые функции отрисовки полигонов (без цветов и материалов). класс QGLVector - обычный, хранит в себе 3 координаты. В общем, думаю, можно оттолкнуться и  использовать для написания своего кода.
Вопрос: сколько строк (в %) было использовано для повторения операций над всеми 3-мя компонентами (x, y, z)?
Технику-то подтянуть надо.
Ответ: критикуешь - предлагай.
Вот приходишь так на форум, выкладываешь свой кусок кода на просьбу человека, а следующий приходит и говорит что код уродский. Ну выложи свой.
« Последнее редактирование: Январь 11, 2010, 05:35 от Dendy » Записан
romank
Гость
« Ответ #6 : Январь 10, 2010, 23:39 »

Редкий "великий русский программист" пройдет чтобы не плюнуть в код. Привыкайте.
« Последнее редактирование: Январь 11, 2010, 05:35 от Dendy » Записан
Dendy
Гость
« Ответ #7 : Январь 11, 2010, 05:37 »

ieroglif, учитесь воспринимать критику. Дальше в теме по существу.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Январь 11, 2010, 15:17 »

Дальше в теме по существу.
Согласен  Улыбающийся

Код:
class vertex{
public:
float x,y,z;
};
Если этот скромный ("конкретный") класс развить - толку будет намного больше чем от использования всех умных контейнеров вместе взятых. Например

Код:
struct vertex {
// avoid constructor
 vertex & xyz( float _x = 0.0f, float _y = 0.0f, float _z = 0.0f )  { x = _x; y = _y; z = _z; return *this; }

// math
  vertex & operator += ( const vertex & t ) { x += t.x; y += t.y; z += t.z; return *this; } 
  vertex & operator -= ( const vertex & t ) { x -= t.x; y -= t.y; z -= t.z; return *this; } 

  vertex & operator *= ( float t ) { x *= t; y *= t; z *= t; return *this; } 
  vertex & operator /= ( float t ) { x /= t; y /= t; z /= t; return *this; } 

// length & normalize
  float lenSq ( void ) const { return x * x + y * y + z * z; }
  float length ( void ) const { return sqrtf(lenSq); }

  vertex & normalize( void ) { return *this /= length(); }

// friend operators
  friend vertex operator + ( const vertex & a , const vertex & b ) { vertex t; return t.xyz(a.x + b.x, a.y + b.y, a.z + b.z); }
  friend vertex operator - ( const vertex & a , const vertex & b ) { vertex t; return t.xyz(a.x - b.x, a.y - b.y, a.z - b.z); }

  friend vertex operator * ( const vertex & a, float t ) { vertex v = a; return v *= t; } 
  friend vertex operator / ( const vertex & a, float t ) { vertex v = a; return v /= t; } 

// scalar product (overloaded *)
  friend float operator * ( const vertex & a , const vertex & b ) { return a.x * b.x + a.y * b.y + a.z * b.z; }
 
// vector product (overloaded |)
  friend vertex operator | ( const vertex & a , const vertex & b )
  {
    vertex t;
    return t.xyz(a.y * b.z - a.z * b.y,
                     a.x * b.z - a.z * b.x, 
                     a.x * b.y - a.y * b.x);
  }
};
Теперь ф-ция CalcNormal может выглядеть напр. так

Код:
void QGLMesh::CalcNormal(const & vertex p1, const & vertex p2, const & vertex p3, vertex *res)
{
 *res = ((p2 - p1) | (p3 - p1)).normalize();
}
{

А про вертексные нормали можно долго говорить (после того как ieroglif перестанет обижаться  Улыбающийся)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.048 секунд. Запросов: 23.