2 contrôles dans une fenêtre avec openGL

Résolu
cs_Tibabou Messages postés 129 Date d'inscription mercredi 2 janvier 2002 Statut Membre Dernière intervention 7 juillet 2012 - 2 juil. 2005 à 11:58
cs_Tibabou Messages postés 129 Date d'inscription mercredi 2 janvier 2002 Statut Membre Dernière intervention 7 juillet 2012 - 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

6 réponses

cs_MeRiX Messages postés 15 Date d'inscription lundi 11 octobre 2004 Statut Membre Dernière intervention 23 juin 2009
2 juil. 2005 à 20:28
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
3
cs_MeRiX Messages postés 15 Date d'inscription lundi 11 octobre 2004 Statut Membre Dernière intervention 23 juin 2009
2 juil. 2005 à 16:26
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 ?...
0
cs_Tibabou Messages postés 129 Date d'inscription mercredi 2 janvier 2002 Statut Membre Dernière intervention 7 juillet 2012
2 juil. 2005 à 17:13
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
0
cs_Tibabou Messages postés 129 Date d'inscription mercredi 2 janvier 2002 Statut Membre Dernière intervention 7 juillet 2012
3 juil. 2005 à 00:15
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
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_MeRiX Messages postés 15 Date d'inscription lundi 11 octobre 2004 Statut Membre Dernière intervention 23 juin 2009
3 juil. 2005 à 14:42
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++
0
cs_Tibabou Messages postés 129 Date d'inscription mercredi 2 janvier 2002 Statut Membre Dernière intervention 7 juillet 2012
3 juil. 2005 à 17:32
Te baigner ??? :-o
Chanceux...

Merci pour les explications ;-)

Tibabou
0
Rejoignez-nous