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