2 * Vertex "skinning" example.
3 * The idea is there are multiple modeling matrices applied to every
4 * vertex. Weighting values in [0,1] control the influence of each
5 * matrix on each vertex.
17 #include "shaderutil.h"
20 static char *FragProgFile
= "skinning.frag";
21 static char *VertProgFile
= "skinning.vert";
23 /* program/shader objects */
24 static GLuint fragShader
;
25 static GLuint vertShader
;
26 static GLuint program
;
30 static GLboolean Anim
= GL_TRUE
;
31 static GLboolean WireFrame
= GL_TRUE
;
32 static GLfloat xRot
= 0.0f
, yRot
= 90.0f
, zRot
= 0.0f
;
36 static GLfloat Matrices
[NUM_MATS
][16];
37 static GLint uMat0
, uMat1
;
38 static GLint WeightAttr
;
44 yRot
= 90 + glutGet(GLUT_ELAPSED_TIME
) * 0.005;
50 Cylinder(GLfloat length
, GLfloat radius
, GLint slices
, GLint stacks
)
52 float dw
= 1.0 / (stacks
- 1);
53 float dz
= length
/ stacks
;
56 for (j
= 0; j
< stacks
; j
++) {
60 glBegin(GL_TRIANGLE_STRIP
);
61 for (i
= 0; i
< slices
; i
++) {
62 float a
= (float) i
/ (slices
- 1) * M_PI
* 2.0;
63 float x
= radius
* cos(a
);
64 float y
= radius
* sin(a
);
65 glVertexAttrib1f(WeightAttr
, w0
);
66 glNormal3f(x
, y
, 0.0);
69 glVertexAttrib1f(WeightAttr
, w0
+ dw
);
70 glNormal3f(x
, y
, 0.0);
71 glVertex3f(x
, y
, z0
+ dz
);
79 * Update/animate the two matrices. One rotates, the other scales.
84 GLfloat t
= glutGet(GLUT_ELAPSED_TIME
) * 0.0025;
85 GLfloat scale
= 0.5 * (1.1 + sin(0.5 * t
));
86 GLfloat rot
= cos(t
) * 90.0;
90 glScalef(1.0, scale
, 1.0);
91 glGetFloatv(GL_MODELVIEW_MATRIX
, Matrices
[0]);
96 glRotatef(rot
, 0, 0, 1);
97 glGetFloatv(GL_MODELVIEW_MATRIX
, Matrices
[1]);
107 glUniformMatrix4fv(uMat0
, 1, GL_FALSE
, Matrices
[0]);
108 glUniformMatrix4fv(uMat1
, 1, GL_FALSE
, Matrices
[1]);
111 glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
);
113 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
115 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
118 glRotatef(xRot
, 1.0f
, 0.0f
, 0.0f
);
119 glRotatef(yRot
, 0.0f
, 1.0f
, 0.0f
);
120 glRotatef(zRot
, 0.0f
, 0.0f
, 1.0f
);
123 glTranslatef(0, 0, -2.5);
124 Cylinder(5.0, 1.0, 10, 20);
134 Reshape(int width
, int height
)
136 glViewport(0, 0, width
, height
);
137 glMatrixMode(GL_PROJECTION
);
139 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
140 glMatrixMode(GL_MODELVIEW
);
142 glTranslatef(0.0f
, 0.0f
, -15.0f
);
149 glDeleteShader(fragShader
);
150 glDeleteShader(vertShader
);
151 glDeleteProgram(program
);
152 glutDestroyWindow(win
);
157 Key(unsigned char key
, int x
, int y
)
159 const GLfloat step
= 2.0;
172 WireFrame
= !WireFrame
;
190 SpecialKey(int key
, int x
, int y
)
192 const GLfloat step
= 2.0;
219 if (!ShadersSupported())
222 vertShader
= CompileShaderFile(GL_VERTEX_SHADER
, VertProgFile
);
223 fragShader
= CompileShaderFile(GL_FRAGMENT_SHADER
, FragProgFile
);
224 program
= LinkShaders(vertShader
, fragShader
);
226 glUseProgram(program
);
228 uMat0
= glGetUniformLocation(program
, "mat0");
229 uMat1
= glGetUniformLocation(program
, "mat1");
231 WeightAttr
= glGetAttribLocation(program
, "weight");
233 assert(glGetError() == 0);
235 glClearColor(0.4f
, 0.4f
, 0.8f
, 0.0f
);
237 glEnable(GL_DEPTH_TEST
);
244 ParseOptions(int argc
, char *argv
[])
247 for (i
= 1; i
< argc
; i
++) {
248 if (strcmp(argv
[i
], "-fs") == 0) {
249 FragProgFile
= argv
[i
+1];
251 else if (strcmp(argv
[i
], "-vs") == 0) {
252 VertProgFile
= argv
[i
+1];
259 main(int argc
, char *argv
[])
261 glutInit(&argc
, argv
);
262 glutInitWindowSize(500, 500);
263 glutInitDisplayMode(GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
264 win
= glutCreateWindow(argv
[0]);
266 glutReshapeFunc(Reshape
);
267 glutKeyboardFunc(Key
);
268 glutSpecialFunc(SpecialKey
);
269 glutDisplayFunc(Redisplay
);
270 ParseOptions(argc
, argv
);