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

## Recommended Posts

##### Share on other sites
I've not seen/read your previous thread, but I've definitely implemented nearly this exact same code myself at some point in the distant past.

Quote:
 "Declaration can't map to fixed function FVF because position field is missing. Usage: D3DDECLUSAGE_POSITION, with usage index 0 is required for fixed function"This is confusing for a start, because I thought I was trying to use the programmable pipleline
Yes, I wouldn't be expecting that message. Maybe dig into PIX to see what state the pipeline is in - it may well be that with your order of pipeline configuration that it thinks you're using FF and later tell it otherwise. Or something silly like that.

Off the top of my head (don't have my old code to hand) the trick was creating two streams, one with a <D3DDECLUSAGE_POSITION, usage=0, size=float> and a <D3DDECLUSAGE_POSITION, usage=1, size=float2> and then the declaration in the VS can be something like:

struct vsi{    float y : POSITION0;    float2 xz : POSITION1;    // ...};vso vs( in vsi vertex ){    float3 pos = float3( vertex.xz.x, vertex.y, vertex.xz.y );    // ... }

If that fragment doesn't yield anything, can you post your declarations - both app and shader side?

hth
Jack

##### Share on other sites
Just off the top of my head, have you tried setting stream zero as D3DDECLUSAGE_POSITION with a float3 type containing (x,z,0) and stream one as D3DDECLUSAGE_TEXCOORD with a float type containing (y)?

##### Share on other sites
Thanks for the quick responses guys.

Quote:
 Off the top of my head (don't have my old code to hand) the trick was creating two streams, one with a and a and then the declaration in the VS can be something like:

Jack, that doesn't quite work in my configuration as when using POSITION as a usage, it requires a size of FLOAT3. Here is my exact usage at the moment:

D3DVERTEXELEMENT9 declTerrainXYZ[]={  {0, 0, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},  {1, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1},  D3DECL_END()};

When I call the DrawIndexPrimitive method using this declaration, I get

"Declaration can't map to fixed function FVF because position must use D3DDECLTYPE_FLOAT3". Here is the very simple shader fx file I'm using:

struct V_To_P{  float4 Position : POSITION;  float4 Color : COLOR0;};float4x4 xViewProjection;V_To_P SimpleVertexShader( float1 y : POSITION0, float2 xz : POSITION1){  V_To_P Output = (V_To_P)0;  ....  return Output;}technique Simplest{  pass Pass0  {    VertexShader = compile vs_3_0 SimpleVertexShader();    PixelShader = NULL;  }}

Here is the code to draw the primitives:

D3DXHandle technique = effect->GetTechniqueByName("Simplest");D3DXHandle matrix = effect->GetParameterByName(0, "xViewProjection");hr = effect->SetTechnique(technique");hr = effect->SetMatrix(...);hr = DXUTGetD3DDevice()->SetVertexDeclaration(<as above>);hr = DXUTGetD3DDevice()->SetStreamSource(0, <vertexbufferwithsinglefloats>, 0, sizeof(float));hr = DXUTGetD3DDevice()->SetStreamSource(0, <vertexbufferwithfloatpairs>, 0, sizeof(float) * 2);hr = DXUTGetD3DDevice()->SetIndices(<regular indices>);// then simple beginpass, drawindexprimitive, endpass, etc

Tim, if I specify FLOAT3 for both elements and use usagetypes of POSITION, it doesn't error, but how would I specify that my first FLOAT3 is only (x, y, 0) and the second is only (x, 0 ,0)?

Thanks guys, I'd really love to get to the bottom of this.

##### Share on other sites
When you create the VBs you need to fill them with 3 floats, either using three seperate floats or using a D3DXVECTOR3. Not quite sure how to describe it, this isn't my dev machine and I don't have any code here. I'm geussing you define a struct for your vertex data, fill an array of them and then memcopy into your VB. In this struct you need the three floats instead of one or two, when you fill in the instances of this struct in the array you set the unused values as 0.

Also you don't necessarily need to use FLOAT3 for texcoord, which is why i suggested it instead of position1, you can definately use FLOAT2, and i think you might be able to use just FLOAT.

Lastly, in your set stream source calls, the first parameter of the first call should be 1, not 0.

##### Share on other sites
Quote:
 Original post by RobMaddisonJack, that doesn't quite work in my configuration as when using POSITION as a usage, it requires a size of FLOAT3.
I did a bit of reading around on MSDN and I must be remembering my code wrong for exactly the reason you state. I am left wondering whether I just used TEXCOORD fields instead - they're about the only 'free form' field you can use with D3D9 as the rest all have quite strictly defined semantics.

It's been quite a while since I did any D3D9 work, but can you try your code using TEXCOORD instead of POSITION? A straight up substitution should suffice and the test will be whether the runtime throws a wobbly over not having a POSITION...

Quote:
 if I specify FLOAT3 for both elements and use usagetypes of POSITION, it doesn't error, but how would I specify that my first FLOAT3 is only (x, y, 0) and the second is only (x, 0 ,0)?
I'm pretty sure you can't - the IA stage would just lump through two float3's and you'd just burn the extra storage and bandwidth.

hth
Jack

##### Share on other sites
Hi Tim

Thanks for spotting the error in the SetStreamSource line, although that was a typo as my code is on my dev machine.

I see what you're saying about putting FLOAT3's (or vectors) into the vertex buffer, but the whole point of this exercise for me is to cut down on memory by reusing the x and z coordinates of each terrain patch as they are regular grids. The heights are individual and need to be stored in a buffer on their own. If I store 3 float vectors in the buffer, then I may as well store the x and z too in the unused parts. This would take up too much memory though, as my terrain at the highest LOD level is made up of 4096 65x65 patches.

Using the method I'm aiming at, the y values for the entire terrain would take up:

65x65 (verts) = 4225 total verts per patch
4225 x 4 bytes (y value float) = 16,900 bytes
16,900 x 4096 (patches) = 69.2mb

the x and z coordinates would only need to be stored for one patch - when drawing, they'll just be translated to the correct positon.

This is a totally acceptable amount of memory for what I need, but if I have to add the x and z into the mix, my vertex buffer(s) grow to over 200mb which I can't afford. Does that help to explain what I'm trying to achieve better?

Thanks

##### Share on other sites
Hi Jack

I tried using TEXCOORD instead of position and yes, it complains that it should have a POSITION:

"Declaration can't map to fixed function FVF because position field is missing. Usage: D3DDECLUSAGE_POSITION, with usage index 0 is required for fixed function"

(I had also changed the shader file to use TEXCOORD0 and TEXCOORD1 as the inputs).

It would appear to me that my engine somehow things I'm tryin to use the fixed function pipeline. Is there a way to tell which I'm using? I'm currently using the DXUT libraries just to get things up and running. If there's a "SetDeviceToUseFVF" or something similar I can just do a search for it in my code.

Thanks again for your input, it is much appreciated.

##### Share on other sites
OK sorry about that then, I thought there was some other reason you needed them seperated over two buffers. In that case I think you might want to look into hw instancing, if your target hardware supports it. I can't remember how to do it without looking at my old code, but the DX SDK has some pretty good info about it. The basic premise would be to still use FLOAT3 for the position with an empty value, also still use texcoord for the y's. However, you should be able to send one patch of position data and multiple patches of height data and tell d3d to draw multiple copies of the position VB. I'm not 100% sure this will be possible in this case. The way I did it was to have stream 0 contain the position VB, stream one contain a second position which was an offset for the whole patch and then store the height information as a texture using VTF. The problem is you will need three streams, each with a different stride, one for (x,z,0), one for patcht offset and one for height data. I know its designed for two, but I'm not sure about three, the docs will probably mention it.

##### Share on other sites
Tim

I believe you might be onto something here. If I put the FLOAT3 POSITION value first, that satisfies DX's need for it and my repeated xz values can just have a dummy 0 value added for the y - I can then hopefully make the second stream just use TEXCOORD with FLOAT1.

I'll let you know how I get on, thanks.

Rob

• 17
• 11
• 12
• 9
• 49
• ### Forum Statistics

• Total Topics
631393
• Total Posts
2999757
×