# First adventures into D3D10 land not going well :D

## Recommended Posts

_the_phantom_    11250
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" ) );
#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.
#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;
};

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;
}

{
return float4(1.0, 1.0, 1.0, 1.0);
}

// Technique
technique10 RenderModelBasic
{
pass P0
{

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 on other sites
DieterVW    724
 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 on other sites
_the_phantom_    11250
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 on other sites
jollyjeffers    1570
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 on other sites
_the_phantom_    11250
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 on other sites
Schrompf    1035
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 on other sites
sirob    1181
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 on other sites
_the_phantom_    11250
aha, with some fiddling and the above changes it all works fine now :D

Cheers for the advice people, I dare say it won't be the last time I ask for some [grin]