/* * soogl.h -- SOOGL, the Simple Object-Oriented Graphics Library * * A retained mode package based on GLUT and OpenGL. * * Copyright (c) Blair MacIntyre, The Georgia Institute of Technology, 1999. */ #ifndef __soogl_h__ #define __soogl_h__ #include #include #include #include /********************************************************************** * Initialize the package. This routine should do the following (at * least): * - initialize GLUT * - set the display mode to (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH) * - specify the clear color * - enable backface culling * - enable z-buffering * - initialize lighting **********************************************************************/ extern void sooglInit(int *argcp, char **argv); /********************************************************************** * Objects in out scene graph. * * We are mimicking an object oriented approach. Since C is not object- * oriented, each object is identified by a unique integer (which is * used to look up the object internally by your package). * A programmer must use these identifiers to manipulate all objects, and * a selection of methods are provided to perform all needed object * manipulations. Doing so allows SOOGL to redisplay the scene when any * change occurs to a graphical object or property, since it knows when * these changes happen. * * Ideally, we would want all object properties to inherit down the graph, * but for this assignment, you only need to support inheritance for * those properties that have corresponding state in OpenGL (to avoid * implementing stacks). The properties that inherit are described * below, and can be attached to any node. * * Other properties (such as a sphere radius) will only be attached directly * to relevant nodes. The methods to manipulate them are defined in * the same section as the object. **********************************************************************/ /********************************************************************** * geometry nodes **********************************************************************/ /* the sphere, cube and teapot correspond to the GLUT objects with * similar names. "precision" should be used for both the slices and * stacks parameters */ extern int sooglNewSphere(GLdouble radius, GLint precision); extern int sooglNewCube(GLdouble size); extern int sooglNewTeapot(GLdouble size); /* A polygon is specified by a list of 3D points specified in the vertex * parameter. There are numVertex*3 elements in the array, where the * elements are [x1,y1,z1,x2,y2,z2,....]. * The polygon is automatically closed, so vertex[numVertex] is connected to * vertex[1] to close the polygon (ie. a unit square in the x-y plane * would be created with: * GLfloat vertex[12] = [0,0,0, 1,0,0, 1,1,0, 0,1,0]; * int poly = sooglNewPolygon(4, vertex); * * ALERT: make sure you create a "two-sided polygon", since we have * backface culling enabled. You do this by drawing two polygons, one * using the points in the order given, one using them in reverse order. */ extern int sooglNewPolygon(int numVertex, GLfloat* vertex); /* these commands can change the properties of these geometric objects */ extern void sooglSetSphereRadius(int sphere, GLdouble radius); extern GLdouble sooglGetSphereRadius(int sphere); extern void sooglSetSpherePrecision(int sphere, GLint precision); extern GLint sooglGetSpherePrecision(int sphere); extern void sooglSetCubeSize(int cube, GLdouble size); extern GLdouble sooglGetCubeSize(int cube); extern void sooglSetTeapotSize(int teapot, GLdouble size); extern GLdouble sooglGetTeapotSize(int teapot); /********************************************************************** * light nodes **********************************************************************/ /* each light has a basic r,g,b color, and additional parameters * depending on the type of light: * - px,py,pz: position of a positional or spot light * - dx,dy,dz: direction of a directional or spot light * - ca,la,qa: the constant, linear and quadratic attentuation parameters * - cutoff: the angle of the spread of the spot light (see the opengl * book for a discussion of this) * - exponent: the exponent for the spot light * * In addition to properties corresponding to OpenGL lighting command * parameters, the light objects have two additional properties * - a floating point intensity multiplier for the light color. * - a boolean specifying whether a light is on or off */ extern int sooglNewAmbient(GLfloat r, GLfloat g, GLfloat b); extern int sooglNewDirectionalLight(GLfloat r, GLfloat g, GLfloat b, GLfloat dx, GLfloat dy, GLfloat dz); extern int sooglNewPositionalLight(GLfloat r, GLfloat g,GLfloat b, GLfloat px, GLfloat py, GLfloat pz, GLfloat ca, GLfloat la, GLfloat qa); extern int sooglNewSpotLight(GLfloat r, GLfloat g, GLfloat b, GLfloat px, GLfloat py, GLfloat pz, GLfloat dx, GLfloat dy, GLfloat dz, GLfloat ca, GLfloat la, GLfloat qa, GLfloat cutoff, GLfloat exponent); /* Each light has an intensity that is used to scale the color value. * The intensity defaults to 1.0. * * ie. if a light has color 0.2,0.4,0.8 and an intensity of 2, the * light's color ends up as 0.4,0.8,1.6 */ /* First, here is the "type" of the function pointer. */ typedef GLfloat (*IntensityFunc)(int time); extern void sooglLightIntensity(int light, GLfloat intensity); extern void sooglLightIntensityFunc(int light, IntensityFunc func); /* each light can be enabled or disabled with this switch. Lights are * on by default (switch = TRUE) */ extern void sooglSetLightSwitch(int light, GLboolean on); extern GLboolean sooglGetLightSwitch(int light); /* these commands can change the properties of these light objects */ extern void sooglSetLightColor(int light, GLfloat r, GLfloat g, GLfloat b); extern void sooglGetLightColor(int light, GLfloat *r, GLfloat *g, GLfloat *b); extern void sooglSetLightDirection(int light, GLfloat dx, GLfloat dy, GLfloat dz); extern void sooglGetLightDirection(int light, GLfloat *dx, GLfloat *dy, GLfloat *dz); extern void sooglSetLightPosition(int light, GLfloat px, GLfloat py, GLfloat pz); extern void sooglGetLightPosition(int light, GLfloat *px, GLfloat *py, GLfloat *pz); extern void sooglSetLightAttenuation(int light, GLfloat ca, GLfloat la, GLfloat qa); extern void sooglGetLightAttenuation(int light, GLfloat *ca, GLfloat *la, GLfloat *qa); extern void sooglSetLightCutoff(int light, GLfloat cutoff); extern GLfloat sooglGetLightCutoff(int light); extern void sooglSetLightExponent(int light, GLfloat exponent); extern GLfloat sooglGetLightExponent(int light); /********************************************************************** * Camera node for a perspective projection. * * The parameters correspond to what you would use in OpenGL to create a * perspective projection. * fx,fy,fz: the viewpoint ("from") * tx,ty,tz: the lookat point ("to") * ux,uy,uz: the up vector ("up") **********************************************************************/ extern int sooglNewCamera(GLdouble fx, GLdouble fy, GLdouble fz, GLdouble tx, GLdouble ty, GLdouble tz, GLdouble ux, GLdouble uy, GLdouble uz, GLdouble fov, GLdouble aspect, GLdouble near, GLdouble far); /********************************************************************** * Group nodes (group and root) **********************************************************************/ /* Create an empty group node. */ extern int sooglNewGroup(); /* Create a root node. Root nodes are group nodes that draw the scene * graph attached to them in the specified window (using a viewport that * fills the window) and using the camera object for viewing. If the * camera is connected to the scene graph, it will be transformed * accordingly, but it does not need to be attached to the graph. */ extern int sooglNewRoot(int window, int camera); /* Each group node has a list of children associated with it that define * the scene graphs. Here are two routines to add or remove a child to * or from a group. */ extern void sooglAddChild (int parent, int child); extern void sooglRemoveChild (int parent, int child); /* Each root node has a camera that specifies how the scene is drawn. * Here is a routine to change the camera to use for some root window. */ extern void glutUseCamera(int root, int cameraObject); /********************************************************************** * Properties. The properties that inherit down the graph. **********************************************************************/ /********************************* * Each object can be drawn either as lines, points or as a filled object. * * This property defaults to "solid" for each root GO. * * Setting the property to "NO_DRAWMODE" makes this property "undefined" * for this node, causing it to inherit the property value from its parent * node. *********************************/ #define SOOGL_NO_DRAWMODE 0 #define SOOGL_DRAW_FILL GL_FILL #define SOOGL_DRAW_LINE GL_LINE #define SOOGL_DRAW_POINT GL_POINT extern void sooglSetDrawMode(int object, int mode); extern int sooglGetDrawMode(int object); /*********************** * An object can be flat shaded or gouraud shaded (obviously, a polygon * will look the same in both models, but the other objects will look * different). * * This property defaults to flat shading for each root GO. * * Setting the property to "NO_SHADEMODEL" makes this property "undefined" * for this node, causing it to inherit the property value from its parent * node. ***********************/ #define SOOGL_NO_SHADEMODEL 0 #define SOOGL_FLAT_SHADE GL_FLAT #define SOOGL_SMOOTH_SHADE GL_SMOOTH extern void sooglSetShadeModel(int object, int model); extern int sooglGetShadeModel(int object); /*********************** * Material is the OpenGL material of an object. * The parameters are the r/g/b value for the ambient and diffuse part of * the material: we have no specular or emmisive material properties. * * This property defaults to (0.5, 0.5, 0.5) for each root GO. * * Call sooglClearMaterial() to make this property "undefined" for this * node, causing it to inherit the property value from its parent node. * * Material properties can either be constant (sooglSetMaterial) or * time-variant functions (sooglSetMaterialFunc). The function takes * the current time (of the sort returned by glutGet(GLUT_ELAPSED_TIME)), * computes the current material color, and fills the values into the * references provided. ***********************/ /* First, here is the "type" of the function pointer. */ typedef void (*MaterialFunc)(int time, GLfloat *r, GLfloat *g, GLfloat *b); extern void sooglClearMaterial(int object); extern void sooglSetMaterial(int object, GLfloat r, GLfloat g, GLfloat b); extern void sooglSetMaterialFunc(int object, MaterialFunc func); /*********************** * Transformations ***********************/ /* Transformation properties can either be constant or time-variant * functions (sooglSetTransformationFunc). Unlike the material, * shademodel and drawmode, the transformation properties COMPOSE as the * graph is traversed: at any given node, the "current transformation" * is the composition of all transformations on the path from the root * node to the node in question. * * Every node has a transformation property, which is initially the * identity matrix. We provide a set of functions to compose common * transformations (translate, scale, rotate) with the current value. * We also provide functions to replace (sooglSetTransformation) or * compose (sooglMultiplyTransformation) arbitrary transformation * matrices with the current transformation property. * * sooglResetTransformation() reinitializes the current transformation * property to the identity matrix. * * If a node has a time-variant function for its transformation * property, calling any transformation function aside from * sooglSetTransformationFunc() will change the property to a constant * value, and will use the last computed value as the initial constant * property. */ /* Compose a translation matrix onto the end of the object transformation */ extern void sooglTranslate(int object, GLfloat tx, GLfloat ty, GLfloat tz); /* Compose a scale matrix onto the end of the object transformation */ extern void sooglScale(int object, GLfloat sx, GLfloat sy, GLfloat sz); /* Compose a rotation matrix onto the end of the object transformation. * We provide rotations about the primary axes, with the angle specified * in degrees */ extern void sooglRotateX(int object, GLfloat angle); extern void sooglRotateY(int object, GLfloat angle); extern void sooglRotateZ(int object, GLfloat angle); /* set the object transformation to the identity matrix */ extern void sooglResetTransformation(int object); /* set the object transformation to the specified matrix */ extern void sooglSetTransformation(int object, GLfloat* matrix); /* compose a transformation matrix with the current object transformation */ extern void sooglMultiplyTransformation(int object, GLfloat* matrix); /* Specify an arbitrary time-based function as the transformation. * The function takes the current time (of the sort returned by * glutGet(GLUT_ELAPSED_TIME)), computes a transformation matrix, and * fills the matrix into the 16 element array provided. */ /* First, here is the "type" of the function pointer. */ typedef void (*TransformFunc)(int time, GLfloat *m); extern void sooglSetTransformationFunc(int object, TransformFunc func); /****************************** * Utility routines, to create matrices to be passed into SetTransform or * returned by a time-variant transformation function. */ /* translation matrix */ extern void sooglTranslateMatrix(GLfloat tx, GLfloat ty, GLfloat tz, GLfloat* returnMatrix); /* scale matrix */ extern void sooglScaleMatrix(GLfloat sx, GLfloat sy, GLfloat sz, GLfloat *returnMatrix); /* rotations about the primary axes. * the angle should be specified in degrees */ extern void sooglRotateXMatrix(GLfloat angle, GLfloat *returnMatrix); extern void sooglRotateYMatrix(GLfloat angle, GLfloat *returnMatrix); extern void sooglRotateZMatrix(GLfloat angle, GLfloat *returnMatrix); /* the identity matrix */ extern GLfloat soogl_Identity[16]; /********************************************************************** * OPTIONAL OPTIONAL OPTIONAL * Picking constitutes the optional part of the assignment. If you do * not want to implement it, do not define these functions. **********************************************************************/ /********************************************************************** * To specify which parts of the scene graph are important, and can be * picked, you can toggle the "pickable" property on any node. If a * node is pickable, the DAG rooted at that node is treated as one * logical entity by the picking routine: if sub-nodes in the DAG are * pickable, they are treated as sub-parts, and so on. **********************************************************************/ extern void sooglSetPickable(int object, GLboolean pickable); extern GLboolean sooglGetPickable(int object); /********************************************************************** * Pick objects at position x,y in the root's window, with an * area of width/height around the mouse point. * * sooglPickRoot() returns the number of objects picked, and fills in * the user-supplied array with a hit record for each object. The hit * record is defined as follows: * [number of objects on the path , zmin, zmax, o1, o2,...,oN] * * The object identifiers correspond to the pickable objects on the path * from the root node, starting with the object closest to the root (o1) * and ending with the object closest to leaf node (oN). Only those * objects that have their "pickable" property set to true are included * in the list. */ extern int sooglPickRoot (int root, GLdouble x, GLdouble y, GLdouble width, GLdouble height, int *buffer); #endif /* __soogl_h__ */