Eli joka kerta kun yritän siirtää ikkunaa ohjelma sammuu antaen seuraavanlaisen virheilmoituksen:
Could not get a surface after resize: Invalid bits per pixel (range is {8...32})
Bits per pixel on kuiteskin kovakoodattu vakio 24. Eikös tuon pitäisi mahtua tuohon selvästi? Mikä mahtaisi sekoittaa tuon?
Vaikea sanoa kun ei ole tuota kristallipalloa sattunu mukaan.
Eli siis voisitko hieman laittaa jotain koodiakin, sillä uskon että on aika vaikea kenenkään sanoa mitään ilman, että näkee koodia. ...tai ainakin se koodin näkemin helpottaa vian etsinnässä todella paljon.
Lisäksi, millä käyttöjärjestelmällä ajat koodin?
Noh SDL/OpenGL alustukseen liittyvää koodia. Alustana toimii Linux.
void client::init() { /* main loop variable */ /* used to collect events */ /* this holds some info about our display */ const SDL_VideoInfo *videoInfo; /* whether or not the window is active */ isActive = TRUE; if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { fprintf( stderr, "Video initialization failed: %s\n", SDL_GetError( ) ); Quit( 1 ); } /* Fetch the video info */ videoInfo = SDL_GetVideoInfo( ); if ( !videoInfo ) { fprintf( stderr, "Video query failed: %s\n", SDL_GetError( ) ); Quit( 1 ); } /* the flags to pass to SDL_SetVideoMode */ videoFlags = SDL_OPENGL; /* Enable OpenGL in SDL */ videoFlags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */ videoFlags |= SDL_HWPALETTE; /* Store the palette in hardware */ videoFlags |= SDL_RESIZABLE; /* Enable window resizing */ /* This checks to see if surfaces can be stored in memory */ if ( videoInfo->hw_available ) videoFlags |= SDL_HWSURFACE; else videoFlags |= SDL_SWSURFACE; /* This checks if hardware blits can be done */ if ( videoInfo->blit_hw ) videoFlags |= SDL_HWACCEL; /* Sets up OpenGL double buffering */ SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); /* get a SDL surface */ surface = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, videoFlags); /* Verify there is a surface */ if(!surface) { fprintf(stderr, "Video mode set failed: %s\n", SDL_GetError()); Quit(1); } if((SDL_EnableKeyRepeat(50, SDL_DEFAULT_REPEAT_INTERVAL))) { fprintf(stderr, "Setting keyboard repeat failed: %s\n", SDL_GetError()); Quit(1); } /* initialize OpenGL */ initGL(); /* resize the initial window */ resizeWindow(SCREEN_WIDTH, SCREEN_HEIGHT );
int initGL() { /* Enable smooth shading */ glShadeModel( GL_SMOOTH ); glEnable( GL_TEXTURE_2D ); /* Set the background black */ glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); /* Depth buffer setup */ glClearDepth( 1.0f ); /* Enables Depth Testing */ glEnable( GL_DEPTH_TEST ); /* The Type Of Depth Test To Do */ glDepthFunc( GL_LEQUAL ); /* Select The Type Of Blending */ glBlendFunc( GL_SRC_ALPHA, GL_ONE ); /* Really Nice Perspective Calculations */ glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); /* Setup The Ambient Light */ glLightfv( GL_LIGHT1, GL_AMBIENT, LightAmbient ); /* Setup The Diffuse Light */ glLightfv( GL_LIGHT1, GL_DIFFUSE, LightDiffuse ); /* Position The Light */ glLightfv( GL_LIGHT1, GL_POSITION, LightPosition ); /* Enable Light One */ glEnable( GL_LIGHT1 ); return( TRUE ); } /* function to release/destroy our resources and restoring the old desktop */ void Quit( int returnCode ) { /* clean up the window */ SDL_Quit( ); /* and exit appropriately */ exit( returnCode ); } /* function to reset our viewport after a window resize */ int resizeWindow( int width, int height ) { /* Height / width ration */ GLfloat ratio; /* Protect against a divide by zero */ if ( height == 0 ) height = 1; ratio = ( GLfloat )width / ( GLfloat )height; /* Setup our viewport. */ glViewport( 0, 0, ( GLsizei )width, ( GLsizei )height ); /* change to the projection matrix and set our viewing volume. */ glMatrixMode( GL_PROJECTION ); glLoadIdentity( ); /* Set our perspective */ gluPerspective( 45.0f, ratio, 0.1f, 100.0f ); /* Make sure we're chaning the model view and not the projection */ glMatrixMode( GL_MODELVIEW ); /* Reset The View */ glLoadIdentity( ); return( TRUE ); }
while ( SDL_PollEvent( &event ) ) { switch( event.type ) { case SDL_ACTIVEEVENT: /* Something's happend with our focus * If we lost focus or we are iconified, we * shouldn't draw the screen */ if ( event.active.gain == 0 ) isActive = FALSE; else isActive = TRUE; break; case SDL_VIDEORESIZE: /* handle resize event */ surface = SDL_SetVideoMode( event.resize.w, event.resize.h, SCREEN_BPP, videoFlags ); if ( !surface ) { fprintf( stderr, "Could not get a surface after resize: %s\n", SDL_GetError( ) ); Quit( 1 ); } resizeWindow( event.resize.w, event.resize.h ); break;
Tuossa pätkässä se sitten kosahtaa. if(!surface) lauseke mättää.
#define SCREEN_WIDTH 1024 #define SCREEN_HEIGHT 800 #define SCREEN_BPP 24
Siis tapahtuuko tuo virhe vain ja aianostaan jos liikutat ikkunaa??
Edit1:
Oletko kokeillut laittaa tuohon depthiksi suoran numeron? eli kokeiles laittaa sihen suoraan 24.
Noh en ollut kokeillu pienentää ikkunaa mutta näköjään siinäkin tulee. Huomasin ilmiön kun yritin raahata ikkunaa syrjään että näkisi konsoli-ikkunan tulostuksen.
Ei tule tähän heti mieleen muuta paitsi, että kokeiles asettaa tuossa samassa uudellee tuo DOUBLE_BUFFERI
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
kayttaja-3842 on aivan hukassa, joten ehkä kannattaa lopettaa arvailu.
Kysyjäkin taitaa olla hieman hukassa, nimittäin OpenGL:n kanssa SDL_GL_DOUBLEBUFFER ei kuulu SDL_SetVideoModen lippuihin, ja samaten kaiken maailman SDL_HWACCEL-, SDL_HWPALETTE- ja SDL_HWSURFACE-liput eivät kuulu asiaan millään tavalla, koska nämä ovat SDL:n lippuja ja tuossa kuitenkin piirtämisen hoitaa OpenGL, johon nuo eivät vaikuta mitenkään. Samasta syystä tuossa annettavalla bittisyvyydellä ei ole merkitystä, vaan asetukset asetetaan, kuten oppaassani neuvon. Siksi bittisyvyydeksi voi laittaa vaikka nollan, jottei itsekin joskus hämäänny merkityksettömistä luvuista.
Kannattaa harrastaa lähdekritiikkiä ja suoran kopioinnin sijaan myös hieman perehtyä asioihin.
Sinänsä ongelma kuulostaa erikoiselta, koska ikkunan siirtäminen ei edes aiheuta resize-viestiä. Jos kuitenkin tarkoitit koon muuttamista, niin testaa tätä koodia, joka ainakin minulla toimii täysin:
#include <math.h> #include <SDL.h> #include <SDL_opengl.h> int main(int argc, char **argv) { SDL_Event e; SDL_Surface *s, *p; Uint32 t0, t; int quit = 0; Uint32 flags = SDL_RESIZABLE | SDL_OPENGL; SDL_Init(SDL_INIT_VIDEO); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); s = SDL_SetVideoMode(640, 480, 0, flags); t0 = SDL_GetTicks(); while (!quit) { t = SDL_GetTicks() - t0; while (SDL_PollEvent(&e)) { if (e.type == SDL_KEYDOWN || e.type == SDL_QUIT) { quit = 1; } if (e.type == SDL_VIDEORESIZE) { printf("%02d.%02d,%03d: ", t / 60000, t / 1000 % 60, t % 1000); printf("Resized to %dx%d!\n", e.resize.w, e.resize.h); p = SDL_SetVideoMode(e.resize.w, e.resize.h, 0, flags); glViewport(0, 0, e.resize.w, e.resize.h); if (s != p) { printf("ptr: %p => %p\n", s, p); s = p; } } } glLoadIdentity(); glTranslated(-1, -1, 0); glScaled(2, 2, 0); glBegin(GL_QUADS); glColor3d(0, 0, 1); glVertex2d(0, 0); glColor3d(0, 1, 0); glVertex2d(1, 0); glColor3d(1, 0, 0); glVertex2d(1, 1); glColor3d(0.5 + 0.5 * sin(0.005 * t), 0.5 + 0.5 * sin(0.002 * t), 0.5 + 0.5 * sin(0.001 * t)); glVertex2d(0, 1); glEnd(); SDL_GL_SwapBuffers(); } SDL_Quit(); return 0; }
Jos tämä ei toimi, tarkista SDL-versiosi. Jos taas toimii, yritä ihmetellä, mikä omassa koodissasi vielä on vikana (mainitsemieni lisäksi).
Aihe on jo aika vanha, joten et voi enää vastata siihen.