aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.c
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/drivers/windows/gldirect/dglcontext.c')
-rw-r--r--mesalib/src/mesa/drivers/windows/gldirect/dglcontext.c2212
1 files changed, 0 insertions, 2212 deletions
diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.c b/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.c
deleted file mode 100644
index 9aedd2e3c..000000000
--- a/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.c
+++ /dev/null
@@ -1,2212 +0,0 @@
-/****************************************************************************
-*
-* 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: Context handling.
-*
-****************************************************************************/
-
-#include "dglcontext.h"
-
-// Get compile errors without this. KeithH
-//#include "scitech.h" // ibool, etc.
-
-#ifdef _USE_GLD3_WGL
-#include "gld_driver.h"
-
-extern void _gld_mesa_warning(struct gl_context *, char *);
-extern void _gld_mesa_fatal(struct gl_context *, char *);
-#endif // _USE_GLD3_WGL
-
-// TODO: Clean out old DX6-specific code from GLD 2.x CAD driver
-// if it is no longer being built as part of GLDirect. (DaveM)
-
-// ***********************************************************************
-
-#define GLDERR_NONE 0
-#define GLDERR_MEM 1
-#define GLDERR_DDRAW 2
-#define GLDERR_D3D 3
-#define GLDERR_BPP 4
-
-char szResourceWarning[] =
-"GLDirect does not have enough video memory resources\n"
-"to support the requested OpenGL rendering context.\n\n"
-"You may have to reduce the current display resolution\n"
-"to obtain satisfactory OpenGL performance.\n";
-
-char szDDrawWarning[] =
-"GLDirect is unable to initialize DirectDraw for the\n"
-"requested OpenGL rendering context.\n\n"
-"You will have to check the DirectX control panel\n"
-"for further information.\n";
-
-char szD3DWarning[] =
-"GLDirect is unable to initialize Direct3D for the\n"
-"requested OpenGL rendering context.\n\n"
-"You may have to change the display mode resolution\n"
-"color depth or check the DirectX control panel for\n"
-"further information.\n";
-
-char szBPPWarning[] =
-"GLDirect is unable to use the selected color depth for\n"
-"the requested OpenGL rendering context.\n\n"
-"You will have to change the display mode resolution\n"
-"color depth with the Display Settings control panel.\n";
-
-int nContextError = GLDERR_NONE;
-
-// ***********************************************************************
-
-#define VENDORID_ATI 0x1002
-
-static DWORD devATIRagePro[] = {
- 0x4742, // 3D RAGE PRO BGA AGP 1X/2X
- 0x4744, // 3D RAGE PRO BGA AGP 1X only
- 0x4749, // 3D RAGE PRO BGA PCI 33 MHz
- 0x4750, // 3D RAGE PRO PQFP PCI 33 MHz
- 0x4751, // 3D RAGE PRO PQFP PCI 33 MHz limited 3D
- 0x4C42, // 3D RAGE LT PRO BGA-312 AGP 133 MHz
- 0x4C44, // 3D RAGE LT PRO BGA-312 AGP 66 MHz
- 0x4C49, // 3D RAGE LT PRO BGA-312 PCI 33 MHz
- 0x4C50, // 3D RAGE LT PRO BGA-256 PCI 33 MHz
- 0x4C51, // 3D RAGE LT PRO BGA-256 PCI 33 MHz limited 3D
-};
-
-static DWORD devATIRageIIplus[] = {
- 0x4755, // 3D RAGE II+
- 0x4756, // 3D RAGE IIC PQFP PCI
- 0x4757, // 3D RAGE IIC BGA AGP
- 0x475A, // 3D RAGE IIC PQFP AGP
- 0x4C47, // 3D RAGE LT-G
-};
-
-// ***********************************************************************
-
-#ifndef _USE_GLD3_WGL
-extern DGL_mesaFuncs mesaFuncs;
-#endif
-
-extern DWORD dwLogging;
-
-#ifdef GLD_THREADS
-#pragma message("compiling DGLCONTEXT.C vars for multi-threaded support")
-CRITICAL_SECTION CriticalSection; // for serialized access
-DWORD dwTLSCurrentContext = 0xFFFFFFFF; // TLS index for current context
-DWORD dwTLSPixelFormat = 0xFFFFFFFF; // TLS index for current pixel format
-#endif
-HGLRC iCurrentContext = 0; // Index of current context (static)
-BOOL bContextReady = FALSE; // Context state ready ?
-
-DGL_ctx ctxlist[DGL_MAX_CONTEXTS]; // Context list
-
-// ***********************************************************************
-
-static BOOL bHaveWin95 = FALSE;
-static BOOL bHaveWinNT = FALSE;
-static BOOL bHaveWin2K = FALSE;
-
-/****************************************************************************
-REMARKS:
-Detect the installed OS type.
-****************************************************************************/
-static void DetectOS(void)
-{
- OSVERSIONINFO VersionInformation;
- LPOSVERSIONINFO lpVersionInformation = &VersionInformation;
-
- VersionInformation.dwOSVersionInfoSize = sizeof(VersionInformation);
-
- GetVersionEx(lpVersionInformation);
-
- switch (VersionInformation.dwPlatformId) {
- case VER_PLATFORM_WIN32_WINDOWS:
- bHaveWin95 = TRUE;
- bHaveWinNT = FALSE;
- bHaveWin2K = FALSE;
- break;
- case VER_PLATFORM_WIN32_NT:
- bHaveWin95 = FALSE;
- if (VersionInformation.dwMajorVersion <= 4) {
- bHaveWinNT = TRUE;
- bHaveWin2K = FALSE;
- }
- else {
- bHaveWinNT = FALSE;
- bHaveWin2K = TRUE;
- }
- break;
- case VER_PLATFORM_WIN32s:
- bHaveWin95 = FALSE;
- bHaveWinNT = FALSE;
- bHaveWin2K = FALSE;
- break;
- }
-}
-
-// ***********************************************************************
-
-HWND hWndEvent = NULL; // event monitor window
-HWND hWndLastActive = NULL; // last active client window
-LONG __stdcall GLD_EventWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
-
-// ***********************************************************************
-
-// Checks if the HGLRC is valid in range of context list.
-BOOL dglIsValidContext(
- HGLRC a)
-{
- return ((int)a > 0 && (int)a <= DGL_MAX_CONTEXTS);
-}
-
-// ***********************************************************************
-
-// Convert a HGLRC to a pointer into the context list.
-DGL_ctx* dglGetContextAddress(
- const HGLRC a)
-{
- if (dglIsValidContext(a))
- return &ctxlist[(int)a-1];
- return NULL;
-}
-
-// ***********************************************************************
-
-// Return the current HGLRC (however it may be stored for multi-threading).
-HGLRC dglGetCurrentContext(void)
-{
-#ifdef GLD_THREADS
- HGLRC hGLRC;
- // load from thread-specific instance
- if (glb.bMultiThreaded) {
- // protect against calls from arbitrary threads
- __try {
- hGLRC = (HGLRC)TlsGetValue(dwTLSCurrentContext);
- }
- __except(EXCEPTION_EXECUTE_HANDLER) {
- hGLRC = iCurrentContext;
- }
- }
- // load from global static var
- else {
- hGLRC = iCurrentContext;
- }
- return hGLRC;
-#else
- return iCurrentContext;
-#endif
-}
-
-// ***********************************************************************
-
-// Set the current HGLRC (however it may be stored for multi-threading).
-void dglSetCurrentContext(HGLRC hGLRC)
-{
-#ifdef GLD_THREADS
- // store in thread-specific instance
- if (glb.bMultiThreaded) {
- // protect against calls from arbitrary threads
- __try {
- TlsSetValue(dwTLSCurrentContext, (LPVOID)hGLRC);
- }
- __except(EXCEPTION_EXECUTE_HANDLER) {
- iCurrentContext = hGLRC;
- }
- }
- // store in global static var
- else {
- iCurrentContext = hGLRC;
- }
-#else
- iCurrentContext = hGLRC;
-#endif
-}
-
-// ***********************************************************************
-
-// Return the current HDC only for a currently active HGLRC.
-HDC dglGetCurrentDC(void)
-{
- HGLRC hGLRC;
- DGL_ctx* lpCtx;
-
- hGLRC = dglGetCurrentContext();
- if (hGLRC) {
- lpCtx = dglGetContextAddress(hGLRC);
- return lpCtx->hDC;
- }
- return 0;
-}
-
-// ***********************************************************************
-
-void dglInitContextState()
-{
- int i;
- WNDCLASS wc;
-
-#ifdef GLD_THREADS
- // Allocate thread local storage indexes for current context and pixel format
- dwTLSCurrentContext = TlsAlloc();
- dwTLSPixelFormat = TlsAlloc();
-#endif
-
- dglSetCurrentContext(NULL); // No current rendering context
-
- // Clear all context data
- ZeroMemory(ctxlist, sizeof(ctxlist[0]) * DGL_MAX_CONTEXTS);
-
- for (i=0; i<DGL_MAX_CONTEXTS; i++)
- ctxlist[i].bAllocated = FALSE; // Flag context as unused
-
- // This section of code crashes the dll in circumstances where the app
- // creates and destroys contexts.
-/*
- // Register the class for our event monitor window
- wc.style = 0;
- wc.lpfnWndProc = GLD_EventWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = GetModuleHandle(NULL);
- wc.hIcon = LoadIcon(GetModuleHandle(NULL), IDI_APPLICATION);
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = "GLDIRECT";
- RegisterClass(&wc);
-
- // Create the non-visible window to monitor all broadcast messages
- hWndEvent = CreateWindowEx(
- WS_EX_TOOLWINDOW,"GLDIRECT","GLDIRECT",WS_POPUP,
- 0,0,0,0,
- NULL,NULL,GetModuleHandle(NULL),NULL);
-*/
-
-#ifdef GLD_THREADS
- // Create a critical section object for serializing access to
- // DirectDraw and DDStereo create/destroy functions in multiple threads
- if (glb.bMultiThreaded)
- InitializeCriticalSection(&CriticalSection);
-#endif
-
- // Context state is now initialized and ready
- bContextReady = TRUE;
-}
-
-// ***********************************************************************
-
-void dglDeleteContextState()
-{
- int i;
- static BOOL bOnceIsEnough = FALSE;
-
- // Only call once, from either DGL_exitDriver(), or DLL_PROCESS_DETACH
- if (bOnceIsEnough)
- return;
- bOnceIsEnough = TRUE;
-
- for (i=0; i<DGL_MAX_CONTEXTS; i++) {
- if (ctxlist[i].bAllocated == TRUE) {
- ddlogPrintf(DDLOG_WARN, "** Context %i not deleted - cleaning up.", (i+1));
- dglDeleteContext((HGLRC)(i+1));
- }
- }
-
- // Context state is no longer ready
- bContextReady = FALSE;
-
- // If executed when DLL unloads, DDraw objects may be invalid.
- // So catch any page faults with this exception handler.
-__try {
-
- // Release final DirectDraw interfaces
- if (glb.bDirectDrawPersistant) {
-// RELEASE(glb.lpGlobalPalette);
-// RELEASE(glb.lpDepth4);
-// RELEASE(glb.lpBack4);
-// RELEASE(glb.lpPrimary4);
-// RELEASE(glb.lpDD4);
- }
-}
-__except(EXCEPTION_EXECUTE_HANDLER) {
- ddlogPrintf(DDLOG_WARN, "Exception raised in dglDeleteContextState.");
-}
-
- // Destroy our event monitor window
- if (hWndEvent) {
- DestroyWindow(hWndEvent);
- hWndEvent = hWndLastActive = NULL;
- }
-
-#ifdef GLD_THREADS
- // Destroy the critical section object
- if (glb.bMultiThreaded)
- DeleteCriticalSection(&CriticalSection);
-
- // Release thread local storage indexes for current HGLRC and pixel format
- TlsFree(dwTLSPixelFormat);
- TlsFree(dwTLSCurrentContext);
-#endif
-}
-
-// ***********************************************************************
-
-// Application Window message handler interception
-static LONG __stdcall dglWndProc(
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
-{
- DGL_ctx* lpCtx = NULL;
- LONG lpfnWndProc = 0L;
- int i;
- HGLRC hGLRC;
- RECT rect;
- PAINTSTRUCT ps;
- BOOL bQuit = FALSE;
- BOOL bMain = FALSE;
- LONG rc;
-
- // Get the window's message handler *before* it is unhooked in WM_DESTROY
-
- // Is this the main window?
- if (hwnd == glb.hWndActive) {
- bMain = TRUE;
- lpfnWndProc = glb.lpfnWndProc;
- }
- // Search for DGL context matching window handle
- for (i=0; i<DGL_MAX_CONTEXTS; i++) {
- if (ctxlist[i].hWnd == hwnd) {
- lpCtx = &ctxlist[i];
- lpfnWndProc = lpCtx->lpfnWndProc;
- break;
- }
- }
- // Not one of ours...
- if (!lpfnWndProc)
- return DefWindowProc(hwnd, msg, wParam, lParam);
-
- // Intercept messages amd process *before* passing on to window
- switch (msg) {
-#ifdef _USE_GLD3_WGL
- case WM_DISPLAYCHANGE:
- glb.bPixelformatsDirty = TRUE;
- break;
-#endif
- case WM_ACTIVATEAPP:
- glb.bAppActive = (BOOL)wParam;
- ddlogPrintf(DDLOG_INFO, "Calling app has been %s", glb.bAppActive ? "activated" : "de-activated");
- break;
- case WM_ERASEBKGND:
- // Eat the GDI erase event for the GL window
- if (!lpCtx || !lpCtx->bHasBeenCurrent)
- break;
- lpCtx->bGDIEraseBkgnd = TRUE;
- return TRUE;
- case WM_PAINT:
- // Eat the invalidated update region if render scene is in progress
- if (!lpCtx || !lpCtx->bHasBeenCurrent)
- break;
- if (lpCtx->bFrameStarted) {
- if (GetUpdateRect(hwnd, &rect, FALSE)) {
- BeginPaint(hwnd, &ps);
- EndPaint(hwnd, &ps);
- ValidateRect(hwnd, &rect);
- return TRUE;
- }
- }
- break;
- }
- // Call the appropriate window message handler
- rc = CallWindowProc((WNDPROC)lpfnWndProc, hwnd, msg, wParam, lParam);
-
- // Intercept messages and process *after* passing on to window
- switch (msg) {
- case WM_QUIT:
- case WM_DESTROY:
- bQuit = TRUE;
- if (lpCtx && lpCtx->bAllocated) {
- ddlogPrintf(DDLOG_WARN, "WM_DESTROY detected for HWND=%X, HDC=%X, HGLRC=%d", hwnd, lpCtx->hDC, i+1);
- dglDeleteContext((HGLRC)(i+1));
- }
- break;
-#if 0
- case WM_SIZE:
- // Resize surfaces to fit window but not viewport (in case app did not bother)
- if (!lpCtx || !lpCtx->bHasBeenCurrent)
- break;
- w = LOWORD(lParam);
- h = HIWORD(lParam);
- if (lpCtx->dwWidth < w || lpCtx->dwHeight < h) {
- if (!dglWglResizeBuffers(lpCtx->glCtx, TRUE))
- dglWglResizeBuffers(lpCtx->glCtx, FALSE);
- }
- break;
-#endif
- }
-
- // If the main window is quitting, then so should we...
- if (bMain && bQuit) {
- ddlogPrintf(DDLOG_SYSTEM, "shutting down after WM_DESTROY detected for main HWND=%X", hwnd);
- dglDeleteContextState();
- dglExitDriver();
- }
-
- return rc;
-}
-
-// ***********************************************************************
-
-// Driver Window message handler
-static LONG __stdcall GLD_EventWndProc(
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
-{
- switch (msg) {
- // May be sent by splash screen dialog on exit
- case WM_ACTIVATE:
- if (LOWORD(wParam) == WA_ACTIVE && glb.hWndActive) {
- SetForegroundWindow(glb.hWndActive);
- return 0;
- }
- break;
- }
- return DefWindowProc(hwnd, msg, wParam, lParam);
-}
-
-// ***********************************************************************
-
-// Intercepted Keyboard handler for detecting hot keys.
-LRESULT CALLBACK dglKeyProc(
- int code,
- WPARAM wParam,
- LPARAM lParam)
-{
- HWND hWnd, hWndFrame;
- HGLRC hGLRC = NULL;
- DGL_ctx* lpCtx = NULL;
- int cmd = 0, dx1 = 0, dx2 = 0, i;
- static BOOL bAltPressed = FALSE;
- static BOOL bCtrlPressed = FALSE;
- static BOOL bShiftPressed = FALSE;
- RECT r, rf, rc;
- POINT pt;
- BOOL bForceReshape = FALSE;
-
- return CallNextHookEx(hKeyHook, code, wParam, lParam);
-}
-
-// ***********************************************************************
-
-HWND hWndMatch;
-
-// Window handle enumeration procedure.
-BOOL CALLBACK dglEnumChildProc(
- HWND hWnd,
- LPARAM lParam)
-{
- RECT rect;
-
- // Find window handle with matching client rect.
- GetClientRect(hWnd, &rect);
- if (EqualRect(&rect, (RECT*)lParam)) {
- hWndMatch = hWnd;
- return FALSE;
- }
- // Continue with next child window.
- return TRUE;
-}
-
-// ***********************************************************************
-
-// Find window handle with matching client rect.
-HWND dglFindWindowRect(
- RECT* pRect)
-{
- hWndMatch = NULL;
- EnumChildWindows(GetForegroundWindow(), dglEnumChildProc, (LPARAM)pRect);
- return hWndMatch;
-}
-
-// ***********************************************************************
-#ifndef _USE_GLD3_WGL
-void dglChooseDisplayMode(
- DGL_ctx *lpCtx)
-{
- // Note: Choose an exact match if possible.
-
- int i;
- DWORD area;
- DWORD bestarea;
- DDSURFACEDESC2 *lpDDSD = NULL; // Mode list pointer
- DDSURFACEDESC2 *lpBestDDSD = NULL; // Pointer to best
-
- lpDDSD = glb.lpDisplayModes;
- for (i=0; i<glb.nDisplayModeCount; i++, lpDDSD++) {
- if ((lpDDSD->dwWidth == lpCtx->dwWidth) &&
- (lpDDSD->dwHeight == lpCtx->dwHeight))
- goto matched; // Mode has been exactly matched
- // Choose modes that are larger in both dimensions than
- // the window, but smaller in area than the current best.
- if ( (lpDDSD->dwWidth >= lpCtx->dwWidth) &&
- (lpDDSD->dwHeight >= lpCtx->dwHeight))
- {
- if (lpBestDDSD == NULL) {
- lpBestDDSD = lpDDSD;
- bestarea = lpDDSD->dwWidth * lpDDSD->dwHeight;
- continue;
- }
- area = lpDDSD->dwWidth * lpDDSD->dwHeight;
- if (area < bestarea) {
- lpBestDDSD = lpDDSD;
- bestarea = area;
- }
- }
- }
-
- // Safety check
- if (lpBestDDSD == NULL) {
- ddlogMessage(DDLOG_CRITICAL, "dglChooseDisplayMode");
- return;
- }
-
- lpCtx->dwModeWidth = lpBestDDSD->dwWidth;
- lpCtx->dwModeHeight = lpBestDDSD->dwHeight;
-matched:
- ddlogPrintf(DDLOG_INFO, "Matched (%ldx%ld) to (%ldx%ld)",
- lpCtx->dwWidth, lpCtx->dwHeight, lpCtx->dwModeWidth, lpCtx->dwModeHeight);
-}
-#endif // _USE_GLD3_WGL
-// ***********************************************************************
-
-static BOOL IsDevice(
- DWORD *lpDeviceIdList,
- DWORD dwDeviceId,
- int count)
-{
- int i;
-
- for (i=0; i<count; i++)
- if (dwDeviceId == lpDeviceIdList[i])
- return TRUE;
-
- return FALSE;
-}
-
-// ***********************************************************************
-
-void dglTestForBrokenCards(
- DGL_ctx *lpCtx)
-{
-#ifndef _GLD3
- DDDEVICEIDENTIFIER dddi; // DX6 device identifier
-
- // Sanity check.
- if (lpCtx == NULL) {
- // Testing for broken cards is sensitive area, so we don't want
- // anything saying "broken cards" in the error message. ;)
- ddlogMessage(DDLOG_ERROR, "Null context passed to TFBC\n");
- return;
- }
-
- if (lpCtx->lpDD4 == NULL) {
- // Testing for broken cards is sensitive area, so we don't want
- // anything saying "broken cards" in the error message. ;)
- ddlogMessage(DDLOG_ERROR, "Null DD4 passed to TFBC\n");
- return;
- }
-
- // Microsoft really fucked up with the GetDeviceIdentifier function
- // on Windows 2000, since it locks up on stock driers on the CD. Updated
- // drivers from vendors appear to work, but we can't identify the drivers
- // without this function!!! For now we skip these tests on Windows 2000.
- if ((GetVersion() & 0x80000000UL) == 0)
- return;
-
- // Obtain device info
- if (FAILED(IDirectDraw4_GetDeviceIdentifier(lpCtx->lpDD4, &dddi, 0)))
- return;
-
- // Useful info. Log it.
- ddlogPrintf(DDLOG_INFO, "DirectDraw: VendorId=0x%x, DeviceId=0x%x", dddi.dwVendorId, dddi.dwDeviceId);
-
- // Vendor 1: ATI
- if (dddi.dwVendorId == VENDORID_ATI) {
- // Test A: ATI Rage PRO
- if (IsDevice(devATIRagePro, dddi.dwDeviceId, sizeof(devATIRagePro)))
- glb.bUseMipmaps = FALSE;
- // Test B: ATI Rage II+
- if (IsDevice(devATIRageIIplus, dddi.dwDeviceId, sizeof(devATIRageIIplus)))
- glb.bEmulateAlphaTest = TRUE;
- }
-
- // Vendor 2: Matrox
- if (dddi.dwVendorId == 0x102B) {
- // Test: Matrox G400 stencil buffer support does not work for AutoCAD
- if (dddi.dwDeviceId == 0x0525) {
- lpCtx->lpPF->pfd.cStencilBits = 0;
- if (lpCtx->lpPF->iZBufferPF != -1) {
- glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwStencilBitDepth = 0;
- glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwStencilBitMask = 0;
- glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwFlags &= ~DDPF_STENCILBUFFER;
- }
- }
- }
-#endif // _GLD3
-}
-
-// ***********************************************************************
-
-BOOL dglCreateContextBuffers(
- HDC a,
- DGL_ctx *lpCtx,
- BOOL bFallback)
-{
- HRESULT hResult;
-
- int i;
-// HGLRC hGLRC;
-// DGL_ctx* lpCtx;
-
-#ifndef _USE_GLD3_WGL
- DWORD dwFlags;
- DDSURFACEDESC2 ddsd2;
- DDSCAPS2 ddscaps2;
- LPDIRECTDRAWCLIPPER lpddClipper;
- D3DDEVICEDESC D3DHWDevDesc; // Direct3D Hardware description
- D3DDEVICEDESC D3DHELDevDesc; // Direct3D Hardware Emulation Layer
-#endif // _USE_GLD3_WGL
-
- float inv_aspect;
-
- GLenum bDoubleBuffer; // TRUE if double buffer required
- GLenum bDepthBuffer; // TRUE if depth buffer required
-
- const PIXELFORMATDESCRIPTOR *lpPFD = &lpCtx->lpPF->pfd;
-
- // Vars for Mesa visual
- DWORD dwDepthBits = 0;
- DWORD dwStencilBits = 0;
- DWORD dwAlphaBits = 0;
- DWORD bAlphaSW = GL_FALSE;
- DWORD bDouble = GL_FALSE;
-
- DDSURFACEDESC2 ddsd2DisplayMode;
- BOOL bFullScrnWin = FALSE; // fullscreen-size window ?
- DDBLTFX ddbltfx;
- DWORD dwMemoryType = (bFallback) ? DDSCAPS_SYSTEMMEMORY : glb.dwMemoryType;
- BOOL bBogusWindow = FALSE; // non-drawable window ?
- DWORD dwColorRef = 0; // GDI background color
- RECT rcDst; // GDI window rect
- POINT pt; // GDI window point
-
- // Palette used for creating default global palette
- PALETTEENTRY ppe[256];
-
-#ifndef _USE_GLD3_WGL
- // Vertex buffer description. Used for creation of vertex buffers
- D3DVERTEXBUFFERDESC vbufdesc;
-#endif // _USE_GLD3_WGL
-
-#define DDLOG_CRITICAL_OR_WARN (bFallback ? DDLOG_CRITICAL : DDLOG_WARN)
-
- ddlogPrintf(DDLOG_SYSTEM, "dglCreateContextBuffers for HDC=%X", a);
- nContextError = GLDERR_NONE;
-
-#ifdef GLD_THREADS
- // Serialize access to DirectDraw object creation or DDS start
- if (glb.bMultiThreaded)
- EnterCriticalSection(&CriticalSection);
-#endif
-
- // Check for back buffer
- bDoubleBuffer = GL_TRUE; //(lpPFD->dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE;
- // Since we always do back buffering, check if we emulate front buffering
- lpCtx->EmulateSingle =
- (lpPFD->dwFlags & PFD_DOUBLEBUFFER) ? FALSE : TRUE;
-#if 0 // Don't have to mimic MS OpenGL behavior for front-buffering (DaveM)
- lpCtx->EmulateSingle |=
- (lpPFD->dwFlags & PFD_SUPPORT_GDI) ? TRUE : FALSE;
-#endif
-
- // Check for depth buffer
- bDepthBuffer = (lpPFD->cDepthBits) ? GL_TRUE : GL_FALSE;
-
- lpCtx->bDoubleBuffer = bDoubleBuffer;
- lpCtx->bDepthBuffer = bDepthBuffer;
-
- // Set the Fullscreen flag for the context.
-// lpCtx->bFullscreen = glb.bFullscreen;
-
- // Obtain the dimensions of the rendering window
- lpCtx->hDC = a; // Cache DC
- lpCtx->hWnd = WindowFromDC(lpCtx->hDC);
- // Check for non-window DC = memory DC ?
- if (lpCtx->hWnd == NULL) {
- // bitmap memory contexts are always single-buffered
- lpCtx->EmulateSingle = TRUE;
- bBogusWindow = TRUE;
- ddlogPrintf(DDLOG_INFO, "Non-Window Memory Device Context");
- if (GetClipBox(lpCtx->hDC, &lpCtx->rcScreenRect) == ERROR) {
- ddlogMessage(DDLOG_WARN, "GetClipBox failed in dglCreateContext\n");
- SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0);
- }
- }
- else if (!GetClientRect(lpCtx->hWnd, &lpCtx->rcScreenRect)) {
- bBogusWindow = TRUE;
- ddlogMessage(DDLOG_WARN, "GetClientRect failed in dglCreateContext\n");
- SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0);
- }
- lpCtx->dwWidth = lpCtx->rcScreenRect.right - lpCtx->rcScreenRect.left;
- lpCtx->dwHeight = lpCtx->rcScreenRect.bottom - lpCtx->rcScreenRect.top;
-
- ddlogPrintf(DDLOG_INFO, "Input window %X: w=%i, h=%i",
- lpCtx->hWnd, lpCtx->dwWidth, lpCtx->dwHeight);
-
- // What if app only zeroes one dimension instead of both? (DaveM)
- if ( (lpCtx->dwWidth == 0) || (lpCtx->dwHeight == 0) ) {
- // Make the buffer size something sensible
- lpCtx->dwWidth = 8;
- lpCtx->dwHeight = 8;
- }
-
- // Set defaults
- lpCtx->dwModeWidth = lpCtx->dwWidth;
- lpCtx->dwModeHeight = lpCtx->dwHeight;
-/*
- // Find best display mode for fullscreen
- if (glb.bFullscreen || !glb.bPrimary) {
- dglChooseDisplayMode(lpCtx);
- }
-*/
- // Misc initialisation
- lpCtx->bCanRender = FALSE; // No rendering allowed yet
- lpCtx->bSceneStarted = FALSE;
- lpCtx->bFrameStarted = FALSE;
-
- // Detect OS (specifically 'Windows 2000' or 'Windows XP')
- DetectOS();
-
- // NOTE: WinNT not supported
- ddlogPrintf(DDLOG_INFO, "OS: %s", bHaveWin95 ? "Win9x" : (bHaveWin2K ? "Win2000/XP" : "Unsupported") );
-
- // Test for Fullscreen
- if (bHaveWin95) { // Problems with fullscreen on Win2K/XP
- if ((GetSystemMetrics(SM_CXSCREEN) == lpCtx->dwWidth) &&
- (GetSystemMetrics(SM_CYSCREEN) == lpCtx->dwHeight))
- {
- // Workaround for some apps that crash when going fullscreen.
- //lpCtx->bFullscreen = TRUE;
- }
-
- }
-
-#ifdef _USE_GLD3_WGL
- _gldDriver.CreateDrawable(lpCtx, glb.bDirectDrawPersistant, glb.bPersistantBuffers);
-#else
- // Check if DirectDraw has already been created by original GLRC (DaveM)
- if (glb.bDirectDrawPersistant && glb.bDirectDraw) {
- lpCtx->lpDD4 = glb.lpDD4;
- IDirectDraw4_AddRef(lpCtx->lpDD4);
- goto SkipDirectDrawCreate;
- }
-
- // Create DirectDraw object
- if (glb.bPrimary)
- hResult = DirectDrawCreate(NULL, &lpCtx->lpDD1, NULL);
- else {
- // A non-primary device is to be used.
- // Force context to be Fullscreen, secondary adaptors can not
- // be used in a window.
- hResult = DirectDrawCreate(&glb.ddGuid, &lpCtx->lpDD1, NULL);
- lpCtx->bFullscreen = TRUE;
- }
- if (FAILED(hResult)) {
- MessageBox(NULL, "Unable to initialize DirectDraw", "GLDirect", MB_OK);
- ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create DirectDraw interface", hResult);
- nContextError = GLDERR_DDRAW;
- goto return_with_error;
- }
-
- // Query for DX6 IDirectDraw4.
- hResult = IDirectDraw_QueryInterface(lpCtx->lpDD1,
- &IID_IDirectDraw4,
- (void**)&lpCtx->lpDD4);
- if (FAILED(hResult)) {
- MessageBox(NULL, "GLDirect requires DirectX 6.0 or above", "GLDirect", MB_OK);
- ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create DirectDraw4 interface", hResult);
- nContextError = GLDERR_DDRAW;
- goto return_with_error;
- }
-
- // Cache DirectDraw interface for subsequent GLRCs
- if (glb.bDirectDrawPersistant && !glb.bDirectDraw) {
- glb.lpDD4 = lpCtx->lpDD4;
- IDirectDraw4_AddRef(glb.lpDD4);
- glb.bDirectDraw = TRUE;
- }
-SkipDirectDrawCreate:
-
- // Now we have a DD4 interface we can check for broken cards
- dglTestForBrokenCards(lpCtx);
-
- // Test if primary device can use flipping instead of blitting
- ZeroMemory(&ddsd2DisplayMode, sizeof(ddsd2DisplayMode));
- ddsd2DisplayMode.dwSize = sizeof(ddsd2DisplayMode);
- hResult = IDirectDraw4_GetDisplayMode(
- lpCtx->lpDD4,
- &ddsd2DisplayMode);
- if (SUCCEEDED(hResult)) {
- if ( (lpCtx->dwWidth == ddsd2DisplayMode.dwWidth) &&
- (lpCtx->dwHeight == ddsd2DisplayMode.dwHeight) ) {
- // We have a fullscreen-size window
- bFullScrnWin = TRUE;
- // OK to use DirectDraw fullscreen mode ?
- if (glb.bPrimary && !glb.bFullscreenBlit && !lpCtx->EmulateSingle && !glb.bDirectDrawPersistant) {
- lpCtx->bFullscreen = TRUE;
- ddlogMessage(DDLOG_INFO, "Primary upgraded to page flipping.\n");
- }
- }
- // Cache the display mode dimensions
- lpCtx->dwModeWidth = ddsd2DisplayMode.dwWidth;
- lpCtx->dwModeHeight = ddsd2DisplayMode.dwHeight;
- }
-
- // Clamp the effective window dimensions to primary surface.
- // We need to do this for D3D viewport dimensions even if wide
- // surfaces are supported. This also is a good idea for handling
- // whacked-out window dimensions passed for non-drawable windows
- // like Solid Edge. (DaveM)
- if (lpCtx->dwWidth > ddsd2DisplayMode.dwWidth)
- lpCtx->dwWidth = ddsd2DisplayMode.dwWidth;
- if (lpCtx->dwHeight > ddsd2DisplayMode.dwHeight)
- lpCtx->dwHeight = ddsd2DisplayMode.dwHeight;
-
- // Check for non-RGB desktop resolution
- if (!lpCtx->bFullscreen && ddsd2DisplayMode.ddpfPixelFormat.dwRGBBitCount <= 8) {
- ddlogPrintf(DDLOG_CRITICAL_OR_WARN, "Desktop color depth %d bpp not supported",
- ddsd2DisplayMode.ddpfPixelFormat.dwRGBBitCount);
- nContextError = GLDERR_BPP;
- goto return_with_error;
- }
-#endif // _USE_GLD3_WGL
-
- ddlogPrintf(DDLOG_INFO, "Window: w=%i, h=%i (%s)",
- lpCtx->dwWidth,
- lpCtx->dwHeight,
- lpCtx->bFullscreen ? "fullscreen" : "windowed");
-
-#ifndef _USE_GLD3_WGL
- // Obtain ddraw caps
- ZeroMemory(&lpCtx->ddCaps, sizeof(DDCAPS));
- lpCtx->ddCaps.dwSize = sizeof(DDCAPS);
- if (glb.bHardware) {
- // Get HAL caps
- IDirectDraw4_GetCaps(lpCtx->lpDD4, &lpCtx->ddCaps, NULL);
- } else {
- // Get HEL caps
- IDirectDraw4_GetCaps(lpCtx->lpDD4, NULL, &lpCtx->ddCaps);
- }
-
- // If this flag is present then we can't default to Mesa
- // SW rendering between BeginScene() and EndScene().
- if (lpCtx->ddCaps.dwCaps2 & DDCAPS2_NO2DDURING3DSCENE) {
- ddlogMessage(DDLOG_INFO,
- "Warning : No 2D allowed during 3D scene.\n");
- }
-
- // Query for DX6 Direct3D3 interface
- hResult = IDirectDraw4_QueryInterface(lpCtx->lpDD4,
- &IID_IDirect3D3,
- (void**)&lpCtx->lpD3D3);
- if (FAILED(hResult)) {
- MessageBox(NULL, "Unable to initialize Direct3D", "GLDirect", MB_OK);
- ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create Direct3D interface", hResult);
- nContextError = GLDERR_D3D;
- goto return_with_error;
- }
-
- // Context creation
- if (lpCtx->bFullscreen) {
- // FULLSCREEN
-
- // Disable warning popups when in fullscreen mode
- ddlogWarnOption(FALSE);
-
- // Have to release persistant primary surface if fullscreen mode
- if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) {
- RELEASE(glb.lpPrimary4);
- glb.bDirectDrawPrimary = FALSE;
- }
-
- dwFlags = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT;
- if (glb.bFastFPU)
- dwFlags |= DDSCL_FPUSETUP; // fast FPU setup optional (DaveM)
- hResult = IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4, lpCtx->hWnd, dwFlags);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to set Exclusive Fullscreen mode", hResult);
- goto return_with_error;
- }
-
- hResult = IDirectDraw4_SetDisplayMode(lpCtx->lpDD4,
- lpCtx->dwModeWidth,
- lpCtx->dwModeHeight,
- lpPFD->cColorBits,
- 0,
- 0);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "SetDisplayMode failed", hResult);
- goto return_with_error;
- }
-
- // ** The display mode has changed, so dont use MessageBox! **
-
- ZeroMemory(&ddsd2, sizeof(ddsd2));
- ddsd2.dwSize = sizeof(ddsd2);
-
- if (bDoubleBuffer) {
- // Double buffered
- // Primary surface
- ddsd2.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
- ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
- DDSCAPS_FLIP |
- DDSCAPS_COMPLEX |
- DDSCAPS_3DDEVICE |
- dwMemoryType;
- ddsd2.dwBackBufferCount = 1;
-
- hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpFront4, NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (primary) failed", hResult);
- nContextError = GLDERR_MEM;
- goto return_with_error;
- }
-
- // Render target surface
- ZeroMemory(&ddscaps2, sizeof(ddscaps2)); // Clear the entire struct.
- ddscaps2.dwCaps = DDSCAPS_BACKBUFFER;
- hResult = IDirectDrawSurface4_GetAttachedSurface(lpCtx->lpFront4, &ddscaps2, &lpCtx->lpBack4);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "GetAttachedSurface failed", hResult);
- nContextError = GLDERR_MEM;
- goto return_with_error;
- }
- } else {
- // Single buffered
- // Primary surface
- ddsd2.dwFlags = DDSD_CAPS;
- ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
- //DDSCAPS_3DDEVICE |
- dwMemoryType;
-
- hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpFront4, NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (primary) failed", hResult);
- nContextError = GLDERR_MEM;
- goto return_with_error;
- }
-
- lpCtx->lpBack4 = NULL;
- }
- } else {
- // WINDOWED
-
- // OK to enable warning popups in windowed mode
- ddlogWarnOption(glb.bMessageBoxWarnings);
-
- dwFlags = DDSCL_NORMAL;
- if (glb.bMultiThreaded)
- dwFlags |= DDSCL_MULTITHREADED;
- if (glb.bFastFPU)
- dwFlags |= DDSCL_FPUSETUP; // fast FPU setup optional (DaveM)
- hResult = IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4,
- lpCtx->hWnd,
- dwFlags);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to set Normal coop level", hResult);
- goto return_with_error;
- }
- // Has Primary surface already been created for original GLRC ?
- // Note this can only be applicable for windowed modes
- if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) {
- lpCtx->lpFront4 = glb.lpPrimary4;
- IDirectDrawSurface4_AddRef(lpCtx->lpFront4);
- // Update the window on the default clipper
- IDirectDrawSurface4_GetClipper(lpCtx->lpFront4, &lpddClipper);
- IDirectDrawClipper_SetHWnd(lpddClipper, 0, lpCtx->hWnd);
- IDirectDrawClipper_Release(lpddClipper);
- goto SkipPrimaryCreate;
- }
-
- // Primary surface
- ZeroMemory(&ddsd2, sizeof(ddsd2));
- ddsd2.dwSize = sizeof(ddsd2);
- ddsd2.dwFlags = DDSD_CAPS;
- ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
- hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpFront4, NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (primary) failed", hResult);
- nContextError = GLDERR_MEM;
- goto return_with_error;
- }
-
- // Cache Primary surface for subsequent GLRCs
- // Note this can only be applicable to subsequent windowed modes
- if (glb.bDirectDrawPersistant && !glb.bDirectDrawPrimary) {
- glb.lpPrimary4 = lpCtx->lpFront4;
- IDirectDrawSurface4_AddRef(glb.lpPrimary4);
- glb.bDirectDrawPrimary = TRUE;
- }
-
- // Clipper object
- hResult = DirectDrawCreateClipper(0, &lpddClipper, NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateClipper failed", hResult);
- goto return_with_error;
- }
- hResult = IDirectDrawClipper_SetHWnd(lpddClipper, 0, lpCtx->hWnd);
- if (FAILED(hResult)) {
- RELEASE(lpddClipper);
- ddlogError(DDLOG_CRITICAL_OR_WARN, "SetHWnd failed", hResult);
- goto return_with_error;
- }
- hResult = IDirectDrawSurface4_SetClipper(lpCtx->lpFront4, lpddClipper);
- RELEASE(lpddClipper); // We have finished with it.
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "SetClipper failed", hResult);
- goto return_with_error;
- }
-SkipPrimaryCreate:
-
- if (bDoubleBuffer) {
- // Render target surface
- ZeroMemory(&ddsd2, sizeof(ddsd2));
- ddsd2.dwSize = sizeof(ddsd2);
- ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd2.dwWidth = lpCtx->dwWidth;
- ddsd2.dwHeight = lpCtx->dwHeight;
- ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE |
- DDSCAPS_OFFSCREENPLAIN |
- dwMemoryType;
-
- // Reserve the entire desktop size for persistant buffers option
- if (glb.bDirectDrawPersistant && glb.bPersistantBuffers) {
- ddsd2.dwWidth = ddsd2DisplayMode.dwWidth;
- ddsd2.dwHeight = ddsd2DisplayMode.dwHeight;
- }
- // Re-use original back buffer if persistant buffers exist
- if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpBack4)
- hResult = IDirectDrawSurface4_AddRef(lpCtx->lpBack4 = glb.lpBack4);
- else
- hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpBack4, NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "Create Backbuffer failed", hResult);
- nContextError = GLDERR_MEM;
- goto return_with_error;
- }
- if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && !glb.lpBack4)
- IDirectDrawSurface4_AddRef(glb.lpBack4 = lpCtx->lpBack4);
- } else {
- lpCtx->lpBack4 = NULL;
- }
- }
-
- //
- // Now create the Z-buffer
- //
- lpCtx->bStencil = FALSE; // Default to no stencil buffer
- if (bDepthBuffer && (lpCtx->lpPF->iZBufferPF != -1)) {
- // Get z-buffer dimensions from the render target
- // Setup the surface desc for the z-buffer.
- ZeroMemory(&ddsd2, sizeof(ddsd2));
- ddsd2.dwSize = sizeof(ddsd2);
- ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
- ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | dwMemoryType;
- ddsd2.dwWidth = lpCtx->dwWidth;
- ddsd2.dwHeight = lpCtx->dwHeight;
- memcpy(&ddsd2.ddpfPixelFormat,
- &glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF],
- sizeof(DDPIXELFORMAT) );
-
- // Reserve the entire desktop size for persistant buffers option
- if (glb.bDirectDrawPersistant && glb.bPersistantBuffers) {
- ddsd2.dwWidth = ddsd2DisplayMode.dwWidth;
- ddsd2.dwHeight = ddsd2DisplayMode.dwHeight;
- }
-
- // Create a z-buffer
- if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpDepth4)
- hResult = IDirectDrawSurface4_AddRef(lpCtx->lpDepth4 = glb.lpDepth4);
- else
- hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpDepth4, NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (ZBuffer) failed", hResult);
- nContextError = GLDERR_MEM;
- goto return_with_error;
- }
- if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && !glb.lpDepth4)
- IDirectDrawSurface4_AddRef(glb.lpDepth4 = lpCtx->lpDepth4);
- else if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpDepth4 && glb.lpBack4)
- IDirectDrawSurface4_DeleteAttachedSurface(glb.lpBack4, 0, glb.lpDepth4);
-
- // Attach Zbuffer to render target
- TRY(IDirectDrawSurface4_AddAttachedSurface(
- bDoubleBuffer ? lpCtx->lpBack4 : lpCtx->lpFront4,
- lpCtx->lpDepth4),
- "dglCreateContext: Attach Zbuffer");
- if (glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwFlags & DDPF_STENCILBUFFER) {
- lpCtx->bStencil = TRUE;
- ddlogMessage(DDLOG_INFO, "Depth buffer has stencil\n");
- }
- }
-
- // Clear all back buffers and Z-buffers in case of memory recycling.
- ZeroMemory(&ddbltfx, sizeof(ddbltfx));
- ddbltfx.dwSize = sizeof(ddbltfx);
- IDirectDrawSurface4_Blt(lpCtx->lpBack4, NULL, NULL, NULL,
- DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
- if (lpCtx->lpDepth4)
- IDirectDrawSurface4_Blt(lpCtx->lpDepth4, NULL, NULL, NULL,
- DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
-
- // Now that we have a Z-buffer we can create the 3D device
- hResult = IDirect3D3_CreateDevice(lpCtx->lpD3D3,
- &glb.d3dGuid,
- bDoubleBuffer ? lpCtx->lpBack4 : lpCtx->lpFront4,
- &lpCtx->lpDev3,
- NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create Direct3D device", hResult);
- nContextError = GLDERR_D3D;
- goto return_with_error;
- }
-
- // We must do this as soon as the device is created
- dglInitStateCaches(lpCtx);
-
- // Obtain the D3D Device Description
- D3DHWDevDesc.dwSize = D3DHELDevDesc.dwSize = sizeof(D3DDEVICEDESC);
- TRY(IDirect3DDevice3_GetCaps(lpCtx->lpDev3,
- &D3DHWDevDesc,
- &D3DHELDevDesc),
- "dglCreateContext: GetCaps failed");
-
- // Choose the relevant description and cache it in the context.
- // We will use this description later for caps checking
- memcpy( &lpCtx->D3DDevDesc,
- glb.bHardware ? &D3DHWDevDesc : &D3DHELDevDesc,
- sizeof(D3DDEVICEDESC));
-
- // Now we can examine the texture formats
- if (!dglBuildTextureFormatList(lpCtx->lpDev3)) {
- ddlogMessage(DDLOG_CRITICAL_OR_WARN, "dglBuildTextureFormatList failed\n");
- goto return_with_error;
- }
-
- // Get the pixel format of the back buffer
- lpCtx->ddpfRender.dwSize = sizeof(lpCtx->ddpfRender);
- if (bDoubleBuffer)
- hResult = IDirectDrawSurface4_GetPixelFormat(
- lpCtx->lpBack4,
- &lpCtx->ddpfRender);
- else
- hResult = IDirectDrawSurface4_GetPixelFormat(
- lpCtx->lpFront4,
- &lpCtx->ddpfRender);
-
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "GetPixelFormat failed", hResult);
- goto return_with_error;
- }
- // Find a pixel packing function suitable for this surface
- pxClassifyPixelFormat(&lpCtx->ddpfRender,
- &lpCtx->fnPackFunc,
- &lpCtx->fnUnpackFunc,
- &lpCtx->fnPackSpanFunc);
-
- // Viewport
- hResult = IDirect3D3_CreateViewport(lpCtx->lpD3D3, &lpCtx->lpViewport3, NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateViewport failed", hResult);
- goto return_with_error;
- }
-
- hResult = IDirect3DDevice3_AddViewport(lpCtx->lpDev3, lpCtx->lpViewport3);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "AddViewport failed", hResult);
- goto return_with_error;
- }
-
- // Initialise the viewport
- // Note screen coordinates are used for viewport clipping since D3D
- // transform operations are not used in the GLD CAD driver. (DaveM)
- inv_aspect = (float)lpCtx->dwHeight/(float)lpCtx->dwWidth;
-
- lpCtx->d3dViewport.dwSize = sizeof(lpCtx->d3dViewport);
- lpCtx->d3dViewport.dwX = 0;
- lpCtx->d3dViewport.dwY = 0;
- lpCtx->d3dViewport.dwWidth = lpCtx->dwWidth;
- lpCtx->d3dViewport.dwHeight = lpCtx->dwHeight;
- lpCtx->d3dViewport.dvClipX = 0; // -1.0f;
- lpCtx->d3dViewport.dvClipY = 0; // inv_aspect;
- lpCtx->d3dViewport.dvClipWidth = lpCtx->dwWidth; // 2.0f;
- lpCtx->d3dViewport.dvClipHeight = lpCtx->dwHeight; // 2.0f * inv_aspect;
- lpCtx->d3dViewport.dvMinZ = 0.0f;
- lpCtx->d3dViewport.dvMaxZ = 1.0f;
- TRY(IDirect3DViewport3_SetViewport2(lpCtx->lpViewport3, &lpCtx->d3dViewport), "dglCreateContext: SetViewport2");
-
- hResult = IDirect3DDevice3_SetCurrentViewport(lpCtx->lpDev3, lpCtx->lpViewport3);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "SetCurrentViewport failed", hResult);
- goto return_with_error;
- }
-
- lpCtx->dwBPP = lpPFD->cColorBits;
- lpCtx->iZBufferPF = lpCtx->lpPF->iZBufferPF;
-
- // Set last texture to NULL
- for (i=0; i<MAX_TEXTURE_UNITS; i++) {
- lpCtx->ColorOp[i] = D3DTOP_DISABLE;
- lpCtx->AlphaOp[i] = D3DTOP_DISABLE;
- lpCtx->tObj[i] = NULL;
- }
-
- // Default to perspective correct texture mapping
- dglSetRenderState(lpCtx, D3DRENDERSTATE_TEXTUREPERSPECTIVE, TRUE, "TexturePersp");
-
- // Set the default culling mode
- lpCtx->cullmode = D3DCULL_NONE;
- dglSetRenderState(lpCtx, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE, "CullMode");
-
- // Disable specular
- dglSetRenderState(lpCtx, D3DRENDERSTATE_SPECULARENABLE, FALSE, "SpecularEnable");
- // Disable subpixel correction
-// dglSetRenderState(lpCtx, D3DRENDERSTATE_SUBPIXEL, FALSE, "SubpixelEnable");
- // Disable dithering
- dglSetRenderState(lpCtx, D3DRENDERSTATE_DITHERENABLE, FALSE, "DitherEnable");
-
- // Initialise the primitive caches
-// lpCtx->dwNextLineVert = 0;
-// lpCtx->dwNextTriVert = 0;
-
- // Init the global texture palette
- lpCtx->lpGlobalPalette = NULL;
-
- // Init the HW/SW usage counters
-// lpCtx->dwHWUsageCount = lpCtx->dwSWUsageCount = 0L;
-
- //
- // Create two D3D vertex buffers.
- // One will hold the pre-transformed data with the other one
- // being used to hold the post-transformed & clipped verts.
- //
-#if 0 // never used (DaveM)
- vbufdesc.dwSize = sizeof(D3DVERTEXBUFFERDESC);
- vbufdesc.dwCaps = D3DVBCAPS_WRITEONLY;
- if (glb.bHardware == FALSE)
- vbufdesc.dwCaps = D3DVBCAPS_SYSTEMMEMORY;
- vbufdesc.dwNumVertices = 32768; // For the time being
-
- // Source vertex buffer
- vbufdesc.dwFVF = DGL_LVERTEX;
- hResult = IDirect3D3_CreateVertexBuffer(lpCtx->lpD3D3, &vbufdesc, &lpCtx->m_vbuf, 0, NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateVertexBuffer(src) failed", hResult);
- goto return_with_error;
- }
-
- // Destination vertex buffer
- vbufdesc.dwFVF = (glb.bMultitexture == FALSE) ? D3DFVF_TLVERTEX : (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX2);
- hResult = IDirect3D3_CreateVertexBuffer(lpCtx->lpD3D3, &vbufdesc, &lpCtx->m_pvbuf, 0, NULL);
- if(FAILED(hResult)) {
- ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateVertexBuffer(dst) failed", hResult);
- goto return_with_error;
- }
-#endif
-
-#endif _USE_GLD3_WGL
-
- //
- // Now create the Mesa context
- //
-
- // Create the Mesa visual
- if (lpPFD->cDepthBits)
- dwDepthBits = 16;
- if (lpPFD->cStencilBits)
- dwStencilBits = 8;
- if (lpPFD->cAlphaBits) {
- dwAlphaBits = 8;
- bAlphaSW = GL_TRUE;
- }
- if (lpPFD->dwFlags & PFD_DOUBLEBUFFER)
- bDouble = GL_TRUE;
-// lpCtx->EmulateSingle =
-// (lpPFD->dwFlags & PFD_DOUBLEBUFFER) ? FALSE : TRUE;
-
-#ifdef _USE_GLD3_WGL
- lpCtx->glVis = _mesa_create_visual(
- bDouble, /* double buffer */
- GL_FALSE, // stereo
- lpPFD->cRedBits,
- lpPFD->cGreenBits,
- lpPFD->cBlueBits,
- dwAlphaBits,
- dwDepthBits,
- dwStencilBits,
- lpPFD->cAccumRedBits, // accum bits
- lpPFD->cAccumGreenBits, // accum bits
- lpPFD->cAccumBlueBits, // accum bits
- lpPFD->cAccumAlphaBits, // accum alpha bits
- 1 // num samples
- );
-#else // _USE_GLD3_WGL
- lpCtx->glVis = (*mesaFuncs.gl_create_visual)(
- GL_TRUE, // RGB mode
- bAlphaSW, // Is an alpha buffer required?
- bDouble, // Is an double-buffering required?
- GL_FALSE, // stereo
- dwDepthBits, // depth_size
- dwStencilBits, // stencil_size
- lpPFD->cAccumBits, // accum_size
- 0, // colour-index bits
- lpPFD->cRedBits, // Red bit count
- lpPFD->cGreenBits, // Green bit count
- lpPFD->cBlueBits, // Blue bit count
- dwAlphaBits // Alpha bit count
- );
-#endif // _USE_GLD3_WGL
-
- if (lpCtx->glVis == NULL) {
- ddlogMessage(DDLOG_CRITICAL_OR_WARN, "gl_create_visual failed\n");
- goto return_with_error;
- }
-
-#ifdef _USE_GLD3_WGL
- lpCtx->glCtx = _mesa_create_context(API_OPENGL, lpCtx->glVis, NULL, (void *)lpCtx, GL_TRUE);
-#else
- // Create the Mesa context
- lpCtx->glCtx = (*mesaFuncs.gl_create_context)(
- lpCtx->glVis, // Mesa visual
- NULL, // share list context
- (void *)lpCtx, // Pointer to our driver context
- GL_TRUE // Direct context flag
- );
-#endif // _USE_GLD3_WGL
-
- if (lpCtx->glCtx == NULL) {
- ddlogMessage(DDLOG_CRITICAL_OR_WARN, "gl_create_context failed\n");
- goto return_with_error;
- }
-
- // Create the Mesa framebuffer
-#ifdef _USE_GLD3_WGL
- lpCtx->glBuffer = _mesa_create_framebuffer(
- lpCtx->glVis,
- lpCtx->glVis->depthBits > 0,
- lpCtx->glVis->stencilBits > 0,
- lpCtx->glVis->accumRedBits > 0,
- GL_FALSE //swalpha
- );
-#else
- lpCtx->glBuffer = (*mesaFuncs.gl_create_framebuffer)(lpCtx->glVis);
-#endif // _USE_GLD3_WGL
-
- if (lpCtx->glBuffer == NULL) {
- ddlogMessage(DDLOG_CRITICAL_OR_WARN, "gl_create_framebuffer failed\n");
- goto return_with_error;
- }
-
-#ifdef _USE_GLD3_WGL
- // Init Mesa internals
- _swrast_CreateContext( lpCtx->glCtx );
- _vbo_CreateContext( lpCtx->glCtx );
- _tnl_CreateContext( lpCtx->glCtx );
- _swsetup_CreateContext( lpCtx->glCtx );
-
- _gldDriver.InitialiseMesa(lpCtx);
-
- lpCtx->glCtx->imports.warning = _gld_mesa_warning;
- lpCtx->glCtx->imports.fatal = _gld_mesa_fatal;
-
-#else
- // Tell Mesa how many texture stages we have
- glb.wMaxSimultaneousTextures = lpCtx->D3DDevDesc.wMaxSimultaneousTextures;
- // Only use as many Units as the spec requires
- if (glb.wMaxSimultaneousTextures > MAX_TEXTURE_UNITS)
- glb.wMaxSimultaneousTextures = MAX_TEXTURE_UNITS;
- lpCtx->glCtx->Const.MaxTextureUnits = glb.wMaxSimultaneousTextures;
- ddlogPrintf(DDLOG_INFO, "Texture stages : %d", glb.wMaxSimultaneousTextures);
-
- // Set the max texture size.
- // NOTE: clamped to a max of 1024 for extra performance!
- lpCtx->dwMaxTextureSize = (lpCtx->D3DDevDesc.dwMaxTextureWidth <= 1024) ? lpCtx->D3DDevDesc.dwMaxTextureWidth : 1024;
-
-// Texture resize takes place elsewhere. KH
-// NOTE: This was added to workaround an issue with the Intel app.
-#if 0
- lpCtx->glCtx->Const.MaxTextureSize = lpCtx->dwMaxTextureSize;
-#else
- lpCtx->glCtx->Const.MaxTextureSize = 1024;
-#endif
- lpCtx->glCtx->Const.MaxDrawBuffers = 1;
-
- // Setup the Display Driver pointers
- dglSetupDDPointers(lpCtx->glCtx);
-
- // Initialise all the Direct3D renderstates
- dglInitStateD3D(lpCtx->glCtx);
-
-#if 0
- // Signal a reload of texture state on next glBegin
- lpCtx->m_texHandleValid = FALSE;
- lpCtx->m_mtex = FALSE;
- lpCtx->m_texturing = FALSE;
-#else
- // Set default texture unit state
-// dglSetTexture(lpCtx, 0, NULL);
-// dglSetTexture(lpCtx, 1, NULL);
-#endif
-
- //
- // Set the global texture palette to default values.
- //
-
- // Clear the entire palette
- ZeroMemory(ppe, sizeof(PALETTEENTRY) * 256);
-
- // Fill the palette with a default colour.
- // A garish colour is used to catch bugs. Here Magenta is used.
- for (i=0; i < 256; i++) {
- ppe[i].peRed = 255;
- ppe[i].peGreen = 0;
- ppe[i].peBlue = 255;
- }
-
- RELEASE(lpCtx->lpGlobalPalette);
-
- if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpGlobalPalette)
- hResult = IDirectDrawPalette_AddRef(lpCtx->lpGlobalPalette = glb.lpGlobalPalette);
- else
- hResult = IDirectDraw4_CreatePalette(
- lpCtx->lpDD4,
- DDPCAPS_INITIALIZE | DDPCAPS_8BIT | DDPCAPS_ALLOW256,
- ppe,
- &(lpCtx->lpGlobalPalette),
- NULL);
- if (FAILED(hResult)) {
- ddlogError(DDLOG_ERROR, "Default CreatePalette failed\n", hResult);
- lpCtx->lpGlobalPalette = NULL;
- goto return_with_error;
- }
- if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && !glb.lpGlobalPalette)
- IDirectDrawPalette_AddRef(glb.lpGlobalPalette = lpCtx->lpGlobalPalette);
-
-#endif // _USE_GLD3_WGL
-
- // ** If we have made it to here then we can enable rendering **
- lpCtx->bCanRender = TRUE;
-
-// ddlogMessage(DDLOG_SYSTEM, "dglCreateContextBuffers succeded\n");
-
-#ifdef GLD_THREADS
- // Release serialized access
- if (glb.bMultiThreaded)
- LeaveCriticalSection(&CriticalSection);
-#endif
-
- return TRUE;
-
-return_with_error:
- // Clean up before returning.
- // This is critical for secondary devices.
-
- lpCtx->bCanRender = FALSE;
-
-#ifdef _USE_GLD3_WGL
- // Destroy the Mesa context
- if (lpCtx->glBuffer)
- _mesa_destroy_framebuffer(lpCtx->glBuffer);
- if (lpCtx->glCtx)
- _mesa_destroy_context(lpCtx->glCtx);
- if (lpCtx->glVis)
- _mesa_destroy_visual(lpCtx->glVis);
-
- // Destroy driver data
- _gldDriver.DestroyDrawable(lpCtx);
-#else
- // Destroy the Mesa context
- if (lpCtx->glBuffer)
- (*mesaFuncs.gl_destroy_framebuffer)(lpCtx->glBuffer);
- if (lpCtx->glCtx)
- (*mesaFuncs.gl_destroy_context)(lpCtx->glCtx);
- if (lpCtx->glVis)
- (*mesaFuncs.gl_destroy_visual)(lpCtx->glVis);
-
- RELEASE(lpCtx->m_pvbuf); // Release D3D vertex buffer
- RELEASE(lpCtx->m_vbuf); // Release D3D vertex buffer
-
- if (lpCtx->lpViewport3) {
- if (lpCtx->lpDev3) IDirect3DDevice3_DeleteViewport(lpCtx->lpDev3, lpCtx->lpViewport3);
- RELEASE(lpCtx->lpViewport3);
- lpCtx->lpViewport3 = NULL;
- }
-
- RELEASE(lpCtx->lpDev3);
- if (lpCtx->lpDepth4) {
- if (lpCtx->lpBack4)
- IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpBack4, 0L, lpCtx->lpDepth4);
- else
- IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpFront4, 0L, lpCtx->lpDepth4);
- RELEASE(lpCtx->lpDepth4);
- lpCtx->lpDepth4 = NULL;
- }
- RELEASE(lpCtx->lpBack4);
- RELEASE(lpCtx->lpFront4);
- else
- if (lpCtx->bFullscreen) {
- IDirectDraw4_RestoreDisplayMode(lpCtx->lpDD4);
- IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4, NULL, DDSCL_NORMAL);
- }
- RELEASE(lpCtx->lpD3D3);
- RELEASE(lpCtx->lpDD4);
- RELEASE(lpCtx->lpDD1);
-#endif // _USE_GLD3_WGL
-
- lpCtx->bAllocated = FALSE;
-
-#ifdef GLD_THREADS
- // Release serialized access
- if (glb.bMultiThreaded)
- LeaveCriticalSection(&CriticalSection);
-#endif
-
- return FALSE;
-
-#undef DDLOG_CRITICAL_OR_WARN
-}
-
-// ***********************************************************************
-
-HGLRC dglCreateContext(
- HDC a,
- const DGL_pixelFormat *lpPF)
-{
- int i;
- HGLRC hGLRC;
- DGL_ctx* lpCtx;
- static BOOL bWarnOnce = TRUE;
- DWORD dwThreadId = GetCurrentThreadId();
- char szMsg[256];
- HWND hWnd;
- LONG lpfnWndProc;
-
- // Validate license
- if (!dglValidate())
- return NULL;
-
- // Is context state ready ?
- if (!bContextReady)
- return NULL;
-
- ddlogPrintf(DDLOG_SYSTEM, "dglCreateContext for HDC=%X, ThreadId=%X", a, dwThreadId);
-
- // Find next free context.
- // Also ensure that only one Fullscreen context is created at any one time.
- hGLRC = 0; // Default to Not Found
- for (i=0; i<DGL_MAX_CONTEXTS; i++) {
- if (ctxlist[i].bAllocated) {
- if (/*glb.bFullscreen && */ctxlist[i].bFullscreen)
- break;
- } else {
- hGLRC = (HGLRC)(i+1);
- break;
- }
- }
-
- // Bail if no GLRC was found
- if (!hGLRC)
- return NULL;
-
- // Set the context pointer
- lpCtx = dglGetContextAddress(hGLRC);
- // Make sure that context is zeroed before we do anything.
- // MFC and C++ apps call wglCreateContext() and wglDeleteContext() multiple times,
- // even though only one context is ever used by the app, so keep it clean. (DaveM)
- ZeroMemory(lpCtx, sizeof(DGL_ctx));
- lpCtx->bAllocated = TRUE;
- // Flag that buffers need creating on next wglMakeCurrent call.
- lpCtx->bHasBeenCurrent = FALSE;
- lpCtx->lpPF = (DGL_pixelFormat *)lpPF; // cache pixel format
- lpCtx->bCanRender = FALSE;
-
- // Create all the internal resources here, not in dglMakeCurrent().
- // We do a re-size check in dglMakeCurrent in case of re-allocations. (DaveM)
- // We now try context allocations twice, first with video memory,
- // then again with system memory. This is similar to technique
- // used for dglWglResizeBuffers(). (DaveM)
- if (lpCtx->bHasBeenCurrent == FALSE) {
- if (!dglCreateContextBuffers(a, lpCtx, FALSE)) {
- if (glb.bMessageBoxWarnings && bWarnOnce && dwLogging) {
- bWarnOnce = FALSE;
- switch (nContextError) {
- case GLDERR_DDRAW: strcpy(szMsg, szDDrawWarning); break;
- case GLDERR_D3D: strcpy(szMsg, szD3DWarning); break;
- case GLDERR_MEM: strcpy(szMsg, szResourceWarning); break;
- case GLDERR_BPP: strcpy(szMsg, szBPPWarning); break;
- default: strcpy(szMsg, "");
- }
- if (strlen(szMsg))
- MessageBox(NULL, szMsg, "GLDirect", MB_OK | MB_ICONWARNING);
- }
- // Only need to try again if memory error
- if (nContextError == GLDERR_MEM) {
- ddlogPrintf(DDLOG_WARN, "dglCreateContext failed 1st time with video memory");
- }
- else {
- ddlogPrintf(DDLOG_ERROR, "dglCreateContext failed");
- return NULL;
- }
- }
- }
-
- // Now that we have a hWnd, we can intercept the WindowProc.
- hWnd = lpCtx->hWnd;
- if (hWnd) {
- // Only hook individual window handler once if not hooked before.
- lpfnWndProc = GetWindowLong(hWnd, GWL_WNDPROC);
- if (lpfnWndProc != (LONG)dglWndProc) {
- lpCtx->lpfnWndProc = lpfnWndProc;
- SetWindowLong(hWnd, GWL_WNDPROC, (LONG)dglWndProc);
- }
- // Find the parent window of the app too.
- if (glb.hWndActive == NULL) {
- while (hWnd != NULL) {
- glb.hWndActive = hWnd;
- hWnd = GetParent(hWnd);
- }
- // Hook the parent window too.
- lpfnWndProc = GetWindowLong(glb.hWndActive, GWL_WNDPROC);
- if (glb.hWndActive == lpCtx->hWnd)
- glb.lpfnWndProc = lpCtx->lpfnWndProc;
- else if (lpfnWndProc != (LONG)dglWndProc)
- glb.lpfnWndProc = lpfnWndProc;
- if (glb.lpfnWndProc)
- SetWindowLong(glb.hWndActive, GWL_WNDPROC, (LONG)dglWndProc);
- }
- }
-
- ddlogPrintf(DDLOG_SYSTEM, "dglCreateContext succeeded for HGLRC=%d", (int)hGLRC);
-
- return hGLRC;
-}
-
-// ***********************************************************************
-// Make a DirectGL context current
-// Used by wgl functions and dgl functions
-BOOL dglMakeCurrent(
- HDC a,
- HGLRC b)
-{
- int context;
- DGL_ctx* lpCtx;
- HWND hWnd;
- BOOL bNeedResize = FALSE;
- BOOL bWindowChanged, bContextChanged;
- LPDIRECTDRAWCLIPPER lpddClipper;
- DWORD dwThreadId = GetCurrentThreadId();
- LONG lpfnWndProc;
-
- // Validate license
- if (!dglValidate())
- return FALSE;
-
- // Is context state ready ?
- if (!bContextReady)
- return FALSE;
-
- context = (int)b; // This is as a result of STRICT!
- ddlogPrintf(DDLOG_SYSTEM, "dglMakeCurrent: HDC=%X, HGLRC=%d, ThreadId=%X", a, context, dwThreadId);
-
- // If the HGLRC is NULL then make no context current;
- // Ditto if the HDC is NULL either. (DaveM)
- if (context == 0 || a == 0) {
- // Corresponding Mesa operation
-#ifdef _USE_GLD3_WGL
- _mesa_make_current(NULL, NULL);
-#else
- (*mesaFuncs.gl_make_current)(NULL, NULL);
-#endif
- dglSetCurrentContext(0);
- return TRUE;
- }
-
- // Make sure the HGLRC is in range
- if ((context > DGL_MAX_CONTEXTS) || (context < 0)) {
- ddlogMessage(DDLOG_ERROR, "dglMakeCurrent: HGLRC out of range\n");
- return FALSE;
- }
-
- // Find address of context and make sure that it has been allocated
- lpCtx = dglGetContextAddress(b);
- if (!lpCtx->bAllocated) {
- ddlogMessage(DDLOG_ERROR, "dglMakeCurrent: Context not allocated\n");
-// return FALSE;
- return TRUE; // HACK: Shuts up "WebLab Viewer Pro". KeithH
- }
-
-#ifdef GLD_THREADS
- // Serialize access to DirectDraw or DDS operations
- if (glb.bMultiThreaded)
- EnterCriticalSection(&CriticalSection);
-#endif
-
- // Check if window has changed
- hWnd = (a != lpCtx->hDC) ? WindowFromDC(a) : lpCtx->hWnd;
- bWindowChanged = (hWnd != lpCtx->hWnd) ? TRUE : FALSE;
- bContextChanged = (b != dglGetCurrentContext()) ? TRUE : FALSE;
-
- // If the window has changed, make sure the clipper is updated. (DaveM)
- if (glb.bDirectDrawPersistant && !lpCtx->bFullscreen && (bWindowChanged || bContextChanged)) {
- lpCtx->hWnd = hWnd;
-#ifndef _USE_GLD3_WGL
- IDirectDrawSurface4_GetClipper(lpCtx->lpFront4, &lpddClipper);
- IDirectDrawClipper_SetHWnd(lpddClipper, 0, lpCtx->hWnd);
- IDirectDrawClipper_Release(lpddClipper);
-#endif // _USE_GLD3_WGL
- }
-
- // Make sure hDC and hWnd is current. (DaveM)
- // Obtain the dimensions of the rendering window
- lpCtx->hDC = a; // Cache DC
- lpCtx->hWnd = hWnd;
- hWndLastActive = hWnd;
-
- // Check for non-window DC = memory DC ?
- if (hWnd == NULL) {
- if (GetClipBox(a, &lpCtx->rcScreenRect) == ERROR) {
- ddlogMessage(DDLOG_WARN, "GetClipBox failed in dglMakeCurrent\n");
- SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0);
- }
- }
- else if (!GetClientRect(lpCtx->hWnd, &lpCtx->rcScreenRect)) {
- ddlogMessage(DDLOG_WARN, "GetClientRect failed in dglMakeCurrent\n");
- SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0);
- }
- // Check if buffers need to be re-sized;
- // If so, wait until Mesa GL stuff is setup before re-sizing;
- if (lpCtx->dwWidth != lpCtx->rcScreenRect.right - lpCtx->rcScreenRect.left ||
- lpCtx->dwHeight != lpCtx->rcScreenRect.bottom - lpCtx->rcScreenRect.top)
- bNeedResize = TRUE;
-
- // Now we can update our globals
- dglSetCurrentContext(b);
-
- // Corresponding Mesa operation
-#ifdef _USE_GLD3_WGL
- _mesa_make_current(lpCtx->glCtx, lpCtx->glBuffer);
- lpCtx->glCtx->Driver.UpdateState(lpCtx->glCtx, _NEW_ALL);
- if (bNeedResize) {
- // Resize buffers (Note Mesa GL needs to be setup beforehand);
- // Resize Mesa internal buffer too via glViewport() command,
- // which subsequently calls dglWglResizeBuffers() too.
- lpCtx->glCtx->Driver.Viewport(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight);
- lpCtx->bHasBeenCurrent = TRUE;
- }
-#else
- (*mesaFuncs.gl_make_current)(lpCtx->glCtx, lpCtx->glBuffer);
-
- dglSetupDDPointers(lpCtx->glCtx);
-
- // Insure DirectDraw surfaces fit current window DC
- if (bNeedResize) {
- // Resize buffers (Note Mesa GL needs to be setup beforehand);
- // Resize Mesa internal buffer too via glViewport() command,
- // which subsequently calls dglWglResizeBuffers() too.
- (*mesaFuncs.gl_Viewport)(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight);
- lpCtx->bHasBeenCurrent = TRUE;
- }
-#endif // _USE_GLD3_WGL
- ddlogPrintf(DDLOG_SYSTEM, "dglMakeCurrent: width = %d, height = %d", lpCtx->dwWidth, lpCtx->dwHeight);
-
- // We have to clear D3D back buffer and render state if emulated front buffering
- // for different window (but not context) like in Solid Edge.
- if (glb.bDirectDrawPersistant && glb.bPersistantBuffers
- && (bWindowChanged /* || bContextChanged */) && lpCtx->EmulateSingle) {
-#ifdef _USE_GLD3_WGL
-// IDirect3DDevice8_EndScene(lpCtx->pDev);
-// lpCtx->bSceneStarted = FALSE;
- lpCtx->glCtx->Driver.Clear(lpCtx->glCtx, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
- GL_TRUE, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight);
-#else
- IDirect3DDevice3_EndScene(lpCtx->lpDev3);
- lpCtx->bSceneStarted = FALSE;
- dglClearD3D(lpCtx->glCtx, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
- GL_TRUE, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight);
-#endif // _USE_GLD3_WGL
- }
-
- // The first time we call MakeCurrent we set the initial viewport size
- if (lpCtx->bHasBeenCurrent == FALSE)
-#ifdef _USE_GLD3_WGL
- lpCtx->glCtx->Driver.Viewport(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight);
-#else
- (*mesaFuncs.gl_Viewport)(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight);
-#endif // _USE_GLD3_WGL
- lpCtx->bHasBeenCurrent = TRUE;
-
-#ifdef GLD_THREADS
- // Release serialized access
- if (glb.bMultiThreaded)
- LeaveCriticalSection(&CriticalSection);
-#endif
-
- return TRUE;
-}
-
-// ***********************************************************************
-
-BOOL dglDeleteContext(
- HGLRC a)
-{
- DGL_ctx* lpCtx;
- DWORD dwThreadId = GetCurrentThreadId();
- char argstr[256];
-
-#if 0 // We have enough trouble throwing exceptions as it is... (DaveM)
- // Validate license
- if (!dglValidate())
- return FALSE;
-#endif
-
- // Is context state ready ?
- if (!bContextReady)
- return FALSE;
-
- ddlogPrintf(DDLOG_SYSTEM, "dglDeleteContext: Deleting context HGLRC=%d, ThreadId=%X", (int)a, dwThreadId);
-
- // Make sure the HGLRC is in range
- if (((int) a> DGL_MAX_CONTEXTS) || ((int)a < 0)) {
- ddlogMessage(DDLOG_ERROR, "dglDeleteCurrent: HGLRC out of range\n");
- return FALSE;
- }
-
- // Make sure context is valid
- lpCtx = dglGetContextAddress(a);
- if (!lpCtx->bAllocated) {
- ddlogPrintf(DDLOG_WARN, "Tried to delete unallocated context HGLRC=%d", (int)a);
-// return FALSE;
- return TRUE; // HACK: Shuts up "WebLab Viewer Pro". KeithH
- }
-
- // Make sure context is de-activated
- if (a == dglGetCurrentContext()) {
- ddlogPrintf(DDLOG_WARN, "dglDeleteContext: context HGLRC=%d still active", (int)a);
- dglMakeCurrent(NULL, NULL);
- }
-
-#ifdef GLD_THREADS
- // Serialize access to DirectDraw or DDS operations
- if (glb.bMultiThreaded)
- EnterCriticalSection(&CriticalSection);
-#endif
-
- // We are about to destroy all Direct3D objects.
- // Therefore we must disable rendering
- lpCtx->bCanRender = FALSE;
-
- // This exception handler was installed to catch some
- // particularly nasty apps. Console apps that call exit()
- // fall into this catagory (i.e. Win32 Glut).
-
- // VC cannot successfully implement multiple exception handlers
- // if more than one exception occurs. Therefore reverting back to
- // single exception handler as Keith originally had it. (DaveM)
-
-#define WARN_MESSAGE(p) strcpy(argstr, (#p));
-#define SAFE_RELEASE(p) WARN_MESSAGE(p); RELEASE(p);
-
-__try {
-#ifdef _USE_GLD3_WGL
- WARN_MESSAGE(gl_destroy_framebuffer);
- if (lpCtx->glBuffer)
- _mesa_destroy_framebuffer(lpCtx->glBuffer);
- WARN_MESSAGE(gl_destroy_context);
- if (lpCtx->glCtx)
- _mesa_destroy_context(lpCtx->glCtx);
- WARN_MESSAGE(gl_destroy_visual);
- if (lpCtx->glVis)
- _mesa_destroy_visual(lpCtx->glVis);
-
- _gldDriver.DestroyDrawable(lpCtx);
-#else
- // Destroy the Mesa context
- WARN_MESSAGE(gl_destroy_framebuffer);
- if (lpCtx->glBuffer)
- (*mesaFuncs.gl_destroy_framebuffer)(lpCtx->glBuffer);
- WARN_MESSAGE(gl_destroy_context);
- if (lpCtx->glCtx)
- (*mesaFuncs.gl_destroy_context)(lpCtx->glCtx);
- WARN_MESSAGE(gl_destroy_visual);
- if (lpCtx->glVis)
- (*mesaFuncs.gl_destroy_visual)(lpCtx->glVis);
-
- SAFE_RELEASE(lpCtx->m_pvbuf); // release D3D vertex buffer
- SAFE_RELEASE(lpCtx->m_vbuf); // release D3D vertex buffer
-
- // Delete the global palette
- SAFE_RELEASE(lpCtx->lpGlobalPalette);
-
- // Clean up.
- if (lpCtx->lpViewport3) {
- if (lpCtx->lpDev3) IDirect3DDevice3_DeleteViewport(lpCtx->lpDev3, lpCtx->lpViewport3);
- SAFE_RELEASE(lpCtx->lpViewport3);
- lpCtx->lpViewport3 = NULL;
- }
-
- SAFE_RELEASE(lpCtx->lpDev3);
- if (lpCtx->lpDepth4) {
- if (lpCtx->lpBack4)
- IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpBack4, 0L, lpCtx->lpDepth4);
- else
- IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpFront4, 0L, lpCtx->lpDepth4);
- SAFE_RELEASE(lpCtx->lpDepth4);
- lpCtx->lpDepth4 = NULL;
- }
- SAFE_RELEASE(lpCtx->lpBack4);
- SAFE_RELEASE(lpCtx->lpFront4);
- if (lpCtx->bFullscreen) {
- IDirectDraw4_RestoreDisplayMode(lpCtx->lpDD4);
- IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4, NULL, DDSCL_NORMAL);
- }
- SAFE_RELEASE(lpCtx->lpD3D3);
- SAFE_RELEASE(lpCtx->lpDD4);
- SAFE_RELEASE(lpCtx->lpDD1);
-#endif // _ULSE_GLD3_WGL
-
-}
-__except(EXCEPTION_EXECUTE_HANDLER) {
- ddlogPrintf(DDLOG_WARN, "Exception raised in dglDeleteContext: %s", argstr);
-}
-
- // Restore the window message handler because this context may be used
- // again by another window with a *different* message handler. (DaveM)
- if (lpCtx->lpfnWndProc) {
- SetWindowLong(lpCtx->hWnd, GWL_WNDPROC, (LONG)lpCtx->lpfnWndProc);
- lpCtx->lpfnWndProc = (LONG)NULL;
- }
-
- lpCtx->bAllocated = FALSE; // This context is now free for use
-
-#ifdef GLD_THREADS
- // Release serialized access
- if (glb.bMultiThreaded)
- LeaveCriticalSection(&CriticalSection);
-#endif
-
- return TRUE;
-}
-
-// ***********************************************************************
-
-BOOL dglSwapBuffers(
- HDC hDC)
-{
- RECT rSrcRect; // Source rectangle
- RECT rDstRect; // Destination rectangle
- POINT pt;
- HRESULT hResult;
-
- DDBLTFX bltFX;
- DWORD dwBlitFlags;
- DDBLTFX *lpBltFX;
-
-// DWORD dwThreadId = GetCurrentThreadId();
- HGLRC hGLRC = dglGetCurrentContext();
- DGL_ctx *lpCtx = dglGetContextAddress(hGLRC);
- HWND hWnd;
-
- HDC hDCAux; // for memory DC
- int x,y,w,h; // for memory DC BitBlt
-
-#if 0 // Perhaps not a good idea. Called too often. KH
- // Validate license
- if (!dglValidate())
- return FALSE;
-#endif
-
- if (!lpCtx) {
- return TRUE; //FALSE; // No current context
- }
-
- if (!lpCtx->bCanRender) {
- // Don't return false else some apps will bail.
- return TRUE;
- }
-
- hWnd = lpCtx->hWnd;
- if (hDC != lpCtx->hDC) {
- ddlogPrintf(DDLOG_WARN, "dglSwapBuffers: HDC=%X does not match HDC=%X for HGLRC=%d", hDC, lpCtx->hDC, hGLRC);
- hWnd = WindowFromDC(hDC);
- }
-
-#ifndef _USE_GLD3_WGL
- // Ensure that the surfaces exist before we tell
- // the device to render to them.
- IDirectDraw4_RestoreAllSurfaces(lpCtx->lpDD4);
-
- // Make sure that the vertex caches have been emptied
-// dglStateChange(lpCtx);
-
- // Some OpenGL programs don't issue a glFinish - check for it here.
- if (lpCtx->bSceneStarted) {
- IDirect3DDevice3_EndScene(lpCtx->lpDev3);
- lpCtx->bSceneStarted = FALSE;
- }
-#endif
-
-#if 0
- // If the calling app is not active then we don't need to Blit/Flip.
- // We can therefore simply return TRUE.
- if (!glb.bAppActive)
- return TRUE;
- // Addendum: This is WRONG! We should bail if the app is *minimized*,
- // not merely if the app is just plain 'not active'.
- // KeithH, 27/May/2000.
-#endif
-
- // Check for non-window DC = memory DC ?
- if (hWnd == NULL) {
- if (GetClipBox(hDC, &rSrcRect) == ERROR)
- return TRUE;
- // Use GDI BitBlt instead from compatible DirectDraw DC
- x = rSrcRect.left;
- y = rSrcRect.top;
- w = rSrcRect.right - rSrcRect.left;
- h = rSrcRect.bottom - rSrcRect.top;
-
- // Ack. DX8 does not have a GetDC() function...
- // TODO: Defer to DX7 or DX9 drivers... (DaveM)
- return TRUE;
- }
-
- // Bail if window client region is not drawable, like in Solid Edge
- if (!IsWindow(hWnd) /* || !IsWindowVisible(hWnd) */ || !GetClientRect(hWnd, &rSrcRect))
- return TRUE;
-
-#ifdef GLD_THREADS
- // Serialize access to DirectDraw or DDS operations
- if (glb.bMultiThreaded)
- EnterCriticalSection(&CriticalSection);
-#endif
-
-#ifdef _USE_GLD3_WGL
- // Notify Mesa of impending swap, so Mesa can flush internal buffers.
- _mesa_notifySwapBuffers(lpCtx->glCtx);
- // Now perform driver buffer swap
- _gldDriver.SwapBuffers(lpCtx, hDC, hWnd);
-#else
- if (lpCtx->bFullscreen) {
- // Sync with retrace if required
- if (glb.bWaitForRetrace) {
- IDirectDraw4_WaitForVerticalBlank(
- lpCtx->lpDD4,
- DDWAITVB_BLOCKBEGIN,
- 0);
- }
-
- // Perform the fullscreen flip
- TRY(IDirectDrawSurface4_Flip(
- lpCtx->lpFront4,
- NULL,
- DDFLIP_WAIT),
- "dglSwapBuffers: Flip");
- } else {
- // Calculate current window position and size
- pt.x = pt.y = 0;
- ClientToScreen(hWnd, &pt);
- GetClientRect(hWnd, &rDstRect);
- if (rDstRect.right > lpCtx->dwModeWidth)
- rDstRect.right = lpCtx->dwModeWidth;
- if (rDstRect.bottom > lpCtx->dwModeHeight)
- rDstRect.bottom = lpCtx->dwModeHeight;
- OffsetRect(&rDstRect, pt.x, pt.y);
- rSrcRect.left = rSrcRect.top = 0;
- rSrcRect.right = lpCtx->dwWidth;
- rSrcRect.bottom = lpCtx->dwHeight;
- if (rSrcRect.right > lpCtx->dwModeWidth)
- rSrcRect.right = lpCtx->dwModeWidth;
- if (rSrcRect.bottom > lpCtx->dwModeHeight)
- rSrcRect.bottom = lpCtx->dwModeHeight;
-
- if (glb.bWaitForRetrace) {
- // Sync the blit to the vertical retrace
- ZeroMemory(&bltFX, sizeof(bltFX));
- bltFX.dwSize = sizeof(bltFX);
- bltFX.dwDDFX = DDBLTFX_NOTEARING;
- dwBlitFlags = DDBLT_WAIT | DDBLT_DDFX;
- lpBltFX = &bltFX;
- } else {
- dwBlitFlags = DDBLT_WAIT;
- lpBltFX = NULL;
- }
-
- // Perform the actual blit
- TRY(IDirectDrawSurface4_Blt(
- lpCtx->lpFront4,
- &rDstRect,
- lpCtx->lpBack4, // Blit source
- &rSrcRect,
- dwBlitFlags,
- lpBltFX),
- "dglSwapBuffers: Blt");
- }
-#endif // _USE_GLD3_WGL
-
-#ifdef GLD_THREADS
- // Release serialized access
- if (glb.bMultiThreaded)
- LeaveCriticalSection(&CriticalSection);
-#endif
-
- // TODO: Re-instate rendering bitmap snapshot feature??? (DaveM)
-
- // Render frame is completed
- ValidateRect(hWnd, NULL);
- lpCtx->bFrameStarted = FALSE;
-
- return TRUE;
-}
-
-// ***********************************************************************