2 * Test mipmap generation and lod bias.
19 #define TEXTURE_FILE "../images/arch.rgb"
22 #define SIZE (1<<LEVELS)
23 static int TexWidth
= SIZE
, TexHeight
= SIZE
;
24 static int WinWidth
= 1044, WinHeight
= 900;
25 static GLfloat Bias
= 0.0;
26 static GLboolean ScaleQuads
= GL_FALSE
;
27 static GLboolean Linear
= GL_FALSE
;
29 static GLint RenderTextureLevel
= 0;
37 GLenum err
= glGetError();
39 printf("GL Error 0x%x at line %d\n", (int) err
, line
);
46 PrintString(const char *s
)
49 glutBitmapCharacter(GLUT_BITMAP_8_BY_13
, (int) *s
);
60 /* test auto mipmap generation */
61 GLint width
, height
, i
;
63 GLubyte
*image
= LoadRGBImage(TEXTURE_FILE
, &width
, &height
, &format
);
65 printf("Error: could not load texture image %s\n", TEXTURE_FILE
);
68 /* resize to TexWidth x TexHeight */
69 if (width
!= TexWidth
|| height
!= TexHeight
) {
70 GLubyte
*newImage
= malloc(TexWidth
* TexHeight
* 4);
72 fprintf(stderr
, "rescale %d %d to %d %d\n", width
, height
,
76 gluScaleImage(format
, width
, height
, GL_UNSIGNED_BYTE
, image
,
77 TexWidth
, TexHeight
, GL_UNSIGNED_BYTE
, newImage
);
81 printf("Using GL_SGIS_generate_mipmap\n");
82 glTexParameteri(GL_TEXTURE_2D
, GL_GENERATE_MIPMAP_SGIS
, GL_TRUE
);
83 glTexImage2D(GL_TEXTURE_2D
, 0, format
, TexWidth
, TexHeight
, 0,
84 format
, GL_UNSIGNED_BYTE
, image
);
87 /* make sure mipmap was really generated correctly */
90 for (i
= 0; i
< 9; i
++) {
92 glGetTexLevelParameteriv(GL_TEXTURE_2D
, i
, GL_TEXTURE_WIDTH
, &w
);
93 glGetTexLevelParameteriv(GL_TEXTURE_2D
, i
, GL_TEXTURE_HEIGHT
, &h
);
94 printf("Level %d size: %d x %d\n", i
, w
, h
);
102 glTexParameteri(GL_TEXTURE_2D
, GL_GENERATE_MIPMAP_SGIS
, GL_FALSE
);
108 ResetTextureLevel( int i
)
110 GLubyte tex2d
[SIZE
*SIZE
][4];
113 GLint Width
= TexWidth
/ (1 << i
);
114 GLint Height
= TexHeight
/ (1 << i
);
117 for (s
= 0; s
< Width
; s
++) {
118 for (t
= 0; t
< Height
; t
++) {
119 tex2d
[t
*Width
+s
][0] = ((s
/ 16) % 2) ? 0 : 255;
120 tex2d
[t
*Width
+s
][1] = ((t
/ 16) % 2) ? 0 : 255;
121 tex2d
[t
*Width
+s
][2] = 128;
122 tex2d
[t
*Width
+s
][3] = 255;
126 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
128 glTexImage2D(GL_TEXTURE_2D
, i
, GL_RGB
, Width
, Height
, 0,
129 GL_RGBA
, GL_UNSIGNED_BYTE
, tex2d
);
138 /* This doesn't work so well as the arch texture is 512x512.
140 LoadRGBMipmaps(TEXTURE_FILE
, GL_RGB
);
145 for (i
= 0; i
<= LEVELS
; i
++)
147 ResetTextureLevel(i
);
160 RenderTexture( void )
165 fprintf(stderr
, "RenderTextureLevel %d\n", RenderTextureLevel
);
168 /* gen framebuffer id, delete it, do some assertions, just for testing */
169 glGenFramebuffersEXT(1, &MyFB
);
170 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, MyFB
);
171 assert(glIsFramebufferEXT(MyFB
));
173 CheckError(__LINE__
);
175 /* Render color to texture */
176 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT
,
177 GL_COLOR_ATTACHMENT0_EXT
,
178 GL_TEXTURE_2D
, TexObj
,
183 CheckError(__LINE__
);
186 glMatrixMode(GL_PROJECTION
);
188 glOrtho(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
189 glMatrixMode(GL_MODELVIEW
);
191 glTranslatef(0.0, 0.0, -15.0);
193 status
= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT
);
194 if (status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
195 printf("Framebuffer incomplete!!!\n");
199 TexWidth
/ (1 << RenderTextureLevel
),
200 TexHeight
/ (1 << RenderTextureLevel
));
202 glClearColor(0.5, 0.5, 1.0, 0.0);
203 glClear(GL_COLOR_BUFFER_BIT
);
205 CheckError(__LINE__
);
217 /* Bind normal framebuffer */
218 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, 0);
219 CheckError(__LINE__
);
221 glDeleteFramebuffersEXT(1, &MyFB
);
222 CheckError(__LINE__
);
224 glClearColor(0, 0, 0, 0);
232 int texWidth
= TexWidth
, texHeight
= TexHeight
;
234 glViewport(0, 0, WinHeight
, WinHeight
);
236 glClear(GL_COLOR_BUFFER_BIT
);
238 glMatrixMode(GL_PROJECTION
);
240 glOrtho(0, WinWidth
, 0, WinHeight
, -1, 1);
241 glMatrixMode(GL_MODELVIEW
);
247 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR_MIPMAP_LINEAR
);
248 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
251 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST_MIPMAP_NEAREST
);
252 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
258 for (bias
= -1; bias
< 11; bias
++) {
262 if (texWidth
== 1 && texHeight
== 1)
264 texWidth
= TexWidth
>> bias
;
265 texHeight
= TexHeight
>> bias
;
271 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT
, GL_TEXTURE_LOD_BIAS_EXT
, 0.0);
274 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT
, GL_TEXTURE_LOD_BIAS_EXT
, bias
);
277 glRasterPos2f(x
, y
+ TexHeight
+ 5);
279 sprintf(str
, "Texture Level %d: %d x %d",
280 (bias
< 0 ? 0 : bias
),
281 texWidth
, texHeight
);
283 sprintf(str
, "Texture LOD Bias = %d", bias
);
287 glTranslatef(x
, y
, 0);
289 glEnable(GL_TEXTURE_2D
);
292 glTexCoord2f(0, 0); glVertex2f(0, 0);
293 glTexCoord2f(1, 0); glVertex2f(texWidth
, 0);
294 glTexCoord2f(1, 1); glVertex2f(texWidth
, texHeight
);
295 glTexCoord2f(0, 1); glVertex2f(0, texHeight
);
300 glDisable(GL_TEXTURE_2D
);
314 Reshape(int width
, int height
)
322 Key(unsigned char key
, int x
, int y
)
337 RenderTextureLevel
++;
340 RenderTextureLevel
--;
349 ResetTextureLevel(RenderTextureLevel
);
361 Bias
= 100.0 * (key
- '0');
364 ScaleQuads
= !ScaleQuads
;
370 RenderTextureLevel
= 0;
375 glutDestroyWindow(Win
);
388 if (!glutExtensionSupported("GL_EXT_texture_lod_bias")) {
389 printf("Sorry, GL_EXT_texture_lod_bias not supported by this renderer.\n");
393 if (!glutExtensionSupported("GL_SGIS_generate_mipmap")) {
394 printf("Sorry, GL_SGIS_generate_mipmap not supported by this renderer.\n");
398 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
400 glGenTextures(1, &TexObj
);
401 glBindTexture(GL_TEXTURE_2D
, TexObj
);
408 /* mipmapping required for this extension */
409 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
411 glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS_EXT
, &maxBias
);
413 printf("GL_RENDERER: %s\n", (char*) glGetString(GL_RENDERER
));
414 printf("LOD bias range: [%g, %g]\n", -maxBias
, maxBias
);
416 printf("Press 's' to toggle quad scaling\n");
421 main(int argc
, char *argv
[])
423 glutInit(&argc
, argv
);
424 glutInitWindowPosition(0, 0);
425 glutInitWindowSize(WinWidth
, WinHeight
);
426 glutInitDisplayMode(GLUT_RGB
| GLUT_DOUBLE
);
427 Win
= glutCreateWindow(argv
[0]);
429 glutReshapeFunc(Reshape
);
430 glutKeyboardFunc(Key
);
431 glutDisplayFunc(Display
);