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

📄 dglwgl.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
	DDBLTFX						ddbltfx;	POINT						pt;	RECT						rcDst;#ifdef _USE_GLD3_WGL	GLD_displayMode				glddm;#endif#define DDLOG_CRITICAL_OR_WARN	(bDefaultDriver ? DDLOG_WARN : DDLOG_CRITICAL)	// Validate license	if (!dglValidate())		return FALSE;	// Sanity checks	if (ctx == NULL)		return FALSE;	dgl = ctx->DriverCtx;	if (dgl == NULL)		return FALSE;	// Get the window size and calculate its dimensions	if (dgl->hWnd == NULL) {		// Check for non-window DC = memory DC ?		if (GetClipBox(dgl->hDC, &rcScreenRect) == ERROR)			SetRect(&rcScreenRect, 0, 0, 0, 0);	}	else if (!GetClientRect(dgl->hWnd, &rcScreenRect))		SetRect(&rcScreenRect, 0, 0, 0, 0);	dwWidth = rcScreenRect.right - rcScreenRect.left;	dwHeight = rcScreenRect.bottom - rcScreenRect.top;    CopyRect(&dgl->rcScreenRect, &rcScreenRect);	// This will occur on Alt-Tab	if ((dwWidth == 0) && (dwHeight == 0)) {		//dgl->bCanRender = FALSE;		return TRUE; // No resize possible!	}	// Some apps zero only 1 dimension for non-visible window... (DaveM)	if ((dwWidth == 0) || (dwHeight == 0)) {		dwWidth = 8;		dwHeight = 8;	}	// Test to see if a resize is required.	// Note that the dimensions will be the same if a prior resize attempt failed.	if ((dwWidth == dgl->dwWidth) && (dwHeight == dgl->dwHeight) && bDefaultDriver) {		return TRUE; // No resize required	}	ddlogPrintf(DDLOG_SYSTEM, "dglResize: %dx%d", dwWidth, dwHeight);#ifndef _USE_GLD3_WGL	// Work out where we want our surfaces created	dwMemoryType = (bDefaultDriver) ? glb.dwMemoryType : DDSCAPS_SYSTEMMEMORY;#endif // _USE_GLD3_WGL	// Note previous fullscreen vs window display status	bWasFullscreen = dgl->bFullscreen;#ifdef _USE_GLD3_WGL	if (_gldDriver.GetDisplayMode(dgl, &glddm)) {		if ( (dwWidth == glddm.Width) &&				 (dwHeight == glddm.Height) ) {			bFullScrnWin = TRUE;		}		if (bFullScrnWin && glb.bPrimary && !glb.bFullscreenBlit && !glb.bDirectDrawPersistant) {			dgl->bFullscreen = TRUE;			ddlogMessage(DDLOG_INFO, "Fullscreen window after resize.\n");		}		else {			dgl->bFullscreen = FALSE;			ddlogMessage(DDLOG_INFO, "Non-Fullscreen window after resize.\n");		}		// Cache the display mode dimensions		dgl->dwModeWidth = glddm.Width;		dgl->dwModeHeight = glddm.Height;	}	// 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 (dgl->dwWidth > glddm.Width)		dgl->dwWidth = glddm.Width;	if (dgl->dwHeight > glddm.Height)		dgl->dwHeight = glddm.Height;#else // _USE_GLD3_WGL	// Window resize may have changed to fullscreen	ZeroMemory(&ddsd2DisplayMode, sizeof(ddsd2DisplayMode));	ddsd2DisplayMode.dwSize = sizeof(ddsd2DisplayMode);	hResult = IDirectDraw4_GetDisplayMode(					dgl->lpDD4,					&ddsd2DisplayMode);	if (SUCCEEDED(hResult)) {		if ( (dwWidth == ddsd2DisplayMode.dwWidth) &&				 (dwHeight == ddsd2DisplayMode.dwHeight) ) {			bFullScrnWin = TRUE;		}		if (bFullScrnWin && glb.bPrimary && !glb.bFullscreenBlit && !glb.bDirectDrawPersistant) {			dgl->bFullscreen = TRUE;			ddlogMessage(DDLOG_INFO, "Fullscreen window after resize.\n");		}		else {			dgl->bFullscreen = FALSE;			ddlogMessage(DDLOG_INFO, "Non-Fullscreen window after resize.\n");		}		// Cache the display mode dimensions		dgl->dwModeWidth = ddsd2DisplayMode.dwWidth;		dgl->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 (dgl->dwWidth > ddsd2DisplayMode.dwWidth)		dgl->dwWidth = ddsd2DisplayMode.dwWidth;	if (dgl->dwHeight > ddsd2DisplayMode.dwHeight)		dgl->dwHeight = ddsd2DisplayMode.dwHeight;#endif // _USE_GLD3_WGL	// Note if fullscreen vs window display has changed?	bSaveDesktop = (!bWasFullscreen && !dgl->bFullscreen) ? TRUE : FALSE;	// Save the desktop primary surface from being destroyed	// whenever remaining in windowed mode, since the stereo mode	// switches are expensive...#ifndef _USE_GLD3_WGL	// Don't need to re-allocate persistant buffers. (DaveM)	// Though we should clear the back buffers to hide artifacts.	if (glb.bDirectDrawPersistant && glb.bPersistantBuffers) {		dgl->dwWidth = dwWidth;		dgl->dwHeight = dwHeight;		ZeroMemory(&ddbltfx, sizeof(ddbltfx));		ddbltfx.dwSize = sizeof(ddbltfx);		ddbltfx.dwFillColor = dgl->dwClearColorPF;		IDirectDrawSurface4_Blt(dgl->lpBack4, &rcScreenRect, NULL, NULL,			DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);		return TRUE;	}	// Ensure all rendering is complete	if (ctx->Driver.Finish)		(*ctx->Driver.Finish)(ctx);	if (dgl->bSceneStarted == TRUE) {		IDirect3DDevice3_EndScene(dgl->lpDev3);		dgl->bSceneStarted = FALSE;	}#endif // _USE_GLD3_WGL	dgl->bCanRender = FALSE;#ifdef GLD_THREADS	// Serialize access to DirectDraw and DDS operations	if (glb.bMultiThreaded)		EnterCriticalSection(&CriticalSection);#endif#ifndef _USE_GLD3_WGL	// Release existing surfaces	RELEASE(dgl->lpDev3);	RELEASE(dgl->lpDepth4);	RELEASE(dgl->lpBack4);	if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary)        ;	else	RELEASE(dgl->lpFront4);#endif // _USE_GLD3_WGL	dgl->dwWidth = dwWidth;	dgl->dwHeight = dwHeight;	// Set defaults	dgl->dwModeWidth = dgl->dwWidth;	dgl->dwModeHeight = dgl->dwHeight;#ifdef _USE_GLD3_WGL	if (!_gldDriver.ResizeDrawable(dgl, bDefaultDriver, glb.bDirectDrawPersistant, glb.bPersistantBuffers))		goto cleanup_and_return_with_error;#else // _USE_GLD3_WGL	if (dgl->bFullscreen) {		//		// FULLSCREEN		//        // Disable warning popups when in fullscreen mode        ddlogWarnOption(FALSE);		// Have to release the persistant DirectDraw primary surface		// if switching to fullscreen mode. So if application wants		// persistant display in fullscreen mode, a fullscreen-size		// window should be used instead via fullscreen-blit option.		if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) {			RELEASE(glb.lpPrimary4);			glb.bDirectDrawPrimary = FALSE;		}		dwFlags = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT;		if (glb.bFastFPU)			dwFlags |= DDSCL_FPUSETUP;	// optional		hResult = IDirectDraw4_SetCooperativeLevel(dgl->lpDD4, dgl->hWnd, dwFlags);		if (FAILED(hResult)) {			ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Unable to set Exclusive Fullscreen mode", hResult);			goto cleanup_and_return_with_error;		}		hResult = IDirectDraw4_SetDisplayMode(dgl->lpDD4,											  dgl->dwModeWidth,											  dgl->dwModeHeight,											  dgl->dwBPP,											  0,											  0);		if (FAILED(hResult)) {			ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetDisplayMode failed", hResult);			goto cleanup_and_return_with_error;		}		// ** The display mode has changed, so dont use MessageBox! **		ZeroMemory(&ddsd2, sizeof(ddsd2));		ddsd2.dwSize = sizeof(ddsd2);		if (dgl->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(dgl->lpDD4, &ddsd2, &dgl->lpFront4, NULL);			if (FAILED(hResult)) {				ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (primary) failed", hResult);				goto cleanup_and_return_with_error;			}			// Render target surface			ZeroMemory(&ddscaps2, sizeof(ddscaps2)); // Clear the entire struct.			ddscaps2.dwCaps = DDSCAPS_BACKBUFFER;			hResult = IDirectDrawSurface4_GetAttachedSurface(dgl->lpFront4, &ddscaps2, &dgl->lpBack4);			if (FAILED(hResult)) {				ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: GetAttachedSurface failed", hResult);				goto cleanup_and_return_with_error;			}		} else {			// Single buffered			// Primary surface			ddsd2.dwFlags = DDSD_CAPS;			ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |								   //DDSCAPS_3DDEVICE |								   dwMemoryType;			hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpFront4, NULL);			if (FAILED(hResult)) {				ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (primary) failed", hResult);				goto cleanup_and_return_with_error;			}			dgl->lpBack4 = NULL;		}	} else {		// WINDOWED        // OK to enable warning popups in windowed mode        ddlogWarnOption(glb.bMessageBoxWarnings);		// Ditto if persistant DirectDraw primary		if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary)			goto DoClipperOnly;		// WINDOWED		dwFlags = DDSCL_NORMAL;		if (glb.bMultiThreaded)			dwFlags |= DDSCL_MULTITHREADED;		if (glb.bFastFPU)			dwFlags |= DDSCL_FPUSETUP;	// optional		hResult = IDirectDraw4_SetCooperativeLevel(dgl->lpDD4,												  dgl->hWnd,												  dwFlags);		if (FAILED(hResult)) {			ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Unable to set Normal coop level", hResult);			goto cleanup_and_return_with_error;		}		// Primary surface		ZeroMemory(&ddsd2, sizeof(ddsd2));		ddsd2.dwSize = sizeof(ddsd2);		ddsd2.dwFlags = DDSD_CAPS;		ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;		hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpFront4, NULL);		if (FAILED(hResult)) {			ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (primary) failed", hResult);			goto cleanup_and_return_with_error;		}		// Cache the primary surface for persistant DirectDraw state		if (glb.bDirectDrawPersistant && !glb.bDirectDrawPrimary) {			glb.lpPrimary4 = dgl->lpFront4;			IDirectDrawSurface4_AddRef(glb.lpPrimary4);			glb.bDirectDrawPrimary = TRUE;		}		// Clipper object		hResult = DirectDrawCreateClipper(0, &lpddClipper, NULL);		if (FAILED(hResult)) {			ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateClipper failed", hResult);			goto cleanup_and_return_with_error;		}		hResult = IDirectDrawClipper_SetHWnd(lpddClipper, 0, dgl->hWnd);		if (FAILED(hResult)) {			RELEASE(lpddClipper);			ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetHWnd failed", hResult);			goto cleanup_and_return_with_error;		}		hResult = IDirectDrawSurface4_SetClipper(dgl->lpFront4, lpddClipper);		RELEASE(lpddClipper); // We have finished with it.		if (FAILED(hResult)) {			ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetClipper failed", hResult);			goto cleanup_and_return_with_error;		}DoClipperOnly:		// Update the window for the original clipper		if ((glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) || bSaveDesktop) {			IDirectDrawSurface4_GetClipper(dgl->lpFront4, &lpddClipper);			IDirectDrawClipper_SetHWnd(lpddClipper, 0, dgl->hWnd);			RELEASE(lpddClipper);		}		if (dgl->bDoubleBuffer) {			// Render target surface			ZeroMemory(&ddsd2, sizeof(ddsd2));			ddsd2.dwSize = sizeof(ddsd2);			ddsd2.dwFlags        = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;			ddsd2.dwWidth        = dgl->dwWidth;			ddsd2.dwHeight       = dgl->dwHeight;			ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE |								   DDSCAPS_OFFSCREENPLAIN |								   dwMemoryType;			hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpBack4, NULL);			if (FAILED(hResult)) {				ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Create Backbuffer failed", hResult);				goto cleanup_and_return_with_error;			}		} else {			dgl->lpBack4 = NULL;		}	}	//	// Now create the Zbuffer	//	if (dgl->bDepthBuffer) {		// 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 = dgl->dwWidth;		ddsd2.dwHeight = dgl->dwHeight;		memcpy(&ddsd2.ddpfPixelFormat,			   &glb.lpZBufferPF[dgl->iZBufferPF],			   sizeof(DDPIXELFORMAT) );		// Create a z-buffer		hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpDepth4, NULL);		if (FAILED(hResult)) {			ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (ZBuffer) failed", hResult);			goto cleanup_and_return_with_error;		}		// Attach Zbuffer to render target		TRY(IDirectDrawSurface4_AddAttachedSurface(			dgl->bDoubleBuffer ? dgl->lpBack4 : dgl->lpFront4,			dgl->lpDepth4),			"dglResize: Attach Zbuffer");	}	// Clear the newly resized back buffers for the window client area.	ZeroMemory(&ddbltfx, sizeof(ddbltfx));	ddbltfx.dwSize = sizeof(ddbltfx);	ddbltfx.dwFillColor = dgl->dwClearColorPF;	IDirectDrawSurface4_Blt(dgl->lpBack4, &rcScreenRect, NULL, NULL,		DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);	//	// Now that we have a zbuffer we can create the 3D device	//	hResult = IDirect3D3_CreateDevice(dgl->lpD3D3,									  bDefaultDriver ? &glb.d3dGuid : &IID_IDirect3DRGBDevice,									  dgl->bDoubleBuffer ? dgl->lpBack4 : dgl->lpFront4,									  &dgl->lpDev3,									  NULL);	if (FAILED(hResult)) {		ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Could not create Direct3D device", hResult);		goto cleanup_and_return_with_error;	}	// We must do this as soon as the device is created	dglInitStateCaches(dgl);	//	// Viewport	//	hResult = IDirect3DDevice3_AddViewport(dgl->lpDev3, dgl->lpViewport3);	if (FAILED(hResult)) {		ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: AddViewport failed", hResult);		goto cleanup_and_return_with_error;	}	// Initialise the viewport	dgl->d3dViewport.dwSize = sizeof(dgl->d3dViewport);	dgl->d3dViewport.dwX = 0;	dgl->d3dViewport.dwY = 0;	dgl->d3dViewport.dwWidth = dgl->dwWidth;	dgl->d3dViewport.dwHeight = dgl->dwHeight;	dgl->d3dViewport.dvClipX = 0;	dgl->d3dViewport.dvClipY = 0;	dgl->d3dViewport.dvClipWidth = dgl->dwWidth;	dgl->d3dViewport.dvClipHeight = dgl->dwHeight;//	dgl->d3dViewport.dvMinZ = 0.0f;//	dgl->d3dViewport.dvMaxZ = 1.0f;	TRY(IDirect3DViewport3_SetViewport2(dgl->lpViewport3, &dgl->d3dViewport),		"dglResize: SetViewport2");	hResult = IDirect3DDevice3_SetCurrentViewport(dgl->lpDev3, dgl->lpViewport3);	if (FAILED(hResult)) {		ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetCurrentViewport failed", hResult);		goto cleanup_and_return_with_error;	}	// (Re)Initialise all the Direct3D renderstates	dglInitStateD3D(ctx);	// Now we have to recreate all of our textures (+ mipmaps).	// Walk over all textures in hash table	// XXX what about the default texture objects (id=0)?	{		struct _mesa_HashTable *textures = ctx->Shared->TexObjects;		GLuint id;		for (id = _mesa_HashFirstEntry(textures);				 id;				 id = _mesa_HashNextEntry(textures, id)) {			tObj = (struct gl_texture_object *) _mesa_HashLookup(textures, id);			if (tObj->DriverData) {				// We could call our TexImage function directly, but it's				// safer to use the driver pointer.				for (i=0; i<MAX_TEXTURE_LEVELS; i++) {					image = tObj->Image[i];					if (image) {						switch (tObj->Dimensions){						case 1:							if (ctx->Driver.TexImage)								(*ctx->Driver.TexImage)(ctx, GL_TEXTURE_1D, tObj, i, image->Format, image);							break;						case 2:							if (ctx->Driver.TexImage)								(*ctx->Driver.TexImage)(ctx, GL_TEXTURE_2D, tObj, i, image->Format, image);							break;						default:							break;						}					}				}			}		}	}	// Re-Bind each texture Unit	for (i=0; i<glb.wMaxSimultaneousTextures; i++) {		tObj = ctx->Texture.Unit[i].Current;		if (tObj) {			DGL_texture *lpTex = (DGL_texture *)tObj->DriverData;			hResult = dglSetTexture(dgl, i, lpTex ? lpTex->lpTexture : NULL);			if (FAILED(hResult)) {				ddlogError(DDLOG_ERROR, "dglResize: SetTexture failed", hResult);			}		}	}#endif // _USE_GLD3_WGL	dgl->bCanRender = TRUE;#ifdef GLD_THREADS	// Release serialized access	if (glb.bMultiThreaded)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -