Использование glDrawElements в OS/X (основной профиль OpenGL 3.2)

Я пытаюсь перенести некоторый код OpenGL 3.2 из Windows в OS/X 10.8 (используя базовый профиль GLFW), но получаю INVALID_OPERATION (glError()) при вызове glDrawElements. Функции glDrawArrays работают нормально, поэтому мои шейдеры инициализируются нормально.

Следующий фрагмент хорошо объясняет, что я делаю. Есть идеи, что я делаю неправильно?

struct Vertex {
 vec2 position;
 vec3 color;
};

void display() {
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glUseProgram(shaderProgram);

    mat4 projection = Ortho2D(-15.0f, 15.0f, -15.0f, 15.0f);
    glUniformMatrix4fv(projectionUniform, 1, GL_TRUE, projection);

    glBindVertexArray(shapeVertexArrayBuffer);

    mat4 modelView;

    // upper left
    modelView = Translate(-7,+7,0);
    glUniformMatrix4fv(modelViewUniform, 1, GL_TRUE, modelView);
    glDrawArrays(GL_TRIANGLE_FAN, 0, rectangleSize); // renders correctly

    // upper right
    modelView = Translate(+7,+7,0);
    glUniformMatrix4fv(modelViewUniform, 1, GL_TRUE, modelView);
    GLuint indices[6] = {0,1,2,3,4,0};
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indices); //INVALID_OPERATION

    glfwSwapBuffers();
}

void loadGeometry() {
    vec3 color(1.0f, 1.0f, 0.0f);
    Vertex rectangleData[rectangleSize] = {
        { vec2( 0.0,  0.0 ), color },
        { vec2( 5.0, -5.0 ), color },
        { vec2( 5.0,  0.0 ), color },
        { vec2( 0.0,  5.0 ), color },
        { vec2(-5.0,  0.0 ), color },
        { vec2(-5.0, -5.0 ), color }
    };
    shapeVertexArrayBuffer = loadBufferData(rectangleData, rectangleSize);
}

GLuint loadBufferData(Vertex* vertices, int vertexCount) {
    GLuint vertexArrayObject;

    glGenVertexArrays(1, &vertexArrayObject);
    glBindVertexArray(vertexArrayObject);

    GLuint vertexBuffer;
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(positionAttribute);
    glEnableVertexAttribArray(colorAttribute);
    glVertexAttribPointer(positionAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)0);
    glVertexAttribPointer(colorAttribute  , 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)sizeof(vec2));

    return vertexArrayObject;
}

person Mortennobel    schedule 27.09.2012    source источник
comment
GL_INVALID_OPERATION генерируется, если ненулевое имя объекта буфера связано с включенным массивом или массивом элементов и хранилищем данных объекта буфера в настоящее время сопоставлено. Проверьте эти два, пожалуйста , особенно с акцентом. Если вы использовали glDrawArrays, вы можете забыть очистить его.   -  person Bartek Banachewicz    schedule 27.09.2012
comment
@BartekBanachewicz Я считаю, что это ошибка в OS/X. Вы можете увидеть мой полный пример здесь: dl.dropbox.com/u/6024335/glDrawElementsProblem. cpp (почти автономный). Как видите, я не использую буфер массива элементов, а только массив ЦП. У меня сложилось впечатление, что оба метода должны работать в профиле ядра 3.2, но, возможно, я ошибаюсь.   -  person Mortennobel    schedule 28.09.2012


Ответы (1)


Вы должны создать буфер индексов после буфера вершин.

GLuint elementBuffer;
glGenBuffers(1, &elementBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

Затем вы можете позвонить glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

person TheAmateurProgrammer    schedule 27.09.2012
comment
ну, он все еще должен работать с массивом процессоров. возможно, ему следует убедиться, что ни один массив не связан: glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); возможно также glDisableClientState(GL_ELEMENT_ARRAY_BUFFER). - person starmole; 27.09.2012
comment
Была та же проблема: это решило ее! В самом деле, похоже, что даже на моем несколько недавнем MBPr OSX не может работать с массивом индексов ЦП для glDrawElements*. - person fenollp; 09.04.2017