📄 fxwgl.c
字号:
/* * Mesa 3-D graphics library * Version: 4.0 * * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//* Authors: * David Bucciarelli * Brian Paul * Keith Whitwell * Hiroshi Morii * Daniel Borca *//* fxwgl.c - Microsoft wgl functions emulation for * 3Dfx VooDoo/Mesa interface */#ifdef _WIN32#ifdef __cplusplusextern "C" {#endif#include <windows.h>#define GL_GLEXT_PROTOTYPES#include "GL/gl.h"#include "GL/glext.h"#ifdef __cplusplus}#endif#include "GL/fxmesa.h"#include "glheader.h"#include "glapi.h"#include "imports.h"#include "../../glide/fxdrv.h"#define MAX_MESA_ATTRS 20#if (_MSC_VER >= 1200)#pragma warning( push )#pragma warning( disable : 4273 )#endifstruct __extensions__ { PROC proc; char *name;};struct __pixelformat__ { PIXELFORMATDESCRIPTOR pfd; GLint mesaAttr[MAX_MESA_ATTRS];};WINGDIAPI void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *);static GLushort gammaTable[3 * 256];struct __pixelformat__ pix[] = { /* 16bit RGB565 single buffer with depth */ { {sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL, PFD_TYPE_RGBA, 16, 5, 0, 6, 5, 5, 11, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0} , {FXMESA_COLORDEPTH, 16, FXMESA_ALPHA_SIZE, 0, FXMESA_DEPTH_SIZE, 16, FXMESA_STENCIL_SIZE, 0, FXMESA_ACCUM_SIZE, 0, FXMESA_NONE} } , /* 16bit RGB565 double buffer with depth */ { {sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_SWAP_COPY, PFD_TYPE_RGBA, 16, 5, 0, 6, 5, 5, 11, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0} , {FXMESA_COLORDEPTH, 16, FXMESA_DOUBLEBUFFER, FXMESA_ALPHA_SIZE, 0, FXMESA_DEPTH_SIZE, 16, FXMESA_STENCIL_SIZE, 0, FXMESA_ACCUM_SIZE, 0, FXMESA_NONE} } , /* 16bit ARGB1555 single buffer with depth */ { {sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL, PFD_TYPE_RGBA, 16, 5, 0, 5, 5, 5, 10, 1, 15, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0} , {FXMESA_COLORDEPTH, 15, FXMESA_ALPHA_SIZE, 1, FXMESA_DEPTH_SIZE, 16, FXMESA_STENCIL_SIZE, 0, FXMESA_ACCUM_SIZE, 0, FXMESA_NONE} } , /* 16bit ARGB1555 double buffer with depth */ { {sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_SWAP_COPY, PFD_TYPE_RGBA, 16, 5, 0, 5, 5, 5, 10, 1, 15, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0} , {FXMESA_COLORDEPTH, 15, FXMESA_DOUBLEBUFFER, FXMESA_ALPHA_SIZE, 1, FXMESA_DEPTH_SIZE, 16, FXMESA_STENCIL_SIZE, 0, FXMESA_ACCUM_SIZE, 0, FXMESA_NONE} } , /* 32bit ARGB8888 single buffer with depth */ { {sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL, PFD_TYPE_RGBA, 32, 8, 0, 8, 8, 8, 16, 8, 24, 0, 0, 0, 0, 0, 24, 8, 0, PFD_MAIN_PLANE, 0, 0, 0, 0} , {FXMESA_COLORDEPTH, 32, FXMESA_ALPHA_SIZE, 8, FXMESA_DEPTH_SIZE, 24, FXMESA_STENCIL_SIZE, 8, FXMESA_ACCUM_SIZE, 0, FXMESA_NONE} } , /* 32bit ARGB8888 double buffer with depth */ { {sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_SWAP_COPY, PFD_TYPE_RGBA, 32, 8, 0, 8, 8, 8, 16, 8, 24, 0, 0, 0, 0, 0, 24, 8, 0, PFD_MAIN_PLANE, 0, 0, 0, 0} , {FXMESA_COLORDEPTH, 32, FXMESA_DOUBLEBUFFER, FXMESA_ALPHA_SIZE, 8, FXMESA_DEPTH_SIZE, 24, FXMESA_STENCIL_SIZE, 8, FXMESA_ACCUM_SIZE, 0, FXMESA_NONE} }};static fxMesaContext ctx = NULL;static WNDPROC hWNDOldProc;static int curPFD = 0;static HDC hDC;static HWND hWND;static GLboolean haveDualHead;/* For the in-window-rendering hack */#ifndef GR_CONTROL_RESIZE/* Apparently GR_CONTROL_RESIZE can be ignored. OK? */#define GR_CONTROL_RESIZE -1#endifstatic GLboolean gdiWindowHack;static void *dibSurfacePtr;static BITMAPINFO *dibBMI;static HBITMAP dibHBM;static HWND dibWnd;static intenv_check (const char *var, int val){ const char *env = getenv(var); return (env && (env[0] == val));}static LRESULT APIENTRY__wglMonitor (HWND hwnd, UINT message, UINT wParam, LONG lParam){ long ret; /* Now gives the resized window at the end to hWNDOldProc */ if (ctx && hwnd == hWND) { switch (message) { case WM_PAINT: case WM_MOVE: break; case WM_DISPLAYCHANGE: case WM_SIZE:#if 0 if (wParam != SIZE_MINIMIZED) { static int moving = 0; if (!moving) { if (!FX_grSstControl(GR_CONTROL_RESIZE)) { moving = 1; SetWindowPos(hwnd, 0, 0, 0, 300, 300, SWP_NOMOVE | SWP_NOZORDER); moving = 0; if (!FX_grSstControl(GR_CONTROL_RESIZE)) { /*MessageBox(0,_T("Error changing windowsize"),_T("fxMESA"),MB_OK);*/ PostMessage(hWND, WM_CLOSE, 0, 0); } } /* Do the clipping in the glide library */ grClipWindow(0, 0, FX_grSstScreenWidth(), FX_grSstScreenHeight()); /* And let the new size set in the context */ fxMesaUpdateScreenSize(ctx); } }#endif break; case WM_ACTIVATE: break; case WM_SHOWWINDOW: break; case WM_SYSKEYDOWN: case WM_SYSCHAR: break; } } /* Finally call the hWNDOldProc, which handles the resize with the * now changed window sizes */ ret = CallWindowProc(hWNDOldProc, hwnd, message, wParam, lParam); return ret;}static voidwgl_error (long error){#define WGL_INVALID_PIXELFORMAT ERROR_INVALID_PIXEL_FORMAT SetLastError(0xC0000000 /* error severity */ |0x00070000 /* error facility (who we are) */ |error);}GLAPI BOOL GLAPIENTRYwglCopyContext (HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask){ return FALSE;}GLAPI HGLRC GLAPIENTRYwglCreateContext (HDC hdc){ HWND hWnd; WNDPROC oldProc; int error; if (ctx) { SetLastError(0); return NULL; } if (!(hWnd = WindowFromDC(hdc))) { SetLastError(0); return NULL; } if (curPFD == 0) { wgl_error(WGL_INVALID_PIXELFORMAT); return NULL; } if ((oldProc = (WNDPROC)GetWindowLong(hWnd, GWL_WNDPROC)) != __wglMonitor) { hWNDOldProc = oldProc; SetWindowLong(hWnd, GWL_WNDPROC, (LONG)__wglMonitor); } /* always log when debugging, or if user demands */ if (TDFX_DEBUG || env_check("MESA_FX_INFO", 'r')) { freopen("MESA.LOG", "w", stderr); } { RECT cliRect; ShowWindow(hWnd, SW_SHOWNORMAL); SetForegroundWindow(hWnd); Sleep(100); /* a hack for win95 */ if (env_check("MESA_GLX_FX", 'w') && !(GetWindowLong(hWnd, GWL_STYLE) & WS_POPUP)) { /* XXX todo - windowed modes */ error = !(ctx = fxMesaCreateContext((GLuint) hWnd, GR_RESOLUTION_NONE, GR_REFRESH_NONE, pix[curPFD - 1].mesaAttr)); } else { GetClientRect(hWnd, &cliRect); error = !(ctx = fxMesaCreateBestContext((GLuint) hWnd, cliRect.right, cliRect.bottom, pix[curPFD - 1].mesaAttr)); } } /*if (getenv("SST_DUALHEAD")) haveDualHead = ((atoi(getenv("SST_DUALHEAD")) == 1) ? GL_TRUE : GL_FALSE); else haveDualHead = GL_FALSE;*/ if (error) { SetLastError(0); return NULL; } hDC = hdc; hWND = hWnd; /* Required by the OpenGL Optimizer 1.1 (is it a Optimizer bug ?) */ wglMakeCurrent(hdc, (HGLRC)1); return (HGLRC)1;}GLAPI HGLRC GLAPIENTRYwglCreateLayerContext (HDC hdc, int iLayerPlane){ SetLastError(0); return NULL;}GLAPI BOOL GLAPIENTRYwglDeleteContext (HGLRC hglrc){ if (ctx && hglrc == (HGLRC)1) { fxMesaDestroyContext(ctx); SetWindowLong(WindowFromDC(hDC), GWL_WNDPROC, (LONG) hWNDOldProc); ctx = NULL; hDC = 0; return TRUE; } SetLastError(0); return FALSE;}GLAPI HGLRC GLAPIENTRYwglGetCurrentContext (VOID){ if (ctx) return (HGLRC)1; SetLastError(0); return NULL;}GLAPI HDC GLAPIENTRYwglGetCurrentDC (VOID){ if (ctx) return hDC; SetLastError(0); return NULL;}GLAPI BOOL GLAPIENTRYwglSwapIntervalEXT (int interval){ if (ctx == NULL) { return FALSE; } if (interval < 0) { interval = 0; } else if (interval > 3) { interval = 3; } ctx->swapInterval = interval; return TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -