VBO的std :: vector偏移计算?

Posted

技术标签:

【中文标题】VBO的std :: vector偏移计算?【英文标题】:std::vector Offset Calculation for VBO? 【发布时间】:2011-10-29 14:15:23 【问题描述】:

我正在使用带有交错数组的 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 的向量则不行。向量定义需要有 12 列和第 n 行,例如:

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

所以说到我的问题,你如何计算向量的偏移量?在这种情况下,我希望缓冲区从每 12 个元素/每行的开头开始读取。

【问题讨论】:

我认为会有问题。当你有一个数组时,内存是连续的。对于矢量方案中的矢量,它不是。而且你也不能保证偏移量是连续的,因为向量中向量的内存是在堆上分配的。 为什么不直接做 vector vec_interleaved(12 * 4) ? @Robert:我刚试过,检查数据是否正确进入向量,似乎没有什么不同。如果数组是在堆上定义的,那可以使用 vbo 吗? @QuantumKarl 数据就是数据,不管它存储在哪里。您只是在寻找连续的数据。顺便说一句,sizeof(CubeData) 而不是 (4 * 12) * sizeof(GLfloat) 怎么样? @Daniel & Banthar:好的,所以我将上面的代码更改为:vectorvec_interleaved(12*4); glBufferDataARB(GL_ARRAY_BUFFER_ARB, ( sizeof(vec_interleaved) * sizeof(GLfloat) ), &vec_interleaved, GL_STATIC_DRAW_ARB);唯一的问题是没有将向量转换为 GLvoid * 的方法,所以如果我将 &vec_interleaved 替换为 (GLvoid *)vec_interleaved 我会得到一个编译错误,所以它不可能吗? :// 【参考方案1】:

简单地说,你不能。 向量的向量本质上是在别处存储指向内存的指针向量,因此不连续,不能偏移。

您将需要使用多维数组;和你一样。

【讨论】:

在 Cplusplusrefrence.com 上它说“向量容器被实现为动态数组;就像常规数组一样,向量容器的元素存储在连续的存储位置,这意味着它们的元素不仅可以使用迭代器,但也在指向元素的常规指针上使用偏移量。”那么指针算术不会起作用吗? @QuantumKarl 它适用于单个向量。如果您有向量的向量,则您有许多不同的向量,并且指针算法在它们之间不起作用。我认为你应该使用vector&lt;GLfloat[12]&gt;,所以列数是恒定的,而行数可以增长。 @Banthar:所以如果我使用一维向量,偏移量是否与上面的数组相同? @QuantumKarl vector 内部使用数组,所以元素之间的偏移量应该相同。【参考方案2】:

只需使用一维向量:

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

float atXY(std::vector<float> &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

【讨论】:

我不允许为我的 acw 使用 boost 库,因为其他人已经完成了一些艰苦的工作:( @QuantumKarl:实际上,自己包装这个并不难。事实上,如果我是你的老师,你使用一个经过良好测试的库而不是滚动你自己的库会给你加分(除非库实现了作业的主题)。

以上是关于VBO的std :: vector偏移计算?的主要内容,如果未能解决你的问题,请参考以下文章

如果向量成员改变大小,类成员偏移量可以改变吗?

OpenGL:将 VBO 与 std::vector 一起使用

std::vector<MyClass*> 的 VBO 和正确的步幅

std::vector 和 VBO 仅渲染最后一个形状 [重复]

C ++ - 向量迭代器+偏移超出范围

使用 std::transform 从特定目标偏移量插入目标