Sign in to follow this  

First adventures into D3D10 land not going well :D

This topic is 3500 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So, over the weekend I decided to look into this D3D10 lark and generally fiddle with 'stuff', however despite things not crashing my output isn't quite right and I'm having a hard time spotting why [smile] In short, I'm trying to draw a quad on the X-Z plane (which I'm assuming is flat with Y up, but that's kinda by the by), however what I'm getting is a flicking mess which seems to indicate I've screwed up somewhere [grin] I've checked over MSDN a few times and while I can't see anything off hand I'm new to this D3D10 game so I might have just missed something subtle, who knows. anyways, enough jabbering, onto the code! Setup;
HRESULT CreatePlane(ID3D10Device* pd3dDevice)
{
	HRESULT hr;

	// Read the D3DX effect file
	WCHAR str[MAX_PATH];
	V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"md5renderer.fx" ) );
	DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
	// Set the D3D10_SHADER_DEBUG flag to embed debug information in the shaders.
	// Setting this flag improves the shader debugging experience, but still allows 
	// the shaders to be optimized and to run exactly the way they will run in 
	// the release configuration of this program.
	dwShaderFlags |= D3D10_SHADER_DEBUG;
#endif
	V_RETURN( D3DX10CreateEffectFromFile( str, NULL, NULL, "fx_4_0", dwShaderFlags, 0, pd3dDevice, NULL, NULL, &g_pPlaneEffect10, NULL, NULL ) );

	// Get effects techniques
	g_pPlaneRenderModel = g_pPlaneEffect10->GetTechniqueByName("RenderModelBasic");

	// Get effects variables
	g_pmPlaneWorldViewProj = g_pPlaneEffect10->GetVariableByName( "g_mWorldViewProj" )->AsMatrix();
	g_pmPlaneWorld = g_pPlaneEffect10->GetVariableByName( "g_mWorld" )->AsMatrix();

	const D3D10_INPUT_ELEMENT_DESC datalayout[] =
	{
		{"POSITION",	0, DXGI_FORMAT_R32G32B32_FLOAT,	0,	0, D3D10_INPUT_PER_VERTEX_DATA,	0	},
		{"NORMAL",		0, DXGI_FORMAT_R32G32B32_FLOAT,	0,	12, D3D10_INPUT_PER_VERTEX_DATA, 0	}
	};

	const int numElements = sizeof(datalayout)/sizeof(datalayout[0]);
	D3D10_PASS_DESC PassDesc;
	g_pPlaneRenderModel->GetPassByIndex( 0 )->GetDesc( &PassDesc );
	V_RETURN( pd3dDevice->CreateInputLayout( datalayout, numElements, PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, &PlanemodelInputLayout ) );

	float vertexdata[] = 
	{
		1,0,1,0,1,0,
		1,0,-1,0,1,0,
		-1,0,-1,0,1,0,
		-1,0,1,0,1,0
	};

	// next we need to create a VB and IB pair for the data
	D3D10_BUFFER_DESC vb;
	vb.Usage = D3D10_USAGE_DEFAULT;
	vb.ByteWidth = sizeof(float) * 24;
	vb.BindFlags = D3D10_BIND_VERTEX_BUFFER;
	vb.CPUAccessFlags = 0;
	vb.MiscFlags = 0;

	
	D3D10_SUBRESOURCE_DATA VertInitData;
	VertInitData.pSysMem = vertexdata;
	VertInitData.SysMemPitch = 0;
	VertInitData.SysMemSlicePitch = 0;

	V_RETURN(pd3dDevice->CreateBuffer(&vb, &VertInitData, &g_pPlaneVertexBuffer));

//	unsigned int indices[] = {3,2,0,0,2,1 };
	unsigned int indices[] = {0,2,1,2,0,3 };

	D3D10_BUFFER_DESC bufferDesc;
	bufferDesc.Usage           = D3D10_USAGE_DEFAULT;
	bufferDesc.ByteWidth	   = sizeof(unsigned int) * 6;
	bufferDesc.BindFlags       = D3D10_BIND_INDEX_BUFFER;
	bufferDesc.CPUAccessFlags  = 0;
	bufferDesc.MiscFlags       = 0;

	D3D10_SUBRESOURCE_DATA InitData;
	InitData.pSysMem = indices;
	InitData.SysMemPitch = 0;
	InitData.SysMemSlicePitch = 0;
	hr = pd3dDevice->CreateBuffer( &bufferDesc, &InitData, &g_pPlaneIndexBuffer );

	return hr;
}


and render;
void RenderPlane(ID3D10Device* pd3dDevice, D3DXMATRIX  &mViewProj)
{
	D3DXMATRIX mWorld;
	D3DXMatrixIdentity( &mWorld );
	D3DXMATRIX mWorldViewProj = mWorld * mViewProj;

	g_pmPlaneWorldViewProj->SetMatrix( (float*)&mWorldViewProj );
	g_pmPlaneWorld->SetMatrix( (float*)&mWorld );

	pd3dDevice->IASetInputLayout( PlanemodelInputLayout );

	// Set vertex buffer
	UINT stride = sizeof( float ) * 6;
	UINT offset = 0;
	pd3dDevice->IASetVertexBuffers( 0, 1, &g_pPlaneVertexBuffer, &stride, &offset );
	pd3dDevice->IASetIndexBuffer( g_pPlaneIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );


	D3D10_TECHNIQUE_DESC techDesc;
	g_pPlaneRenderModel->GetDesc( &techDesc );

	for(int i = 0; i < techDesc.Passes; i++)
	{
		pd3dDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
		g_pPlaneRenderModel->GetPassByIndex( i )->Apply(0);
		//	pd3dDevice->DrawIndexed(meshes_[0].tri_indices_.size(), 0,0);
		pd3dDevice->DrawIndexed(6, 0, 0);
	}

	return;
}


For the record the referenced variables are the right sort (as noted it neither crashes nor gives me any warnings in the debug output). I'm using the DXUT framework for current window setup and copied the code from the D3D10 skinning example, stripping out bits which weren't directly related to what I was doing (mostly the skinning example stuff). The render thread is fed via the following chunk of code;
D3DXMATRIX  mWorldViewProj;
	D3DXMATRIX  mViewProj;
	D3DXMATRIX  mWorld;
	D3DXMATRIX  mView;
	D3DXMATRIX  mProj;

	float ClearColor[4] = { 0.176f, 0.196f, 0.667f, 0.0f };
	ID3D10RenderTargetView* pRTV = DXUTGetD3D10RenderTargetView();
	pd3dDevice->ClearRenderTargetView( pRTV, ClearColor );

	// Clear the depth stencil
	ID3D10DepthStencilView* pDSV = DXUTGetD3D10DepthStencilView();
	pd3dDevice->ClearDepthStencilView( pDSV, D3D10_CLEAR_DEPTH, 1.0, 0 );

	// If the settings dialog is being shown, then render it instead of rendering the app's scene
	if( g_SettingsDlg.IsActive() )
	{
		g_SettingsDlg.OnRender( fElapsedTime );
		return;
	}

	// Get the projection & view matrix from the camera class
	D3DXMatrixIdentity( &mWorld );
	mProj = *g_Camera.GetProjMatrix();
	mView = *g_Camera.GetViewMatrix();
	mViewProj = mView * mProj;
	RenderPlane(pd3dDevice,mViewProj);
	
	DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" );
	RenderText();
	g_HUD.OnRender( fElapsedTime ); 
	g_SampleUI.OnRender( fElapsedTime );
	DXUT_EndPerfEvent();


edit: crud, forgot the .fx file;
// MD5 rendering .fx file

struct VSDataIn
{
	float3 Pos : POSITION;
	float3 Norm : NORMAL;
};

struct PSDataIn
{
	float4 Pos : SV_Position;
	float4 vPos : POSWORLD;
	float3 Norm : NORMAL;
};

// Constant buffers
cbuffer cb0
{
    float4x4 g_mWorldViewProj;
    float4x4 g_mWorld;
};


// State

DepthStencilState EnableDepth
{
    DepthEnable = TRUE;
    DepthWriteMask = ALL;
};

// Vertex Shader
PSDataIn VSSimpleBind(VSDataIn input)
{
	PSDataIn output;
	
	output.Pos = mul (input.Pos, g_mWorldViewProj);
	output.vPos = mul (input.Pos, g_mWorld );
	output.Norm = normalize(mul(input.Norm, (float3x3)g_mWorld));
	
	return output;
}

// Fragment shader
float4 PSSimpleShader(PSDataIn input) : SV_Target
{
	return float4(1.0, 1.0, 1.0, 1.0);
}

// Technique
technique10 RenderModelBasic
{
	pass P0
	{
		SetVertexShader( CompileShader( vs_4_0, VSSimpleBind() ) );
		SetGeometryShader ( NULL );
		SetPixelShader( CompileShader( ps_4_0, PSSimpleShader() ) );
		
		SetDepthStencilState( EnableDepth, 0 );
	}
}

And if it makes any difference I'm running in x64 mode and on an NV 8800GT card. OK, feel free to point out my stupid mistake now [grin]

Share this post


Link to post
Share on other sites
[Edit] You're right, the vertex buffer data looks fine.

Take a look at it in PIX, It'll show you how the data is transformed and perhaps provide a clue to the issue.

[Edited by - DieterVW on May 14, 2008 12:02:00 PM]

Share this post


Link to post
Share on other sites
hmmmm, are you sure? I would have thought this would have been fine;


float vertexdata[] =
{
1,0,1, 0,1,0,
1,0,-1, 0,1,0,
-1,0,-1, 0,1,0,
-1,0,1, 0,1,0
};



First 3 floats = position, 2nd 3 floats = normal, stride = 6 * float.
4 verts, as per index array, first 12 bytes = position (rgb 32 float) and at 12 byte offset we have normal data in rgb32 float format.

Of course, if that isn't right what data should I given it to get that effect?

Share this post


Link to post
Share on other sites
Your data looks fine to me - it's a little uncommon to define it that way, but as a chunk of binary data D3D will see it the same as having an array of struct's containing pairs of D3DXVECTOR3's...

By flickering do you mean Z-fighting type flickering? That would suggest to me that you've got a problem with the pixel/rasterizer stage of the pipeline rather than the geometry or geometry setup.

Digging around in PIX might well give you some insight - with both the FX framework and DXUT it's possible for states to not be exactly as they appear from a simple static code review.

I did hit on a bug/change a few SDK's ago where you had to change the rasterizer state to get it rendering correctly. I'm at work now so don't have my resources to hand, but there was definitely something about forcing pipeline state in a RasterizerState object within the .FX file.


hth
Jack

Share this post


Link to post
Share on other sites
Yeah, I probably should have explained the visuals better.

Basically when you pan around using the mouse a white shape appears but it seems to have one vertex stuck to the middle of the view port and as you move around the shape kinda spins and folds around itself.

I'll see if I can get a few screen grabs later, although its really one of those effects you need to see in motion to understand :|

Anyway, I'll check out PIX later once I get home, I was just hoping it was something simple I'd missed [grin]

Share this post


Link to post
Share on other sites
Those "triangles corners heading into infinity" that you described are usually the result of a) invalid vertex input, for example a mismatch of vertex structure and vertex shader input or b) invalid values such as #NAN or #INF produced in the vertex shader. I'm not familiar with DX10 so feel free to correct my DX9 knowledge here :-)

Your source looks fine as far as I can jugde, but one thing worries me: somewhere along the line from VSDataIn::Pos to PSDataIn::Pos this vector is enhanced to 4 components. Depending on where this happens your WorldViewProjection matrix multiplication might work as expected or produce rubbish. Might be worth padding the position manually to (x, y, z, 1) and see if it works then.

Share this post


Link to post
Share on other sites
Your input position is a float3, and you're multiplying it by a 4x4 matrix.

Use mul (float4(input.Pos, 1), g_mWorldViewProj); to explicitly assign 1 to the 4th element of the vector, so you get the correct 4-element multiply.

And welcome to D3D_LAND!

Share this post


Link to post
Share on other sites

This topic is 3500 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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

Sign in to follow this