- <tt>i I </tt> Show info
- <tt>p P </tt> Toggle perspective or orthographic projection
- <tt>r R </tt> Toggle fixed or animated rotation around model X-axis
+ - <tt>s S </tt> Toggle toggle fixed function or shader render path
+ - <tt>n N </tt> Toggle visualization of object's normal vectors
- <tt>= + </tt> Increase \a slices
- <tt>- _ </tt> Decreate \a slices
- <tt>, < </tt> Decreate \a stacks
#define APIENTRY
#endif
-#ifndef GL_VERSION_1_5
-typedef void (APIENTRY *PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
-typedef void (APIENTRY *PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
-typedef void (APIENTRY *PFNGLBUFFERDATAPROC) (GLenum target, ourGLsizeiptr size, const GLvoid *data, GLenum usage);
-#endif
#ifndef GL_VERSION_2_0
typedef GLuint (APIENTRY *PFNGLCREATESHADERPROC) (GLenum type);
typedef void (APIENTRY *PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const ourGLchar **string, const GLint *length);
gl_GetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) glutGetProcAddress ("glGetUniformLocation");
gl_UniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) glutGetProcAddress ("glUniformMatrix4fv");
gl_UniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) glutGetProcAddress ("glUniformMatrix3fv");
+ if (!gl_CreateShader || !gl_ShaderSource || !gl_CompileShader || !gl_CreateProgram || !gl_AttachShader || !gl_LinkProgram || !gl_UseProgram || !gl_GetShaderiv || !gl_GetShaderInfoLog || !gl_GetProgramiv || !gl_GetProgramInfoLog || !gl_GetAttribLocation || !gl_GetUniformLocation || !gl_UniformMatrix4fv || !gl_UniformMatrix3fv)
+ {
+ fprintf (stderr, "glCreateShader, glShaderSource, glCompileShader, glCreateProgram, glAttachShader, glLinkProgram, glUseProgram, glGetShaderiv, glGetShaderInfoLog, glGetProgramiv, glGetProgramInfoLog, glGetAttribLocation, glGetUniformLocation, glUniformMatrix4fv or gl_UniformMatrix3fv not found");
+ exit(1);
+ }
}
const ourGLchar *vertexShaderSource[] = {
static GLboolean visNormals = GL_FALSE;
/*
+ * Enum to tell drawSizeInfo what to draw for each object
+ */
+#define GEO_NO_SIZE 0
+#define GEO_SIZE 1
+#define GEO_SCALE 2
+#define GEO_INNER_OUTER_RAD 4
+#define GEO_RAD 8
+#define GEO_BASE_HEIGHT 16
+#define GEO_RAD_HEIGHT 32
+
+/*
* These one-liners draw particular objects, fetching appropriate
* information from the above globals. They are just thin wrappers
* for the FreeGLUT objects.
static void drawWireTorus(void) { glutWireTorus (irad,orad,slices,stacks); }
static void drawSolidSphere(void) { glutSolidSphere(orad,slices,stacks); } /* orad doubles as size input */
static void drawWireSphere(void) { glutWireSphere(orad,slices,stacks); } /* orad doubles as size input */
-static void drawSolidCone(void) { glutSolidCone(orad,orad,slices,stacks); } /* orad doubles as size input */
-static void drawWireCone(void) { glutWireCone(orad,orad,slices,stacks); } /* orad doubles as size input */
-static void drawSolidCylinder(void) { glutSolidCylinder(orad,orad,slices,stacks); } /* orad doubles as size input */
-static void drawWireCylinder(void) { glutWireCylinder(orad,orad,slices,stacks); } /* orad doubles as size input */
+static void drawSolidCone(void) { glutSolidCone(irad,orad,slices,stacks); } /* irad doubles as base input, and orad as height input */
+static void drawWireCone(void) { glutWireCone(irad,orad,slices,stacks); } /* irad doubles as base input, and orad as height input */
+static void drawSolidCylinder(void) { glutSolidCylinder(irad,orad,slices,stacks); } /* irad doubles as radius input, and orad as height input */
+static void drawWireCylinder(void) { glutWireCylinder(irad,orad,slices,stacks); } /* irad doubles as radius input, and orad as height input */
+/* per Glut manpage, it should be noted that the teapot is rendered
+ * with clockwise winding for front facing polygons...
+ * Same for the teacup and teaspoon
+ */
static void drawSolidTeapot(void)
-{
- /* per Glut manpage, it should be noted that the teapot is rendered
- * with clockwise winding for front facing polygons...
- */
- glFrontFace(GL_CW);
- glutSolidTeapot(orad); /* orad doubles as size input */
- glFrontFace(GL_CCW);
-}
+{ glFrontFace(GL_CW); glutSolidTeapot(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
static void drawWireTeapot(void)
-{
- /* per Glut manpage, it should be noted that the teapot is rendered
- * with clockwise winding for front facing polygons...
- */
- glFrontFace(GL_CW);
- glutWireTeapot(orad); /* orad doubles as size input */
- glFrontFace(GL_CCW);
-}
+{ glFrontFace(GL_CW); glutWireTeapot(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
+static void drawSolidTeacup(void)
+{ glFrontFace(GL_CW); glutSolidTeacup(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
+static void drawWireTeacup(void)
+{ glFrontFace(GL_CW); glutWireTeacup(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
+static void drawSolidTeaspoon(void)
+{ glFrontFace(GL_CW); glutSolidTeaspoon(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
+static void drawWireTeaspoon(void)
+{ glFrontFace(GL_CW); glutWireTeaspoon(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
#define RADIUSFAC 0.70710678118654752440084436210485f
const char * const name;
void (*solid) (void);
void (*wire) (void);
+ int drawSizeInfoFlag;
} entry;
-#define ENTRY(e) {#e, drawSolid##e, drawWire##e}
+#define ENTRY(e,f) {#e, drawSolid##e, drawWire##e,f}
static const entry table [] =
{
- ENTRY (Tetrahedron),
- ENTRY (Cube),
- ENTRY (Octahedron),
- ENTRY (Dodecahedron),
- ENTRY (RhombicDodecahedron),
- ENTRY (Icosahedron),
- ENTRY (SierpinskiSponge),
- ENTRY (Teapot),
- ENTRY (Torus),
- ENTRY (Sphere),
- ENTRY (Cone),
- ENTRY (Cylinder),
- ENTRY (Cuboctahedron) /* This one doesn't work when in shader mode and is then skipped */
+ ENTRY (Tetrahedron,GEO_NO_SIZE),
+ ENTRY (Cube,GEO_SIZE),
+ ENTRY (Octahedron,GEO_NO_SIZE),
+ ENTRY (Dodecahedron,GEO_NO_SIZE),
+ ENTRY (RhombicDodecahedron,GEO_NO_SIZE),
+ ENTRY (Icosahedron,GEO_NO_SIZE),
+ ENTRY (SierpinskiSponge,GEO_SCALE),
+ ENTRY (Teapot,GEO_SIZE),
+ ENTRY (Teacup,GEO_SIZE),
+ ENTRY (Teaspoon,GEO_SIZE),
+ ENTRY (Torus,GEO_INNER_OUTER_RAD),
+ ENTRY (Sphere,GEO_RAD),
+ ENTRY (Cone,GEO_BASE_HEIGHT),
+ ENTRY (Cylinder,GEO_RAD_HEIGHT),
+ ENTRY (Cuboctahedron,GEO_SIZE) /* This one doesn't work when in shader mode and is then skipped */
};
#undef ENTRY
glPopMatrix();
}
-/* GLUT callback Handlers */
+/* Print info about the about the current shape and render state on the screen */
+static void DrawSizeInfo(int *row)
+{
+ switch (table [function_index].drawSizeInfoFlag)
+ {
+ case GEO_NO_SIZE:
+ break;
+ case GEO_SIZE:
+ shapesPrintf ((*row)++, 1, "Size Up Down : %f", orad);
+ break;
+ case GEO_SCALE:
+ shapesPrintf ((*row)++, 1, "Scale Up Down : %f", orad);
+ break;
+ case GEO_INNER_OUTER_RAD:
+ shapesPrintf ((*row)++, 1, "Inner radius Left Right: %f", irad);
+ shapesPrintf ((*row)++, 1, "Outer radius Up Down : %f", orad);
+ break;
+ case GEO_RAD:
+ shapesPrintf ((*row)++, 1, "Radius Up Down : %f", orad);
+ break;
+ case GEO_BASE_HEIGHT:
+ shapesPrintf ((*row)++, 1, "Base Left Right: %f", irad);
+ shapesPrintf ((*row)++, 1, "Height Up Down : %f", orad);
+ break;
+ case GEO_RAD_HEIGHT:
+ shapesPrintf ((*row)++, 1, "Radius Left Right: %f", irad);
+ shapesPrintf ((*row)++, 1, "Height Up Down : %f", orad);
+ break;
+ }
+}
+
+static void drawInfo()
+{
+ int row = 1;
+ shapesPrintf (row++, 1, "Shape PgUp PgDn: %s", table [function_index].name);
+ shapesPrintf (row++, 1, "Slices +-: %d Stacks <>: %d", slices, stacks);
+ shapesPrintf (row++, 1, "nSides +-: %d nRings <>: %d", slices, stacks);
+ shapesPrintf (row++, 1, "Depth (): %d", depth);
+ DrawSizeInfo(&row);
+ if (persProject)
+ shapesPrintf (row++, 1, "Perspective projection (p)");
+ else
+ shapesPrintf (row++, 1, "Orthographic projection (p)");
+ if (useShader)
+ shapesPrintf (row++, 1, "Using shader (s)");
+ else
+ shapesPrintf (row++, 1, "Using fixed function pipeline (s)");
+ if (animateXRot)
+ shapesPrintf (row++, 1, "2D rotation (r)");
+ else
+ shapesPrintf (row++, 1, "1D rotation (r)");
+ shapesPrintf (row++, 1, "visualizing normals: %i (n)",visNormals);
+}
+/* GLUT callback Handlers */
static void
resize(int width, int height)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glutSetOption(GLUT_OBJECTS_VISUALIZE_NORMALS,visNormals); /* Normals visualized or not? */
+ glutSetOption(GLUT_GEOMETRY_VISUALIZE_NORMALS,visNormals); /* Normals visualized or not? */
if (useShader && !shaderReady)
initShader();
gl_UseProgram (program);
glutSetVertexAttribCoord3(attribute_fg_coord);
glutSetVertexAttribNormal(attribute_fg_normal);
+ /* There is also a glutSetVertexAttribTexCoord2, which is used only when drawing the teapot, teacup or teaspoon */
gl_matrix_mode(GL_PROJECTION);
gl_load_identity();
glColor3d(0.1,0.1,0.4);
}
- if( show_info ) {
- shapesPrintf (1, 1, "Shape PgUp PgDn: %s", table [function_index].name);
- shapesPrintf (2, 1, "Slices +-: %d Stacks <>: %d", slices, stacks);
- shapesPrintf (3, 1, "nSides +-: %d nRings <>: %d", slices, stacks);
- shapesPrintf (4, 1, "Depth (): %d", depth);
- shapesPrintf (5, 1, "Outer radius Up Down : %f", orad);
- shapesPrintf (6, 1, "Inner radius Left Right: %f", irad);
- if (persProject)
- shapesPrintf (7, 1, "Perspective projection (p)");
- else
- shapesPrintf (7, 1, "Orthographic projection (p)");
- if (useShader)
- shapesPrintf (8, 1, "Using shader (s)");
- else
- shapesPrintf (8, 1, "Using fixed function pipeline (s)");
- if (animateXRot)
- shapesPrintf (9, 1, "2D rotation (r)");
- else
- shapesPrintf (9, 1, "1D rotation (r)");
- shapesPrintf (10, 1, "visualizing normals: %i (n)",visNormals);
- } else {
+ if( show_info )
+ /* print info to screen */
+ drawInfo();
+ else
/* print to command line instead */
printf ( "Shape %d slides %d stacks %d\n", function_index, slices, stacks ) ;
- }
glutSwapBuffers();
}