|
Языки программирования Изучаем С++, Sql, php, Lua, Python |
|
Опции темы | Поиск в этой теме | Опции просмотра |
08.05.2013, 17:16 | #1 |
Ученый
Регистрация: 07.03.2010
Адрес: Беларусь,Брест
Сообщений: 188
Сказал(а) спасибо: 131
Поблагодарили 34 раз(а) в 27 сообщениях
|
QT+LIB3DS [QGLViewer]
Здравствуйте уважаемые пользователи!
Юзаю библиотеку QGLViewer для загрузки 3ds модели! Модель сама загружается, а текстура нет! Вот мой код: Код:
#ifndef _3DSVIEWER_H #define _3DSVIEWER_H #include <QtGui> #include "lib3ds\file.h" #include "lib3ds\node.h" #include "QGLViewer\QGLViewer.h" #define CountTexture 1 class Viewer : public QGLViewer { Q_OBJECT public: Viewer(); protected : virtual void draw(); virtual void animate(); virtual void init(); virtual void keyPressEvent(QKeyEvent *e); virtual QString helpString() const; void renderNode(Lib3dsNode *node); void initScene(); void loadFile(); QImage loadBMP(QString NameBMP); void setTexture(); private : Lib3dsFile *file; float current_frame; char* camera_name; GLuint Texture;//[CountTexture]; // Texture parameters float ratio, u_max, v_max; float scale_x, scale_y; // scale the texcoords, as OpenGL thinks in TEX_XSIZE and TEX_YSIZE }; #endif // _3DSVIEWER_H Код:
#include "3dsViewer.h" #include "lib3ds\camera.h" #include "lib3ds\mesh.h" #include "lib3ds\material.h" #include "lib3ds\matrix.h" #include "lib3ds\vector.h" #include "lib3ds\light.h" #include <string.h> #include <math.h> #include <qfiledialog.h> using namespace std; using namespace qglviewer; #define TEX_XSIZE 1024 #define TEX_YSIZE 1024 Viewer::Viewer() : file(NULL), current_frame(0.0), camera_name(NULL) { } void Viewer::keyPressEvent(QKeyEvent *e) { switch (e->key()) { case Qt::Key_L : loadFile(); break; default: QGLViewer::keyPressEvent(e); } } QString Viewer::helpString() const { QString text("<h2>3 d s V i e w e r</h2>"); text += "This example uses the lib3ds library to load a 3ds object file.<br><br>"; text += "Press <b>L</b>(oad) to open a 3ds file.<br><br>"; text += "Note that certain 3ds files contain animated sequences that can "; text += "be played using the <b>Return</b> (animate) key."; return text; } void Viewer::loadFile() { /*#if QT_VERSION < 0x040000 QString name = QFileDialog::getOpenFileName(".", "3DS files (*.3ds *.3DS);;All files (*)", this, "Choose", "Select a 3ds model"); #else QString name = QFileDialog::getOpenFileName(this, "Select a 3ds model", ".", "3DS files (*.3ds *.3DS);;All files (*)"); #endif*/ QString name("blyak.3DS"); // In case of Cancel if (name.isEmpty()) return; #if QT_VERSION < 0x040000 file = lib3ds_file_load(name.latin1()); #else file = lib3ds_file_load(name.toLatin1().constData()); #endif if (!file) { qWarning("Error : Unable to open file "); exit(1); } if (file->cameras) camera_name = file->cameras->name; else camera_name = NULL; lib3ds_file_eval(file,0); initScene(); float min[3], max[3]; lib3ds_file_bounding_box(file, min, max); setSceneBoundingBox(Vec(min), Vec(max)); if (!file->cameras) camera()->showEntireScene(); else updateGL(); stopAnimation(); } QImage Viewer::loadBMP(QString NameBMP) { QImage img(NameBMP); if (img.isNull()) { qWarning("Unable to load file[bmp]"); return img; } QMatrix matr; matr = matr.rotate(90); QTransform trans(matr); img.transformed(trans); //img. // 1E-3 needed. Just try with width=128 and see ! /*int newWidth = 1<<(int)(1+log(img.width() -1+1E-3) / log(2.0)); int newHeight = 1<<(int)(1+log(img.height()-1+1E-3) / log(2.0)); u_max = img.width() / (float)newWidth; v_max = img.height() / (float)newHeight; if ((img.width()!=newWidth) || (img.height()!=newHeight)) { qWarning("Image size set to %dx%d pixels", newWidth, newHeight); img = img.copy(0, 0, newWidth, newHeight); } ratio = newWidth / float(newHeight);*/ return QGLWidget::convertToGLFormat(img); // flipped 32bit RGBA } void Viewer::setTexture() { QImage glImg = loadBMP("blyak.bmp"); if(glImg.isNull()) return; Texture = bindTexture(glImg, GL_TEXTURE_2D); //glBindTexture(GL_TEXTURE_2D, Texture); glTexImage2D(GL_TEXTURE_2D, 0, 4, glImg.width(), glImg.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, glImg.bits()); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); scale_x = (float)glImg.width()/(float)TEX_XSIZE; scale_y = (float)glImg.height()/(float)TEX_YSIZE; } void Viewer::init() { // Texture parameters u_max = 1.0; v_max = 1.0; ratio = 1.0; glShadeModel(GL_SMOOTH); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glDisable(GL_LIGHT1); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glDisable(GL_COLOR_MATERIAL); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); //glEnable(GL_TEXTURE_2D); // Enable GL textures //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glEnable(GL_TEXTURE_2D); // Nice texture coordinate interpolation glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); setKeyDescription(Qt::Key_L, "Loads a new 3ds file"); restoreStateFromFile(); //help(); setTexture(); loadFile(); } void Viewer::initScene() { if (!file) return; // Lights GLfloat amb[] = {0.0, 0.0, 0.0, 1.0}; GLfloat dif[] = {1.0, 1.0, 1.0, 1.0}; GLfloat spe[] = {1.0, 1.0, 1.0, 1.0}; GLfloat pos[] = {0.0, 0.0, 0.0, 1.0}; int li=GL_LIGHT0; for (Lib3dsLight* l=file->lights; l; l=l->next) { glEnable(li); glLightfv(li, GL_AMBIENT, amb); glLightfv(li, GL_DIFFUSE, dif); glLightfv(li, GL_SPECULAR, spe); pos[0] = l->position[0]; pos[1] = l->position[1]; pos[2] = l->position[2]; glLightfv(li, GL_POSITION, pos); if (!l->spot_light) continue; pos[0] = l->spot[0] - l->position[0]; pos[1] = l->spot[1] - l->position[1]; pos[2] = l->spot[2] - l->position[2]; glLightfv(li, GL_SPOT_DIRECTION, pos); ++li; } // Camera Lib3dsNode* c = lib3ds_file_node_by_name(file, camera_name, LIB3DS_CAMERA_NODE); Lib3dsNode* t = lib3ds_file_node_by_name(file, camera_name, LIB3DS_TARGET_NODE); if (!c || !t) return; Lib3dsMatrix M; lib3ds_matrix_camera(M, c->data.camera.pos, t->data.target.pos, c->data.camera.roll); // cout << "Pos = " << Vec(c->data.camera.pos) << endl; // cout << "Tar = " << Vec(t->data.target.pos) << endl; // cout << "Rol = " << c->data.camera.roll << endl; camera()->setPosition(Vec(c->data.camera.pos)); camera()->lookAt(Vec(t->data.target.pos)); Vec up=camera()->frame()->transformOf(Vec(0.0, 0.0, 1.0)); float angle=atan2(up.x, up.y); Quaternion q(Vec(0.0, 0.0, 1.0), c->data.camera.roll-angle); camera()->frame()->rotate(q); camera()->setFieldOfView(M_PI/180.0*c->data.camera.fov); glRotatef(-90, 1.0,0,0); } void Viewer::renderNode(Lib3dsNode *node) { for (Lib3dsNode* p=node->childs; p!=0; p=p->next) renderNode(p); if (node->type == LIB3DS_OBJECT_NODE) { if (strcmp(node->name,"$$$DUMMY")==0) return; if (!node->user.d) { Lib3dsMesh *mesh=lib3ds_file_mesh_by_name(file, node->name); if (!mesh) return; node->user.d = glGenLists(1); glNewList(node->user.d, GL_COMPILE); Lib3dsVector *normalL = new Lib3dsVector[3*mesh->faces]; Lib3dsMatrix M; lib3ds_matrix_copy(M, mesh->matrix); lib3ds_matrix_inv(M); glMultMatrixf(&M[0][0]); lib3ds_mesh_calculate_normals(mesh, normalL); for (unsigned int p=0; p<mesh->faces; ++p) { Lib3dsFace *f=&mesh->faceL[p]; Lib3dsMaterial *mat=0; if (f->material[0]) mat=lib3ds_file_material_by_name(file, f->material); if (mat) { static GLfloat a[4]={0,0,0,1}; float s; glMaterialfv(GL_FRONT, GL_AMBIENT, a); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular); s = pow(2, 10.0*mat->shininess); if (s>128.0) s=128.0; glMaterialf(GL_FRONT, GL_SHININESS, s); } else { Lib3dsRgba a={0.2, 0.2, 0.2, 1.0}; Lib3dsRgba d={0.8, 0.8, 0.8, 1.0}; Lib3dsRgba s={0.0, 0.0, 0.0, 1.0}; glMaterialfv(GL_FRONT, GL_AMBIENT, a); glMaterialfv(GL_FRONT, GL_DIFFUSE, d); glMaterialfv(GL_FRONT, GL_SPECULAR, s); } glBindTexture(GL_TEXTURE_2D, Texture); glBegin(GL_TRIANGLES); glNormal3fv(f->normal); for (int i=0; i<3; ++i) { glNormal3fv(normalL[3*p+i]); glTexCoord2f(mesh->texelL[f->points[i]][1]*scale_x, scale_y - mesh->texelL[f->points[i]][0]*scale_y); //glTexCoord2f(mesh->texelL[f->points[i]][1], mesh->texelL[f->points[i]][0]); glVertex3fv(mesh->pointL[f->points[i]].pos); } glEnd(); } delete[] normalL; glEndList(); } if (node->user.d) { glPushMatrix(); Lib3dsObjectData* d = &node->data.object; glMultMatrixf(&node->matrix[0][0]); glTranslatef(-d->pivot[0], -d->pivot[1], -d->pivot[2]); glCallList(node->user.d); glPopMatrix(); } } } void Viewer::draw() { if (!file) return; glBindTexture(GL_TEXTURE_2D, Texture); /*glNormal3f(0.0, 0.0, 1.0); glBegin(GL_QUADS); glTexCoord2f(0.0, 1.0-v_max); //glVertex2f(-u_max*ratio,-v_max); glTexCoord2f(0.0, 1.0); //glVertex2f(-u_max*ratio, v_max); glTexCoord2f(u_max, 1.0); //glVertex2f( u_max*ratio, v_max); glTexCoord2f(u_max, 1.0-v_max); //glVertex2f( u_max*ratio,-v_max); glEnd();*/ for (Lib3dsNode* p=file->nodes; p!=0; p=p->next) renderNode(p); } void Viewer::animate() { current_frame++; if (current_frame > file->frames) current_frame=0; lib3ds_file_eval(file, current_frame); initScene(); } Opengl пока разбираю и опыта нет. Мб кто поможет?
__________________
sql-language.ru Последний раз редактировалось lovepsone; 15.05.2013 в 22:00. |
09.05.2013, 14:32 | #2 |
Ученый
Регистрация: 02.04.2010
Сообщений: 237
Сказал(а) спасибо: 41
Поблагодарили 99 раз(а) в 44 сообщениях
|
Чувак, я твой фанат теперь Я давно эту идею вынашиваю, написать собственый модельвивер на qt
__________________
SpellWork Qt4 |
09.05.2013, 18:03 | #3 |
Ученый
Регистрация: 07.03.2010
Адрес: Беларусь,Брест
Сообщений: 188
Сказал(а) спасибо: 131
Поблагодарили 34 раз(а) в 27 сообщениях
|
Да вот пока с Opengl изучаю + в Qt интегрирую! Вот тока пока проблем выше крыши!
__________________
sql-language.ru |
10.05.2013, 10:21 | #4 |
Пользователь
Регистрация: 06.01.2012
Сообщений: 98
Сказал(а) спасибо: 12
Поблагодарили 33 раз(а) в 21 сообщениях
|
glBindTexture после glGenLists...не?
Даже не после а внутри блока....и тестурку выбрать клетчатую салатовую, что бы наверняка знать грузится-нет. |
11.05.2013, 17:40 | #5 |
Ученый
Регистрация: 07.03.2010
Адрес: Беларусь,Брест
Сообщений: 188
Сказал(а) спасибо: 131
Поблагодарили 34 раз(а) в 27 сообщениях
|
Обновил первый пост!Вроде теперь текстура загружается, но моделька отображается черным цветом!
Смотрите скрин ниже в первом посте! Я даже нарисовал куб и попытался наложить текстуру, но нечего не вышло! Значит я чего-то не знаю... Буду думать.
__________________
sql-language.ru Последний раз редактировалось lovepsone; 11.05.2013 в 18:41. |
11.05.2013, 20:00 | #6 |
Ученый
Регистрация: 02.04.2010
Сообщений: 237
Сказал(а) спасибо: 41
Поблагодарили 99 раз(а) в 44 сообщениях
|
Альфа канал указал верно? Я помню когда делал для m2 то текстура blp в RGBA не отображалась, потом выставил альфа на максимум и все появилось Долго ломал тогда голову )
__________________
SpellWork Qt4 |
15.05.2013, 21:59 | #7 |
Ученый
Регистрация: 07.03.2010
Адрес: Беларусь,Брест
Сообщений: 188
Сказал(а) спасибо: 131
Поблагодарили 34 раз(а) в 27 сообщениях
|
Текстуру удалось наложить, но есть некоторые проблемы!
Я поворачиваю камеру на 90 градусов( Что бы модель стояла правильно по координатам х,у.z, т.е стояла ровно)! При таком раскладе я налаживаю текстуру и... Текстура ложится прямо а не по вершинам указанных в 3ds файле! Далее пришлось посчитать вершины текстуры, в итоге по коду вышло так: Код:
glBindTexture(GL_TEXTURE_2D, Texture); glBegin(GL_TRIANGLES); glNormal3fv(f->normal); for (int i=0; i<3; ++i) { glNormal3fv(normalL[3*p+i]); glTexCoord2f(mesh->texelL[f->points[i]][1]*scale_x, scale_y - mesh->texelL[f->points[i]][0]*scale_y); glVertex3fv(mesh->pointL[f->points[i]].pos); } glEnd(); Меня это не устроило и попробовал поворачивать текстуру перед наложением на модель(в самом коде). Сделал так: Код:
QImage Viewer::loadBMP(QString NameBMP) { QImage img(NameBMP); if (img.isNull()) { qWarning("Unable to load file[bmp]"); return img; } QMatrix matr; matr = matr.rotate(90); QTransform trans(matr); img.transformed(trans); // переменная img типа QImage, в которой помещена текстура формата .bmp return QGLWidget::convertToGLFormat(img); // flipped 32bit RGBA }
__________________
sql-language.ru Последний раз редактировалось lovepsone; 15.05.2013 в 22:09. |
15.05.2013, 22:55 | #8 |
Пользователь
Регистрация: 06.01.2012
Сообщений: 98
Сказал(а) спасибо: 12
Поблагодарили 33 раз(а) в 21 сообщениях
|
Код:
glPushMatrix(); glTranslatef glRotatef Draw() glPopMatrix(); |
Пользователь сказал cпасибо: | lovepsone (16.05.2013) |
16.05.2013, 13:21 | #9 |
Ученый
Регистрация: 07.03.2010
Адрес: Беларусь,Брест
Сообщений: 188
Сказал(а) спасибо: 131
Поблагодарили 34 раз(а) в 27 сообщениях
|
Завтра буду дома, постараюсь доделать! Код вполне рабочий, но нужно оптимизировать... Всем спасибо!
__________________
sql-language.ru |