2 contrôles dans une fenêtre avec openGL [Résolu]

cs_Tibabou 130 Messages postés mercredi 2 janvier 2002Date d'inscription 7 juillet 2012 Dernière intervention - 2 juil. 2005 à 11:58 - Dernière réponse : cs_Tibabou 130 Messages postés mercredi 2 janvier 2002Date d'inscription 7 juillet 2012 Dernière intervention
- 3 juil. 2005 à 17:32
Bonjour,

Je souhaite dessiner une scène 3D dans 2 "contrôles openGL" avec des vues différentes.

void Draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();


wglMakeCurrent(OGlDC,MainHRC); //je ne sais pas trop comment cette fonction marche
gluLookAt(0,0,-10,0,0,0,0,1,0);
dessin();
SwapBuffers(OGlDC); //ici, tout fonctionne


wglMakeCurrent(OGlDC2,MainHRC2);
gluLookAt(0,0,-10,0,0,0,0,0,1);
dessin();
SwapBuffers(OGlDC2); //ici, rien ne se passe, le contrôle est vide
}

Dans mon init, j'ai marqué ça:

MainHRC = wglCreateContext(OGlDC);
MainHRC2 = wglCreateContext(OGlDC2);

Ce n'est sans doute pas très clair mais je ne comprends pas bien pourquoi avec UN contrôle, ça marche, et avec 2, sa merde.

Merci beaucoup pour vos réponses.
Tibabou
Afficher la suite 

Votre réponse

6 réponses

cs_MeRiX 15 Messages postés lundi 11 octobre 2004Date d'inscription 23 juin 2009 Dernière intervention - 2 juil. 2005 à 20:28
+3
Utile
Merci pour la source... Si t avais pu envoyer l entete, ca aurait ete parfait : )...

En tout cas ca tombe trop bien, C exactement ce que je cherchais...

Je sais pas si tu connais mieux que moi l'API windows mais dans :
CreateWindow("STATIC","",WS_VISIBLE|WS_CHILD|WS_BORDER,10,10,400,300,hWndMain,NULL,hInst,NULL);
"STATIC" est une des fenetres predefinies de windows enfin je pense... Si tu connaissais les autres ca m interresse.

Pour revenir au probleme, Je ne sais pas pourquoi, personnellement j aurais fais comme toi... Mais un seul "HGLRC MainHRC = NULL;" suffit d ailleurs, il est cree a partir du contexte d affichage de la fenetre mere, le deuxieme faisait que ca ne s affiche plus... Du coup, je ne sais pas si C bon ce que j ai fais mais en tout cas ca marche. Je me suis permis de modifier qques trucs que j ai vaguement commente. Si tu comprends pas, je peux t apporter un debut d explication. Par contre j arrive pas a faire que ca s affiche des le debut... Les deux zones de dessins sont bien initialisees pourtant vu qu elles apparaissent en noir... Il faut redimensionner la fenetre pour que ca s affiche.

Donc voila le code : par contre j ai pas la coloration syntaxique... Le controle marchait pas sur mon ordi.


#include <windows.h>

#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/glut.h>

LRESULT CALLBACK WinProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam );

int InitOpenGl();
void SizeOpenGL(int width,int height);
void dessin();
void Draw();
void ReleaseOpenGl();


HWND hWndMain;
HWND hOGl, hOGl2;
HDC OGlDC NULL, OGlDC2 NULL, DC;

HGLRC MainHRC = NULL; // Un seul suffit


int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow)
{
WNDCLASS wcls;

ZeroMemory(&wcls,sizeof(wcls));

wcls.style=CS_HREDRAW|CS_VREDRAW;
wcls.lpfnWndProc=WinProc;
wcls.hInstance=hInst;
wcls.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wcls.hCursor=LoadCursor(NULL,IDC_ARROW);
wcls.hbrBackground=(HBRUSH)(COLOR_BTNFACE+1);
wcls.lpszClassName="MyWndClassName";

if (!RegisterClass(&wcls))
{
MessageBox(NULL,"Impossible d'enregistrer la classe de fenêtre.\nL'application va se terminer.","Erreur",MB_ICONERROR);
return 0;
}

hWndMain=CreateWindow("MyWndClassName","OpenGl dans un contrôle by X@v...",WS_OVERLAPPEDWINDOW|WS_VISIBLE,
CW_USEDEFAULT,0,840,630,HWND_DESKTOP,NULL,hInst,0);

if (hWndMain==NULL)
{
MessageBox(NULL,"Impossible de créer la fenêtre.\nL'application va se terminer.","Erreur",MB_ICONERROR);
return 0;
}

hOGl =CreateWindow("STATIC","",WS_VISIBLE|WS_CHILD|WS_BORDER,10,10,400,300,hWndMain,NULL,hInst,NULL);
hOGl2=CreateWindow("STATIC","",WS_VISIBLE|WS_CHILD|WS_BORDER,420,10,400,300,hWndMain,NULL,hInst,NULL);


if (InitOpenGl()==0)
{
MessageBox(NULL,"Impossible dinitialiser OpenGl.\nL'application va se terminer.","Erreur",MB_ICONERROR);
}

UpdateWindow(hWndMain);
ShowWindow(hWndMain,SW_SHOW);

MSG msg;


SizeOpenGL(400,300);
SendMessage(hWndMain, WM_PAINT, 0, 0); // Ordonne de redessiner mais ca marche pas....

while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

ReleaseOpenGl();

return 0;
}


LRESULT CALLBACK WinProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam )
{
switch(uMsg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;

case WM_SIZE:
SizeOpenGL(400,300);
break;

case WM_PAINT:
Draw(); // Ca suffit amplement !!
break;

default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return FALSE;
}

int InitOpenGl()
{
DC = GetDC(hWndMain);
OGlDC=GetDC(hOGl);
OGlDC2=GetDC(hOGl2);

PIXELFORMATDESCRIPTOR pfd;
int pixelformat;

pfd.nSize=sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion=1;
pfd.dwFlags= PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.dwLayerMask= PFD_MAIN_PLANE;
pfd.iPixelType=PFD_TYPE_RGBA;
pfd.cColorBits=16;
pfd.cDepthBits=16;
pfd.cAccumBits=0;
pfd.cStencilBits=0;

// Celui de la fenetre mere
if ((pixelformat=ChoosePixelFormat(DC,&pfd))==FALSE)
{
MessageBox(hWndMain,"ChoosePixelFormat : L'opération a échoué.","Erreur",MB_ICONERROR);
return 0;
}

if (SetPixelFormat(DC,pixelformat,&pfd)==FALSE)
{
MessageBox(hWndMain,"SetPixelFormat : L'opération a échoué.","Erreur",MB_ICONERROR);
return 0;
}
// 1ere fille
if ((pixelformat=ChoosePixelFormat(OGlDC,&pfd))==FALSE)
{
MessageBox(hWndMain,"ChoosePixelFormat : L'opération a échoué.","Erreur",MB_ICONERROR);
return 0;
}

if (SetPixelFormat(OGlDC,pixelformat,&pfd)==FALSE)
{
MessageBox(hWndMain,"SetPixelFormat : L'opération a échoué.","Erreur",MB_ICONERROR);
return 0;
}
// 2eme fille
if ((pixelformat=ChoosePixelFormat(OGlDC2,&pfd))==FALSE)
{
MessageBox(hWndMain,"ChoosePixelFormat : L'opération a échoué.","Erreur",MB_ICONERROR);
return 0;
}

if (SetPixelFormat(OGlDC2,pixelformat,&pfd)==FALSE)
{
MessageBox(hWndMain,"SetPixelFormat : L'opération a échoué.","Erreur",MB_ICONERROR);
return 0;
}

// Un seul RC Pour toute les fenetres...
MainHRC = wglCreateContext(DC);

return 1;
}

void SizeOpenGL(int width,int height)
{
if (hOGl==NULL) return;
if (hOGl2==NULL) return;
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,float(width)/float(height),0.1,100);
}

void dessin()
{
glBegin(GL_QUADS);
glColor3f(1.f,0.f,0.f);
glVertex2i(-1,-1);
glColor3f(0.f,1.f,0.f);
glVertex2i(1,-1);
glColor3f(0.f,0.f,1.f);
glVertex2i(1,1);
glColor3f(1.f,1.f,1.f);
glVertex2i(-1,1);
glEnd();
}


void Draw()
{
static float i = 0.0;

wglMakeCurrent(OGlDC, MainHRC);// A mettre en premier pour que tous les ordres opengl s appliquent a la fenetre en cours
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glPushMatrix();
gluLookAt(0,0,-10,0,0,0,0,1,0);

glRotatef(i, 0.0, 1.0, 0.0);

dessin();
SwapBuffers(OGlDC);
glPopMatrix();

wglMakeCurrent(OGlDC2, MainHRC); // A mettre en premier pour que tous les ordres opengl s appliquent a la fenetre en cours
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glPushMatrix();
gluLookAt(0,0,-10,0,0,0,0,1,0);

glRotatef(-i, 0.0, 1.0, 0.0);
dessin();
SwapBuffers(OGlDC2);
glPopMatrix();

i+=1.0;
}

void ReleaseOpenGl()
{
wglMakeCurrent(NULL, NULL);
if (MainHRC) wglDeleteContext(MainHRC);
ReleaseDC(hOGl,OGlDC);
}


Donc bien heureux... Merci tu m as file un sacre coup de main en tout cas : )... Ca faisait un peu deux semaines que j allais de forum en forum pour trouver une solution.

Tchao
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_MeRiX
cs_MeRiX 15 Messages postés lundi 11 octobre 2004Date d'inscription 23 juin 2009 Dernière intervention - 2 juil. 2005 à 16:26
0
Utile
Salut... Ca tombe bien que tu poses cette question si je te comprends bien j ai a peu pres le meme soucis en ce moment... Je voudrais avoir plusieurs zones ou je pourrais afficher un rendu openGL. Seulement j avais opte pour avoir plusieurs fenetres filles dans un contexte MDI... Le probleme C que j ai les barres de titres des fenetres filles visibles et je ne voudrais pas ( d ailleurs j ai pose une question hier soir pour savoir comment l enlever )... Toi tu as fais comment pour avoir plusieurs contexte ( OGlDC et OGlDC2 ) ? Tu travailles avec une seule fenetre ? Tu veux deux zones de dessins distinctes ?...
Commenter la réponse de cs_MeRiX
cs_Tibabou 130 Messages postés mercredi 2 janvier 2002Date d'inscription 7 juillet 2012 Dernière intervention - 2 juil. 2005 à 17:13
0
Utile
Je tiens à préciser que c'est Xavious qui m'a donné le code permettant de dessiner dans un controle, j'ai essayé, à partir de sa source, d'en créer un deuxième.


int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow)
{
WNDCLASS wcls;


ZeroMemory(&wcls,sizeof(wcls));


wcls.style=CS_HREDRAW|CS_VREDRAW;
wcls.lpfnWndProc=WinProc;
wcls.hInstance=hInst;
wcls.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wcls.hCursor=LoadCursor(NULL,IDC_ARROW);
wcls.hbrBackground=(HBRUSH)(COLOR_BTNFACE+1);
wcls.lpszClassName="MyWndClassName";


if (!RegisterClass(&wcls))
{
MessageBox(NULL,"Impossible d'enregistrer la classe de fenêtre.\nL'application va se terminer.","Erreur",MB_ICONERROR);
return 0;
}


hWndMain=CreateWindow("MyWndClassName","OpenGl dans un contrôle by X@v...",WS_OVERLAPPEDWINDOW|WS_VISIBLE,
CW_USEDEFAULT,0,840,630,HWND_DESKTOP,NULL,hInst,0);


if (hWndMain==NULL)
{
MessageBox(NULL,"Impossible de créer la fenêtre.\nL'application va se terminer.","Erreur",MB_ICONERROR);
return 0;
}


hOGl=CreateWindow("STATIC","",WS_VISIBLE|WS_CHILD|WS_BORDER,10,10,400,300,hWndMain,NULL,hInst,NULL);
hOGl2=CreateWindow("STATIC","",WS_VISIBLE|WS_CHILD|WS_BORDER,420,10,400,300,hWndMain,NULL,hInst,NULL);


UpdateWindow(hWndMain);
ShowWindow(hWndMain,SW_SHOW);


if (InitOpenGl()==0)
{
MessageBox(NULL,"Impossible dinitialiser OpenGl.\nL'application va se terminer.","Erreur",MB_ICONERROR);
}


SizeOpenGL(400,300);
MSG msg;


while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
ReleaseOpenGl();


return 0;
}



LRESULT CALLBACK WinProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam )
{
switch(uMsg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_SIZE:
SizeOpenGL(400,300);
break;
case WM_PAINT:
PAINTSTRUCT ps,ps1,ps2;
BeginPaint(hWndMain,&ps);


BeginPaint(hOGl,&ps1);
EndPaint(hOGl,&ps1);


BeginPaint(hOGl2,&ps2);
EndPaint(hOGl2,&ps2);


EndPaint(hWndMain,&ps);


Draw();


break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return FALSE;
}


int InitOpenGl()
{
OGlDC=GetDC(hOGl);
OGlDC2=GetDC(hOGl2);


PIXELFORMATDESCRIPTOR pfd,pfd2;
int pixelformat,pixelformat2;


pfd.nSize=sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion=1;
pfd.dwFlags= PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.dwLayerMask= PFD_MAIN_PLANE;
pfd.iPixelType=PFD_TYPE_RGBA;
pfd.cColorBits=16;
pfd.cDepthBits=16;
pfd.cAccumBits=0;
pfd.cStencilBits=0;
//2
pfd2.nSize=sizeof(PIXELFORMATDESCRIPTOR);
pfd2.nVersion=1;
pfd2.dwFlags= PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd2.dwLayerMask= PFD_MAIN_PLANE;
pfd2.iPixelType=PFD_TYPE_RGBA;
pfd2.cColorBits=16;
pfd2.cDepthBits=16;
pfd2.cAccumBits=0;
pfd2.cStencilBits=0;


if ((pixelformat=ChoosePixelFormat(OGlDC,&pfd))==FALSE)
{
MessageBox(hWndMain,"ChoosePixelFormat : L'opération a échoué.","Erreur",MB_ICONERROR);
return 0;
}


if (SetPixelFormat(OGlDC,pixelformat,&pfd)==FALSE)
{
MessageBox(hWndMain,"SetPixelFormat : L'opération a échoué.","Erreur",MB_ICONERROR);
return 0;
}
//2
if ((pixelformat2=ChoosePixelFormat(OGlDC2,&pfd2))==FALSE)
{
MessageBox(hWndMain,"ChoosePixelFormat : L'opération a échoué.","Erreur",MB_ICONERROR);
return 0;
}


if (SetPixelFormat(OGlDC2,pixelformat2,&pfd2)==FALSE)
{
MessageBox(hWndMain,"SetPixelFormat : L'opération a échoué.","Erreur",MB_ICONERROR);
return 0;
}
MainHRC = wglCreateContext(OGlDC);
MainHRC2 = wglCreateContext(OGlDC2);


return 1;
}


void SizeOpenGL(int width,int height)
{
if (hOGl==NULL) return;
if (hOGl2==NULL) return;
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,float(width)/float(height),0.1,100);
}


void dessin()
{


glBegin(GL_QUADS);
glColor3f(1.f,0.f,0.f);
glVertex2i(-1,-1);
glColor3f(0.f,1.f,0.f);
glVertex2i(1,-1);
glColor3f(0.f,0.f,1.f);
glVertex2i(1,1);
glColor3f(1.f,1.f,1.f);
glVertex2i(-1,1);
glEnd();


}


void Draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();


wglMakeCurrent(OGlDC,MainHRC);
gluLookAt(0,0,-10,0,0,0,0,1,0);
dessin();
SwapBuffers(OGlDC);


wglMakeCurrent(OGlDC2,MainHRC2);
gluLookAt(0,0,-10,0,0,0,0,0,1);
dessin();
SwapBuffers(OGlDC2);



}


void ReleaseOpenGl()
{


wglMakeCurrent(NULL, NULL);
if (MainHRC) wglDeleteContext(MainHRC);
ReleaseDC(hOGl,OGlDC);


wglMakeCurrent(NULL, NULL);
if (MainHRC2) wglDeleteContext(MainHRC2);
ReleaseDC(hOGl2,OGlDC2);


}

Désolé pour la longueur...

Tibabou
Commenter la réponse de cs_Tibabou
cs_Tibabou 130 Messages postés mercredi 2 janvier 2002Date d'inscription 7 juillet 2012 Dernière intervention - 3 juil. 2005 à 00:15
0
Utile
Merci bien ! ça marche déjà mieux... En revanche je suis très surpris que l'on n'arrive pas à afficher qqch à la création de la fenêtre... Je continue de chercher et je te tiens au courant.
Pendant que j'y suis:
Avec le code que j'avais modifié, j'avais au lancement de mon programme l'image "en mémoire" qui s'affichait (si j'ai joué à un jeu avant par exemple, je reconnais le dessin par bandes horizontales). Bref, sais-tu quelle est la fonction qui permet de dire à la CG: "on efface tout et on recommence" ?

Merci ;-)

Tibabou
Commenter la réponse de cs_Tibabou
cs_MeRiX 15 Messages postés lundi 11 octobre 2004Date d'inscription 23 juin 2009 Dernière intervention - 3 juil. 2005 à 14:42
0
Utile
Salut...

Tu devrais chercher il y a de tres bon tuto pour openGL, et meme en francais... Je n ai pas d adresse sous la main, mais tu trouveras facilement des liens vers des sites sur ce forum.... ( cherche tuto opengl + nehe )

Dans :
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
"GL_COLOR_BUFFER_BIT" reinitialise le buffer de couleur avec la couleur par default
"GL_DEPTH_BUFFER_BIT" nettoie le buffer de profondeur associe aux couleurs

glLoadIdentity(); : vide la pile de matrices et l initialise avec la matrice identite si ca te dit qque chose...

J ose pas trop detaille, je ne suis pas expert et les explications que je me suis faites ne sont pas forcement les mieux...

Voili voilo... Moi V me baigner... Et finir ma nuit.
A++
Commenter la réponse de cs_MeRiX
cs_Tibabou 130 Messages postés mercredi 2 janvier 2002Date d'inscription 7 juillet 2012 Dernière intervention - 3 juil. 2005 à 17:32
0
Utile
Te baigner ??? :-o
Chanceux...

Merci pour les explications ;-)

Tibabou
Commenter la réponse de cs_Tibabou

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.