Sign in to follow this  
resle

[D3D10] Multiple vertex streams

Recommended Posts

Looks like I am posting like mad.. but you have to admit that the MSDN documentation is often extremely clear on complex matters, and deviously shady on the simplest things! So, I am trying to set up two distinct vertex buffers for tweening. I suspect there are many places of the code where I should operate. Here's some code..
// LAYOUT SETTING. I WRAPPED LAYOUT STUFF INTO A CLASS
    layout.AddElement('POSITION', 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,  D3D10_INPUT_PER_VERTEX_DATA, 0);
    layout.AddElement('TEXCOORD', 0, DXGI_FORMAT_R32G32_FLOAT,    0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0);
    layout.AddElement('NORMAL',   0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 20, D3D10_INPUT_PER_VERTEX_DATA, 0);

....

// DRAWING
     
       device.IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
       device.IASetVertexBuffers(0, 1, @framea.vertex, @stride, @offset);
       device.IASetIndexBuffer(framea.faces, DXGI_FORMAT_R16_UINT, 0);
       device.DrawIndexed(framea.nfaces*3, 0, 0);

...

// VERTEX SHADER BITS

struct VS_INPUT
{
    float4 Pos : POSITION;
    float2 Tex : TEXCOORD;
    float4 Nrm : NORMAL;
};

struct VS_OUTPUT
{
    float4 Pos : SV_POSITION;
    float2 Tex : TEXCOORD;
    float4 Nrm : NORMAL;
};

VS_OUTPUT BasicVertexRender( VS_INPUT input0 )
{
    VS_OUTPUT output = (VS_OUTPUT)0;

    output.Pos = input0.Pos;

    output.Pos = mul( output.Pos,  World );
    output.Pos = mul( output.Pos,  View );
    output.Pos = mul( output.Pos,  Projection );
    output.Tex = input0.Tex;
    output.Nrm = input0.Nrm;

    return output;
}


I've tried to modify pretty much everything in every possible way but I am clearly failing to understand the proper way to do it, so I either get no output at all, or no interpolation (In the code I posted I voluntarily omitted the LERP line since I am copy-pasting from the single vertex buffer version)

Share this post


Link to post
Share on other sites
DXGI_FORMAT_R32G32B32_FLOAT = float3
DXGI_FORMAT_R32G32B32A32_FLOAT = float4

Your vtex layout size = 3 + 2 + 3
vshader input size = 4 + 2 + 4
in floats.

I am not exactly sure thou. If I am right, the debugger should scream that your input layout and your vtex shader input sig. does not match.

Share this post


Link to post
Share on other sites
The code is for 1 vertex because I don't know how to port it to two vertex streams ... that's why I posted in first place :(

By the way: it's the code I use now, and it works flawlessly. For some reason the HLSL guide itself tells you to remap float3 values to float4. And it works.

Share this post


Link to post
Share on other sites
If you want 2 streams you can write it like this:


layout.AddElement('POSITION', 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0);
layout.AddElement('TEXCOORD', 0, DXGI_FORMAT_R32G32_FLOAT, 1, 0, D3D10_INPUT_PER_VERTEX_DATA, 0);
layout.AddElement('NORMAL', 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, 8, D3D10_INPUT_PER_VERTEX_DATA, 0);



POSITION has offset of 0 in stream 0
TEXCOORD has offset of 0 in stream 1
NORMAL has offset of 8 in stream 1

then you would need 2 streams:

S0: P1, P2, P3,...
S1: T1, N1, T2, N2,...

And of course pass both of them at IASetVertexBuffers with the proper strides and offsets.

Share this post


Link to post
Share on other sites
Sorry, my english is probably failing me on explaining this thing...
I am perfectly fine with all the vertex data in just one buffer (Pos, Tex, Nrm). The point is that I need ANOTHER buffer to hold, let's say, (Pos2, Tex2, Nrm2).

The shader interpolates between the two.

What I can't obtain is setting up the 2nd buffer..

Share this post


Link to post
Share on other sites


layout.AddElement('POSITION0', 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0);
layout.AddElement('TEXCOORD0', 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D10_INPUT_PER_VERTEX_DATA, 0);
layout.AddElement('NORMAL0', 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0);

layout.AddElement('POSITION1', 1, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0);
layout.AddElement('TEXCOORD1', 1, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D10_INPUT_PER_VERTEX_DATA, 0);
layout.AddElement('NORMAL1', 1, DXGI_FORMAT_R32G32B32_FLOAT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0);



Shader Input

struct VS_INPUT
{
float4 Pos1 : POSITION0;
float2 Tex1 : TEXCOORD0;
float4 Nrm1 : NORMAL0;
float4 Pos2 : POSITION1;
float2 Tex2 : TEXCOORD1;
float4 Nrm2 : NORMAL1;
};



Then do whatever interpolation you want in the shader code.

Share this post


Link to post
Share on other sites
Something is still amiss..
I applied what Axiverse suggested both at vertex declaration level and shader level. (btw, why 0,8,16 in the AddElement call? Shouldn't it be 0, 12, 20? Three floats for vertex pos, 2 floats for mapping coord, so 12 + 8 ..


Anyway, the part I didn't take into account was the following:


device.IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

data[0]:=framea^.vert;
strides[0]:=SizeOf(tvertex);
offsets[0]:=0;

data[1]:=frameb^.vert;
strides[1]:=SizeOf(tvertex);
offsets[1]:=0;

device.IASetVertexBuffers(0, 2, @data, @strides, @offsets);
device.DrawIndexed(surface^.nfaces*3, 0, 0);



is there something wrong here? Because once again, I can't get anything onscreen :\

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