⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dglcontext.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
                   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 + -