Показать сообщение отдельно
Старый 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 Кб, 238 просмотров)
__________________
sql-language.ru

Последний раз редактировалось lovepsone; 15.05.2013 в 22:00.
lovepsone вне форума   Ответить с цитированием