1/* 2 * Copyright (C) 2000 Brian Paul All Rights Reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 */ 21 22/** 23 * \file bug_3195.c 24 * 25 * Simple regression test for bug #3195. A bug in the i180 driver caused 26 * a segfault (inside the driver) when the LOD bias is adjusted and no texture 27 * is enabled. This test, which is based on progs/demos/lodbias.c, sets up 28 * all the texturing, disables all textures, adjusts the LOD bias, then 29 * re-enables \c GL_TEXTURE_2D. 30 * 31 * \author Brian Paul 32 * \author Ian Romanick <idr@us.ibm.com> 33 */ 34 35#include <assert.h> 36#include <stdlib.h> 37#include <stdio.h> 38#include <math.h> 39#include <GL/glew.h> 40#include "glut_wrap.h" 41 42#include "readtex.h" 43 44#define TEXTURE_FILE DEMOS_DATA_DIR "girl.rgb" 45 46static GLfloat Xrot = 0, Yrot = -30, Zrot = 0; 47static GLint Bias = 0, BiasStepSign = +1; /* ints avoid fp precision problem */ 48static GLint BiasMin = -400, BiasMax = 400; 49 50 51 52static void 53PrintString(const char *s) 54{ 55 while (*s) { 56 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); 57 s++; 58 } 59} 60 61static void Idle( void ) 62{ 63 static int lastTime = 0; 64 int time = glutGet(GLUT_ELAPSED_TIME); 65 int step; 66 67 if (lastTime == 0) 68 lastTime = time; 69 else if (time - lastTime < 10) 70 return; 71 72 step = (time - lastTime) / 10 * BiasStepSign; 73 lastTime = time; 74 75 Bias += step; 76 if (Bias < BiasMin) { 77 exit(0); 78 } 79 else if (Bias > BiasMax) { 80 Bias = BiasMax; 81 BiasStepSign = -1; 82 } 83 84 glutPostRedisplay(); 85} 86 87 88static void Display( void ) 89{ 90 char str[100]; 91 92 glClear( GL_COLOR_BUFFER_BIT ); 93 94 glMatrixMode( GL_PROJECTION ); 95 glLoadIdentity(); 96 glOrtho(-1, 1, -1, 1, -1, 1); 97 glMatrixMode( GL_MODELVIEW ); 98 glLoadIdentity(); 99 100 glDisable(GL_TEXTURE_2D); 101 glColor3f(1,1,1); 102 glRasterPos3f(-0.9, -0.9, 0.0); 103 sprintf(str, "Texture LOD Bias = %4.1f", Bias * 0.01); 104 PrintString(str); 105 106 glMatrixMode( GL_PROJECTION ); 107 glLoadIdentity(); 108 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 ); 109 glMatrixMode( GL_MODELVIEW ); 110 glLoadIdentity(); 111 glTranslatef( 0.0, 0.0, -8.0 ); 112 113 glPushMatrix(); 114 glRotatef(Xrot, 1, 0, 0); 115 glRotatef(Yrot, 0, 1, 0); 116 glRotatef(Zrot, 0, 0, 1); 117 118 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.01 * Bias); 119 glEnable(GL_TEXTURE_2D); 120 121 glBegin(GL_POLYGON); 122 glTexCoord2f(0, 0); glVertex2f(-1, -1); 123 glTexCoord2f(2, 0); glVertex2f( 1, -1); 124 glTexCoord2f(2, 2); glVertex2f( 1, 1); 125 glTexCoord2f(0, 2); glVertex2f(-1, 1); 126 glEnd(); 127 128 glPopMatrix(); 129 130 glutSwapBuffers(); 131} 132 133 134static void Reshape( int width, int height ) 135{ 136 glViewport( 0, 0, width, height ); 137} 138 139 140static void Key( unsigned char key, int x, int y ) 141{ 142 (void) x; 143 (void) y; 144 switch (key) { 145 case 27: 146 exit(0); 147 break; 148 } 149 glutPostRedisplay(); 150} 151 152 153static void SpecialKey( int key, int x, int y ) 154{ 155 const GLfloat step = 3.0; 156 (void) x; 157 (void) y; 158 switch (key) { 159 case GLUT_KEY_UP: 160 Xrot -= step; 161 break; 162 case GLUT_KEY_DOWN: 163 Xrot += step; 164 break; 165 case GLUT_KEY_LEFT: 166 Yrot -= step; 167 break; 168 case GLUT_KEY_RIGHT: 169 Yrot += step; 170 break; 171 } 172 glutPostRedisplay(); 173} 174 175 176static void Init( void ) 177{ 178 GLfloat maxBias; 179 const char * const ver_string = (const char *) 180 glGetString( GL_VERSION ); 181 182 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 183 printf("GL_VERSION = %s\n", ver_string); 184 185 printf("\nThis program should function nearly identically to Mesa's lodbias demo.\n" 186 "It should cycle through the complet LOD bias range once and exit. If bug\n" 187 "#3195 still exists, the demo should crash almost immediatly.\n"); 188 printf("This is a regression test for bug #3195.\n"); 189 printf("https://bugs.freedesktop.org/show_bug.cgi?id=3195\n"); 190 191 if (!glutExtensionSupported("GL_EXT_texture_lod_bias")) { 192 printf("Sorry, GL_EXT_texture_lod_bias not supported by this renderer.\n"); 193 exit(1); 194 } 195 196 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 197 198 if (glutExtensionSupported("GL_SGIS_generate_mipmap")) { 199 /* test auto mipmap generation */ 200 GLint width, height, i; 201 GLenum format; 202 GLubyte *image = LoadRGBImage(TEXTURE_FILE, &width, &height, &format); 203 if (!image) { 204 printf("Error: could not load texture image %s\n", TEXTURE_FILE); 205 exit(1); 206 } 207 /* resize to 256 x 256 */ 208 if (width != 256 || height != 256) { 209 GLubyte *newImage = malloc(256 * 256 * 4); 210 gluScaleImage(format, width, height, GL_UNSIGNED_BYTE, image, 211 256, 256, GL_UNSIGNED_BYTE, newImage); 212 free(image); 213 image = newImage; 214 } 215 printf("Using GL_SGIS_generate_mipmap\n"); 216 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); 217 glTexImage2D(GL_TEXTURE_2D, 0, format, 256, 256, 0, 218 format, GL_UNSIGNED_BYTE, image); 219 free(image); 220 221 /* make sure mipmap was really generated correctly */ 222 width = height = 256; 223 for (i = 0; i < 9; i++) { 224 GLint w, h; 225 glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &w); 226 glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_HEIGHT, &h); 227 printf("Level %d size: %d x %d\n", i, w, h); 228 assert(w == width); 229 assert(h == height); 230 width /= 2; 231 height /= 2; 232 } 233 234 } 235 else if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) { 236 printf("Error: could not load texture image %s\n", TEXTURE_FILE); 237 exit(1); 238 } 239 240 /* mipmapping required for this extension */ 241 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 242 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 243 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 244 245 glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS_EXT, &maxBias); 246 printf("LOD bias range: [%g, %g]\n", -maxBias, maxBias); 247 BiasMin = -100 * maxBias; 248 BiasMax = 100 * maxBias; 249 250 /* Since we have (about) 8 mipmap levels, no need to bias beyond 251 * the range [-1, +8]. 252 */ 253 if (BiasMin < -100) 254 BiasMin = -100; 255 if (BiasMax > 800) 256 BiasMax = 800; 257} 258 259 260int main( int argc, char *argv[] ) 261{ 262 glutInit( &argc, argv ); 263 glutInitWindowPosition( 0, 0 ); 264 glutInitWindowSize( 350, 350 ); 265 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); 266 glutCreateWindow( "Bug #3195 Test" ); 267 glewInit(); 268 glutReshapeFunc( Reshape ); 269 glutKeyboardFunc( Key ); 270 glutSpecialFunc( SpecialKey ); 271 glutDisplayFunc( Display ); 272 glutIdleFunc(Idle); 273 Init(); 274 glutMainLoop(); 275 return 0; 276} 277