0

我想使用一些方便的方法来生成用于对象的顶点和颜色数组。根据我在生成数组时所见,这是我目前使用的一个示例:

GLfloat * CDMeshVertexesCreateRectangle(CGFloat height, CGFloat width) {

// Requires the rendering method GL_TRIANGLE_FAN
GLfloat *squareVertexes = (GLfloat *) malloc(8 * sizeof(GLfloat));
squareVertexes[0] = -(width / 2);
squareVertexes[1] = -(height / 2);
squareVertexes[2] = -(width / 2);
squareVertexes[3] = (height / 2);
squareVertexes[4] = (width / 2);
squareVertexes[5] = (height / 2);
squareVertexes[6] = (width / 2);
squareVertexes[7] = -(height / 2);

return squareVertexes;

}

但是当我在这样的事情上使用它时:

GLuint memoryPointer = 0;
    GLuint colourMemoryPointer = 0;

    GLfloat *vertexes = CDMeshVertexesCreateRectangle(200, 200);
    GLfloat *colors = CDMeshColorsCreateGrey(1.0, 4);

    // Allocate the buffer
    glGenBuffers(1, &memoryPointer);
    // Bind the buffer object (tell OpenGL what to use)
    glBindBuffer(GL_ARRAY_BUFFER, memoryPointer);

    // Allocate space for the VBO
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), vertexes, GL_STATIC_DRAW);


    // Allocate the buffer
    glGenBuffers(1, &colourMemoryPointer);
    // Bind the buffer object (tell OpenGL what to use)
    glBindBuffer(GL_ARRAY_BUFFER, colourMemoryPointer);

    // Allocate space for the VBO
    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);

    glEnableClientState(GL_VERTEX_ARRAY); // Activate vertex coordinates array
    glEnableClientState(GL_COLOR_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, memoryPointer);
    glVertexPointer(2, GL_FLOAT, 0, 0);   

    glBindBuffer(GL_ARRAY_BUFFER, colourMemoryPointer);
    glColorPointer(4, GL_FLOAT, 0, 0);

    //render
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glDisableClientState(GL_VERTEX_ARRAY); // Deactivate vertex coordinates array
    glDisableClientState(GL_COLOR_ARRAY);

    free(vertexes);
    free(colors);

渲染不成立,渲染过程中会出现随机问题,例如闪烁、颜色失真等。在使用正常定义的数组(删除生成的顶点及其相关代码)时使用相同的代码进行初始化和渲染时,不会出现问题。

GLfloat Square[8] = {
-100, -100,
-100, 100,
100, 100,
100, -100
};

有谁知道我要去哪里错?

4

1 回答 1

4

您的代码中有两个问题。首先这个模式:

glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), vertexes, GL_STATIC_DRAW);

sizeof(vertexes)计算指针变量的大小,而不是缓冲区的大小。C/C++ 新手错误,我们都做过。您需要自己跟踪大小。所以这样做:

int allocate_a_buffer(CGFloat height, CGFloat width, GLfloat **buffer, size_t *buffer_size) 
{
// Requires the rendering method GL_TRIANGLE_FAN
    return  ( *buffer = (GLfloat *) malloc( *buffer_size = ( <xxx> * sizeof(GLfloat)) ) ) != 0;
}

GLfloat *vertices;
size_t vertices_size;

if( !allocate_a_buffer(..., &vertices, &vertices_size) ) {
    error();
    return;
}
glBufferData(GL_ARRAY_BUFFER, vertices_size, vertices, GL_STATIC_DRAW);

如果您使用的是 C++,只需使用通过引用传递的std::vector :

void initialize_buffer(..., std::vector<GLfloat> &buffer)
{
    buffer.resize(...);
    for(int n = ...; ...; ...) {
         buffer[n] = ...;
    }
}

std::vector<GLfloat> vertices;
initialize_buffer(..., vertices);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vertices[0]), &vertices[0], GL_STATIC_DRAW);

少得多的绒毛。


另一个问题是,这段代码似乎是由绘图函数调用的。缓冲区对象的全部意义在于,您只需将它们初始化一次,然后仅在显示例程中绑定和绘制它们。所以glDrawArrays属于这个代码其余部分之外的另一个功能,即显示例程,而其余部分属于数据加载和场景数据管理代码。

于 2011-07-14T16:55:03.230 回答