@Capehill Something wrong with beret from github when built as SWSURFACE one. To reproduce:
1). replace HWSURFACE on SWSURFACE in 2 places in beret from github, recompile, run game 2). press alt+tab to going to the window mode 3). press alt+tab to going to fullscreenmode again
As result everything slow downs like hell :) 3-4 fps. And if i quit, it even didn't quit.
My old main.c rebuilded with new SDL give no that problem, so probably some code changes in beret about flags and co cause that.
@Capehill Btw, for dbl-buffering, i see that minigl in os4sdl is playing dirty games with surfaces and dbl-buffering. At least i only checked on word "OPENGL" in video/amigaos4 directory and there few places which looks strange (with strange comments about using surfaces and dbl-buffering).
There is one check which removes SDL_DOUBLEBUF flag in OpenGL path, to avoid resource allocation. Do you mean that one? Double buffering seems to be handled separately and it's forced in OpenGL case.
I would like to do some changes, for example it would be nice to have bitdepth user-configurable (now it's 16-bit hard coded).
/* Hack. We assert HWSURFACE above to simplify
* initialization of GL surfaces, but we cannot pass these flags
* back to SDL.
* Need to re-work surface set-up code so that this nonsense isn't
* necessary
*/
current->flags &= ~SDL_HWSURFACE;
}
}
#endif
Dunno how right comment about hack and needs to re-work surface setup code is at current state, through.
I also found that in video/SDL_glfuncs.h, we have that part:
Dunno if minigl still didn't have 1d texturing, but even if not, there we probably need somehow to make common ifdef, which we can later use for minigl, but didn't use for ogles and gl4es
// Faking 1D textures using 2D textures
// WARNING: This assumes that Warp3D doesn't support texture borders. If this changes, then so must this
// function
cgl_GLCopyTexImage2D(Self, GL_TEXTURE_2D, level, internalFormat, x, y, width, 1, border);
// The vertical direction should always be repeated
cgl_GLTexParameteri(Self, gltarget, GL_TEXTURE_WRAP_T, GL_REPEAT);
@Capehill Right, i do check changelog of MiniGl, and it was added long time ago, in the 2.2 version. And that ifdef in SDL probably keeps there much longer, and we can then remove it at all.
@Capehill Btw, did you know for what that video/SDL_glfuncs.h is need it at all ? I mean, didn't we use those gl fucntions we need , just taken includes and whatever from opengl itself, and use them in any SDL app ?
I didn't check all sources but they seem to be used for OpenGL-blitting. Something we can ignore. At least I don't have interest to study the topic in SDL1. Easier to use graphics.library for 2D and OpenGL for 3D.
Spent quite much time to debug Beret issue. After all, the issue was that SDL creates a "shadow surface" (SW) under certain conditions and accelerated blits are canceled. In practise it could happen when asked for SDL_HWSURFACE|SDL_DOUBLEBUF but without SDL_FULLSCREEN.
Whole surface creation is so complicated business due to all combinations. Now, if the backend would use the same flipping code for both window and fullscreen, this problem might be solved but at the moment my advice is to pass SDL_DOUBLEBUF only with FULLSCREEN|HWSURFACE combo.
So, for accelerated blitting, either use:
SDL_FULLSCREEN|SDL_HWSURFACE|SDL_DOUBLEBUF or SDL_HWSURFACE (window).
Or if your application needs to poke surfaces like many emulators do, maybe use just SWSURFACEs.
Found today some other issue (which can be again issues with game's code, but maybe not): i build some game via SDL1 / MiniGL which, when switch to/from fullscreen, or resize the gl window when in window mode, give a black window. Game logic works, but just black window.
If i start originally game in lets say fullscreen mode : it works. If i start originalluy game in window mode: it works.
But once i trying to swith to/from window/fullscreen, then black window. Same for resizing when in window mode.
The functions in question are this ones:
/***********************************************************************
* Initialize SDL and make a SDL-Window / Fullscreen *
***********************************************************************/
void sys_create_display(int width,int height)
{
/* Information about the current video settings. */
const SDL_VideoInfo* info = NULL;
int vidmode_flags=0, samplingerror = 0;
/* Let's get some video information. */
info = SDL_GetVideoInfo( );
if( !info ) {
/* This should probably never happen. */
fprintf( stderr, "Video query failed: %s\n",
SDL_GetError( ) );
sys_exit(1);
}
vidmode_bpp = info->vfmt->BitsPerPixel;
/*
* Now, we want to setup our requested
* window attributes for our OpenGL window.
* We want *at least* 5 bits of red, green
* and blue. We also want at least a 16-bit
* depth buffer.
*
* The last thing we do is request a VMfloat
* buffered window. '1' turns on VMfloat
* buffering, '0' turns it off.
*
* Note that we do not use SDL_DOUBLEBUF in
* the flags to SDL_SetVideoMode. That does
* not affect the GL attribute state, only
* the standard 2D blitting setup.
*/
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
if (SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ) <0) {
fprintf(stderr, "SDL_GL_DOUBLEBUFFER error: %s\n", SDL_GetError());
options_vsync = 0;
} else {
//compile without errors, if SDL is < Version 1.2.10 at compile time
#if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION == 2 && SDL_PATCHLEVEL > 9
// The next works only with fsaa options off!!!!
if(!options_fsaa_value) {
if(SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 ) < 0 ) {
fprintf( stderr, "Unable to guarantee accelerated visual with libSDL < 1.2.10\n");
}
}
if(vsync_supported()) {
if(options_vsync) {
if (SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1) < 0) { // since SDL v1.2.10
fprintf(stderr, "SDL_GL_SWAP_CONTROL error: %s\n", SDL_GetError());
options_vsync = 0;
}
}
} else {
fprintf(stderr,"SDL-System without control of vsync. Scrolling may stutter\n");
}
#endif
}
fprintf( stderr, "Video mode set failed: %s\nSwitch to other mode\n", SDL_GetError());
if(options_fsaa_value) {
options_fsaa_value >>= 1;
fprintf(stderr,"FSAA %i\n",options_fsaa_value);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, options_fsaa_value);
} else {
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,0);
}
}
}
// Check new settings for better output the next line is a must for multisample
if(!samplingerror && options_fsaa_value){
glEnable(GL_MULTISAMPLE);
//glHint(GL_MULTISAMPLE_FILTER_HINT_NV,GL_NICEST); //be careful (Nvidia-specific), set over an option ?
}
SDL_WM_SetCaption("game","game");
glPolygonMode(GL_FRONT,GL_FILL); // fill the front of the polygons
glPolygonMode(GL_BACK,GL_LINE); // only lines for back (better seeing on zooming)
glCullFace(GL_BACK); // Standards for rendering only front of textures
glEnable(GL_CULL_FACE);
}
/***********************************************************************
* Fullscreen active ? *
***********************************************************************/
int sys_get_fullscreen(void)
{
return fullscreen;
}
/**************************************************************************
* Set a fullscreen(1) or window(0) window *
* SDL_WM_ToggleFullScreen(screen) works only on X11 and there not stable *
**************************************************************************/
void sys_fullscreen( int fullscr )
{
SDL_Surface * screen;
Uint32 flags;
screen = SDL_GetVideoSurface();
flags = screen->flags; /* Save the current flags in case toggling fails */
SDL_EnableKeyRepeat( 0, 0 );
if ( fullscr!=0 && (screen->flags & SDL_FULLSCREEN)==0 ){
screen = SDL_SetVideoMode( 0, 0, 0, screen->flags | SDL_FULLSCREEN );
} else if( fullscr==0 && (screen->flags & SDL_FULLSCREEN)!=0 ){
screen = SDL_SetVideoMode( 0, 0, 0, screen->flags & ~SDL_FULLSCREEN);
}
if(screen == NULL) {
screen = SDL_SetVideoMode(0, 0, 0, flags); /* If toggle FullScreen failed, then switch back */
} else {
fullscreen = fullscr;
}
SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL );
if(screen == NULL) {
fprintf(stderr,"Video-Error on set full-screen/windowed mode. Terminating\n");
sys_exit(1); /* If you can't switch back for some reason, then epic fail */
}
}
/***********************************************************************
* Toggle between Fullscreen and windowed mode *
***********************************************************************/
/***********************************************************************
* Resize the SDL Surface handle *
***********************************************************************/
void sys_resize( int width, int height, int callfrom )
{
SDL_Surface * screen;
Uint32 flags;
if(width < 958) width = 958; // don't resize below this
if(height < 750) height = 750;
ignore = callfrom;
screen = SDL_GetVideoSurface();
flags = screen->flags; /* Save the current flags in case toggling fails */
SDL_EnableKeyRepeat( 0, 0 );
screen = SDL_SetVideoMode( width, height, screen->format->BitsPerPixel, screen->flags);
SDL_Delay(300);
//fprintf(stderr,"Called x: %i y: %i\n",width,height);
SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL );
if(screen == NULL) {
screen = SDL_SetVideoMode(0, 0, 0, flags); /* If failed, then switch back */
}
SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL );
if(screen == NULL) {
fprintf(stderr,"Video-Error on window resize. Terminating\n");
sys_exit(1); /* If you can't switch back for some reason, then epic fail */
}
ResizeWindow(width,height);
}
/***********************************************************************
* get all resolution modes for SDL/OpenGL *
***********************************************************************/
sysResolution *sys_list_modes( void ) {
sysResolution * sysmodes;
SDL_Rect ** modes;
int i, modenr;
Maybe its something with SDL_GetVideoSurface() ? Is looks like something with sys_resize() done wrong for us (or didn't done what we need to do). Maybe something with HWSURFACE there ?
SDL destroys existing OpenGL context in most cases when SetVideoMode is called. It might explain the issue if application assumes that old context exists after display change.
On the other hand, that fullscreen toggling workaround may not be needed. SDL_WM_ToggleFullScreen works, I tried testgl with ALT+ENTER combo.
Everything start works as expected. I.e. just change screen->flags on SDL_OPENGL | SDL_RESIZABLE.
What is more interesting, that in the debug output, flags in both cases are same OPENGL RESIZABLE. But in first case , when screen->flags is used, i have that kind of output when trying to resize window:
[os4video_SetVideoMode] Requesting new video mode 958x750x32
[os4video_SetVideoMode] Requested flags: OPENGL RESIZEABLE
[os4video_SetVideoMode] Current mode 1202x750x32
[os4video_SetVideoMode] Current mode flags OPENGL RESIZEABLE
[os4video_SetVideoMode] Current hwdata 0x596B4794
[os4video_SetVideoMode] Creating new display
[os4video_SetVideoMode] Deleting old display
[os4video_GL_Term] Here
[os4video_DeleteCurrentDisplay] Closing window 0x62996018
[os4video_SetVideoMode] Opening new display
[os4video_CreateDisplay] Creating a 958x750x32 windowed display
[os4video_CreateDisplay] Screen depth: 32 pixel format: 6
[os4video_GetBestWindowPosition] Visible screen: (0,0)/(1920x1080)
[os4video_OpenWindow] Trying to open window at (476,149) of size (958x750)
[os4video_GL_Init] Initializing MiniGL (window 0x62996018)...
[os4video_AllocateBitMap] Allocating bitmap 958*750*16
[os4video_AllocateBitMap] Allocating bitmap 958*750*16
[os4video_SetVideoMode] New display created
[os4video_SetVideoMode] Obtained flags: OPENGL RESIZEABLE
[os4video_ShowWMCursor] Setting cursor 0x639F6010
[os4video_ResetCursor] Cursor image set
And that one, when all works, when i only change screen->flags on SDL_OPENGL | SDL_RESIZABLE:
[os4video_SetVideoMode] Requesting new video mode 1154x750x32
[os4video_SetVideoMode] Requested flags: OPENGL RESIZEABLE
[os4video_SetVideoMode] Current mode 958x750x32
[os4video_SetVideoMode] Current mode flags OPENGL RESIZEABLE
[os4video_SetVideoMode] Current hwdata 0x596B4794
[os4video_SetVideoMode] Resizing window: 1154x750
[os4video_PIXF2Bits] Unknown pixelformat 0
[os4video_InitOffScreenBuffer] Allocating a 1156x752x0 off-screen buffer with pixel format 0, SWSURFACE
[os4video_InitOffScreenBuffer] Pixels 0x62E6E000, pitch 1168
[os4video_AllocateBitMap] Allocating bitmap 1154*750*16
[os4video_AllocateBitMap] Allocating bitmap 1154*750*16
[os4video_ShowWMCursor] Setting cursor 0x639FB010
See, it tries to resize then.
Question is : wtf ! Maybe that code produce something weird:
So, while in serial output we have same OPENGL RESIZABLE words, it still have something else in screen->flags, which make calling of os4video_SetVideoMode's Resizing window() skips ?
printf("flags in dec = %d\n", flags);
printf("flags in hex = %x\n", flags);
printf("flags_from_screen in dec = %d\n", screen->flags);
printf("flags_from_screen in hex = %x\n", screen->flags);
SDL_Quit();
}
When compile and run this code over win32 , that what i have in output:
$ ./sdltest.exe flags in dec = 18 flags in hex = 12 flags_from_screen in dec = 18 flags_from_screen in hex = 12
If i compile that for amigaos4 and run, then output are:
$ ./sdltest
flags in dec = 18 flags in hex = 12 flags_from_screen in dec = 16777234 flags_from_screen in hex = 1000012
So, in case with amigaos4, we have other value returned when do SDL_GetVideoSurface(). Seems it return something else in flags field (its not just 12 , but 1000012 , so another 1 at begining of byte).
Is it bug or feature ? At least, in case with SDL everything should works the same on all platforms, so i assume bug ?