📄 dglcontext.c
字号:
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 functionsBOOL 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -