📄 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 __cplusplus
extern "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 )
#endif
struct __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
#endif
static GLboolean gdiWindowHack;
static void *dibSurfacePtr;
static BITMAPINFO *dibBMI;
static HBITMAP dibHBM;
static HWND dibWnd;
static int
env_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 void
wgl_error (long error)
{
#define WGL_INVALID_PIXELFORMAT ERROR_INVALID_PIXEL_FORMAT
SetLastError(0xC0000000 /* error severity */
|0x00070000 /* error facility (who we are) */
|error);
}
GLAPI BOOL GLAPIENTRY
wglCopyContext (HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
{
return FALSE;
}
GLAPI HGLRC GLAPIENTRY
wglCreateContext (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 GLAPIENTRY
wglCreateLayerContext (HDC hdc, int iLayerPlane)
{
SetLastError(0);
return NULL;
}
GLAPI BOOL GLAPIENTRY
wglDeleteContext (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 GLAPIENTRY
wglGetCurrentContext (VOID)
{
if (ctx)
return (HGLRC)1;
SetLastError(0);
return NULL;
}
GLAPI HDC GLAPIENTRY
wglGetCurrentDC (VOID)
{
if (ctx)
return hDC;
SetLastError(0);
return NULL;
}
GLAPI BOOL GLAPIENTRY
wglSwapIntervalEXT (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 + -