glClearColor( 0.0, 0.0, 0.0, 1.0 );
glShadeModel( GL_SMOOTH );
glEnable( GL_DEPTH_TEST );
+ glDepthFunc( GL_LEQUAL );
glEnable( GL_CULL_FACE );
glDisable( GL_BLEND );
+ //glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glEnable( GL_COLOR_SUM_EXT );
glLightModeli( GL_LIGHT_MODEL_COLOR_CONTROL_EXT,
GL_SEPARATE_SPECULAR_COLOR_EXT );
+
+ setupObjects();
}
void KalziumGLWidget::paintGL()
return;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
+
// set up the camera
glLoadIdentity();
GLTRANSLATE ( 0.0, 0.0, -3.0 * (m_molRadius + atomRadius () ) );
// render the atoms
if( m_atomStyle == ATOM_SPHERE )
{
- glEnable( GL_NORMALIZE );
+ m_sphere.select();
+
glEnable( GL_LIGHTING );
FOR_ATOMS_OF_MOL( a, m_molecule )
drawSphere(
x, y, z,
- atomRadius (),
c);
}
-
- glDisable( GL_NORMALIZE );
}
// prepare for rendering the bonds
case BOND_CYLINDER_GRAY:
case BOND_CYLINDER_BICOLOR:
glEnable( GL_LIGHTING );
+ m_cylinder.select();
break;
case BOND_DISABLED: break;
}
if( radius < min_radius ) radius = min_radius;
glEnable( GL_BLEND );
- glEnable( GL_NORMALIZE );
+
glEnable( GL_LIGHTING );
+ m_sphere.select();
+
drawSphere(
x, y, z,
- radius,
c);
- glDisable( GL_NORMALIZE );
glDisable( GL_BLEND );
}
}
}
-void KalziumGLWidget::drawGenericSphere()
-{
- static int lastDetail = -1;
- if( 0 == m_sphereDisplayList || lastDetail != m_detail)
- {
- if( m_sphereDisplayList )
- glDeleteLists( m_sphereDisplayList, 1 );
- m_sphereDisplayList = glGenLists( 1 );
- if( 0 == m_sphereDisplayList ) return;
- GLUquadricObj *q = gluNewQuadric();
- if( 0 == q) return;
- glNewList( m_sphereDisplayList, GL_COMPILE );
- switch( m_detail)
- {
- case 0:
- gluSphere( q, 1.0, 10, 10 );
- break;
- case 1:
- gluSphere( q, 1.0, 20, 20 );
- break;
- case 2:
- gluSphere( q, 1.0, 40, 40 );
- break;
- }
- glEndList();
- gluDeleteQuadric( q );
- lastDetail = m_detail;
- }
-
- glCallList( m_sphereDisplayList );
-}
-
-void KalziumGLWidget::drawGenericBond()
+void KalziumGLWidget::setupObjects()
{
- int slices;
- static int lastDetail = -1;
- static float lastBondRadiusCoeff = -1.0;
- if( 0 == m_bondDisplayList || lastDetail != m_detail
- || lastBondRadiusCoeff != m_bondRadiusCoeff)
- {
- m_bondDisplayList = glGenLists( 1 );
- if( 0 == m_bondDisplayList ) return;
- switch( m_detail)
- {
- case 0:
- slices = 10;
- break;
- case 1:
- slices = 10;
- break;
- case 2:
- slices = 20;
- break;
- }
- glNewList( m_bondDisplayList, GL_COMPILE );
- glBegin( GL_QUADS );
- 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) * 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) * 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) * 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) * bondRadius(), sin(2*M_PI * (i+1)/slices) * bondRadius(), 1.0 );
- }
- glEnd();
- glEndList();
- lastDetail = m_detail;
- lastBondRadiusCoeff = m_bondRadiusCoeff;
- }
-
- glCallList( m_bondDisplayList );
-
+ m_sphere.setup( 3 * ( m_detail + 1 ), atomRadius() );
+ m_cylinder.setup( 8 * ( m_detail + 1 ), bondRadius() );
}
-void KalziumGLWidget::drawSphere( GLdouble x, GLdouble y, GLdouble z,
- GLdouble radius, GLColor &color )
+void KalziumGLWidget::drawSphere( GLdouble x, GLdouble y, GLdouble z, GLColor &color )
{
color.applyAsMaterials();
glPushMatrix();
glTranslated( x, y, z );
- glScaled( radius, radius, radius);
- drawGenericSphere();
+ m_sphere.draw();
glPopMatrix();
}
//now we can do the actual drawing !
glPushMatrix();
GLMULTMATRIX( matrix );
- drawGenericBond();
+ m_cylinder.draw();
glPopMatrix();
}
m_molecule = molecule;
m_selectedAtom = 0;
prepareMoleculeData();
+ setupObjects();
updateGL();
}
m_bondRadiusCoeff = 0.0;
break;
}
-
+ setupObjects();
updateGL();
}
FLOAT x = (FLOAT) a->GetX();
FLOAT y = (FLOAT) a->GetY();
FLOAT z = (FLOAT) a->GetZ();
- FLOAT rad = SQRT(x*x + y*y + z*z);
+ FLOAT rad = GLSQRT(x*x + y*y + z*z);
if( rad > m_molRadius )
m_molRadius = rad;
}
FLOAT x2 = (FLOAT) static_cast<OBAtom*>(b->GetEnd())->GetX();
FLOAT y2 = (FLOAT) static_cast<OBAtom*>(b->GetEnd())->GetY();
FLOAT z2 = (FLOAT) static_cast<OBAtom*>(b->GetEnd())->GetZ();
- FLOAT len = SQRT ( (x1 - x2) * (x1 - x2)
- + (y1 - y2) * (y1 - y2)
- + (z1 - z2) * (z1 - z2) );
+ FLOAT len = GLSQRT ( (x1 - x2) * (x1 - x2)
+ + (y1 - y2) * (y1 - y2)
+ + (z1 - z2) * (z1 - z2) );
if( len > m_molMaxBondLength )
m_molMaxBondLength = len;
if( len < m_molMinBondLength )
m_detail = detail;
if( m_detail >= 2 ) m_useFog = true;
else m_useFog = false;
+ setupObjects();
updateGL();
}
bool KalziumGLWidget::approx_equal( FLOAT a, FLOAT b, FLOAT precision )
{
- FLOAT abs_a = FABS( a );
- FLOAT abs_b = FABS( b );
+ FLOAT abs_a = GLFABS( a );
+ FLOAT abs_b = GLFABS( b );
FLOAT max_abs;
if( abs_a < abs_b )
max_abs = abs_b;
else
max_abs = abs_a;
- return( FABS( a - b ) <= precision * max_abs );
+ return( GLFABS( a - b ) <= precision * max_abs );
}
FLOAT KalziumGLWidget::norm3( FLOAT *u )
{
- return SQRT( u[0] * u[0] + u[1] * u[1] + u[2] * u[2] );
+ return GLSQRT( u[0] * u[0] + u[1] * u[1] + u[2] * u[2] );
}
void KalziumGLWidget::normalize3( FLOAT *u )
GLVertexArray::GLVertexArray()
{
- m_vertices = 0;
- m_indices = 0;
+ m_vertexBuffer = 0;
+ m_normalBuffer = 0;
+ m_indexBuffer = 0;
+ m_isInitialized = false;
}
GLVertexArray::~GLVertexArray()
{
- if( m_vertices ) delete []m_vertices;
- if( m_indices ) delete []m_indices;
+ if( m_indexBuffer ) delete [] m_indexBuffer;
+ if( m_vertexBuffer ) delete [] m_vertexBuffer;
+ if( m_normalBuffer ) delete [] m_normalBuffer;
+}
+
+void GLVertexArray::select()
+{
+ if( ! m_isInitialized ) return;
+ glEnableClientState( GL_VERTEX_ARRAY );
+ glEnableClientState( GL_NORMAL_ARRAY );
+ glVertexPointer( 3, GL_FLOAT, 0, m_vertexBuffer );
+ glNormalPointer( GL_FLOAT, 0, m_normalBuffer );
}
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 );
+ if( m_isInitialized )
+ glDrawElements( m_mode, m_indexCount,
+ GL_UNSIGNED_SHORT, m_indexBuffer );
+}
+
+bool GLVertexArray::reallocateBuffers()
+{
+ if( m_vertexCount > 65536 ) return false;
+
+ m_isInitialized = false;
+
+ if( m_indexBuffer )
+ {
+ delete [] m_indexBuffer;
+ m_indexBuffer = 0;
+ }
+ if( m_vertexBuffer )
+ {
+ delete [] m_vertexBuffer;
+ m_vertexBuffer = 0;
+ }
+ if( m_normalBuffer )
+ {
+ delete [] m_normalBuffer;
+ m_normalBuffer = 0;
+ }
+
+ m_vertexBuffer = new GLVector3<GLfloat>[m_vertexCount];
+ if( ! m_vertexBuffer ) return false;
+ m_normalBuffer = new GLVector3<GLfloat>[m_vertexCount];
+ if( ! m_normalBuffer ) return false;
+ m_indexBuffer = new unsigned short[m_indexCount];
+ if( ! m_indexBuffer ) return false;
+
+ return true;
+}
+
+GLSphere::GLSphere()
+ : GLVertexArray()
+{
+ m_mode = GL_TRIANGLE_STRIP;
+ m_detail = 0;
+ m_radius = -1.0;
+}
+
+unsigned short GLSphere::indexOfVertex( int strip, int column, int row)
+{
+ return ( row + ( 3 * m_detail + 1 ) * ( column + m_detail * strip ) );
+}
+
+void GLSphere::computeVertex( int strip, int column, int row)
+{
+ strip %= 5;
+ int next_strip = (strip + 1) % 5;
+
+ GLVector3<GLfloat> *vertex =
+ &m_vertexBuffer[ indexOfVertex( strip, column, row ) ];
+
+ GLVector3<GLfloat> *normal =
+ &m_normalBuffer[ indexOfVertex( strip, column, row ) ];
+
+ const GLfloat phi = ( 1 + sqrt(5) ) / 2;
+
+ const GLVector3<GLfloat> northPole( 0, 1, phi );
+ const GLVector3<GLfloat> northVertex[5] = {
+ GLVector3<GLfloat>( 0, -1, phi ),
+ GLVector3<GLfloat>( phi, 0, 1 ),
+ GLVector3<GLfloat>( 1, phi, 0 ),
+ GLVector3<GLfloat>( -1, phi, 0 ),
+ GLVector3<GLfloat>( -phi, 0, 1 ) };
+ const GLVector3<GLfloat> southVertex[5] = {
+ GLVector3<GLfloat>( -1, -phi, 0 ),
+ GLVector3<GLfloat>( 1, -phi, 0 ),
+ GLVector3<GLfloat>( phi, 0, -1 ),
+ GLVector3<GLfloat>( 0, 1, -phi ),
+ GLVector3<GLfloat>( -phi, 0, -1 )
+ };
+ const GLVector3<GLfloat> southPole( 0, -1, -phi );
+
+ const GLVector3<GLfloat> *v0, *v1, *v2;
+ int c1, c2;
+
+ if( row >= 2 * m_detail && column == 0 )
+ {
+ strip--;
+ if( strip < 0 ) strip += 5;
+ next_strip--;
+ if( next_strip < 0 ) next_strip += 5;
+ column = m_detail;
+ }
+
+ if( row <= m_detail )
+ {
+ v0 = &northVertex[strip];
+ v1 = &northPole;
+ v2 = &northVertex[next_strip];
+ c1 = m_detail - row;
+ c2 = column;
+ }
+ else if( row >= 2 * m_detail )
+ {
+ v0 = &southVertex[next_strip];
+ v1 = &southPole;
+ v2 = &southVertex[strip];
+ c1 = row - 2 * m_detail;
+ c2 = m_detail - column;
+ }
+ else if( row <= m_detail + column )
+ {
+ v0 = &northVertex[next_strip];
+ v1 = &southVertex[next_strip];
+ v2 = &northVertex[strip];
+ c1 = row - m_detail;
+ c2 = m_detail - column;
+ }
+ else
+ {
+ v0 = &southVertex[strip];
+ v1 = &southVertex[next_strip];
+ v2 = &northVertex[strip];
+ c1 = column;
+ c2 = 2 * m_detail - row;
+ }
+
+ GLfloat u1 = GLfloat(c1) / m_detail;
+ GLfloat u2 = GLfloat(c2) / m_detail;
+
+ vertex->x = v0->x + u1 * (v1->x - v0->x) + u2 * (v2->x - v0->x);
+ vertex->y = v0->y + u1 * (v1->y - v0->y) + u2 * (v2->y - v0->y);
+ vertex->z = v0->z + u1 * (v1->z - v0->z) + u2 * (v2->z - v0->z);
+
+ vertex->normalize();
+
+ *normal = *vertex;
+
+ vertex->x *= m_radius;
+ vertex->y *= m_radius;
+ vertex->z *= m_radius;
+}
+
+
+void GLSphere::initialize()
+{
+ if( m_detail < 1 ) return;
+ m_vertexCount = ( 3 * m_detail + 1 ) * ( 5 * m_detail + 1 );
+ m_indexCount = (2 * ( 2 * m_detail + 1 ) + 2 ) * 5 * m_detail;
+
+ if( ! reallocateBuffers() ) return;
+
+ for( int strip = 0; strip < 5; strip++ )
+ for( int column = 1; column < m_detail; column++ )
+ for( int row = column; row <= 2 * m_detail + column; row++ )
+ computeVertex( strip, column, row );
+
+ for( int strip = 1; strip < 5; strip++ )
+ for( int row = 0; row <= 3 * m_detail; row++ )
+ computeVertex( strip, 0, row );
+
+ for( int row = 0; row <= 2 * m_detail; row++ )
+ computeVertex( 0, 0, row );
+
+ for( int row = m_detail; row <= 3 * m_detail; row++ )
+ computeVertex( 4, m_detail, row );
+
+ unsigned int i = 0;
+ for( int strip = 0; strip < 5; strip++ )
+ for( int column = 0; column < m_detail; column++ )
+ {
+ int row = column;
+ m_indexBuffer[i++] = indexOfVertex( strip, column, row );
+ for( ; row <= 2 * m_detail + column; row++ )
+ {
+ m_indexBuffer[i++] =
+ indexOfVertex( strip, column, row );
+ m_indexBuffer[i++] =
+ indexOfVertex( strip, column + 1, row + 1 );
+ }
+ m_indexBuffer[i++] = indexOfVertex( strip, column + 1,
+ 2 * m_detail + column + 1);
+ }
+
+ m_isInitialized = true;
}
-SphereVertexArray::SphereVertexArray( unsigned int strips,
- unsigned int lozangesPerStrip ) : GLVertexArray()
+void GLSphere::setup( int detail, GLfloat radius )
{
- regenerate( strips, lozangesPerStrip );
+ if( detail == m_detail && radius == m_radius ) return;
+ m_detail = detail;
+ m_radius = radius;
+ initialize();
}
-SphereVertexArray::~SphereVertexArray()
+GLCylinder::GLCylinder()
+ : GLVertexArray()
{
+ m_mode = GL_QUAD_STRIP;
+ m_faces = 0;
+ m_radius = -1.0;
}
-void SphereVertexArray::regenerate( unsigned int strips,
- unsigned int lozangesPerStrip )
+void GLCylinder::setup( int faces, GLfloat radius )
{
- m_strips = strips;
- m_lozangesPerStrip = lozangesPerStrip;
- if( m_vertices ) delete []m_vertices;
- if( m_indices ) delete []m_indices;
- generate();
+ if( faces == m_faces && radius == m_radius ) return;
+ m_faces = faces;
+ m_radius = radius;
+ initialize();
}
-void SphereVertexArray::generate()
+void GLCylinder::initialize()
{
+ if( m_faces < 3 ) return;
+
+ m_vertexCount = 2 * m_faces + 2; // we will use a redundant vertex array
+ m_indexCount = 1; // we won't use it.
+
+ if( ! reallocateBuffers() ) return;
+
+ for( int i = 0; i <= m_faces; i++)
+ {
+ float angle = 2 * M_PI * i / m_faces;
+ float x = cosf( angle );
+ float y = sinf( angle );
+
+ m_normalBuffer[ 2 * i ].x = x;
+ m_normalBuffer[ 2 * i ].y = y;
+ m_normalBuffer[ 2 * i ].z = 0.0;
+
+ m_vertexBuffer[ 2 * i ].x = x * m_radius ;
+ m_vertexBuffer[ 2 * i ].y = y * m_radius;
+ m_vertexBuffer[ 2 * i ].z = 1.0;
+ m_normalBuffer[ 2 * i + 1].x = x;
+ m_normalBuffer[ 2 * i + 1].y = y;
+ m_normalBuffer[ 2 * i + 1].z = 0.0;
+
+ m_vertexBuffer[ 2 * i + 1].x = x * m_radius;
+ m_vertexBuffer[ 2 * i + 1].y = y * m_radius ;
+ m_vertexBuffer[ 2 * i + 1].z = 0.0;
+ }
+
+ m_isInitialized = true;
+}
+
+void GLCylinder::draw()
+{
+ if ( m_isInitialized ) glDrawArrays( m_mode, 0, m_vertexCount );
}
#include "kalziumglwidget.moc"
#ifdef USE_DOUBLE_PRECISION
#define FLOAT double
#define GLFLOAT GLdouble
-#define GLTRANSLATE glTranslated
-#define GLMULTMATRIX glMultMatrixd
-#define SQRT sqrt
-#define COS cos
-#define SIN sin
-#define FABS fabs
#else
#define FLOAT float
#define GLFLOAT GLfloat
-#define GLTRANSLATE glTranslatef
-#define GLMULTMATRIX glMultMatrixf
-#define SQRT sqrtf
-#define COS cosf
-#define SIN sinf
-#define FABS fabsf
#endif
-struct GLColor;
+inline float GLSQRT( float x ) { return sqrtf( x ); }
+inline double GLSQRT( double x ) { return sqrt( x ); }
+inline float GLSIN( float x ) { return sinf( x ); }
+inline double GLSIN( double x ) { return sin( x ); }
+inline float GLCOS( float x ) { return cosf( x ); }
+inline double GLCOS( double x ) { return cos( x ); }
+inline float GLFABS( float x ) { return fabsf( x ); }
+inline double GLFABS( double x ) { return fabs( x ); }
+inline void GLMULTMATRIX( const GLfloat *m ) { glMultMatrixf(m); }
+inline void GLMULTMATRIX( const GLdouble *m ) { glMultMatrixd(m); }
+inline void GLTRANSLATE( GLfloat x, GLfloat y, GLfloat z ) \
+ { glTranslatef( x, y, z ); }
+inline void GLTRANSLATE( GLdouble x, GLdouble y, GLdouble z ) \
+ { glTranslated( x, y, z ); }
+
+/**
+ * This class represents a color in OpenGL float red-green-blue format.
+ *
+ * @author Benoit Jacob
+ */
+struct GLColor
+{
+ GLfloat m_red, m_green, m_blue, m_alpha;
+
+ GLColor();
+ GLColor( GLfloat red, GLfloat green, GLfloat blue,
+ GLfloat alpha = 1.0 );
+
+ GLColor& operator=( const GLColor& other );
+
+ /**
+ * Sets this color to be the one used by OpenGL for rendering
+ * when lighting is disabled. It just calls glColor4fv.
+ */
+ 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();
+};
+
+
+
+template<class T> struct GLVector3
+{
+ T x, y, z;
+ GLVector3() {}
+ GLVector3( T _x, T _y, T _z)
+ { x = _x; y = _y; z = _z; }
+ inline T norm() { return GLSQRT( x * x + y * y + z * z ); }
+ void normalize()
+ {
+ T n = norm();
+ if( n == 0.0 ) return;
+ x /= n;
+ y /= n;
+ z /= n;
+ }
+ GLVector3<T>& operator= ( const GLVector3<T>& other )
+ {
+ x = other.x;
+ y = other.y;
+ z = other.z;
+ return *this;
+ }
+};
+
+/**
+ * This is an abstract base class for an OpenGL vertex array.
+ *
+ * @author Benoit Jacob
+ */
+class GLVertexArray
+{
+ protected:
+ GLenum m_mode;
+ GLVector3<GLfloat> *m_vertexBuffer;
+ GLVector3<GLfloat> *m_normalBuffer;
+ unsigned int m_vertexCount;
+ unsigned short *m_indexBuffer;
+ unsigned int m_indexCount;
+
+ bool m_isInitialized;
+
+ virtual void initialize() = 0;
+ virtual bool reallocateBuffers();
+
+ public:
+ GLVertexArray();
+ virtual ~GLVertexArray();
+ virtual void select();
+ virtual inline void draw();
+};
+
+/**
+ * This class represents and draws a sphere
+ *
+ * @author Benoit Jacob
+ */
+class GLSphere : public GLVertexArray
+{
+ private:
+ inline unsigned short indexOfVertex(
+ int strip, int column, int row);
+ void computeVertex( int strip, int column, int row );
+
+ protected:
+ int m_detail;
+ GLfloat m_radius;
+
+ virtual void initialize();
+
+ public:
+ GLSphere();
+ virtual ~GLSphere() {}
+ virtual void setup( int detail, GLfloat radius );
+};
+
+/**
+ * This class represents and draws a cylinder
+ *
+ * @author Benoit Jacob
+ */
+class GLCylinder : public GLVertexArray
+{
+ protected:
+ int m_faces;
+ GLfloat m_radius;
+
+ virtual void initialize();
+
+ public:
+ GLCylinder();
+ virtual ~GLCylinder() {}
+ virtual void setup( int detail, GLfloat radius );
+ virtual inline void draw();
+};
/**
* This class displays the 3D-view of a molecule
protected:
GLuint m_sphereDisplayList;
GLuint m_bondDisplayList;
+ GLSphere m_sphere;
+ GLCylinder m_cylinder;
/**
* equals true if the user is currently dragging (rotating)
* Chooses the style of rendering among some presets
* @param stylePreset the wanted style preset
*/
- void ChooseStylePreset( StylePreset stylePreset );
+ virtual void ChooseStylePreset( StylePreset stylePreset );
public slots:
/**
* it.
*/
void 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 draws a sphere
* @param x
* @param y
* @param z
- * @param radius
* @param red
* @param green
* @param blue
GLFLOAT x,
GLFLOAT y,
GLFLOAT z,
- GLFLOAT radius,
GLColor &color );
/**
GLColor& getAtomColor( OpenBabel::OBAtom* atom );
+ virtual void setupObjects();
};
-/**
- * This class represents a color in OpenGL float red-green-blue format.
- *
- * @author Benoit Jacob
- */
-struct GLColor
-{
- GLfloat m_red, m_green, m_blue, m_alpha;
-
- GLColor();
- GLColor( GLfloat red, GLfloat green, GLfloat blue,
- GLfloat alpha = 1.0 );
-
- GLColor& operator=( const GLColor& other );
-
- /**
- * Sets this color to be the one used by OpenGL for rendering
- * when lighting is disabled. It just calls glColor4fv.
- */
- 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();
-};
-
-/**
- * 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);
-};
#endif // KALZIUMGLWIDGET_H