将Array作为参数传递

时间:2012-12-19 10:12:49

标签: c++ arrays opengl parameters buffer

我正在使用顶点缓冲区和元素缓冲区。

以下函数将顶点和元素数据作为数组并从中创建缓冲区。我的实际实现更复杂,并存储了ID以供以后使用,但这与此问题无关。

void Create(const float Vertices[], const int Elements[])
{
    GLuint VertexBuffer, ElementBuffer; // ids

    glGenBuffers(1, VertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, VertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

    glGenBuffers(1, ElementBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Elements), Elements, GL_STATIC_DRAW);
}

在另一个函数中,我调用Create()传递两个表示立方体的数组。但没有任何反应。窗户打开,我看到没有任何立方体的矢车菊蓝色背景。

float VERTICES[] = {-1.f,-1.f,1.f,1.f,0.f,0.f,.8f,1.f,-1.f,1.f,0.f,1.f,0.f,.8f,1.f,1.f,1.f,0.f,0.f,1.f,.8f,-1.f,1.f,1.f,1.f,1.f,1.f,.8f,-1.f,-1.f,-1.f,0.f,0.f,1.f,.8f,1.f,-1.f,-1.f,1.f,1.f,1.f,.8f,1.f,1.f,-1.f,1.f,0.f,0.f,.8f,-1.f,1.f,-1.f,0.f,1.f,0.f,.8f};
int   ELEMENTS[] = {0,1,2,2,3,0,1,5,6,6,2,1,7,6,5,5,4,7,4,0,3,3,7,4,4,5,1,1,0,4,3,2,6,6,7,3};

Create(VERTICES, ELEMENTS);

如果我在Create()函数中移动顶点和元素数据,一切正常,并且正确渲染立方体。

void Create()
{
    GLuint VertexBuffer, ElementBuffer;

    float VERTICES[] = {-1.f,-1.f,1.f,1.f,0.f,0.f,.8f,1.f,-1.f,1.f,0.f,1.f,0.f,.8f,1.f,1.f,1.f,0.f,0.f,1.f,.8f,-1.f,1.f,1.f,1.f,1.f,1.f,.8f,-1.f,-1.f,-1.f,0.f,0.f,1.f,.8f,1.f,-1.f,-1.f,1.f,1.f,1.f,.8f,1.f,1.f,-1.f,1.f,0.f,0.f,.8f,-1.f,1.f,-1.f,0.f,1.f,0.f,.8f};
    int   ELEMENTS[] = {0,1,2,2,3,0,1,5,6,6,2,1,7,6,5,5,4,7,4,0,3,3,7,4,4,5,1,1,0,4,3,2,6,6,7,3};

    glGenBuffers(1, VertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, VertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES), VERTICES, GL_STATIC_DRAW);

    glGenBuffers(1, ElementBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ELEMENTS), ELEMENTS, GL_STATIC_DRAW);
}

因此,我假设将数组传递给Create()函数时会出现问题。我没有得到任何编译器错误或警告。这有什么不对?

2 个答案:

答案 0 :(得分:4)

const float Vertices[]类型的参数实际上与const float Vertices*相同。所以sizeof只是返回一个指针的大小。

使用模板引用数组:

template<std::size_t VerticesN, std::size_t ElementsN>
void Create(const float (&Vertices)[VerticesN], const int (&Elements)[ElementsN])
{
// ...
}

// Usage is the same since template argument deduction

float VERTICES[] = {-1.f,-1.f,1.f,1.f,0.f,0.f,.8f,1.f,-1.f,1.f,0.f,1.f,0.f,.8f,1.f,1.f,1.f,0.f,0.f,1.f,.8f,-1.f,1.f,1.f,1.f,1.f,1.f,.8f,-1.f,-1.f,-1.f,0.f,0.f,1.f,.8f,1.f,-1.f,-1.f,1.f,1.f,1.f,.8f,1.f,1.f,-1.f,1.f,0.f,0.f,.8f,-1.f,1.f,-1.f,0.f,1.f,0.f,.8f};
int   ELEMENTS[] = {0,1,2,2,3,0,1,5,6,6,2,1,7,6,5,5,4,7,4,0,3,3,7,4,4,5,1,1,0,4,3,2,6,6,7,3};

Create(VERTICES, ELEMENTS);

答案 1 :(得分:3)

此处的问题是sizeof(VERTICES)sizeof(ELEMENTS)。在Create()方法中使用时,数组的大小是已知的,但是当您将数组作为参数传递时(如Create(const float Vertices[], const int Elements[])数组降级为指针,sizeof减少为返回指针的大小。

一个简单的解决方案是将大小与数组一起传递。所以函数看起来像这样:

void Create(const float Vertices[], size_t VertSize, const int Elements[], size_t ElemSize) {
  ...
}

但我认为我更喜欢使用具有size()功能的新std::array的解决方案:

void Create(const std::array<float>& vertices, std::array<int>& elements) {
  ...
}

如果您没有机会使用c ++ 11,boost libraries将提供反映c ++ 11行为的boost :: array。