+/* declare for drawing using the different OpenGL versions here so we can
+ have a nice code order below */
+static void fghDrawGeometryWire11(GLfloat *vertices, GLfloat *normals,
+ GLushort *vertIdxs, GLsizei numParts, GLsizei numVertPerPart, GLenum vertexMode,
+ GLushort *vertIdxs2, GLsizei numParts2, GLsizei numVertPerPart2
+ );
+static void fghDrawGeometrySolid11(GLfloat *vertices, GLfloat *normals, GLfloat *textcs, GLsizei numVertices,
+ GLushort *vertIdxs, GLsizei numParts, GLsizei numVertIdxsPerPart);
+static void fghDrawGeometryWire20(GLfloat *vertices, GLfloat *normals, GLsizei numVertices,
+ GLushort *vertIdxs, GLsizei numParts, GLsizei numVertPerPart, GLenum vertexMode,
+ GLushort *vertIdxs2, GLsizei numParts2, GLsizei numVertPerPart2,
+ GLint attribute_v_coord, GLint attribute_v_normal
+ );
+static void fghDrawGeometrySolid20(GLfloat *vertices, GLfloat *normals, GLfloat *textcs, GLsizei numVertices,
+ GLushort *vertIdxs, GLsizei numParts, GLsizei numVertIdxsPerPart,
+ GLint attribute_v_coord, GLint attribute_v_normal, GLint attribute_v_texture);
+/* declare function for generating visualization of normals */
+static void fghGenerateNormalVisualization(GLfloat *vertices, GLfloat *normals, GLsizei numVertices);
+static void fghDrawNormalVisualization11();
+static void fghDrawNormalVisualization20(GLint attribute_v_coord);
+
+/* Drawing geometry:
+ * Explanation of the functions has to be separate for the polyhedra and
+ * the non-polyhedra (objects with a circular cross-section).
+ * Polyhedra:
+ * - We have only implemented the five platonic solids and the rhomboid
+ * dodecahedron. If you need more types of polyhedra, please see
+ * CPolyhedron in MRPT
+ * - Solids are drawn by glDrawArrays if composed of triangular faces
+ * (the tetrahedron, octahedron, and icosahedron), or are first
+ * decomposed into triangles and then drawn by glDrawElements if its
+ * faces are squares or pentagons (cube, dodecahedron and rhombic
+ * dodecahedron) as some vertices are repeated in that case.
+ * - WireFrame drawing is done using a GL_LINE_LOOP per face, and thus
+ * issuing one draw call per face. glDrawArrays is always used as no
+ * triangle decomposition is needed to draw faces. We use the "first"
+ * parameter in glDrawArrays to go from face to face.
+ *
+ * Non-polyhedra:
+ * - We have implemented the sphere, cylinder, cone and torus.
+ * - All shapes are characterized by two parameters: the number of
+ * subdivisions along two axes used to construct the shape's vertices
+ * (e.g. stacks and slices for the sphere).
+ * As different subdivisions are most suitable for different shapes,
+ * and are thus also named differently, I wont provide general comments
+ * on them here.
+ * - Solids are drawn using glDrawArrays and GL_TRIANGLE_STRIP. Each
+ * strip covers one revolution around one of the two subdivision axes
+ * of the shape.
+ * - WireFrame drawing is done for the subdivisions along the two axes
+ * separately, usually using GL_LINE_LOOP. Vertex index arrays are
+ * built containing the vertices to be drawn for each loop, which are
+ * then drawn using multiple calls to glDrawElements. As the number of
+ * subdivisions along the two axes is not guaranteed to be equal, the
+ * vertex indices for e.g. stacks and slices are stored in separate
+ * arrays, which makes the input to the drawing function a bit clunky,
+ * but allows for the same drawing function to be used for all shapes.
+ */
+
+
+/**
+ * Draw geometric shape in wire mode (only edges)
+ *
+ * Arguments:
+ * GLfloat *vertices, GLfloat *normals, GLsizei numVertices
+ * The vertex coordinate and normal buffers, and the number of entries in
+ * those
+ * GLushort *vertIdxs
+ * a vertex indices buffer, optional (never passed for the polyhedra)
+ * GLsizei numParts, GLsizei numVertPerPart
+ * polyhedra: number of faces, and the number of vertices for drawing
+ * each face
+ * non-polyhedra: number of edges to draw for first subdivision (not
+ * necessarily equal to number of subdivisions requested by user, e.g.
+ * as each subdivision is enclosed by two edges), and number of
+ * vertices for drawing each
+ * numParts * numVertPerPart gives the number of entries in the vertex
+ * array vertIdxs
+ * GLenum vertexMode
+ * vertex drawing mode (e.g. always GL_LINE_LOOP for polyhedra, varies
+ * for others)
+ * GLushort *vertIdxs2, GLsizei numParts2, GLsizei numVertPerPart2
+ * non-polyhedra only: same as the above, but now for subdivisions along
+ * the other axis. Always drawn as GL_LINE_LOOP.
+ *
+ * Feel free to contribute better naming ;)
+ */
+void fghDrawGeometryWire(GLfloat *vertices, GLfloat *normals, GLsizei numVertices,
+ GLushort *vertIdxs, GLsizei numParts, GLsizei numVertPerPart, GLenum vertexMode,
+ GLushort *vertIdxs2, GLsizei numParts2, GLsizei numVertPerPart2
+ )
+{
+ GLint attribute_v_coord = fgStructure.CurrentWindow->Window.attribute_v_coord;
+ GLint attribute_v_normal = fgStructure.CurrentWindow->Window.attribute_v_normal;
+
+ if (fgState.HasOpenGL20 && (attribute_v_coord != -1 || attribute_v_normal != -1))
+ /* User requested a 2.0 draw */
+ fghDrawGeometryWire20(vertices, normals, numVertices,
+ vertIdxs, numParts, numVertPerPart, vertexMode,
+ vertIdxs2, numParts2, numVertPerPart2,
+ attribute_v_coord, attribute_v_normal);
+ else
+ fghDrawGeometryWire11(vertices, normals,
+ vertIdxs, numParts, numVertPerPart, vertexMode,
+ vertIdxs2, numParts2, numVertPerPart2);
+}