]> Git trees. - libqmvoc.git/commitdiff
* Many many changes by Benoit in the OpenGL-code
authorCarsten Niehaus <cniehaus@gmx.de>
Sat, 17 Jun 2006 08:26:31 +0000 (08:26 +0000)
committerCarsten Niehaus <cniehaus@gmx.de>
Sat, 17 Jun 2006 08:26:31 +0000 (08:26 +0000)
svn path=/trunk/KDE/kdeedu/kalzium/src/kalziumglwidget.h; revision=552261

kalzium/kalziumglwidget.cpp
kalzium/kalziumglwidget.h

index c695b5c4e8fc34d6e1e7fec8fe4d0b6be55b6e47..43ea0e35c81f09dc83cbe6f2f27728db3d3cb17a 100644 (file)
 
 using namespace OpenBabel;
 
-GLVertexArray::GLVertexArray()
-{
-       m_vertices = 0;
-       m_indices = 0;
-}
-
-GLVertexArray::~GLVertexArray()
-{
-       if( m_vertices ) delete []m_vertices;
-       if( m_indices ) delete []m_indices;
-}
-
-void GLVertexArray::draw()
-{
-       if( ! m_vertices ) return;
-       if( ! m_indices ) return;
-       glInterleavedArrays( GL_N3F_V3F, 0,  m_vertices );
-       glDrawElements( GL_TRIANGLE_STRIP, m_nbIndices, GL_UNSIGNED_SHORT, m_indices );
-}
-
-SphereVertexArray::SphereVertexArray( unsigned int strips,
-       unsigned int lozangesPerStrip ) : GLVertexArray()
-{
-       regenerate( strips, lozangesPerStrip );
-}
-
-SphereVertexArray::~SphereVertexArray()
-{
-}
-
-void SphereVertexArray::regenerate( unsigned int strips,
-       unsigned int lozangesPerStrip )
-{
-       m_strips = strips;
-       m_lozangesPerStrip = lozangesPerStrip;
-       if( m_vertices ) delete []m_vertices;
-       if( m_indices ) delete []m_indices;
-       generate();
-}
-
-void SphereVertexArray::generate()
-{
-
-}
-
 KalziumGLWidget::KalziumGLWidget( QWidget * parent )
        : QGLWidget( parent )
 {
@@ -78,7 +33,9 @@ KalziumGLWidget::KalziumGLWidget( QWidget * parent )
        m_isDragging = false;
        m_molecule = 0;
        m_detail = 0;
-       m_atomsRadiusCoeff = 0.0;
+       m_useFog = false;
+
+       slotChooseStylePreset( PRESET_SPHERES_AND_BICOLOR_BONDS );
        
        setMinimumSize( 100,100 );
 }
@@ -94,7 +51,7 @@ void KalziumGLWidget::initializeGL()
        glClearColor( 0.0, 0.0, 0.0, 1.0 );
        glShadeModel( GL_SMOOTH );
        glEnable( GL_DEPTH_TEST );
-       glDisable( GL_CULL_FACE );
+       glEnable( GL_CULL_FACE );
        glDisable( GL_BLEND );
 
        glMatrixMode( GL_MODELVIEW );
@@ -116,7 +73,7 @@ void KalziumGLWidget::initializeGL()
        glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
        glLightfv(GL_LIGHT0, GL_POSITION, position);
 
-//     glEnable(GL_FOG);
+       glEnable(GL_FOG);
        GLfloat fogColor[] = { 0.0, 0.0, 0.0, 1.0 };
        glFogfv( GL_FOG_COLOR, fogColor );
        glFogi( GL_FOG_MODE, GL_LINEAR );
@@ -171,37 +128,75 @@ void KalziumGLWidget::getColor( OBAtom &a, GLfloat &r, GLfloat &g, GLfloat &b )
 
 void KalziumGLWidget::paintGL()
 {
+       glMatrixMode( GL_PROJECTION );
+       glLoadIdentity();
+       gluPerspective( 40.0, float( width() ) / height(), m_molRadius, 5.0 * (m_molRadius + atomRadius ()));
+       glMatrixMode( GL_MODELVIEW );
+
        if( !m_molecule )
                return;
 
-       float bondsRadius = m_molMinBondLength / 8;
-       float atomsRadius = (1 - m_atomsRadiusCoeff) * bondsRadius
-                         + m_atomsRadiusCoeff * m_molMinBondLength / 2;
-       
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+       
+       // set up the camera
        glLoadIdentity();
-       GLTRANSLATE ( 0.0, 0.0, -3.0 * m_molRadius);
+       GLTRANSLATE ( 0.0, 0.0, -3.0 * (m_molRadius + atomRadius () ) );
        GLMULTMATRIX ( m_RotationMatrix );
 
-       glEnable( GL_NORMALIZE );
-       FOR_ATOMS_OF_MOL( a, m_molecule )
+       // set up fog
+       if( m_useFog == true )
        {
-               FLOAT x = ( FLOAT )a->GetX();
-               FLOAT y = ( FLOAT )a->GetY();
-               FLOAT z = ( FLOAT )a->GetZ();
+               glEnable( GL_FOG );
+               GLfloat fogColor[] = { 0.0, 0.0, 0.0, 1.0 };
+               glFogfv( GL_FOG_COLOR, fogColor );
+               glFogi( GL_FOG_MODE, GL_LINEAR );
+               glFogf( GL_FOG_DENSITY, 0.45 );
+               glFogf( GL_FOG_START, 2.7 * ( m_molRadius + atomRadius() ) );
+               glFogf( GL_FOG_END, 5.0 * ( m_molRadius + atomRadius() ) );
+       }
+       else glDisable( GL_FOG );
 
-               GLfloat r, g, b;
+       // render the atoms
+       if( m_atomStyle == ATOM_SPHERE )
+       {
+               glEnable( GL_NORMALIZE );
+               glEnable( GL_LIGHTING );
 
-               getColor( *a, r, g, b );
+               FOR_ATOMS_OF_MOL( a, m_molecule )
+               {
+                       FLOAT x = (FLOAT) a->GetX();
+                       FLOAT y = (FLOAT) a->GetY();
+                       FLOAT z = (FLOAT) a->GetZ();
+       
+                       GLfloat r, g, b;
+       
+                       getColor( *a, r, g, b );
                
-               drawSphere(
+                       drawSphere(
                                x, y, z,
-                               atomsRadius,
+                               atomRadius (),
                                r, g, b);
+               }
+
+               glDisable( GL_NORMALIZE );
+       }
+
+       // prepare for rendering the bonds
+       switch( m_bondStyle )
+       {
+               case BOND_LINE:
+                       glDisable( GL_LIGHTING );
+                       break;
+               
+               case BOND_CYLINDER_GRAY:
+               case BOND_CYLINDER_BICOLOR:
+                       glEnable( GL_LIGHTING );
+                       break;
+               case BOND_DISABLED: break;
        }
 
-       glDisable( GL_NORMALIZE );
-       FOR_BONDS_OF_MOL( bond, m_molecule )
+       // render the bonds
+       if( BOND_DISABLED != m_bondStyle) FOR_BONDS_OF_MOL( bond, m_molecule )
        {
                FLOAT x1 = (FLOAT) static_cast<OBAtom*>(bond->GetBgn())->GetX();
                FLOAT y1 = (FLOAT) static_cast<OBAtom*>(bond->GetBgn())->GetY();
@@ -214,21 +209,40 @@ void KalziumGLWidget::paintGL()
                FLOAT y3 = (y1 + y2) / 2;
                FLOAT z3 = (z1 + z2) / 2;
                
-               GLfloat r, g, b;
-               getColor( *static_cast<OBAtom*>(bond->GetBgn()), r, g, b );
-               drawBond( x1, y1, z1, x3, y3, z3, r, g, b );
-               getColor( *static_cast<OBAtom*>(bond->GetEnd()), r, g, b );
-               drawBond( x2, y2, z2, x3, y3, z3, r, g, b );
+               GLfloat r1, g1, b1, r2, g2, b2;
+               getColor( *static_cast<OBAtom*>(bond->GetBgn()), r1, g1, b1 );
+               getColor( *static_cast<OBAtom*>(bond->GetEnd()), r2, g2, b2 );
+               
+               switch( m_bondStyle )
+               {
+                       case BOND_LINE:
+                               glBegin( GL_LINES );
+                               glColor3f( r1, g1, b1 );
+                               glVertex3f( x1, y1, z1 );
+                               glVertex3f( x3, y3, z3 );
+                               glColor3f( r2, g2, b2 );
+                               glVertex3f( x3, y3, z3 );
+                               glVertex3f( x2, y2, z2 );
+                               glEnd();
+                               break;
+                       
+                       case BOND_CYLINDER_GRAY:
+                               drawBond( x1, y1, z1, x2, y2, z2, 0.5, 0.5, 0.5 );
+                               break;
+
+                       case BOND_CYLINDER_BICOLOR:
+                               drawBond( x1, y1, z1, x3, y3, z3, r1, g1, b1 );
+                               drawBond( x2, y2, z2, x3, y3, z3, r2, g2, b2 );
+                               break;
+
+                       case BOND_DISABLED: break;
+               }
        }
 }
 
 void KalziumGLWidget::resizeGL( int width, int height )
 {
-       glViewport( 0, 0, width, height );
-       glMatrixMode( GL_PROJECTION );
-       glLoadIdentity();
-       gluPerspective( 40.0, float(width) / height, m_molRadius, 5.0 * m_molRadius );
-       glMatrixMode( GL_MODELVIEW );
+       glViewport( 0, 0, width , height );
 }
 
 void KalziumGLWidget::mousePressEvent( QMouseEvent * event )
@@ -303,7 +317,9 @@ void KalziumGLWidget::drawGenericBond()
 {
        int slices;
        static int lastDetail = -1;
-       if( 0 == m_bondDisplayList  || lastDetail != m_detail)
+       static float lastBondRadiusCoeff = -1.0;
+       if( 0 == m_bondDisplayList  || lastDetail != m_detail
+        || lastBondRadiusCoeff != m_bondRadiusCoeff)
        {
                m_bondDisplayList = glGenLists( 1 );
                if( 0 == m_bondDisplayList ) return;
@@ -324,17 +340,18 @@ void KalziumGLWidget::drawGenericBond()
                for (double i = 0.0; i < slices; i++)
                {       
                        glNormal3f( cos(2*M_PI * i/slices), sin(2*M_PI * i/slices), 0.0 );
-                       glVertex3f( cos(2*M_PI * i/slices) * m_bondsRadius, sin(2*M_PI * i/slices) * m_bondsRadius, 1.0 );
+                       glVertex3f( cos(2*M_PI * i/slices) * bondRadius(), sin(2*M_PI * i/slices) * bondRadius(), 1.0 );
                        glNormal3f( cos(2*M_PI * i/slices), sin(2*M_PI * i/slices), 0.0 );
-                       glVertex3f( cos(2*M_PI * i/slices) * m_bondsRadius, sin(2*M_PI * i/slices) * m_bondsRadius, 0.0 );
+                       glVertex3f( cos(2*M_PI * i/slices) * bondRadius(), sin(2*M_PI * i/slices) * bondRadius(), 0.0 );
                        glNormal3f( cos(2*M_PI * (i+1)/slices), sin(2*M_PI * (i+1)/slices), 0.0 );
-                       glVertex3f( cos(2*M_PI * (i+1)/slices) * m_bondsRadius, sin(2*M_PI * (i+1)/slices) * m_bondsRadius, 0.0 );
+                       glVertex3f( cos(2*M_PI * (i+1)/slices) * bondRadius(), sin(2*M_PI * (i+1)/slices) * bondRadius(), 0.0 );
                        glNormal3f( cos(2*M_PI * (i+1)/slices), sin(2*M_PI * (i+1)/slices), 0.0 );
-                       glVertex3f( cos(2*M_PI * (i+1)/slices) * m_bondsRadius, sin(2*M_PI * (i+1)/slices) * m_bondsRadius, 1.0 );
+                       glVertex3f( cos(2*M_PI * (i+1)/slices) * bondRadius(), sin(2*M_PI * (i+1)/slices) * bondRadius(), 1.0 );
                }
                glEnd();
                glEndList();
                lastDetail = m_detail;
+               lastBondRadiusCoeff = m_bondRadiusCoeff;
        }
        
        glCallList( m_bondDisplayList );
@@ -418,12 +435,66 @@ void KalziumGLWidget::drawBond( FLOAT x1, FLOAT y1, FLOAT z1,
        glPopMatrix();
 }
 
+
+inline float KalziumGLWidget::bondRadius()
+{
+       return m_bondRadiusCoeff * m_molMinBondLength;
+       
+}
+inline float KalziumGLWidget::atomRadius()
+{
+       return m_atomRadiusCoeff * m_molMinBondLength;
+}
+
 void KalziumGLWidget::slotSetMolecule( OpenBabel::OBMol* molecule )
 {
        if ( !molecule ) return;
-
        m_molecule = molecule;
-       
+       prepareMoleculeData();
+       updateGL();
+}
+
+void KalziumGLWidget::slotChooseStylePreset( StylePreset stylePreset )
+{
+       switch( stylePreset )
+       {
+               case PRESET_LINES:
+                       m_atomStyle = ATOM_DISABLED;
+                       m_bondStyle = BOND_LINE;
+                       m_atomRadiusCoeff = 0.0;
+                       m_bondRadiusCoeff = 0.0;
+                       break;
+               case PRESET_STICKS:
+                       m_atomStyle = ATOM_SPHERE;
+                       m_bondStyle = BOND_CYLINDER_BICOLOR;
+                       m_atomRadiusCoeff = 0.13;
+                       m_bondRadiusCoeff = 0.13;
+                       break;
+               case PRESET_SPHERES_AND_GRAY_BONDS:
+                       m_atomStyle = ATOM_SPHERE;
+                       m_bondStyle = BOND_CYLINDER_GRAY;
+                       m_atomRadiusCoeff = 0.20;
+                       m_bondRadiusCoeff = 0.05;
+                       break;
+               case PRESET_SPHERES_AND_BICOLOR_BONDS:
+                       m_atomStyle = ATOM_SPHERE;
+                       m_bondStyle = BOND_CYLINDER_BICOLOR;
+                       m_atomRadiusCoeff = 0.20;
+                       m_bondRadiusCoeff = 0.05;
+                       break;
+               case PRESET_BIG_SPHERES:
+                       m_atomStyle = ATOM_SPHERE;
+                       m_bondStyle = BOND_DISABLED;
+                       m_atomRadiusCoeff = 2.4;
+                       m_bondRadiusCoeff = 0.0;
+                       break;
+       }
+
+       updateGL();
+}
+
+void KalziumGLWidget::prepareMoleculeData()
+{
        // translate the molecule so that center has coords 0,0,0
        m_molecule->Center();
 
@@ -460,23 +531,18 @@ void KalziumGLWidget::slotSetMolecule( OpenBabel::OBMol* molecule )
                if( len < m_molMinBondLength )
                        m_molMinBondLength = len;
        }
-
-       m_bondsRadius = m_molMinBondLength / 8;
-       
-       updateGL();
 }
 
 void KalziumGLWidget::slotSetDetail( int detail )
 {
        m_detail = detail;
-       if( 2 <= m_detail ) glEnable( GL_FOG );
-       else glDisable( GL_FOG );
+       if( m_detail >= 2 ) m_useFog = true;
+       else m_useFog = false;
        updateGL();
 }
 
-bool approx_equal( FLOAT a, FLOAT b )
+bool KalziumGLWidget::approx_equal( FLOAT a, FLOAT b, FLOAT precision )
 {
-       const FLOAT precision = 0.01;
        FLOAT abs_a = FABS( a );
        FLOAT abs_b = FABS( b );
 
@@ -485,16 +551,15 @@ bool approx_equal( FLOAT a, FLOAT b )
                max_abs = abs_b;
        else
                max_abs = abs_a;
-       if( 0.0 == max_abs ) return true;
-       else return( FABS( a - b ) < precision * max_abs );
+       return( FABS( a - b ) <= precision * max_abs );
 }
 
-FLOAT norm3( FLOAT *u )
+FLOAT KalziumGLWidget::norm3( FLOAT *u )
 {
        return SQRT( u[0] * u[0] + u[1] * u[1] + u[2] * u[2] );
 }
 
-void normalize3( FLOAT *u )
+void KalziumGLWidget::normalize3( FLOAT *u )
 {
        FLOAT n = norm3( u );
        if( 0 == n ) return;
@@ -503,7 +568,7 @@ void normalize3( FLOAT *u )
        u[2] /= n;
 }
 
-void construct_ortho_3D_basis_given_first_vector3(
+void KalziumGLWidget::construct_ortho_3D_basis_given_first_vector3(
        const FLOAT *U, FLOAT *v, FLOAT *w)
 {
        // let us first make a normalized copy of U
@@ -515,16 +580,16 @@ void construct_ortho_3D_basis_given_first_vector3(
        // initially we set v = u
        v[0] = u[0]; v[1] = u[1]; v[2] = u[2];
 
-       // next we want to change v so that it becomes nocolinear to u
-       if( ! approx_equal( v[0], v[1] ) )
+       // next we want to change v so that it becomes non-colinear to u
+       if( ! approx_equal( v[0], v[1], 0.01 ) )
        {
-               GLFLOAT tmp = v[0];
+               FLOAT tmp = v[0];
                v[0] = v[1];
                v[1] = tmp;
        }
-       else if( ! approx_equal( v[1], v[2] ) )
+       else if( ! approx_equal( v[1], v[2], 0.01 ) )
        {
-               GLFLOAT tmp = v[2];
+               FLOAT tmp = v[2];
                v[2] = v[1];
                v[1] = tmp;
        }
@@ -548,4 +613,66 @@ void construct_ortho_3D_basis_given_first_vector3(
        w[2] = u[0] * v[1] - u[1] * v[0];
 }
 
+inline void GLColor::apply()
+{
+       glColor3fv( reinterpret_cast<GLfloat *>( this ) );
+}
+
+void GLColor::applyAsMaterials()
+{
+       GLfloat ambientColor [] = { red / 2, green / 2, blue / 2, 1.0 };
+       GLfloat diffuseColor [] = { red, green, blue, 1.0 };
+       GLfloat specularColor [] = { (2.0 + red) / 3, (2.0 + green) / 3,
+               (2.0 + blue) / 3, 1.0 };
+       glMaterialfv(GL_FRONT, GL_AMBIENT, ambientColor);
+       glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseColor);
+       glMaterialfv(GL_FRONT, GL_SPECULAR, specularColor);
+       glMaterialf(GL_FRONT, GL_SHININESS, 50.0);
+}
+
+GLVertexArray::GLVertexArray()
+{
+       m_vertices = 0;
+       m_indices = 0;
+}
+
+GLVertexArray::~GLVertexArray()
+{
+       if( m_vertices ) delete []m_vertices;
+       if( m_indices ) delete []m_indices;
+}
+
+void GLVertexArray::draw()
+{
+       if( ! m_vertices ) return;
+       if( ! m_indices ) return;
+       glInterleavedArrays( GL_N3F_V3F, 0,  m_vertices );
+       glDrawElements( GL_TRIANGLE_STRIP, m_nbIndices, GL_UNSIGNED_SHORT, m_indices );
+}
+
+SphereVertexArray::SphereVertexArray( unsigned int strips,
+       unsigned int lozangesPerStrip ) : GLVertexArray()
+{
+       regenerate( strips, lozangesPerStrip );
+}
+
+SphereVertexArray::~SphereVertexArray()
+{
+}
+
+void SphereVertexArray::regenerate( unsigned int strips,
+       unsigned int lozangesPerStrip )
+{
+       m_strips = strips;
+       m_lozangesPerStrip = lozangesPerStrip;
+       if( m_vertices ) delete []m_vertices;
+       if( m_indices ) delete []m_indices;
+       generate();
+}
+
+void SphereVertexArray::generate()
+{
+
+}
+
 #include "kalziumglwidget.moc"
index d301654a5a0d24f140fb11bdd4dee43991ff2a61..eafb904eda53615b335d91be33032c45679cac57 100644 (file)
 #define FABS           fabsf
 #endif
 
-/**
- * This is an abstract base class for a GL vertex array
- *
- * @author Benoit Jacob
- */
-class GLVertexArray
-{
-       protected:
-               struct Vertex {
-                       float nx, ny, nz;
-                       float vx, vy, vz;
-               };
-
-               Vertex *m_vertices;
-               unsigned short *m_indices;
-               unsigned int m_nbVertices;
-               unsigned int  m_nbIndices;
-               
-               virtual void generate() = 0;
-       public:
-               GLVertexArray();
-               virtual ~GLVertexArray();
-               void draw();
-};
-
-/**
- * This class generates and stores a GL vertex array representing a sphere
- *
- * @author Benoit Jacob
- */
-class SphereVertexArray : public GLVertexArray
-{
-       protected:
-               unsigned int m_strips, m_lozangesPerStrip;
-               virtual void generate();
-
-       public:
-               SphereVertexArray(unsigned int strips, unsigned int lozangesPerStrip);
-               virtual ~SphereVertexArray();
-
-               virtual void regenerate(unsigned int strips, unsigned int lozangesPerStrip);
-};
-
 /**
  * This class displays the 3D-view of a molecule
  * 
@@ -100,11 +57,106 @@ class KalziumGLWidget : public QGLWidget
                 * the view
                 */
                bool m_isDragging;
-               
+
                QPoint m_lastDraggingPosition;
 
                GLFLOAT m_RotationMatrix[16];
 
+               /**
+                * The molecule which is displayed
+                */
+               OpenBabel::OBMol* m_molecule;
+               FLOAT m_molRadius;
+               FLOAT m_molMinBondLength;
+               FLOAT m_molMaxBondLength;
+
+               /**
+                * The coefficient set by the user, determining the
+                * radius of atoms.
+                * WARNING: its meaning has just changed! (june 17)
+                * Now the actual radius is proportional to
+                * m_atomRadiusCoeff.
+                */
+               float m_atomRadiusCoeff;
+
+               /**
+                * The coefficient set by the user, determining the
+                * radius (that is, half the thickness) of bonds.
+                */
+               float m_bondRadiusCoeff;
+
+               /**
+                * The detail-grade from 0 to 2.
+                */
+               int m_detail;
+
+               /**
+                * Set this to true to enable the fog effect
+                */
+               bool m_useFog;
+
+               /**
+                * The style in which the atoms are rendered.
+                */
+               enum AtomStyle
+               {
+                       ATOM_DISABLED,
+                       ATOM_SPHERE
+               } m_atomStyle;
+
+               /**
+                * The style in which the bonds are rendered.
+                */
+               enum BondStyle
+               {
+                       BOND_DISABLED,
+                       BOND_LINE,
+                       BOND_CYLINDER_GRAY,
+                       BOND_CYLINDER_BICOLOR
+               } m_bondStyle;
+
+               /**
+                * Some style presets
+                */
+               enum StylePreset
+               {
+                       PRESET_LINES,
+                       PRESET_STICKS,
+                       PRESET_SPHERES_AND_GRAY_BONDS,
+                       PRESET_SPHERES_AND_BICOLOR_BONDS,
+                       PRESET_BIG_SPHERES
+               };
+
+       private: // some standard 3D math stuff here
+
+               /**
+                * Tests whether two FLOATs are approximately equal.
+                * Recall that operator == between floating-point types
+                * is broken.
+                * returns true if abs( a - b ) <= c * precision
+                * where c = max( abs( a ), abs( b ) )
+                */
+               bool approx_equal( FLOAT a, FLOAT b, FLOAT precision );
+
+               /**
+                * Returns the norm of a 3D vector
+                */
+               FLOAT norm3( FLOAT *u );
+
+               /**
+                * Normalizes a 3D vector
+                */
+               void normalize3( FLOAT *u );
+
+               /**
+                * Given a 3D vector U, constructs two vectors v and w
+                * such that (U, v, w) is a direct orthogonal basis.
+                * U is not supposed to be normalized, and v and w
+                * are not getting normalized.
+                */
+               void construct_ortho_3D_basis_given_first_vector3(
+                       const FLOAT *U, FLOAT *v, FLOAT *w);
+
        public:
                /**
                 * Constructor
@@ -116,10 +168,14 @@ class KalziumGLWidget : public QGLWidget
                 */
                virtual ~KalziumGLWidget();
 
+               /**
+                * This methods returns the color in which a given atom
+                * should be painted.
+                */
                virtual void getColor( OpenBabel::OBAtom &a, GLfloat &r, GLfloat &g, GLfloat &b );
 
                /**
-                * @return the current molecule
+                * @return the molecule
                 */
                OpenBabel::OBMol* molecule(){
                        return m_molecule;
@@ -138,25 +194,52 @@ class KalziumGLWidget : public QGLWidget
                 */
                void slotSetDetail( int detail );
 
+               /**
+                * Chooses the style of rendering among some presets
+                * @param stylePreset the wanted style preset
+                */
+
+               void slotChooseStylePreset( StylePreset stylePreset );
+
        protected:
                /**
-                * This method initilized OpenGL
+                * This method initializes OpenGL. Automatically called by Qt
                 */
                virtual void initializeGL();
+
+               /**
+                * This method does the painting. Automatically called by Qt
+                */
                virtual void paintGL();
+
+               /**
+                * This method is called by Qt whenever the widget is resized.
+                */
                virtual void resizeGL( int width, int height );
+
                virtual void mousePressEvent( QMouseEvent * event );
                virtual void mouseReleaseEvent( QMouseEvent * event );
                virtual void mouseMoveEvent( QMouseEvent * event );
 
                /**
-                * This method...
+                * This method is called by slotSetMolecule. It prepares the
+                * molecule for rendering, and computes some useful data about
+                * it.
+                */
+               void KalziumGLWidget::prepareMoleculeData();
+
+               /**
+                * This method will shortly be removed, hence no doc.
                 */
                virtual void drawGenericSphere();
+
+               /**
+                * This method will shortly be removed, hence no doc.
+                */
                virtual void drawGenericBond();
                
                /**
-                * This method...
+                * This method draws a sphere
                 * @param x
                 * @param y
                 * @param z
@@ -165,6 +248,7 @@ class KalziumGLWidget : public QGLWidget
                 * @param green
                 * @param blue
                 */
+
                virtual void drawSphere( 
                                GLFLOAT x, 
                                GLFLOAT y, 
@@ -174,49 +258,89 @@ class KalziumGLWidget : public QGLWidget
                                GLfloat green, 
                                GLfloat blue );
 
+               /**
+                * This method draws a bond
+                * @param x
+                * @param y
+                * @param z
+                * @param radius
+                * @param red
+                * @param green
+                * @param blue
+                */
+
                virtual void drawBond( GLFLOAT x1, GLFLOAT y1, GLFLOAT z1,
                        GLFLOAT x2, GLFLOAT y2, GLFLOAT z2,
                        GLfloat red, GLfloat green, GLfloat blue );
 
-               /**
-                * The molecule which is displayed
-                */
-               OpenBabel::OBMol* m_molecule;
-               FLOAT m_molRadius;
-               FLOAT m_molMinBondLength;
-               FLOAT m_molMaxBondLength;
-               FLOAT m_bondsRadius;
+               inline float bondRadius();
+               inline float atomRadius();
+};
 
-               /**
-                * The detail-grade from 0 to 2
-                */
-               int m_detail;
+/**
+ * This class represents a color in OpenGL float red-green-blue format.
+ *
+ * @author Benoit Jacob
+ */
+struct GLColor
+{
+       GLfloat red, green, blue;
 
-               /**
-                * The coefficient set by the user, determining the
-                * radius of atoms.
-                * 0.0 -> minimum radius -> "sticks-style" rendering
-                * 1.0 -> maximum radius for which all bonds are visible
-                * values larger than 1.0 result in atoms so large
-                * that they completely hide some bonds.
-                */
-               float m_atomsRadiusCoeff;
+       /**
+        * Sets this color to be the one used by OpenGL for rendering
+        * when lighting is disabled. It just calls glColor3fv.
+        */
+       inline void apply();
+
+       /**
+        * Applies nice OpenGL materials using this color as the
+        * diffuse color while using different shades for the ambient and
+         * specular colors. This is only useful if GL lighting is enabled.
+        */
+       void applyAsMaterials();
 };
 
-// tests whether two FLOATs are approximately equal
-// this is a very vague approximation, it is enough for our needs here
-bool approx_equal( FLOAT a, FLOAT b );
+/**
+ * This is an abstract base class for a GL vertex array
+ *
+ * @author Benoit Jacob
+ */
+class GLVertexArray
+{
+       protected:
+               struct Vertex {
+                       float nx, ny, nz;
+                       float vx, vy, vz;
+               };
 
-// compute the norm of a vector (dimension 3)
-FLOAT norm3 ( const FLOAT *u );
+               Vertex *m_vertices;
+               unsigned short *m_indices;
+               unsigned int m_nbVertices;
+               unsigned int  m_nbIndices;
+               
+               virtual void generate() = 0;
+       public:
+               GLVertexArray();
+               virtual ~GLVertexArray();
+               void draw();
+};
+
+/**
+ * This class generates and stores a GL vertex array representing a sphere
+ *
+ * @author Benoit Jacob
+ */
+class SphereVertexArray : public GLVertexArray
+{
+       protected:
+               unsigned int m_strips, m_lozangesPerStrip;
+               virtual void generate();
 
-// normalize a vector (dimension 3)
-void normalize3( FLOAT *u );
+       public:
+               SphereVertexArray(unsigned int strips, unsigned int lozangesPerStrip);
+               virtual ~SphereVertexArray();
 
-// given a first vector U, construct two new vectors v and w such that
-// (U, v, w) is a direct orthogonal basis (dimension 3).
-// U is not supposed to be normalized, and v and w aren't normalized.
-void construct_ortho_3D_basis_given_first_vector3(
-       const FLOAT *U, FLOAT *v, FLOAT *w);
+               virtual void regenerate(unsigned int strips, unsigned int lozangesPerStrip);
+};
 
 #endif // KALZIUMGLWIDGET_H