Jump to content
  • Advertisement

Recommended Posts

Hi, I want to change directx version that the game uses from 8 to 9 (if I succeed, maybe I will try to change to 11 in the future). I have a few problems that I can not deal with.

Firstly, I don't know how to change vertex shader declaration.

Spoiler

// template shader for fixed function vertex shader
DWORD _adwDeclTemplateFF[] = {
	D3DVSD_STREAM(0),
	D3DVSD_REG( D3DVSDE_POSITION,  D3DVSDT_FLOAT3),
	D3DVSD_STREAM(1),
	D3DVSD_REG( D3DVSDE_DIFFUSE,   D3DVSDT_D3DCOLOR),
	D3DVSD_STREAM(2),
	D3DVSD_REG( D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
	D3DVSD_STREAM(3),
	D3DVSD_REG( D3DVSDE_TEXCOORD1, D3DVSDT_FLOAT2),
	D3DVSD_STREAM(4),
	D3DVSD_REG( D3DVSDE_TEXCOORD2, D3DVSDT_FLOAT2),
	D3DVSD_STREAM(5),
	D3DVSD_REG( D3DVSDE_TEXCOORD3, D3DVSDT_FLOAT2),
	D3DVSD_STREAM(6),
	D3DVSD_REG( D3DVSDE_NORMAL,    D3DVSDT_FLOAT3),
	D3DVSD_STREAM(7), // not used in fixed-function vs but must be declared for stream reset
	D3DVSD_REG( NONE, NONE),
	D3DVSD_REG( NONE, NONE),
	D3DVSD_END()
};
// template shader for programmable vertex shader
DWORD _adwDeclTemplateVP[] = {
	D3DVSD_STREAM(0),
	D3DVSD_REG( 0,  D3DVSDT_FLOAT3),    // position
	D3DVSD_STREAM(1),
	D3DVSD_REG( 4,  D3DVSDT_D3DCOLOR),  // diffuse
	D3DVSD_STREAM(2),
	D3DVSD_REG( 5,  D3DVSDT_FLOAT2),    // texcoord0
	D3DVSD_STREAM(3),
	D3DVSD_REG( 6,  D3DVSDT_FLOAT2),    // texcoord1
	D3DVSD_STREAM(4),
	D3DVSD_REG( 7,  D3DVSDT_FLOAT2),    // texcoord2
	D3DVSD_STREAM(5),
	D3DVSD_REG( 8, D3DVSDT_FLOAT2),     // texcoord3
	D3DVSD_STREAM(6),
	D3DVSD_REG( 1,  D3DVSDT_FLOAT3),    // normal
	D3DVSD_STREAM(7),
	D3DVSD_REG( 3,  D3DVSDT_D3DCOLOR),  // blend indices
	D3DVSD_REG( 2,  D3DVSDT_D3DCOLOR),  // blend weights
	D3DVSD_END()
};

 

Secondly, I have a function that returns shader declaration from given flags. How to change it?

Spoiler

// Get shader stream declaration from stream flags
extern void GetShaderDeclaration_D3D(ULONG *ulRetDecl, ULONG ulStreamFlags)
{
	// if using position stream
	if(ulStreamFlags&GFX_POSITION_STREAM) {
		*(  ulRetDecl) = D3DVSD_STREAM(0);
		*(++ulRetDecl) = D3DVSD_REG( 0,  D3DVSDT_FLOAT3);
		ulStreamFlags&=~GFX_POSITION_STREAM;
	}
	// if using color stream
	if(ulStreamFlags&GFX_COLOR_STREAM) {
		*(++ulRetDecl) = D3DVSD_STREAM(1);
		*(++ulRetDecl) = D3DVSD_REG( 4,  D3DVSDT_D3DCOLOR);
		ulStreamFlags&=~GFX_COLOR_STREAM;
	}
	// if using texture unit 1
	if(ulStreamFlags&GFX_TEXCOORD0) {
		*(++ulRetDecl) = D3DVSD_STREAM(2);
		*(++ulRetDecl) = D3DVSD_REG( 5,  D3DVSDT_FLOAT2);
		ulStreamFlags&=~GFX_TEXCOORD0;
	}
	// if using texture unit 2
	if(ulStreamFlags&GFX_TEXCOORD1) {
		*(++ulRetDecl) = D3DVSD_STREAM(3);
		*(++ulRetDecl) = D3DVSD_REG( 6,  D3DVSDT_FLOAT2);
		ulStreamFlags&=~GFX_TEXCOORD1;
	}
	// if using texture unit 3
	if(ulStreamFlags&GFX_TEXCOORD2) {
		*(++ulRetDecl) = D3DVSD_STREAM(4);
		*(++ulRetDecl) = D3DVSD_REG( 7,  D3DVSDT_FLOAT2);
		ulStreamFlags&=~GFX_TEXCOORD2;
	}
	// if using texture unit 4
	if(ulStreamFlags&GFX_TEXCOORD3) {
		*(++ulRetDecl) = D3DVSD_STREAM(5);
		*(++ulRetDecl) = D3DVSD_REG( 8,  D3DVSDT_FLOAT2);
		ulStreamFlags&=~GFX_TEXCOORD3;
	}
	if(ulStreamFlags&GFX_NORMAL_STREAM) {
		*(++ulRetDecl) = D3DVSD_STREAM(6);
		*(++ulRetDecl) = D3DVSD_REG( 1,  D3DVSDT_FLOAT3);
		ulStreamFlags&=~GFX_NORMAL_STREAM;
	}
	if(ulStreamFlags&GFX_WEIGHT_STREAM) {
		*(++ulRetDecl) = D3DVSD_STREAM(7);
		*(++ulRetDecl) = D3DVSD_REG( 3,  D3DVSDT_D3DCOLOR);
		*(++ulRetDecl) = D3DVSD_REG( 2,  D3DVSDT_D3DCOLOR);
		ulStreamFlags&=~GFX_WEIGHT_STREAM;
	}
	// if using tangent
	if(ulStreamFlags&GFX_TANGENT_STREAM) {
		*(++ulRetDecl) = D3DVSD_STREAM(3);
		*(++ulRetDecl) = D3DVSD_REG( 9,  D3DVSDT_FLOAT4);
		ulStreamFlags&=~GFX_TANGENT_STREAM;
	}
	ASSERT(ulStreamFlags==0); // make sure stream flags were valid
	*(++ulRetDecl) = D3DVSD_END();
}

 

And I have one question. Is it possible to combine dx8 shaders with dx9?

Thanks for any help.

Share this post


Link to post
Share on other sites
Advertisement

If you have the time, give DX12 or Vulkan a chance? DX8 and DX9 are very similar and very old technology (over a decade old now). If you restrict yourself to around shader model 2 you should be able to interchange your shaders between DX8 and DX9 IIRC.

For the code conversion, I recommend using DX9 with vertex declarations instead of FVF.

Thus the first code block becomes this in DX9:

// template shader for fixed function vertex shader
D3DVERTEXELEMENT9 _awDeclTemplateFF[] = {
       {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
       {1, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
       {2, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
       {3, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
       {4, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
       {5, 40, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
       {6, 48, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
       D3DDECL_END()
};
// template shader for programmable vertex shader
D3DVERTEXELEMENT9 _awDeclTemplateVP[] = {
       {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
       {1, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
       {2, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
       {3, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
       {4, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
       {5, 40, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
       {6, 48, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
       {7, 60, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
       {7, 64, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
       D3DDECL_END()
};

You'll have to extrapolate the above to figure out how you want to handle your second code fragment. I recommend either thunking the DX9 vertex declaration above down to DX8 or create some abstract intermediate representation of a vertex description and return that instead.

Share this post


Link to post
Share on other sites

Thank you so much. I feel that I am one step closer to the goal :D

However, I have another problem.

I have this function:

Spoiler

// construct vertex shader out of streams' bit-mask
extern DWORD SetupShader_D3D( ULONG ulStreamsMask)
{
	HRESULT hr;
	const LPDIRECT3DDEVICE8 pd3dDev = _pGfx->gl_pd3dDevice;
	const INDEX ctFixedShaders = _avsFixedShaders.Count();

	INDEX iVS;

	// delete all shaders?
	if( ulStreamsMask==NONE) {
		// first set default vertex shader
		hr = pd3dDev->SetVertexShader(D3DFVF_CTVERTEX);
		D3D_CHECKERROR(hr);
		gfxSetPixelProgram(NONE);

		for( iVS=0; iVS<ctFixedShaders; iVS++) {
			hr = pd3dDev->DeleteVertexShader(_avsFixedShaders[iVS].vs_dwHandle);
			D3D_CHECKERROR(hr);
		}

		// Delete all programable vertex and pixel programs
		extern void ClearVertexAndPixelPrograms(void);
		ClearVertexAndPixelPrograms();

		// free array
		_avsFixedShaders.PopAll();
		_dwCurrentVS = NONE;
		_dwCurrentPS = NONE;
		_dwLastVertexProgram = NONE;
		return NONE;
	}

	// see if required fixed function shader has already been created
	for( iVS=0; iVS<ctFixedShaders; iVS++) {
		if( _avsFixedShaders[iVS].vs_ulStreamMask==ulStreamsMask) return _avsFixedShaders[iVS].vs_dwHandle;
	}

	// darn, need to create shader :(

	// pre-adjustment for eventual projective mapping
	_adwDeclTemplateFF[DECLTEXOFS+1] = D3DVSD_REG( D3DVSDE_TEXCOORD0, (ulStreamsMask&0x1000) ? D3DVSDT_FLOAT4 : D3DVSDT_FLOAT2);

	ulStreamsMask &= ~0x1000;

	ULONG ulMask = ulStreamsMask;

	// process mask, bit by bit
	INDEX iSrcDecl=0, iDstDecl=0;
	INDEX iStream=0;
	while(_adwDeclTemplateFF[iSrcDecl]!=D3DVSD_END())
	{ // add declarator if used
		INDEX ctRegs = _aiStreamRegs[iStream] + 1; // n*D3DVSD_REG() + D3DVSD_STREAM()
		if( ulMask&1) {
			for(INDEX ireg=0;ireg<ctRegs;ireg++) {
				_adwCurrentDecl[iDstDecl+ireg] = _adwDeclTemplateFF[iSrcDecl+ireg];
			}
			iDstDecl+=ctRegs;
		}
		iSrcDecl+=ctRegs;
		ulMask >>= 1;
		iStream++;
	}
	// mark end
	_adwCurrentDecl[iDstDecl] = D3DVSD_END();
	ASSERT( _iTexPass>=0 && _iColPass>=0);
	ASSERT( _iVtxPos >=0 && _iVtxPos<65536);

	// create new vertex shader
	const DWORD dwFlags = (_pGfx->gl_ulFlags&GLF_D3D_USINGHWTNL) ? NONE : D3DUSAGE_SOFTWAREPROCESSING;

	VertexShader &vs = _avsFixedShaders.Push();
	vs.vs_ulStreamMask = ulStreamsMask;
	
	// create fixed shader
	hr = pd3dDev->CreateVertexShader( &_adwCurrentDecl[0], NULL, &vs.vs_dwHandle, dwFlags);
	D3D_CHECKERROR(hr);
	// reset current shader
	_pGfx->gl_dwVertexShader = NONE;
	return vs.vs_dwHandle;
}

 

Can I change

hr = pd3dDev->SetVertexShader(D3DFVF_CTVERTEX);

to

hr = _pGfx->gl_pd3dDevice->CreateVertexDeclaration(_adwDeclTemplateFF, &(_pGfx->gl_pVertexDeclaration));
hr = _pGfx->gl_pd3dDevice->SetVertexDeclaration(_pGfx->gl_pVertexDeclaration);

?

And what should I do with

hr = pd3dDev->CreateVertexShader( &_adwCurrentDecl[0], NULL, &vs.vs_dwHandle, dwFlags);

?

In DX9, CreateVertexShader accepts completely different arguments.

I don't quite understand what this function does.

I will be grateful for any help.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!