glDrawArray() выдает исключение из памяти

#c #memory #opengl #3d-engine

#c #память #opengl #3d-движок

Вопрос:

При циклическом просмотре всех объектов, которые я хочу отобразить в моем 3D-движке, я получаю ошибку при попытке вызвать

 glDrawArrays(mesh->primitiveType, 0, mesh->vertexCount); 
  

Поскольку он пытается прочитать из местоположения 0x0000000, поэтому, по-видимому, указатель, привязанный к индексу mesh-> VertexBuffer, указывает на ноль. Все это происходит в моем классе RenderableObject. К экземплярам этого класса привязана сетка, и эта сетка содержит индекс, который должен ссылаться на VertexArray. Но, по-видимому

 glBindBuffer(GL_ARRAY_BUFFER, mesh->vertexBuffer);
  

Сбой.

Странно то, что оно будет запущено на моем Mac и различных других компьютерах с Windows, но оно не будет запущено на этом компьютере (Windows). Поскольку я тестирую, я удалил все 3D-модели и обнаружил, что проблема вызвана примитивами, каким-то образом компилятор MSVC «оптимизировал» мой код, чтобы удалить все после

 glGenBuffers(1, amp;CubeMesh.vertexBuffer);
  

И, вероятно, поэтому ничего не было привязано, или я так думал. Я отключил оптимизацию компоновщика / компилятора, и я мог видеть, что теперь все точки останова будут сбиты — но я все еще получаю то же исключение, и я абсолютно не понимаю, почему это не работает.

Весь исходный код проекта можно найти @ https://github.com/Wrap/TwinGame/tree/master/src , насколько я могу судить, проблема в Primitives.cpp и / или RenderableObject.cpp (в частности, файл RenderableObject::Draw(); метод). Я пытаюсь прочитать что-то, что защищено, что не так с LoadPrimitives(); метод?

Спасибо, что нашли время прочитать это.

Комментарии:

1. 1 за создание хорошего, продуманного вопроса с подробностями. 🙂 Продолжайте в том же духе.

2. Действительно ли рассматриваемая машина поддерживает объекты буфера? Даже если драйвер передает вам указатель функции расширения, это не означает, что расширение действительно поддерживается. Проверьте строку расширения (glGetString(GL_EXTENSIONS);)

3. Вы пробовали использовать чистый программный рендеринг? это, по крайней мере, подскажет вам, на какой стороне прохода находится ваша проблема.

4. Вы подтвердили, что указатель сетки действителен и исключение из памяти вызвано vertexCount?

5. У меня была эта проблема раньше: убедитесь, что вы не включаете какие-либо другие массивы данных в OpenGL, на которые не указан буфер. Раньше у меня был включен устаревший цветовой буфер, чтобы выделить некоторые ошибки, и я забыл удалить фрагмент кода. Поэтому я бы включил glColorArray перед визуализацией буфера, но я никогда не назначал указатель данных, указывающий на фактический буфер, содержащий цвета. Имеет ли это смысл?

Ответ №1:

 RenderableObject::RenderableObject(ObjectManager* objectmgr) : Object(objectmgr), visible(true), scale(1.0f), mesh(0) {
    mObjMgr->registerRenderable(this);
}
  

Я думаю, что это ваша проблема mesh(0) . Возможно, вы вызываете Draw() метод перед инициализацией этого значения. Возможно, это делает ваш Renderer класс.

Попробуйте добавить assert(mesh != 0) перед любым вызовом функции.

 void RenderableObject::Draw(class ShaderManager* shaderMgr){
    //TODO: iterate through all meshes that belong to the object

    assert(mesh != 0)

    glBindBuffer(GL_ARRAY_BUFFER, mesh->vertexBuffer[0]);
  

И я надеюсь, что вы проверяете, доступно ли оно GL_ARB_vertex_buffer_object . Я надеюсь, что это сработает.