📄 glwindow.c
字号:
/****************************************************************************** $Id: glbox.cpp,v 1.5.2.1 1999/09/08 08:30:38 aavit Exp $**** Implementation of GLWindow** This is a simple QGLWidget displaying an openGL wireframe box**** The OpenGL code is mostly borrowed from Brian Pauls "spin" example** in the Mesa distribution******************************************************************************/#include <stdlib.h>#include <stdio.h>#include <iostream>#include <ctype.h>#include <math.h>#include <time.h>#include <qapplication.h>#include <assert.h>#include <GL/glut.h>#include <fstream>//#include "ClusterTool.hpp"#include <GL/gl.h>#include "_generic.h"//#include "geometry.h"#include "real.h"#include "glwindow.h"#include "glwindow_geometry.h"// Camera - define the camera viewclass Camera{public: double fovy, aspect; double znear, zfar; gpoint3_t from, at, up; void look_at( const GBBox & bb, double ratio = 1.333333 ); void apply(); void apply(GLenum mode);};// ArcBall - based on public domain code published by// Ken Shoemake in Graphics Gems IV.struct BallData;class Arcball {private: int mousex, mousey; int startx, starty; BallData *ball; GPoint4 center; float radius; enum {NoDrag=0, Spin, Dolly, Zoom} dragging;public: GPoint4 vNow; float cam[3];public: Arcball() { ball=NULL; } Arcball(const GBBox & bb, float aspect) { ball=NULL; init( bb,aspect); } ~Arcball(); void init(const GBBox& bounds, float aspect); bool mouse_down(int which, int x, int y, int width, int height ); bool mouse_up(int which, int x, int y); bool motion(int x, int y, int width, int height ); // bool motion(int x, int y); void apply(); void unapply(); double *get_qnow();};/*! Create a GLWindow widget*/GLWindow::GLWindow( QWidget* parent, const char* name ) : QGLWidget( parent, name ){ gl_scene = 0; //object = 0; f_draw_direct = false; //true; f_display_scene = true; camera = new Camera(); arcball = new Arcball();}/*! Release allocated resources*/GLWindow::~GLWindow(){ glDeleteLists( gl_scene, 1 );}void GLWindow::prepareGL(){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* glMatrixMode(GL_PROJECTION); glLoadIdentity(); camera->apply(); */ //glMatrixMode(GL_MODELVIEW); //arcball->apply();}void GLWindow::smartDrawScene(){ if ( f_draw_direct ) { drawScene(); return; } if ( gl_scene != 0 ) { glCallList( gl_scene ); //printf( "calling list!\n" ); return; } //printf( "1\n" ); gl_scene = glGenLists(1); glNewList( gl_scene, GL_COMPILE); drawScene(); glEndList(); glCallList( gl_scene ); //printf( "2\n" );}void GLWindow::paintGL(){ //glClear( GL_COLOR_BUFFER_BIT ); prepareGL(); glMatrixMode(GL_MODELVIEW); arcball->apply(); //glCallList( object ); //printf ( "%d, %d\n", f_display_terrain, f_display_simp ); if ( f_display_scene ) smartDrawScene(); glFlush(); glMatrixMode(GL_MODELVIEW); arcball->unapply();}/*! Set up the OpenGL rendering state, and define display list*/void GLWindow::initializeGL(){ //printf( "initializeGL!\n" ); //glCullFace( GL_FRONT_AND_BACK ); glDisable( GL_CULL_FACE ); //glEnable( GL_CULL_FACE ); //glEnable( GL_LIGHTING ); //glEnable( GL_LIGHT0 ); glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE ); glEnable( GL_DEPTH_TEST ); glShadeModel( GL_SMOOTH ); glEnable( GL_NORMALIZE ); // // Initialize the general GL setup // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); glShadeModel(GL_SMOOTH); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); GLfloat mat_ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f }; GLfloat mat_diffuse[] = { 0.5f, 0.5f, 0.5f, 1.0f }; GLfloat mat_specular[] = { 0.1f, 0.1f, 0.1f, 1.0f }; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular); glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 40); GLfloat light_pos[] = {0.0f, 0.0f, 1.0f, 0.0f}; glLightfv(GL_LIGHT0, GL_POSITION, light_pos); glEnable(GL_LIGHT0); GLfloat light_pos_1[] = {5.0f, 0.0f, 1.0f, 0.0f}; glLightfv( GL_LIGHT1, GL_POSITION, light_pos_1 ); glEnable( GL_LIGHT1 ); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); glColor3f(0.5f, 0.5f, 0.5f); glClearColor(0.3f, 0.3f, 1.0f, 0.0f);}/*! Set up the OpenGL view port, matrix mode, etc.*/void GLWindow::resizeGL( int w, int h ){ prepareView();}/*! Set the rotation angle of the object to \e degrees around the X axis.*/void GLWindow::deleteGLObject(){ if ( gl_scene != 0 ) glDeleteLists( gl_scene, 1 ); gl_scene = 0;}inline int button_trans( int button ){ switch ( button ) { case Qt::LeftButton : return 1; case Qt::MidButton : return 2; case Qt::RightButton : return 3; }; return button;}void GLWindow::mousePressEvent ( QMouseEvent * event ){ //int mouse_x, mouse_y, bwidth; arcball->mouse_down( button_trans( event->button() ), event->x(), event->y(), width(), height() ); // where[0], where[1]); repaint();}void GLWindow::mouseReleaseEvent ( QMouseEvent * event ){ //int mouse_x, mouse_y, bwidth; arcball->mouse_up( button_trans(event->button()), event->x(), event->y() );}void GLWindow::mouseMoveEvent ( QMouseEvent * event ){ bool f_update; //int mouse_x, mouse_y, bwidth; //printf( "mousemoveevent\n" ); f_update = arcball->motion( event->x(), event->y(), width(), height() ); if ( f_update ) repaint(); // where[0], where[1]);}void GLWindow::prepareView(){ //printf( "prepare view!\n"); //deleteGLObject(); GBBox bb; getBBox( &bb ); //bb.dump(); glViewport( 0, 0, width(), height() ); double aspect = (double)width()/(double)height(); camera->look_at( bb, aspect ); //camera->apply(); arcball->init( bb, aspect ); glMatrixMode(GL_PROJECTION); glLoadIdentity(); camera->apply(); //glMatrixMode(GL_MODELVIEW); //repaint();}void Camera::look_at(const GBBox & bb, double ratio){ double d = 3* bb.get_radius() / tan(60*M_PI/180.0); bb.center( at ); memcpy( from, at, sizeof( from ) ); from[Z] += d; up[X] = 0; up[Y] = 1; up[Z] = 0; fovy = 60.0; aspect = ratio; znear = d/20; zfar = 10*d;}void Camera::apply(){ gluPerspective(fovy, aspect, znear, zfar); gluLookAt(from[X], from[Y], from[Z], at[X], at[Y], at[Z], up[X], up[Y], up[Z]);}void Camera::apply(GLenum mode){ GLint last_mode; glGetIntegerv(GL_MATRIX_MODE, &last_mode); glMatrixMode(mode); apply(); glMatrixMode((GLenum)last_mode);}/************************************************************************ "Stolen" from Arcball rotation control -- The Arcball is a handy manipulator for spinning objects in 3D. This particular controller also supports some limited camera and light movements as well. Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. The core arcball code was originally published in: "Arcball Rotation Control" by Ken Shoemake <shoemake@graphics.cis.upenn.edu> in "Graphics Gems IV", Academic Press, 1994. and was placed in the public domain. Originally written for IRIS GL, the OpenGL code is based on the modifications of Victor Ng-Thow-Hing <victorng@dgp.toronto.edu>. Over time, I've made various modifications including: - Porting from ANSI C to C++ - Nominal integration with the MixKit library - Removed drawing code $Id: Arcball.cxx,v 1.19 1999/12/08 17:26:10 garland Exp $ ************************************************************************/class Mat4{private: GPoint4 row[4];protected: inline void copy(const Mat4& m); inline GPoint4 col(int i) const { return GPoint4(row[0].pnt[i], row[1].pnt[i], row[2].pnt[i], row[3].pnt[i] ); }public: // Standard matrices static Mat4 I; static Mat4 zero; static Mat4 unit; /* static Mat4 zero() { Mat4 m; m.row[ 0 ] = m.row[ 1 ] = m.row[ 2 ] = m.row[ 3 ] = GPoint4( 0, 0, 0, 0 ); return m; } static Mat4 I() { Mat4 m; m.row[ 0 ] = GPoint4( 1, 0, 0, 0 ); m.row[ 1 ] = GPoint4( 0, 1, 0, 0 ); m.row[ 2 ] = GPoint4( 0, 0, 1, 0 ); m.row[ 3 ] = GPoint4( 0, 0, 0, 1 ); return m; } */ static Mat4 trans(double,double,double); static Mat4 scale(double,double,double); static Mat4 xrot(double theta); // static Mat4 yrot(double theta); // Angles are in radians static Mat4 zrot(double theta); // // // rotation about an axis given by a unit vector; angle in radians. static Mat4 rot(double theta, double x, double y, double z); // // Viewing matrices static Mat4 persp(double fovy, double aspect, double zmin=0.0, double zmax=0.0); static Mat4 lookat(double e_x, double e_y, double e_z, double at_x, double at_y, double at_z, double up_x, double up_y, double up_z); static Mat4 viewport(double w, double h); // Standard constructors Mat4() { copy(zero); } Mat4(const gpoint4_t& r0,const gpoint4_t& r1, const gpoint4_t& r2,const gpoint4_t& r3) { row[0] = r0; row[1] = *(gpoint4_t *)&r1; row[2] = *(gpoint4_t *)&r2; row[3] = *(gpoint4_t *)&r3; } Mat4(const GPoint4 & r0,const GPoint4 & r1, const GPoint4 & r2,const GPoint4 & r3 ) { row[0] = r0.pnt; row[1] = *(gpoint4_t *)&r1; row[2] = *(gpoint4_t *)&r2; row[3] = *(gpoint4_t *)&r3; } Mat4(const Mat4& m) { copy(m); } // Access methods // M(i, j) == row i;col j double& operator()(int i, int j) { return row[i].pnt[j]; } double operator()(int i, int j) const { return row[i].pnt[j]; } gpoint4_t& operator[](int i) { return row[i].pnt; } const gpoint4_t& operator[](int i) const { return row[i].pnt; } operator double*() { return row[0].pnt; } operator const double*() const { return row[0].pnt; } // Comparison methods inline int operator==(const Mat4&); // Assignment methods inline Mat4& operator=(const Mat4& m) { copy(m); return *this; } inline Mat4& operator+=(const Mat4& m); inline Mat4& operator-=(const Mat4& m); inline Mat4& operator*=(double s); inline Mat4& operator/=(double s); // Arithmetic methods inline Mat4 operator+(const Mat4& m) const; inline Mat4 operator-(const Mat4& m) const; inline Mat4 operator-() const; inline Mat4 operator*(double s) const; inline Mat4 operator/(double s) const; Mat4 operator*(const Mat4& m) const; inline GPoint4 operator*(const GPoint4 & v) const; // [x y z w] inline GPoint3 operator*(const GPoint3 & v) const; // [x y z w] // Matrix operations double det() const; Mat4 transpose() const; Mat4 adjoint() const; double invert(Mat4&) const; double cramerInvert(Mat4&) const;};Mat4 Mat4::I(GPoint4(1,0,0,0), GPoint4(0,1,0,0), GPoint4(0,0,1,0), GPoint4(0,0,0,1));Mat4 Mat4::zero(GPoint4(0,0,0,0), GPoint4(0,0,0,0), GPoint4(0,0,0,0), GPoint4(0,0,0,0));Mat4 Mat4::unit(GPoint4(1,1,1,1), GPoint4(1,1,1,1), GPoint4(1,1,1,1), GPoint4(1,1,1,1));inline void Mat4::copy(const Mat4& m){ row[0] = m.row[0]; row[1] = m.row[1]; row[2] = m.row[2]; row[3] = m.row[3];}inline int Mat4::operator==(const Mat4& m){ return row[0].pnt==m.row[0].pnt && row[1].pnt==m.row[1].pnt && row[2].pnt==m.row[2].pnt && row[3].pnt==m.row[3].pnt ;}inline Mat4& Mat4::operator+=(const Mat4& m){ row[0] += m.row[0]; row[1] += m.row[1]; row[2] += m.row[2]; row[3] += m.row[3]; return *this;}inline Mat4& Mat4::operator-=(const Mat4& m){ row[0] -= m.row[0]; row[1] -= m.row[1]; row[2] -= m.row[2]; row[3] -= m.row[3]; return *this;}inline Mat4& Mat4::operator*=(double s){ row[0] *= s; row[1] *= s; row[2] *= s; row[3] *= s; return *this;}inline Mat4& Mat4::operator/=(double s){ row[0] /= s; row[1] /= s; row[2] /= s; row[3] /= s; return *this;}inline Mat4 Mat4::operator+(const Mat4& m) const{ return Mat4(row[0] + m.row[0], row[1] + m.row[1], row[2] + m.row[2], row[3] + m.row[3]);}inline Mat4 Mat4::operator-(const Mat4& m) const{ return Mat4(row[0]-m.row[0], row[1]-m.row[1], row[2]-m.row[2], row[3]-m.row[3]);}inline Mat4 Mat4::operator-() const{ return Mat4(-row[0], -row[1], -row[2], -row[3]);}inline Mat4 Mat4::operator*(double s) const{ return Mat4(row[0]*s, row[1]*s, row[2]*s, row[3]*s);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -