Logo Search packages:      
Sourcecode: view3ds version File versions  Download package

viewport.cpp

/*
 * The 3D Studio File Format Library
 * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
 * All rights reserved.
 *
 * This program is  free  software;  you can redistribute it and/or modify it
 * under the terms of the  GNU Lesser General Public License  as published by 
 * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
 * your option) any later version.
 *
 * This  program  is  distributed in  the  hope that it will  be useful,  but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
 * License for more details.
 *
 * You should  have received  a copy of the GNU Lesser General Public License
 * along with  this program;  if not, write to the  Free Software Foundation,
 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: viewport.cpp,v 1.3 2001/01/15 10:56:12 jeh Exp $
 */
#include "viewport.h"
#include "document.h"
#include <lib3ds/file.h>
#include <lib3ds/node.h>
#include <lib3ds/mesh.h>
#include <lib3ds/vector.h>
#include <lib3ds/quat.h>
#include <lib3ds/matrix.h>
#include <lib3ds/material.h>
#include <lib3ds/camera.h>
#include <GL/gl.h>
#include <GL/glu.h>


/*!
 *
 */
Viewport::Viewport(Document *doc, const QGLFormat& f, QWidget *parent, const char* name) 
  : QGLWidget(f, parent, name)
{
  d_doc=doc;
}


/*!
 *
 */
Viewport::~Viewport()
{
}


/*!
 *
 */
void 
Viewport::initializeGL()
{
  glClearColor(0.5, 0.5, 0.5, 1.0);

  GLfloat lightPos[] = {0.0f, 0.0f, 1.0f, 0.0f};
  glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);
  glDepthFunc(GL_LEQUAL);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_CULL_FACE);
  glCullFace(GL_BACK);
  glEnable(GL_NORMALIZE);
  glPolygonOffset(1.0, 2);
}


/*!
 *
 */
void 
Viewport::resizeGL(int w, int h)
{
  d_glWidth=w;
  d_glHeight=h;
  glViewport(0,0,w,h);
}


void
Viewport::renderNode(Lib3dsNode *node)
{
  Lib3dsFile *file=d_doc->file();
  ASSERT(file);

  {
    Lib3dsNode *p;
    for (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);
      ASSERT(mesh);
      if (!mesh) {
        return;
      }

      node->user.d=glGenLists(1);
      glNewList(node->user.d, GL_COMPILE);

      float s[1];
      unsigned p;
      Lib3dsMatrix invMeshMatrix;
      lib3ds_matrix_copy(invMeshMatrix, mesh->matrix);
      lib3ds_matrix_inv(invMeshMatrix);

      for (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) {
          s[0]=1.0;
          glMaterialfv(GL_FRONT, GL_AMBIENT, mat->ambient);
          glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse);
          glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular);
          glMaterialf(GL_FRONT, GL_SHININESS, 11.0-0.1*mat->shininess);
        }
        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);
          glMaterialf(GL_FRONT, GL_SHININESS, 0.0);
        }
        {
          int i;
          Lib3dsVector v[3];
          for (i=0; i<3; ++i) {
            lib3ds_vector_transform(v[i], invMeshMatrix, mesh->pointL[f.points[i]].pos);
          }
          glBegin(GL_TRIANGLES);
            glNormal3fv(f.normal);
            glVertex3fv(v[0]);
            glVertex3fv(v[1]);
            glVertex3fv(v[2]);
          glEnd();
        }
      }

      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 
Viewport::paintGL()
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  Lib3dsFile *file=d_doc->file();
  if (!file) {
    return;
  }
  QString camera=d_doc->camera();
  Lib3dsNode *c=lib3ds_file_node_by_name(file, (const char*)camera, LIB3DS_CAMERA_NODE);
  Lib3dsNode *t=lib3ds_file_node_by_name(file, (const char*)camera, LIB3DS_TARGET_NODE);
  if (!c || !t) {
    return;
  }

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective( c->data.camera.fov, 1.0*d_glWidth/d_glHeight, 1.0, 20000.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glRotatef(-90, 1.0,0,0);

  Lib3dsMatrix M;
  lib3ds_matrix_camera(M, c->data.camera.pos, t->data.target.pos, c->data.camera.roll);
  glMultMatrixf(&M[0][0]);
  
  {
    Lib3dsNode *p;
    for (p=file->nodes; p!=0; p=p->next) {
      renderNode(p);
    }
  }
  glFlush();
}



Generated by  Doxygen 1.6.0   Back to index