Revert "wglgears: show stereo-option in usage"
[mesa-demos.git] / src / glsl / geom-sprites.c
blob168d75673fdc03b48b685c35d339c1c25e4d1a6c
1 /**
2 * Test using a geometry shader to implement point sprites.
3 * XXX we should also demo point size attenuation.
5 * Brian Paul
6 * March 2011
7 */
9 #include <assert.h>
10 #include <string.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <math.h>
14 #include <GL/glew.h>
15 #include "glut_wrap.h"
16 #include "shaderutil.h"
18 static GLint WinWidth = 500, WinHeight = 500;
19 static GLint Win = 0;
20 static GLuint VertShader, GeomShader, FragShader, Program;
21 static GLboolean Anim = GL_TRUE;
22 static GLfloat Xrot = 0, Yrot = 0;
23 static int uPointSize = -1, uInverseViewportSize = -1;
25 static const int NumPoints = 50;
26 static float Points[100][3];
28 static void
29 CheckError(int line)
31 GLenum err = glGetError();
32 if (err) {
33 printf("GL Error %s (0x%x) at line %d\n",
34 gluErrorString(err), (int) err, line);
39 static void
40 Redisplay(void)
42 int i;
44 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
46 glPushMatrix();
47 glRotatef(Xrot, 1, 0, 0);
48 glRotatef(Yrot, 0, 0, 1);
50 glBegin(GL_POINTS);
51 for (i = 0; i < NumPoints; i++) {
52 glVertex3fv(Points[i]);
54 glEnd();
56 glPopMatrix();
58 glutSwapBuffers();
62 static void
63 Idle(void)
65 int curTime = glutGet(GLUT_ELAPSED_TIME);
66 Xrot = curTime * 0.02;
67 Yrot = curTime * 0.05;
68 glutPostRedisplay();
72 static void
73 Reshape(int width, int height)
75 float ar = (float) width / height;
76 glViewport(0, 0, width, height);
77 glMatrixMode(GL_PROJECTION);
78 glLoadIdentity();
79 glFrustum(-ar, ar, -1, 1, 3, 25);
80 glMatrixMode(GL_MODELVIEW);
81 glLoadIdentity();
82 glTranslatef(0, 0, -10);
85 GLfloat viewport[4];
86 glGetFloatv(GL_VIEWPORT, viewport);
87 glUniform2f(uInverseViewportSize, 1.0F / viewport[2], 1.0F / viewport[3]);
92 static void
93 CleanUp(void)
95 glDeleteShader(FragShader);
96 glDeleteShader(VertShader);
97 glDeleteShader(GeomShader);
98 glDeleteProgram(Program);
99 glutDestroyWindow(Win);
103 static void
104 Key(unsigned char key, int x, int y)
106 (void) x;
107 (void) y;
109 switch(key) {
110 case ' ':
111 case 'a':
112 Anim = !Anim;
113 if (Anim) {
114 glutIdleFunc(Idle);
116 else
117 glutIdleFunc(NULL);
118 break;
119 case 27:
120 CleanUp();
121 exit(0);
122 break;
124 glutPostRedisplay();
128 static GLuint
129 MakeTexture(void)
131 #define TEX_SIZE 32
132 GLubyte image[TEX_SIZE][TEX_SIZE][3];
133 GLuint i, j;
134 GLuint tex;
136 glGenTextures(1, &tex);
137 glBindTexture(GL_TEXTURE_2D, tex);
139 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
140 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
142 /* 'X' pattern */
143 for (i = 0; i < TEX_SIZE; i++) {
144 for (j = 0; j < TEX_SIZE; j++) {
145 int p1 = i - j, p2 = TEX_SIZE - 1 - i - j;
146 p1 = (p1 >= -2 && p1 <= 2);
147 p2 = (p2 >= -2 && p2 <= 2);
148 if (p1 || p2) {
149 image[i][j][0] = 255;
150 image[i][j][1] = 255;
151 image[i][j][2] = 255;
153 else {
154 image[i][j][0] = 50;
155 image[i][j][1] = 50;
156 image[i][j][2] = 50;
161 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEX_SIZE, TEX_SIZE, 0,
162 GL_RGB, GL_UNSIGNED_BYTE, image);
164 return tex;
168 static void
169 MakePoints(void)
171 int i;
172 for (i = 0; i < NumPoints; i++) {
173 Points[i][0] = ((rand() % 2000) - 1000.0) / 500.0;
174 Points[i][1] = ((rand() % 2000) - 1000.0) / 500.0;
175 Points[i][2] = ((rand() % 2000) - 1000.0) / 500.0;
179 static void
180 Init(void)
182 static const char *fragShaderText =
183 "uniform sampler2D tex; \n"
184 "void main() \n"
185 "{ \n"
186 " gl_FragColor = texture2D(tex, gl_TexCoord[0].xy); \n"
187 "} \n";
188 static const char *vertShaderText =
189 "void main() \n"
190 "{ \n"
191 " gl_FrontColor = gl_Color; \n"
192 " gl_Position = ftransform(); \n"
193 "} \n";
194 static const char *geomShaderText =
195 "#version 120 \n"
196 "#extension GL_ARB_geometry_shader4: enable \n"
197 "uniform vec2 InverseViewportSize; \n"
198 "uniform float PointSize; \n"
199 "void main() \n"
200 "{ \n"
201 " vec4 pos = gl_PositionIn[0]; \n"
202 " vec2 d = vec2(PointSize * pos.w) * InverseViewportSize; \n"
203 " gl_FrontColor = gl_FrontColorIn[0]; \n"
204 " gl_TexCoord[0] = vec4(0, 0, 0, 1); \n"
205 " gl_Position = pos + vec4(-d.x, -d.y, 0, 0); \n"
206 " EmitVertex(); \n"
207 " gl_TexCoord[0] = vec4(1, 0, 0, 1); \n"
208 " gl_Position = pos + vec4( d.x, -d.y, 0, 0); \n"
209 " EmitVertex(); \n"
210 " gl_TexCoord[0] = vec4(0, 1, 0, 1); \n"
211 " gl_Position = pos + vec4(-d.x, d.y, 0, 0); \n"
212 " EmitVertex(); \n"
213 " gl_TexCoord[0] = vec4(1, 1, 0, 1); \n"
214 " gl_Position = pos + vec4( d.x, d.y, 0, 0); \n"
215 " EmitVertex(); \n"
216 "} \n";
218 if (!ShadersSupported())
219 exit(1);
221 if (!glutExtensionSupported("GL_ARB_geometry_shader4")) {
222 fprintf(stderr, "Sorry, GL_ARB_geometry_shader4 is not supported.\n");
223 exit(1);
226 VertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
227 FragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
228 GeomShader = CompileShaderText(GL_GEOMETRY_SHADER_ARB, geomShaderText);
229 assert(GeomShader);
231 Program = LinkShaders3(VertShader, GeomShader, FragShader);
232 assert(Program);
233 CheckError(__LINE__);
236 * The geometry shader will convert incoming points to quads (4-vertex
237 * triangle strips).
239 glProgramParameteriARB(Program, GL_GEOMETRY_INPUT_TYPE_ARB,
240 GL_POINTS);
241 glProgramParameteriARB(Program, GL_GEOMETRY_OUTPUT_TYPE_ARB,
242 GL_TRIANGLE_STRIP);
243 glProgramParameteriARB(Program,GL_GEOMETRY_VERTICES_OUT_ARB, 4);
244 CheckError(__LINE__);
246 glLinkProgramARB(Program);
248 /* check link */
250 GLint stat;
251 GetProgramiv(Program, GL_LINK_STATUS, &stat);
252 if (!stat) {
253 GLchar log[1000];
254 GLsizei len;
255 GetProgramInfoLog(Program, 1000, &len, log);
256 fprintf(stderr, "Shader link error:\n%s\n", log);
260 CheckError(__LINE__);
262 glUseProgram(Program);
263 CheckError(__LINE__);
265 uInverseViewportSize = glGetUniformLocation(Program, "InverseViewportSize");
266 uPointSize = glGetUniformLocation(Program, "PointSize");
268 glUniform1f(uPointSize, 24.0);
270 glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
272 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
274 assert(glIsProgram(Program));
275 assert(glIsShader(FragShader));
276 assert(glIsShader(VertShader));
277 assert(glIsShader(GeomShader));
279 glEnable(GL_DEPTH_TEST);
281 MakeTexture();
282 MakePoints();
287 main(int argc, char *argv[])
289 glutInit(&argc, argv);
290 glutInitWindowSize(WinWidth, WinHeight);
291 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
292 Win = glutCreateWindow(argv[0]);
293 glewInit();
294 glutReshapeFunc(Reshape);
295 glutKeyboardFunc(Key);
296 glutDisplayFunc(Redisplay);
297 if (Anim)
298 glutIdleFunc(Idle);
300 Init();
301 glutMainLoop();
302 return 0;