From a374c42e7510b66a16a7a627d189509a289dc365 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Beno=C3=AEt=20Jacob?= Date: Thu, 20 Jul 2006 17:04:42 +0000 Subject: [PATCH] Fully commented kalziumglhelperclasses.h Softened the specular highlights M src/kalziumglhelperclasses.h M src/kalziumglhelperclasses.cpp svn path=/trunk/KDE/kdeedu/kalzium/src/kalziumglhelperclasses.cpp; revision=564634 --- kalzium/kalziumglhelperclasses.cpp | 4 +- kalzium/kalziumglhelperclasses.h | 180 +++++++++++++++++++++++++---- 2 files changed, 160 insertions(+), 24 deletions(-) diff --git a/kalzium/kalziumglhelperclasses.cpp b/kalzium/kalziumglhelperclasses.cpp index bb249bd..6607182 100644 --- a/kalzium/kalziumglhelperclasses.cpp +++ b/kalzium/kalziumglhelperclasses.cpp @@ -77,8 +77,8 @@ void Color::applyAsMaterials() m_alpha }; GLfloat diffuseColor [] = { m_red, m_green, m_blue, m_alpha }; - float s = ( 1.0 + fabsf( m_red - m_green ) - + fabsf( m_blue - m_green ) + fabsf( m_blue - m_red ) ) / 3; + float s = ( 0.5 + fabsf( m_red - m_green ) + + fabsf( m_blue - m_green ) + fabsf( m_blue - m_red ) ) / 4.0; float t = 1.0 - s; diff --git a/kalzium/kalziumglhelperclasses.h b/kalzium/kalziumglhelperclasses.h index 224f9b7..4e6bb10 100644 --- a/kalzium/kalziumglhelperclasses.h +++ b/kalzium/kalziumglhelperclasses.h @@ -47,32 +47,56 @@ namespace KalziumGLHelpers */ 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() ); } }; @@ -84,7 +108,9 @@ struct MolStyle */ struct Color { + ///{ The four components of the color, ranging between 0 and 1. GLfloat m_red, m_green, m_blue, m_alpha; + ///} Color() {} @@ -92,23 +118,20 @@ struct 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( this ) ); @@ -117,8 +140,7 @@ struct Color /** * 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(); }; @@ -140,38 +162,96 @@ class VertexArray { 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 @@ -183,19 +263,38 @@ class VertexArray }; /** -* 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(); @@ -203,7 +302,15 @@ class Sphere : public VertexArray 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 ); }; @@ -215,6 +322,9 @@ class Sphere : public VertexArray 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(); @@ -223,12 +333,36 @@ class Cylinder : public VertexArray 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 @@ -268,7 +402,9 @@ class CharRenderer }; -/** 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) -- 2.47.3