2 * Exercise all available GLSL texture samplers.
4 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 * We generate a fragment shader which uses the maximum number of supported
27 * For each sampler we create a separate texture. Each texture has a
28 * single strip of color at a different intensity. The fragment shader
29 * samples all the textures at the same coordinate and sums the values.
30 * The result should be a quad with rows of colors of increasing intensity
42 #include <glad/glad.h>
43 #include "glut_wrap.h"
44 #include "shaderutil.h"
47 #define MAX_SAMPLERS 128
50 static const char *Demo
= "samplers";
52 static GLuint Program
;
53 static GLint NumSamplers
;
54 static GLuint Textures
[MAX_SAMPLERS
];
55 static GLfloat Xrot
= 0.0, Yrot
= .0, Zrot
= 0.0;
56 static GLfloat EyeDist
= 10;
57 static GLboolean Anim
= GL_FALSE
;
61 DrawPolygon(GLfloat size
)
67 glMultiTexCoord2f(GL_TEXTURE0
, 0, 0);
68 glVertex2f(-size
, -size
);
70 glMultiTexCoord2f(GL_TEXTURE0
, 1, 0);
71 glVertex2f( size
, -size
);
73 glMultiTexCoord2f(GL_TEXTURE0
, 1, 1);
74 glVertex2f( size
, size
);
76 glMultiTexCoord2f(GL_TEXTURE0
, 0, 1);
77 glVertex2f(-size
, size
);
87 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
90 glTranslatef(0.0, 0.0, -EyeDist
);
91 glRotatef(Zrot
, 0, 0, 1);
92 glRotatef(Yrot
, 0, 1, 0);
93 glRotatef(Xrot
, 1, 0, 0);
106 GLfloat t
= 0.05 * glutGet(GLUT_ELAPSED_TIME
);
113 key(unsigned char k
, int x
, int y
)
144 specialkey(int key
, int x
, int y
)
167 /* new window size or exposure */
169 Reshape(int width
, int height
)
171 GLfloat ar
= (float) width
/ (float) height
;
172 glViewport(0, 0, (GLint
)width
, (GLint
)height
);
173 glMatrixMode(GL_PROJECTION
);
175 glFrustum(-2.0*ar
, 2.0*ar
, -2.0, 2.0, 4.0, 100.0);
176 glMatrixMode(GL_MODELVIEW
);
184 const GLint size
= MAX_SAMPLERS
;
186 GLenum filter
= GL_NEAREST
;
190 texImage
= (GLubyte
*) malloc(size
* size
* 4);
192 glGenTextures(NumSamplers
, Textures
);
194 /* size of texels stripe */
195 stripeSize
= size
/ NumSamplers
;
197 /* create a texture for each sampler */
198 for (s
= 0; s
< NumSamplers
; s
++) {
200 GLubyte intensity
= 31 + s
* (256-32) / (NumSamplers
- 1);
202 printf("Texture %d: color = %d, %d, %d\n", s
,
203 (int) intensity
, 0, (int) intensity
);
205 /* initialize the texture to black */
206 memset(texImage
, 0, size
* size
* 4);
208 /* set a stripe of texels to the intensity value */
209 ypos
= s
* stripeSize
;
210 for (y
= 0; y
< stripeSize
; y
++) {
211 for (x
= 0; x
< size
; x
++) {
212 GLint k
= 4 * ((ypos
+ y
) * size
+ x
);
214 texImage
[k
+ 0] = intensity
;
215 texImage
[k
+ 1] = intensity
;
217 texImage
[k
+ 3] = 255;
220 texImage
[k
+ 0] = 255 - intensity
;
223 texImage
[k
+ 3] = 255;
228 glActiveTexture(GL_TEXTURE0
+ s
);
229 glBindTexture(GL_TEXTURE_2D
, Textures
[s
]);
230 gluBuild2DMipmaps(GL_TEXTURE_2D
, 4, size
, size
,
231 GL_RGBA
, GL_UNSIGNED_BYTE
, texImage
);
233 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_REPEAT
);
234 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_REPEAT
);
235 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, filter
);
236 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, filter
);
244 * Generate a fragment shader that uses the given number of samplers.
247 GenFragmentShader(GLint numSamplers
)
249 const int maxLen
= 10 * 1000;
250 char *prog
= (char *) malloc(maxLen
);
254 p
+= sprintf(p
, "// Generated fragment shader:\n");
255 #ifndef SAMPLERS_ARRAY
256 for (s
= 0; s
< numSamplers
; s
++) {
257 p
+= sprintf(p
, "uniform sampler2D tex%d;\n", s
);
260 p
+= sprintf(p
, "uniform sampler2D tex[%d];\n", numSamplers
);
262 p
+= sprintf(p
, "void main()\n");
263 p
+= sprintf(p
, "{\n");
264 p
+= sprintf(p
, " vec4 color = vec4(0.0);\n");
265 for (s
= 0; s
< numSamplers
; s
++) {
266 #ifndef SAMPLERS_ARRAY
267 p
+= sprintf(p
, " color += texture2D(tex%d, gl_TexCoord[0].xy);\n", s
);
269 p
+= sprintf(p
, " color += texture2D(tex[%d], gl_TexCoord[0].xy);\n", s
);
272 p
+= sprintf(p
, " gl_FragColor = color;\n");
273 p
+= sprintf(p
, "}\n");
275 assert(p
- prog
< maxLen
);
280 /** Create & bind shader program */
284 GLuint fragShader
, vertShader
, program
;
285 const char *vertShaderText
=
288 " gl_TexCoord[0] = gl_MultiTexCoord0; \n"
289 " gl_Position = ftransform(); \n"
291 char *fragShaderText
= GenFragmentShader(NumSamplers
);
293 printf("%s", fragShaderText
);
295 vertShader
= CompileShaderText(GL_VERTEX_SHADER
, vertShaderText
);
296 fragShader
= CompileShaderText(GL_FRAGMENT_SHADER
, fragShaderText
);
298 program
= LinkShaders(vertShader
, fragShader
);
300 glUseProgram(program
);
302 free(fragShaderText
);
313 Program
= CreateAProgram();
315 /* init sampler uniforms */
316 for (s
= 0; s
< NumSamplers
; s
++) {
320 #ifndef SAMPLERS_ARRAY
321 sprintf(uname
, "tex%d", s
);
323 sprintf(uname
, "tex[%d]", s
);
325 loc
= glGetUniformLocation(Program
, uname
);
336 if (!ShadersSupported()) {
337 printf("GLSL not supported!\n");
341 printf("GL_RENDERER = %s\n", (const char *) glGetString(GL_RENDERER
));
343 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS
, &NumSamplers
);
344 if (NumSamplers
> MAX_SAMPLERS
)
345 NumSamplers
= MAX_SAMPLERS
;
346 printf("Testing %d samplers\n", NumSamplers
);
351 glClearColor(.6, .6, .9, 0);
352 glColor3f(1.0, 1.0, 1.0);
354 printf("Each color corresponds to a separate sampler/texture.\n");
359 main(int argc
, char *argv
[])
361 glutInit(&argc
, argv
);
362 glutInitWindowSize(500, 400);
363 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
364 glutCreateWindow(Demo
);
366 glutReshapeFunc(Reshape
);
367 glutKeyboardFunc(key
);
368 glutSpecialFunc(specialkey
);
369 glutDisplayFunc(draw
);