Example #1
0
bool RendererD3D::Init(void* window, int width, int height, bool fullScreen)
{
    IDirect3D9* d3d = Direct3DCreate9(D3D_SDK_VERSION);

    D3DPRESENT_PARAMETERS presentParams;
    memset(&presentParams, 0, sizeof(presentParams));
    presentParams.Windowed = fullScreen ? FALSE : TRUE;
    presentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
    presentParams.hDeviceWindow = (HWND)window;
    presentParams.BackBufferFormat = D3DFMT_X8R8G8B8;
    presentParams.BackBufferWidth = width;
    presentParams.BackBufferHeight = height;
    presentParams.EnableAutoDepthStencil = TRUE;
    presentParams.AutoDepthStencilFormat = D3DFMT_D24S8;

    d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &mDeviceCaps);
    HRESULT res = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, (HWND)window, D3DCREATE_HARDWARE_VERTEXPROCESSING, &presentParams, &mDevice);
    if( res != D3D_OK )
        return false;
    
    mCurrentVertexBuffers = (VertexBuffer**)malloc(sizeof(VertexBuffer*) * mDeviceCaps.MaxStreams);
    memset(mCurrentVertexBuffers, 0, sizeof(VertexBuffer*) * mDeviceCaps.MaxStreams);

    mVertexShaderProfile = D3DXGetVertexShaderProfile(mDevice);
    mPixelShaderProfile = D3DXGetPixelShaderProfile(mDevice);

    mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
    //mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL);

    CreateSpriteProfile();

    return true;
}
Example #2
0
ErrorCode Shader::compile(std::string vert, std::string pixel)
{
    LPD3DXBUFFER code;
    LPD3DXBUFFER err;

    HRESULT result;

    result = D3DXCompileShader(vert.c_str(), vert.length(), NULL, NULL, "main", D3DXGetVertexShaderProfile(mamain->d3ddev), 0, &code, &err, &VConstants.constants);

    if (FAILED(result))
    {
        ErrorHandleCritical(mamain->err, mamain->errCrit, ErrorCompileVertexShader, result, (char*) err->GetBufferPointer());
        err->Release();

        return ErrorCompileVertexShader;
    }

    result = mamain->d3ddev->CreateVertexShader((DWORD*) code->GetBufferPointer(), &VShader);

    code->Release();

    if (FAILED(result))
        return ErrorHandleCritical(mamain->err, mamain->errCrit, ErrorCreateVertexShader, result);

    result = D3DXCompileShader(pixel.c_str(), pixel.length(), NULL, NULL, "main", D3DXGetPixelShaderProfile(mamain->d3ddev), 0, &code, &err, &PConstants.constants);

    if (FAILED(result))
    {
        ErrorHandleCritical(mamain->err, mamain->errCrit, ErrorCompilePixelShader, result, (char*) err->GetBufferPointer());
        err->Release();

        VShader->Release();
        VShader = 0;

        return ErrorCompilePixelShader;
    }

    result = mamain->d3ddev->CreatePixelShader((DWORD*) code->GetBufferPointer(), &PShader);

    code->Release();

    if (FAILED(result))
    {
        ErrorHandleCritical(mamain->err, mamain->errCrit, ErrorCreatePixelShader, result);

        VShader->Release();
        VShader = 0;

        return ErrorCreatePixelShader;
    }

    return ErrorOk;
}
Example #3
0
//---------------------------------------------------------------------------------
// init
// this function load and compile a vertex/fragment program on the specified context
// if the source file is not found, it assigns a default GREEN color shader
// if the compile failed, it assigns a default RED color shader
//---------------------------------------------------------------------------------
bool FFxProgram::init(CGcontext aContext)
{
	CGenum	fileType;

	// remove existing program (in case a program is already loaded)

	if (mProgram)
	{
		cgDestroyProgram(mProgram);
		mProgram = 0;
	}
	fileType = CG_SOURCE;

#ifdef WIN32
	HRESULT hr;

	if (GDD->GetClassID() == ClassIDZDisplayDeviceDX9)
	{
		const char** profileOpts;
		profileOpts = cgD3D9GetOptimalOptions(mProfile);
		const char *nOpts[16];
		nOpts[0] = COMPILE_ARGS[0];
		int idx =1;
		while ( (idx<15) && profileOpts[idx-1])
		{
			nOpts[idx] = profileOpts[idx-1];
			idx++;
		}
		nOpts[idx] = 0;

		const char *szDXprofile = NULL;

		if (mProfile == CG_PROFILE_VS_2_0)
		{
			szDXprofile = D3DXGetVertexShaderProfile(GDD->GetD3D9Device());
		}
		else
		{
			szDXprofile = D3DXGetPixelShaderProfile(GDD->GetD3D9Device());
		}
/*

		//LPD3DXBUFFER mDXShader;
		D3DXCompileShader(
			mSourceBuffer,
			strlen(mSourceBuffer),
			NULL,
			NULL,
			mEntry.c_str(),
			szDXprofile,
			0,
			&mDXShader,
			NULL,
			NULL
			);
		*/



		mProgram = cgCreateProgram(aContext, fileType, mSourceBuffer, mProfile, mEntry.c_str(), nOpts);
		hr = cgD3D9LoadProgram(mProgram, true, 0);
	}
	else
#endif
	{
		// opengl
		//mProgram = cgCreateProgram(aContext, fileType, mSourceBuffer, mProfile, mEntry.c_str(), COMPILE_ARGS);
		mProfile = (mProfileDomain == CG_VERTEX_DOMAIN) ?cgGLGetLatestProfile(CG_GL_VERTEX):cgGLGetLatestProfile(CG_GL_FRAGMENT );
		assert(cgGLIsProfileSupported(mProfile));
		mProgram = cgCreateProgramFromFile(aContext, fileType, mFileName, mProfile, mEntry.c_str(), COMPILE_ARGS);
		if (mProgram == NULL) {
			CGerror error;
			const char* errTxt = cgGetLastErrorString(&error);
			LOG ("ERROR %x: can't compile %s : %s\n", error, mFileName.c_str(), errTxt);
			useDefaultProgram(aContext);
			assert(false);
			return false;
		}
		cgGLLoadProgram(mProgram);
		checkForCgError("loadprog");
	}
	if (mProgram == 0)
	{
		CGerror error = cgGetError();
		LOG ("ERROR %x: can't load or compile %s : %s\n", error, mFileName.c_str(), cgGetLastErrorString(&error));
		useDefaultProgram(aContext);
		assert(false);
		return false;
	}
	return true;
}
Example #4
0
/*
extern "C"
{
	LPCSTR WINAPI	D3DXGetPixelShaderProfile	(LPDIRECT3DDEVICE9  pDevice);
	LPCSTR WINAPI	D3DXGetVertexShaderProfile	(LPDIRECT3DDEVICE9	pDevice);
};
*/
HRESULT	CRender::shader_compile			(
    LPCSTR							name,
    LPCSTR                          pSrcData,
    UINT                            SrcDataLen,
    void*							_pDefines,
    void*							_pInclude,
    LPCSTR                          pFunctionName,
    LPCSTR                          pTarget,
    DWORD                           Flags,
    void*							_ppShader,
    void*							_ppErrorMsgs,
    void*							_ppConstantTable)
{
    D3DXMACRO						defines			[128];
    int								def_it			= 0;
    CONST D3DXMACRO*                pDefines		= (CONST D3DXMACRO*)	_pDefines;
    char							c_smapsize		[32];
    char							c_gloss			[32];

//	Msg("%s.%s", name, pTarget);

    if (pDefines)	{
        // transfer existing defines
        for (;; def_it++)	{
            if (0==pDefines[def_it].Name)	break;
            defines[def_it]			= pDefines[def_it];
        }
    }
    // options
    {
        sprintf						(c_smapsize,"%d",u32(o.smapsize));
        defines[def_it].Name		=	"SMAP_size";
        defines[def_it].Definition	=	c_smapsize;
        def_it						++	;
    }
    if (o.fp16_filter)		{
        defines[def_it].Name		=	"FP16_FILTER";
        defines[def_it].Definition	=	"1";
        def_it						++	;
    }
    if (o.fp16_blend)		{
        defines[def_it].Name		=	"FP16_BLEND";
        defines[def_it].Definition	=	"1";
        def_it						++	;
    }
    if (o.HW_smap)			{
        defines[def_it].Name		=	"USE_HWSMAP";
        defines[def_it].Definition	=	"1";
        def_it						++	;
    }
    if (o.HW_smap_PCF)			{
        defines[def_it].Name		=	"USE_HWSMAP_PCF";
        defines[def_it].Definition	=	"1";
        def_it						++	;
    }
    if (o.HW_smap_FETCH4)			{
        defines[def_it].Name		=	"USE_FETCH4";
        defines[def_it].Definition	=	"1";
        def_it						++	;
    }
    if (o.sjitter)			{
        defines[def_it].Name		=	"USE_SJITTER";
        defines[def_it].Definition	=	"1";
        def_it						++	;
    }
    if (HW.Caps.raster_major >= 3)	{
        defines[def_it].Name		=	"USE_BRANCHING";
        defines[def_it].Definition	=	"1";
        def_it						++	;
    }
    if (HW.Caps.geometry.bVTF)	{
        defines[def_it].Name		=	"USE_VTF";
        defines[def_it].Definition	=	"1";
        def_it						++	;
    }
    if (o.Tshadows)			{
        defines[def_it].Name		=	"USE_TSHADOWS";
        defines[def_it].Definition	=	"1";
        def_it						++	;
    }
    if (o.mblur)			{
        defines[def_it].Name		=	"USE_MBLUR";
        defines[def_it].Definition	=	"1";
        def_it						++	;
    }
    if (o.sunfilter)		{
        defines[def_it].Name		=	"USE_SUNFILTER";
        defines[def_it].Definition	=	"1";
        def_it						++	;
    }
    if (o.sunstatic)		{
        defines[def_it].Name		=	"USE_R2_STATIC_SUN";
        defines[def_it].Definition	=	"1";
        def_it						++	;
    }
    if (o.forcegloss)		{
        sprintf						(c_gloss,"%f",o.forcegloss_v);
        defines[def_it].Name		=	"FORCE_GLOSS";
        defines[def_it].Definition	=	c_gloss;
        def_it						++	;
    }
    if (o.forceskinw)		{
        defines[def_it].Name		=	"SKIN_COLOR";
        defines[def_it].Definition	=	"1";
        def_it						++;
    }

    // skinning
    if (m_skinning<0)		{
        defines[def_it].Name		=	"SKIN_NONE";
        defines[def_it].Definition	=	"1";
        def_it						++	;
    }
    if (0==m_skinning)		{
        defines[def_it].Name		=	"SKIN_0";
        defines[def_it].Definition	=	"1";
        def_it						++;
    }
    if (1==m_skinning)		{
        defines[def_it].Name		=	"SKIN_1";
        defines[def_it].Definition	=	"1";
        def_it						++;
    }
    if (2==m_skinning)		{
        defines[def_it].Name		=	"SKIN_2";
        defines[def_it].Definition	=	"1";
        def_it						++;
    }

    // finish
    defines[def_it].Name			=	0;
    defines[def_it].Definition		=	0;
    def_it							++;

    //
    if (0==xr_strcmp(pFunctionName,"main"))	{
        if ('v'==pTarget[0])			pTarget = D3DXGetVertexShaderProfile	(HW.pDevice);	// vertex	"vs_2_a"; //
        else							pTarget = D3DXGetPixelShaderProfile		(HW.pDevice);	// pixel	"ps_2_a"; //
    }

    LPD3DXINCLUDE                   pInclude		= (LPD3DXINCLUDE)		_pInclude;
    LPD3DXBUFFER*                   ppShader		= (LPD3DXBUFFER*)		_ppShader;
    LPD3DXBUFFER*                   ppErrorMsgs		= (LPD3DXBUFFER*)		_ppErrorMsgs;
    LPD3DXCONSTANTTABLE*            ppConstantTable	= (LPD3DXCONSTANTTABLE*)_ppConstantTable;

#ifdef	D3DXSHADER_USE_LEGACY_D3DX9_31_DLL	//	December 2006 and later
    HRESULT		_result	= D3DXCompileShader(pSrcData,SrcDataLen,defines,pInclude,pFunctionName,pTarget,Flags|D3DXSHADER_USE_LEGACY_D3DX9_31_DLL,ppShader,ppErrorMsgs,ppConstantTable);
#else
    HRESULT		_result	= D3DXCompileShader(pSrcData,SrcDataLen,defines,pInclude,pFunctionName,pTarget,Flags,ppShader,ppErrorMsgs,ppConstantTable);
#endif
    if (SUCCEEDED(_result) && o.disasm)
    {
        ID3DXBuffer*		code	= *((LPD3DXBUFFER*)_ppShader);
        ID3DXBuffer*		disasm	= 0;
        D3DXDisassembleShader		(LPDWORD(code->GetBufferPointer()), FALSE, 0, &disasm );
        string_path			dname;
        strconcat			(dname,"disasm\\",name,('v'==pTarget[0])?".vs":".ps" );
        IWriter*			W		= FS.w_open("$logs$",dname);
        W->w				(disasm->GetBufferPointer(),disasm->GetBufferSize());
        FS.w_close			(W);
        _RELEASE			(disasm);
    }
    return		_result;
}
bool U2D3DXEffectShader::LoadResource()
{
	U2ASSERT(0 == m_pD3DEffect);

	HRESULT hr;
	
	IDirect3DDevice9* pD3DDev = m_pRenderer->GetD3DDevice();
	U2ASSERT(pD3DDev);

	U2FilePath fPath;		
	TCHAR fullPath[MAX_PATH];
	// StackString Memory Leak...
	U2DynString includePath(FX_SHADER_PATH);
	includePath += _T("\\2.0");

	fPath.ConvertToAbs(fullPath, MAX_PATH * sizeof(TCHAR) , m_szFilename.Str(), includePath);		

	U2File* pFile = U2File::GetFile(fullPath, U2File::READ_ONLY);
	if(!pFile)
	{
		U2_DELETE pFile;
		return false;
	}

	uint32 uBuffLen = pFile->GetfileSize();
	if(uBuffLen == 0)
	{
		U2_DELETE pFile;
		return false;
	}

	unsigned char* pBuffer = U2_ALLOC(unsigned char, uBuffLen);
	pFile->Read(pBuffer, uBuffLen);

	U2_DELETE pFile;

	ID3DXBuffer* pErrorBuffer = NULL;

#ifdef DEBUG_SHADER
	DWORD compileFlags = D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION | D3DXSHADER_USE_LEGACY_D3DX9_31_DLL
		| D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT | D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT ;	
#else
	DWORD compileFlags = D3DXSHADER_USE_LEGACY_D3DX9_31_DLL;
#endif

	//U2DynString includePath(FX_SHADER_PATH);
	//includePath += _T("\\2.0");
	
	U2D3DXEffectShaderInclude includeHandler(includePath);

	ID3DXEffectPool* pEffectPool = m_pRenderer->GetD3DEffectPool();
	U2ASSERT(pEffectPool);

	// get the highest supported shader profiles
//	LPCSTR vsProfile, psProfile;
//#ifdef UNICODE 
//	 vsProfile = ToUnicode( D3DXGetVertexShaderProfile(pD3DDev) );
//	 psProfile = ToUnicode( D3DXGetPixelShaderProfile(pD3DDev) );
//#else 
//	vsProfile = D3DXGetVertexShaderProfile(pD3DDev);
//	psProfile = D3DXGetPixelShaderProfile(pD3DDev);
//#endif
	LPCSTR vsProfile = D3DXGetVertexShaderProfile(pD3DDev);
	LPCSTR psProfile = D3DXGetPixelShaderProfile(pD3DDev);

	if (0 == vsProfile)
	{
		FDebug("Invalid Vertex Shader profile! Fallback to vs_2_0!\n");
		vsProfile = "vs_2_0";
	}

	if (0 == psProfile)
	{
		FDebug("Invalid Pixel Shader profile! Fallback to ps_2_0!\n");
		psProfile = "ps_2_0";
	}

	// create macro definitions for shader compiler
	D3DXMACRO defines[] = {
		{ "VS_PROFILE", vsProfile },
		{ "PS_PROFILE", psProfile },
		{ 0, 0 },
	};

	// create effect
	if (compileFlags)
	{
		hr = D3DXCreateEffectFromFile(
			pD3DDev,            // pDevice
			fullPath,   // File name
			defines,            // pDefines
			&includeHandler,    // pInclude
			compileFlags,       // Flags
			pEffectPool,         // pPool
			&m_pD3DEffect,    // ppEffect
			&pErrorBuffer);      // ppCompilationErrors
	}
	else
	{
		hr = D3DXCreateEffect(
			pD3DDev,            // pDevice
			pBuffer,             // pFileData
			uBuffLen,           // DataSize
			defines,            // pDefines
			&includeHandler,    // pInclude
			compileFlags,       // Flags
			pEffectPool,         // pPool
			&(m_pD3DEffect),    // ppEffect
			&pErrorBuffer);      // ppCompilationErrors
	}

	U2_FREE(pBuffer);
	pBuffer = NULL;

	if (FAILED(hr))
	{
		FDebug("nD3D9Shader: failed to load fx file '%s' with:\n\n%s\n",
			fullPath,
			pErrorBuffer ? pErrorBuffer->GetBufferPointer() : "No D3DX error message.");
		if (pErrorBuffer)
		{
			pErrorBuffer->Release();
		}
		return false;
	}
	U2ASSERT(m_pD3DEffect);

	m_bValidated = false;
	m_bNotValidate = false;

	this->ValidateEffect();

	return true;
}
Example #6
0
	bool CShaderHLSL::Create(P3D::sShaderDesc &desc)
	{
		const char *pData;
		ULONG fsize;
		IFileSystem* pFS = CRenderer::mEngine()->mFilesystem();
		wchar path[P3DMAX_PATH];
		wsprintf(path, P3DMAX_PATH-1, _W("shaders/%s.rshader"), desc.ShaderFile.Get());
		FSFILE *fp = pFS->Load(path, (BYTE *&)pData, fsize, true);
		if (!fp)
		{
			CON(MSG_ERR, _W("Can't open %s.hlsl shader file from data/shaders directory!"), desc.ShaderFile.Get());
			return false;
		}

		ID3DXBuffer *pShaderBlob = NULL;
		ID3DXBuffer *pErrors = NULL;
		DWORD flags = D3DXSHADER_DEBUG;  //D3DXSHADER_OPTIMIZATION_LEVEL3

		char profile[128];
		switch(desc.ShaderType)
		{
		case SHADERTYPE_VERTEX_SHADER:
			strcpy(profile, D3DXGetVertexShaderProfile(g_pD3ddev));
			break;
		case SHADERTYPE_PIXEL_SHADER:
			strcpy(profile, D3DXGetPixelShaderProfile(g_pD3ddev));
			break;
		case SHADERTYPE_GEOMETRY_SHADER:
			CON(MSG_ERR, _W("DX9 does not support geometry shaders."));
			return false;
		default:
			CON(MSG_ERR, _W("Chader creation failed. No apropriate ShaderType given."));
			return false;
		}

		CIncludeHandler includeHandler;
		
		D3DXMACRO Shader_Macros[] = 
		{
			{ "DX9", NULL },
			{ "SM3", NULL },
			NULL
		};

		if(FAILED(D3DXCompileShader(
			pData, 
			fsize, 
			Shader_Macros, 
			&includeHandler, 
			_W2A(desc.EntryFunction.Get()), 
			profile, 
			flags,
			&pShaderBlob, 
			&pErrors,
			&m_pConstTable
			)))
		{
			if(pErrors) CON(MSG_ERR, _W("%s"), _A2W((char*)pErrors->GetBufferPointer()));
			else CON(MSG_ERR, _W("Error description not given"));
			CON(MSG_ERR, _W("Shader %s could not be compiled"), desc.ShaderFile.Get());
			SAFE_RELEASE(pErrors);
			return false;
		}

		pFS->UnLoad(fp, (BYTE *)pData);

		//save to cache
		fp = pFS->Open(_W("cache/shaders/hlsl"), _W("wb"));
		const char* cs = (const char*)pShaderBlob->GetBufferPointer();
		pFS->Write(cs, 1, pShaderBlob->GetBufferSize(), fp);
		pFS->Close(fp);

		bool shaderCreated = false;
		switch(desc.ShaderType)
		{
		case SHADERTYPE_VERTEX_SHADER:
			shaderCreated = SUCCEEDED(g_pD3ddev->CreateVertexShader((const DWORD*)pShaderBlob->GetBufferPointer(), &m_pVS));
			break;
		case SHADERTYPE_PIXEL_SHADER:
			shaderCreated = SUCCEEDED(g_pD3ddev->CreatePixelShader((const DWORD*)pShaderBlob->GetBufferPointer(), &m_pPS));
			break;
		}

		if(!shaderCreated)
		{
			CON(MSG_ERR, _W("Shader creation error"));
			return false;
		}

		//set constant to their default values 
		m_pConstTable->SetDefaults(g_pD3ddev);

		//create vertex declaration
		if(desc.ShaderType == SHADERTYPE_VERTEX_SHADER)
			m_pVertDecl = new CVertexDeclaration(CRenderer::cGraphicsManager()->GetVertexDescByID(desc.VertexDescID), pShaderBlob);

		SAFE_RELEASE(pShaderBlob);

		m_desc = desc;

		CON(MSG_INFO, _W("Shader '%s' created"), desc.ShaderFile);

		return true;
	}
Example #7
0
HRESULT InitD3D(HINSTANCE hInstance)
{
	// 先创建DInput和DSound
	if(FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&g_pDI, NULL)))
		return E_FAIL;
	if(FAILED(g_pDI->CreateDevice(GUID_SysKeyboard, &g_pDIKey, NULL)))
		return E_FAIL;
	if(FAILED(g_pDI->CreateDevice(GUID_SysMouse, &g_pDIMouse, NULL)))
		return E_FAIL;
		// 设置参数
	if(FAILED(g_pDIKey->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
		return E_FAIL;
	if(FAILED(g_pDIKey->SetDataFormat(&c_dfDIKeyboard)))
		return E_FAIL;
	if(FAILED(g_pDIMouse->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
		return E_FAIL;
	if(FAILED(g_pDIMouse->SetDataFormat(&c_dfDIMouse)))
		return E_FAIL;
		
		// 缓冲输入,设置数据格式和属性
	DIPROPDWORD dipdw;
	dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
	dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
	dipdw.diph.dwObj        = 0;
	dipdw.diph.dwHow        = DIPH_DEVICE;
	dipdw.dwData            = SAMPLE_BUFFER_SIZE; // Arbitary buffer size

#ifdef USE_BUFFERED_KEYBOARD_INPUT
	if( FAILED( g_pDIKey->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ) ) )
		return E_FAIL;
#endif
#ifdef USE_BUFFERED_MOUSE_INPUT
	if( FAILED( g_pDIMouse->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ) ) )
		return E_FAIL;
#endif

		// 开始
	g_pDIKey->Acquire();
	g_pDIMouse->Acquire();



	// 初始化D3D
	if(NULL==(d3d=Direct3DCreate9(D3D_SDK_VERSION)))
		  return E_FAIL;

	//查询当前显卡模式,Desktop是目前桌面设置,d3ddm总是当前使用全屏模式的设置,即使是窗口模式,颜色数值也总和当前的一样
	if(FAILED(d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &DesktopDisplayMode)))
		  return E_FAIL;
	if(FAILED(d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
		return E_FAIL;

	//全屏的话默认是32位色
	if(!WindowMode) d3ddm.Format = D3DFMT_X8R8G8B8;

	//查询设备能力,并设置顶点处理器模式
	DWORD UserVertexShaderProcessing;

	d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dcaps);

	if(FAILED(DetectDeviceCaps())) return E_FAIL;

	if(d3dcaps.VertexShaderVersion < D3DVS_VERSION(1, 0))
		UserVertexShaderProcessing=D3DCREATE_HARDWARE_VERTEXPROCESSING;
	else
		UserVertexShaderProcessing=D3DCREATE_SOFTWARE_VERTEXPROCESSING;

//创建D3D设备
	ZeroMemory(&d3dpp,sizeof(d3dpp));

	d3dpp.Windowed = WindowMode;
	d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
	d3dpp.hDeviceWindow = hWnd;
	d3dpp.BackBufferCount = 1;
	d3dpp.BackBufferWidth = d3ddm.Width;
	d3dpp.BackBufferHeight = d3ddm.Height;
	d3dpp.EnableAutoDepthStencil = TRUE;
	
	if(WindowMode)
	{
		d3ddm.Format = DesktopDisplayMode.Format;
		d3dpp.BackBufferWidth = WindowWidth;
		d3dpp.BackBufferHeight = WindowHeight;
	}

	d3dpp.BackBufferFormat = d3ddm.Format;

	if(d3ddm.Format == D3DFMT_X8R8G8B8)
	{
		d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
		TextureFormat = D3DFMT_A8R8G8B8;
	}
	else
	{
		d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
		TextureFormat = D3DFMT_A4R4G4B4;
	}


	// 先强制以硬件顶点方式创建设备(为了不漏掉MX440这种不支持VS但支持T&L的显卡,XIXI)
	UserVertexShaderProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING;
	HRESULT hr = d3d->CreateDevice( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hWnd, UserVertexShaderProcessing, &d3dpp, &d3ddevice);
	// 这种错误表示顶点处理方式不被硬件支持,强制以软件方式创建设备(为了兼容不支持T&L的DX7显卡,比如某些集成显卡)
	if(hr == D3DERR_INVALIDCALL)
	{
		mymessage("警告:显卡不支持硬件顶点处理,强制以软件方式创建设备,性能会急剧下降!!!");
		UserVertexShaderProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
		hr = d3d->CreateDevice( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hWnd, UserVertexShaderProcessing, &d3dpp, &d3ddevice);
	}
	// 全部失败?有问题吧?
	if(FAILED(hr))
	{
		char szErrorInfo[512] = "";
		sprintf(szErrorInfo, "创建D3D设备失败!请检查系统或硬件设置!比如显卡驱动程序或DirectX是否安装正确!错误号%x", hr);
		mymessage(szErrorInfo);
		return E_FAIL;
	}

	// Shader版本检测
	char pVSVersion[7] = "", pPSVersion[7] = "";
	char pNeedVSVersion[7] = USE_VSVERSION, pNeedPSVersion[7] = USE_PSVERSION;
	char szErrorInfo[100] = "";

#ifdef USE_PIXELSHADER
	// 判断PS版本
	memcpy(pPSVersion, D3DXGetPixelShaderProfile(d3ddevice), 7);
	// 2.x中'b'虽然字母数值大于'a',但它从支持度上来看是小于a的,所以这里强制把它置为小于'a',以便后面比较
	if(pPSVersion[3] == '2' && pPSVersion[5] == 'b')
		pPSVersion[5] = 'a'-1;
	if(pNeedPSVersion[3] == '2' && pNeedPSVersion[5] == 'b')
		pNeedPSVersion[5] = 'a'-1;
	if(pPSVersion[3]<pNeedPSVersion[3] || pPSVersion[3]==pNeedPSVersion[3]&&pPSVersion[5]<pNeedPSVersion[5])
	{
		sprintf(szErrorInfo, "不支持Pixel Shader %c.%c!", pNeedPSVersion[3], pNeedPSVersion[5]);
		mymessage(szErrorInfo);	return E_FAIL;
	}
	
	// 判断PS2.0x的条件是否符合程序的最小需求
	if(!strcmp(USE_PSVERSION, "ps_2_a") || !strcmp(USE_PSVERSION, "ps_2_b") || !strcmp(USE_PSVERSION, "ps_2_x"))
	{
		BOOL bFlowControl = FALSE;
#ifdef PS2x_USE_FLOWCONTROL
		bFlowControl = TRUE;
#endif

		if(!CheckPS2xSupport(PS2x_USE_MAXNUM_TEMP, bFlowControl))
		{
			sprintf(szErrorInfo, "不完整支持Pixel Shader 2.x,无法执行程序!");
			mymessage(szErrorInfo);	return E_FAIL;
		}
	}


#endif USE_PIXELSHADER

#ifdef USE_VERTEXSHADER
	BOOL bSoftwareVertexProcessing = FALSE;
	// 完全不支持的,要跳过版本检测,否则D3DXGetVertexShaderProfile会返回空指针造成非法操作
	if((d3dcaps.VertexShaderVersion&0xffff) == 0) 
	{
		bSoftwareVertexProcessing = TRUE;
	}
	else
	{
		// 判断VS版本
		memcpy(pVSVersion, D3DXGetVertexShaderProfile(d3ddevice), 7);
		if(pVSVersion[3]<pNeedVSVersion[3] || pVSVersion[3]==pNeedVSVersion[3]&&pVSVersion[5]<pNeedVSVersion[5])
		{
			bSoftwareVertexProcessing = TRUE;
		}
		// 判断VS2.0x的条件是否符合程序的最小需求
		if(!strcmp(USE_VSVERSION, "vs_2_a") || !strcmp(USE_VSVERSION, "vs_2_b") || !strcmp(USE_VSVERSION, "vs_2_x"))
		{
#ifdef VS2a_USE_MAXNUM_TEMP
			if(d3dcaps.VS20Caps.NumTemps < VS2x_USE_MAXNUM_TEMP)
			{
				bSoftwareVertexProcessing = TRUE;
			}
#endif
		}
	}

	// 如果刚才是以硬件顶点创建设备的,而现在又需要强制软顶点以运行硬件不支持的VS,那么释放设备,重新创建
	if(bSoftwareVertexProcessing && UserVertexShaderProcessing == D3DCREATE_HARDWARE_VERTEXPROCESSING)
	{
		// 如果不支持指定版本的Vertex Shader,就强制创建软顶点处理设备
		sprintf(szErrorInfo, "警告:显卡不支持Vertex Shader %c.%c!强制以软件方式创建设备,性能会急剧下降!!!", pNeedVSVersion[3], pNeedVSVersion[5]);
		mymessage(szErrorInfo);
		SAFE_RELEASE(d3ddevice);
		hr = d3d->CreateDevice( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddevice);
		if(FAILED(hr))
		{
			char szErrorInfo[512] = "";
			sprintf(szErrorInfo, "创建D3D设备失败!请检查系统或硬件设置!比如显卡驱动程序或DirectX是否安装正确!错误号%x", hr);
			mymessage(szErrorInfo);
			return E_FAIL;
		}
	}

#endif



	//初始化摄像机,之所以放在这里,是为了设备丢失后不会又重置到初始位置
	D3DXVECTOR3 PtLookAt = g_PtCameraInitPos + g_VecCameraInitDir;
	CameraChange.InitCamera(g_PtCameraInitPos.x, g_PtCameraInitPos.y, g_PtCameraInitPos.z,  PtLookAt.x, PtLookAt.y, PtLookAt.z,  0.0f,1.0f,0.0f, 7,7,90);

	//得到硬件精确计时器的频率
	QueryPerformanceFrequency(&PerformanceFrequency);

	return S_OK;
}
Example #8
0
	void D3D9Device::init(
		const ion_uint32 width,const ion_uint32 height,
		const base::String& title,const bool fullscreen,void* displayhandle,
		const ion_uint32 adapter,
		const video::Pixelformat colorbufferformat,
		const video::Pixelformat depthstencilformat,const ion_uint32 Hz,const bool vsync)
	{
		if (!m_IsValid) {
			base::log("D3D9Device::init()",base::Warning) <<
				"Initializing an invalid device\n";
		}

		openWindow(width,height,title,fullscreen,displayhandle);

		bool windowed=!m_Fullscreen;

		D3DFORMAT adapterfmt;
		if (windowed) {
			 D3DDISPLAYMODE d3ddm;
			 m_pD3D9->GetAdapterDisplayMode(adapter,&d3ddm);
			 adapterfmt=d3ddm.Format;
		} else adapterfmt=d3dpixelformat(colorbufferformat);

		if (adapterfmt==D3DFMT_UNKNOWN) {
			base::log("D3D9Device::init()",base::Error) << "Unknown/unsupported color buffer format\n";
			m_IsValid=false; return;
		}

		RECT r;
		GetClientRect(m_hWindow,&r);

		m_D3DPP.Windowed=windowed;
		m_D3DPP.BackBufferWidth=r.right-r.left;
		m_D3DPP.BackBufferHeight=r.bottom-r.top;
		m_D3DPP.BackBufferCount=1;
		m_D3DPP.BackBufferFormat=adapterfmt;
		m_D3DPP.AutoDepthStencilFormat=d3dpixelformat(depthstencilformat);
		m_D3DPP.EnableAutoDepthStencil=TRUE;
		m_D3DPP.Flags=0;
		m_D3DPP.PresentationInterval=vsync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE;
		m_D3DPP.FullScreen_RefreshRateInHz=windowed ? 0 : Hz;
		m_D3DPP.hDeviceWindow=m_hWindow;
		m_D3DPP.MultiSampleQuality=0;
		m_D3DPP.MultiSampleType=D3DMULTISAMPLE_NONE;
		m_D3DPP.SwapEffect=D3DSWAPEFFECT_DISCARD;
		m_D3DPP.Windowed=windowed;

		// Getting caps
		base::log("D3D9Device::init()",base::Message) << "Getting caps\n";

		HRESULT hr=m_pD3D9->GetDeviceCaps(adapter,D3DDEVTYPE_HAL,&m_D3DCaps);
		if (FAILED(hr)) {
			base::log("D3D9Device::init()",base::Error) << "GetDeviceCaps() failed\n";
			m_IsValid=false;
			return;
		}

		// Caps structure is initialized here
		{
			base::log("D3D9Device::init()",base::Message) << "Analyzing caps\n";

			m_Caps.m_NPOTTextures=!((m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_POW2) ||
				(m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_NONPOW2CONDITIONAL));
			m_Caps.m_RectangularTextures=(m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_SQUAREONLY)==0;
			m_Caps.m_Cubemaps=(m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_CUBEMAP)!=0;
			m_Caps.m_NPOTCubemaps=(m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_CUBEMAP_POW2)==0;
			m_Caps.m_ProjectedTextures=(m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_PROJECTED)!=0;
			m_Caps.m_DisplacementMaps=false;
			m_Caps.m_CompressedTextures=false;

			m_Caps.m_MaxTextureWidth=m_D3DCaps.MaxTextureWidth;
			m_Caps.m_MaxTextureHeight=m_D3DCaps.MaxTextureHeight;
			m_Caps.m_MaxTextureVolumeDepth=m_D3DCaps.MaxVolumeExtent;
			m_Caps.m_MaxAnisotropy=m_D3DCaps.MaxAnisotropy;
			m_Caps.m_MaxTextureBlendStages=m_D3DCaps.MaxTextureBlendStages;
			m_Caps.m_MaxActiveFFLights=m_D3DCaps.MaxActiveLights;
			m_Caps.m_MaxPointSize=m_D3DCaps.MaxPointSize;
			m_Caps.m_MaxPrimitiveCount=m_D3DCaps.MaxPrimitiveCount;
			m_Caps.m_MaxVertexIndex=m_D3DCaps.MaxVertexIndex;

		}

		// Probing formats
		{

			video::Caps::Texflags **pTexflags,
				*pTexflagarrays[]={m_Caps.m_Valid2DTextureFormats,m_Caps.m_Valid3DTextureFormats,
				m_Caps.m_ValidCubemapFormats,0};

			const D3DRESOURCETYPE rtype[]={D3DRTYPE_TEXTURE,D3DRTYPE_VOLUMETEXTURE,D3DRTYPE_CUBETEXTURE};

			pTexflags=pTexflagarrays;
			unsigned int ii=0;

			base::log("D3D9Device::init()",base::Message) << "Probing texture formats\n";

			while (*pTexflags) {

				video::Caps::Texflags *pTexflagarray=*pTexflags;

				for (unsigned int i=0;i<video::Pixelformat_NumFormats;++i) {
					D3DFORMAT fmt=d3dpixelformat((video::Pixelformat)i);
					hr=0;

					hr=m_pD3D9->CheckDeviceFormat(adapter,D3DDEVTYPE_HAL,adapterfmt,0,rtype[ii],fmt);
					if (FAILED(hr)) { pTexflagarray[i].m_Supported=false; continue; }
					else pTexflagarray[i].m_Supported=true;

					if ((i==video::Pixelformat_RGB_DXT1)
						|| (i==video::Pixelformat_RGBA_DXT1)
						|| (i==video::Pixelformat_RGBA_DXT3)
						|| (i==video::Pixelformat_RGBA_DXT5))
						m_Caps.m_CompressedTextures=true;

					// Volume textures are not supported as render targets
					if (rtype[ii]!=D3DRTYPE_VOLUMETEXTURE) {
						hr=m_pD3D9->CheckDeviceFormat(adapter,D3DDEVTYPE_HAL,adapterfmt,D3DUSAGE_RENDERTARGET,rtype[ii],fmt);
						pTexflagarray[i].m_Rendertarget=(hr==D3D_OK);
						m_Caps.m_Rendertargets=true;
					} else pTexflagarray[i].m_Rendertarget=false;

					hr=m_pD3D9->CheckDeviceFormat(adapter,D3DDEVTYPE_HAL,adapterfmt,D3DUSAGE_DYNAMIC,rtype[ii],fmt);
					pTexflagarray[i].m_Dynamic=(hr==D3D_OK);

					// For depth buffers, only depth formats are supported
					// Volume textures are not supported
					if (isDepthformat((video::Pixelformat)i) && (rtype[ii]!=D3DRTYPE_VOLUMETEXTURE)) {
						hr=m_pD3D9->CheckDeviceFormat(adapter,D3DDEVTYPE_HAL,adapterfmt,D3DUSAGE_DEPTHSTENCIL,rtype[ii],fmt);
						pTexflagarray[i].m_Depth=(hr==D3D_OK);
					} else pTexflagarray[i].m_Depth=false;

					if ((m_D3DCaps.DevCaps2&D3DDEVCAPS2_DMAPNPATCH)!=0) {
						hr=m_pD3D9->CheckDeviceFormat(adapter,D3DDEVTYPE_HAL,adapterfmt,D3DUSAGE_DMAP,rtype[ii],fmt);
						pTexflagarray[i].m_DisplacementMap=(hr==D3D_OK);
					} else pTexflagarray[i].m_DisplacementMap=false;
				}

				++pTexflags;
				++ii;
			}
		}

		base::log("D3D9Device::init()",base::Message) << "Creating D3D device\n";

		hr=m_pD3D9->CreateDevice(adapter,D3DDEVTYPE_HAL,m_hWindow,
			D3DCREATE_HARDWARE_VERTEXPROCESSING,&m_D3DPP,&m_pD3DDev9);

		if (FAILED(hr)) {
			base::log("D3D9Device::init()",base::Error) << "CreateDevice() failed\n";
			m_IsValid=false;
			return;
		}

		D3DVIEWPORT9 viewport;
		viewport.X=0;
		viewport.Y=0;
		viewport.Width=r.right-r.left;
		viewport.Height=r.bottom-r.top;
		viewport.MinZ=0;
		viewport.MaxZ=1;
		m_pD3DDev9->SetViewport(&viewport);

#ifdef D3D9DRV_USE_CG
		base::log("D3D9Device::init()",base::Message) << "Initializing Cg\n";
		{
			m_CgContext=cgCreateContext();
			cgD3D9SetDevice(m_pD3DDev9);

#ifdef D3D9DRV_CG_DEBUG_ERRORCALLBACK
			errctx=m_CgContext;
			cgSetErrorCallback(cgErrorCallback);
#endif

			m_CgVertexProfile=cgD3D9GetLatestVertexProfile();
			m_CgFragmentProfile=cgD3D9GetLatestPixelProfile();
			m_CgOptimalVertexProfileOptions=cgD3D9GetOptimalOptions(m_CgVertexProfile);
			m_CgOptimalFragmentProfileOptions=cgD3D9GetOptimalOptions(m_CgFragmentProfile);
		}
#endif
			
		base::log("D3D9Device::init()",base::Message) << "Probing queries\n";
		{
			IDirect3DQuery9* pQuery=0;
			hr=m_pD3DDev9->CreateQuery(D3DQUERYTYPE_OCCLUSION,&pQuery);
			m_Caps.m_HWOcclusionQueries=(hr==D3D_OK);
			if (pQuery) pQuery->Release();
		}
			
		{
			base::log("D3D9Device::init()",base::Message) << "Probing vertex program support\n";

			// Supported vertex programs
			{
				unsigned int version=HIBYTE(LOWORD(m_D3DCaps.VertexShaderVersion));
				unsigned int subversion=LOBYTE(LOWORD(m_D3DCaps.VertexShaderVersion));

				if (version>=3) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_vs11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_vs20");
					m_Caps.m_SupportedProgramFormats.addString("d3d_vs30");
				} else if (version>=2) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_vs11");
					if (subversion>=0) m_Caps.m_SupportedProgramFormats.addString("d3d_vs20");
				} else if (version>=1) {
					if (subversion>=1) m_Caps.m_SupportedProgramFormats.addString("d3d_vs11");
				}

				// HLSL support

				LPCSTR vsprofile=D3DXGetVertexShaderProfile(m_pD3DDev9);
				base::String hlslvsprofile;
				if (vsprofile) hlslvsprofile=vsprofile;

				if (hlslvsprofile.compare("vs_1_1",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs11");
				} else if (hlslvsprofile.compare("vs_2_0",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs20");
				} else if (hlslvsprofile.compare("vs_2_a",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs20");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs2a");
				} else if (hlslvsprofile.compare("vs_3_0",true) || (version>=3)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs20");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs2a");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs30");
				}

#ifdef D3D9DRV_USE_CG
				m_Caps.m_SupportedProgramFormats.addString("cg_vprogram");
#endif
			}

			base::log("D3D9Device::init()",base::Message) << "Probing fragment program support\n";

			// Supported fragment programs
			{
				unsigned int version=HIBYTE(LOWORD(m_D3DCaps.PixelShaderVersion));
				unsigned int subversion=LOBYTE(LOWORD(m_D3DCaps.PixelShaderVersion));

				if (version>=3) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps12");
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps13");
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps14");
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps20");
					if (subversion>=0) m_Caps.m_SupportedProgramFormats.addString("d3d_ps30");
				} else if (version>=2) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps12");
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps13");
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps14");
					if (subversion>=0) m_Caps.m_SupportedProgramFormats.addString("d3d_ps20");
				} else if (version>=1) {
					if (subversion>=1) m_Caps.m_SupportedProgramFormats.addString("d3d_ps11");
					if (subversion>=2) m_Caps.m_SupportedProgramFormats.addString("d3d_ps12");
					if (subversion>=3) m_Caps.m_SupportedProgramFormats.addString("d3d_ps13");
					if (subversion>=4) m_Caps.m_SupportedProgramFormats.addString("d3d_ps14");
				}
				

				

				// HLSL support

				LPCSTR vsprofile=D3DXGetPixelShaderProfile(m_pD3DDev9);
				base::String hlslpsprofile;
				if (vsprofile) hlslpsprofile=vsprofile;

				if (hlslpsprofile.compare("ps_1_1",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11");
				} else if (hlslpsprofile.compare("ps_1_2",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12");
				} else if (hlslpsprofile.compare("ps_1_3",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps13");
				} else if (hlslpsprofile.compare("ps_1_4",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps13");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps14");
				} else if (hlslpsprofile.compare("ps_2_0",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps13");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps14");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps20");
				} else if (hlslpsprofile.compare("ps_2_a",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps13");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps14");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps20");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps2a");
				} else if (hlslpsprofile.compare("ps_3_0",true) || (version>=3)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps13");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps14");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps20");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps2a");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps30");
				}

#ifdef D3D9DRV_USE_CG
				m_Caps.m_SupportedProgramFormats.addString("cg_fprogram");
#endif
			}

		} // Caps end

		m_Displaywidth=viewport.Width;
		m_Displayheight=viewport.Height;
		m_ColorbufferFormat=colorbufferformat;
		m_DepthstencilbufferFormat=depthstencilformat;

		m_pD3DDev9->SetRenderState(D3DRS_FOGVERTEXMODE,D3DFOG_LINEAR);

		fixedLighting(false);

		base::log("D3D9Device::init()",base::Message) << "Init complete\n";
	}