Sign in to follow this  
Manpreet

[D3D9,HLSL] Problem when using vertex Declaration

Recommended Posts

Manpreet    162
Hey folks!

I'm having some trouble trying to render a textured quad with a vertex declaration.

I have a vertex shader that takes position and 1 set of UV coordinates and outputs a position and 1 set of uv coords , and a pixel shader that takes the uv coords from the vertex shader and outputs a color value;

The problem : If i use the device->SetFVF function and set the vertex format to D3DFVF_XYZ|D3DFVF_TEX1 everything works fine and good.

But when i use the SetVertexDeclaration the program crashes.

After some debugging and running this through PIX i found out that the program was crashing at the DrawIndexedPrimitive call . which leads me to believe that in my shaders somewhere i'm messing up the semantics(because this call works if i use the fixed function SetFVF);

the vertex structure & Declaration

struct Vertex
{
D3DXVECTOR3 Pos;
D3DXVECTOR2 U0V0;

Vertex(D3DXVECTOR3 A,D3DXVECTOR2 B):Pos(A),U0V0(B){}

static const DWORD FVF;

};

D3DVERTEXELEMENT9 VElement[] =
{
{0,0,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION,0},

{0,12,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,0},

D3DDECL_END()
};


const DWORD Vertex::FVF = D3DFVF_XYZ|D3DFVF_TEX1;






vertex shader :-

matrix ViewMatrix;
matrix ProjMatrix;
matrix ViewProjMatrix;
matrix Rotation;



struct Input
{
vector position : POSITION0;
float2 tCoord1 : TEXCOORD0;


};

struct Output
{
vector position : POSITION0;
float2 tCoord1 : TEXCOORD0;

};



Output VSMain(Input input)
{
Output output = (Output)0;

ViewProjMatrix = mul(ViewMatrix,ProjMatrix);

input.position = mul(input.position,Rotation);

output.tCoord1 = input.tCoord1;

output.position = mul(input.position,ViewProjMatrix);

return output;

}



Pixel shader :-

sampler Tex1;


struct PsInput
{
float2 Tex1 : TEXCOORD0;
};

struct PsOutput
{
vector Color : COLOR0;
};



PsOutput PSMain(PsInput input)
{
PsOutput output = (PsOutput)0;

vector t1 = tex2D(Tex1,input.Tex1);

output.Color = t1;

return output;
}



i didnt list entire source because just changing the

D3DDEVICE->SetFVF(D3DFVF_XYZ|D3DFVF_TEX1);
to
D3DDEVICE->SetVertexDeclaration(VDECL);

is causing the all problems.So it seems the problem resides here only.
I checked the CreateVertexDeclaration for failure,but it returns success everytime

Also PIX showed this

PRE: <this=0x036edf08>IDirect3DDevice9::DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2)
An unhandled exception occurred.



So if you think that the problem might be somewhere else then do tell me , i'll list the other parts of the code


Share this post


Link to post
Share on other sites
Manpreet    162
Hey buckeye,heres the code



//.....Code for initializing the device snipped............

/* Create the vertex buffer , NOTE that the FVF part is commented out */

if(FAILED(g_pDevice->CreateVertexBuffer(4*sizeof(Vertex),0,0/*Vertex::FVF*/,D3DPOOL_MANAGED,&g_pVB,NULL)))
return 0;

if(FAILED(g_pDevice->CreateIndexBuffer(6*sizeof(DWORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX32,D3DPOOL_MANAGED,&g_pIB,NULL)))
return 0;

/* THE VELEMENT STRUCTURE IS THE ONE I LISTED IN MY PREVIOUS POST */

g_pDevice->CreateVertexDeclaration(VElement,&VDeclaration);


D3DXCreateTextureFromFile(g_pDevice,"Texture.bmp",&g_pTexture);

g_pVB->Lock(0,0,(void **)&V,0);

V[0] = Vertex(D3DXVECTOR3(2.0f,-2.0f,0.0f),D3DXVECTOR2(0.0f,1.0f));
V[1] = Vertex(D3DXVECTOR3(2.0f,2.0f,0.0f),D3DXVECTOR2(0.0f,0.0f));
V[2] = Vertex(D3DXVECTOR3(-2.0f,2.0f,0.0f),D3DXVECTOR2(1.0f,0.0f));
V[3] = Vertex(D3DXVECTOR3(-2.0f,-2.0f,0.0f),D3DXVECTOR2(1.0f,1.0f));

g_pVB->Unlock();

g_pIB->Lock(0,0,(void **)&I,0);

I[0] = 0;
I[1] = 1;
I[2] = 2;

I[3] = 0;
I[4] = 2;
I[5] = 3;

g_pIB->Unlock();

D3DXMatrixLookAtLH(&View,&CamPos,&CamLook,&CamUp);

D3DXMatrixPerspectiveFovLH(&Projection,3.14f*0.5f,(float)SCREEN_WIDTH/SCREEN_HEIGHT,1.0f,1000.0f);


D3DXCompileShaderFromFile("Shader1.txt",0,0,
"PSMain","ps_2_0",
D3DXSHADER_DEBUG|D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY,
&ShaderCode,
&ErrorCode,
&PSConstTable);

if(ErrorCode)
{
MessageBox(handle,(char *)ErrorCode->GetBufferPointer(),"Error",MB_OK);
ErrorCode->Release();
}

if(FAILED(g_pDevice->CreatePixelShader((DWORD *)ShaderCode->GetBufferPointer(),&PShader)))
{
MessageBox(handle,"ERROR creating pixel shader","ERROR",0);
}



HTex1 = PSConstTable->GetConstantByName(0,"Tex1");

UINT count;

PSConstTable->GetConstantDesc(HTex1,&Tex1Desc,&count);

D3DXCompileShaderFromFile("Shader12.txt",0,0,
"VSMain","vs_2_0",
D3DXSHADER_DEBUG|D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY,
&S2,
&ErrorCode,
&VSConstTable);


if(ErrorCode)
{
MessageBox(handle,(char *)ErrorCode->GetBufferPointer(),"Error",MB_OK);
ErrorCode->Release();
}

if(FAILED(g_pDevice->CreateVertexShader((DWORD *)S2->GetBufferPointer(),&VShader)))
{
MessageBox(handle,"ERROR","ERROR",0);
}

HViewM = VSConstTable->GetConstantByName(0,"ViewMatrix");
HProjM = VSConstTable->GetConstantByName(0,"ProjMatrix");
HViewProjM = VSConstTable->GetConstantByName(0,"ViewProjMatrix");

VSConstTable->SetDefaults(g_pDevice);
PSConstTable->SetDefaults(g_pDevice);

g_pDevice->SetRenderState(D3DRS_LIGHTING,false);

return 1;
}





And my render function looks like this


//TRIVIAL ROTATION CODE SNIPPED

g_pDevice->BeginScene();

g_pDevice->SetStreamSource(0,g_pVB,0,sizeof(Vertex));

g_pDevice->SetIndices(g_pIB);

g_pDevice->SetPixelShader(PShader);

g_pDevice->SetVertexShader(VShader);



// g_pDevice->SetFVF(Vertex::FVF);

g_pDevice->SetVertexDeclaration(VDeclaration);



g_pDevice->SetTexture(Tex1Desc.RegisterIndex,g_pTexture);
g_pDevice->SetSamplerState(Tex1Desc.RegisterIndex,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
g_pDevice->SetSamplerState(Tex1Desc.RegisterIndex,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
g_pDevice->SetSamplerState(Tex1Desc.RegisterIndex,D3DSAMP_MIPFILTER,D3DTEXF_POINT);

g_pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,4,0,2);

g_pDevice->EndScene();




Thanks!

Share this post


Link to post
Share on other sites
Buckeye    10747
Does the Debug Runtime provide any information?

Is "g_pDevice->CreateVertexDeclaration(VElement,&VDeclaration)" successful? You assume it works without checking.

You would get complaints from the compiler (just checking), but is VDeclaration declared as LPDIRECT3DVERTEXDECLARATION9?

Share this post


Link to post
Share on other sites
Manpreet    162
Quote:
Original post by Buckeye
Does the Debug Runtime provide any information?


Um to be honest i am not able to use the vc debugger at all , due to the fact that it cannot locate my bitmap files( even after i add them to the project).
To run my program i build it and then have to manually run it from the debug folder everytime.A program which uses external bitmaps files etc runs fine when executed from the debug folder but crashes when run through the debugger.


Quote:
Original post by Buckeye
Is "g_pDevice->CreateVertexDeclaration(VElement,&VDeclaration)" successful? You assume it works without checking.


Well i checked it but still no use, its returning success.Like i said in my first post , the only thing that was causing the crash was the Device->SetVertexDeclaration() call instead of SetFVF() call.If i comment out the SetVertexdeclaration and use the fvf one instead without touching anything else(even leaving out CreateVertexDeclaration as it is) everything runs perfectly fine.

Like i said earlier , PIX pointed out that after the Call to DrawIndexedPrimitive
an unhandled exception was returned , so im guessing the input and output data of my shaders are messed up somewhere?


The vertex shader takes a position vector and u,v coordinates and outputs the same.

So does the pixel shader need only the tex coord for its input or does it also need the position coords?


Quote:
Original post by Buckeye
You would get complaints from the compiler (just checking), but is VDeclaration declared as LPDIRECT3DVERTEXDECLARATION9?



Yes its declared like you said , but why??? And i didn't get any complaints , was i supposed to ?:))



@Mussi

Well I am reading this stuff from Frank luna's Intro to Game programming and in this example he has used color as a vector , so i did the same and got fine results ( that is , using the fixed funtion FVF). I tried using float4 but that didnt make any difference.The program still crashes with SetVertexDeclaration :(


Share this post


Link to post
Share on other sites
Buckeye    10747
First, I understand you want to fix the immediate problem first. However..
Quote:
i am not able to use the vc debugger at all , due to the fact that it cannot locate my bitmap files

Fix that! You have a very valuable built-in debugging tool you're not using. You're losing a tremendous amount of programming time and information without being able to step through code line-by-line, set breakpoints, check variables values, etc.

I'm guessing you assume a path to the textures rather than specifying it - something like CreateTextureFromFile(...,"someBM.png").

Your program will look for files like that in the current working directory, which will be different when run from the IDE, or from the Debug folder, or from the Release folder, etc.

For the time being, you should specify the full path to the textures somehow:

such as:

CreateTexturexxx(...,"c:\\myProject\\someBM.png");


or:

std::string filePath = "c:\\myProject\\";
//...
std::string texturePath = filePath;
texturePath.append("someBM.png");
CreateTexturexxx(....,texturePath.c_str());


Then you can run the app from anywhere.
Quote:
Yes its declared like you said , but why???

[smile] I was just checking. That's what it should be.

Share this post


Link to post
Share on other sites
Manpreet    162
hey buckeye,

Thanks for the info but it still didn't work :(((
I tried both your methods and while the manual execution is working , debugging still isnt.

Share this post


Link to post
Share on other sites
NightCreature83    5002
Quote:
Original post by Manpreet
Quote:
Original post by Buckeye
Does the Debug Runtime provide any information?


Um to be honest i am not able to use the vc debugger at all , due to the fact that it cannot locate my bitmap files( even after i add them to the project).
To run my program i build it and then have to manually run it from the debug folder everytime.A program which uses external bitmaps files etc runs fine when executed from the debug folder but crashes when run through the debugger.


Quote:
Original post by Buckeye
Is "g_pDevice->CreateVertexDeclaration(VElement,&VDeclaration)" successful? You assume it works without checking.


Well i checked it but still no use, its returning success.Like i said in my first post , the only thing that was causing the crash was the Device->SetVertexDeclaration() call instead of SetFVF() call.If i comment out the SetVertexdeclaration and use the fvf one instead without touching anything else(even leaving out CreateVertexDeclaration as it is) everything runs perfectly fine.

Like i said earlier , PIX pointed out that after the Call to DrawIndexedPrimitive
an unhandled exception was returned , so im guessing the input and output data of my shaders are messed up somewhere?


The vertex shader takes a position vector and u,v coordinates and outputs the same.

So does the pixel shader need only the tex coord for its input or does it also need the position coords?


Quote:
Original post by Buckeye
You would get complaints from the compiler (just checking), but is VDeclaration declared as LPDIRECT3DVERTEXDECLARATION9?



Yes its declared like you said , but why??? And i didn't get any complaints , was i supposed to ?:))



@Mussi

Well I am reading this stuff from Frank luna's Intro to Game programming and in this example he has used color as a vector , so i did the same and got fine results ( that is , using the fixed funtion FVF). I tried using float4 but that didnt make any difference.The program still crashes with SetVertexDeclaration :(


You can specify what the current directory should be from VS as well it's under project options:
1. Right click your project file and select properties
2. Under "Configuration Properties" select "Debugging"
3. In the pane on the right locate "Working Directory" and set that to the path that your exe is in.

If you launch the debug app from the directory you can still attach the debugger to it, you can attach the debugger to any running process by doing the following:
1. From the "Debug" menu pick "Attach to Process"
2. Select your executable from the list and click "Attach"
3. You should now be able to see output coming into the Output pane and be able to debug as normal.

I normally use the VertexOutput struct as my pixel shaders input struct so position is then in the struct. But as far as I know it is not neccesary to input that as you can't access that field from the PS anyways.

Share this post


Link to post
Share on other sites
Manpreet    162
Quote:
Original post by NightCreature83

You can specify what the current directory should be from VS as well it's under project options:
1. Right click your project file and select properties
2. Under "Configuration Properties" select "Debugging"
3. In the pane on the right locate "Working Directory" and set that to the path that your exe is in.


Thanks for the info nightcreature!
Although sadly the problem still persists x(
I have another program(which doesn't use external bitmaps,but uses a vertex shader)
that i can now debug successfully.

But for this particular program, i dont know whats wrong,still doesnt work

I'm sorry i forgot to mention,am using VS 2010

I copy pasted the bitmaps in each of the folders of the project i could find, but no use.

As for the attaching process , how am i supposed to attach the process if it exits before i can do anything . It says the program stopped working and then just exits.

it seems like PIX is the only good option for debugging at this time , and like i said earlier, it gives an unhandled exception at the DrawIndexedPrimitive() call

Am i declaring the vertex element structure the wrong way??
why is SetFVF() giving absolutely correct results(if you see in my code above i passed a zero for the FVF argument in the create Vertex Buffer and still the SetFVF works) whereas SetVertexDecl is crashing the entire program??

Buckeye , nightcreature,Mussi thanks for the responses and for sparing your time!

Share this post


Link to post
Share on other sites
Mussi    4407
You could test it using a simple shader, don't know if that could cause such problems but I guess it's worth a try. Here's a very basic one from Nvidia:
float4x4 WorldViewProj;
float4 Color;

struct a2v {
float4 Position : POSITION; //in object space
};

struct v2f {
float4 Position : POSITION; //in projection space
float4 Color : COLOR0;
};

v2f SimpleTransform(a2v IN)
{
v2f OUT;
OUT.Color = Color;
OUT.Position = mul(IN.Position, WorldViewProj);
return OUT;
}

Technique SimpleTransformTechnique
{
Pass P0
{
VertexShader = compile vs_1_1 SimpleTransform();
PixelShader = NULL;
}
}

Also, your sampler has no body. I haven't really worked with shaders yet, so I'm just pointing out stuff that looks a little odd to me.

Share this post


Link to post
Share on other sites
NightCreature83    5002
Quote:
Original post by Manpreet
it seems like PIX is the only good option for debugging at this time , and like i said earlier, it gives an unhandled exception at the DrawIndexedPrimitive() call


You could stall your app for say like 5 seconds in the beginning of the application whith the "wait(5000);" being the first call in the app maybe that way you could attach a debugger before it crashes.

Ok then to just see the output of the debug runtime you could try running debug view (http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx) before running your application. Debug view captures all traces from your application and shows them in its log window. This is also the way you view XNA output from the DX debug dlls.

Or look in Pix at the output when clicking on the different events it captures it should also show you what the debug runtime outputs.

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

Sign in to follow this