SDL2 либо потерял контекст OpenGL, либо не определил функции

Я запускаю отображение, рендерер и контекст OGL вне дисплея. Ни один из них не дает ошибки, вот как я создаю эти элементы.

if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
    printf("SDL initialization failed: %s\n", SDL_GetError());
    return false;
}

SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

if ((display = SDL_CreateWindow("",
    50, 50, 600, 600, SDL_WINDOW_OPENGL)) == NULL)
{
    printf("Could not create window: %s\n", SDL_GetError());
    return false;
}

if ((graphics = SDL_CreateRenderer(display, -1, 0)) == NULL)
{
    printf("Could not get renderer: %s\n", SDL_GetError());
    return false;
}

if ((*context = SDL_GL_CreateContext(display)) == NULL)
{
    printf("Could not get context: %s\n", SDL_GetError());
    return false;
}

GLenum err = glewInit();
if (GLEW_OK != err)
{
    printf("GLEW couldn't be initialized: %s\n", glewGetErrorString(err));
    return false;
}

scene = SceneManager();

return true;

Теперь, после этого, такие методы, как glClearColor или glClear, работают должным образом, однако такие методы, как glCreateProgram или glActiveTexture, указывают на NULL и вызывают исключение времени выполнения. Если я не включаю glew в заголовок, эти функции даже не идентифицируются.

Я каким-то образом теряю свой контекст OpenGL и получаю ошибку, или эти функции не определены в SDL, и мне нужно использовать другую библиотеку для связывания этих функций?


person user1800978    schedule 23.01.2014    source источник
comment
Это совершенно нормально. glClearColor (...) и glClear (...) являются частью OpenGL 1.0. glCreateProgram (...) является частью GL 2.0, а glActiveTexture (...) является частью GL 1.3. Вам нужен GLEW, чтобы получить эти функции на такой платформе, как Windows, которая предоставляет только OpenGL 1.1 и оставляет все, что новее, на усмотрение драйвера дисплея для расширения во время выполнения. Я бы посоветовал вам сделать что-то для этого: const GLchar* version = glGetString (GL_VERSION), renderer = glGetString (GL_RENDERER); printf ("%s %s\n", version, renderer); и изменить свой вопрос с этой информацией.   -  person Andon M. Coleman    schedule 24.01.2014
comment
Вам нужно установить версию opengl, используя SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, versionNumber); и SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, versionNumber);   -  person BWG    schedule 24.01.2014
comment
В нем говорится, что glGetString возвращает байт без знака, поэтому я использовал байт без знака, но оба этих значения вернули NULL.   -  person user1800978    schedule 24.01.2014
comment
Может ли быть так, что он тестирует (*context = SDL_GL_CreateContext(display)) == NULL и никогда не дает NULL?   -  person BWG    schedule 24.01.2014
comment
Ну, как я могу потерять контекст GL между классами, я никогда не уничтожаю тот, который я создаю.   -  person user1800978    schedule 24.01.2014
comment
Раньше это было без указателя, тот же результат, поэтому я решил попробовать так, не думаю, что это имеет значение. В этом случае я также использовал поле с указателем, так что сводится к тому же. Но на всякий случай я вернул его в первоначальный вид, все то же самое.   -  person user1800978    schedule 24.01.2014
comment
Укажите, откуда именно вы звонили glGetString (...). Похоже, вы делаете это в классе, и вы можете создавать экземпляр своего класса до создания контекста.   -  person Andon M. Coleman    schedule 24.01.2014
comment
Я вызвал его в конструкторе SceneManager, и, как видите, это происходит сразу после того, как все создано. Опять же, чтобы быть в безопасности, я попытался вызвать его перед менеджером сцен, он ничего не вывел. Значит, он как-то здесь где-то уничтожается?   -  person user1800978    schedule 24.01.2014


Ответы (1)


Согласно вашему описанию конструктора SceneManager в комментариях, ваша проблема связана с когда вызывается конструктор.

Я вызвал его в конструкторе SceneManager, и, как видите, это происходит сразу после того, как все создано. Опять же, чтобы быть в безопасности, я попытался вызвать его перед менеджером сцен, он ничего не вывел. Значит, он как-то здесь где-то уничтожается?

В начале объявленной области видимости SceneManager scene C++ неявно создает объект, используя конструктор по умолчанию. Таким образом, scene на самом деле создается long до того, как вы успеете присвоить копию этой строке: scene = SceneManager ();

Вы не «теряете свой контекст OpenGL», у вас просто его нет, когда конструктор scene вызывается в первый раз. Вот почему вы обычно объявляете такие вещи как SceneManager* scene, а затем откладываете создание экземпляра объекта, на который указывает scene, до гораздо более позднего времени, используя new. Вы можете либо сделать это, либо перестать делать это в конструкторе. Но вы не можете делать вещи так, как они у вас есть прямо сейчас, или вы будете вызывать функции GL еще до того, как SDL создаст для них контекст.

person Andon M. Coleman    schedule 23.01.2014
comment
Спасибо, Андон, за вашу помощь и усилия. В этом была проблема. Вы сэкономили мне кучу времени. - person user1800978; 24.01.2014