📄 dglwgl.c
字号:
/****************************************************************************
*
* Mesa 3-D graphics library
* Direct3D Driver Interface
*
* ========================================================================
*
* Copyright (C) 1991-2004 SciTech Software, Inc. 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
* SCITECH SOFTWARE INC 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.
*
* ======================================================================
*
* Language: ANSI C
* Environment: Windows 9x (Win32)
*
* Description: OpenGL window functions (wgl*).
*
****************************************************************************/
#include "dglwgl.h"
#ifdef _USE_GLD3_WGL
#include "gld_driver.h"
#endif
#include "gl/glu.h" // MUST USE MICROSOFT'S GLU32!
#ifndef _USE_GLD3_WGL
extern DGL_mesaFuncs mesaFuncs;
#endif
// Need to export wgl* functions if using GLD3,
// otherwise export GLD2 DGL_* functions.
#ifdef _USE_GLD3_WGL
#define _GLD_WGL_EXPORT(a) wgl##a
#else
#define _GLD_WGL_EXPORT(a) DGL_##a
#endif
// Calls into Mesa 4.x are different
#ifdef _USE_GLD3_WGL
#include "dlist.h"
#include "drawpix.h"
#include "get.h"
#include "matrix.h"
// NOTE: All the _GLD* macros now call the gl* functions direct.
// This ensures that the correct internal pathway is taken. KeithH
#define _GLD_glNewList glNewList
#define _GLD_glBitmap glBitmap
#define _GLD_glEndList glEndList
#define _GLD_glDeleteLists glDeleteLists
#define _GLD_glGetError glGetError
#define _GLD_glTranslatef glTranslatef
#define _GLD_glBegin glBegin
#define _GLD_glVertex2fv glVertex2fv
#define _GLD_glEnd glEnd
#define _GLD_glNormal3f glNormal3f
#define _GLD_glVertex3f glVertex3f
#define _GLD_glVertex3fv glVertex3fv
#else // _USE_GLD3_WGL
#define _GLD_glNewList (*mesaFuncs.glNewList)
#define _GLD_glBitmap (*mesaFuncs.glBitmap)
#define _GLD_glEndList (*mesaFuncs.glEndList)
#define _GLD_glDeleteLists (*mesaFuncs.glDeleteLists)
#define _GLD_glGetError (*mesaFuncs.glGetError)
#define _GLD_glTranslatef (*mesaFuncs.glTranslatef)
#define _GLD_glBegin (*mesaFuncs.glBegin)
#define _GLD_glVertex2fv (*mesaFuncs.glVertex2fv)
#define _GLD_glEnd (*mesaFuncs.glEnd)
#define _GLD_glNormal3f (*mesaFuncs.glNormal3f)
#define _GLD_glVertex3f (*mesaFuncs.glVertex3f)
#define _GLD_glVertex3fv (*mesaFuncs.glVertex3fv)
#endif // _USE_GLD3_WGL
// ***********************************************************************
// Emulate SGI DDK calls.
#define __wglMalloc(a) GlobalAlloc(GPTR, (a))
#define __wglFree(a) GlobalFree((a))
// ***********************************************************************
// Mesa glu.h and MS glu.h call these different things...
//#define GLUtesselator GLUtriangulatorObj
//#define GLU_TESS_VERTEX_DATA GLU_VERTEX_DATA
// For wglFontOutlines
typedef GLUtesselator *(APIENTRY *gluNewTessProto)(void);
typedef void (APIENTRY *gluDeleteTessProto)(GLUtesselator *tess);
typedef void (APIENTRY *gluTessBeginPolygonProto)(GLUtesselator *tess, void *polygon_data);
typedef void (APIENTRY *gluTessBeginContourProto)(GLUtesselator *tess);
typedef void (APIENTRY *gluTessVertexProto)(GLUtesselator *tess, GLdouble coords[3], void *data);
typedef void (APIENTRY *gluTessEndContourProto)(GLUtesselator *tess);
typedef void (APIENTRY *gluTessEndPolygonProto)(GLUtesselator *tess);
typedef void (APIENTRY *gluTessPropertyProto)(GLUtesselator *tess, GLenum which, GLdouble value);
typedef void (APIENTRY *gluTessNormalProto)(GLUtesselator *tess, GLdouble x, GLdouble y, GLdouble z);
typedef void (APIENTRY *gluTessCallbackProto)(GLUtesselator *tess, GLenum which, void (CALLBACK *)());
static HINSTANCE gluModuleHandle;
static gluNewTessProto gluNewTessProc;
static gluDeleteTessProto gluDeleteTessProc;
static gluTessBeginPolygonProto gluTessBeginPolygonProc;
static gluTessBeginContourProto gluTessBeginContourProc;
static gluTessVertexProto gluTessVertexProc;
static gluTessEndContourProto gluTessEndContourProc;
static gluTessEndPolygonProto gluTessEndPolygonProc;
static gluTessPropertyProto gluTessPropertyProc;
static gluTessNormalProto gluTessNormalProc;
static gluTessCallbackProto gluTessCallbackProc;
static HFONT hNewFont, hOldFont;
static FLOAT ScaleFactor;
#define LINE_BUF_QUANT 4000
#define VERT_BUF_QUANT 4000
static FLOAT* LineBuf;
static DWORD LineBufSize;
static DWORD LineBufIndex;
static FLOAT* VertBuf;
static DWORD VertBufSize;
static DWORD VertBufIndex;
static GLenum TessErrorOccurred;
static int AppendToLineBuf(
FLOAT value);
static int AppendToVertBuf(
FLOAT value);
static int DrawGlyph(
UCHAR* glyphBuf,
DWORD glyphSize,
FLOAT chordalDeviation,
FLOAT extrusion,
INT format);
static void FreeLineBuf(void);
static void FreeVertBuf(void);
static long GetWord(
UCHAR** p);
static long GetDWord(
UCHAR** p);
static double GetFixed(
UCHAR** p);
static int InitLineBuf(void);
static int InitVertBuf(void);
static HFONT CreateHighResolutionFont(
HDC hDC);
static int MakeDisplayListFromGlyph(
DWORD listName,
UCHAR* glyphBuf,
DWORD glyphSize,
LPGLYPHMETRICSFLOAT glyphMetricsFloat,
FLOAT chordalDeviation,
FLOAT extrusion,
INT format);
static BOOL LoadGLUTesselator(void);
static BOOL UnloadGLUTesselator(void);
static int MakeLinesFromArc(
FLOAT x0,
FLOAT y0,
FLOAT x1,
FLOAT y1,
FLOAT x2,
FLOAT y2,
DWORD vertexCountIndex,
FLOAT chordalDeviationSquared);
static int MakeLinesFromGlyph( UCHAR* glyphBuf,
DWORD glyphSize,
FLOAT chordalDeviation);
static int MakeLinesFromTTLine( UCHAR** pp,
DWORD vertexCountIndex,
WORD pointCount);
static int MakeLinesFromTTPolycurve( UCHAR** pp,
DWORD vertexCountIndex,
FLOAT chordalDeviation);
static int MakeLinesFromTTPolygon( UCHAR** pp,
FLOAT chordalDeviation);
static int MakeLinesFromTTQSpline( UCHAR** pp,
DWORD vertexCountIndex,
WORD pointCount,
FLOAT chordalDeviation);
static void CALLBACK TessCombine( double coords[3],
void* vertex_data[4],
FLOAT weight[4],
void** outData);
static void CALLBACK TessError( GLenum error);
static void CALLBACK TessVertexOutData( FLOAT p[3],
GLfloat z);
// ***********************************************************************
#ifdef GLD_THREADS
#pragma message("compiling DGLWGL.C vars for multi-threaded support")
extern CRITICAL_SECTION CriticalSection;
extern DWORD dwTLSPixelFormat; // TLS index for current pixel format
#endif
int curPFD = 0; // Current PFD (static)
// ***********************************************************************
int dglGetPixelFormat(void)
{
#ifdef GLD_THREADS
int iPixelFormat;
// get thread-specific instance
if (glb.bMultiThreaded) {
__try {
iPixelFormat = (int)TlsGetValue(dwTLSPixelFormat);
}
__except(EXCEPTION_EXECUTE_HANDLER) {
iPixelFormat = curPFD;
}
}
// get global static var
else {
iPixelFormat = curPFD;
}
return iPixelFormat;
#else
return curPFD;
#endif
}
// ***********************************************************************
void dglSetPixelFormat(int iPixelFormat)
{
#ifdef GLD_THREADS
// set thread-specific instance
if (glb.bMultiThreaded) {
__try {
TlsSetValue(dwTLSPixelFormat, (LPVOID)iPixelFormat);
}
__except(EXCEPTION_EXECUTE_HANDLER) {
curPFD = iPixelFormat;
}
}
// set global static var
else {
curPFD = iPixelFormat;
}
#else
curPFD = iPixelFormat;
#endif
}
// ***********************************************************************
int APIENTRY _GLD_WGL_EXPORT(ChoosePixelFormat)(
HDC a,
CONST PIXELFORMATDESCRIPTOR *ppfd)
{
DGL_pixelFormat *lpPF = glb.lpPF;
PIXELFORMATDESCRIPTOR ppfdBest;
int i;
int bestIndex = -1;
int numPixelFormats;
DWORD dwFlags;
char buf[128];
char cat[8];
DWORD dwAllFlags =
PFD_DRAW_TO_WINDOW |
PFD_DRAW_TO_BITMAP |
PFD_SUPPORT_GDI |
PFD_SUPPORT_OPENGL |
PFD_GENERIC_FORMAT |
PFD_NEED_PALETTE |
PFD_NEED_SYSTEM_PALETTE |
PFD_DOUBLEBUFFER |
PFD_STEREO |
/*PFD_SWAP_LAYER_BUFFERS |*/
PFD_DOUBLEBUFFER_DONTCARE |
PFD_STEREO_DONTCARE |
PFD_SWAP_COPY |
PFD_SWAP_EXCHANGE |
PFD_GENERIC_ACCELERATED |
0;
// Validate license
if (!dglValidate())
return 0;
// List may not be built until dglValidate() is called! KeithH
lpPF = glb.lpPF;
//
// Lets print the input pixel format to the log
// ** Based on "wglinfo" by Nate Robins **
//
ddlogMessage(DDLOG_SYSTEM, "ChoosePixelFormat:\n");
ddlogMessage(DDLOG_INFO, "Input pixel format for ChoosePixelFormat:\n");
ddlogMessage(DDLOG_INFO,
" visual x bf lv rg d st r g b a ax dp st accum buffs ms\n");
ddlogMessage(DDLOG_INFO,
" id dep cl sp sz l ci b ro sz sz sz sz bf th cl r g b a ns b\n");
ddlogMessage(DDLOG_INFO,
"-----------------------------------------------------------------\n");
sprintf(buf, " . ");
sprintf(cat, "%2d ", ppfd->cColorBits);
strcat(buf, cat);
if(ppfd->dwFlags & PFD_DRAW_TO_WINDOW) sprintf(cat, "wn ");
else if(ppfd->dwFlags & PFD_DRAW_TO_BITMAP) sprintf(cat, "bm ");
else sprintf(cat, ". ");
strcat(buf, cat);
/* should find transparent pixel from LAYERPLANEDESCRIPTOR */
sprintf(cat, " . ");
strcat(buf, cat);
sprintf(cat, "%2d ", ppfd->cColorBits);
strcat(buf, cat);
/* bReserved field indicates number of over/underlays */
if(ppfd->bReserved) sprintf(cat, " %d ", ppfd->bReserved);
else sprintf(cat, " . ");
strcat(buf, cat);
sprintf(cat, " %c ", ppfd->iPixelType == PFD_TYPE_RGBA ? 'r' : 'c');
strcat(buf, cat);
sprintf(cat, "%c ", ppfd->dwFlags & PFD_DOUBLEBUFFER ? 'y' : '.');
strcat(buf, cat);
sprintf(cat, " %c ", ppfd->dwFlags & PFD_STEREO ? 'y' : '.');
strcat(buf, cat);
if(ppfd->cRedBits && ppfd->iPixelType == PFD_TYPE_RGBA)
sprintf(cat, "%2d ", ppfd->cRedBits);
else sprintf(cat, " . ");
strcat(buf, cat);
if(ppfd->cGreenBits && ppfd->iPixelType == PFD_TYPE_RGBA)
sprintf(cat, "%2d ", ppfd->cGreenBits);
else sprintf(cat, " . ");
strcat(buf, cat);
if(ppfd->cBlueBits && ppfd->iPixelType == PFD_TYPE_RGBA)
sprintf(cat, "%2d ", ppfd->cBlueBits);
else sprintf(cat, " . ");
strcat(buf, cat);
if(ppfd->cAlphaBits && ppfd->iPixelType == PFD_TYPE_RGBA)
sprintf(cat, "%2d ", ppfd->cAlphaBits);
else sprintf(cat, " . ");
strcat(buf, cat);
if(ppfd->cAuxBuffers) sprintf(cat, "%2d ", ppfd->cAuxBuffers);
else sprintf(cat, " . ");
strcat(buf, cat);
if(ppfd->cDepthBits) sprintf(cat, "%2d ", ppfd->cDepthBits);
else sprintf(cat, " . ");
strcat(buf, cat);
if(ppfd->cStencilBits) sprintf(cat, "%2d ", ppfd->cStencilBits);
else sprintf(cat, " . ");
strcat(buf, cat);
if(ppfd->cAccumRedBits) sprintf(cat, "%2d ", ppfd->cAccumRedBits);
else sprintf(cat, " . ");
strcat(buf, cat);
if(ppfd->cAccumGreenBits) sprintf(cat, "%2d ", ppfd->cAccumGreenBits);
else sprintf(cat, " . ");
strcat(buf, cat);
if(ppfd->cAccumBlueBits) sprintf(cat, "%2d ", ppfd->cAccumBlueBits);
else sprintf(cat, " . ");
strcat(buf, cat);
if(ppfd->cAccumAlphaBits) sprintf(cat, "%2d ", ppfd->cAccumAlphaBits);
else sprintf(cat, " . ");
strcat(buf, cat);
/* no multisample in Win32 */
sprintf(cat, " . .\n");
strcat(buf, cat);
ddlogMessage(DDLOG_INFO, buf);
ddlogMessage(DDLOG_INFO,
"-----------------------------------------------------------------\n");
ddlogMessage(DDLOG_INFO, "\n");
//
// Examine the flags for correctness
//
dwFlags = ppfd->dwFlags;
if (dwFlags != (dwFlags & dwAllFlags))
{
/* error: bad dwFlags */
ddlogPrintf(DDLOG_WARN,
"ChoosePixelFormat: bad flags (0x%x)",
dwFlags & (~dwAllFlags));
// Mask illegal flags and continue
dwFlags = dwFlags & dwAllFlags;
}
switch (ppfd->iPixelType) {
case PFD_TYPE_RGBA:
case PFD_TYPE_COLORINDEX:
break;
default:
/* error: bad iPixelType */
ddlogMessage(DDLOG_WARN, "ChoosePixelFormat: bad pixel type\n");
return 0;
}
switch (ppfd->iLayerType) {
case PFD_MAIN_PLANE:
case PFD_OVERLAY_PLANE:
case PFD_UNDERLAY_PLANE:
break;
default:
/* error: bad iLayerType */
ddlogMessage(DDLOG_WARN, "ChoosePixelFormat: bad layer type\n");
return 0;
}
numPixelFormats = glb.nPixelFormatCount;
/* loop through candidate pixel format descriptors */
for (i=0; i<numPixelFormats; ++i) {
PIXELFORMATDESCRIPTOR ppfdCandidate;
memcpy(&ppfdCandidate, &lpPF[i].pfd, sizeof(PIXELFORMATDESCRIPTOR));
/*
** Check attributes which must match
*/
if (ppfd->iPixelType != ppfdCandidate.iPixelType) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -