r300: Cleanup r300_fragment_program_code
[mesa.git] / progs / glsl / skinning.c
1 /**
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.
6 *
7 * 4 Nov 2008
8 */
9
10 #include <assert.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <math.h>
15 #include <GL/glew.h>
16 #include <GL/glut.h>
17 #include "shaderutil.h"
18
19
20 static char *FragProgFile = "skinning.frag";
21 static char *VertProgFile = "skinning.vert";
22
23 /* program/shader objects */
24 static GLuint fragShader;
25 static GLuint vertShader;
26 static GLuint program;
27
28
29 static GLint win = 0;
30 static GLboolean Anim = GL_TRUE;
31 static GLboolean WireFrame = GL_TRUE;
32 static GLfloat xRot = 0.0f, yRot = 90.0f, zRot = 0.0f;
33
34 #define NUM_MATS 2
35
36 static GLfloat Matrices[NUM_MATS][16];
37 static GLint uMat0, uMat1;
38 static GLint WeightAttr;
39
40
41 static void
42 Idle(void)
43 {
44 yRot = 90 + glutGet(GLUT_ELAPSED_TIME) * 0.005;
45 glutPostRedisplay();
46 }
47
48
49 static void
50 Cylinder(GLfloat length, GLfloat radius, GLint slices, GLint stacks)
51 {
52 float dw = 1.0 / (stacks - 1);
53 float dz = length / stacks;
54 int i, j;
55
56 for (j = 0; j < stacks; j++) {
57 float w0 = j * dw;
58 float z0 = j * dz;
59
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);
67 glVertex3f(x, y, z0);
68
69 glVertexAttrib1f(WeightAttr, w0 + dw);
70 glNormal3f(x, y, 0.0);
71 glVertex3f(x, y, z0 + dz);
72 }
73 glEnd();
74 }
75 }
76
77
78 /**
79 * Update/animate the two matrices. One rotates, the other scales.
80 */
81 static void
82 UpdateMatrices(void)
83 {
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;
87
88 glPushMatrix();
89 glLoadIdentity();
90 glScalef(1.0, scale, 1.0);
91 glGetFloatv(GL_MODELVIEW_MATRIX, Matrices[0]);
92 glPopMatrix();
93
94 glPushMatrix();
95 glLoadIdentity();
96 glRotatef(rot, 0, 0, 1);
97 glGetFloatv(GL_MODELVIEW_MATRIX, Matrices[1]);
98 glPopMatrix();
99 }
100
101
102 static void
103 Redisplay(void)
104 {
105 UpdateMatrices();
106
107 glUniformMatrix4fv(uMat0, 1, GL_FALSE, Matrices[0]);
108 glUniformMatrix4fv(uMat1, 1, GL_FALSE, Matrices[1]);
109
110 if (WireFrame)
111 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
112 else
113 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
114
115 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
116
117 glPushMatrix();
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);
121
122 glPushMatrix();
123 glTranslatef(0, 0, -2.5);
124 Cylinder(5.0, 1.0, 10, 20);
125 glPopMatrix();
126
127 glPopMatrix();
128
129 glutSwapBuffers();
130 }
131
132
133 static void
134 Reshape(int width, int height)
135 {
136 glViewport(0, 0, width, height);
137 glMatrixMode(GL_PROJECTION);
138 glLoadIdentity();
139 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
140 glMatrixMode(GL_MODELVIEW);
141 glLoadIdentity();
142 glTranslatef(0.0f, 0.0f, -15.0f);
143 }
144
145
146 static void
147 CleanUp(void)
148 {
149 glDeleteShader(fragShader);
150 glDeleteShader(vertShader);
151 glDeleteProgram(program);
152 glutDestroyWindow(win);
153 }
154
155
156 static void
157 Key(unsigned char key, int x, int y)
158 {
159 const GLfloat step = 2.0;
160 (void) x;
161 (void) y;
162
163 switch(key) {
164 case 'a':
165 Anim = !Anim;
166 if (Anim)
167 glutIdleFunc(Idle);
168 else
169 glutIdleFunc(NULL);
170 break;
171 case 'w':
172 WireFrame = !WireFrame;
173 break;
174 case 'z':
175 zRot += step;
176 break;
177 case 'Z':
178 zRot -= step;
179 break;
180 case 27:
181 CleanUp();
182 exit(0);
183 break;
184 }
185 glutPostRedisplay();
186 }
187
188
189 static void
190 SpecialKey(int key, int x, int y)
191 {
192 const GLfloat step = 2.0;
193
194 (void) x;
195 (void) y;
196
197 switch(key) {
198 case GLUT_KEY_UP:
199 xRot += step;
200 break;
201 case GLUT_KEY_DOWN:
202 xRot -= step;
203 break;
204 case GLUT_KEY_LEFT:
205 yRot -= step;
206 break;
207 case GLUT_KEY_RIGHT:
208 yRot += step;
209 break;
210 }
211 glutPostRedisplay();
212 }
213
214
215
216 static void
217 Init(void)
218 {
219 if (!ShadersSupported())
220 exit(1);
221
222 vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
223 fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
224 program = LinkShaders(vertShader, fragShader);
225
226 glUseProgram(program);
227
228 uMat0 = glGetUniformLocation(program, "mat0");
229 uMat1 = glGetUniformLocation(program, "mat1");
230
231 WeightAttr = glGetAttribLocation(program, "weight");
232
233 assert(glGetError() == 0);
234
235 glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
236
237 glEnable(GL_DEPTH_TEST);
238
239 glColor3f(1, 0, 0);
240 }
241
242
243 static void
244 ParseOptions(int argc, char *argv[])
245 {
246 int i;
247 for (i = 1; i < argc; i++) {
248 if (strcmp(argv[i], "-fs") == 0) {
249 FragProgFile = argv[i+1];
250 }
251 else if (strcmp(argv[i], "-vs") == 0) {
252 VertProgFile = argv[i+1];
253 }
254 }
255 }
256
257
258 int
259 main(int argc, char *argv[])
260 {
261 glutInit(&argc, argv);
262 glutInitWindowSize(500, 500);
263 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
264 win = glutCreateWindow(argv[0]);
265 glewInit();
266 glutReshapeFunc(Reshape);
267 glutKeyboardFunc(Key);
268 glutSpecialFunc(SpecialKey);
269 glutDisplayFunc(Redisplay);
270 ParseOptions(argc, argv);
271 Init();
272 if (Anim)
273 glutIdleFunc(Idle);
274 glutMainLoop();
275 return 0;
276 }
277