Advertisement

[SDL] SDL_SetVideoMode with OpenGL and fullscreen

Started by June 28, 2011 03:37 PM
10 comments, last by EvilTesla-RG 13 years, 4 months ago
I'm having issues with SDL_SetVideoMode when I use SDL_OPENGL, and SDL_FULLSCREEN flags.


The first time I call it, it works fine. But if I call it again to change the screen resolution, then the screen just turns black.

It works just fine without SDL_FULLSCREEN. And I've tried calling SDL_QuitSubSystem(SDL_INIT_VIDEO) and SDL_InitSubSystem(SDL_INIT_VIDEO) before time. But that doesn't seem to work.

any help would be great.


Thanks,
EvilTesla-RG
Are you using a pre-built version of SDL? If so, which version? Have you downloaded the most up to date version from www.libsdl.org? There was a bug at one stage where SDL destroyed the OpenGL context when you resized the window. This was fixed at some stage in SDL 1.2.X, but depending on where you downloaded the precompiled DLLs you might not have a version with the fix.
Advertisement
I'm using SDL 1.2.14

I don't think that is the issue, as it works just fine if I don't use the fullscreen flag.

And I reload everything anyway.
Can you post a small example program demonstrating the problem?
I'll have to write it, current program is not small. (menu system)


I'll post again once I have it writtin.
alright,

I wrote a simple program that calls SDL_SetVideoMode twice, and it works just fine.



Guess I'll just make a copy of my current project and start deconstructing it untill I can find the issue.



Thanks for helping
Advertisement
I was wrong, the short program I wrote isn't working, and I can't figure out why.

I have attached a code::blocks project with all the code
[attachment=3968:MS test.zip]


It simply a program that uses SDL and OpenGL, and creates a white block that follows the mouse.


If you press the 'a' key, then the program will call SDL_SetVideoMode with a differnt resolution. You will notice that the white box no longer follows the mouse.

It does the same thing no matter what the resolution is (same or differnt for each SDL_SetVideoMode call). But if fullscreen is removed, than the program works.

Here is the main file



//#include <iostream>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_opengl.h>
#include <gl/gl.h>

#include "OGL_setup.h"

using namespace std;

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
Uint32 rmask = 0xff000000;
Uint32 gmask = 0x00ff0000;
Uint32 bmask = 0x0000ff00;
Uint32 amask = 0x000000ff;
#else
Uint32 rmask = 0x000000ff;
Uint32 gmask = 0x0000ff00;
Uint32 bmask = 0x00ff0000;
Uint32 amask = 0xff000000;
#endif

int main(int argc, char *argv[])
{

//enable SDL
SDL_Init(SDL_INIT_VIDEO);
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 0 );
SDL_SetVideoMode(640, 480, 0, SDL_OPENGL | SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_RESIZABLE | SDL_FULLSCREEN);
//note that if SDL_FULLSCREEN is removed (both here and in event handeling), then this works

//enable openGL
setupExtensions();

glViewport(0, 0, 640, 480);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, 640, 480, 0.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();


//load white square texture
SDL_Surface* surf=SDL_CreateRGBSurface(SDL_SRCALPHA, 15, 18, 32, rmask, gmask, bmask, amask);
Uint32 color=SDL_MapRGBA(surf->format,255,255,255,255);
SDL_FillRect(surf, NULL, color);

GLuint texture;
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surf->w, surf->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels);

GLuint GLcalllist=glGenLists(1);
glNewList(GLcalllist, GL_COMPILE);

glBegin( GL_QUADS );
//Bottom-left vertex (corner)
glMultiTexCoord2fARB(GL_TEXTURE0, 0, 0);
glVertex2f( 0.f, 0.f);

//Bottom-right vertex (corner)
glMultiTexCoord2fARB(GL_TEXTURE0, 1, 0);
glVertex2f( 15, 0.f );

//Top-right vertex (corner)
glMultiTexCoord2fARB(GL_TEXTURE0, 1, 1);
glVertex2f( 15, 18 );

//Top-left vertex (corner)
glMultiTexCoord2fARB(GL_TEXTURE0, 0, 1);
glVertex2f( 0.f, 18 );
glEnd();

glEndList();

//Down to buisness
while(true)
{
//handel events
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_KEYDOWN:
if(event.key.keysym.sym==SDLK_ESCAPE)
return(0);
else if(event.key.keysym.sym==SDLK_a) //resize screen
SDL_SetVideoMode(760, 480, 0, SDL_OPENGL | SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_RESIZABLE | SDL_FULLSCREEN);
break;
case SDL_QUIT:
return(0);
break;
}
}

//render square at mouse position
int pos[2]={0,0};
SDL_GetMouseState(&pos[0], &pos[1]);
glLoadIdentity();
glTranslatef(pos[0], pos[1], 0);
glCallList(GLcalllist);
SDL_GL_SwapBuffers();
}

return(0);
}






Thanks

[attachment=3968:MS test.zip]


Bump

Bump


SDL_SetVideoMode should create a new opengl rendering context when you call it the second time on Windows, you probably have to create new textures and setup your modelview and projection matrices again afterwards. (On Linux it supposedly doesn't do that but it doesn't hurt that much to use the same code on all platforms).

you probably also have to recreate your display list and a bunch of other things. (it might be a good idea to move all opengl initialization to its own function and call that after you change resolution/videmode
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
I don't think that's the problem.

As my larger program does completely reload OpenGL and all the textures, and it has the same problems.


Furthermore, it works if I run it in windowed mode. It only doesn't work if it is in fullscreen.

This topic is closed to new replies.

Advertisement