Commit 2eed452d authored by Sam Lantinga's avatar Sam Lantinga

Setting up the OpenGL support

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401957
parent 89484fea
...@@ -172,6 +172,7 @@ extern DECLSPEC int SDLCALL SDL_DisplayYUVOverlay(SDL_Overlay * overlay, ...@@ -172,6 +172,7 @@ extern DECLSPEC int SDLCALL SDL_DisplayYUVOverlay(SDL_Overlay * overlay,
SDL_Rect * dstrect); SDL_Rect * dstrect);
extern DECLSPEC void SDLCALL SDL_FreeYUVOverlay(SDL_Overlay * overlay); extern DECLSPEC void SDLCALL SDL_FreeYUVOverlay(SDL_Overlay * overlay);
extern DECLSPEC int SDLCALL SDL_GL_GetAttribute(SDL_GLattr attr, int *value); extern DECLSPEC int SDLCALL SDL_GL_GetAttribute(SDL_GLattr attr, int *value);
extern DECLSPEC void SDLCALL SDL_GL_SwapBuffers(void);
/* Ends C function definitions when using C++ */ /* Ends C function definitions when using C++ */
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -1499,6 +1499,10 @@ extern DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_WindowID windowID, ...@@ -1499,6 +1499,10 @@ extern DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_WindowID windowID,
* *
* \brief Set the swap interval for the current OpenGL context. * \brief Set the swap interval for the current OpenGL context.
* *
* \param interval 0 for immediate updates, 1 for updates synchronized with the vertical retrace
*
* \return 0 on success, or -1 if setting the swap interval is not supported.
*
* \sa SDL_GL_GetSwapInterval() * \sa SDL_GL_GetSwapInterval()
*/ */
extern DECLSPEC int SDLCALL SDL_GL_SetSwapInterval(int interval); extern DECLSPEC int SDLCALL SDL_GL_SetSwapInterval(int interval);
...@@ -1508,16 +1512,18 @@ extern DECLSPEC int SDLCALL SDL_GL_SetSwapInterval(int interval); ...@@ -1508,16 +1512,18 @@ extern DECLSPEC int SDLCALL SDL_GL_SetSwapInterval(int interval);
* *
* \brief Get the swap interval for the current OpenGL context. * \brief Get the swap interval for the current OpenGL context.
* *
* \return 0 if there is no vertical retrace synchronization, 1 if the buffer swap is synchronized with the vertical retrace, and -1 if getting the swap interval is not supported.
*
* \sa SDL_GL_SetSwapInterval() * \sa SDL_GL_SetSwapInterval()
*/ */
extern DECLSPEC int SDLCALL SDL_GL_GetSwapInterval(void); extern DECLSPEC int SDLCALL SDL_GL_GetSwapInterval(void);
/** /**
* \fn void SDL_GL_SwapBuffers(void) * \fn void SDL_GL_SwapWindow(SDL_WindowID windowID)
* *
* Swap the OpenGL buffers, if double-buffering is supported. * \brief Swap the OpenGL buffers for the window, if double-buffering is supported.
*/ */
extern DECLSPEC void SDLCALL SDL_GL_SwapBuffers(void); extern DECLSPEC void SDLCALL SDL_GL_SwapWindow(SDL_WindowID windowID);
/** /**
* \fn void SDL_GL_DeleteContext(SDL_GLContext context) * \fn void SDL_GL_DeleteContext(SDL_GLContext context)
......
...@@ -36,6 +36,7 @@ static SDL_TextureID SDL_VideoTexture; ...@@ -36,6 +36,7 @@ static SDL_TextureID SDL_VideoTexture;
static SDL_Surface *SDL_VideoSurface; static SDL_Surface *SDL_VideoSurface;
static SDL_Surface *SDL_ShadowSurface; static SDL_Surface *SDL_ShadowSurface;
static SDL_Surface *SDL_PublicSurface; static SDL_Surface *SDL_PublicSurface;
static SDL_GLContext *SDL_VideoContext;
static char *wm_title; static char *wm_title;
char * char *
...@@ -335,6 +336,11 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) ...@@ -335,6 +336,11 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
SDL_FreeSurface(SDL_VideoSurface); SDL_FreeSurface(SDL_VideoSurface);
SDL_VideoSurface = NULL; SDL_VideoSurface = NULL;
} }
if (SDL_VideoContext) {
SDL_GL_MakeCurrent(0, SDL_VideoContext);
SDL_GL_DeleteContext(SDL_VideoContext);
SDL_VideoContext = NULL;
}
if (SDL_VideoWindow) { if (SDL_VideoWindow) {
SDL_GetWindowPosition(SDL_VideoWindow, &window_x, &window_y); SDL_GetWindowPosition(SDL_VideoWindow, &window_x, &window_y);
} }
...@@ -432,6 +438,13 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) ...@@ -432,6 +438,13 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
/* If we're in OpenGL mode, just create a stub surface and we're done! */ /* If we're in OpenGL mode, just create a stub surface and we're done! */
if (flags & SDL_OPENGL) { if (flags & SDL_OPENGL) {
SDL_VideoContext = SDL_GL_CreateContext(SDL_VideoWindow);
if (!SDL_VideoContext) {
return NULL;
}
if (SDL_GL_MakeCurrent(SDL_VideoWindow, SDL_VideoContext) < 0) {
return NULL;
}
SDL_VideoSurface = SDL_VideoSurface =
SDL_CreateRGBSurfaceFrom(NULL, width, height, bpp, 0, 0, 0, 0, 0); SDL_CreateRGBSurfaceFrom(NULL, width, height, bpp, 0, 0, 0, 0, 0);
if (!SDL_VideoSurface) { if (!SDL_VideoSurface) {
...@@ -1418,4 +1431,16 @@ SDL_FreeYUVOverlay(SDL_Overlay * overlay) ...@@ -1418,4 +1431,16 @@ SDL_FreeYUVOverlay(SDL_Overlay * overlay)
} }
} }
int
SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
{
return SDL_GL_GetWindowAttribute(SDL_VideoWindow, attr, value);
}
void
SDL_GL_SwapBuffers(void)
{
SDL_GL_SwapWindow(SDL_VideoWindow);
}
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
...@@ -227,36 +227,21 @@ struct SDL_VideoDevice ...@@ -227,36 +227,21 @@ struct SDL_VideoDevice
void (*VideoQuit) (_THIS); void (*VideoQuit) (_THIS);
/* * * */ /* * * */
/* OpenGL support */ /* OpenGL support
*/
/* Sets the dll to use for OpenGL and loads it */
int (*GL_LoadLibrary) (_THIS, const char *path); int (*GL_LoadLibrary) (_THIS, const char *path);
/* Retrieves the address of a function in the gl library */
void *(*GL_GetProcAddress) (_THIS, const char *proc); void *(*GL_GetProcAddress) (_THIS, const char *proc);
/* Get attribute information from the windowing system. */
int (*GL_GetAttribute) (_THIS, SDL_GLattr attrib, int *value); int (*GL_GetAttribute) (_THIS, SDL_GLattr attrib, int *value);
SDL_GLContext(*GL_CreateContext) (_THIS, SDL_Window * window);
/* Make the context associated with this driver current */ int (*GL_MakeCurrent) (_THIS, SDL_Window * window, SDL_GLContext context);
int (*GL_MakeCurrent) (_THIS); int (*GL_SetSwapInterval) (_THIS, int interval);
int (*GL_GetSwapInterval) (_THIS);
/* Swap the current buffers in double buffer mode. */ void (*GL_SwapWindow) (_THIS, SDL_Window * window);
void (*GL_SwapBuffers) (_THIS); void (*GL_DeleteContext) (_THIS, SDL_GLContext context);
/* Determine whether the mouse should be in relative mode or not.
This function is called when the input grab state or cursor
visibility state changes.
If the cursor is not visible, and the input is grabbed, the
driver can place the mouse in relative mode, which may result
in higher accuracy sampling of the pointer motion.
*/
void (*CheckMouseMode) (_THIS);
/* * * */ /* * * */
/* Event manager functions */ /* Event manager functions
*/
/* Handle any queued OS events */
void (*PumpEvents) (_THIS); void (*PumpEvents) (_THIS);
/* * * */ /* * * */
...@@ -266,8 +251,6 @@ struct SDL_VideoDevice ...@@ -266,8 +251,6 @@ struct SDL_VideoDevice
int current_display; int current_display;
Uint32 next_object_id; Uint32 next_object_id;
/* Driver information flags */
/* * * */ /* * * */
/* Data used by the GL drivers */ /* Data used by the GL drivers */
struct struct
......
...@@ -153,6 +153,12 @@ cmpmodes(const void *A, const void *B) ...@@ -153,6 +153,12 @@ cmpmodes(const void *A, const void *B)
return 0; return 0;
} }
static void
SDL_UninitializedVideo()
{
SDL_SetError("Video subsystem has not been initialized");
}
int int
SDL_GetNumVideoDrivers(void) SDL_GetNumVideoDrivers(void)
{ {
...@@ -285,6 +291,7 @@ const char * ...@@ -285,6 +291,7 @@ const char *
SDL_GetCurrentVideoDriver() SDL_GetCurrentVideoDriver()
{ {
if (!_this) { if (!_this) {
SDL_UninitializedVideo();
return NULL; return NULL;
} }
return _this->name; return _this->name;
...@@ -334,6 +341,7 @@ int ...@@ -334,6 +341,7 @@ int
SDL_GetNumVideoDisplays(void) SDL_GetNumVideoDisplays(void)
{ {
if (!_this) { if (!_this) {
SDL_UninitializedVideo();
return 0; return 0;
} }
return _this->num_displays; return _this->num_displays;
...@@ -343,7 +351,7 @@ int ...@@ -343,7 +351,7 @@ int
SDL_SelectVideoDisplay(int index) SDL_SelectVideoDisplay(int index)
{ {
if (!_this) { if (!_this) {
SDL_SetError("Video subsystem has not been initialized"); SDL_UninitializedVideo();
return (-1); return (-1);
} }
if (index >= 0) { if (index >= 0) {
...@@ -535,7 +543,7 @@ SDL_SetDisplayMode(const SDL_DisplayMode * mode) ...@@ -535,7 +543,7 @@ SDL_SetDisplayMode(const SDL_DisplayMode * mode)
int i, ncolors; int i, ncolors;
if (!_this) { if (!_this) {
SDL_SetError("Video subsystem has not been initialized"); SDL_UninitializedVideo();
return -1; return -1;
} }
...@@ -621,7 +629,7 @@ SDL_SetFullscreenDisplayMode(const SDL_DisplayMode * mode) ...@@ -621,7 +629,7 @@ SDL_SetFullscreenDisplayMode(const SDL_DisplayMode * mode)
int i; int i;
if (!_this) { if (!_this) {
SDL_SetError("Video subsystem has not been initialized"); SDL_UninitializedVideo();
return -1; return -1;
} }
...@@ -659,7 +667,7 @@ SDL_SetDisplayPalette(const SDL_Color * colors, int firstcolor, int ncolors) ...@@ -659,7 +667,7 @@ SDL_SetDisplayPalette(const SDL_Color * colors, int firstcolor, int ncolors)
int status = 0; int status = 0;
if (!_this) { if (!_this) {
SDL_SetError("Video subsystem has not been initialized"); SDL_UninitializedVideo();
return -1; return -1;
} }
palette = SDL_CurrentDisplay.palette; palette = SDL_CurrentDisplay.palette;
...@@ -684,7 +692,7 @@ SDL_GetDisplayPalette(SDL_Color * colors, int firstcolor, int ncolors) ...@@ -684,7 +692,7 @@ SDL_GetDisplayPalette(SDL_Color * colors, int firstcolor, int ncolors)
SDL_Palette *palette; SDL_Palette *palette;
if (!_this) { if (!_this) {
SDL_SetError("Video subsystem has not been initialized"); SDL_UninitializedVideo();
return -1; return -1;
} }
...@@ -721,7 +729,12 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) ...@@ -721,7 +729,12 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
SDL_Window *windows; SDL_Window *windows;
if (!_this) { if (!_this) {
SDL_SetError("Video subsystem has not been initialized"); SDL_UninitializedVideo();
return 0;
}
if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) {
SDL_SetError("No OpenGL support in video driver");
return 0; return 0;
} }
...@@ -783,7 +796,7 @@ SDL_CreateWindowFrom(const void *data) ...@@ -783,7 +796,7 @@ SDL_CreateWindowFrom(const void *data)
SDL_Window *windows; SDL_Window *windows;
if (!_this) { if (!_this) {
SDL_SetError("Video subsystem has not been initialized"); SDL_UninitializedVideo();
return (0); return (0);
} }
...@@ -822,6 +835,7 @@ SDL_GetWindowFromID(SDL_WindowID windowID) ...@@ -822,6 +835,7 @@ SDL_GetWindowFromID(SDL_WindowID windowID)
int i, j; int i, j;
if (!_this) { if (!_this) {
SDL_UninitializedVideo();
return NULL; return NULL;
} }
...@@ -841,6 +855,7 @@ SDL_VideoDisplay * ...@@ -841,6 +855,7 @@ SDL_VideoDisplay *
SDL_GetDisplayFromWindow(SDL_Window * window) SDL_GetDisplayFromWindow(SDL_Window * window)
{ {
if (!_this) { if (!_this) {
SDL_UninitializedVideo();
return NULL; return NULL;
} }
return &_this->displays[window->display]; return &_this->displays[window->display];
...@@ -1281,6 +1296,7 @@ int ...@@ -1281,6 +1296,7 @@ int
SDL_GetRendererInfo(int index, SDL_RendererInfo * info) SDL_GetRendererInfo(int index, SDL_RendererInfo * info)
{ {
if (!_this) { if (!_this) {
SDL_UninitializedVideo();
return -1; return -1;
} }
...@@ -1374,6 +1390,7 @@ SDL_CreateTexture(Uint32 format, int access, int w, int h) ...@@ -1374,6 +1390,7 @@ SDL_CreateTexture(Uint32 format, int access, int w, int h)
SDL_Texture *texture; SDL_Texture *texture;
if (!_this) { if (!_this) {
SDL_UninitializedVideo();
return 0; return 0;
} }
...@@ -1752,6 +1769,7 @@ SDL_RenderFill(const SDL_Rect * rect, Uint32 color) ...@@ -1752,6 +1769,7 @@ SDL_RenderFill(const SDL_Rect * rect, Uint32 color)
SDL_Rect real_rect; SDL_Rect real_rect;
if (!_this) { if (!_this) {
SDL_UninitializedVideo();
return -1; return -1;
} }
...@@ -1821,6 +1839,7 @@ SDL_RenderPresent(void) ...@@ -1821,6 +1839,7 @@ SDL_RenderPresent(void)
SDL_Renderer *renderer; SDL_Renderer *renderer;
if (!_this) { if (!_this) {
SDL_UninitializedVideo();
return; return;
} }
...@@ -1839,6 +1858,7 @@ SDL_DestroyTexture(SDL_TextureID textureID) ...@@ -1839,6 +1858,7 @@ SDL_DestroyTexture(SDL_TextureID textureID)
SDL_Renderer *renderer; SDL_Renderer *renderer;
if (!_this) { if (!_this) {
SDL_UninitializedVideo();
return; return;
} }
...@@ -1977,21 +1997,21 @@ SDL_VideoQuit(void) ...@@ -1977,21 +1997,21 @@ SDL_VideoQuit(void)
_this = NULL; _this = NULL;
} }
/* Load the GL driver library */
int int
SDL_GL_LoadLibrary(const char *path) SDL_GL_LoadLibrary(const char *path)
{ {
int retval; int retval;
retval = -1; if (!_this) {
if (_this == NULL) { SDL_UninitializedVideo();
SDL_SetError("Video subsystem has not been initialized"); return -1;
}
if (_this->GL_LoadLibrary) {
retval = _this->GL_LoadLibrary(_this, path);
} else { } else {
if (_this->GL_LoadLibrary) { SDL_SetError("No dynamic GL support in video driver");
retval = _this->GL_LoadLibrary(_this, path); retval = -1;
} else {
SDL_SetError("No dynamic GL support in video driver");
}
} }
return (retval); return (retval);
} }
...@@ -2001,6 +2021,11 @@ SDL_GL_GetProcAddress(const char *proc) ...@@ -2001,6 +2021,11 @@ SDL_GL_GetProcAddress(const char *proc)
{ {
void *func; void *func;
if (!_this) {
SDL_UninitializedVideo();
return NULL;
}
func = NULL; func = NULL;
if (_this->GL_GetProcAddress) { if (_this->GL_GetProcAddress) {
if (_this->gl_config.driver_loaded) { if (_this->gl_config.driver_loaded) {
...@@ -2014,12 +2039,16 @@ SDL_GL_GetProcAddress(const char *proc) ...@@ -2014,12 +2039,16 @@ SDL_GL_GetProcAddress(const char *proc)
return func; return func;
} }
/* Set the specified GL attribute for setting up a GL video mode */
int int
SDL_GL_SetAttribute(SDL_GLattr attr, int value) SDL_GL_SetAttribute(SDL_GLattr attr, int value)
{ {
int retval; int retval;
if (!_this) {
SDL_UninitializedVideo();
return -1;
}
retval = 0; retval = 0;
switch (attr) { switch (attr) {
case SDL_GL_RED_SIZE: case SDL_GL_RED_SIZE:
...@@ -2075,30 +2104,113 @@ SDL_GL_SetAttribute(SDL_GLattr attr, int value) ...@@ -2075,30 +2104,113 @@ SDL_GL_SetAttribute(SDL_GLattr attr, int value)
retval = -1; retval = -1;
break; break;
} }
return (retval); return retval;
} }
/* Retrieve an attribute value from the windowing system. */
int int
SDL_GL_GetAttribute(SDL_GLattr attr, int *value) SDL_GL_GetWindowAttribute(SDL_WindowID windowID, SDL_GLattr attr, int *value)
{ {
int retval = -1; SDL_Window *window = SDL_GetWindowFromID(windowID);
int retval;
if (!window) {
return -1;
}
if (_this->GL_GetAttribute) { if (_this->GL_GetAttribute) {
retval = _this->GL_GetAttribute(_this, attr, value); retval = _this->GL_GetAttribute(_this, attr, value);
} else { } else {
*value = 0; *value = 0;
SDL_SetError("GL_GetAttribute not supported"); SDL_SetError("GL_GetAttribute not supported");
retval = -1;
} }
return retval; return retval;
} }
/* Perform a GL buffer swap on the current GL context */ SDL_GLContext
SDL_GL_CreateContext(SDL_WindowID windowID)
{
SDL_Window *window = SDL_GetWindowFromID(windowID);
if (!window) {
return NULL;
}
if (!(window->flags & SDL_WINDOW_OPENGL)) {
SDL_SetError("The specified window isn't an OpenGL window");
return NULL;
}
return _this->GL_CreateContext(_this, window);
}
int
SDL_GL_MakeCurrent(SDL_WindowID windowID, SDL_GLContext context)
{
SDL_Window *window = SDL_GetWindowFromID(windowID);
if (!window || !context) {
return -1;
}
if (!(window->flags & SDL_WINDOW_OPENGL)) {
SDL_SetError("The specified window isn't an OpenGL window");
return -1;
}
return _this->GL_MakeCurrent(_this, window, context);
}
int
SDL_GL_SetSwapInterval(int interval)
{
if (!_this) {
SDL_UninitializedVideo();
return -1;
}
if (_this->GL_SetSwapInterval) {
return _this->GL_SetSwapInterval(_this, interval);
} else {
SDL_SetError("Setting the swap interval is not supported");
return -1;
}
}
int
SDL_GL_GetSwapInterval(void)
{
if (!_this) {
SDL_UninitializedVideo();
return -1;
}
if (_this->GL_GetSwapInterval) {
return _this->GL_GetSwapInterval(_this);
} else {
SDL_SetError("Getting the swap interval is not supported");
return -1;
}
}
void void
SDL_GL_SwapBuffers(void) SDL_GL_SwapWindow(SDL_WindowID windowID)
{ {
// FIXME: Track the current window context - do we provide N contexts, and match them to M windows, or is there a one-to-one mapping? SDL_Window *window = SDL_GetWindowFromID(windowID);
_this->GL_SwapBuffers(_this);
if (!window) {
return;
}
if (!(window->flags & SDL_WINDOW_OPENGL)) {
SDL_SetError("The specified window isn't an OpenGL window");
return;
}
return _this->GL_SwapWindow(_this, window);
}
void
SDL_GL_DeleteContext(SDL_GLContext context)
{
if (!_this || !context) {
return;
}
_this->GL_DeleteContext(_this, context);
} }
#if 0 // FIXME #if 0 // FIXME
......
This diff is collapsed.
...@@ -457,16 +457,16 @@ RunGLTest(int argc, char *argv[], ...@@ -457,16 +457,16 @@ RunGLTest(int argc, char *argv[],
if (accel) { if (accel) {
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
} }
if (sync) {
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
} else {
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0);
}
if (SDL_SetVideoMode(w, h, bpp, video_flags) == NULL) { if (SDL_SetVideoMode(w, h, bpp, video_flags) == NULL) {
fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError()); fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError());
SDL_Quit(); SDL_Quit();
exit(1); exit(1);
} }
if (sync) {
SDL_GL_SetSwapInterval(1);
} else {
SDL_GL_SetSwapInterval(0);
}
printf("Screen BPP: %d\n", SDL_GetVideoSurface()->format->BitsPerPixel); printf("Screen BPP: %d\n", SDL_GetVideoSurface()->format->BitsPerPixel);
printf("\n"); printf("\n");
...@@ -498,8 +498,8 @@ RunGLTest(int argc, char *argv[], ...@@ -498,8 +498,8 @@ RunGLTest(int argc, char *argv[],
printf("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value); printf("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value);
} }
if (sync) { if (sync) {
SDL_GL_GetAttribute(SDL_GL_SWAP_CONTROL, &value); printf("Buffer swap interval: requested 1, got %d\n",
printf("SDL_GL_SWAP_CONTROL: requested 1, got %d\n", value); SDL_GL_GetSwapInterval());
} }
/* Set the window manager title bar */ /* Set the window manager title bar */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment