📄 wgl.c
字号:
/* $Id: wgl.c,v 1.9 2005/07/01 15:56:14 kschultz Exp $ */
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/*
* File name : wgl.c
* WGL stuff. Added by Oleg Letsinsky, ajl@ultersys.ru
* Some things originated from the 3Dfx WGL functions
*/
/*
* This file contains the implementation of the wgl* functions for
* Mesa on Windows. Since these functions are provided by Windows in
* GDI/OpenGL, we must supply our versions that work with Mesa here.
*/
/* We're essentially building part of GDI here, so define this so that
* we get the right export linkage. */
#define _GDI32_
#include <windows.h>
#include "GL/wmesa.h" /* protos for wmesa* functions */
typedef struct wmesa_context *PWMC;
/*
* Pixel Format Descriptors
*/
/* Extend the PFD to include DB flag */
struct __pixelformat__
{
PIXELFORMATDESCRIPTOR pfd;
GLboolean doubleBuffered;
};
/* These are the PFD's supported by this driver. */
struct __pixelformat__ pfd[] =
{
#if 0
/* Double Buffer, alpha */
{
{
sizeof(PIXELFORMATDESCRIPTOR), 1,
PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
PFD_TYPE_RGBA,
24,
8, 0,
8, 8,
8, 16,
8, 24,
0, 0, 0, 0, 0,
16, 8,
0, 0, 0,
0, 0, 0
},
GL_TRUE
},
/* Single Buffer, alpha */
{
{
sizeof(PIXELFORMATDESCRIPTOR), 1,
PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
PFD_GENERIC_FORMAT,
PFD_TYPE_RGBA,
24,
8, 0,
8, 8,
8, 16,
8, 24,
0, 0, 0, 0, 0,
16, 8,
0, 0, 0,
0, 0, 0
},
GL_FALSE
},
#endif
/* Double Buffer, no alpha */
{
{
sizeof(PIXELFORMATDESCRIPTOR), 1,
PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
PFD_TYPE_RGBA,
24,
8, 0,
8, 8,
8, 16,
0, 0,
0, 0, 0, 0, 0,
16, 8,
0, 0, 0,
0, 0, 0
},
GL_TRUE
},
/* Single Buffer, no alpha */
{
{
sizeof(PIXELFORMATDESCRIPTOR), 1,
PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
PFD_GENERIC_FORMAT,
PFD_TYPE_RGBA,
24,
8, 0,
8, 8,
8, 16,
0, 0,
0, 0, 0, 0, 0,
16, 8,
0, 0, 0,
0, 0, 0
},
GL_FALSE
},
};
int npfd = sizeof(pfd) / sizeof(pfd[0]);
/*
* Contexts
*/
typedef struct {
WMesaContext ctx;
HDC hdc;
} MesaWglCtx;
#define MESAWGL_CTX_MAX_COUNT 20
static MesaWglCtx wgl_ctx[MESAWGL_CTX_MAX_COUNT];
static unsigned ctx_count = 0;
static int ctx_current = -1;
static unsigned curPFD = 0;
WINGDIAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc)
{
HWND hWnd;
int i = 0;
if(!(hWnd = WindowFromDC(hdc))) {
SetLastError(0);
return(NULL);
}
if (!ctx_count) {
for(i=0;i<MESAWGL_CTX_MAX_COUNT;i++) {
wgl_ctx[i].ctx = NULL;
wgl_ctx[i].hdc = NULL;
}
}
for( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) {
if ( wgl_ctx[i].ctx == NULL ) {
wgl_ctx[i].ctx =
WMesaCreateContext(hWnd, NULL, GL_TRUE,
pfd[curPFD-1].doubleBuffered,
pfd[curPFD-1].pfd.cAlphaBits ?
GL_TRUE : GL_FALSE);
if (wgl_ctx[i].ctx == NULL)
break;
wgl_ctx[i].hdc = hdc;
ctx_count++;
return ((HGLRC)wgl_ctx[i].ctx);
}
}
SetLastError(0);
return(NULL);
}
WINGDIAPI BOOL GLAPIENTRY wglDeleteContext(HGLRC hglrc)
{
int i;
for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) {
if ( wgl_ctx[i].ctx == (PWMC) hglrc ){
WMesaMakeCurrent((PWMC) hglrc);
WMesaDestroyContext();
wgl_ctx[i].ctx = NULL;
wgl_ctx[i].hdc = NULL;
ctx_count--;
return(TRUE);
}
}
SetLastError(0);
return(FALSE);
}
WINGDIAPI HGLRC GLAPIENTRY wglGetCurrentContext(VOID)
{
if (ctx_current < 0)
return 0;
else
return (HGLRC) wgl_ctx[ctx_current].ctx;
}
WINGDIAPI HDC GLAPIENTRY wglGetCurrentDC(VOID)
{
if (ctx_current < 0)
return 0;
else
return wgl_ctx[ctx_current].hdc;
}
WINGDIAPI BOOL GLAPIENTRY wglMakeCurrent(HDC hdc,HGLRC hglrc)
{
int i;
if (!hdc || !hglrc) {
WMesaMakeCurrent(NULL);
ctx_current = -1;
return TRUE;
}
for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) {
if ( wgl_ctx[i].ctx == (PWMC) hglrc ) {
wgl_ctx[i].hdc = hdc;
WMesaMakeCurrent( (WMesaContext) hglrc );
ctx_current = i;
return TRUE;
}
}
return FALSE;
}
WINGDIAPI int GLAPIENTRY wglChoosePixelFormat(HDC hdc,
CONST
PIXELFORMATDESCRIPTOR *ppfd)
{
int i,best = -1,bestdelta = 0x7FFFFFFF,delta;
(void) hdc;
if(ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1)
{
SetLastError(0);
return(0);
}
for(i = 0; i < npfd;i++)
{
delta = 0;
if(
(ppfd->dwFlags & PFD_DRAW_TO_WINDOW) &&
!(pfd[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW))
continue;
if(
(ppfd->dwFlags & PFD_DRAW_TO_BITMAP) &&
!(pfd[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP))
continue;
if(
(ppfd->dwFlags & PFD_SUPPORT_GDI) &&
!(pfd[i].pfd.dwFlags & PFD_SUPPORT_GDI))
continue;
if(
(ppfd->dwFlags & PFD_SUPPORT_OPENGL) &&
!(pfd[i].pfd.dwFlags & PFD_SUPPORT_OPENGL))
continue;
if(
!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
((ppfd->dwFlags & PFD_DOUBLEBUFFER) !=
(pfd[i].pfd.dwFlags & PFD_DOUBLEBUFFER)))
continue;
if(
!(ppfd->dwFlags & PFD_STEREO_DONTCARE) &&
((ppfd->dwFlags & PFD_STEREO) !=
(pfd[i].pfd.dwFlags & PFD_STEREO)))
continue;
if(ppfd->iPixelType != pfd[i].pfd.iPixelType)
delta++;
if(ppfd->cAlphaBits != pfd[i].pfd.cAlphaBits)
delta++;
if(delta < bestdelta)
{
best = i + 1;
bestdelta = delta;
if(bestdelta == 0)
break;
}
}
if(best == -1)
{
SetLastError(0);
return(0);
}
return(best);
}
WINGDIAPI int GLAPIENTRY wglDescribePixelFormat(HDC hdc,
int iPixelFormat,
UINT nBytes,
LPPIXELFORMATDESCRIPTOR ppfd)
{
(void) hdc;
if(ppfd == NULL)
return(npfd);
if(iPixelFormat < 1 || iPixelFormat > npfd ||
nBytes != sizeof(PIXELFORMATDESCRIPTOR))
{
SetLastError(0);
return(0);
}
*ppfd = pfd[iPixelFormat - 1].pfd;
return(npfd);
}
WINGDIAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc)
{
PROC p = (PROC) _glapi_get_proc_address((const char *) lpszProc);
if (p)
return p;
SetLastError(0);
return(NULL);
}
WINGDIAPI int GLAPIENTRY wglGetPixelFormat(HDC hdc)
{
(void) hdc;
if(curPFD == 0) {
SetLastError(0);
return(0);
}
return(curPFD);
}
WINGDIAPI BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat,
PIXELFORMATDESCRIPTOR *ppfd)
{
(void) hdc;
if(iPixelFormat < 1 || iPixelFormat > npfd ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -