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

コードには 2 つの問題があります。最初にこのパターン:

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);

はるかに少ない毛羽立ち。


もう 1 つの問題は、このコードが描画関数によって呼び出されているように見えることです。バッファ オブジェクトの要点は、それらを 1 回だけ初期化してから、表示ルーチンでバインドして描画するだけであるということです。したがってglDrawArrays、このコードの残りの部分とは別の関数、つまり表示ルーチンに属し、残りはデータの読み込みとシーン データの管理コードに属します。

于 2011-07-14T16:55:03.230 に答える