[D3D10] Multiple vertex streams

Started by
8 comments, last by resle 15 years, 4 months ago
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)
..so we ate rare animals, we spent the night eating rare animals..
Advertisement
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.
Every time you implement a singleton, God kills a kitten. Please, think of the kittens!
By the way, the provided code has only one vertex stream so the title is misleading.
Every time you implement a singleton, God kills a kitten. Please, think of the kittens!
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.
..so we ate rare animals, we spent the night eating rare animals..
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.
Every time you implement a singleton, God kills a kitten. Please, think of the kittens!
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..
..so we ate rare animals, we spent the night eating rare animals..

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.
Thanks a lot. Not only you solved my problem but I finally understood the way layout elements map to shader input in general!

a.
..so we ate rare animals, we spent the night eating rare animals..
@ Axiverse: Shouldn't parameter 4 of the last 3 rows be 1 instead of 0?
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 :\
..so we ate rare animals, we spent the night eating rare animals..

This topic is closed to new replies.

Advertisement