2 * Test using a geometry shader to implement point sprites.
3 * XXX we should also demo point size attenuation.
15 #include "glut_wrap.h"
16 #include "shaderutil.h"
18 static GLint WinWidth
= 500, WinHeight
= 500;
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];
31 GLenum err
= glGetError();
33 printf("GL Error %s (0x%x) at line %d\n",
34 gluErrorString(err
), (int) err
, line
);
44 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
47 glRotatef(Xrot
, 1, 0, 0);
48 glRotatef(Yrot
, 0, 0, 1);
51 for (i
= 0; i
< NumPoints
; i
++) {
52 glVertex3fv(Points
[i
]);
65 int curTime
= glutGet(GLUT_ELAPSED_TIME
);
66 Xrot
= curTime
* 0.02;
67 Yrot
= curTime
* 0.05;
73 Reshape(int width
, int height
)
75 float ar
= (float) width
/ height
;
76 glViewport(0, 0, width
, height
);
77 glMatrixMode(GL_PROJECTION
);
79 glFrustum(-ar
, ar
, -1, 1, 3, 25);
80 glMatrixMode(GL_MODELVIEW
);
82 glTranslatef(0, 0, -10);
86 glGetFloatv(GL_VIEWPORT
, viewport
);
87 glUniform2f(uInverseViewportSize
, 1.0F
/ viewport
[2], 1.0F
/ viewport
[3]);
95 glDeleteShader(FragShader
);
96 glDeleteShader(VertShader
);
97 glDeleteShader(GeomShader
);
98 glDeleteProgram(Program
);
99 glutDestroyWindow(Win
);
104 Key(unsigned char key
, int x
, int y
)
132 GLubyte image
[TEX_SIZE
][TEX_SIZE
][3];
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
);
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);
149 image
[i
][j
][0] = 255;
150 image
[i
][j
][1] = 255;
151 image
[i
][j
][2] = 255;
161 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGB
, TEX_SIZE
, TEX_SIZE
, 0,
162 GL_RGB
, GL_UNSIGNED_BYTE
, image
);
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;
182 static const char *fragShaderText
=
183 "uniform sampler2D tex; \n"
186 " gl_FragColor = texture2D(tex, gl_TexCoord[0].xy); \n"
188 static const char *vertShaderText
=
191 " gl_FrontColor = gl_Color; \n"
192 " gl_Position = ftransform(); \n"
194 static const char *geomShaderText
=
196 "#extension GL_ARB_geometry_shader4: enable \n"
197 "uniform vec2 InverseViewportSize; \n"
198 "uniform float PointSize; \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"
207 " gl_TexCoord[0] = vec4(1, 0, 0, 1); \n"
208 " gl_Position = pos + vec4( d.x, -d.y, 0, 0); \n"
210 " gl_TexCoord[0] = vec4(0, 1, 0, 1); \n"
211 " gl_Position = pos + vec4(-d.x, d.y, 0, 0); \n"
213 " gl_TexCoord[0] = vec4(1, 1, 0, 1); \n"
214 " gl_Position = pos + vec4( d.x, d.y, 0, 0); \n"
218 if (!ShadersSupported())
221 if (!glutExtensionSupported("GL_ARB_geometry_shader4")) {
222 fprintf(stderr
, "Sorry, GL_ARB_geometry_shader4 is not supported.\n");
226 VertShader
= CompileShaderText(GL_VERTEX_SHADER
, vertShaderText
);
227 FragShader
= CompileShaderText(GL_FRAGMENT_SHADER
, fragShaderText
);
228 GeomShader
= CompileShaderText(GL_GEOMETRY_SHADER_ARB
, geomShaderText
);
231 Program
= LinkShaders3(VertShader
, GeomShader
, FragShader
);
233 CheckError(__LINE__
);
236 * The geometry shader will convert incoming points to quads (4-vertex
239 glProgramParameteriARB(Program
, GL_GEOMETRY_INPUT_TYPE_ARB
,
241 glProgramParameteriARB(Program
, GL_GEOMETRY_OUTPUT_TYPE_ARB
,
243 glProgramParameteriARB(Program
,GL_GEOMETRY_VERTICES_OUT_ARB
, 4);
244 CheckError(__LINE__
);
246 glLinkProgramARB(Program
);
251 GetProgramiv(Program
, GL_LINK_STATUS
, &stat
);
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
);
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]);
294 glutReshapeFunc(Reshape
);
295 glutKeyboardFunc(Key
);
296 glutDisplayFunc(Redisplay
);