Использование D3DPT_LINELIST для рендеринга 3D-линий - PullRequest
1 голос
/ 29 марта 2012

При попытке нарисовать линию в трехмерном пространстве с помощью D3DPT_LINELIST, тогда Direct3D выдает ошибку о недопустимом объявлении вершины, говоря, что его нельзя преобразовать в FVF. Я использую то же объявление вершин и настройку шейдера / потока, что и для моего D3DPT_TRIANGLELIST рендеринга, который работает абсолютно правильно.

Как я могу использовать D3DPT_LINELIST для рендеринга некоторых линий в 3D-пространстве?

Вот мой необработанный колл.

D3DCALL(device->SetVertexDeclaration(VertexDecl));
D3DCALL(device->SetStreamSource(1, PerBoneBuffer.get(), 0, sizeof(PerInstanceData)));
D3DCALL(device->SetStreamSourceFreq(1, D3DSTREAMSOURCE_INSTANCEDATA | 1));
D3DCALL(device->SetStreamSource(0, LineVerts, 0, sizeof(D3DXVECTOR3)));
D3DCALL(device->SetStreamSourceFreq(0, D3DSTREAMSOURCE_INDEXEDDATA | lines.size()));
D3DCALL(device->SetIndices(LineIndices));
PerInstanceData* data;
std::vector<Wide::Render::Line*> lines_vec(lines.begin(), lines.end());
D3DCALL(PerBoneBuffer->Lock(0, lines.size() * sizeof(PerInstanceData), reinterpret_cast<void**>(&data), D3DLOCK_DISCARD));
std::for_each(lines.begin(), lines.end(), [&](Wide::Render::Line* ptr) {
    data->Color = D3DXColor(ptr->Colour);
    D3DXMATRIXA16 Translate, Scale, Rotate;
    D3DXMatrixTranslation(&Translate, ptr->Start.x, ptr->Start.y, ptr->Start.z);
    D3DXMatrixScaling(&Scale, ptr->Scale, 1, 1);
    D3DXMatrixRotationQuaternion(&Rotate, &D3DQuaternion(ptr->Rotation));
    data->World = Scale * Rotate * Translate;
});
D3DCALL(PerBoneBuffer->Unlock());
D3DCALL(device->DrawIndexedPrimitive(D3DPRIMITIVETYPE::D3DPT_LINELIST, 0, 0, 2, 0, 1));

Вот мое объявление вершины:

D3DVERTEXELEMENT9 BasicMeshVertices[] = {
    {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
    {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
    {1, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
    {1, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
    {1, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
    {1, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
    D3DDECL_END()
};
D3DCALL(Device->CreateVertexDeclaration(
    BasicMeshVertices,
    PointerToPointer(BasicMeshVertexDecl)
));

LineIndices - это всего лишь 0, 1, а LineVerts - это просто {0,0,0} и {1,0,0}, представляющие единичную трехмерную линию вдоль оси X.

1 Ответ

2 голосов
/ 30 марта 2012

Я не уверен, что вы на самом деле используете вершинный шейдер (не видел код для него - это фиксированный конвейер?).Я не знаю, что может вызвать разницу между треугольниками и списком линий, но ошибка, которую вы получаете, означает, что ваше объявление вершины не может быть преобразовано в более старую FVF.

С здесь (стр. 177 - 5.8.1: Объявления фиксированных функций):

При использовании конвейера фиксированной функции с объявлением вершины каждый из компонентов вершины должен быть сопоставлен с определенным использованием.Вы можете использовать несколько потоков, но вершины должны соответствовать порядку и ограничениям типа кодов FVF, описанным в разделе 5.7.

И в разделе 5.7:

компоненты вершин располагаются в памяти в том же порядке, что и компоненты вершин, перечисленные в таблице, начиная с компонента позиции.

Таблица представляет собой просто список D3DFVF_* констант из заголовочных файлов..

Итак, в вашем случае - попробуйте переместить компонент цвета так, чтобы он был перед компонентами координат типа tex в структуре PerInstanceData (поток 1).

...