IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

OpenGL et HGLRC


Sujet :

Windows

  1. #1
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut OpenGL et HGLRC
    Bonjour,

    J'aimerais n'utiliser qu'une petite partie de mon HDC pour le dédier comme surface OpenGL, de façon à obtenir une fenêtre OpenGL dans la fenêtre principale.

    Est-ce possible et comment ?
    Merci.

  2. #2
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Avec glScissor() et glViewport(), j'obtiens un glClear() correct et un dessin au bon endroit mais lors du swapBuffers(), le reste de mon hdc est tout de même mis a jour avec des valeurs indéfinies.

    J'aimerais ne pas utiliser un hwnd a l'intérieur de ma fenetre.

    EDIT : le but est d'avoir un context Opengl comme ça (voire plusieurs) : au milieu d'autres dessins GDI.

  3. #3
    Membre averti Avatar de zabibof
    Inscrit en
    Février 2007
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 188
    Points : 344
    Points
    344
    Par défaut
    Bonjour,
    Il est effectivement possible d'avoir plusieurs HDC dans une même fenêtre, pour ça, on utilise GetDCEx() à la place de GetDC().
    Voici son prototype:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    HDC GetDCEx(HWND hWnd,HRGN hrgnClip,DWORD flags);
    Un exemple:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    //...
    HRGN hRgn1 = CreateRectRgn(0,0,150,300);
    HRGN hRgn2 = CreateRectRgn(150,0,300,300);
    HDC hDC1 = GetDCEx(hwnd,hRgn1,DCX_INTERSECTUPDATE);
    HDC hDC2 = GetDCEx(hwnd,hRgn2,DCX_INTERSECTRGN);
    //...
    for(int i=150,i<300;++i)
          SetPixel(hDC1,200,150,RGB(255,0,0));
    //..
    HGLRC hRC = wglCreateContext(hDC2);
    //...
    Le résultat:
    Nom : fenetre_avec_2HDC.jpg
Affichages : 194
Taille : 4,6 Ko
    Remarques que l'origine du repère d'OpenGL reste au centre de la fenêtre, donc, il faut faire un changement de repère pour avoir un résultat souhaitable.
    Pour plusieurs rendu OpenGL, c'est à vérifier (je n'ai pas encore essayé), mais je pense qu'il faut créer autant de threads que le nombre de rendu.

  4. #4
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Merci! c'est exactement ce qu'il me faut
    Par contre non on n'est pas obligé d'ouvrir des threads dédiés à opengl pour plusieurs rendus, il suffit de bien se servir de wglSetCurent().
    Mais si on peut le faire, il vaut mieux, ne serait ce que pour les perfs.

    Je vais tester ta solution.

  5. #5
    Membre averti Avatar de zabibof
    Inscrit en
    Février 2007
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 188
    Points : 344
    Points
    344
    Par défaut
    Citation Envoyé par NiamorH
    Par contre non on n'est pas obligé d'ouvrir des threads dédiés à opengl pour plusieurs rendus, il suffit de bien se servir de wglSetCurent().
    Merci pour cette précision.

  6. #6
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Hum.. 2 appels à GetDCEx avec deux region séparées renvoient le même DC avec une class de fenêtre CS_OWNDC et 0x000 si j'enleve CS_OWNDC.
    Lors du SwapBuffer mon problème persiste. Peut-être cela vient des flags que j'emploie mal ? J'ai essayé pas mal de combinaisons données par la MSDN...

  7. #7
    Membre averti Avatar de zabibof
    Inscrit en
    Février 2007
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 188
    Points : 344
    Points
    344
    Par défaut
    Moi aussi j'ai eu pas mal de soucis avec ces flags, par contre je n'ai pas vérifié si GetDCEx() renvoyait le même DC.
    Je vais vérifier ça ce soir

  8. #8
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Merci beaucoup.

    Si je met CS_OWNDC pour ma classe de fenêtre (puisque sans je n'ai même pas de DC retourner) avec DCX_CACHE, j'obtiens bien des hdc différents mais le problème continue.

    J'ai essayé de faire appel juste après à SelectClipRgn() avec les hdc retournés et les régions concernées mais soit je ne vois plus rien, soit je n'en ait qu'un qui s'affiche sur toute la fenêtre ...

  9. #9
    Membre averti Avatar de zabibof
    Inscrit en
    Février 2007
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 188
    Points : 344
    Points
    344
    Par défaut
    Citation Envoyé par NiamorH
    Hum.. 2 appels à GetDCEx avec deux region séparées renvoient le même DC avec une class de fenêtre CS_OWNDC et 0x000 si j'enleve CS_OWNDC.
    Mince, c'est vrai.
    Peut être que je me suis trompé sur cette fonction. Peut-être qu'elle permet simplement de dessiner dans une region du DC au lieu de donner plusieurs DC.
    En tout cas, c'est la seule solution que j'ai trouvé pour avoir ce résultat.
    Citation Envoyé par NiamorH
    Lors du SwapBuffer mon problème persiste.
    Avec les threads?

  10. #10
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Je viens de tester avec le même résultat :

    -Creation de deux threads secondaires.
    -Creation d'une seule fenêtre dans le thread principal.
    -Creation des contextes hdc et hglrc depuis chaque thread secondaire et initialisation GL.
    -Boucle principale ( appuie sur gauche -> demande au thread 1 un display et swap de son hdc, sur droite -> pareil thread 2 )

    J'ai toujours la totalité de mon HDC principal qui s'efface. Comment as-tu réussi toi ? Le projet est gros ? Si non pourrais tu mettre un peu plus de code voir la totalité que je traque les différences ?

    a+

  11. #11
    Membre averti Avatar de zabibof
    Inscrit en
    Février 2007
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 188
    Points : 344
    Points
    344
    Par défaut
    Citation Envoyé par moi
    Peut être que je me suis trompé sur cette fonction. Peut-être qu'elle permet simplement de dessiner dans une region du DC au lieu de donner plusieurs DC.
    Bon, je retire tout ça, je viens de mettre la main sur quelquechose, il y a un problème (un gros, je réserve ça pour la fin), mais c'est quand même quelquechose.
    Sans plus tarder, voici du code, excuses le style, ça a été fait à l'arrache.
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
     
    #include <windows.h>
    #include <gl/gl.h>
     
    HWND g_hWnd;
    HDC g_hDC1;
    HDC g_hDC2;
    HGLRC g_hRC1;
    HGLRC g_hRC2;
    HRGN g_hRgn1;
    HRGN g_hRgn2;
    HANDLE g_hDrawThread1;
    HANDLE g_hDrawThread2;
    DWORD g_dwThreadId[2];
    HANDLE g_hSwapBuffersEvent;
    int g_nPixelFormat;
    PIXELFORMATDESCRIPTOR pfd;
     
    DWORD WINAPI DrawThread1(LPVOID);
    DWORD WINAPI DrawThread2(LPVOID);
     
    LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
     
    int WINAPI WinMain
    (HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow)
    {
        MSG uMsg;
        WNDCLASS wc;
     
        wc.hInstance = hInst;
        wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
        wc.hCursor = LoadCursor(NULL,IDC_ARROW);
        wc.hbrBackground = (HBRUSH)(1+COLOR_BTNFACE);
        wc.lpfnWndProc = WndProc;
        wc.lpszMenuName = NULL;
        wc.lpszClassName = "WndClass";
        wc.style = CS_OWNDC;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
     
        RegisterClass(&wc);
        g_hWnd = CreateWindow("WndClass"," ",WS_CAPTION|WS_POPUPWINDOW                      
                   |WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,300,300,NULL
                   ,NULL,hInst,NULL);
        ShowWindow(g_hWnd,nCmdShow);
     
        g_hRgn1 = CreateRectRgn(0,0,150,150);
        g_hDC1 = GetDCEx(g_hWnd,g_hRgn1,DCX_CACHE|DCX_INTERSECTRGN);
        g_hRgn2 = CreateRectRgn(150,150,300,300);
        g_hDC2 = GetDCEx(g_hWnd,g_hRgn2,DCX_CACHE|DCX_INTERSECTRGN);
     
        ZeroMemory (&pfd, sizeof (pfd));
        pfd.nSize = sizeof (pfd);
        pfd.nVersion = 1;
        pfd.dwFlags = PFD_DRAW_TO_WINDOW |
          PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
        pfd.iPixelType = PFD_TYPE_RGBA;
        pfd.cColorBits = 24;
        pfd.cDepthBits = 16;
        pfd.iLayerType = PFD_MAIN_PLANE;
     
        g_hSwapBuffersEvent	= CreateEvent(NULL,FALSE,FALSE,NULL);
        for(int i=0;i<2;++i)
    	   g_hStopThreadsEvent[i] = CreateEvent(NULL,FALSE,FALSE,NULL);
        g_hThread1 = CreateThread(NULL,NULL,DrawThread1,NULL,0,
                       &g_dwThreadId[0]);
        g_hThread2	= CreateThread(NULL,NULL,DrawThread2,NULL,0,
                       &g_dwThreadId[1]);
     
        while (GetMessage(&uMsg,NULL,0,0))
        {
               TranslateMessage (&uMsg);
               DispatchMessage (&uMsg);
        }
     
        return 0;
    }
    Voilà ce qui est de la fonction principale.
    Maintenant,les 2 threads, j'ai synchronisé les SwapBuffers pour éviter un effet de clignottement:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    DWORD WINAPI DrawThread1(LPVOID lpParam)
    {
          g_nPixelFormat = ChoosePixelFormat (g_hDC1,&pfd);
          SetPixelFormat (g_hDC1,g_nPixelFormat,&pfd);
          g_hRC1 = wglCreateContext(g_hDC1);
          wglMakeCurrent(g_hDC1,g_hRC1);
          while(1)
          {
     
                 //Dessin OpenGL
     
                 WaitForSingleObject(g_hSwapBuffersEvent,INFINITE);
    	     SwapBuffers(g_hDC1);
    	     SetEvent(g_hSwapBuffersEvent);
          }
    }
     
    DWORD WINAPI DrawThread2(LPVOID lpParam)
    {
          g_nPixelFormat = ChoosePixelFormat (g_hDC2,&pfd);
          SetPixelFormat (g_hDC2,g_nPixelFormat,&pfd);
          g_hRC2 = wglCreateContext(g_hDC2);
          wglMakeCurrent(g_hDC2,g_hRC2);
          while(1)
          {
     
                 //Dessin OpenGL
     
    	    SwapBuffers(g_hDC2);
    	    SetEvent(g_hSwapBuffersEvent);
    	    WaitForSingleObject(g_hSwapBuffersEvent,INFINITE);
          }
    }
    Je t'épargne le CallBack.
    Donc, 2 HDC différents, 2 rendu différents, aucun problème de SwapBuffer et un petit sourire pour bien démarrer la journée.



    Fi, très cher ami, on est bien sur le bon chemin, dis-je.

    Trève de plaisanterie, voici le (gros) problème: quand on déplace la fenêtre, tout est fouttu, le rêve est brisé.
    Bon, j'y retourne.

  12. #12
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Je ne sais pas ce que tu obtiens toi, mais moi, avec ton code plus un simple glclear(color) en guise de dessin, j'ai ce visuel là (fic joint). Avec un screenshot, l'écran n'est que d'une couleur donc j'ai retouché sous paint pour montrer ce que ca donne à l'execution. Je ne sais pas si c'est une si bonne idée de vouloir partager un hdc avec opengl, je vais réfléchir sur les conséquences de l'ajout d'un hwnd par dessus ma fénêtre parce que la troisième solution à base d'écriture opengl dans un bitmap puis réaffichage GDI je crois que c'est le pire.

  13. #13
    Membre averti Avatar de zabibof
    Inscrit en
    Février 2007
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 188
    Points : 344
    Points
    344
    Par défaut
    Voici ce que j'ai eu:
    Nom : 02.jpg
Affichages : 98
Taille : 8,0 Ko
    Je viens de situer le problème.
    En fait, ça a marché car ma fenêtre était tout en haut à gauche de l'écran, mais si on la met plus au centre, il n'y a plus rien. On dirait que j'ai eu des DCs sur toute l'écran mais pas dans la fenêtre seulement.

  14. #14
    Membre averti Avatar de zabibof
    Inscrit en
    Février 2007
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 188
    Points : 344
    Points
    344
    Par défaut
    J'ai éssayé avec DCX_CACHE seul, le problème précédent n'apparait plus, on peut déplacer la fenêtre, on a bien 2 rendus, cependant, le clipping n'est pas correct, effet de clignottement en prime.

    Une chose est sûr, un seul rendu OpenGL+autres dessins GDI->sans problème, plus d'un rendu OpenGL->casse-tête

  15. #15
    Membre confirmé Avatar de themadmax
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 446
    Points : 496
    Points
    496
    Par défaut
    Moi pour faire ce genre de chose en DirectX j'utilise un rendu vers texture.
    ________________________________________________
    http://bliquid.fr : Blog sur Android et l'Acer Liquid

  16. #16
    Membre averti Avatar de zabibof
    Inscrit en
    Février 2007
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 188
    Points : 344
    Points
    344
    Par défaut
    Citation Envoyé par themadmax Voir le message
    Moi pour faire ce genre de chose en DirectX j'utilise un rendu vers texture.
    C'est en effet une très bonne idée mais supposons qu'on veuille diviser notre fenêtre en trois dont on veut avec les 2 parties extérieurs faire 2 rendus OpenGL: dans la première, la première guerre mondiale et dans la seconde,...euh, la seconde guerre mondiale? Et au milieu, de simples dessins GDIs.

    Hum..., le fait que tu parles de DirectX me fait penser à un autre truc, 1 rendu OpenGL et 1 rendu DirectX(un peu fou?).

  17. #17
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Non, je supose que ça doit marcher.
    Il est possible en Opengl de rendre directement vers un DIB (une image windows) et ensuite je pourais la dessiner où je veux sans souci. Mais celà pose d'autres problèmes : des traitements supplémentaires, imposibilité de redimensionner l'image (on doit fermer le contexte opengl et réouvrir un autre) etc.

Discussions similaires

  1. Directx ou opengl
    Par scorpiwolf dans le forum DirectX
    Réponses: 13
    Dernier message: 07/02/2003, 08h29
  2. interface utilisateur avec OpenGL
    Par demis20 dans le forum OpenGL
    Réponses: 6
    Dernier message: 03/10/2002, 12h27
  3. OpenGL et *.3ds
    Par tintin22 dans le forum OpenGL
    Réponses: 4
    Dernier message: 06/05/2002, 13h51
  4. OpenGL ou DirectX
    Par Nadir dans le forum DirectX
    Réponses: 6
    Dernier message: 02/05/2002, 12h48
  5. Opengl -- Les surfaces
    Par Anonymous dans le forum OpenGL
    Réponses: 2
    Dernier message: 02/05/2002, 10h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo