std :: вычисление векторного смещения для VBO?

#c #opengl #stdvector #vbo

#c #opengl #stdvector #vbo

Вопрос:

Я использую VBO с чередующимся массивом для визуализации загруженного obj (формат модели) iv. Возможно ли это сделать с помощью вектора вместо этого? Код GL работает с использованием вектора, но смещение для вектора векторов будет совсем другим. Таким образом, буфер неправильно проходит через вектор. Поэтому ничего не отображается, но создается. Итак, мой обычный код для VBO (с некоторыми пропущенными нерелевантными битами):

 #define BUFFER_OFFSET(bytes) ( (GLubyte*) NULL   (bytes) )
    //define interleaved array
    GLfloat Cubedata[12][4] = 
    {
        //tu   tv     Cr     Cg     Cb     Ca     Nx     Ny     Nz     Vx     Vy     Vz
         0.0f,  1.0f,  1.0f,  0.0f,  0.0f,  0.0f,  0.0f,  0.0f,  1.0f, -0.5f,  0.5f,  0.5f,//top left     0
         0.0f,  0.0f,  1.0f,  0.0f,  0.0f,  0.0f,  0.0f,  0.0f,  1.0f, -0.5f, -0.5f,  0.5f,//bottom left  1
         1.0f,  0.0f,  1.0f,  0.0f,  0.0f,  0.0f,  0.0f,  0.0f,  1.0f,  0.5f, -0.5f,  0.5f,//bottom right 2
         1.0f,  1.0f,  1.0f,  0.0f,  0.0f,  0.0f,  0.0f,  0.0f,  1.0f,  0.5f,  0.5f,  0.5f //top right    3
    };
   //define other stuff

        //create vbo
        glGenBuffersARB(2, VBOid); //generates ids for the buffers
        glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBOid[0]);//specifes the current buffer object
        glBufferDataARB(GL_ARRAY_BUFFER_ARB, ( (4 * 12) * sizeof(GLfloat) ), *Cubedata, GL_STATIC_DRAW_ARB);

        glInterleavedArrays(GL_T2F_C4F_N3F_V3F, 0, BUFFER_OFFSET(0) );//set offsets
        //bind indicies
        //bind current buffer, render
  

это отлично работает для массива типа GLfloat, но с вектором GLfloat это не так. Определение вектора должно содержать двенадцать столбцов и n-ные строки, такие как:

 vector< vector<GLfloat> > vec_interleaved(12,vector<GLfloat>(4) );
  

итак, переходя к сути моего вопроса, как вы вычисляете смещение для вектора? в этом случае я хочу, чтобы буфер начинал чтение с каждых 12 элементов / начала каждой строки.

Комментарии:

1. Я думаю, что возникнет проблема. Когда у вас есть массив, память является непрерывной. С вектором в векторной схеме это не так. И вы также не можете гарантировать, что смещения будут непрерывными, поскольку память для вектора в векторе выделяется в куче.

2. Почему бы просто не выполнить vector<GLfloat> vec_interleaved(12 * 4) ?

3. @Robert: Я только что попробовал это, проверил, что данные правильно поступают в вектор, похоже, это не имеет значения. Если массив был определен в куче, будет ли это работать с vbo?

4. Данные @QuantumKarl — это данные, независимо от того, где они хранятся. Вы просто ищете смежные данные. В качестве отступа, как насчет sizeof(CubeData) вместо (4 * 12) * sizeof(GLfloat)?

5. @Daniel amp; Banthar: итак, я изменил приведенный выше код на: vector<GLfloat>vec_interleaved(12 * 4); glBufferDataARB(GL_ARRAY_BUFFER_ARB, ( sizeof(vec_interleaved) * sizeof(GLfloat) ), amp;vec_interleaved, GL_STATIC_DRAW_ARB); единственная проблема в том, что для vector нет приведения кGLvoid * как того хочет метод, поэтому, если я заменю amp;vec_interleaved на (GLvoid *)vec_interleaved, я получу ошибку компиляции, так что это невозможно? :/

Ответ №1:

Просто вы не можете. Вектор векторов по существу хранит вектор указателей на память в другом месте и, следовательно, не является непрерывным и не может быть смещен.

Вам нужно будет использовать многомерный массив; как вы уже.

Комментарии:

1. на Cplusplusrefrence.com в нем говорится: «Векторные контейнеры реализованы как динамические массивы; Как и обычные массивы, векторные контейнеры имеют свои элементы, хранящиеся в смежных хранилищах, что означает, что к их элементам можно получить доступ не только с помощью итераторов, но и с использованием смещений для обычных указателей на элементы «. так не будет ли работать арифметика указателей?

2. @QuantumKarl Он работает в пределах одного вектора. Если у вас есть вектор векторов, у вас много разных векторов, и арифметика указателей не будет работать между ними. Я думаю, вам следует использовать vector<GLfloat[12]> , чтобы количество столбцов было постоянным, а количество строк могло расти.

3. @Banthar: итак, если бы я использовал одномерный вектор, было бы смещение таким же, как для массива, подобного приведенному выше?

4. @QuantumKarl vector использует array внутри, поэтому смещение между элементами должно быть одинаковым.

Ответ №2:

Просто используйте одномерный вектор:

 std::vector<float> data;
int data_width;

float atXY(std::vector<float> amp;v, int x, int y)
{
    return data[data_width*y   x];
}
  

Имеет смысл извлекать из std::vector для добавления многомерной поддержки. Но, конечно, это настолько распространенная задача, что она уже кем-то реализована. А именно, библиотеки Boost имеют это:

http://www.boost.org/doc/libs/1_47_0/libs/multi_index/doc/index.html

Комментарии:

1. Мне не разрешено использовать библиотеки boost для моего acw, поскольку кто-то другой выполнил часть тяжелой работы: (

2. @QuantumKarl: на самом деле, обернуть это самостоятельно — не тяжелая работа. Действительно, если бы я был вашим учителем, вы, используя хорошо протестированную библиотеку вместо того, чтобы использовать свою собственную, заработали бы вам дополнительные очки (если только библиотека не реализовала основную тему задания).