From ebcb7b71ac86cce52ab30f72ce79d6d00ea35ccb Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 17 Jul 2006 06:47:33 +0000 Subject: [PATCH] Implemented Windows OpenGL support Fixed slowdown enumerating display modes, which was hosing OpenGL as well... Removed SDL_ from the render driver prefixes --- src/SDL_compat.c | 2 +- src/video/SDL_sysvideo.h | 15 +- src/video/SDL_video.c | 11 +- src/video/dummy/SDL_nullvideo.c | 2 +- src/video/win32/SDL_d3drender.c | 194 +++++---- src/video/win32/SDL_gdirender.c | 217 +++++----- src/video/win32/SDL_win32events.c | 17 +- src/video/win32/SDL_win32modes.c | 9 +- src/video/win32/SDL_win32opengl.c | 643 ++++++++++++++++++++++++++++++ src/video/win32/SDL_win32opengl.h | 129 ++++++ src/video/win32/SDL_win32video.c | 13 +- src/video/win32/SDL_win32video.h | 1 + src/video/win32/SDL_win32window.c | 18 +- src/video/win32/SDL_win32window.h | 1 + 14 files changed, 1024 insertions(+), 248 deletions(-) create mode 100644 src/video/win32/SDL_win32opengl.c create mode 100644 src/video/win32/SDL_win32opengl.h diff --git a/src/SDL_compat.c b/src/SDL_compat.c index 80c18aff4..cb6a2ee64 100644 --- a/src/SDL_compat.c +++ b/src/SDL_compat.c @@ -337,7 +337,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) SDL_VideoSurface = NULL; } if (SDL_VideoContext) { - SDL_GL_MakeCurrent(0, SDL_VideoContext); + SDL_GL_MakeCurrent(0, NULL); SDL_GL_DeleteContext(SDL_VideoContext); SDL_VideoContext = NULL; } diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 2bb7cb7bf..302cd236d 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -172,6 +172,11 @@ struct SDL_VideoDevice */ int (*VideoInit) (_THIS); + /* Reverse the effects VideoInit() -- called if VideoInit() fails + or if the application is shutting down the video subsystem. + */ + void (*VideoQuit) (_THIS); + /* * * */ /* Display functions */ @@ -221,17 +226,13 @@ struct SDL_VideoDevice SDL_bool(*GetWindowWMInfo) (_THIS, SDL_Window * window, struct SDL_SysWMinfo * info); - /* Reverse the effects VideoInit() -- called if VideoInit() fails - or if the application is shutting down the video subsystem. - */ - void (*VideoQuit) (_THIS); - /* * * */ /* OpenGL support */ int (*GL_LoadLibrary) (_THIS, const char *path); void *(*GL_GetProcAddress) (_THIS, const char *proc); - int (*GL_GetAttribute) (_THIS, SDL_GLattr attrib, int *value); + int (*GL_GetWindowAttribute) (_THIS, SDL_Window * window, + SDL_GLattr attrib, int *value); SDL_GLContext(*GL_CreateContext) (_THIS, SDL_Window * window); int (*GL_MakeCurrent) (_THIS, SDL_Window * window, SDL_GLContext context); int (*GL_SetSwapInterval) (_THIS, int interval); @@ -279,7 +280,7 @@ struct SDL_VideoDevice /* * * */ /* Data private to this driver */ void *driverdata; - struct SDL_PrivateGLData *gl_data; + struct SDL_GLDriverData *gl_data; /* * * */ /* The function used to dispose of this structure */ diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index e0c81afe7..7ce375435 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -2117,11 +2117,11 @@ SDL_GL_GetWindowAttribute(SDL_WindowID windowID, SDL_GLattr attr, int *value) return -1; } - if (_this->GL_GetAttribute) { - retval = _this->GL_GetAttribute(_this, attr, value); + if (_this->GL_GetWindowAttribute) { + retval = _this->GL_GetWindowAttribute(_this, window, attr, value); } else { *value = 0; - SDL_SetError("GL_GetAttribute not supported"); + SDL_SetError("GL_GetWindowAttribute not supported"); retval = -1; } return retval; @@ -2147,10 +2147,7 @@ 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)) { + if (window && !(window->flags & SDL_WINDOW_OPENGL)) { SDL_SetError("The specified window isn't an OpenGL window"); return -1; } diff --git a/src/video/dummy/SDL_nullvideo.c b/src/video/dummy/SDL_nullvideo.c index 490c03edf..46d57516d 100644 --- a/src/video/dummy/SDL_nullvideo.c +++ b/src/video/dummy/SDL_nullvideo.c @@ -89,8 +89,8 @@ DUMMY_CreateDevice(int devindex) /* Set the function pointers */ device->VideoInit = DUMMY_VideoInit; - device->SetDisplayMode = DUMMY_SetDisplayMode; device->VideoQuit = DUMMY_VideoQuit; + device->SetDisplayMode = DUMMY_SetDisplayMode; device->PumpEvents = DUMMY_PumpEvents; device->free = DUMMY_DeleteDevice; diff --git a/src/video/win32/SDL_d3drender.c b/src/video/win32/SDL_d3drender.c index ded7b39a6..c30efa4f6 100644 --- a/src/video/win32/SDL_d3drender.c +++ b/src/video/win32/SDL_d3drender.c @@ -27,43 +27,37 @@ /* Direct3D renderer implementation */ -static SDL_Renderer *SDL_D3D_CreateRenderer(SDL_Window * window, - Uint32 flags); -static int SDL_D3D_CreateTexture(SDL_Renderer * renderer, - SDL_Texture * texture); -static int SDL_D3D_SetTexturePalette(SDL_Renderer * renderer, - SDL_Texture * texture, - const SDL_Color * colors, int firstcolor, - int ncolors); -static int SDL_D3D_GetTexturePalette(SDL_Renderer * renderer, - SDL_Texture * texture, - SDL_Color * colors, int firstcolor, - int ncolors); -static int SDL_D3D_UpdateTexture(SDL_Renderer * renderer, - SDL_Texture * texture, const SDL_Rect * rect, - const void *pixels, int pitch); -static int SDL_D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, int markDirty, - void **pixels, int *pitch); -static void SDL_D3D_UnlockTexture(SDL_Renderer * renderer, - SDL_Texture * texture); -static void SDL_D3D_DirtyTexture(SDL_Renderer * renderer, - SDL_Texture * texture, int numrects, - const SDL_Rect * rects); -static int SDL_D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 color); -static int SDL_D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, - const SDL_Rect * dstrect, int blendMode, - int scaleMode); -static void SDL_D3D_RenderPresent(SDL_Renderer * renderer); -static void SDL_D3D_DestroyTexture(SDL_Renderer * renderer, - SDL_Texture * texture); -static void SDL_D3D_DestroyRenderer(SDL_Renderer * renderer); - - -SDL_RenderDriver SDL_D3D_RenderDriver = { - SDL_D3D_CreateRenderer, +static SDL_Renderer *D3D_CreateRenderer(SDL_Window * window, Uint32 flags); +static int D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static int D3D_SetTexturePalette(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Color * colors, int firstcolor, + int ncolors); +static int D3D_GetTexturePalette(SDL_Renderer * renderer, + SDL_Texture * texture, SDL_Color * colors, + int firstcolor, int ncolors); +static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, + int pitch); +static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, int markDirty, + void **pixels, int *pitch); +static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static void D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, + int numrects, const SDL_Rect * rects); +static int D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 color); +static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_Rect * dstrect, + int blendMode, int scaleMode); +static void D3D_RenderPresent(SDL_Renderer * renderer); +static void D3D_DestroyTexture(SDL_Renderer * renderer, + SDL_Texture * texture); +static void D3D_DestroyRenderer(SDL_Renderer * renderer); + + +SDL_RenderDriver D3D_RenderDriver = { + D3D_CreateRenderer, { "d3d", (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy | @@ -93,12 +87,12 @@ typedef struct { IDirect3DDevice9 *device; SDL_bool beginScene; -} SDL_D3D_RenderData; +} D3D_RenderData; typedef struct { IDirect3DTexture9 *texture; -} SDL_D3D_TextureData; +} D3D_TextureData; typedef struct { @@ -225,18 +219,18 @@ D3D_AddRenderDriver(_THIS) SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; if (data->d3d) { - SDL_AddRenderDriver(0, &SDL_D3D_RenderDriver); + SDL_AddRenderDriver(0, &D3D_RenderDriver); } } SDL_Renderer * -SDL_D3D_CreateRenderer(SDL_Window * window, Uint32 flags) +D3D_CreateRenderer(SDL_Window * window, Uint32 flags) { SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); SDL_VideoData *videodata = (SDL_VideoData *) display->device->driverdata; SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; SDL_Renderer *renderer; - SDL_D3D_RenderData *data; + D3D_RenderData *data; HRESULT result; D3DPRESENT_PARAMETERS pparams; IDirect3DSwapChain9 *chain; @@ -248,27 +242,27 @@ SDL_D3D_CreateRenderer(SDL_Window * window, Uint32 flags) } SDL_zerop(renderer); - data = (SDL_D3D_RenderData *) SDL_malloc(sizeof(*data)); + data = (D3D_RenderData *) SDL_malloc(sizeof(*data)); if (!data) { - SDL_D3D_DestroyRenderer(renderer); + D3D_DestroyRenderer(renderer); SDL_OutOfMemory(); return NULL; } SDL_zerop(data); - renderer->CreateTexture = SDL_D3D_CreateTexture; - renderer->SetTexturePalette = SDL_D3D_SetTexturePalette; - renderer->GetTexturePalette = SDL_D3D_GetTexturePalette; - renderer->UpdateTexture = SDL_D3D_UpdateTexture; - renderer->LockTexture = SDL_D3D_LockTexture; - renderer->UnlockTexture = SDL_D3D_UnlockTexture; - renderer->DirtyTexture = SDL_D3D_DirtyTexture; - renderer->RenderFill = SDL_D3D_RenderFill; - renderer->RenderCopy = SDL_D3D_RenderCopy; - renderer->RenderPresent = SDL_D3D_RenderPresent; - renderer->DestroyTexture = SDL_D3D_DestroyTexture; - renderer->DestroyRenderer = SDL_D3D_DestroyRenderer; - renderer->info = SDL_D3D_RenderDriver.info; + renderer->CreateTexture = D3D_CreateTexture; + renderer->SetTexturePalette = D3D_SetTexturePalette; + renderer->GetTexturePalette = D3D_GetTexturePalette; + renderer->UpdateTexture = D3D_UpdateTexture; + renderer->LockTexture = D3D_LockTexture; + renderer->UnlockTexture = D3D_UnlockTexture; + renderer->DirtyTexture = D3D_DirtyTexture; + renderer->RenderFill = D3D_RenderFill; + renderer->RenderCopy = D3D_RenderCopy; + renderer->RenderPresent = D3D_RenderPresent; + renderer->DestroyTexture = D3D_DestroyTexture; + renderer->DestroyRenderer = D3D_DestroyRenderer; + renderer->info = D3D_RenderDriver.info; renderer->window = window->id; renderer->driverdata = data; @@ -316,7 +310,7 @@ SDL_D3D_CreateRenderer(SDL_Window * window, Uint32 flags) D3DCREATE_SOFTWARE_VERTEXPROCESSING, &pparams, &data->device); if (FAILED(result)) { - SDL_D3D_DestroyRenderer(renderer); + D3D_DestroyRenderer(renderer); D3D_SetError("CreateDevice()", result); return NULL; } @@ -325,14 +319,14 @@ SDL_D3D_CreateRenderer(SDL_Window * window, Uint32 flags) /* Get presentation parameters to fill info */ result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); if (FAILED(result)) { - SDL_D3D_DestroyRenderer(renderer); + D3D_DestroyRenderer(renderer); D3D_SetError("GetSwapChain()", result); return NULL; } result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams); if (FAILED(result)) { IDirect3DSwapChain9_Release(chain); - SDL_D3D_DestroyRenderer(renderer); + D3D_DestroyRenderer(renderer); D3D_SetError("GetPresentParameters()", result); return NULL; } @@ -376,17 +370,16 @@ SDL_D3D_CreateRenderer(SDL_Window * window, Uint32 flags) } static int -SDL_D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { - SDL_D3D_RenderData *renderdata = - (SDL_D3D_RenderData *) renderer->driverdata; + D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata; SDL_Window *window = SDL_GetWindowFromID(renderer->window); SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); - SDL_D3D_TextureData *data; + D3D_TextureData *data; D3DPOOL pool; HRESULT result; - data = (SDL_D3D_TextureData *) SDL_malloc(sizeof(*data)); + data = (D3D_TextureData *) SDL_malloc(sizeof(*data)); if (!data) { SDL_OutOfMemory(); return -1; @@ -415,33 +408,30 @@ SDL_D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) } static int -SDL_D3D_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Color * colors, int firstcolor, - int ncolors) +D3D_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Color * colors, int firstcolor, int ncolors) { - SDL_D3D_RenderData *renderdata = - (SDL_D3D_RenderData *) renderer->driverdata; - SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata; + D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata; + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; return 0; } static int -SDL_D3D_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, - SDL_Color * colors, int firstcolor, int ncolors) +D3D_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, + SDL_Color * colors, int firstcolor, int ncolors) { - SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata; + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; return 0; } static int -SDL_D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, const void *pixels, int pitch) +D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, int pitch) { - SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata; - SDL_D3D_RenderData *renderdata = - (SDL_D3D_RenderData *) renderer->driverdata; + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; + D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata; IDirect3DTexture9 *temp; RECT d3drect; D3DLOCKED_RECT locked; @@ -496,11 +486,11 @@ SDL_D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, } static int -SDL_D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, int markDirty, void **pixels, - int *pitch) +D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, int markDirty, void **pixels, + int *pitch) { - SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata; + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; RECT d3drect; D3DLOCKED_RECT locked; HRESULT result; @@ -528,18 +518,18 @@ SDL_D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, } static void -SDL_D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) { - SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata; + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; IDirect3DTexture9_UnlockRect(data->texture, 0); } static void -SDL_D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, - int numrects, const SDL_Rect * rects) +D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects, + const SDL_Rect * rects) { - SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata; + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; RECT d3drect; int i; @@ -556,10 +546,9 @@ SDL_D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, } static int -SDL_D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 color) +D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 color) { - SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; + D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; D3DRECT d3drect; HRESULT result; @@ -584,13 +573,12 @@ SDL_D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, } static int -SDL_D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - int blendMode, int scaleMode) +D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_Rect * dstrect, + int blendMode, int scaleMode) { - SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; - SDL_D3D_TextureData *texturedata = - (SDL_D3D_TextureData *) texture->driverdata; + D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata; float minx, miny, maxx, maxy; float minu, maxu, minv, maxv; Vertex vertices[4]; @@ -658,9 +646,9 @@ SDL_D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, } static void -SDL_D3D_RenderPresent(SDL_Renderer * renderer) +D3D_RenderPresent(SDL_Renderer * renderer) { - SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; + D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; HRESULT result; if (!data->beginScene) { @@ -675,9 +663,9 @@ SDL_D3D_RenderPresent(SDL_Renderer * renderer) } static void -SDL_D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) { - SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata; + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; if (!data) { return; @@ -690,9 +678,9 @@ SDL_D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) } void -SDL_D3D_DestroyRenderer(SDL_Renderer * renderer) +D3D_DestroyRenderer(SDL_Renderer * renderer) { - SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; + D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; if (data) { if (data->device) { diff --git a/src/video/win32/SDL_gdirender.c b/src/video/win32/SDL_gdirender.c index 6e8e85c9f..81ad72ca5 100644 --- a/src/video/win32/SDL_gdirender.c +++ b/src/video/win32/SDL_gdirender.c @@ -29,46 +29,40 @@ /* GDI renderer implementation */ -static SDL_Renderer *SDL_GDI_CreateRenderer(SDL_Window * window, - Uint32 flags); -static int SDL_GDI_CreateTexture(SDL_Renderer * renderer, - SDL_Texture * texture); -static int SDL_GDI_QueryTexturePixels(SDL_Renderer * renderer, - SDL_Texture * texture, void **pixels, - int *pitch); -static int SDL_GDI_SetTexturePalette(SDL_Renderer * renderer, - SDL_Texture * texture, - const SDL_Color * colors, int firstcolor, - int ncolors); -static int SDL_GDI_GetTexturePalette(SDL_Renderer * renderer, - SDL_Texture * texture, - SDL_Color * colors, int firstcolor, - int ncolors); -static int SDL_GDI_UpdateTexture(SDL_Renderer * renderer, - SDL_Texture * texture, const SDL_Rect * rect, - const void *pixels, int pitch); -static int SDL_GDI_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, int markDirty, - void **pixels, int *pitch); -static void SDL_GDI_UnlockTexture(SDL_Renderer * renderer, - SDL_Texture * texture); -static void SDL_GDI_DirtyTexture(SDL_Renderer * renderer, - SDL_Texture * texture, int numrects, - const SDL_Rect * rects); -static int SDL_GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 color); -static int SDL_GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, - const SDL_Rect * dstrect, int blendMode, - int scaleMode); -static void SDL_GDI_RenderPresent(SDL_Renderer * renderer); -static void SDL_GDI_DestroyTexture(SDL_Renderer * renderer, - SDL_Texture * texture); -static void SDL_GDI_DestroyRenderer(SDL_Renderer * renderer); - - -SDL_RenderDriver SDL_GDI_RenderDriver = { - SDL_GDI_CreateRenderer, +static SDL_Renderer *GDI_CreateRenderer(SDL_Window * window, Uint32 flags); +static int GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static int GDI_QueryTexturePixels(SDL_Renderer * renderer, + SDL_Texture * texture, void **pixels, + int *pitch); +static int GDI_SetTexturePalette(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Color * colors, int firstcolor, + int ncolors); +static int GDI_GetTexturePalette(SDL_Renderer * renderer, + SDL_Texture * texture, SDL_Color * colors, + int firstcolor, int ncolors); +static int GDI_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, + int pitch); +static int GDI_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, int markDirty, + void **pixels, int *pitch); +static void GDI_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static void GDI_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, + int numrects, const SDL_Rect * rects); +static int GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 color); +static int GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_Rect * dstrect, + int blendMode, int scaleMode); +static void GDI_RenderPresent(SDL_Renderer * renderer); +static void GDI_DestroyTexture(SDL_Renderer * renderer, + SDL_Texture * texture); +static void GDI_DestroyRenderer(SDL_Renderer * renderer); + + +SDL_RenderDriver GDI_RenderDriver = { + GDI_CreateRenderer, { "gdi", (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy | @@ -106,7 +100,7 @@ typedef struct int current_hbm; SDL_DirtyRectList dirty; SDL_bool makedirty; -} SDL_GDI_RenderData; +} GDI_RenderData; typedef struct { @@ -116,12 +110,12 @@ typedef struct HBITMAP hbm; void *pixels; int pitch; -} SDL_GDI_TextureData; +} GDI_TextureData; static void UpdateYUVTextureData(SDL_Texture * texture) { - SDL_GDI_TextureData *data = (SDL_GDI_TextureData *) texture->driverdata; + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; SDL_Rect rect; rect.x = 0; @@ -135,15 +129,15 @@ UpdateYUVTextureData(SDL_Texture * texture) void GDI_AddRenderDriver(_THIS) { - SDL_AddRenderDriver(0, &SDL_GDI_RenderDriver); + SDL_AddRenderDriver(0, &GDI_RenderDriver); } SDL_Renderer * -SDL_GDI_CreateRenderer(SDL_Window * window, Uint32 flags) +GDI_CreateRenderer(SDL_Window * window, Uint32 flags) { SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; SDL_Renderer *renderer; - SDL_GDI_RenderData *data; + GDI_RenderData *data; int bmi_size; HBITMAP hbm; int i, n; @@ -155,35 +149,35 @@ SDL_GDI_CreateRenderer(SDL_Window * window, Uint32 flags) } SDL_zerop(renderer); - data = (SDL_GDI_RenderData *) SDL_malloc(sizeof(*data)); + data = (GDI_RenderData *) SDL_malloc(sizeof(*data)); if (!data) { - SDL_GDI_DestroyRenderer(renderer); + GDI_DestroyRenderer(renderer); SDL_OutOfMemory(); return NULL; } SDL_zerop(data); - renderer->CreateTexture = SDL_GDI_CreateTexture; - renderer->QueryTexturePixels = SDL_GDI_QueryTexturePixels; - renderer->SetTexturePalette = SDL_GDI_SetTexturePalette; - renderer->GetTexturePalette = SDL_GDI_GetTexturePalette; - renderer->UpdateTexture = SDL_GDI_UpdateTexture; - renderer->LockTexture = SDL_GDI_LockTexture; - renderer->UnlockTexture = SDL_GDI_UnlockTexture; - renderer->DirtyTexture = SDL_GDI_DirtyTexture; - renderer->RenderFill = SDL_GDI_RenderFill; - renderer->RenderCopy = SDL_GDI_RenderCopy; - renderer->RenderPresent = SDL_GDI_RenderPresent; - renderer->DestroyTexture = SDL_GDI_DestroyTexture; - renderer->DestroyRenderer = SDL_GDI_DestroyRenderer; - renderer->info = SDL_GDI_RenderDriver.info; + renderer->CreateTexture = GDI_CreateTexture; + renderer->QueryTexturePixels = GDI_QueryTexturePixels; + renderer->SetTexturePalette = GDI_SetTexturePalette; + renderer->GetTexturePalette = GDI_GetTexturePalette; + renderer->UpdateTexture = GDI_UpdateTexture; + renderer->LockTexture = GDI_LockTexture; + renderer->UnlockTexture = GDI_UnlockTexture; + renderer->DirtyTexture = GDI_DirtyTexture; + renderer->RenderFill = GDI_RenderFill; + renderer->RenderCopy = GDI_RenderCopy; + renderer->RenderPresent = GDI_RenderPresent; + renderer->DestroyTexture = GDI_DestroyTexture; + renderer->DestroyRenderer = GDI_DestroyRenderer; + renderer->info = GDI_RenderDriver.info; renderer->window = window->id; renderer->driverdata = data; renderer->info.flags = SDL_Renderer_Accelerated; data->hwnd = windowdata->hwnd; - data->window_hdc = GetDC(data->hwnd); + data->window_hdc = windowdata->hdc; data->render_hdc = CreateCompatibleDC(data->window_hdc); data->memory_hdc = CreateCompatibleDC(data->window_hdc); @@ -191,7 +185,7 @@ SDL_GDI_CreateRenderer(SDL_Window * window, Uint32 flags) bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); data->bmi = (LPBITMAPINFO) SDL_malloc(bmi_size); if (!data->bmi) { - SDL_GDI_DestroyRenderer(renderer); + GDI_DestroyRenderer(renderer); SDL_OutOfMemory(); return NULL; } @@ -221,7 +215,7 @@ SDL_GDI_CreateRenderer(SDL_Window * window, Uint32 flags) data->hbm[i] = CreateCompatibleBitmap(data->window_hdc, window->w, window->h); if (!data->hbm[i]) { - SDL_GDI_DestroyRenderer(renderer); + GDI_DestroyRenderer(renderer); WIN_SetError("CreateCompatibleBitmap()"); return NULL; } @@ -240,15 +234,14 @@ SDL_GDI_CreateRenderer(SDL_Window * window, Uint32 flags) } static int -SDL_GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { - SDL_GDI_RenderData *renderdata = - (SDL_GDI_RenderData *) renderer->driverdata; + GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; SDL_Window *window = SDL_GetWindowFromID(renderer->window); SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); - SDL_GDI_TextureData *data; + GDI_TextureData *data; - data = (SDL_GDI_TextureData *) SDL_malloc(sizeof(*data)); + data = (GDI_TextureData *) SDL_malloc(sizeof(*data)); if (!data) { SDL_OutOfMemory(); return -1; @@ -260,7 +253,7 @@ SDL_GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { data->yuv = SDL_SW_CreateYUVTexture(texture); if (!data->yuv) { - SDL_GDI_DestroyTexture(renderer, texture); + GDI_DestroyTexture(renderer, texture); return -1; } data->format = display->current_mode.format; @@ -277,7 +270,7 @@ SDL_GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); bmi = (LPBITMAPINFO) SDL_malloc(bmi_size); if (!bmi) { - SDL_GDI_DestroyTexture(renderer, texture); + GDI_DestroyTexture(renderer, texture); SDL_OutOfMemory(); return -1; } @@ -303,7 +296,7 @@ SDL_GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ncolors * sizeof(PALETTEENTRY)); if (!palette) { SDL_free(bmi); - SDL_GDI_DestroyTexture(renderer, texture); + GDI_DestroyTexture(renderer, texture); SDL_OutOfMemory(); return -1; } @@ -339,7 +332,7 @@ SDL_GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) data->pixels = NULL; } if (!data->hbm) { - SDL_GDI_DestroyTexture(renderer, texture); + GDI_DestroyTexture(renderer, texture); WIN_SetError("Couldn't create bitmap"); return -1; } @@ -347,10 +340,10 @@ SDL_GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) } static int -SDL_GDI_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, - void **pixels, int *pitch) +GDI_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, + void **pixels, int *pitch) { - SDL_GDI_TextureData *data = (SDL_GDI_TextureData *) texture->driverdata; + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; if (data->yuv) { return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch); @@ -362,13 +355,11 @@ SDL_GDI_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, } static int -SDL_GDI_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Color * colors, int firstcolor, - int ncolors) +GDI_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Color * colors, int firstcolor, int ncolors) { - SDL_GDI_RenderData *renderdata = - (SDL_GDI_RenderData *) renderer->driverdata; - SDL_GDI_TextureData *data = (SDL_GDI_TextureData *) texture->driverdata; + GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; if (data->yuv) { SDL_SetError("YUV textures don't have a palette"); @@ -392,10 +383,10 @@ SDL_GDI_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, } static int -SDL_GDI_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, - SDL_Color * colors, int firstcolor, int ncolors) +GDI_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, + SDL_Color * colors, int firstcolor, int ncolors) { - SDL_GDI_TextureData *data = (SDL_GDI_TextureData *) texture->driverdata; + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; if (data->yuv) { SDL_SetError("YUV textures don't have a palette"); @@ -418,10 +409,10 @@ SDL_GDI_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, } static int -SDL_GDI_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, const void *pixels, int pitch) +GDI_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, int pitch) { - SDL_GDI_TextureData *data = (SDL_GDI_TextureData *) texture->driverdata; + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; if (data->yuv) { if (SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch) < 0) { @@ -430,8 +421,7 @@ SDL_GDI_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, UpdateYUVTextureData(texture); return 0; } else { - SDL_GDI_RenderData *renderdata = - (SDL_GDI_RenderData *) renderer->driverdata; + GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; if (data->pixels) { Uint8 *src, *dst; @@ -465,11 +455,11 @@ SDL_GDI_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, } static int -SDL_GDI_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, int markDirty, void **pixels, - int *pitch) +GDI_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, int markDirty, void **pixels, + int *pitch) { - SDL_GDI_TextureData *data = (SDL_GDI_TextureData *) texture->driverdata; + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; if (data->yuv) { return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels, @@ -488,9 +478,9 @@ SDL_GDI_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, } static void -SDL_GDI_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +GDI_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) { - SDL_GDI_TextureData *data = (SDL_GDI_TextureData *) texture->driverdata; + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; if (data->yuv) { SDL_SW_UnlockYUVTexture(data->yuv); @@ -499,16 +489,15 @@ SDL_GDI_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) } static void -SDL_GDI_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, - int numrects, const SDL_Rect * rects) +GDI_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects, + const SDL_Rect * rects) { } static int -SDL_GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 color) +GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 color) { - SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata; + GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; Uint8 r, g, b; RECT rc; HBRUSH brush; @@ -541,13 +530,12 @@ SDL_GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, } static int -SDL_GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect, - int blendMode, int scaleMode) +GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_Rect * dstrect, + int blendMode, int scaleMode) { - SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata; - SDL_GDI_TextureData *texturedata = - (SDL_GDI_TextureData *) texture->driverdata; + GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; + GDI_TextureData *texturedata = (GDI_TextureData *) texture->driverdata; if (data->makedirty) { SDL_AddDirtyRect(&data->dirty, dstrect); @@ -596,9 +584,9 @@ SDL_GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, } static void -SDL_GDI_RenderPresent(SDL_Renderer * renderer) +GDI_RenderPresent(SDL_Renderer * renderer) { - SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata; + GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; SDL_DirtyRect *dirty; /* Send the data to the display */ @@ -622,9 +610,9 @@ SDL_GDI_RenderPresent(SDL_Renderer * renderer) } static void -SDL_GDI_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +GDI_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) { - SDL_GDI_TextureData *data = (SDL_GDI_TextureData *) texture->driverdata; + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; if (!data) { return; @@ -643,13 +631,12 @@ SDL_GDI_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) } void -SDL_GDI_DestroyRenderer(SDL_Renderer * renderer) +GDI_DestroyRenderer(SDL_Renderer * renderer) { - SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata; + GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; int i; if (data) { - ReleaseDC(data->hwnd, data->window_hdc); DeleteDC(data->render_hdc); DeleteDC(data->memory_hdc); if (data->bmi) { diff --git a/src/video/win32/SDL_win32events.c b/src/video/win32/SDL_win32events.c index c2ce5feca..27befe249 100644 --- a/src/video/win32/SDL_win32events.c +++ b/src/video/win32/SDL_win32events.c @@ -29,6 +29,7 @@ /*#define WMMSG_DEBUG*/ #ifdef WMMSG_DEBUG +#include #include "wmmsg.h" #endif @@ -398,13 +399,17 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam); } #ifdef WMMSG_DEBUG - fprintf(stderr, "Received windows message: "); - if (msg > MAX_WMMSG) { - fprintf(stderr, "%d", msg); - } else { - fprintf(stderr, "%s", wmtab[msg]); + { + FILE *log = fopen("wmmsg.txt", "a"); + fprintf(log, "Received windows message: %p ", hwnd); + if (msg > MAX_WMMSG) { + fprintf(log, "%d", msg); + } else { + fprintf(log, "%s", wmtab[msg]); + } + fprintf(log, " -- 0x%X, 0x%X\n", wParam, lParam); + fclose(log); } - fprintf(stderr, " -- 0x%X, 0x%X\n", wParam, lParam); #endif /* Send a SDL_SYSWMEVENT if the application wants them */ diff --git a/src/video/win32/SDL_win32modes.c b/src/video/win32/SDL_win32modes.c index c4a091750..90e18556f 100644 --- a/src/video/win32/SDL_win32modes.c +++ b/src/video/win32/SDL_win32modes.c @@ -24,10 +24,6 @@ #include "SDL_win32video.h" -/* FIXME: Each call to EnumDisplaySettings() takes about 6 ms on my laptop. - With 500 or so modes, this takes almost 3 seconds to run! -*/ - static SDL_bool WIN_GetDisplayMode(LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode) { @@ -58,8 +54,8 @@ WIN_GetDisplayMode(LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode) mode->refresh_rate = devmode.dmDisplayFrequency; mode->driverdata = data; - hdc = CreateDC(deviceName, NULL, NULL, &devmode); - if (hdc) { + if (index == ENUM_CURRENT_SETTINGS + && (hdc = CreateDC(deviceName, NULL, NULL, NULL)) != NULL) { char bmi_data[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)]; LPBITMAPINFO bmi; HBITMAP hbm; @@ -92,6 +88,7 @@ WIN_GetDisplayMode(LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode) mode->format = SDL_PixelFormat_Index8; } } else { + /* FIXME: Can we tell what this will be? */ switch (devmode.dmBitsPerPel) { case 32: mode->format = SDL_PixelFormat_RGB888; diff --git a/src/video/win32/SDL_win32opengl.c b/src/video/win32/SDL_win32opengl.c new file mode 100644 index 000000000..34e1c8f6d --- /dev/null +++ b/src/video/win32/SDL_win32opengl.c @@ -0,0 +1,643 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_win32video.h" + +/* WGL implementation of SDL OpenGL support */ + +#if SDL_VIDEO_OPENGL +#include "SDL_opengl.h" + +#define DEFAULT_GL_DRIVER_PATH "OPENGL32.DLL" + + +int +WIN_GL_LoadLibrary(_THIS, const char *path) +{ + LPTSTR wpath; + HANDLE handle; + + if (_this->gl_config.driver_loaded) { + if (path) { + SDL_SetError("OpenGL library already loaded"); + return -1; + } else { + ++_this->gl_config.driver_loaded; + return 0; + } + } + if (path == NULL) { + path = DEFAULT_GL_DRIVER_PATH; + } + wpath = WIN_UTF8ToString(path); + handle = LoadLibrary(wpath); + SDL_free(wpath); + if (!handle) { + char message[1024]; + SDL_snprintf(message, SDL_arraysize(message), "LoadLibrary(\"%s\")", + path); + WIN_SetError(message); + return -1; + } + + /* Load function pointers */ + _this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *)) + GetProcAddress(handle, "wglGetProcAddress"); + _this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC)) + GetProcAddress(handle, "wglCreateContext"); + _this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC)) + GetProcAddress(handle, "wglDeleteContext"); + _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC)) + GetProcAddress(handle, "wglMakeCurrent"); + _this->gl_data->wglSwapIntervalEXT = (void (WINAPI *) (int)) + GetProcAddress(handle, "wglSwapIntervalEXT"); + _this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *) (void)) + GetProcAddress(handle, "wglGetSwapIntervalEXT"); + + if (!_this->gl_data->wglGetProcAddress || + !_this->gl_data->wglCreateContext || + !_this->gl_data->wglDeleteContext || + !_this->gl_data->wglMakeCurrent) { + SDL_SetError("Could not retrieve OpenGL functions"); + FreeLibrary(handle); + return -1; + } + + _this->gl_config.dll_handle = handle; + SDL_strlcpy(_this->gl_config.driver_path, path, + SDL_arraysize(_this->gl_config.driver_path)); + _this->gl_config.driver_loaded = 1; + return 0; +} + +void * +WIN_GL_GetProcAddress(_THIS, const char *proc) +{ + void *func; + + /* This is to pick up extensions */ + func = _this->gl_data->wglGetProcAddress(proc); + if (!func) { + /* This is probably a normal GL function */ + func = GetProcAddress(_this->gl_config.dll_handle, proc); + } + return func; +} + +static void +WIN_GL_UnloadLibrary(_THIS) +{ + if (_this->gl_config.driver_loaded > 0) { + if (--_this->gl_config.driver_loaded > 0) { + return; + } + FreeLibrary((HMODULE) _this->gl_config.dll_handle); + _this->gl_config.dll_handle = NULL; + } +} + +static void +WIN_GL_SetupPixelFormat(_THIS, PIXELFORMATDESCRIPTOR * pfd) +{ + SDL_zerop(pfd); + pfd->nSize = sizeof(*pfd); + pfd->nVersion = 1; + pfd->dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL); + if (_this->gl_config.double_buffer) { + pfd->dwFlags |= PFD_DOUBLEBUFFER; + } + if (_this->gl_config.stereo) { + pfd->dwFlags |= PFD_STEREO; + } + pfd->iLayerType = PFD_MAIN_PLANE; + pfd->iPixelType = PFD_TYPE_RGBA; + pfd->cRedBits = _this->gl_config.red_size; + pfd->cGreenBits = _this->gl_config.green_size; + pfd->cBlueBits = _this->gl_config.blue_size; + pfd->cAlphaBits = _this->gl_config.alpha_size; + if (_this->gl_config.buffer_size) { + pfd->cColorBits = + _this->gl_config.buffer_size - _this->gl_config.alpha_size; + } else { + pfd->cColorBits = (pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits); + } + pfd->cAccumRedBits = _this->gl_config.accum_red_size; + pfd->cAccumGreenBits = _this->gl_config.accum_green_size; + pfd->cAccumBlueBits = _this->gl_config.accum_blue_size; + pfd->cAccumAlphaBits = _this->gl_config.accum_alpha_size; + pfd->cAccumBits = + (pfd->cAccumRedBits + pfd->cAccumGreenBits + pfd->cAccumBlueBits + + pfd->cAccumAlphaBits); + pfd->cDepthBits = _this->gl_config.depth_size; + pfd->cStencilBits = _this->gl_config.stencil_size; +} + +static SDL_bool +HasExtension(const char *extension, const char *extensions) +{ + const char *start; + const char *where, *terminator; + + /* Extension names should not have spaces. */ + where = SDL_strchr(extension, ' '); + if (where || *extension == '\0') + return SDL_FALSE; + + if (!extensions) + return SDL_FALSE; + + /* It takes a bit of care to be fool-proof about parsing the + * OpenGL extensions string. Don't be fooled by sub-strings, + * etc. */ + + start = extensions; + + for (;;) { + where = SDL_strstr(start, extension); + if (!where) + break; + + terminator = where + SDL_strlen(extension); + if (where == start || *(where - 1) == ' ') + if (*terminator == ' ' || *terminator == '\0') + return SDL_TRUE; + + start = terminator; + } + return SDL_FALSE; +} + +static void +WIN_GL_InitExtensions(_THIS) +{ + HWND hwnd; + HDC hdc; + PIXELFORMATDESCRIPTOR pfd; + int pixel_format; + HGLRC hglrc; + const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0; + const GLubyte *(WINAPI * glGetStringFunc) (GLenum); + const char *extensions; + + hwnd = + CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0, + 10, 10, NULL, NULL, SDL_Instance, NULL); + WIN_PumpEvents(_this); + + hdc = GetDC(hwnd); + + WIN_GL_SetupPixelFormat(_this, &pfd); + pixel_format = ChoosePixelFormat(hdc, &pfd); + SetPixelFormat(hdc, pixel_format, &pfd); + + hglrc = _this->gl_data->wglCreateContext(hdc); + if (hglrc) { + _this->gl_data->wglMakeCurrent(hdc, hglrc); + } + + wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC)) + _this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB"); + if (wglGetExtensionsStringARB) { + extensions = wglGetExtensionsStringARB(hdc); + } else { + extensions = NULL; + } + + /* Check for WGL_ARB_pixel_format */ + _this->gl_data->WGL_ARB_pixel_format = 0; + if (HasExtension("WGL_ARB_pixel_format", extensions)) { + _this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *) + (HDC, const int *, + const FLOAT *, UINT, + int *, UINT *)) + WIN_GL_GetProcAddress(_this, "wglChoosePixelFormatARB"); + _this->gl_data->wglGetPixelFormatAttribivARB = + (BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *)) + WIN_GL_GetProcAddress(_this, "wglGetPixelFormatAttribivARB"); + + if ((_this->gl_data->wglChoosePixelFormatARB != NULL) && + (_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) { + _this->gl_data->WGL_ARB_pixel_format = 1; + } + } + + glGetStringFunc = WIN_GL_GetProcAddress(_this, "glGetString"); + if (glGetStringFunc) { + extensions = (const char *) glGetStringFunc(GL_EXTENSIONS); + } else { + /* Uh oh, something is seriously wrong here... */ + extensions = NULL; + } + + /* Check for WGL_EXT_swap_control */ + if (HasExtension("WGL_EXT_swap_control", extensions)) { + _this->gl_data->wglSwapIntervalEXT = + WIN_GL_GetProcAddress(_this, "wglSwapIntervalEXT"); + _this->gl_data->wglGetSwapIntervalEXT = + WIN_GL_GetProcAddress(_this, "wglGetSwapIntervalEXT"); + } + + if (hglrc) { + _this->gl_data->wglMakeCurrent(NULL, NULL); + _this->gl_data->wglDeleteContext(hglrc); + } + ReleaseDC(hwnd, hdc); + DestroyWindow(hwnd); + WIN_PumpEvents(_this); +} + +static void +WIN_GL_Shutdown(_THIS) +{ + if (!_this->gl_data || (--_this->gl_data->initialized > 0)) { + return; + } + + WIN_GL_UnloadLibrary(_this); + + SDL_free(_this->gl_data); + _this->gl_data = NULL; +} + +static int +WIN_GL_Initialize(_THIS) +{ + if (_this->gl_data) { + ++_this->gl_data->initialized; + return 0; + } + + _this->gl_data = + (struct SDL_GLDriverData *) SDL_calloc(1, + sizeof(struct + SDL_GLDriverData)); + if (!_this->gl_data) { + SDL_OutOfMemory(); + return -1; + } + _this->gl_data->initialized = 1; + + if (WIN_GL_LoadLibrary(_this, NULL) < 0) { + return -1; + } + + /* Initialize extensions */ + WIN_GL_InitExtensions(_this); + + return 0; +} + +int +WIN_GL_SetupWindow(_THIS, SDL_Window * window) +{ + HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; + PIXELFORMATDESCRIPTOR pfd; + int pixel_format; + unsigned int matching; + int iAttribs[64]; + int *iAttr; + float fAttribs[1] = { 0 }; + + if (WIN_GL_Initialize(_this) < 0) { + return -1; + } + + WIN_GL_SetupPixelFormat(_this, &pfd); + + /* setup WGL_ARB_pixel_format attribs */ + iAttr = &iAttribs[0]; + + *iAttr++ = WGL_DRAW_TO_WINDOW_ARB; + *iAttr++ = GL_TRUE; + *iAttr++ = WGL_ACCELERATION_ARB; + *iAttr++ = WGL_FULL_ACCELERATION_ARB; + *iAttr++ = WGL_RED_BITS_ARB; + *iAttr++ = _this->gl_config.red_size; + *iAttr++ = WGL_GREEN_BITS_ARB; + *iAttr++ = _this->gl_config.green_size; + *iAttr++ = WGL_BLUE_BITS_ARB; + *iAttr++ = _this->gl_config.blue_size; + + if (_this->gl_config.alpha_size) { + *iAttr++ = WGL_ALPHA_BITS_ARB; + *iAttr++ = _this->gl_config.alpha_size; + } + + *iAttr++ = WGL_DOUBLE_BUFFER_ARB; + *iAttr++ = _this->gl_config.double_buffer; + + *iAttr++ = WGL_DEPTH_BITS_ARB; + *iAttr++ = _this->gl_config.depth_size; + + if (_this->gl_config.stencil_size) { + *iAttr++ = WGL_STENCIL_BITS_ARB; + *iAttr++ = _this->gl_config.stencil_size; + } + + if (_this->gl_config.accum_red_size) { + *iAttr++ = WGL_ACCUM_RED_BITS_ARB; + *iAttr++ = _this->gl_config.accum_red_size; + } + + if (_this->gl_config.accum_green_size) { + *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB; + *iAttr++ = _this->gl_config.accum_green_size; + } + + if (_this->gl_config.accum_blue_size) { + *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB; + *iAttr++ = _this->gl_config.accum_blue_size; + } + + if (_this->gl_config.accum_alpha_size) { + *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB; + *iAttr++ = _this->gl_config.accum_alpha_size; + } + + if (_this->gl_config.stereo) { + *iAttr++ = WGL_STEREO_ARB; + *iAttr++ = GL_TRUE; + } + + if (_this->gl_config.multisamplebuffers) { + *iAttr++ = WGL_SAMPLE_BUFFERS_ARB; + *iAttr++ = _this->gl_config.multisamplebuffers; + } + + if (_this->gl_config.multisamplesamples) { + *iAttr++ = WGL_SAMPLES_ARB; + *iAttr++ = _this->gl_config.multisamplesamples; + } + + if (_this->gl_config.accelerated >= 0) { + *iAttr++ = WGL_ACCELERATION_ARB; + *iAttr++ = + (_this->gl_config. + accelerated ? WGL_GENERIC_ACCELERATION_ARB : + WGL_NO_ACCELERATION_ARB); + } + + *iAttr = 0; + + /* Choose and set the closest available pixel format */ + if (!_this->gl_data->WGL_ARB_pixel_format + || !_this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs, + 1, &pixel_format, + &matching) || !matching) { + pixel_format = ChoosePixelFormat(hdc, &pfd); + } + if (!pixel_format) { + SDL_SetError("No matching GL pixel format available"); + return -1; + } + if (!SetPixelFormat(hdc, pixel_format, &pfd)) { + WIN_SetError("SetPixelFormat()"); + return (-1); + } + return 0; +} + +void +WIN_GL_CleanupWindow(_THIS, SDL_Window * window) +{ + WIN_GL_Shutdown(_this); +} + +int +WIN_GL_GetWindowAttribute(_THIS, SDL_Window * window, SDL_GLattr attrib, + int *value) +{ + HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; + int pixel_format; + + pixel_format = GetPixelFormat(hdc); + + if (_this->gl_data->WGL_ARB_pixel_format) { + int wgl_attrib; + + switch (attrib) { + case SDL_GL_RED_SIZE: + wgl_attrib = WGL_RED_BITS_ARB; + break; + case SDL_GL_GREEN_SIZE: + wgl_attrib = WGL_GREEN_BITS_ARB; + break; + case SDL_GL_BLUE_SIZE: + wgl_attrib = WGL_BLUE_BITS_ARB; + break; + case SDL_GL_ALPHA_SIZE: + wgl_attrib = WGL_ALPHA_BITS_ARB; + break; + case SDL_GL_DOUBLEBUFFER: + wgl_attrib = WGL_DOUBLE_BUFFER_ARB; + break; + case SDL_GL_BUFFER_SIZE: + wgl_attrib = WGL_COLOR_BITS_ARB; + break; + case SDL_GL_DEPTH_SIZE: + wgl_attrib = WGL_DEPTH_BITS_ARB; + break; + case SDL_GL_STENCIL_SIZE: + wgl_attrib = WGL_STENCIL_BITS_ARB; + break; + case SDL_GL_ACCUM_RED_SIZE: + wgl_attrib = WGL_ACCUM_RED_BITS_ARB; + break; + case SDL_GL_ACCUM_GREEN_SIZE: + wgl_attrib = WGL_ACCUM_GREEN_BITS_ARB; + break; + case SDL_GL_ACCUM_BLUE_SIZE: + wgl_attrib = WGL_ACCUM_BLUE_BITS_ARB; + break; + case SDL_GL_ACCUM_ALPHA_SIZE: + wgl_attrib = WGL_ACCUM_ALPHA_BITS_ARB; + break; + case SDL_GL_STEREO: + wgl_attrib = WGL_STEREO_ARB; + break; + case SDL_GL_MULTISAMPLEBUFFERS: + wgl_attrib = WGL_SAMPLE_BUFFERS_ARB; + break; + case SDL_GL_MULTISAMPLESAMPLES: + wgl_attrib = WGL_SAMPLES_ARB; + break; + case SDL_GL_ACCELERATED_VISUAL: + wgl_attrib = WGL_ACCELERATION_ARB; + _this->gl_data->wglGetPixelFormatAttribivARB(hdc, pixel_format, 0, + 1, &wgl_attrib, + value); + if (*value == WGL_NO_ACCELERATION_ARB) { + *value = SDL_FALSE; + } else { + *value = SDL_TRUE; + } + return 0; + break; + default: + return (-1); + } + _this->gl_data->wglGetPixelFormatAttribivARB(hdc, pixel_format, 0, 1, + &wgl_attrib, value); + return 0; + } else { + PIXELFORMATDESCRIPTOR pfd; + int retval; + + if (!DescribePixelFormat(hdc, pixel_format, sizeof(pfd), &pfd)) { + WIN_SetError("DescribePixelFormat()"); + return -1; + } + retval = 0; + switch (attrib) { + case SDL_GL_RED_SIZE: + *value = pfd.cRedBits; + break; + case SDL_GL_GREEN_SIZE: + *value = pfd.cGreenBits; + break; + case SDL_GL_BLUE_SIZE: + *value = pfd.cBlueBits; + break; + case SDL_GL_ALPHA_SIZE: + *value = pfd.cAlphaBits; + break; + case SDL_GL_DOUBLEBUFFER: + if (pfd.dwFlags & PFD_DOUBLEBUFFER) { + *value = 1; + } else { + *value = 0; + } + break; + case SDL_GL_BUFFER_SIZE: + *value = pfd.cColorBits; + break; + case SDL_GL_DEPTH_SIZE: + *value = pfd.cDepthBits; + break; + case SDL_GL_STENCIL_SIZE: + *value = pfd.cStencilBits; + break; + case SDL_GL_ACCUM_RED_SIZE: + *value = pfd.cAccumRedBits; + break; + case SDL_GL_ACCUM_GREEN_SIZE: + *value = pfd.cAccumGreenBits; + break; + case SDL_GL_ACCUM_BLUE_SIZE: + *value = pfd.cAccumBlueBits; + break; + case SDL_GL_ACCUM_ALPHA_SIZE: + *value = pfd.cAccumAlphaBits; + break; + case SDL_GL_STEREO: + if (pfd.dwFlags & PFD_STEREO) { + *value = 1; + } else { + *value = 0; + } + break; + case SDL_GL_MULTISAMPLEBUFFERS: + *value = 0; + break; + case SDL_GL_MULTISAMPLESAMPLES: + *value = 1; + break; + default: + retval = -1; + break; + } + return retval; + } +} + +SDL_GLContext +WIN_GL_CreateContext(_THIS, SDL_Window * window) +{ + HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; + + return _this->gl_data->wglCreateContext(hdc); +} + +int +WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +{ + HDC hdc; + int status; + + if (window) { + hdc = ((SDL_WindowData *) window->driverdata)->hdc; + } else { + hdc = NULL; + } + if (!_this->gl_data->wglMakeCurrent(hdc, (HGLRC) context)) { + WIN_SetError("wglMakeCurrent()"); + status = -1; + } else { + status = 0; + } + return status; +} + +int +WIN_GL_SetSwapInterval(_THIS, int interval) +{ + if (_this->gl_data->wglSwapIntervalEXT) { + _this->gl_data->wglSwapIntervalEXT(interval); + return 0; + } else { + SDL_Unsupported(); + return -1; + } +} + +int +WIN_GL_GetSwapInterval(_THIS) +{ + if (_this->gl_data->wglGetSwapIntervalEXT) { + return _this->gl_data->wglGetSwapIntervalEXT(); + } else { + SDL_Unsupported(); + return -1; + } +} + +void +WIN_GL_SwapWindow(_THIS, SDL_Window * window) +{ + HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; + + SwapBuffers(hdc); +} + +void +WIN_GL_DeleteContext(_THIS, SDL_GLContext context) +{ + if (context) { + _this->gl_data->wglDeleteContext((HGLRC) context); + } +} + +#endif /* SDL_VIDEO_OPENGL */ + + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/win32/SDL_win32opengl.h b/src/video/win32/SDL_win32opengl.h new file mode 100644 index 000000000..3e09973c8 --- /dev/null +++ b/src/video/win32/SDL_win32opengl.h @@ -0,0 +1,129 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#ifndef _SDL_win32opengl_h +#define _SDL_win32opengl_h + +#if SDL_VIDEO_OPENGL + +struct SDL_GLDriverData +{ + int initialized; + int WGL_ARB_pixel_format; + + void *(WINAPI * wglGetProcAddress) (const char *proc); + HGLRC(WINAPI * wglCreateContext) (HDC hdc); + BOOL(WINAPI * wglDeleteContext) (HGLRC hglrc); + BOOL(WINAPI * wglMakeCurrent) (HDC hdc, HGLRC hglrc); + BOOL(WINAPI * wglChoosePixelFormatARB) (HDC hdc, + const int *piAttribIList, + const FLOAT * pfAttribFList, + UINT nMaxFormats, + int *piFormats, + UINT * nNumFormats); + BOOL(WINAPI * wglGetPixelFormatAttribivARB) (HDC hdc, int iPixelFormat, + int iLayerPlane, + UINT nAttributes, + const int *piAttributes, + int *piValues); + void (WINAPI * wglSwapIntervalEXT) (int interval); + int (WINAPI * wglGetSwapIntervalEXT) (void); +}; + +/* OpenGL functions */ +extern int WIN_GL_LoadLibrary(_THIS, const char *path); +extern void *WIN_GL_GetProcAddress(_THIS, const char *proc); +extern int WIN_GL_SetupWindow(_THIS, SDL_Window * window); +extern void WIN_GL_CleanupWindow(_THIS, SDL_Window * window); +extern int WIN_GL_GetWindowAttribute(_THIS, SDL_Window * window, + SDL_GLattr attrib, int *value); +extern SDL_GLContext WIN_GL_CreateContext(_THIS, SDL_Window * window); +extern int WIN_GL_MakeCurrent(_THIS, SDL_Window * window, + SDL_GLContext context); +extern int WIN_GL_SetSwapInterval(_THIS, int interval); +extern int WIN_GL_GetSwapInterval(_THIS); +extern void WIN_GL_SwapWindow(_THIS, SDL_Window * window); +extern void WIN_GL_DeleteContext(_THIS, SDL_GLContext context); + +#ifndef WGL_ARB_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#endif + +#ifndef WGL_ARB_multisample +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif + +#endif /* SDL_VIDEO_OPENGL */ + +#endif /* _SDL_win32opengl_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/win32/SDL_win32video.c b/src/video/win32/SDL_win32video.c index 0fdff0ee8..d5254910d 100644 --- a/src/video/win32/SDL_win32video.c +++ b/src/video/win32/SDL_win32video.c @@ -101,11 +101,11 @@ WIN_CreateDevice(int devindex) /* Set the function pointers */ device->VideoInit = WIN_VideoInit; + device->VideoQuit = WIN_VideoQuit; device->GetDisplayModes = WIN_GetDisplayModes; device->SetDisplayMode = WIN_SetDisplayMode; device->SetDisplayGammaRamp = WIN_SetDisplayGammaRamp; device->GetDisplayGammaRamp = WIN_GetDisplayGammaRamp; - device->VideoQuit = WIN_VideoQuit; device->PumpEvents = WIN_PumpEvents; #undef CreateWindow @@ -123,6 +123,17 @@ WIN_CreateDevice(int devindex) device->SetWindowGrab = WIN_SetWindowGrab; device->DestroyWindow = WIN_DestroyWindow; device->GetWindowWMInfo = WIN_GetWindowWMInfo; +#ifdef SDL_VIDEO_OPENGL + device->GL_LoadLibrary = WIN_GL_LoadLibrary; + device->GL_GetProcAddress = WIN_GL_GetProcAddress; + device->GL_GetWindowAttribute = WIN_GL_GetWindowAttribute; + device->GL_CreateContext = WIN_GL_CreateContext; + device->GL_MakeCurrent = WIN_GL_MakeCurrent; + device->GL_SetSwapInterval = WIN_GL_SetSwapInterval; + device->GL_GetSwapInterval = WIN_GL_GetSwapInterval; + device->GL_SwapWindow = WIN_GL_SwapWindow; + device->GL_DeleteContext = WIN_GL_DeleteContext; +#endif device->free = WIN_DeleteDevice; diff --git a/src/video/win32/SDL_win32video.h b/src/video/win32/SDL_win32video.h index 5a06bae44..574b18f51 100644 --- a/src/video/win32/SDL_win32video.h +++ b/src/video/win32/SDL_win32video.h @@ -42,6 +42,7 @@ #include "SDL_win32keyboard.h" #include "SDL_win32modes.h" #include "SDL_win32mouse.h" +#include "SDL_win32opengl.h" #include "SDL_win32window.h" #ifdef UNICODE diff --git a/src/video/win32/SDL_win32window.c b/src/video/win32/SDL_win32window.c index 20616cd34..786978aba 100644 --- a/src/video/win32/SDL_win32window.c +++ b/src/video/win32/SDL_win32window.c @@ -43,12 +43,14 @@ SetupWindowData(SDL_Window * window, HWND hwnd, BOOL created) } data->windowID = window->id; data->hwnd = hwnd; + data->hdc = GetDC(hwnd); data->created = created; data->mouse_pressed = SDL_FALSE; data->videodata = (SDL_VideoData *) SDL_GetVideoDevice()->driverdata; /* Associate the data with the window */ if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) { + ReleaseDC(hwnd, data->hdc); SDL_free(data); WIN_SetError("SetProp() failed"); return -1; @@ -133,7 +135,7 @@ WIN_CreateWindow(_THIS, SDL_Window * window) LPTSTR title = NULL; HWND top; RECT rect; - DWORD style = 0; + DWORD style = (WS_CLIPSIBLINGS | WS_CLIPCHILDREN); int x, y; int w, h; @@ -210,6 +212,14 @@ WIN_CreateWindow(_THIS, SDL_Window * window) DestroyWindow(hwnd); return -1; } +#ifdef SDL_VIDEO_OPENGL + if (window->flags & SDL_WINDOW_OPENGL) { + if (WIN_GL_SetupWindow(_this, window) < 0) { + WIN_DestroyWindow(_this, window); + return -1; + } + } +#endif return 0; } @@ -408,6 +418,12 @@ WIN_DestroyWindow(_THIS, SDL_Window * window) SDL_WindowData *data = (SDL_WindowData *) window->driverdata; if (data) { +#ifdef SDL_VIDEO_OPENGL + if (window->flags & SDL_WINDOW_OPENGL) { + WIN_GL_CleanupWindow(_this, window); + } +#endif + ReleaseDC(data->hwnd, data->hdc); if (data->created) { DestroyWindow(data->hwnd); } diff --git a/src/video/win32/SDL_win32window.h b/src/video/win32/SDL_win32window.h index 5582f9e74..b6be0c215 100644 --- a/src/video/win32/SDL_win32window.h +++ b/src/video/win32/SDL_win32window.h @@ -31,6 +31,7 @@ typedef struct { SDL_WindowID windowID; HWND hwnd; + HDC hdc; WNDPROC wndproc; BOOL created; int mouse_pressed;