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.
19 #include "shaderutil.h"
22 static char *FragProgFile
= "skinning.frag";
23 static char *VertProgFile
= "skinning.vert";
25 /* program/shader objects */
26 static GLuint fragShader
;
27 static GLuint vertShader
;
28 static GLuint program
;
32 static GLboolean Anim
= GL_TRUE
;
33 static GLboolean WireFrame
= GL_TRUE
;
34 static GLfloat xRot
= 0.0f
, yRot
= 90.0f
, zRot
= 0.0f
;
38 static GLfloat Matrices
[NUM_MATS
][16];
39 static GLint uMat0
, uMat1
;
40 static GLint WeightAttr
;
46 yRot
= 90 + glutGet(GLUT_ELAPSED_TIME
) * 0.005;
52 Cylinder(GLfloat length
, GLfloat radius
, GLint slices
, GLint stacks
)
54 float dw
= 1.0 / (stacks
- 1);
55 float dz
= length
/ stacks
;
58 for (j
= 0; j
< stacks
; j
++) {
62 glBegin(GL_TRIANGLE_STRIP
);
63 for (i
= 0; i
< slices
; i
++) {
64 float a
= (float) i
/ (slices
- 1) * M_PI
* 2.0;
65 float x
= radius
* cos(a
);
66 float y
= radius
* sin(a
);
67 glVertexAttrib1f_func(WeightAttr
, w0
);
68 glNormal3f(x
, y
, 0.0);
71 glVertexAttrib1f_func(WeightAttr
, w0
+ dw
);
72 glNormal3f(x
, y
, 0.0);
73 glVertex3f(x
, y
, z0
+ dz
);
81 * Update/animate the two matrices. One rotates, the other scales.
86 GLfloat t
= glutGet(GLUT_ELAPSED_TIME
) * 0.0025;
87 GLfloat scale
= 0.5 * (1.1 + sin(0.5 * t
));
88 GLfloat rot
= cos(t
) * 90.0;
92 glScalef(1.0, scale
, 1.0);
93 glGetFloatv(GL_MODELVIEW_MATRIX
, Matrices
[0]);
98 glRotatef(rot
, 0, 0, 1);
99 glGetFloatv(GL_MODELVIEW_MATRIX
, Matrices
[1]);
109 glUniformMatrix4fv_func(uMat0
, 1, GL_FALSE
, Matrices
[0]);
110 glUniformMatrix4fv_func(uMat1
, 1, GL_FALSE
, Matrices
[1]);
113 glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
);
115 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
117 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
120 glRotatef(xRot
, 1.0f
, 0.0f
, 0.0f
);
121 glRotatef(yRot
, 0.0f
, 1.0f
, 0.0f
);
122 glRotatef(zRot
, 0.0f
, 0.0f
, 1.0f
);
125 glTranslatef(0, 0, -2.5);
126 Cylinder(5.0, 1.0, 10, 20);
136 Reshape(int width
, int height
)
138 glViewport(0, 0, width
, height
);
139 glMatrixMode(GL_PROJECTION
);
141 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
142 glMatrixMode(GL_MODELVIEW
);
144 glTranslatef(0.0f
, 0.0f
, -15.0f
);
151 glDeleteShader_func(fragShader
);
152 glDeleteShader_func(vertShader
);
153 glDeleteProgram_func(program
);
154 glutDestroyWindow(win
);
159 Key(unsigned char key
, int x
, int y
)
161 const GLfloat step
= 2.0;
174 WireFrame
= !WireFrame
;
192 SpecialKey(int key
, int x
, int y
)
194 const GLfloat step
= 2.0;
221 if (!ShadersSupported())
226 vertShader
= CompileShaderFile(GL_VERTEX_SHADER
, VertProgFile
);
227 fragShader
= CompileShaderFile(GL_FRAGMENT_SHADER
, FragProgFile
);
228 program
= LinkShaders(vertShader
, fragShader
);
230 glUseProgram_func(program
);
232 uMat0
= glGetUniformLocation_func(program
, "mat0");
233 uMat1
= glGetUniformLocation_func(program
, "mat1");
235 WeightAttr
= glGetAttribLocation_func(program
, "weight");
237 assert(glGetError() == 0);
239 glClearColor(0.4f
, 0.4f
, 0.8f
, 0.0f
);
241 glEnable(GL_DEPTH_TEST
);
248 ParseOptions(int argc
, char *argv
[])
251 for (i
= 1; i
< argc
; i
++) {
252 if (strcmp(argv
[i
], "-fs") == 0) {
253 FragProgFile
= argv
[i
+1];
255 else if (strcmp(argv
[i
], "-vs") == 0) {
256 VertProgFile
= argv
[i
+1];
263 main(int argc
, char *argv
[])
265 glutInit(&argc
, argv
);
266 glutInitWindowSize(500, 500);
267 glutInitDisplayMode(GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
268 win
= glutCreateWindow(argv
[0]);
269 glutReshapeFunc(Reshape
);
270 glutKeyboardFunc(Key
);
271 glutSpecialFunc(SpecialKey
);
272 glutDisplayFunc(Redisplay
);
273 ParseOptions(argc
, argv
);