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

📄 chrcdevice.cpp

📁 Windows上的MUD客户端程序
💻 CPP
字号:
/*----------------------------------------------------------------------------
                        _                              _ _       
        /\             | |                            | (_)      
       /  \   _ __   __| |_ __ ___  _ __ ___   ___  __| |_  __ _ 
      / /\ \ | '_ \ / _` | '__/ _ \| '_ ` _ \ / _ \/ _` | |/ _` |
     / ____ \| | | | (_| | | | (_) | | | | | |  __/ (_| | | (_| |
    /_/    \_\_| |_|\__,_|_|  \___/|_| |_| |_|\___|\__,_|_|\__,_|

    The contents of this file are subject to the Andromedia Public
	License Version 1.0 (the "License"); you may not use this file
	except in compliance with the License. You may obtain a copy of
	the License at http://www.andromedia.com/APL/

    Software distributed under the License is distributed on an
	"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
	implied. See the License for the specific language governing
	rights and limitations under the License.

    The Original Code is Pueblo client code, released November 4, 1998.

    The Initial Developer of the Original Code is Andromedia Incorporated.
	Portions created by Andromedia are Copyright (C) 1998 Andromedia
	Incorporated.  All Rights Reserved.

	Andromedia Incorporated                         415.365.6700
	818 Mission Street - 2nd Floor                  415.365.6701 fax
	San Francisco, CA 94103

    Contributor(s):
	--------------------------------------------------------------------------
	   Chaco team:  Dan Greening, Glenn Crocker, Jim Doubek,
	                Coyote Lussier, Pritham Shetty.

					Wrote and designed original codebase.

------------------------------------------------------------------------------

	Implementation of native device creation for the ChRenderContext class.
	Used by RL and D3D implementations

----------------------------------------------------------------------------*/

// $Header: /home/cvs/chaco/modules/client/msw/ChGraphx/ChRCDevice.cpp,v 2.4 1996/07/19 20:44:45 jimd Exp $

#include "grheader.h"

#include "ChMaze.h"
#include "ChRCDevice.h"

#if defined(CH_USE_D3D)

#if !defined(CH_EXCEPTIONS)
#error "This file requires enabling of C++ Exceptions!"
#endif

HRESULT
GetSurfDesc(LPDDSURFACEDESC lpDDSurfDesc,LPDIRECTDRAWSURFACE lpDDSurf)
{
    HRESULT result;
    memset(lpDDSurfDesc, 0, sizeof(DDSURFACEDESC));
    lpDDSurfDesc->dwSize = sizeof(DDSURFACEDESC);
    result = lpDDSurf->GetSurfaceDesc(lpDDSurfDesc);
    return result;
}

#endif 	 // D3D

ChNativeContext ChRenderContext::CreateDevice(int width, int height)
{
	#if (defined(CH_USE_RLAB))
	#ifdef DDRAW
	m_hRC = createWinDevice(win, hdc, NULL, width, height);
	#else
	m_hRC = RLWinCreateDevice(GetWnd()->GetSafeHwnd(), NULL, width, height);
	#endif
	#elif (defined(CH_USE_D3D))

	ChRenderOptimization setting = ((ChMazeWnd*)GetWnd())->GetSettings()->GetRenderOptimization();

	for(int j = 0; j < renderOptimizationCount; j++)
	{
		m_drivers[j] = ChD3dDriver();
	}
	if(m_drivers[renderBetter].GetName().IsEmpty())
	{
		if(!EnumDrivers()) return 0;	// FAILURE!
	}

	/*
     * Create the D3DRM device from this window and using the specified D3D
     * driver.
     */
	GUID guid = m_drivers[setting].GetGUID();	// our driver to use
	m_hRC = 0;									// in case of failure
	#if FANCY_CREATE
	// NOT DONE YET!!
	// Create the front and back buffers, along with the clipper

	// Create the Z buffer

	// Create the device on top of the buffers

	#else
    HRESULT rval = m_D3DRM->CreateDeviceFromClipper(m_DDClipper, &guid, width, height, &m_hRC);
	#endif

	#if 0
	DDSURFACEDESC desc;
	LPDIRECTDRAWSURFACE lpDDSurf = 0;
	LPDIRECT3DDEVICE d3dDevice = 0;
	rval = m_hRC->GetDirect3DDevice(&d3dDevice);
	if(rval == DD_OK)
	{

		rval = d3dDevice->QueryInterface(IID_IDirectDrawSurface, (void**)&lpDDSurf);
		if(rval == DD_OK)
		{
			GetSurfDesc(&desc,lpDDSurf);
			if((desc.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER) == 0)
			{
				LPDIRECTDRAWSURFACE backSurf = 0;
				DDSCAPS ddsCaps;
				ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
				rval = lpDDSurf->GetAttachedSurface(&ddsCaps, &backSurf); 
				if(rval == DD_OK)
				{
					GetSurfDesc(&desc,backSurf);
				}
				RELEASE_INTERFACE(backSurf);
			}
		}
	}
	RELEASE_INTERFACE(lpDDSurf);
	RELEASE_INTERFACE(d3dDevice);
	#endif	// 0

	#endif // elif (defined(CH_USE_D3D))
	return m_hRC;
}

#if (defined(CH_USE_D3D))

int ChRenderContext::GetBPP()
{
    return GetDeviceCaps(m_hDC, BITSPIXEL);
}

static HRESULT
WINAPI enumDeviceFunc(LPGUID lpGuid, LPSTR lpDeviceDescription, LPSTR lpDeviceName,
        LPD3DDEVICEDESC lpHWDesc, LPD3DDEVICEDESC lpHELDesc, LPVOID lpContext)
{

	ChRenderContext *pRC = (ChRenderContext *)lpContext;

	return pRC->EnumDriver(lpGuid, lpDeviceDescription, lpDeviceName,
        lpHWDesc, lpHELDesc);

}

/****************************************************************************/
/*                         D3D Device Enumeration                           */
/****************************************************************************/
/*
 * BPPToDDBD
 * Converts bits per pixel to a DirectDraw bit depth flag
 */
static DWORD
BPPToDDBD(int bpp)
{
    switch(bpp) {
        case 1:
            return DDBD_1;
        case 2:
            return DDBD_2;
        case 4:
            return DDBD_4;
        case 8:
            return DDBD_8;
        case 16:
            return DDBD_16;
        case 24:
            return DDBD_24;
        case 32:
            return DDBD_32;
        default:
            return 0;
    }
}

HRESULT ChRenderContext::EnumDriver(LPGUID lpGuid, LPSTR lpDeviceDescription, LPSTR lpDeviceName,
        LPD3DDEVICEDESC lpHWDesc, LPD3DDEVICEDESC lpHELDesc)
{
    BOOL hardware = FALSE; /* current start driver is hardware */
    BOOL mono = FALSE;     /* current start driver is mono light */
    LPD3DDEVICEDESC lpDesc;
    /*
     * Decide which device description we should consult
     */
    lpDesc = lpHWDesc->dcmColorModel ? lpHWDesc : lpHELDesc;
    /*
     * If this driver cannot render in the current display bit depth skip
     * it and continue with the enumeration.
     */
    if (!(lpDesc->dwDeviceRenderBitDepth & BPPToDDBD(GetBPP())))
        return D3DENUMRET_OK;
    /*
     * Record this driver's info
     */
    //memcpy(&myglobs.DriverGUID[myglobs.NumDrivers], lpGuid, sizeof(GUID));
    //lstrcpy(&myglobs.DriverName[myglobs.NumDrivers][0], lpDeviceName);
    /*
     * Choose hardware over software for everything, RGB lights over mono lights for "better"
	 * mono over rgb for "faster"
     */
    hardware = lpDesc == lpHWDesc ? TRUE : FALSE;
    mono = lpDesc->dcmColorModel & D3DCOLOR_MONO ? TRUE : FALSE;
    if (m_drivers[renderBetter].GetName().IsEmpty()) {
        /*
         * this is the first valid driver
         */
		m_drivers[renderBetter].Set(lpDeviceName, *lpGuid, hardware, mono);
		m_drivers[renderFaster].Set(lpDeviceName, *lpGuid, hardware, mono);
    } 
    else
    {
    	if (hardware)
	    {
	        /*
	         * this driver is hardware and start driver is not
	         */
			 if(!m_drivers[renderBetter].IsHardware() || (!mono && m_drivers[renderBetter].IsMono()))
			 {
			 	// If both mono, choose the hardware one
				m_drivers[renderBetter].Set(lpDeviceName, *lpGuid, hardware, mono);
			 }
			 if(!m_drivers[renderFaster].IsHardware() || (mono && !m_drivers[renderFaster].IsMono()))
			 {
				m_drivers[renderFaster].Set(lpDeviceName, *lpGuid, hardware, mono);
			 }
    	}
		if(mono)
		{
			 if(!m_drivers[renderFaster].IsHardware() && !m_drivers[renderFaster].IsMono())
			 {
				m_drivers[renderFaster].Set(lpDeviceName, *lpGuid, hardware, mono);
			 }
		}
		else
		{
			 if(!m_drivers[renderBetter].IsHardware() && m_drivers[renderBetter].IsMono())
			 {
				m_drivers[renderBetter].Set(lpDeviceName, *lpGuid, hardware, mono);
			 }
		}
	}

	//#pragma message("D3D no-devices failure handling Not done!")
    return (D3DENUMRET_OK);
}

/*
 * EnumDrivers
 * Enumerate the available D3D drivers, add them to the file menu, and choose
 * one to use.
 */
BOOL ChRenderContext::EnumDrivers()
{
    LPDIRECTDRAW lpDD;
    LPDIRECT3D lpD3D;
    HRESULT rval;

    /*
     * Create a DirectDraw object and query for the Direct3D interface to use
     * to enumerate the drivers.
     */
    rval = DirectDrawCreate(NULL, &lpDD, NULL);
    if (rval != DD_OK) {
        //TRACE1("Creation of DirectDraw HEL failed.\n%s", D3DRMErrorToString(rval));
        return FALSE;
    }
    rval = lpDD->QueryInterface(IID_IDirect3D, (void**) &lpD3D);
    if (rval != DD_OK) {
        //TRACE1("Creation of Direct3D interface failed.\n%s", D3DRMErrorToString(rval));
        lpDD->Release();
        return FALSE;
    }
    /*
     * Enumerate the drivers, setting CurrDriver to -1 to initialize the
     * driver selection code in enumDeviceFunc
     */

    rval = lpD3D->EnumDevices(enumDeviceFunc, this);
    if (rval != DD_OK) {
        //TRACE1("Enumeration of drivers failed.\n%s", D3DAppErrorToString(rval));
        return FALSE;
    }
    lpD3D->Release();
    lpDD->Release();

    /*
     * Make sure we found at least one valid driver for each one
     */

	if(m_drivers[renderBetter].GetName().IsEmpty() || 
		m_drivers[renderFaster].GetName().IsEmpty())
	{
		return FALSE;
	}

    return TRUE;
}

#endif	// D3D


#if (defined(CH_USE_D3D))
ChDevice3D::ChDevice3D() :
		#if (defined(CH_USE_D3D))
		m_frontSurface(0),
		m_backSurface(0),
		m_zSurface(0),
		m_clipper(0),
		#endif
		m_pRC(0),
		m_device(0)
{
}
ChDevice3D::ChDevice3D(ChRenderContext *pRC, int width, int height, bool boolOffscreen ) :
		#if (defined(CH_USE_D3D))
		m_frontSurface(0),
		m_backSurface(0),
		m_zSurface(0),
		m_clipper(0),
		#endif
		m_pRC(0),
		m_device(0)
{
	Init(pRC, width, height, boolOffscreen);	
}


ChDevice3D::~ChDevice3D()
{
	Kill();
}

void ChDevice3D::Kill()
{
	RELEASE_INTERFACE(m_device);
	RELEASE_INTERFACE(m_backSurface);
	RELEASE_INTERFACE(m_frontSurface);
	RELEASE_INTERFACE(m_zSurface);
	RELEASE_INTERFACE(m_clipper);
}



bool ChDevice3D::Init(ChRenderContext *pRC, int width, int height, bool boolOffscreen)
{
	Kill();					// If we decide we want to reuse these,
							// just release eveything first
	m_pRC = pRC;
	if(boolOffscreen)
	{
		return pRC->InitOffscreenDevice(*this, width, height);
	}
	else
	{
		return pRC->InitWindowDevice(*this, width, height);
	}
}

bool ChRenderContext::InitWindowDevice(ChDevice3D &device, int width, int height)
{
	return false;
}

bool ChRenderContext::InitOffscreenDevice(ChDevice3D &device, int width, int height)
{
	bool boolSuccess = true;
	#if (defined(CH_USE_D3D))
    DDSURFACEDESC       ddsd;
    //HRESULT result;

	device.m_frontSurface = 0;
	device.m_backSurface = 0;
	device.m_device = 0;

	try
	{
	    memset( &ddsd, 0, sizeof( ddsd ) );
	    ddsd.dwSize = sizeof( ddsd );
	    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH | DDSD_BACKBUFFERCOUNT;
	    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY | DDSCAPS_FLIP |
            DDSCAPS_3DDEVICE | DDSCAPS_COMPLEX;
	    ddsd.dwBackBufferCount = 1;
		ddsd.dwHeight = height;
	    ddsd.dwWidth = width;

	    if(m_DD->CreateSurface(&ddsd, &device.m_frontSurface, NULL) != DD_OK) 
	    	throw ChExInterface(CH_EX_CREATE_FAILED);

		ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;

		if(device.m_frontSurface->GetAttachedSurface(&ddsd.ddsCaps, &device.m_backSurface) != DD_OK) 
	    	throw ChExInterface(CH_EX_QUERY_FAILED);


		ChRenderOptimization setting = ((ChMazeWnd*)GetWnd())->GetSettings()->GetRenderOptimization();
		GUID guid = m_drivers[setting].GetGUID();	// our driver to use
		if(m_D3DRM->CreateDeviceFromSurface(&guid, m_DD, device.m_backSurface, &device.m_device) != DD_OK) 
	    	throw ChExInterface(CH_EX_QUERY_FAILED);

	}
	catch( ChExInterface qExcept )
	{
		int val =  qExcept.val;
		TRACE1("Offscreen device creation failure - reason %d", val);  
		RELEASE_INTERFACE(device.m_frontSurface);
		RELEASE_INTERFACE(device.m_backSurface);
		boolSuccess = false;
	}
	catch(...)
	{
		RELEASE_INTERFACE(device.m_frontSurface);
		RELEASE_INTERFACE(device.m_backSurface);
		boolSuccess = false;
	}
	#endif

	return (boolSuccess);
	
}

#endif // D3D


//#endif // (defined(CH_USE_RLAB)) || defined(CH_USE_D3D)




#if 0
	// maybe useful debris
		#if 0
		if(device.m_backSurface->QueryInterface( , &device.m_device) != DD_OK) 
	    	throw ChExInterface(CH_EX_QUERY_FAILED);


           d3dappi.lpBackBuffer->lpVtbl->QueryInterface(d3dappi.lpBackBuffer,
                                                &d3dappi.Driver[driver].Guid,
                                              (LPVOID*)&d3dappi.lpD3DDevice);
		#endif
HRESULT
D3DAppICreateSurface(LPDDSURFACEDESC lpDDSurfDesc,
                LPDIRECTDRAWSURFACE FAR *lpDDSurface) {
    HRESULT result;
    if (d3dappi.bOnlySystemMemory)
        lpDDSurfDesc->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
    result = d3dappi.lpDD->lpVtbl->CreateSurface(d3dappi.lpDD, lpDDSurfDesc,
                                                 lpDDSurface, NULL);
    return result;
}


    ddrval = D3DAppCreateSurface(&ddsd, &myglobs.lpFrameRateBuffer);
    if (ddrval != DD_OK) {
        Msg("Could not create frame rate buffer.\n%s", D3DAppErrorToString(ddrval));    
        goto exit_with_error;
    }
#endif	// debris

⌨️ 快捷键说明

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