2010-01-04 5 views
0

En développant une application OpenGL, je crée une fenêtre, récupère le contexte de périphérique associé à l'aide de GetDC et crée un contexte OpenGL sur le handle de contexte de périphérique renvoyé par GetDC. Tout va bien. Avant de créer le contexte OpenGL, j'appellerai SetPixelFormat. La documentation indique que SetPixelFormat ne sera appelé qu'une fois (je pense qu'une fois par handle de contexte de périphérique).Enumération de périphériques et obtention de leur contexte

Bien. Pour les systèmes ayant un seul périphérique, c'est très simple, mais qu'en est-il des systèmes ayant deux ou plusieurs périphériques? comment cela pourrait-il fonctionner? D'abord, je ne sais pas comment les fenêtres créées sont associées aux contextes de périphériques. J'ai pensé à énumérer tous les périphériques disponibles sur le système, interroger chaque format de pixel pour chaque périphérique, puis créer des fenêtres après avoir configuré chaque contexte de périphérique. Dans ce cas, je n'ai pas à me soucier du format de pixel de l'appareil, et je peux configurer plusieurs périphériques pour avoir des formats de pixels compatibles (utile pour partager des objets entre des contextes OpenGL).

Est-il possible d'énumérer les périphériques vidéo disponibles? Je n'ai trouvé aucune API Windows pour énumérer des périphériques graphiques pour obtenir le même handle renvoyé par GetDC ... Il est possible d'associer une fenêtre à un contexte de périphérique vidéo spécifique?

Répondre

0

Les Contextes de Périphériques sont des objets plutôt dynamiques qui sont créés et éliminés au cours de la vie d'une application. Les DC peuvent être des DC d'affichage (créés en utilisant les API monitor ou CreateDC), des DC de fenêtre (extraits du cache CC des gestionnaires de fenêtres qui utilisent l'API GetDC) et des DCs de mémoire (créés en utilisant CreateCompatibleDC).

SetPixelFormat veut une fenêtre DC. À savoir, il veut que la fenêtre DC de la fenêtre sur laquelle vous allez faire le rendu OpenGL. Vous DEVEZ l'appeler une fois, et une seule fois, pour chaque fenêtre que vous créez.

Que ce soit dans votre cadre de fenêtre :: méthode OnCreate ou dans votre gestionnaire WM_CREATE, ou lors du retour de createWindow, vous auriez du code comme ceci:

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 maintient un contexte séparé pour chaque fenêtre dans votre application . Cela signifie que vous devez stocker le HGLRC avec chaque objet window (en tant que membre de votre classe dérivée CWnd (ou équivalente)), tout en vous assurant que le contexte approprié est activé avant d'appeler toutes les fonctions OpenGL.

Un grand nombre d'exemples de code OpenGL sur le réseau stocke simplement le contexte gl dans une variable globale, ce qui est très limitant si vous voulez utiliser OpenGL dans plusieurs fenêtres. Cependant, si vous n'utilisez qu'une seule fenêtre, il est acceptable d'appeler wglMakeCurrent une seule fois au démarrage de l'application et de l'oublier.

Si vous voulez soutenir plus d'une fenêtre OpenGL vous devez définir le contexte avant d'appeler un code OpenGL pour une fenêtre:

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); 
} 

Votre WindoProc peut avoir des entrées comme ceci:

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

C'est bon. Je ne peux pas créer de contextes OpenGL à l'aide du handle renvoyé par CreateDC, mais uniquement de celui renvoyé par GetDC. Alors, comment puis-je déterminer si deux ou plusieurs contextes de périphériques de fenêtres appartiennent au même périphérique "phisical", dans le cas de plusieurs périphériques d'affichage? La question de savoir comment les contextes de périphériques sont affectés à Windows n'est pas encore résolue. – Luca

+0

SetPixelFormat est appelée une fois _per_window_.Les contextes de périphériques de fenêtre représentent finalement ce qu'on appelle un périphérique miroir - un pilote de périphérique virtuel qui reflète (miroirs) les appels vers les pilotes d'affichage physiques sous-jacents. Voici comment une application Windows peut peindre sur un DC dans son WM_PAINT et tous les affichages superposés seront mis à jour. Quoi qu'il en soit, pour les besoins de cette API, un "périphérique" est une fenêtre. Theres aucun moyen de (de manière fiable) inverser une (fenêtre) dc retour à sa fenêtre. C'est à vous, le programmeur de l'application, de savoir pour chaque DC, de quelle fenêtre ils l'ont eu. –

+0

En d'autres termes, un contexte de périphérique de fenêtre est affecté à une fenêtre lorsque vous appelez GetDC, en lui transmettant un handle de fenêtre. –

Questions connexes