📄 dglcontext.c
字号:
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 + -