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

📄 dglcontext.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
	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(
		GL_TRUE,		// RGB mode
		bDouble,    /* double buffer */
		GL_FALSE,			// stereo
		lpPFD->cRedBits,
		lpPFD->cGreenBits,
		lpPFD->cBlueBits,
		dwAlphaBits,
		0,				// index bits
		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(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 );
	_ac_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

	// 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
}

⌨️ 快捷键说明

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