Ru-MaNGOS

Вернуться   Ru-MaNGOS > Документация > Языки программирования

Важная информация

Языки программирования Изучаем С++, Sql, php, Lua, Python

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 08.05.2013, 17:16   #1
lovepsone
Ученый
 
Регистрация: 07.03.2010
Адрес: Беларусь,Брест
Сообщений: 188
Сказал(а) спасибо: 131
Поблагодарили 34 раз(а) в 27 сообщениях
lovepsone Хрен знает что...lovepsone Хрен знает что...
По умолчанию 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 пока разбираю и опыта нет. Мб кто поможет?
Вложения
Тип файла: zip bes.zip (205.1 Кб, 425 просмотров)
__________________
sql-language.ru

Последний раз редактировалось lovepsone; 15.05.2013 в 22:00.
lovepsone вне форума   Ответить с цитированием
Старый 09.05.2013, 14:32   #2
Sid
Ученый
 
Аватар для Sid
 
Регистрация: 02.04.2010
Сообщений: 237
Сказал(а) спасибо: 41
Поблагодарили 99 раз(а) в 44 сообщениях
Sid Скоро придёт к известностиSid Скоро придёт к известности
По умолчанию

Чувак, я твой фанат теперь Я давно эту идею вынашиваю, написать собственый модельвивер на qt
__________________
SpellWork Qt4
Sid вне форума   Ответить с цитированием
Старый 09.05.2013, 18:03   #3
lovepsone
Ученый
 
Регистрация: 07.03.2010
Адрес: Беларусь,Брест
Сообщений: 188
Сказал(а) спасибо: 131
Поблагодарили 34 раз(а) в 27 сообщениях
lovepsone Хрен знает что...lovepsone Хрен знает что...
По умолчанию

Цитата:
Сообщение от Sid Посмотреть сообщение
Чувак, я твой фанат теперь Я давно эту идею вынашиваю, написать собственый модельвивер на qt
Да вот пока с Opengl изучаю + в Qt интегрирую! Вот тока пока проблем выше крыши!
__________________
sql-language.ru
lovepsone вне форума   Ответить с цитированием
Старый 10.05.2013, 10:21   #4
Evgeniy
Пользователь
 
Регистрация: 06.01.2012
Сообщений: 98
Сказал(а) спасибо: 12
Поблагодарили 33 раз(а) в 21 сообщениях
Evgeniy На верном пути
По умолчанию

glBindTexture после glGenLists...не?
Даже не после а внутри блока....и тестурку выбрать клетчатую салатовую, что бы наверняка знать грузится-нет.
Evgeniy вне форума   Ответить с цитированием
Старый 11.05.2013, 17:40   #5
lovepsone
Ученый
 
Регистрация: 07.03.2010
Адрес: Беларусь,Брест
Сообщений: 188
Сказал(а) спасибо: 131
Поблагодарили 34 раз(а) в 27 сообщениях
lovepsone Хрен знает что...lovepsone Хрен знает что...
По умолчанию

Обновил первый пост!Вроде теперь текстура загружается, но моделька отображается черным цветом!
Смотрите скрин ниже в первом посте!

Я даже нарисовал куб и попытался наложить текстуру, но нечего не вышло! Значит я чего-то не знаю... Буду думать.
__________________
sql-language.ru

Последний раз редактировалось lovepsone; 11.05.2013 в 18:41.
lovepsone вне форума   Ответить с цитированием
Старый 11.05.2013, 20:00   #6
Sid
Ученый
 
Аватар для Sid
 
Регистрация: 02.04.2010
Сообщений: 237
Сказал(а) спасибо: 41
Поблагодарили 99 раз(а) в 44 сообщениях
Sid Скоро придёт к известностиSid Скоро придёт к известности
По умолчанию

Альфа канал указал верно? Я помню когда делал для m2 то текстура blp в RGBA не отображалась, потом выставил альфа на максимум и все появилось Долго ломал тогда голову )
__________________
SpellWork Qt4
Sid вне форума   Ответить с цитированием
Старый 15.05.2013, 21:59   #7
lovepsone
Ученый
 
Регистрация: 07.03.2010
Адрес: Беларусь,Брест
Сообщений: 188
Сказал(а) спасибо: 131
Поблагодарили 34 раз(а) в 27 сообщениях
lovepsone Хрен знает что...lovepsone Хрен знает что...
По умолчанию

Текстуру удалось наложить, но есть некоторые проблемы!
Я поворачиваю камеру на 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();
И что вы думаете? Не получилось... Далее я полез в фотошоп и повернул текстуру на 90 градусов по часовой... Все ок! Текстура легла как надо!!!
Меня это не устроило и попробовал поворачивать текстуру перед наложением на модель(в самом коде). Сделал так:
Код:
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.
lovepsone вне форума   Ответить с цитированием
Старый 15.05.2013, 22:55   #8
Evgeniy
Пользователь
 
Регистрация: 06.01.2012
Сообщений: 98
Сказал(а) спасибо: 12
Поблагодарили 33 раз(а) в 21 сообщениях
Evgeniy На верном пути
По умолчанию

Код:
glPushMatrix(); 
glTranslatef
glRotatef
Draw()
glPopMatrix();
Всегда вращай и двигай объект, а не камеру ...тогда не надо пересчитывать все координаты (всмысле тектурные, нормали и т.п.)...
Evgeniy вне форума   Ответить с цитированием
Пользователь сказал cпасибо:
lovepsone (16.05.2013)
Старый 16.05.2013, 13:21   #9
lovepsone
Ученый
 
Регистрация: 07.03.2010
Адрес: Беларусь,Брест
Сообщений: 188
Сказал(а) спасибо: 131
Поблагодарили 34 раз(а) в 27 сообщениях
lovepsone Хрен знает что...lovepsone Хрен знает что...
По умолчанию

Завтра буду дома, постараюсь доделать! Код вполне рабочий, но нужно оптимизировать... Всем спасибо!
__________________
sql-language.ru
lovepsone вне форума   Ответить с цитированием
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.



Текущее время: 08:28. Часовой пояс GMT +3.


ru-mangos.ru - Русское сообщество MaNGOS
Главная цель проекта MaNGOS - обучающая, поэтому разрешается использовать исходный код и собранную программу только для образовательных целей.
Вы не можете использовать MaNGOS в коммерческих целях, а также не разрешается устанавливать публичные серверы на базе MaNGOS.
Любое копирование материалов, информации в любом виде без указания источника - форума Ru-MaNGOS будет считаться нарушением авторских прав и нарушением Уголовного Кодекса РФ, ст. 146 ст. 147.
Перевод vBulletin: zCarot