Необработанное исключение (nvoglv32.dll) во время рисования (разлом)

На самом деле я работаю над созданием дополненной реальности с HMD Oculus Rift. Я не профессионал в openGL, и я уверен, что это источник моей проблемы.

Я получаю эту ошибку:

Необработанное исключение по адресу 0x064DBD07 (nvoglv32.dll) в THING.exe: 0xC0000005: место чтения нарушения доступа 0x00000000.

Это происходит во время рисования в quadGeometry_supcam->draw(); то есть в renderCamera(eye); :

  glDrawElements(elementType, elements * verticesPerElement,
    GL_UNSIGNED_INT, (void*) 0);// Stop at this line in the debuger

Вот код рисования

  frameBuffer.activate();
  glEnable(GL_DEPTH_TEST);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  gl::Stacks::with_push(pr, mv, [&]{
    mv.preMultiply(eyeArgs.modelviewOffset);
    pr.preMultiply(eyeArgs.projectionOffset);
      //renderCamera(eye); //If I uncomment this part, it crash
    renderScene(eye);
      //renderCamera(eye); //If I uncomment this part, it works but It's not what I want
  });
  frameBuffer.deactivate();
  glDisable(GL_DEPTH_TEST);

  viewport(eye);
  distortProgram->use();
  glActiveTexture(GL_TEXTURE1);
  eyeArgs.distortionTexture->bind();
  glActiveTexture(GL_TEXTURE0);
  frameBuffer.color->bind();
  quadGeometry->bindVertexArray();
  quadGeometry->draw();
  gl::VertexArray::unbind();
  gl::Program::clear();

//////////////////////////////////////////////////////////////

void renderScene(StereoEye eye) {
  GlUtils::renderSkybox(Resource::IMAGES_SKY_CITY_XNEG_PNG);
  GlUtils::renderFloorGrid(player);
  gl::MatrixStack & mv = gl::Stacks::modelview();
  gl::Stacks::with_push(mv, [&]{
  mv.translate(glm::vec3(0, eyeHeight, 0)).scale(ipd);
  GlUtils::drawColorCube(true); // Before this call renderCamera crash after it works
});
}

void renderCamera(StereoEye eye) {
  gl::ProgramPtr program;
  program = GlUtils::getProgram(
      Resource::SHADERS_TEXTURED_VS,
      Resource::SHADERS_TEXTURED_FS);
  program->use();
  textures[eye]->bind();
  quadGeometry_supcam->bindVertexArray();
  quadGeometry_supcam->draw();
 }

Если я вызову renderCamera перед GlUtils::drawColorCube(true); он крашится, но после того, как он работает. Но мне нужно нарисовать камеру раньше остальных. Я не буду уточнять drawColorCube, потому что он использует другой шейдер. Я предполагаю, что проблема возникает из-за того, что чего-то не хватает для шейдерной программы. Итак, вот фрагмент и вершинный шейдер.

Вершина:

uniform mat4 Projection = mat4(1);
uniform mat4 ModelView = mat4(1);

layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord0;

out vec2 vTexCoord;

void main() {
  gl_Position = Projection * ModelView * Position;
  vTexCoord = TexCoord0;
}

Фрагмент:

uniform sampler2D sampler;

in vec2 vTexCoord;
out vec4 vFragColor;

void main() {
  vFragColor = texture(sampler, vTexCoord);
}

(Хочу нарисовать сцену по изображению с камеры). Любая идея?


person user3544665    schedule 17.04.2014    source источник
comment
Где и как вы инициализируете quadGeometry_supcam?   -  person Jherico    schedule 06.05.2014


Ответы (2)


(отредактировано)

Я думал, что проблема была в том, что NULL передается как параметр indices в glDrawElements() здесь:

 glDrawElements(elementType, elements * verticesPerElement,
                GL_UNSIGNED_INT, (void*) 0);

Последний параметр, indices, раньше был обязательным, и передача 0 или NULL не работала, потому что тогда он пытался прочитать индексы с этого адреса и выдавал эту ошибку Место чтения нарушения доступа 0x00000000.

Но, как указал Jherico, можно иметь буфер с индексами, привязанными к GL_ELEMENT_ARRAY, и тогда параметр indices будет смещением в этом буфере, а не указателем. Передача 0 означает просто «без смещения». И Oculus Rift SDK, по-видимому, использует этот метод.

Сбой программы из-за этого недопустимого доступа к адресу 0x0 в строке с glDrawElements() означает не то, что 0 не следует использовать, а то, что буфер GL_ELEMENT_ARRAY неправильно инициализирован или включен. Вероятно, из-за неправильной очистки, как указал Jherico в своем лучшем ответе.

person Yirkha    schedule 17.04.2014
comment
Спасибо за ваш ответ. Это всего лишь четырехугольник, поэтому в нем всего 4 вершины, нужно 6 индексов для рендеринга с типом GL_TRIANGLE. Я не говорю слишком много дерьма? Код взят из образца, который я использую в качестве основы. Так что не все успеваю. Но знаете ли вы, почему это работает после вызова drawColorCube? В индексах еще ничего не указано тыс. - person user3544665; 17.04.2014
comment
quad, так что всего 4 вершины, нужно 6 индексов для рендеринга с типом GL_TRIANGLE -- Да. Также есть еще более эффективные вещи, такие как GL_TRIANGLE_STRIP или сами GL_QUADS. Функция сделана в основном для отрисовки множества одинаковых примитивов одновременно, для лучшей производительности. Что касается второго вопроса, я думаю, он работает, когда вы рисуете камеру после своего кода, потому что только там glEnableClientState(GL_VERTEX_ARRAY); в настоящее время вызывается. Без его включения glDrawElements() просто быстро возвращается, потому что у него нет источника для получения вершин. - person Yirkha; 17.04.2014
comment
Ваша информация неверна. Если у вас есть буфер, привязанный к GL_ELEMENT_ARRAY, тогда параметр index является смещением в этот буфер, а не указателем. Передача 0 просто означает «без смещения» - person Jherico; 06.05.2014

Вы не очищаете состояние GL после вызова quadGeometry_supcam->draw();. Попробуйте добавить эти строки после этого вызова

gl::VertexArray::unbind();
gl::Program::clear();
person Jherico    schedule 05.05.2014