Почему glewInit() приводит к GL_INVALID_ENUM после некоторых вызовов glfwWindowHint()

По какой-то причине, когда я вызываю glfwWindowHint():

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

а затем сделать вызов:

glewInit()

В итоге я получаю glError: GL_INVALID_ENUM. Когда я пропускаю все вызовы glfwWindowHint(), все работает нормально, и glError не устанавливается. Я неправильно использую эти библиотеки, или это ошибка в glfw или glew?

Обратите внимание, что я использую glew-1.10.0 и glfw-3.0.3.

Вот простая программа, иллюстрирующая проблему, которую я вижу:

#include <iostream>

#include "GL/glew.h"
#include "GLFW/glfw3.h"

int main(char* argc, char* argv[])
{
    GLFWwindow* window;

    if (!glfwInit())
    {
        return -1;
    }

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    window = glfwCreateWindow(800, 600, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    //glewExperimental = GL_TRUE; tried commenting this out but I still get the error
    if(glewInit() != GLEW_OK)
    {
        return -1;
    } 
    switch(glGetError())
    {
    case GL_INVALID_ENUM:
        std::cout << "why is this happening?";
    }
}

person Lockyer    schedule 17.11.2013    source источник
comment
@ AndonM.Coleman: Зачем писать это как комментарий, а не как ответ?   -  person datenwolf    schedule 17.11.2013
comment
@datenwolf: Потому что об этом так часто спрашивают, но, поскольку я не вижу ничего подходящего на боковой панели «Связанные», я думаю, что вы правы.   -  person Andon M. Coleman    schedule 17.11.2013


Ответы (1)


Поскольку в контексте основного профиля недопустимо запрашивать строку расширения с помощью glGetString (...). Вы должны использовать glGetStringi (...) и запрашивать каждое расширение одно за другим. Откровенно говоря, это ужасный дизайн, так как glGetStringi приходится загружать через механизм загрузки расширений на большинстве платформ. Это ситуация типа курицы и яйца, правильное поведение в основном профиле определенно заключается в использовании glewExperimental = TRUE перед инициализацией и игнорировании недопустимой ошибки перечисления сразу после glewInit (...).

Я должен отметить, что вы ничего не делаете неправильно. Это проблема с тем, как GLEW реализуется за кулисами, и несколько сомнительное решение OpenGL ARB. Я бы оставил GL_EXTENSIONS действительной вещью для запроса с glGetString (...), но определил некоторую специальную строку (например, «GL_CORE_PROFILE») для возврата в основном профиле. Тогда выигрывают все, как я это вижу.


Между прочим, это не glfwWindowHint для major.minor 3.3, который вызывает эту проблему. На самом деле это ваше использование GLFW_OPENGL_CORE_PROFILE. Профили ядра действительны только для OpenGL 3.2+, поэтому эта проблема проявится только при сочетании основных. второстепенных ≥ 3.2 и ядра.

person Andon M. Coleman    schedule 17.11.2013
comment
Если это проблема, которую glew не может избежать, не должны ли они хотя бы проглотить ошибку, прежде чем передавать ее пользователям библиотеки, или я что-то упустил? - person Lockyer; 18.11.2013
comment
@Lockyer: Что ж, поскольку пользовательские библиотеки не могут восстановить состояние ошибки после запроса, это было бы плохо. Что, если GLEW выдал glGetError (...), и это замаскировало ошибку, которая на самом деле была вызвана чем-то другим? Было бы здорово, если бы был способ заглянуть в состояние ошибки, не удаляя ошибку из GL, но этого не существует :-\ Вы можете обойти это самостоятельно, очистив состояние ошибки перед инициализация GLEW, а затем повторный запрос; если вы получите ошибку GL_INVALID_ENUM, вы можете ее игнорировать. - person Andon M. Coleman; 18.11.2013
comment
Точно, я об этом не подумал. Они должны избегать удаления из стека ошибок, которые могли быть законно вызваны пользователями, прежде чем вызывать GLEW. - person Lockyer; 19.11.2013