#include <QTime>
#endif
-template<class T> bool GLVector3<T>::approx_equal(
- FLOAT a, FLOAT b, FLOAT precision )
-{
- FLOAT abs_a = GLFABS( a );
- FLOAT abs_b = GLFABS( b );
+using namespace KalziumGLHelpers;
- FLOAT max_abs;
- if( abs_a < abs_b )
- max_abs = abs_b;
- else
- max_abs = abs_a;
- return( GLFABS( a - b ) <= precision * max_abs );
-}
-
-template<class T> void GLVector3<T>::construct_ortho_basis_given_first_vector(
- GLVector3<T> &v, GLVector3<T> &w )
+Color::Color()
{
- if( norm() == 0 ) return;
-
- // let us first make a normalized copy of *this
- GLVector3<T> u = *this;
- u.normalize();
-
- // first we want to set v to be non-colinear to u
-
- v = u;
-
- if( ! approx_equal( v.x, v.y, 0.1 ) )
- {
- FLOAT tmp = v.x;
- v.x = v.y;
- v.y = tmp;
- }
- else if( ! approx_equal( v.y, v.z, 0.1 ) )
- {
- FLOAT tmp = v.z;
- v.z = v.y;
- v.y = tmp;
- }
- else // the 3 coords of v are approximately equal
- { // which implies that v is not colinear to (0,0,1)
- v = GLVector3<T>( 0, 0, 1 );
- }
-
- // now, v is not colinear to u. We compute its dot product with u
- FLOAT u_dot_v = u.x * v.x + u.y * v.y + u.z * v.z;
-
- // now we change v so that it becomes orthogonal to u
- v.x -= u.x * u_dot_v;
- v.y -= u.y * u_dot_v;
- v.z -= u.z * u_dot_v;
-
- // now that u and v are orthogonal, w can be constructed as
- // their crossed product
- w.x = u.y * v.z - u.z * v.y;
- w.y = u.z * v.x - u.x * v.z;
- w.z = u.x * v.y - u.y * v.x;
}
-GLColor::GLColor()
-{
-}
-
-GLColor::GLColor( GLfloat red, GLfloat green, GLfloat blue,
+Color::Color( GLfloat red, GLfloat green, GLfloat blue,
GLfloat alpha )
{
m_red = red;
m_alpha = alpha;
}
-GLColor& GLColor::operator=( const GLColor& other )
+Color& Color::operator=( const Color& other )
{
m_red = other.m_red;
m_green = other.m_green;
return *this;
}
-void GLColor::apply()
-{
- glColor4fv( reinterpret_cast<GLfloat *>( this ) );
-}
-
-void GLColor::applyAsMaterials()
+void Color::applyAsMaterials()
{
GLfloat ambientColor [] = { m_red / 2, m_green / 2, m_blue / 2,
m_alpha };
glMaterialf(GL_FRONT, GL_SHININESS, 50.0);
}
-GLVertexArray::GLVertexArray()
+VertexArray::VertexArray()
{
- allocateId();
m_mode = GL_TRIANGLE_STRIP;
m_vertexBuffer = 0;
m_normalBuffer = 0;
m_isInitialized = false;
}
-GLVertexArray::~GLVertexArray()
+VertexArray::~VertexArray()
{
if( m_indexBuffer ) delete [] m_indexBuffer;
if( m_vertexBuffer ) delete [] m_vertexBuffer;
if( m_normalBuffer ) delete [] m_normalBuffer;
}
-void GLVertexArray::allocateId()
-{
- static int counter = 0;
- m_id = counter++;
-}
-
-
-void GLVertexArray::select()
+void VertexArray::select()
{
- static int selected_id = -1;
-
- if( selected_id == m_id ) return;
-
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_NORMAL_ARRAY );
glVertexPointer( 3, GL_FLOAT, 0, m_vertexBuffer );
glNormalPointer( GL_FLOAT, 0, m_normalBuffer );
- selected_id = m_id;
-}
-
-void GLVertexArray::draw()
-{
- if( ! m_isInitialized ) return;
- select();
- glDrawElements( m_mode, m_indexCount,
- GL_UNSIGNED_SHORT, m_indexBuffer );
}
-bool GLVertexArray::allocateBuffers()
+bool VertexArray::allocateBuffers()
{
if( m_vertexCount > 65536 ) return false;
m_normalBuffer = 0;
}
- m_vertexBuffer = new GLVector3<GLfloat>[m_vertexCount];
+ m_vertexBuffer = new Vector3<GLfloat>[m_vertexCount];
if( ! m_vertexBuffer ) return false;
- m_normalBuffer = new GLVector3<GLfloat>[m_vertexCount];
+ m_normalBuffer = new Vector3<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()
+Sphere::Sphere()
+ : VertexArray()
{
m_detail = 0;
m_radius = -1.0;
}
-unsigned short GLSphere::indexOfVertex( int strip, int column, int row)
+unsigned short Sphere::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)
+void Sphere::computeVertex( int strip, int column, int row)
{
strip %= 5;
int next_strip = (strip + 1) % 5;
- GLVector3<GLfloat> *vertex =
+ Vector3<GLfloat> *vertex =
&m_vertexBuffer[ indexOfVertex( strip, column, row ) ];
- GLVector3<GLfloat> *normal =
+ Vector3<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 Vector3<GLfloat> northPole( 0, 1, phi );
+ const Vector3<GLfloat> northVertex[5] = {
+ Vector3<GLfloat>( 0, -1, phi ),
+ Vector3<GLfloat>( phi, 0, 1 ),
+ Vector3<GLfloat>( 1, phi, 0 ),
+ Vector3<GLfloat>( -1, phi, 0 ),
+ Vector3<GLfloat>( -phi, 0, 1 ) };
+ const Vector3<GLfloat> southVertex[5] = {
+ Vector3<GLfloat>( -1, -phi, 0 ),
+ Vector3<GLfloat>( 1, -phi, 0 ),
+ Vector3<GLfloat>( phi, 0, -1 ),
+ Vector3<GLfloat>( 0, 1, -phi ),
+ Vector3<GLfloat>( -phi, 0, -1 )
};
- const GLVector3<GLfloat> southPole( 0, -1, -phi );
+ const Vector3<GLfloat> southPole( 0, -1, -phi );
- const GLVector3<GLfloat> *v0, *v1, *v2;
+ const Vector3<GLfloat> *v0, *v1, *v2;
int c1, c2;
if( row >= 2 * m_detail && column == 0 )
}
-void GLSphere::initialize()
+void Sphere::initialize()
{
if( m_detail < 1 ) return;
m_vertexCount = ( 3 * m_detail + 1 ) * ( 5 * m_detail + 1 );
m_isInitialized = true;
}
-void GLSphere::setup( int detail, GLfloat radius )
+void Sphere::setup( int detail, GLfloat radius )
{
if( detail == m_detail && radius == m_radius ) return;
m_detail = detail;
m_radius = radius;
- allocateId();
initialize();
}
-void GLSphere::drawScaled( GLfloat radius )
+void Sphere::drawScaled( GLfloat radius )
{
const GLfloat precision = 0.001;
- if( GLVector3<GLfloat>::approx_equal( radius, m_radius, precision ) )
+ if( approx_equal( radius, m_radius, precision ) )
{
draw();
return;
glDisable( GL_NORMALIZE );
}
-GLCylinder::GLCylinder()
- : GLVertexArray()
+Cylinder::Cylinder()
+ : VertexArray()
{
m_mode = GL_QUAD_STRIP;
m_faces = 0;
m_radius = -1.0;
}
-void GLCylinder::setup( int faces, GLfloat radius )
+void Cylinder::setup( int faces, GLfloat radius )
{
if( faces == m_faces && radius == m_radius ) return;
m_faces = faces;
m_radius = radius;
- allocateId();
initialize();
}
-void GLCylinder::initialize()
+void Cylinder::initialize()
{
if( m_faces < 3 ) return;
m_isInitialized = true;
}
-
-void GLCylinder::draw()
-{
- if ( ! m_isInitialized ) return;
- select();
- glDrawArrays( m_mode, 0, m_vertexCount );
-}
#include <math.h>
#include <QGLWidget>
-#define USE_DOUBLE_PRECISION
-#define USE_DISPLAY_LIST
-#define USE_FPS_COUNTER
-
-#ifdef USE_DOUBLE_PRECISION
-#define FLOAT double
-#define GLFLOAT GLdouble
-#else
-#define FLOAT float
-#define GLFLOAT GLfloat
-#endif
-
-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
+/** USE_DOUBLE_PRECISION: if defined, use doubles instead of floats for
+ * handling the model's geometric data. This does not seem to impact
+ * significantly the performance. The vertex arrays are unaffected: they
+ * always use floats.
*/
-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.
- */
- //TODO 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();
-};
+#define USE_DOUBLE_PRECISION
-/**
- * This template class represents a vector in 3-space. It is meant to be
- * used with T = a floating-point type.
- *
- * @author Benoit Jacob
+/** USE_FPS_COUNTER: if defined, the GL Widgets will show a frames-per-second
+ * counter. *Use only for testing*: this makes the GL Widget constantly
+ * redraw, which under normal circumstances is a waste of CPU power.
*/
+#define USE_FPS_COUNTER
-template<class T> class GLVector3
+namespace KalziumGLHelpers
{
- public:
- T x, y, z;
- GLVector3() {}
- GLVector3( T _x, T _y, T _z)
- { x = _x; y = _y; z = _z; }
-
- /**
- * 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 ) )
- */
- static bool approx_equal( FLOAT a, FLOAT b, FLOAT precision );
-
- GLVector3<T>& operator= ( const GLVector3<T>& other )
- {
- x = other.x;
- y = other.y;
- z = other.z;
- return *this;
- }
-
- /**
- * returns the norm of the vector, that is, its length
- */
- inline T norm() { return GLSQRT( x * x + y * y + z * z ); }
+ #ifdef USE_DOUBLE_PRECISION
+ typedef double FLOAT;
+ typedef GLdouble GLFLOAT;
+ #else
+ typedef float FLOAT;
+ typedef GLfloat GLFLOAT;
+ #endif
+ inline float SQRT( float x ) { return sqrtf( x ); }
+ inline double SQRT( double x ) { return sqrt( x ); }
+ inline float SIN( float x ) { return sinf( x ); }
+ inline double SIN( double x ) { return sin( x ); }
+ inline float COS( float x ) { return cosf( x ); }
+ inline double COS( double x ) { return cos( x ); }
+ inline float FABS( float x ) { return fabsf( x ); }
+ inline double FABS( 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 Color
+ {
+ GLfloat m_red, m_green, m_blue, m_alpha;
+
+ Color();
+ Color( GLfloat red, GLfloat green, GLfloat blue,
+ GLfloat alpha = 1.0 );
+
+ Color& operator=( const Color& other );
+
/**
- * normalizes the vector, that is, scales it so that its norm
- * becomes 1.
- */
- void normalize()
+ * Sets this color to be the one used by OpenGL for rendering
+ * when lighting is disabled.
+ */
+ inline void apply()
{
- T n = norm();
- if( n == 0.0 ) return;
- x /= n;
- y /= n;
- z /= n;
+ glColor4fv( reinterpret_cast<GLfloat *>( this ) );
}
-
+
/**
- * Constructs two vectors v and w
- * such that (*this, v, w) is a direct orthogonal basis.
- * v and w are not getting normalized.
- */
- void construct_ortho_basis_given_first_vector(
- GLVector3<T> & v, GLVector3<T> & w );
-};
-
-/**
- * This is an abstract base class for an OpenGL vertex array.
- *
- * @author Benoit Jacob
- */
-class GLVertexArray
-{
- private:
- int m_id;
-
- 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 allocateBuffers();
- virtual void allocateId();
- virtual void select();
-
- public:
- GLVertexArray();
- virtual ~GLVertexArray();
- //inline?
- virtual 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;
+ * 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 lighting is enabled.
+ */
+ void applyAsMaterials();
+ };
+
+ /**
+ * Tests whether two Ts are approximately equal. Here T is assumed to be
+ * a floating-point type. Recall that operator== between floating-point
+ * types is broken.
+ * returns true if abs( a - b ) <= c * precision
+ * where c = max( abs( a ), abs( b ) )
+ */
+ template<class T> static bool approx_equal( T a, T b, T precision )
+ {
+ T abs_a = FABS( a );
+ T abs_b = FABS( b );
+
+ T max_abs;
+ if( abs_a <= abs_b )
+ max_abs = abs_b;
+ else
+ max_abs = abs_a;
+ return( FABS( a - b ) <= precision * max_abs );
+ }
- virtual void initialize();
+ /**
+ * This template class represents a vector in 3-space. It is meant to be
+ * used with T = a floating-point type.
+ *
+ * @author Benoit Jacob
+ */
+
+ template<class T> class Vector3
+ {
+ public:
+ T x, y, z;
+ Vector3() {}
+ Vector3( T _x, T _y, T _z)
+ { x = _x; y = _y; z = _z; }
+
+ Vector3<T>& operator= ( const Vector3<T>& other )
+ {
+ x = other.x;
+ y = other.y;
+ z = other.z;
+ return *this;
+ }
+
+ /**
+ * returns the norm of the vector, that is, its length
+ */
+ inline T norm() const { return SQRT( x * x + y * y + z * z ); }
+
+ /**
+ * normalizes the vector, that is, scales it so that its norm
+ * becomes 1.
+ */
+ void normalize()
+ {
+ T n = norm();
+ if( n == 0.0 ) return;
+ x /= n;
+ y /= n;
+ z /= n;
+ }
+ };
- public:
- GLSphere();
- virtual ~GLSphere() {}
- virtual void setup( int detail, GLfloat radius );
- virtual void drawScaled( GLfloat radius );
-};
+ /**
+ * Given a 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.
+ * v and w are not getting normalized.
+ */
+ template<class T> void construct_ortho_basis_given_first_vector(
+ const Vector3<T> &U, Vector3<T> & v, Vector3<T> & w )
+ {
+ if( U.norm() == 0 ) return;
-/**
- * This class represents and draws a cylinder
- *
- * @author Benoit Jacob
- */
-class GLCylinder : public GLVertexArray
-{
- protected:
- int m_faces;
- GLfloat m_radius;
+ // let us first make a normalized copy of U
+ Vector3<T> u = U;
+ u.normalize();
+
+ // first we want to set v to be non-colinear to u
+ v = u;
+
+ if( ! approx_equal( v.x, v.y, 0.1 ) )
+ {
+ T tmp = v.x;
+ v.x = v.y;
+ v.y = tmp;
+ }
+ else if( ! approx_equal( v.y, v.z, 0.1 ) )
+ {
+ T tmp = v.z;
+ v.z = v.y;
+ v.y = tmp;
+ }
+ else // the 3 coords of v are approximately equal
+ { // which implies that v is not colinear to (0,0,1)
+ v = Vector3<T>( 0, 0, 1 );
+ }
+
+ // now, v is not colinear to u. We compute its dot product with u
+ T u_dot_v = u.x * v.x + u.y * v.y + u.z * v.z;
+
+ // now we change v so that it becomes orthogonal to u
+ v.x -= u.x * u_dot_v;
+ v.y -= u.y * u_dot_v;
+ v.z -= u.z * u_dot_v;
+
+ // now that u and v are orthogonal, w can be constructed as
+ // their crossed product
+ w.x = u.y * v.z - u.z * v.y;
+ w.y = u.z * v.x - u.x * v.z;
+ w.z = u.x * v.y - u.y * v.x;
+ }
- virtual void initialize();
+ /**
+ * This is an abstract base class for an OpenGL vertex array.
+ *
+ * @author Benoit Jacob
+ */
+ class VertexArray
+ {
+
+ protected:
+ GLenum m_mode;
+ Vector3<GLfloat> *m_vertexBuffer;
+ Vector3<GLfloat> *m_normalBuffer;
+ unsigned int m_vertexCount;
+ unsigned short *m_indexBuffer;
+ unsigned int m_indexCount;
+
+ bool m_isInitialized;
+
+ virtual void initialize() = 0;
+ virtual bool allocateBuffers();
+
+ public:
+ VertexArray();
+ virtual ~VertexArray();
+ virtual void select();
+ virtual inline void draw()
+ {
+ glDrawElements( m_mode, m_indexCount,
+ GL_UNSIGNED_SHORT, m_indexBuffer );
+ }
+ };
+
+ /**
+ * This class represents and draws a sphere
+ *
+ * @author Benoit Jacob
+ */
+ class Sphere : public VertexArray
+ {
+ 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:
+ Sphere();
+ virtual ~Sphere() {}
+ virtual void setup( int detail, GLfloat radius );
+ virtual void drawScaled( GLfloat radius );
+ };
+
+ /**
+ * This class represents and draws a cylinder
+ *
+ * @author Benoit Jacob
+ */
+ class Cylinder : public VertexArray
+ {
+ protected:
+ int m_faces;
+ GLfloat m_radius;
+
+ virtual void initialize();
+
+ public:
+ Cylinder();
+ virtual ~Cylinder() {}
+ virtual void setup( int detail, GLfloat radius );
+ virtual inline void draw()
+ {
+ glDrawArrays( m_mode, 0, m_vertexCount );
+ }
+ };
- public:
- GLCylinder();
- virtual ~GLCylinder() {}
- virtual void setup( int detail, GLfloat radius );
- virtual inline void draw();
-};
+} // namespace KalziumGL
#endif // KALZIUMGLHELPERCLASSES_H
#include <math.h>
#include <kdebug.h>
+#include <klocale.h>
#include <QMouseEvent>
#include <QListWidget>
KalziumGLWidget::KalziumGLWidget( QWidget * parent )
: QGLWidget( parent )
{
- m_displayList = 0;
m_isDragging = false;
m_molecule = 0;
m_detail = 0;
{
}
-void KalziumGLWidget::deleteDisplayList()
-{
-#ifdef USE_DISPLAY_LIST
- if( m_displayList) glDeleteLists( m_displayList, 1 );
- m_displayList = 0;
-#endif
-}
-
void KalziumGLWidget::initializeGL()
{
glClearColor( 0.0, 0.0, 0.0, 1.0 );
void KalziumGLWidget::paintGL()
{
+ if( ! m_molecule )
+ {
+ return;
+ }
+
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 40.0, float( width() ) / height(), m_molRadius, 5.0 * (m_molRadius + atomRadius ()));
glMatrixMode( GL_MODELVIEW );
- if( !m_molecule )
- return;
-
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// set up the camera
}
else glDisable( GL_FOG );
-#ifdef USE_DISPLAY_LIST
- if ( ! m_displayList )
- {
- m_displayList = glGenLists( 1 );
- glNewList( m_displayList, GL_COMPILE );
-#endif
-
- // render the atoms
+ // prepare for rendering the spheres
if( m_atomStyle == ATOM_SPHERE )
{
+ m_sphere.select();
glEnable( GL_LIGHTING );
+ }
+ else glDisable( GL_LIGHTING );
- FOR_ATOMS_OF_MOL( a, m_molecule )
+ if( m_atomStyle != ATOM_DISABLED )
+ {
+ // render the atoms
+ if( m_atomStyle == ATOM_SPHERE )
{
- GLFLOAT x = (GLFLOAT) a->GetX();
- GLFLOAT y = (GLFLOAT) a->GetY();
- GLFLOAT z = (GLFLOAT) a->GetZ();
-
- GLColor c = getAtomColor( &*a );
-
- drawSphere(
- x, y, z,
- atomRadius(),
- c);
+ FOR_ATOMS_OF_MOL( a, m_molecule )
+ {
+ GLFLOAT x = (GLFLOAT) a->GetX();
+ GLFLOAT y = (GLFLOAT) a->GetY();
+ GLFLOAT z = (GLFLOAT) a->GetZ();
+
+ Color c = getAtomColor( &*a );
+
+ drawSphere(
+ x, y, z,
+ atomRadius(),
+ c);
+ }
}
}
case BOND_CYLINDER_GRAY:
case BOND_CYLINDER_BICOLOR:
+ m_cylinder.select();
glEnable( GL_LIGHTING );
break;
case BOND_DISABLED: break;
}
- // render the bonds
- if( BOND_DISABLED != m_bondStyle) FOR_BONDS_OF_MOL( bond, m_molecule )
+ if( m_bondStyle != BOND_DISABLED )
{
- GLFLOAT x1 = (GLFLOAT)
- static_cast<OBAtom*>(bond->GetBgn())->GetX();
- GLFLOAT y1 = (GLFLOAT)
- static_cast<OBAtom*>(bond->GetBgn())->GetY();
- GLFLOAT z1 = (GLFLOAT)
- static_cast<OBAtom*>(bond->GetBgn())->GetZ();
- GLFLOAT x2 = (GLFLOAT)
- static_cast<OBAtom*>(bond->GetEnd())->GetX();
- GLFLOAT y2 = (GLFLOAT)
- static_cast<OBAtom*>(bond->GetEnd())->GetY();
- GLFLOAT z2 = (GLFLOAT)
- static_cast<OBAtom*>(bond->GetEnd())->GetZ();
-
- GLFLOAT x3 = (x1 + x2) / 2;
- GLFLOAT y3 = (y1 + y2) / 2;
- GLFLOAT z3 = (z1 + z2) / 2;
-
- GLColor c1, c2;
- c1 = getAtomColor( static_cast<OBAtom*>(bond->GetBgn()) );
- c2 = getAtomColor( static_cast<OBAtom*>(bond->GetEnd()) );
- GLColor gray( 0.5, 0.5, 0.5 );
-
- switch( m_bondStyle )
+ // render the bonds
+ FOR_BONDS_OF_MOL( bond, m_molecule )
{
- case BOND_LINE:
- glBegin( GL_LINES );
- c1.apply();
- glVertex3f( x1, y1, z1 );
- glVertex3f( x3, y3, z3 );
- c2.apply();
- glVertex3f( x3, y3, z3 );
- glVertex3f( x2, y2, z2 );
- glEnd();
- break;
+ GLFLOAT x1 = (GLFLOAT)
+ static_cast<OBAtom*>(bond->GetBgn())->GetX();
+ GLFLOAT y1 = (GLFLOAT)
+ static_cast<OBAtom*>(bond->GetBgn())->GetY();
+ GLFLOAT z1 = (GLFLOAT)
+ static_cast<OBAtom*>(bond->GetBgn())->GetZ();
+ GLFLOAT x2 = (GLFLOAT)
+ static_cast<OBAtom*>(bond->GetEnd())->GetX();
+ GLFLOAT y2 = (GLFLOAT)
+ static_cast<OBAtom*>(bond->GetEnd())->GetY();
+ GLFLOAT z2 = (GLFLOAT)
+ static_cast<OBAtom*>(bond->GetEnd())->GetZ();
- case BOND_CYLINDER_GRAY:
- drawBond( x1, y1, z1, x2, y2, z2, gray );
- break;
-
- case BOND_CYLINDER_BICOLOR:
- drawBond( x1, y1, z1, x3, y3, z3, c1 );
- drawBond( x2, y2, z2, x3, y3, z3, c2 );
- break;
-
- case BOND_DISABLED: break;
+ GLFLOAT x3 = (x1 + x2) / 2;
+ GLFLOAT y3 = (y1 + y2) / 2;
+ GLFLOAT z3 = (z1 + z2) / 2;
+
+ Color c1, c2;
+ c1 = getAtomColor( static_cast<OBAtom*>(bond->GetBgn()) );
+ c2 = getAtomColor( static_cast<OBAtom*>(bond->GetEnd()) );
+ Color gray( 0.5, 0.5, 0.5 );
+
+ switch( m_bondStyle )
+ {
+ case BOND_LINE:
+ glBegin( GL_LINES );
+ c1.apply();
+ glVertex3f( x1, y1, z1 );
+ glVertex3f( x3, y3, z3 );
+ c2.apply();
+ glVertex3f( x3, y3, z3 );
+ glVertex3f( x2, y2, z2 );
+ glEnd();
+ break;
+
+ case BOND_CYLINDER_GRAY:
+ drawBond( x1, y1, z1, x2, y2, z2, gray );
+ break;
+
+ case BOND_CYLINDER_BICOLOR:
+ drawBond( x1, y1, z1, x3, y3, z3, c1 );
+ drawBond( x2, y2, z2, x3, y3, z3, c2 );
+ break;
+
+ case BOND_DISABLED: break;
+ }
}
}
-#ifdef USE_DISPLAY_LIST
- glEndList();
- }
-
- glCallList( m_displayList );
-#endif
-
// now, paint a semitransparent sphere around the selected atom
if( m_selectedAtom )
GLFLOAT y = (GLFLOAT) m_selectedAtom->GetY();
GLFLOAT z = (GLFLOAT) m_selectedAtom->GetZ();
- GLColor c( 0.4, 0.4, 1.0, 0.7 );
+ Color c( 0.4, 0.4, 1.0, 0.7 );
GLFLOAT radius = m_molMinBondLength * 0.35;
GLFLOAT min_radius = (GLFLOAT) atomRadius () * 1.25;
old_time = new_time;
}
- renderText ( 20, 20, s );
+ glDisable( GL_LIGHTING );
+ glColor3f( 1.0, 1.0, 0.0 );
+ renderText ( 20, height() - 20, s );
update();
#endif
m_sphere.setup( sphere_detail, atomRadius() );
m_cylinder.setup( cylinder_faces, bondRadius() );
-
- deleteDisplayList();
}
void KalziumGLWidget::drawSphere( GLdouble x, GLdouble y, GLdouble z,
- GLfloat radius, GLColor &color )
+ GLfloat radius, Color &color )
{
color.applyAsMaterials();
}
void KalziumGLWidget::drawBond( FLOAT x1, FLOAT y1, FLOAT z1,
- FLOAT x2, FLOAT y2, FLOAT z2, GLColor &color )
+ FLOAT x2, FLOAT y2, FLOAT z2, Color &color )
{
color.applyAsMaterials();
// the "axis vector" of the cylinder
- GLVector3<FLOAT> axis( x2 - x1, y2 - y1, z2 - z1 );
+ Vector3<FLOAT> axis( x2 - x1, y2 - y1, z2 - z1 );
// find two vectors v, w such that (axis,v,w) is an orthogonal basis.
- GLVector3<FLOAT> v, w;
-// axis.construct_ortho_basis_given_first_vector( v, w );
+ Vector3<FLOAT> v, w;
+ construct_ortho_basis_given_first_vector( axis, v, w );
// normalize v and w. We DON'T want to normalize axis
v.normalize();
FLOAT x = (FLOAT) a->GetX();
FLOAT y = (FLOAT) a->GetY();
FLOAT z = (FLOAT) a->GetZ();
- FLOAT rad = GLSQRT(x*x + y*y + z*z);
+ FLOAT rad = SQRT(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 = GLSQRT ( (x1 - x2) * (x1 - x2)
+ FLOAT len = SQRT ( (x1 - x2) * (x1 - x2)
+ (y1 - y2) * (y1 - y2)
+ (z1 - z2) * (z1 - z2) );
if( len > m_molMaxBondLength )
updateGL();
}
-GLColor& KalziumGLWidget::getAtomColor( OpenBabel::OBAtom* atom )
+Color& KalziumGLWidget::getAtomColor( OpenBabel::OBAtom* atom )
{
- static GLColor c;
+ static Color c;
if ( atom->IsHydrogen() )
{//white
#include <QGLWidget>
#include <QList>
+#include <QFont>
#include <openbabel/mol.h>
+using namespace KalziumGLHelpers;
+
/**
* This class displays the 3D-view of a molecule
*
Q_OBJECT
protected:
-
- GLuint m_displayList;
- void deleteDisplayList();
-
/**
* The geometric model of the sphere (used for atoms).
*/
- GLSphere m_sphere;
+ Sphere m_sphere;
/**
* The geometric model of the cylinder (used for bonds).
*/
- GLCylinder m_cylinder;
+ Cylinder m_cylinder;
/**
* equals true if the user is currently dragging (rotating)
GLFLOAT y,
GLFLOAT z,
GLfloat radius,
- GLColor &color );
+ Color &color );
/**
* This method draws a bond
*/
virtual void drawBond( GLFLOAT x1, GLFLOAT y1, GLFLOAT z1,
GLFLOAT x2, GLFLOAT y2, GLFLOAT z2,
- GLColor &color );
+ Color &color );
/**
* returns the radius ( = half-thickness ) with which the
/**
* returns the color which a given atom should be painted
*/
- GLColor& getAtomColor( OpenBabel::OBAtom* atom );
+ Color& getAtomColor( OpenBabel::OBAtom* atom );
/**
* recomputes the geometry of the geometric objects ( sphere,