*/
struct MolStyle
{
+
+ /** This style in which the bonds are rendered (or not) */
enum BondStyle
{
- BONDS_DISABLED,
- BONDS_GRAY,
- BONDS_USE_ATOMS_COLORS
+ BONDS_DISABLED, /**< don't render the bonds */
+ BONDS_GRAY, /**< render them as gray cylinders */
+ BONDS_USE_ATOMS_COLORS /**< render them as cylinders split
+ in half in the middle, each half being rendered
+ with the color of the atom it touches */
} m_bondStyle;
+ /** This style in which the atoms are rendered (or not) */
enum AtomStyle
{
- ATOMS_DISABLED,
- ATOMS_USE_FIXED_RADIUS,
- ATOMS_USE_VAN_DER_WAALS_RADIUS,
+ ATOMS_DISABLED,/**< don't render the atoms */
+ ATOMS_USE_FIXED_RADIUS, /**< render all atoms with the same,
+ fixed radius (given by the m_atomRadiusFactor member,
+ which is then interpreted as the radius itself) */
+ ATOMS_USE_VAN_DER_WAALS_RADIUS, /**< render each atom with
+ its own van der Waals radius, multiplied by
+ m_atomRadiusFactor */
} m_atomStyle;
+ /** The radius ( = half-thickness ) of single bonds */
double m_singleBondRadius;
+ /** The radius ( = half-thickness ) of each bond inside a
+ * multiple bond */
double m_multipleBondRadius;
+ /** Inside a multiple bond, this measures the displacement of each bond
+ * from the axis of the multiple bond */
double m_multipleBondShift;
+ /** When using ATOMS_USE_VAN_DER_WAALS_RADIUS, this is the factor by
+ * which the van der Waals radii are multiplied, so a value of 1.0 here
+ * gives physically realistic rendering. When using
+ * ATOMS_USE_FIXED_RADIUS, this s interpreted as the radius itself. */
double m_atomRadiusFactor;
+ /** This method is just a convenient way to set the values of
+ * the members. */
void setup( BondStyle bondStyle, AtomStyle atomStyle,
double singleBondRadius,
double multipleBondRadius,
double multipleBondShift,
double atomRadiusFactor );
+ /** This function returns the radius in which an atom with given atomic
+ * number should be rendered, when using this style */
double getAtomRadius( int atomicNumber );
+ /** This function returns the radius in which the passed OBAtom
+ * should be rendered, when using this style */
inline double getAtomRadius( const OpenBabel::OBAtom *atom )
{ return getAtomRadius( atom->GetAtomicNum() ); }
};
*/
struct Color
{
+ ///{ The four components of the color, ranging between 0 and 1.
GLfloat m_red, m_green, m_blue, m_alpha;
+ ///}
Color() {}
* This constructor sets the four components of the color
* individually. Each one ranges from 0.0 (lowest intensity) to
* 1.0 (highest intensity). For the alpha component, 0.0 means fully
- * transparent and 1.0 (the default) means fully opaque.
- */
+ * transparent and 1.0 (the default) means fully opaque. */
Color( GLfloat red, GLfloat green, GLfloat blue,
GLfloat alpha = 1.0 );
/**
* This constructor uses OpenBabel to retrieve the color in which
- * the atom should be rendered.
- */
+ * the atom should be rendered. */
Color( const OpenBabel::OBAtom *atom );
Color& operator=( const Color& other );
/**
- * Sets this color to be the one used by OpenGL for rendering
- * when lighting is disabled.
- */
+ * Sets this color to be the one used by OpenGL for rendering
+ * when lighting is disabled. */
inline void apply()
{
glColor4fv( reinterpret_cast<GLfloat *>( this ) );
/**
* 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.
- */
+ * specular colors. This is only useful if lighting is enabled. */
void applyAsMaterials();
};
{
protected:
+ /**
+ * This struct represents a vector to be passed to OpenGL as
+ * part of a Vertex Array. Here we don't want to use OpenBabel's
+ * vector3 class, because it uses double-precision coordinates,
+ * which would be a waste of memory here. **/
struct Vector
{
GLfloat x, y, z;
};
+ /** Pointer to the buffer storing the vertex array */
Vector *m_vertexBuffer;
+ /** Pointer to the buffer storing the normal array
+ * If m_hasSeparateNormalBuffer is false, then this is equal
+ * to m_vertexBuffer. */
Vector *m_normalBuffer;
+ /** Pointer to the buffer storing the indices */
unsigned short *m_indexBuffer;
+ /** The mode in which OpenGL should interpred the vertex arrays
+ * (for example, that could be GL_TRIANGLE_STRIP) */
GLenum m_mode;
+ /** The number of vertices, i.e. the size of m_vertexBuffer
+ * or equivalently m_normalBuffer */
int m_vertexCount;
+ /** The number of indices, i.e. the size of m_indexBuffer */
int m_indexCount;
+ /** The id of the OpenGL display list (used only if this option
+ * is turned on) */
GLuint m_displayList;
+ /** Equals true if there is an index buffer, i.e. if this is an
+ * indexed vertex array */
bool m_hasIndexBuffer;
+ /** If this equals false, then the vertex buffer will also be
+ * used as normal buffer. This allows to divide by 2 the space
+ * taken by a sphere vertex array. For most objects other than
+ * spheres, this should equal true. */
bool m_hasSeparateNormalBuffer;
+ /** Equals true if this is a valid, well-initialized vertex
+ * array */
bool m_isValid;
+ /** This pure virtual method should return the number of
+ * vertices, as computed from certain properties of a child
+ * class */
virtual int computeVertexCount() = 0;
+ /** This virtual method returns 0, and should be reimplemented
+ * in child classes to return the number of indices
+ * vertices as computed from certain properties of a child
+ * class */
virtual int computeIndexCount() { return 0; }
- virtual void buildBuffers() = 0;
+ /** This method allocates enough memory for the buffers. It
+ * should only be called once m_vertexCount and m_indexCount
+ * have been set. */
bool allocateBuffers();
+ /** This method frees the buffers. If display list compilation
+ * is enabled, then it is safe to call it once the display list
+ * has been compiled.
+ */
void freeBuffers();
+ /** This pure virtual method should fill the buffers with the
+ * geometric data. It should be called only after
+ * allocateBuffers() */
+ virtual void buildBuffers() = 0;
+ /** If display list compilation is enabled, then this method
+ * compiles the display list and then calls freeBuffers().
+ * It should only be called after buildBuffers(). */
void compileDisplayList();
-
+ /** This is a convenient method calling computeVertexCount(),
+ * computeIndexCount(), allocateBuffers(), buildBuffers() and
+ * compileDisplayList() in that order, thus doing all the
+ * initialization, whether or not display list compilation is
+ * enabled. */
void initialize();
+ /** This function draws the vertex array using OpenGL. */
+ void do_draw();
public:
+ /** This constructors only sets the values of the member data to
+ * some pre-initialization state. See the initialize() method
+ * for actual initialization. */
VertexArray( GLenum mode,
bool hasIndexBuffer,
bool hasSeparateNormalBuffer );
+ /** This destructor frees the buffers if necessary, and also
+ * deletes the display list if it has been compiled. */
virtual ~VertexArray();
- void do_draw();
+ /** If display list compilation is enabled, then this function
+ * just calls the display list. Otherwise, it calls do_draw().
+ */
inline void draw()
{
#ifdef USE_DISPLAY_LISTS
};
/**
-* This class represents and draws a sphere
+* This class represents and draws a sphere. The sphere is computed as a
+* "geosphere", that is, one starts with an icosahedron, which is the regular
+* solid with 20 triangular faces, and one then sub-tesselates each face into
+* smaller triangles. This is a classical algorithm, known to give very good
+* results.
*
* @author Benoit Jacob
*/
class Sphere : public VertexArray
{
private:
+ /** computes the index (position inside the index buffer)
+ * of a vertex given by its position (strip, column, row)
+ * inside a certain flat model of the sub-tesselated
+ * icosahedron */
inline unsigned short indexOfVertex(
int strip, int column, int row);
+ /** computes the coordinates
+ * of a vertex given by its position (strip, column, row)
+ * inside a certain flat model of the sub-tesselated
+ * icosahedron */
void computeVertex( int strip, int column, int row );
protected:
+ /** the detail-level of the sphere. Must be at least 1.
+ * This is interpreted as the number of sub-edges into which
+ * each edge of the icosahedron must be split. So the
+ * number of edges of the sphere is simply:
+ * 20 * detail^2. When detail==1, the sphere is just the
+ * icosahedron */
int m_detail;
+
virtual int computeVertexCount();
virtual int computeIndexCount();
virtual void buildBuffers();
public:
Sphere();
virtual ~Sphere() {}
+
+ /** initializes the sphere with given level of detail. If the
+ * sphere was already initialized, any pre-allocated buffers
+ * are freed and then re-allocated.
+ @param detail the wanted level of detail. See m_detail member */
virtual void setup( int detail );
+
+ /** draws the sphere at specifiec position and with
+ * specified radius */
virtual void draw( const OpenBabel::vector3 ¢er, double radius );
};
class Cylinder : public VertexArray
{
protected:
+ /** the number of faces of the cylinder. This only
+ * includes the lateral faces, as the base and top faces (the
+ * two discs) are not rendered. */
int m_faces;
virtual int computeVertexCount();
public:
Cylinder();
virtual ~Cylinder() {}
- virtual void setup( int detail );
+ /** initializes the cylinder with given number of faces. If the
+ * cylinder was already initialized, any pre-allocated buffers
+ * are freed and then re-allocated */
+ virtual void setup( int faces );
+ /**
+ * draws the cylinder at specified position, with specified
+ * radius. the order and shift arguments allow to render
+ * multiple cylinders at once. If you only want to render one
+ * cylinder, leave order and shift at their default values.
+ @param end1 the position of the first end of the cylinder.
+ that is, the center of the first disc-shaped face.
+ @param end2 the position of the second end of the cylinder.
+ that is, the center of the second disc-shaped face.
+ @param radius the radius of the cylinder
+ @param order to render only one cylinder, leave this set to
+ the default value, which is 1. If order>1, then order
+ parallel cylinders are drawn around the axis
+ (end1 - end2).
+ @param order this is only meaningful of order>1, otherwise
+ just let this set to the default value. When order>1,
+ this is interpreted as the displacement of the axis
+ of the drawn cylinders from the axis (end1 - end2).
+ */
virtual void draw( const OpenBabel::vector3 &end1, const OpenBabel::vector3 &end2,
double radius, int order = 1, double shift = 0.0 );
};
-/** This is a helper class for TextRenderer, and should probably never be
+/** BEEP BEEP BEEP this will likely be removed as Qt 4.2 has something better
+*
+* This is a helper class for TextRenderer, and should probably never be
* used directly. See TextRenderer.
*
* The CharRenderer class represents a character stored as OpenGL rendering
};
-/** This class renders text inside a QGLWidget. It replaces the functionality
+/** BEEP BEEP BEEP this will likely be removed as Qt 4.2 has something better
+*
+* This class renders text inside a QGLWidget. It replaces the functionality
* of QGLWidget::renderText(). The advantages over renderText() include:
* - supports any font, any character encoding supported by Qt
* (renderText is 8-bit-only and can only use "OpenGL-compatible" fonts)