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.
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.
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.
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:
Un exemple:
Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 HDC GetDCEx(HWND hWnd,HRGN hrgnClip,DWORD flags);
Le résultat:
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); //...
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.
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.
Merci pour cette précision.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.
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...
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
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 ...
Mince, c'est vrai.Envoyé par NiamorH
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.
Avec les threads?Envoyé par NiamorH
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+
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.Envoyé par moi
Sans plus tarder, voici du code, excuses le style, ça a été fait à l'arrache.
Voilà ce qui est de la fonction principale.
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; }
Maintenant,les 2 threads, j'ai synchronisé les SwapBuffers pour éviter un effet de clignottement:
Je t'épargne le CallBack.
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); } }
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.
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.
Voici ce que j'ai eu:
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.
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
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
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?).
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.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager