#include "fg_gl2.h"
#include <math.h>
-/* VC++6 in C mode doesn't have C99's sinf/cos/sqrtf */
-#ifndef HAVE_SINF
-#define sinf(x) (float)sin((double)(x))
-#endif
-#ifndef HAVE_COSF
-#define cosf(x) (float)cos((double)(x))
-#endif
-#ifndef HAVE_SQRTF
-#define sqrtf(x) (float)sqrt((double)(x))
-#endif
-
/* declare for drawing using the different OpenGL versions here so we can
have a nice code order below */
#ifndef GL_ES_VERSION_2_0
static void fghDrawGeometryWire11(GLfloat *vertices, GLfloat *normals,
- GLushort *vertIdxs, GLsizei numParts, GLsizei numVertPerPart, GLenum vertexMode,
- GLushort *vertIdxs2, GLsizei numParts2, GLsizei numVertPerPart2
+ GLushort *vertIdxs, GLsizei numParts, GLsizei numVertPerPart, GLenum vertexMode,
+ GLushort *vertIdxs2, GLsizei numParts2, GLsizei numVertPerPart2
);
static void fghDrawGeometrySolid11(GLfloat *vertices, GLfloat *normals, GLsizei numVertices,
- GLushort *vertIdxs, GLsizei numParts, GLsizei numVertIdxsPerPart);
+ GLushort *vertIdxs, GLsizei numParts, GLsizei numVertIdxsPerPart);
#endif
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
+ 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, GLsizei numVertices,
- GLushort *vertIdxs, GLsizei numParts, GLsizei numVertIdxsPerPart,
- GLint attribute_v_coord, GLint attribute_v_normal);
+ GLushort *vertIdxs, GLsizei numParts, GLsizei numVertIdxsPerPart,
+ GLint attribute_v_coord, GLint attribute_v_normal);
+/* declare function for generating visualization of normals */
+static void fghGenerateNormalVisualization(GLfloat *vertices, GLfloat *normals, GLsizei numVertices,
+ GLushort *vertIdxs, GLsizei numParts, GLsizei numVertIdxsPerPart);
+#ifndef GL_ES_VERSION_2_0
+static void fghDrawNormalVisualization11();
+#endif
+static void fghDrawNormalVisualization20(GLint attribute_v_coord);
/* Drawing geometry:
* Explanation of the functions has to be separate for the polyhedra and
* Feel free to contribute better naming ;)
*/
static void fghDrawGeometryWire(GLfloat *vertices, GLfloat *normals, GLsizei numVertices,
- GLushort *vertIdxs, GLsizei numParts, GLsizei numVertPerPart, GLenum vertexMode,
- GLushort *vertIdxs2, GLsizei numParts2, GLsizei numVertPerPart2
+ 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_coord = fgStructure.CurrentWindow->Window.attribute_v_coord;
GLint attribute_v_normal = fgStructure.CurrentWindow->Window.attribute_v_normal;
+ if (fgStructure.CurrentWindow->State.VisualizeNormals)
+ /* generate normals for each vertex to be drawn as well */
+ fghGenerateNormalVisualization(vertices, normals, numVertices,
+ vertIdxs, numParts, numVertIdxsPerPart);
+
if (fgState.HasOpenGL20 && (attribute_v_coord != -1 || attribute_v_normal != -1))
+ {
/* User requested a 2.0 draw */
fghDrawGeometrySolid20(vertices, normals, numVertices,
vertIdxs, numParts, numVertIdxsPerPart,
attribute_v_coord, attribute_v_normal);
+
+ if (fgStructure.CurrentWindow->State.VisualizeNormals)
+ /* draw normals for each vertex as well */
+ fghDrawNormalVisualization20(attribute_v_coord);
+ }
#ifndef GL_ES_VERSION_2_0
else
+ {
fghDrawGeometrySolid11(vertices, normals, numVertices,
vertIdxs, numParts, numVertIdxsPerPart);
+
+ if (fgStructure.CurrentWindow->State.VisualizeNormals)
+ /* draw normals for each vertex as well */
+ fghDrawNormalVisualization11();
+ }
#endif
}
/* Version for OpenGL (ES) 1.1 */
#ifndef GL_ES_VERSION_2_0
static void fghDrawGeometryWire11(GLfloat *vertices, GLfloat *normals,
- GLushort *vertIdxs, GLsizei numParts, GLsizei numVertPerPart, GLenum vertexMode,
- GLushort *vertIdxs2, GLsizei numParts2, GLsizei numVertPerPart2
+ GLushort *vertIdxs, GLsizei numParts, GLsizei numVertPerPart, GLenum vertexMode,
+ GLushort *vertIdxs2, GLsizei numParts2, GLsizei numVertPerPart2
)
{
int i;
static void fghDrawGeometrySolid11(GLfloat *vertices, GLfloat *normals, GLsizei numVertices,
- GLushort *vertIdxs, GLsizei numParts, GLsizei numVertIdxsPerPart)
+ GLushort *vertIdxs, GLsizei numParts, GLsizei numVertIdxsPerPart)
{
int i;
/* Version for OpenGL (ES) >= 2.0 */
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
- )
+ GLushort *vertIdxs, GLsizei numParts, GLsizei numVertPerPart, GLenum vertexMode,
+ GLushort *vertIdxs2, GLsizei numParts2, GLsizei numVertPerPart2,
+ GLint attribute_v_coord, GLint attribute_v_normal)
{
GLuint vbo_coords = 0, vbo_normals = 0,
ibo_elements = 0, ibo_elements2 = 0;
/**
+ * Generate vertex indices for visualizing the normals.
+ */
+static GLfloat *verticesForNormalVisualization;
+static GLushort numNormalVertices = 0;
+static void fghGenerateNormalVisualization(GLfloat *vertices, GLfloat *normals, GLsizei numVertices,
+ GLushort *vertIdxs, GLsizei numParts, GLsizei numVertIdxsPerPart)
+{
+ GLushort i,j;
+ /* calc number of vertices to generate, allocate. Must be freed by caller
+ * We do the free at the end of fghDrawNormalVisualization11/fghDrawNormalVisualization20
+ */
+ if (!vertIdxs)
+ numNormalVertices = numVertices * 2;
+ else
+ numNormalVertices = numParts * numVertIdxsPerPart * 2;
+ verticesForNormalVisualization = malloc(numNormalVertices*3 * sizeof(GLfloat));
+
+ /* Now generate vertices for lines to draw the normals */
+ if (!vertIdxs)
+ {
+ for (i=0,j=0; i<numNormalVertices*3/2; i+=3, j+=6)
+ {
+ verticesForNormalVisualization[j+0] = vertices[i+0];
+ verticesForNormalVisualization[j+1] = vertices[i+1];
+ verticesForNormalVisualization[j+2] = vertices[i+2];
+ verticesForNormalVisualization[j+3] = vertices[i+0] + normals[i+0]/4.f;
+ verticesForNormalVisualization[j+4] = vertices[i+1] + normals[i+1]/4.f;
+ verticesForNormalVisualization[j+5] = vertices[i+2] + normals[i+2]/4.f;
+ }
+ }
+ else
+ {
+ for (i=0,j=0; i<numNormalVertices/2; i++, j+=6)
+ {
+ GLushort idx = vertIdxs[i]*3;
+ verticesForNormalVisualization[j+0] = vertices[idx+0];
+ verticesForNormalVisualization[j+1] = vertices[idx+1];
+ verticesForNormalVisualization[j+2] = vertices[idx+2];
+ verticesForNormalVisualization[j+3] = vertices[idx+0] + normals[idx+0]/4.f;
+ verticesForNormalVisualization[j+4] = vertices[idx+1] + normals[idx+1]/4.f;
+ verticesForNormalVisualization[j+5] = vertices[idx+2] + normals[idx+2]/4.f;
+ }
+ }
+}
+
+/* Version for OpenGL (ES) 1.1 */
+#ifndef GL_ES_VERSION_2_0
+static void fghDrawNormalVisualization11()
+{
+ GLfloat currentColor[4];
+ /* Setup draw color: (1,1,1)-shape's color */
+ glGetFloatv(GL_CURRENT_COLOR,currentColor);
+ glColor4f(1-currentColor[0],1-currentColor[1],1-currentColor[2],currentColor[3]);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ glVertexPointer(3, GL_FLOAT, 0, verticesForNormalVisualization);
+ glDrawArrays(GL_LINES, 0, numNormalVertices);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+
+ /* Done, free memory, reset color */
+ free(verticesForNormalVisualization);
+ glColor4fv(currentColor);
+}
+#endif
+
+/* Version for OpenGL (ES) >= 2.0 */
+static void fghDrawNormalVisualization20(GLint attribute_v_coord)
+{
+ GLuint vbo_coords = 0;
+
+ if (attribute_v_coord != -1) {
+ fghGenBuffers(1, &vbo_coords);
+ fghBindBuffer(FGH_ARRAY_BUFFER, vbo_coords);
+ fghBufferData(FGH_ARRAY_BUFFER, numNormalVertices * 3 * sizeof(verticesForNormalVisualization[0]),
+ verticesForNormalVisualization, FGH_STATIC_DRAW);
+ }
+
+
+ if (vbo_coords) {
+ fghEnableVertexAttribArray(attribute_v_coord);
+ fghBindBuffer(FGH_ARRAY_BUFFER, vbo_coords);
+ fghVertexAttribPointer(
+ attribute_v_coord, /* attribute */
+ 3, /* number of elements per vertex, here (x,y,z) */
+ GL_FLOAT, /* the type of each element */
+ GL_FALSE, /* take our values as-is */
+ 0, /* no extra data between each position */
+ 0 /* offset of first element */
+ );
+ fghBindBuffer(FGH_ARRAY_BUFFER, 0);
+ }
+
+ glDrawArrays(GL_LINES, 0, numNormalVertices);
+
+ if (vbo_coords != 0)
+ fghDisableVertexAttribArray(attribute_v_coord);
+
+ if (vbo_coords != 0)
+ fghDeleteBuffers(1, &vbo_coords);
+
+ /* Done, free memory */
+ free(verticesForNormalVisualization);
+}
+
+/**
* Generate all combinations of vertices and normals needed to draw object.
* Optional shape decomposition to triangles:
* We'll use glDrawElements to draw all shapes that are not naturally
/* -- Sierpinski Sponge -- */
static unsigned int ipow (int x, unsigned int y)
{
- return y==0? 1: y==1? x: (y%2? x: 1) * ipow(x*x, y/2);
+ /* return y==0? 1: y==1? x: (y%2? x: 1) * ipow(x*x, y/2); */
+ if (y==0)
+ return 1;
+ else
+ {
+ if (y==1)
+ return x;
+ else
+ {
+ return (y%2? x: 1) * ipow(x*x, y/2);
+ }
+ }
}
static void fghSierpinskiSpongeGenerate ( int numLevels, double offset[3], GLfloat scale, GLfloat* vertices, GLfloat* normals )
for (i=1; i<size; i++)
{
- (*sint)[i] = sinf(angle*i);
- (*cost)[i] = cosf(angle*i);
+ (*sint)[i] = (GLfloat)sin(angle*i);
+ (*cost)[i] = (GLfloat)cos(angle*i);
}
const GLfloat rStep = (GLfloat)base / ( ( stacks > 0 ) ? stacks : 1 );
/* Scaling factors for vertex normals */
- const GLfloat cosn = ( (GLfloat)height / sqrtf( height * height + base * base ));
- const GLfloat sinn = ( (GLfloat)base / sqrtf( height * height + base * base ));
+ const GLfloat cosn = (GLfloat) (height / sqrt( height * height + base * base ));
+ const GLfloat sinn = (GLfloat) (base / sqrt( height * height + base * base ));
(*vertices)[idx ] = cost[j]*r;
(*vertices)[idx+1] = sint[j]*r;
(*vertices)[idx+2] = z;
- (*normals )[idx ] = cost[j]*sinn;
- (*normals )[idx+1] = sint[j]*sinn;
- (*normals )[idx+2] = cosn;
+ (*normals )[idx ] = cost[j]*cosn;
+ (*normals )[idx+1] = sint[j]*cosn;
+ (*normals )[idx+2] = sinn;
}
z += zStep;