Merge branch 'mesa_7_5_branch'
[mesa.git] / progs / glsl / array.c
1 /**
2 * Test variable array indexing in a vertex shader.
3 * Brian Paul
4 * 17 April 2009
5 */
6
7 #include <assert.h>
8 #include <string.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <math.h>
12 #include <GL/glew.h>
13 #include <GL/gl.h>
14 #include <GL/glut.h>
15 #include "extfuncs.h"
16 #include "shaderutil.h"
17
18
19 /**
20 * The vertex position.z is used as a (variable) index into an
21 * array which returns a new Z value.
22 */
23 static const char *VertShaderText =
24 "uniform sampler2D tex1; \n"
25 "uniform float HeightArray[20]; \n"
26 "void main() \n"
27 "{ \n"
28 " vec4 pos = gl_Vertex; \n"
29 " int i = int(pos.z * 9.5); \n"
30 " pos.z = HeightArray[i]; \n"
31 " gl_Position = gl_ModelViewProjectionMatrix * pos; \n"
32 " gl_FrontColor = pos; \n"
33 "} \n";
34
35 static const char *FragShaderText =
36 "void main() \n"
37 "{ \n"
38 " gl_FragColor = gl_Color; \n"
39 "} \n";
40
41
42 static GLuint fragShader;
43 static GLuint vertShader;
44 static GLuint program;
45
46 static GLint win = 0;
47 static GLboolean Anim = GL_TRUE;
48 static GLboolean WireFrame = GL_TRUE;
49 static GLfloat xRot = -70.0f, yRot = 0.0f, zRot = 0.0f;
50
51
52 static void
53 Idle(void)
54 {
55 zRot = 90 + glutGet(GLUT_ELAPSED_TIME) * 0.05;
56 glutPostRedisplay();
57 }
58
59
60 /** z=f(x,y) */
61 static float
62 fz(float x, float y)
63 {
64 return fabs(cos(1.5*x) + cos(1.5*y));
65 }
66
67
68 static void
69 DrawMesh(void)
70 {
71 GLfloat xmin = -2.0, xmax = 2.0;
72 GLfloat ymin = -2.0, ymax = 2.0;
73 GLuint xdivs = 20, ydivs = 20;
74 GLfloat dx = (xmax - xmin) / xdivs;
75 GLfloat dy = (ymax - ymin) / ydivs;
76 GLfloat ds = 1.0 / xdivs, dt = 1.0 / ydivs;
77 GLfloat x, y, s, t;
78 GLuint i, j;
79
80 y = ymin;
81 t = 0.0;
82 for (i = 0; i < ydivs; i++) {
83 x = xmin;
84 s = 0.0;
85 glBegin(GL_QUAD_STRIP);
86 for (j = 0; j < xdivs; j++) {
87 float z0 = fz(x, y), z1 = fz(x, y + dy);
88
89 glTexCoord2f(s, t);
90 glVertex3f(x, y, z0);
91
92 glTexCoord2f(s, t + dt);
93 glVertex3f(x, y + dy, z1);
94 x += dx;
95 s += ds;
96 }
97 glEnd();
98 y += dy;
99 t += dt;
100 }
101 }
102
103
104 static void
105 Redisplay(void)
106 {
107 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
108
109 if (WireFrame)
110 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
111 else
112 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
113
114 glPushMatrix();
115 glRotatef(xRot, 1.0f, 0.0f, 0.0f);
116 glRotatef(yRot, 0.0f, 1.0f, 0.0f);
117 glRotatef(zRot, 0.0f, 0.0f, 1.0f);
118
119 glPushMatrix();
120 DrawMesh();
121 glPopMatrix();
122
123 glPopMatrix();
124
125 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
126
127 glutSwapBuffers();
128 }
129
130
131 static void
132 Reshape(int width, int height)
133 {
134 glViewport(0, 0, width, height);
135 glMatrixMode(GL_PROJECTION);
136 glLoadIdentity();
137 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
138 glMatrixMode(GL_MODELVIEW);
139 glLoadIdentity();
140 glTranslatef(0.0f, 0.0f, -15.0f);
141 }
142
143
144 static void
145 CleanUp(void)
146 {
147 glDeleteShader_func(fragShader);
148 glDeleteShader_func(vertShader);
149 glDeleteProgram_func(program);
150 glutDestroyWindow(win);
151 }
152
153
154 static void
155 Key(unsigned char key, int x, int y)
156 {
157 const GLfloat step = 2.0;
158 (void) x;
159 (void) y;
160
161 switch(key) {
162 case 'a':
163 Anim = !Anim;
164 if (Anim)
165 glutIdleFunc(Idle);
166 else
167 glutIdleFunc(NULL);
168 break;
169 case 'w':
170 WireFrame = !WireFrame;
171 break;
172 case 'z':
173 zRot += step;
174 break;
175 case 'Z':
176 zRot -= step;
177 break;
178 case 27:
179 CleanUp();
180 exit(0);
181 break;
182 }
183 glutPostRedisplay();
184 }
185
186
187 static void
188 SpecialKey(int key, int x, int y)
189 {
190 const GLfloat step = 2.0;
191
192 (void) x;
193 (void) y;
194
195 switch(key) {
196 case GLUT_KEY_UP:
197 xRot += step;
198 break;
199 case GLUT_KEY_DOWN:
200 xRot -= step;
201 break;
202 case GLUT_KEY_LEFT:
203 yRot -= step;
204 break;
205 case GLUT_KEY_RIGHT:
206 yRot += step;
207 break;
208 }
209 glutPostRedisplay();
210 }
211
212
213 static void
214 Init(void)
215 {
216 GLfloat HeightArray[20];
217 GLint u, i;
218
219 if (!ShadersSupported())
220 exit(1);
221
222 GetExtensionFuncs();
223
224 vertShader = CompileShaderText(GL_VERTEX_SHADER, VertShaderText);
225 fragShader = CompileShaderText(GL_FRAGMENT_SHADER, FragShaderText);
226 program = LinkShaders(vertShader, fragShader);
227
228 glUseProgram_func(program);
229
230 /* Setup the HeightArray[] uniform */
231 for (i = 0; i < 20; i++)
232 HeightArray[i] = i / 20.0;
233 u = glGetUniformLocation_func(program, "HeightArray");
234 glUniform1fv_func(u, 20, HeightArray);
235
236 assert(glGetError() == 0);
237
238 glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
239 glEnable(GL_DEPTH_TEST);
240 glColor3f(1, 1, 1);
241 }
242
243
244 int
245 main(int argc, char *argv[])
246 {
247 glutInit(&argc, argv);
248 glutInitWindowSize(500, 500);
249 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
250 win = glutCreateWindow(argv[0]);
251 glewInit();
252 glutReshapeFunc(Reshape);
253 glutKeyboardFunc(Key);
254 glutSpecialFunc(SpecialKey);
255 glutDisplayFunc(Redisplay);
256 Init();
257 if (Anim)
258 glutIdleFunc(Idle);
259 glutMainLoop();
260 return 0;
261 }
262