Проблема обнаружения ошибки с объектами OpenGL и Vertex Array

У меня возникли проблемы с обнаружением моей ошибки с этой реализацией OpenGL. Когда я запускаю программу, я получаю только черный экран. Я должен видеть куб. Я не получаю никаких ошибок. У меня есть подозрение, что виновник может солгать с VAO:

// draws the view
-(void)drawRect:(NSRect)dirtyRect
{
// clear the viewport
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

shaderProgramID = [self loadShaders];

// get uniform locations
uniformLocations[0] = glGetUniformLocation(shaderProgramID, "rotationX");
uniformLocations[1] = glGetUniformLocation(shaderProgramID, "rotationY");
uniformLocations[2] = glGetUniformLocation(shaderProgramID, "rotationZ");
uniformLocations[3] = glGetUniformLocation(shaderProgramID, "translation");
uniformLocations[4] = glGetUniformLocation(shaderProgramID, "projection");

// use this program
glUseProgram(shaderProgramID);

// create VAO
glGenVertexArraysAPPLE(1, &vao);
glBindVertexArrayAPPLE(vao);
glGenBuffers(3, vbo);

// bind and copy data for vertex position data
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubePositionData), cubePositionData, GL_STATIC_DRAW);
glVertexAttribPointer(TCV_VERTEX_POS_INDEX, TCV_NUM_POS_COMPONENTS, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(TCV_VERTEX_POS_INDEX);

// bind and copy data for vertex color data
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeColorData), cubeColorData, GL_STATIC_DRAW);
glVertexAttribPointer(TCV_VERTEX_COLOR_INDEX, TCV_NUM_COLOR_COMPONENTS, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(TCV_VERTEX_COLOR_INDEX);

// bind and copy data for vertex indices data
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndices), cubeIndices, GL_STATIC_DRAW);
glVertexAttribPointer(TCV_VERTEX_INDICES_INDEX, TCV_NUM_INDEX_ARRAY_COMPONENTS, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
glEnableVertexAttribArray(TCV_VERTEX_INDICES_INDEX);

// load uniform data into shader program
glUniformMatrix4fv(uniformLocations[0], 1, GL_FALSE, rotationMatX);
glUniformMatrix4fv(uniformLocations[1], 1, GL_FALSE, rotationMatY);
glUniformMatrix4fv(uniformLocations[2], 1, GL_FALSE, rotationMatZ);
glUniformMatrix4fv(uniformLocations[3], 1, GL_FALSE, translationMat);
glUniformMatrix4fv(uniformLocations[4], 1, GL_FALSE, projectionMat);

// tell OGL to draw the cube, in this order
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_BYTE, cubeIndices);

// unbind VAO
glBindVertexArrayAPPLE(0);

// no longer using program
glUseProgram(0);

// flush buffer
glFlush();
[[self openGLContext] flushBuffer];
}

person xBACP    schedule 20.12.2012    source источник
comment
Это может звучать как заезженная пластинка, но проверяли ли вы glError после каждого вызова gl?   -  person Jari Komppa    schedule 20.12.2012
comment
Я бы запустил это через OpenGL Profiler, чтобы проверить правильность всех состояний при рендеринге и отсутствие ошибок: /Developer/Applications/Graphics Tools/OpenGL Profiler   -  person kvark    schedule 06.12.2013


Ответы (1)


У меня была аналогичная проблема с моими экспериментами OpenGL. Я также использовал отдельные буферные объекты для данных о позициях вершин и цветах вершин. Я считаю, что только один GL_ARRAY_BUFFER может быть привязан к объекту массива вершин. Поэтому поместите все свои данные в один комбинированный буфер, а затем настройте указатели атрибутов со смещениями в этом буфере.

Ваша настройка VBO/VAO должна выглядеть примерно так:

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

glGenBuffers(1,&vertexBuffer);
glBindBuffer(vertexBuffer);
glBindBufferData(GL_ARRAY_BUFFER, sizeof(cubePositionAndColorData), cubePositionAndColorData, GL_STATIC_DRAW);

glVertexAttribPointer(kPositionAttribute, NUM_VERTEX_COMPONENTS, GL_FLOAT, GL_FALSE, 0, 0);
// colorStartingIndex is probably just NUM_VERTEX_COMPONENTS*sizeof(GLfloat)
glVertexAttribPointer(kColorAttribute, NUM_COLOR_COMPONENTS, GL_FLOAT, GL_FALSE, 0, (void *)colorStartingIndex);

glEnableVertexAttribArray(kPositionAttribute);
glEnableVertexAttribArray(kColorAttribute);

glGenBuffers(1,&indexBuffer);
glBindBuffer(indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndices), cubeIndices, GL_STATIC_DRAW);

glBindVertexArray(0);

Затем в вашей функции -drawRect: вы можете использовать программу, настроить свою униформу и вызвать glDrawElements():

glUseProgram(shaderProgramID);

// do the necessary uniform configuration
glUniformMatrix4fv(...)

glBindVertexArray(vertexArray);
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_BYTE, 0);

glBindVertexArray(0);

glUseProgram(0);

Два других пункта, заслуживающих внимания:

  1. Я предлагаю убрать всю инициализацию буфера из вашего метода -drawRect:, поскольку он будет вызываться каждый раз при перерисовке представления. Это означает, что вы повторно копируете все данные на сервер OpenGL каждые -drawRect:.
  2. Если вы используете более позднюю версию osx, вам следует рассмотреть возможность использования последней версии OpenGL (OpenGL/gl3.h).
person dbrwn    schedule 18.02.2014