2 * Test mipmap generation and lod bias.
18 #define TEXTURE_FILE "../images/arch.rgb"
21 #define SIZE (1<<LEVELS)
22 static int TexWidth
= SIZE
, TexHeight
= SIZE
;
23 static int WinWidth
= 1044, WinHeight
= 900;
24 static GLfloat Bias
= 0.0;
25 static GLboolean ScaleQuads
= GL_FALSE
;
26 static GLboolean Linear
= GL_FALSE
;
28 static GLint RenderTextureLevel
= 0;
36 GLenum err
= glGetError();
38 printf("GL Error 0x%x at line %d\n", (int) err
, line
);
45 PrintString(const char *s
)
48 glutBitmapCharacter(GLUT_BITMAP_8_BY_13
, (int) *s
);
59 /* test auto mipmap generation */
60 GLint width
, height
, i
;
62 GLubyte
*image
= LoadRGBImage(TEXTURE_FILE
, &width
, &height
, &format
);
64 printf("Error: could not load texture image %s\n", TEXTURE_FILE
);
67 /* resize to TexWidth x TexHeight */
68 if (width
!= TexWidth
|| height
!= TexHeight
) {
69 GLubyte
*newImage
= malloc(TexWidth
* TexHeight
* 4);
71 fprintf(stderr
, "rescale %d %d to %d %d\n", width
, height
,
75 gluScaleImage(format
, width
, height
, GL_UNSIGNED_BYTE
, image
,
76 TexWidth
, TexHeight
, GL_UNSIGNED_BYTE
, newImage
);
80 printf("Using GL_SGIS_generate_mipmap\n");
81 glTexParameteri(GL_TEXTURE_2D
, GL_GENERATE_MIPMAP_SGIS
, GL_TRUE
);
82 glTexImage2D(GL_TEXTURE_2D
, 0, format
, TexWidth
, TexHeight
, 0,
83 format
, GL_UNSIGNED_BYTE
, image
);
86 /* make sure mipmap was really generated correctly */
89 for (i
= 0; i
< 9; i
++) {
91 glGetTexLevelParameteriv(GL_TEXTURE_2D
, i
, GL_TEXTURE_WIDTH
, &w
);
92 glGetTexLevelParameteriv(GL_TEXTURE_2D
, i
, GL_TEXTURE_HEIGHT
, &h
);
93 printf("Level %d size: %d x %d\n", i
, w
, h
);
101 glTexParameteri(GL_TEXTURE_2D
, GL_GENERATE_MIPMAP_SGIS
, GL_FALSE
);
107 ResetTextureLevel( int i
)
109 GLubyte tex2d
[SIZE
*SIZE
][4];
112 GLint Width
= TexWidth
/ (1 << i
);
113 GLint Height
= TexHeight
/ (1 << i
);
116 for (s
= 0; s
< Width
; s
++) {
117 for (t
= 0; t
< Height
; t
++) {
118 tex2d
[t
*Width
+s
][0] = ((s
/ 16) % 2) ? 0 : 255;
119 tex2d
[t
*Width
+s
][1] = ((t
/ 16) % 2) ? 0 : 255;
120 tex2d
[t
*Width
+s
][2] = 128;
121 tex2d
[t
*Width
+s
][3] = 255;
125 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
127 glTexImage2D(GL_TEXTURE_2D
, i
, GL_RGB
, Width
, Height
, 0,
128 GL_RGBA
, GL_UNSIGNED_BYTE
, tex2d
);
137 /* This doesn't work so well as the arch texture is 512x512.
139 LoadRGBMipmaps(TEXTURE_FILE
, GL_RGB
);
144 for (i
= 0; i
<= LEVELS
; i
++)
146 ResetTextureLevel(i
);
159 RenderTexture( void )
164 fprintf(stderr
, "RenderTextureLevel %d\n", RenderTextureLevel
);
167 /* gen framebuffer id, delete it, do some assertions, just for testing */
168 glGenFramebuffersEXT(1, &MyFB
);
169 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, MyFB
);
170 assert(glIsFramebufferEXT(MyFB
));
172 CheckError(__LINE__
);
174 /* Render color to texture */
175 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT
,
176 GL_COLOR_ATTACHMENT0_EXT
,
177 GL_TEXTURE_2D
, TexObj
,
182 CheckError(__LINE__
);
185 glMatrixMode(GL_PROJECTION
);
187 glOrtho(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
188 glMatrixMode(GL_MODELVIEW
);
190 glTranslatef(0.0, 0.0, -15.0);
192 status
= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT
);
193 if (status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
194 printf("Framebuffer incomplete!!!\n");
198 TexWidth
/ (1 << RenderTextureLevel
),
199 TexHeight
/ (1 << RenderTextureLevel
));
201 glClearColor(0.5, 0.5, 1.0, 0.0);
202 glClear(GL_COLOR_BUFFER_BIT
);
204 CheckError(__LINE__
);
216 /* Bind normal framebuffer */
217 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, 0);
218 CheckError(__LINE__
);
220 glDeleteFramebuffersEXT(1, &MyFB
);
221 CheckError(__LINE__
);
223 glClearColor(0, 0, 0, 0);
231 int texWidth
= TexWidth
, texHeight
= TexHeight
;
233 glViewport(0, 0, WinHeight
, WinHeight
);
235 glClear(GL_COLOR_BUFFER_BIT
);
237 glMatrixMode(GL_PROJECTION
);
239 glOrtho(0, WinWidth
, 0, WinHeight
, -1, 1);
240 glMatrixMode(GL_MODELVIEW
);
246 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR_MIPMAP_LINEAR
);
247 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
250 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST_MIPMAP_NEAREST
);
251 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
257 for (bias
= -1; bias
< 11; bias
++) {
261 if (texWidth
== 1 && texHeight
== 1)
263 texWidth
= TexWidth
>> bias
;
264 texHeight
= TexHeight
>> bias
;
270 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT
, GL_TEXTURE_LOD_BIAS_EXT
, 0.0);
273 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT
, GL_TEXTURE_LOD_BIAS_EXT
, bias
);
276 glRasterPos2f(x
, y
+ TexHeight
+ 5);
278 sprintf(str
, "Texture Level %d: %d x %d",
279 (bias
< 0 ? 0 : bias
),
280 texWidth
, texHeight
);
282 sprintf(str
, "Texture LOD Bias = %d", bias
);
286 glTranslatef(x
, y
, 0);
288 glEnable(GL_TEXTURE_2D
);
291 glTexCoord2f(0, 0); glVertex2f(0, 0);
292 glTexCoord2f(1, 0); glVertex2f(texWidth
, 0);
293 glTexCoord2f(1, 1); glVertex2f(texWidth
, texHeight
);
294 glTexCoord2f(0, 1); glVertex2f(0, texHeight
);
299 glDisable(GL_TEXTURE_2D
);
313 Reshape(int width
, int height
)
321 Key(unsigned char key
, int x
, int y
)
336 RenderTextureLevel
++;
339 RenderTextureLevel
--;
348 ResetTextureLevel(RenderTextureLevel
);
360 Bias
= 100.0 * (key
- '0');
363 ScaleQuads
= !ScaleQuads
;
369 RenderTextureLevel
= 0;
374 glutDestroyWindow(Win
);
387 if (!glutExtensionSupported("GL_EXT_texture_lod_bias")) {
388 printf("Sorry, GL_EXT_texture_lod_bias not supported by this renderer.\n");
392 if (!glutExtensionSupported("GL_SGIS_generate_mipmap")) {
393 printf("Sorry, GL_SGIS_generate_mipmap not supported by this renderer.\n");
397 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
399 glGenTextures(1, &TexObj
);
400 glBindTexture(GL_TEXTURE_2D
, TexObj
);
407 /* mipmapping required for this extension */
408 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
410 glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS_EXT
, &maxBias
);
412 printf("GL_RENDERER: %s\n", (char*) glGetString(GL_RENDERER
));
413 printf("LOD bias range: [%g, %g]\n", -maxBias
, maxBias
);
415 printf("Press 's' to toggle quad scaling\n");
420 main(int argc
, char *argv
[])
422 glutInit(&argc
, argv
);
423 glutInitWindowPosition(0, 0);
424 glutInitWindowSize(WinWidth
, WinHeight
);
425 glutInitDisplayMode(GLUT_RGB
| GLUT_DOUBLE
);
426 Win
= glutCreateWindow(argv
[0]);
428 glutReshapeFunc(Reshape
);
429 glutKeyboardFunc(Key
);
430 glutDisplayFunc(Display
);