blob: 46ef8043bcff7a72bcb3a207deb5372a4914d50c [file] [log] [blame]
Brian Paul538a8232009-04-17 16:23:33 -06001/**
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/gl.h>
13#include <GL/glut.h>
14#include <GL/glext.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 */
23static 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
35static const char *FragShaderText =
36 "void main() \n"
37 "{ \n"
38 " gl_FragColor = gl_Color; \n"
39 "} \n";
40
41
42static GLuint fragShader;
43static GLuint vertShader;
44static GLuint program;
45
46static GLint win = 0;
47static GLboolean Anim = GL_TRUE;
48static GLboolean WireFrame = GL_TRUE;
49static GLfloat xRot = -70.0f, yRot = 0.0f, zRot = 0.0f;
50
51
52static void
53Idle(void)
54{
55 zRot = 90 + glutGet(GLUT_ELAPSED_TIME) * 0.05;
56 glutPostRedisplay();
57}
58
59
60/** z=f(x,y) */
61static float
62fz(float x, float y)
63{
64 return fabs(cos(1.5*x) + cos(1.5*y));
65}
66
67
68static void
69DrawMesh(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
104static void
105Redisplay(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
131static void
132Reshape(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
144static void
145CleanUp(void)
146{
147 glDeleteShader_func(fragShader);
148 glDeleteShader_func(vertShader);
149 glDeleteProgram_func(program);
150 glutDestroyWindow(win);
151}
152
153
154static void
155Key(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
187static void
188SpecialKey(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
213static void
214Init(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
244int
245main(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 glutReshapeFunc(Reshape);
252 glutKeyboardFunc(Key);
253 glutSpecialFunc(SpecialKey);
254 glutDisplayFunc(Redisplay);
255 Init();
256 if (Anim)
257 glutIdleFunc(Idle);
258 glutMainLoop();
259 return 0;
260}
261