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 )
{
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 );
}
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 );
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 );
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();
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 )
{
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;
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 );
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();
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 );
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;
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
// 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 not colinear 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;
}
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"
#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
*
* 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
*/
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;
*/
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
* @param green
* @param blue
*/
+
virtual void drawSphere(
GLFLOAT x,
GLFLOAT y,
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