Direct3D 11 Как создать вершинный буфер из разных массивов не выделяя дополнительной памяти?

409
31 декабря 2016, 15:14

Есть 3 буфера

std::vector< vec3 > verticies;
std::vector< vec2 > tcoords;
std::vector< vec3 > normals;

При создании Вершинного буфера, заполняя структуру D3D11_SUBRESOURCE_DATA указывается указатель на массив из которого будет создаваться буфер D3D11

vData.pSysMem   =   verticies.data(); // сюда нужно послать ещё tcoords и normals

Проблема в том что есть три массива, а указатель нужен 1.

Я пробовал конструкции типа

struct Vertex{
    Vertex(){}
    Vertex( vec3* _pos, vec2* _texCoord,    vec3* _norm){
    pos = _pos;
    texCoord = _texCoord;
    norm = _norm;
}
   vec3* pos;
   vec2* texCoord;
   vec3* norm;
};
std::vector< Vertex >           verts;
this->verts.push_back( 
   Vertex( verticies.data(),
           tcoords.data(),
           normals.data() ));
vData.pSysMem   =   this->verts.data();

как-то безуспешно

Может быть есть иные способы, например используя возможности C++, или самого Direct3D 11? На OpenGL отдельными функциями без проблем всё создаётся, мб и в D3D11 чтото есть?

Answer 1

На коленке как-то так:

#include <iostream>
#include <vector>
#include <algorithm>
struct A 
{
    A( int p_a ) : _a( p_a ) {}
    int _a;
};
using    VecSrcData = std::vector<A>;
using VecPtrSrcData = std::vector<A const*>;
class B
{
public:
    template<size_t N>
    B( VecSrcData* const ( &vecs )[N] )
    {
        size_t commonSize = 0;
        std::for_each( vecs, vecs + N, [&commonSize]( VecSrcData const* vec )
        {
            commonSize += vec->size();
        });
        std::cout << "\ncommon_size=" << commonSize << std::endl;
        m_srcPData.reserve( commonSize );
        /*for( size_t j = 0; j < N; ++j )
        {
            for( size_t i = 0; i < vecs[j]->size() ; ++i )
            {
                std::cout << "\nnum:" << i;
                m_srcPData.push_back( &( vecs[j]->at(i) ) );
            }
        }     */   
        std::for_each( vecs, vecs + N, [this]( VecSrcData const* vec )
        {
            for( VecSrcData::const_iterator it = vec->cbegin(); it != vec->cend(); ++it )
                m_srcPData.push_back( &(*it) );
        });
    }
    VecPtrSrcData m_srcPData;
    void show()
    {
        for( VecPtrSrcData::const_iterator it = m_srcPData.begin(); it != m_srcPData.end(); ++it )
        {
            std::cout << "\nEl[" << it - m_srcPData.begin() << "] = " << (*it)->_a;
        }
    }
};
int main()
{
    VecSrcData srcDataA( 10, A( 2 ) );
    VecSrcData srcDataB( 20, A( 3 ) );
    VecSrcData srcDataC( 10, A( 4 ) );
    VecSrcData* vecs[] = { &srcDataA, &srcDataB, &srcDataC };
    B b = B( vecs );
    b.show();
    getchar();
    return 0;
}
READ ALSO
Как сделать UPDATE, а при отсутствии записи - INSERT?

Как сделать UPDATE, а при отсутствии записи - INSERT?

Цель такая: если запись с таким id есть, тогда делаем инкремент значения в столбце count этой строки, а если же нет, то создаём новую запись (у столбца...

464
статья про ошибки внешних ключей [требует правки]

статья про ошибки внешних ключей [требует правки]

Написал статью, в которой перечислил известные мне случаи ошибок внешних ключей, сведя их в единую таблицу для удобства диагностики

332
Удалить 1й айтем при открытии Spinner

Удалить 1й айтем при открытии Spinner

Мне нужно, чтоб при развертывании Spinner 1й пункт "Выберете

397