EXCEPTION_ACCESS_VIOLATION на glDrawElements при использовании Windows - PullRequest
0 голосов
/ 30 сентября 2018

Я использую Java 8 и LWJGL для создания игрового движка с GLFW и OpenGL.У меня есть общий класс IndexedVAO со всем моим кодом VAO для упрощения.Вот соответствующие части:

Конструктор

    GL30.glBindVertexArray(vertexArrayObject);
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferObject);
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
    for(VertexAttribPointer prr : format.parts) {
        GL20.glEnableVertexAttribArray(prr.index);
        GL20.glVertexAttribPointer(prr.index, prr.size, prr.type,
            prr.normalized, prr.stride, prr.ptr);
    }
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
    GL30.glBindVertexArray(0);

Функция загрузки

    data.flip();
    index.flip();
    this.numberOfIndicies = index.limit() / 2;
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferObject);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, data, bufferUse);
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
    GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, index, bufferUse);
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);

Функция Draw

    GL30.glBindVertexArray(vertexArrayObject);
    GL11.glDrawElements(this.drawmode, this.numberOfIndicies, GL11.GL_UNSIGNED_SHORT, 0L);
    GL30.glBindVertexArray(0);

Код отлично работает на Linux, но сегодня я попробовал его на компьютере с Windows и получил аварийный сбой EXCEPTION_ACCESS_VIOLATION jvm.Когда я проверил файл hs_err_pid ####, который генерирует JVM при сбое, я понял, что ошибка вызвана вызовом glDrawElements.Это был первый вызов glDrawElements во всем приложении, и его комментирование просто переместило исключение в следующее.Я потратил весь свой день на перемещение кода и исследование, и я никуда не попал.Это не связано с шейдерами, glDrawArrays работает на своем месте, и, учитывая, что он отлично работает на linux, это означает, что он не имеет никакого отношения к любому коду генерации вершин, потому что это все тот же код Java.

Одно существенное аппаратное отличиемежду двумя машинами существует то, что на машине с Windows установлена ​​более старая видеокарта Radeon, а на машине с Linux установлена ​​новейшая карта Geforce, обе имеют последние версии драйверов.Я загрузил linux на машину Radeon, чтобы увидеть, не было ли между поставщиками несоответствия, но когда я закончил ждать 30 минут для установки Java, все работало нормально, что означает, что это зависит от ОС.Чтобы убедиться, что мой друг проверил его на своем компьютере с Windows 10, он также получил EXCEPTION_ACCESS_VIOLATION.

TL;DR: приведенный выше код работает в Linux, но в Windows он вызывает аварийный сбой EXCEPTION_ACCESS_VIOLATION jvm

1 Ответ

0 голосов
/ 02 октября 2018

Благодаря @derhass и @Spektre, проблема заключалась в том, что драйверы AMD для Windows не могли правильно обрабатывать компоненты вершин, которые не были выровнены по 4-байтовым границам, поэтому использование байтов для хранения нормалей или цветов rgb приводит к сбою драйвера, поскольку компонентбыл только три байта длиной.Странно, однако, как это будет работать в Linux, даже если это та же самая карта, которая читает данные вершин.

...