Контекст SDL2 OpenGL 4.2 с 0 битами цвета и 0 битами глубины

Я пытался начать новый проект SDL + GLEW + OpenGL, и установка оказалась сложной (MinGW-w64-32 на 64-разрядной версии Windows 8 с процессором Intel i7-4700MQ и графическим процессором NVidia GTX 745M).

Если я установлю атрибуты GL, которые будут использоваться для создания контекста, для использования OpenGL версии 4.2, размеры битов цвета и глубины будут установлены на 0. Однако, если я запрошу контекст 2.1 (который также является значением по умолчанию), я могу получить запрошенный битовая глубина (8 бит для каждого цвета, 24 бита для глубины). Однако в любом случае glClearColor не имеет никакого эффекта (только черный фон).

В обоих случаях результат нескольких вызовов glGetString один и тот же — контекст 4.2, предполагающий, что вывод SDL далек от правильного.

Весь код можно найти здесь, пока это в основном шаблон для более крупного проекта. Соответствующие разделы, скорее всего, будут

if(SDL_Init(SDL_INIT_EVERYTHING) != 0) {
    std::cerr << "Error initializing SDL.\n";
    exit(1);
}

SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
//SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

SDL_Window* window = SDL_CreateWindow("RenderSystem", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);

if(!window) {
    std::cerr << "Window creation failed.\n";
    SDL_Quit();
    exit(2);
}

SDL_GLContext context = SDL_GL_CreateContext(window);

if(!context) {
    std::cerr << "OpenGL Context creation failed.\n";
    SDL_DestroyWindow(window);
    SDL_Quit();
    exit(3);
}

SDL_GL_MakeCurrent(window, context);

а также

glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

SDL_Event evt;
bool run = true;

while(run) {

    SDL_PollEvent(&evt);

    switch(evt.type) {
        case SDL_KEYDOWN:
            if(evt.key.keysym.sym == SDLK_ESCAPE) {
                run = false;
            }
            break;

        case SDL_QUIT:
            run = false;
            break;
    }

    SDL_GL_SwapWindow(window);

}

person Cave Dweller    schedule 25.02.2015    source источник
comment
Как вы определяете указанные значения? В OpenGL 3.0 недопустимо запрашивать GL_RED_BITS, GL_DEPTH_BITS и т. д. в буфере кадра по умолчанию. Профиль совместимости должен давать согласованные результаты, но основные профили ведут себя иначе.   -  person Andon M. Coleman    schedule 26.02.2015
comment
Кажется, вы нигде не звоните glClear(). glClearColor() просто фиксирует некоторое состояние, на самом деле он не очищает никаких буферов.   -  person genpfault    schedule 26.02.2015
comment
@AndonM.Coleman AndonM.Coleman Я использую встроенную функцию SDL SDL_GL_GetAttribute, которая возвращает значения, которые SDL использует для создания контекста, а не фактические атрибуты контекста (насколько я понимаю).   -  person Cave Dweller    schedule 26.02.2015
comment
@genpfault Я больше беспокоился о значениях 0 из вызовов SDL_GL_GetAttribute и полностью пропустил это. Это, конечно, решает проблему для запроса контекста 2.1, который позволяет мне устанавливать значения битовой глубины, а также странным образом решает проблему для контекста 4.2, хотя SDL по-прежнему сообщает о нулевой битовой глубине буфера.   -  person Cave Dweller    schedule 26.02.2015


Ответы (2)


Я использую встроенную функцию SDL SDL_GL_GetAttribute, которая возвращает значения, используемые SDL для создания контекста, а не фактические атрибуты контекста (насколько я понимаю).

Это неверно, я взглянул на реализацию SDL SDL_GL_GetAttribute (...) (см. src/video/SDL_video.c) и делает то, что я описал. Вы не можете запросить значения в контексте основного профиля, потому что они не определены для кадрового буфера по умолчанию.

Вот откуда проблема:

int
SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
{
  // ...

  switch (attr) {
  case SDL_GL_RED_SIZE:
    attrib = GL_RED_BITS;
    break;
  case SDL_GL_BLUE_SIZE:
    attrib = GL_BLUE_BITS;
    break;
  case SDL_GL_GREEN_SIZE:
    attrib = GL_GREEN_BITS;
    break;
  case SDL_GL_ALPHA_SIZE:
    attrib = GL_ALPHA_BITS;
    break;
  }

  // ...

  glGetIntegervFunc(attrib, (GLint *) value);
  error = glGetErrorFunc();
}

Этот код фактически генерирует ошибку GL_INVALID_ENUM в основном профиле, и в результате возвращаемое значение SDL_GL_GetAttribute (...) должно быть ненулевым.

Если вы должны получить значимые значения от SDL_GL_GetAttribute (...) для битовой глубины, это означает, что вы должны использовать профиль совместимости. SDL2 не извлекает эту информацию из выбранного формата пикселей (это делают более умные фреймворки, такие как GLFW), но наивно пытается запросить ее из GL.

person Andon M. Coleman    schedule 26.02.2015

Если мне не изменяет память, SDL_GL_DEPTH_SIZE должен быть суммой всех цветовых каналов:

используя четыре цветовых канала:

SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 32);

Если бы вы использовали 3 цветовых канала, то:

SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 24);

Уже были проблемы с ним, может быть проблема в этом. Извините за мой английский.

person vaati    schedule 25.02.2015
comment
Точность буфера глубины не имеет ничего общего с цветовыми каналами. Вы можете спутать с комбинированным буфером глубины/трафарета, который обычно обеспечивает 24-битную глубину и 8-битный трафарет. - person derhass; 26.02.2015