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 #define M_PI 3.1415926535
23 static char *FragProgFile
= "skinning.frag";
24 static char *VertProgFile
= "skinning.vert";
26 /* program/shader objects */
27 static GLuint fragShader
;
28 static GLuint vertShader
;
29 static GLuint program
;
33 static GLboolean Anim
= GL_TRUE
;
34 static GLboolean WireFrame
= GL_TRUE
;
35 static GLfloat xRot
= 0.0f
, yRot
= 90.0f
, zRot
= 0.0f
;
39 static GLfloat Matrices
[NUM_MATS
][16];
40 static GLint uMat0
, uMat1
;
41 static GLint WeightAttr
;
47 yRot
= 90 + glutGet(GLUT_ELAPSED_TIME
) * 0.005;
53 Cylinder(GLfloat length
, GLfloat radius
, GLint slices
, GLint stacks
)
55 float dw
= 1.0 / (stacks
- 1);
56 float dz
= length
/ stacks
;
59 for (j
= 0; j
< stacks
; j
++) {
63 glBegin(GL_TRIANGLE_STRIP
);
64 for (i
= 0; i
< slices
; i
++) {
65 float a
= (float) i
/ (slices
- 1) * M_PI
* 2.0;
66 float x
= radius
* cos(a
);
67 float y
= radius
* sin(a
);
68 glVertexAttrib1f(WeightAttr
, w0
);
69 glNormal3f(x
, y
, 0.0);
72 glVertexAttrib1f(WeightAttr
, w0
+ dw
);
73 glNormal3f(x
, y
, 0.0);
74 glVertex3f(x
, y
, z0
+ dz
);
82 * Update/animate the two matrices. One rotates, the other scales.
87 GLfloat t
= glutGet(GLUT_ELAPSED_TIME
) * 0.0025;
88 GLfloat scale
= 0.5 * (1.1 + sin(0.5 * t
));
89 GLfloat rot
= cos(t
) * 90.0;
93 glScalef(1.0, scale
, 1.0);
94 glGetFloatv(GL_MODELVIEW_MATRIX
, Matrices
[0]);
99 glRotatef(rot
, 0, 0, 1);
100 glGetFloatv(GL_MODELVIEW_MATRIX
, Matrices
[1]);
110 glUniformMatrix4fv(uMat0
, 1, GL_FALSE
, Matrices
[0]);
111 glUniformMatrix4fv(uMat1
, 1, GL_FALSE
, Matrices
[1]);
114 glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
);
116 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
118 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
121 glRotatef(xRot
, 1.0f
, 0.0f
, 0.0f
);
122 glRotatef(yRot
, 0.0f
, 1.0f
, 0.0f
);
123 glRotatef(zRot
, 0.0f
, 0.0f
, 1.0f
);
126 glTranslatef(0, 0, -2.5);
127 Cylinder(5.0, 1.0, 10, 20);
137 Reshape(int width
, int height
)
139 glViewport(0, 0, width
, height
);
140 glMatrixMode(GL_PROJECTION
);
142 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
143 glMatrixMode(GL_MODELVIEW
);
145 glTranslatef(0.0f
, 0.0f
, -15.0f
);
152 glDeleteShader(fragShader
);
153 glDeleteShader(vertShader
);
154 glDeleteProgram(program
);
155 glutDestroyWindow(win
);
160 Key(unsigned char key
, int x
, int y
)
162 const GLfloat step
= 2.0;
175 WireFrame
= !WireFrame
;
193 SpecialKey(int key
, int x
, int y
)
195 const GLfloat step
= 2.0;
222 if (!ShadersSupported())
225 vertShader
= CompileShaderFile(GL_VERTEX_SHADER
, VertProgFile
);
226 fragShader
= CompileShaderFile(GL_FRAGMENT_SHADER
, FragProgFile
);
227 program
= LinkShaders(vertShader
, fragShader
);
229 glUseProgram(program
);
231 uMat0
= glGetUniformLocation(program
, "mat0");
232 uMat1
= glGetUniformLocation(program
, "mat1");
234 WeightAttr
= glGetAttribLocation(program
, "weight");
236 assert(glGetError() == 0);
238 glClearColor(0.4f
, 0.4f
, 0.8f
, 0.0f
);
240 glEnable(GL_DEPTH_TEST
);
247 ParseOptions(int argc
, char *argv
[])
250 for (i
= 1; i
< argc
; i
++) {
251 if (strcmp(argv
[i
], "-fs") == 0) {
252 FragProgFile
= argv
[i
+1];
254 else if (strcmp(argv
[i
], "-vs") == 0) {
255 VertProgFile
= argv
[i
+1];
262 main(int argc
, char *argv
[])
264 glutInit(&argc
, argv
);
265 glutInitWindowSize(500, 500);
266 glutInitDisplayMode(GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
267 win
= glutCreateWindow(argv
[0]);
269 glutReshapeFunc(Reshape
);
270 glutKeyboardFunc(Key
);
271 glutSpecialFunc(SpecialKey
);
272 glutDisplayFunc(Redisplay
);
273 ParseOptions(argc
, argv
);