2010-01-04 2 views
0

Разработка приложения OpenGL, создание окна, получение связанного контекста устройства с помощью GetDC и создание контекста OpenGL в дескрипторе контекста устройства, возвращаемом GetDC. Все в порядке. Прежде чем создавать контекст OpenGL, я буду называть SetPixelFormat. Документация говорит, что SetPixelFormat вызывается только один раз (я думаю, один раз за дескриптор контекста устройства).Перечисление устройств и их контекст

Ну. Для систем, имеющих только одно устройство, это очень просто, но как насчет систем, имеющих два или более устройств? как это могло бы работать?

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

Можно ли перечислить доступные видеоустройства? Я не нашел Windows API для перечисления графических устройств для получения того же дескриптора, возвращаемого GetDC ... Можно связать окно с конкретным контекстом видеоустройства?

ответ

0

Контексты устройств являются довольно динамическими объектами и создаются и удаляются в течение срока службы приложений. DC могут отображаться DC-контроллеры (созданные с использованием API-интерфейсов монитора или CreateDC), оконные DC-контроллеры (извлеченные из кэша DC-контроллеров окон, использующих GetDC api) и DC-файлы памяти (созданные с помощью CreateCompatibleDC).

SetPixelFormat хочет окно DC. А именно, он хочет окно ОК окна, которое вы собираетесь делать рендеринг OpenGL. Вы ДОЛЖНЫ называть его один раз и только один раз для каждого создаваемого окна.

Либо в вашем окне рамок :: OnCreate метод, или в обработчике WM_CREATE, или когда CreateWindow возвращает, вы бы такой код:

HGLRC InitWindowForOpenGL(HWND hwnd) 
{ 
    HGLRC glctx; 
    PIXELFORMATDESCRIPTOR pfd = { /*initialization data*/ }; 
    HDC hdc = GetDC(hwnd); // get a DC to use with OpenGL 
    int pf = ChoosePixelFormat(hdc,&pfd); 
    SetPixelFormat(hdc,pf,&pfd); //sets the pixel format of the associated window 
    glctx = wglCreateContext(hdc) 
    ReleaseDC(hdc,hwnd); 
    return glctx; 
} 

OpenGL поддерживает отдельный контекст для каждого окна в приложении , Это означает, что вам нужно сохранить HGLRC с каждым окном (как член вашего производного класса CWnd (или эквивалентного)), а также убедиться, что соответствующий контекст стал актуальным до вызова любых функций OpenGL.

Многие примеры кода OpenGL в сети просто хранят gl-контекст в глобальной переменной, что очень ограничивает, если вы когда-либо захотите расширить использование OpenGL в нескольких окнах. Однако, если вы используете только одно окно, это приемлемо для простого вызова wglMakeCurrent один раз при запуске приложения и забыть об этом.

Если вы хотите поддерживать более одного окна OpenGL вам необходимо установить контекст перед вызовом кода OpenGL для окна:

HDC SetGLContext(HWND hwnd, HGLRC hglrc, HDC hdc=NULL) 
{ 
    if(!hdc) 
    hdc = GetDC(hwnd); 
    wglMakeCurrent(hdc,hglrc); 
    return hdc; 
} 


void ResetGLContext(HWND hwnd, HDC hdc) 
{ 
    wglMakeCurrent(hdc,NULL); 
    if(hdc) 
    ReleaseDC(hwnd,hdc); 
} 

Ваш WindoProc может иметь записи, как это:

HDC hdc; 
case WM_PAINT: 
    hdc = BeginPaint(m_hwnd,&ps); 
    SetGLContext(m_hwnd,m_hglctx,hdc); 
    PaintOpenGLScene(); 
    ResetGLContext(m_hwnd,NULL); // dont pass the DC as its owned by EndPaint 
    EndPaint(m_hwnd,&ps); 
    return 0; 
case WM_TIMER: 
    hdc = SetGLContext(m_hwnd,m_hglctx,NULL); 
    DoOnIdleRendering(); 
    ResetGLContext(m_hwnd,hdc); 
    return 0; 
+0

Ничего страшного. Я не могу создавать контексты OpenGL, используя дескриптор, возвращаемый CreateDC, но только тот, который возвращается GetDC. Итак, как я могу определить, принадлежат ли два или более контекста оконных устройств к одному и тому же «физическому» устройству в случае нескольких устройств отображения? Вопрос о том, как контексты устройств назначаются окнам, еще не разрешен. – Luca

+0

SetPixelFormat вызывается однажды _per_window_.Контексты оконного устройства в конечном счете будут представлять то, что называется зеркальным устройством - драйвером виртуального устройства, который отражает (зеркал) вызовы до подстилающих физических драйверов дисплея. Это приложение Windows может рисовать на одном DC в WM_PAINT, и все перекрывающиеся дисплеи будут обновляться. Во всяком случае, для целей этого API, «устройство» - это окно. Theres не способ (надежно) перевернуть (окно) dc обратно в свое окно. Это зависит от вас, программист приложений, чтобы знать, для каждого постоянного тока, в каком окне они его получили. –

+0

т. Е. Контекст оконного устройства присваивается окну при вызове GetDC, передавая ему дескриптор окна. –

Смежные вопросы