glman supports simple animations through the use of the variable uniform float Timer; glman will automatically assign a value to Timer that ramps from 0 to 1 over a period of 10 seconds (you can specify the time interval in your glib file).
To illustrate the use of the timer, create the following files for the explosion example: explode.glib, explode.vert, explode.geom, and explode.frag
explode.glib: You can change the Timer interval to any positive time in seconds that you want.
##OpenGL GLIB GSTAP Perspective 70 LookAt 0 0 15 0 0 0 0 1 0 Background [1. 1. 1.] Pointsize 2. Vertex explode.vert Geometry explode.geom Fragment explode.frag Program Explode \ uLevel <0 4 6> \ uGravity <-10 -1 0> \ uVelScale <1. 30. 50.> Timer 10 Color .5 1. .5 Obj dino3.obj
explode.vert
#version 330 void main( ) { gl_Position = uModelViewMatrix * aVertex; }
explode.geom: We talked about this shader in the lectures; it is also listed in Chapter 16 of the textbook. Here, I've used Timer to make time a value that ramps from 0 to 1 and back to 0; thus, the model looks like it is repeatedly exploding outwards and then collapsing back inwards. Other effects can be found in Table 16.2 of the textbook.
#version 330 #extension GL_EXT_geometry_shader4: enable #extension GL_EXT_gpu_shader4: enable layout( triangles ) in; layout( points, max_vertices=200 ) out; uniform int uLevel; uniform float uGravity; uniform float Timer; uniform float uVelScale; out float gLightIntensity; const vec3 LIGHTPOS = vec3( 0., 0., 10. ); vec3 V0, V01, V02; vec3 CG; vec3 Normal; void ProduceVertex( float s, float t ) { // compute the time from Timer float time = 20 * Timer; if (Timer > 0.5) time = 20 - time; vec3 v = V0 + s*V01 + t*V02; gLightIntensity = abs( dot( normalize(LIGHTPOS - v), Normal ) ); vec3 vel = uVelScale * ( v - CG ); v = v + vel*time + 0.5*vec3(0.,uGravity,0.)*time*time; v.y = max(v.y, -2.0); gl_Position = uProjectionMatrix * vec4( v, 1. ); EmitVertex( ); } void main( ) { V01 = ( gl_PositionIn[1] - gl_PositionIn[0] ).xyz; V02 = ( gl_PositionIn[2] - gl_PositionIn[0] ).xyz; Normal = normalize( cross( V01, V02 ) ); V0 = gl_PositionIn[0].xyz; CG = ( gl_PositionIn[0].xyz + gl_PositionIn[1].xyz + gl_PositionIn[2].xyz ) / 3.; int numLayers = 1 << uLevel; float dt = 1. / float( numLayers ); float t = 1.; for( int it = 0; it <= numLayers; it++ ) { float smax = 1. - t; int nums = it + 1; float ds = smax / float( nums - 1 ); float s = 0.; for( int is = 0; is < nums; is++ ) { ProduceVertex( s, t ); s += ds; } t -= dt; } }
explode.frag
#version 330 in float gLightIntensity; out vec4 fFragColor; const vec3 COLOR = vec3( 0., 1., 0. ); void main( ) { fFragColor = vec4( gLightIntensity*COLOR, 1. ); }
This is the variation of the silhouette shader we discussed in class; here, we output triangles for the silhouette so that we can render the silhouette in one pass. The handout describes the details of the shader. I've included the glib file, vertex, and fragment shaders below; you should type in the geometry shader included in the handout to help you understand exactly what it is doing.
silh3.glib: Note that you must use an ObjAdj model to obtain the adjacency information needed by the geometry shader.
##OpenGL GLIB GSTAP Perspective 70 LookAt 0 0 8 0 0 0 0 1 0 Vertex silh3.vert Geometry silh3.geom Fragment silh3.frag Program Silhoutte \ uEdgeWidth <0 0.01 0.1> \ uPctExtend <0 0.05 1> \ uLineColor {0. 0. 1. 1.} ObjAdj cow.obj
silh3.vert.
#version 330 in vec4 aVertex; in vec4 aNormal; out vec3 vPosition; out vec3 vNormal; uniform mat4 uModelViewMatrix; uniform mat4 uNormalMatrix; uniform mat4 uModelViewProjectionMatrix; void main( ) { vPosition = vec3(uModelViewMatrix * aVertex); vNormal = normalize(vec3(uNormalMatrix * aNormal)); gl_Position = uModelViewProjectionMatrix * aVertex; }
silh3.frag.
#version 330 compatibility in vec3 gNormal; // position in camera coords in vec3 gPosition; // normal in camera coords flat in int gIsEdge; // edge? out vec4 fFragColor; uniform vec4 uLineColor; // constants; would normally be uniforms // light position in eye coordinates const vec3 myLightPosition = vec3(1., 1., 10.); const vec3 myLightAmbient = vec3(0., 0.2, 0.2); const vec3 myLightDiffuse = vec3(1., 1., 1.); const vec3 myLightSpecular = vec3(1., 1., 1.); const vec3 myMaterialAmbient = vec3(1., 0.5, 0.); const vec3 myMaterialDiffuse = vec3(1., 0.5, 0.); const vec3 myMaterialSpecular = vec3(0.6, 0.6, 0.6); const float myMaterialShininess = 80.; vec3 ADSLightModel(in vec3 myNormal, in vec3 myPosition) { // normal, light, view, and reflection directions vec3 norm = normalize(myNormal); vec3 lightv = normalize(myLightPosition - myPosition); vec3 viewv = normalize(-myPosition); vec3 refl = reflect(-lightv, norm); // ambient vec3 ambient = myMaterialAmbient * myLightAmbient; // diffuse vec3 diffuse = max(0., dot(lightv, norm)) * myMaterialDiffuse * myLightDiffuse; // specular vec3 specular = vec3(0., 0., 0.); if (dot(lightv, viewv) > 0.) { specular = pow(max(0.0, dot(viewv, refl)), myMaterialShininess) * myMaterialSpecular * myLightSpecular; } return clamp(ambient + diffuse + specular, 0., 1.); } void main(void) { if (gIsEdge > 0) { fFragColor = uLineColor; } else { vec3 color = ADSLightModel(gNormal, gPosition); fFragColor.rgb = color; fFragColor.a = 1.; } }