📄 sdl_wingl.c
字号:
/* 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"/* WGL implementation of SDL OpenGL support */#if SDL_VIDEO_OPENGL#include "SDL_opengl.h"#endif#include "SDL_lowvideo.h"#include "SDL_wingl_c.h"#if SDL_VIDEO_OPENGL#define DEFAULT_GL_DRIVER_PATH "OPENGL32.DLL"#endif/* If setting the HDC fails, we may need to recreate the window (MSDN) */static int WIN_GL_ResetWindow(_THIS){ int status = 0;#ifndef _WIN32_WCE /* FIXME WinCE needs the UNICODE version of CreateWindow() */ /* This doesn't work with DirectX code (see CVS comments) */ /* If we were passed a window, then we can't create a new one */ if ( !SDL_windowid && SDL_strcmp(this->name, "windib") == 0 ) { /* Save the existing window attributes */ LONG style; RECT rect = { 0, 0, 0, 0 }; style = GetWindowLong(SDL_Window, GWL_STYLE); GetWindowRect(SDL_Window, &rect); DestroyWindow(SDL_Window); WIN_FlushMessageQueue(); SDL_resizing = 1; SDL_Window = CreateWindow(SDL_Appname, SDL_Appname, style, rect.left, rect.top, (rect.right-rect.left)+1, (rect.bottom-rect.top)+1, NULL, NULL, SDL_Instance, NULL); WIN_FlushMessageQueue(); SDL_resizing = 0; if ( SDL_Window ) { this->SetCaption(this, this->wm_title, this->wm_icon); } else { SDL_SetError("Couldn't create window"); status = -1; } } else#endif /* !_WIN32_WCE */ { SDL_SetError("Unable to reset window for OpenGL context"); status = -1; } return(status);}#if SDL_VIDEO_OPENGLstatic int ExtensionSupported(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 0; if ( ! extensions ) return 0; /* 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 1; start = terminator; } return 0;}static int ChoosePixelFormatARB(_THIS, const int *iAttribs, const FLOAT *fAttribs){ HWND hwnd; HDC hdc; HGLRC hglrc; const char * (WINAPI *wglGetExtensionsStringARB)(HDC) = 0; const char *extensions; int pformat = 0; UINT matches = 0; hwnd = CreateWindow(SDL_Appname, SDL_Appname, WS_POPUP | WS_DISABLED, 0, 0, 10, 10, NULL, NULL, SDL_Instance, NULL); WIN_FlushMessageQueue(); hdc = GetDC(hwnd); SetPixelFormat(hdc, ChoosePixelFormat(hdc, &GL_pfd), &GL_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; } this->gl_data->WGL_ARB_pixel_format = 0; if( ExtensionSupported("WGL_ARB_pixel_format", extensions) ) { BOOL (WINAPI *wglChoosePixelFormatARB)(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); wglChoosePixelFormatARB = (BOOL (WINAPI *)(HDC, const int *, const FLOAT *, UINT, int *, UINT *)) this->gl_data->wglGetProcAddress("wglChoosePixelFormatARB"); if( wglChoosePixelFormatARB && wglChoosePixelFormatARB(hdc, iAttribs, fAttribs, 1, &pformat, &matches) && pformat ) { this->gl_data->WGL_ARB_pixel_format = 1; } } if ( hglrc ) { this->gl_data->wglMakeCurrent(NULL, NULL); this->gl_data->wglDeleteContext(hglrc); } ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); WIN_FlushMessageQueue(); return pformat;}#endif /* SDL_VIDEO_OPENGL */int WIN_GL_SetupWindow(_THIS){ int retval;#if SDL_VIDEO_OPENGL int i; int iAttribs[64]; int *iAttr; float fAttribs[1] = { 0 }; const GLubyte *(WINAPI *glGetStringFunc)(GLenum); const char *wglext; /* load the gl driver from a default path */ if ( ! this->gl_config.driver_loaded ) { /* no driver has been loaded, use default (ourselves) */ if ( WIN_GL_LoadLibrary(this, NULL) < 0 ) { return(-1); } } /* Set up the pixel format descriptor with our needed format */ SDL_memset(&GL_pfd, 0, sizeof(GL_pfd)); GL_pfd.nSize = sizeof(GL_pfd); GL_pfd.nVersion = 1; GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL); if ( this->gl_config.double_buffer ) { GL_pfd.dwFlags |= PFD_DOUBLEBUFFER; } if ( this->gl_config.stereo ) { GL_pfd.dwFlags |= PFD_STEREO; } GL_pfd.iPixelType = PFD_TYPE_RGBA; GL_pfd.cColorBits = this->gl_config.buffer_size; GL_pfd.cRedBits = this->gl_config.red_size; GL_pfd.cGreenBits = this->gl_config.green_size; GL_pfd.cBlueBits = this->gl_config.blue_size; GL_pfd.cAlphaBits = this->gl_config.alpha_size; GL_pfd.cAccumRedBits = this->gl_config.accum_red_size; GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size; GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size; GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size; GL_pfd.cAccumBits = (GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits + GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits); GL_pfd.cDepthBits = this->gl_config.depth_size; GL_pfd.cStencilBits = this->gl_config.stencil_size; /* 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; for ( i=0; ; ++i ) { /* Get the window device context for our OpenGL drawing */ GL_hdc = GetDC(SDL_Window); if ( GL_hdc == NULL ) { SDL_SetError("Unable to get DC for SDL_Window"); return(-1); } /* Choose and set the closest available pixel format */ pixel_format = ChoosePixelFormatARB(this, iAttribs, fAttribs); if ( !pixel_format ) { pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd); } if ( !pixel_format ) { SDL_SetError("No matching GL pixel format available"); return(-1); } if ( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) { if ( i == 0 ) { /* First time through, try resetting the window */ if ( WIN_GL_ResetWindow(this) < 0 ) { return(-1); } continue; } SDL_SetError("Unable to set HDC pixel format"); return(-1); } /* We either succeeded or failed by this point */ break; } DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd); GL_hrc = this->gl_data->wglCreateContext(GL_hdc); if ( GL_hrc == NULL ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -