Deplacement dans une fenêtre opengl sans glut[win32]

Description

voilà j'ai extrait l'inutile donc il reste peut etre deux ou trois lignes de codes qui ne servent à rien...
mais sinon c'est le code pour créer une fenêtre opengl sans glut (utilisation de l'api windows) et de pouvoir gérer le déplacement (en tout cas une partie ) à la souris ...

Source / Exemple :


//inclure dans la partie LINK de projet>setting
// opengl32.lib glu32.lib et comctl32.lib
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <winuser.h>
#include <gl/glu.h>
#include <gl/gl.h>
#include <commctrl.h>
#include <math.h>

#define WM_TYPEOBJ 2525
#define IDMP_IGES	2526
#define IDMP_STEP	2527
#define IDMP_STL	2528
#define IDMP_GEO	2529
#define IDMP_COUPE	2530
#define IDMP_RETOUR	2531
#define PI			3.141592654
#define ID_ETAT		255
#define	ID_BUT		252
#define WM_REINIT	2625
#define WM_DEPL		2626

#define VITESSE_ROTATION	25.0
#define VITESSE_DEPL		1.0

 
//************************************************************************************
//					DECLARATION DES VARIABLES GLOBALES
//************************************************************************************

HINSTANCE MyInstance;
HWND hwnd_fen3;
HWND hwnd_be=NULL;

HDC dess;
HGLRC rc_dess;

HWND gl;
HWND hwnd_button;

float longueur;
float largeur;
float hauteur;

int type_obj;
int typeobj;
float zoom;
float depl;
float angle;
int move=0;
POINT oldpt;
bool mousing = false;
bool mousing_m = false;
bool mousing_d = false;

//****************************************************************************************
//****************************************************************************************

//****************************************************************************************
//					FONCTIONS
//****************************************************************************************

LRESULT CALLBACK WndProc3(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
INT WINAPI fen3(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow,int choix);

//****************************************************************************************
//****************************************************************************************

//menu popup attacher au bouton droit de la souris
void create_popup_menu3ds(HWND hWnd)
{
  HMENU hMenu;
  POINT pt;
  GetCursorPos(&pt);///récupère la position du curseur
  hMenu=CreatePopupMenu();
  AppendMenu(hMenu,MF_STRING,IDMP_IGES,"Enregistrer IGES");//ajoute des entrées au menu
  AppendMenu(hMenu,MF_STRING,IDMP_STEP,"Enregistrer STEP");
  AppendMenu(hMenu,MF_STRING,IDMP_STL,"Enregistrer STL");
  AppendMenu(hMenu,MF_STRING,IDMP_GEO,"Enregistrer GEO");  
  AppendMenu(hMenu,MF_SEPARATOR,NULL,NULL);
  AppendMenu(hMenu,MF_STRING,IDMP_COUPE,"Couper");
  AppendMenu(hMenu,MF_SEPARATOR,NULL,NULL);
  AppendMenu(hMenu,MF_STRING,IDMP_RETOUR,"Retour");

  TrackPopupMenu( hMenu,NULL,pt.x,pt.y,0,hWnd,NULL);//crée le menu à l'emplacement du curseur
}

//initialisation du format pour la fenêtre opengl
void SetupPixelFormat(HDC hDC) 
{   
	PIXELFORMATDESCRIPTOR pfd =  
		{   
		  sizeof(PIXELFORMATDESCRIPTOR),  //taille du descripteur de format 
				1, //version 
				PFD_SUPPORT_OPENGL |
				PFD_DRAW_TO_WINDOW | 
				PFD_DOUBLEBUFFER, //Propriétés 
				PFD_TYPE_RGBA,  //Mode de couleurs 
				16,  //Bits de couleur 
				0, 0, 0, 0, 0, 0, //Paramètres des couleurs 
				0,0,  //Paramètres alpha 
				0,0, 0, 0, 0, //Paramètres du buffer d'accumulation 
				32, //Bits de profondeur 
				0,  //Bits du buffer stencil  
				0,  //Nombre de buffers auxiliaires 
				0,  //ignoré (obsolète) 
				0,  //réservé 
				0,  //ignoré (obsolète) 
				0, //Couleur de transparence 
				0  //Ignoré (obsolète) 
		 };   
  
	int pixelFormat;  
	pixelFormat = ChoosePixelFormat(hDC, &pfd);  
	if (!pixelFormat)  
	{  
 
	  MessageBox(WindowFromDC(hDC),
			"Mode graphique non supporté.",
			"Problème",
			MB_ICONERROR | MB_OK);
		exit(1);
	}    
	if (!SetPixelFormat(hDC, pixelFormat, &pfd))  
	{     
	  MessageBox(WindowFromDC(hDC),"Mode graphique non supporté.",
				"Problème",	MB_ICONERROR | MB_OK);
		exit(1);
	}   
}
 
void SetupMouse(HWND hwnd) 
{   
	TRACKMOUSEEVENT ouais =  
		{   
		  sizeof(TRACKMOUSEEVENT),  //taille du descripteur d' événement 
				TME_LEAVE,//type de retour	: ici sortir de la fenetre
				hwnd,	//fenetre sur laquelle s'applique les événement
				10				 
		 };   
  
	TrackMouseEvent(&ouais);
}

//initialisation de l'opengl
void initgl (void)
{
	//eclairage : utile si vous rajouter des objets et encore... je sais même pas...
	GLfloat light0_pos[4]   = { -50.0f, 50.0f, 0.0f, 0.0f };
	GLfloat light0_color[4] = { .6f, .6f, .6f, 1.0f }; //
	GLfloat light1_pos[4]   = {  50.0f, 50.0f, 0.0f, 0.0f };
	GLfloat light1_color[4] = { .4f, .4f, 1.f, 1.0f };  //
	GLfloat light2_pos[4]   = { 0.0f, -50.0f, 0.0f, 0.0f };
	GLfloat light2_color[4] = { .7f, .7f, .7f, 1.0f };	//
	
	glDisable(GL_CULL_FACE);
	glEnable(GL_DEPTH_TEST);
	
	glEnable(GL_DITHER);
	glShadeModel(GL_SMOOTH);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
	glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
	
	glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);
	glLightfv(GL_LIGHT0, GL_DIFFUSE,  light0_color);
	glLightfv(GL_LIGHT1, GL_POSITION, light1_pos);
	glLightfv(GL_LIGHT1, GL_DIFFUSE,  light1_color);

	glLightfv(GL_LIGHT2, GL_POSITION, light2_pos);
	glLightfv(GL_LIGHT2, GL_DIFFUSE,  light2_color);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHT1);
	glEnable(GL_LIGHT2);

	glEnable(GL_LIGHTING);
	
	glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
	glEnable(GL_COLOR_MATERIAL);	
} 

//dessin des axes (coordonnées à revoir)....
void draw_axes( float scale )
{
	glDisable( GL_LIGHTING );

	glPushMatrix();
	glScalef( scale, scale, scale );

	glLineWidth(2);

	glBegin( GL_LINES );

	glColor3f( 1, 0, 0 );
	glVertex3f( .8f, 0.05f, 0 );  glVertex3f( 1, 0.25f, 0 ); //* Lettre X 
	glVertex3f( 0.8f, .25f, 0 );  glVertex3f( 1, 0.05f, 0 );
	glVertex3f( 0, 0, 0 );  glVertex3f( 1, 0, 0 ); //* X axe      

	glColor3f( 0, 1, 0);
	glVertex3f( -.25f, 0.8f, 0 );  glVertex3f( -.05f, 1, 0 ); //* Lettre Y 
	glVertex3f( -.25f, 1, 0 );  glVertex3f( -.15f, 0.9f, 0 );
	glVertex3f( 0, 0, 0 );  glVertex3f( 0, 1, 0 ); //* Y axe

	glColor3f( 0, 0, 1 );
	glVertex3f( 0, 0, 0 );  glVertex3f( 0.0f, 0.0f, 1.0f ); //* Z axe
	//Ici je place la lettre Z sur l'axe Z
	glVertex3f( -0.1f, 0, 0.8f );	glVertex3f( -0.3f, 0, 0.8f );
	glVertex3f( -0.1f, 0, 0.8f );	glVertex3f( -0.3f, 0, 1 );
	glVertex3f( -0.1f, 0, 1 );	glVertex3f( -0.3f, 0, 1 );

	glEnd();

	glLineWidth(1);

	glPopMatrix();

	glEnable( GL_LIGHTING );
}
 
//fonction de la fenêtre fille opengl
LRESULT CALLBACK WndProc_gl(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	float posX ; 
	float posY ; 
	float posZ ; 
	float ciblX; 
	float ciblY; 
	float ciblZ; 
	
	switch(message)
	{
		case WM_CREATE:
			//création du contexte pour l'opengl
			dess=GetDC(hwnd); 
			SetupPixelFormat(dess);
			rc_dess = wglCreateContext(dess); 
			if (!rc_dess) SendMessage(hwnd,WM_CLOSE,0,0); 
			wglMakeCurrent(dess, rc_dess);
			//fin de la création du contexte
			
			//intialisation divers
			initgl();

			zoom = 30.0;
			depl = 2.0;
			angle = 0.0;

			SendMessage(hwnd,WM_SIZE,0,0);
			break;
		case WM_TYPEOBJ:	//message créé par mes soins...
			typeobj=LOWORD(lParam);
			break;
		case WM_REINIT:		//message créé par mes soins... (version 2)
			typeobj = 21;
			depl = 2.0;
			angle = 0.0;
			break;
		case WM_SIZE:	//dimensionnement de la "vue opengl"
			glViewport (0, 0, LOWORD(lParam), HIWORD(lParam));
			glMatrixMode(GL_PROJECTION);
			glLoadIdentity();
			
			gluPerspective(zoom,1,0.1,100);
			
			SendMessage(hwnd,WM_PAINT,0,0);
			break;
		case WM_PAINT:	//bin on dessine
			ShowCursor(true);
			SetupMouse(gl);
			glClearColor(0.5255f,0.796f,0.9411f,1);
			glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
			glMatrixMode(GL_MODELVIEW);
					
			glLoadIdentity();
			
			posX  = longueur/2 + depl * (float)sin(angle* PI/180);
			posY  = largeur/2;
			posZ  = hauteur/2 + depl * (float)cos(angle* PI/180); 
			ciblX = longueur/2; 
			ciblY = largeur/2; 
			ciblZ = hauteur/2; 

			gluLookAt(posX, posY, posZ, ciblX, ciblY, ciblZ,0,1,0); 
			
			glLineWidth(3);
			glBegin( GL_LINES );

			glColor3f( 0.5f, 1, 0 );
			glVertex3f( 0,0,0);	glVertex3f( 1,0,0);
			glVertex3f( 1,0,0); glVertex3f( 1,1,0);
			glVertex3f( 1,1,0); glVertex3f( 0,1,0);
			glVertex3f( 0,1,0); glVertex3f( 0,0,0);
			glVertex3f( 0,1,0); glVertex3f( 1,0,0); 
			glVertex3f( 0,0,0);	glVertex3f( 1,1,0);

			glVertex3f( 0,0,0);	glVertex3f( 0,1,0);
			glVertex3f( 0,1,0); glVertex3f( 0,1,1);
			glVertex3f( 0,1,1); glVertex3f( 0,0,1);
			glVertex3f( 0,0,1); glVertex3f( 0,0,0);
			glVertex3f( 0,0,1); glVertex3f( 0,1,0); 
			glVertex3f( 0,0,0);	glVertex3f( 0,1,1);

			glEnd();

			draw_axes(.22f);
			

			SwapBuffers(dess);
			break;
		case WM_RBUTTONDOWN:
			switch(typeobj)
			{
				case 21:
					create_popup_menu3ds(gl);
					break;
			}
			break;

		case WM_LBUTTONDOWN:
			if (!mousing_m)
			{
				GetCursorPos(&oldpt);
				ShowCursor(false);
				mousing = true;
			}
			break;
		case WM_LBUTTONUP:
			SetupMouse(hwnd);
			mousing = false;
			SendMessage(gl,WM_PAINT,0,0);
			ShowCursor(true);		
			break;
		case WM_MBUTTONDOWN:
			if (!mousing)
			{
				GetCursorPos(&oldpt);
				ShowCursor(false);
				mousing_m = true;
			}
			break;
		case WM_MBUTTONUP:
			SetupMouse(hwnd);
			mousing_m = false;
			SendMessage(gl,WM_PAINT,0,0);
			ShowCursor(true);		
			break;
		case WM_MOUSELEAVE:
			if (mousing)
				SendMessage(hwnd,WM_LBUTTONUP,0,0);
			if (mousing_m)
				SendMessage(hwnd,WM_MBUTTONUP,0,0);
			break;
		case WM_DEPL:
			if (!mousing_m && !mousing)
			{
				mousing_d = true;
				if (lParam == 1)
				{
					oldpt.y = -1;
					//MessageBox(NULL,"Avant ","roulette",NULL);
				}
				if (lParam == 2)
				{
					oldpt.y = -2;
					//MessageBox(NULL,"Arrière ","roulette",NULL);
				}
			}
			break;
		case WM_MOUSEMOVE:
			if (mousing)
			{
				POINT pt;
				GetCursorPos(&pt);
				if (pt.y < oldpt.y )
					depl -= (float)((( (float)oldpt.y - (float)pt.y ) / (float)oldpt.y ) * VITESSE_DEPL)*depl;
				else
					depl += (float)((( (float)pt.y - (float)oldpt.y ) / (float)pt.y ) * VITESSE_DEPL)*depl;
				if (depl < 1.0) depl = 1.0;
				if (depl > 10.0) depl = 10.0;
				oldpt=pt;
				SendMessage(gl,WM_PAINT,0,0);
			}
			if (mousing_m)
			{
				POINT pt;
				GetCursorPos(&pt);
				if (pt.x < oldpt.x )
					angle -= (float)((( (float)oldpt.x - (float)pt.x ) / (float)oldpt.x ) * VITESSE_ROTATION);// * angle;
				else
					angle += (float)((( (float)pt.x - (float)oldpt.x ) / (float)pt.x ) * VITESSE_ROTATION);// * angle;
				if (angle < 0.0) angle = 360;
				if (angle > 360.0) angle = 0.0;
				oldpt=pt;
				SendMessage(gl,WM_PAINT,0,0);
			}
			if (mousing_d)
			{
				if (oldpt.y == -1)
					depl += 0.1f;
				if (oldpt.y == -2 ) 
					depl -= 0.1f;
				if (depl < 1.0) depl = 1.0;
				if (depl > 10.0) depl = 10.0;
				mousing_d = false;
				SendMessage(gl,WM_PAINT,0,0);
			}
			break;

		case WM_COMMAND:
			switch(LOWORD(wParam))
			{
			case IDMP_IGES:
				MessageBox(NULL,"IGES...","???",NULL);
				break;
			case IDMP_STEP:
				MessageBox(NULL,"STEP...","???",NULL);
				break;
			case IDMP_STL:
				MessageBox(NULL,"STL...","???",NULL);
				break;
			case IDMP_GEO:
				MessageBox(NULL,"GEO...","???",NULL);
				break;
			case IDMP_COUPE:
				SendMessage(gl,WM_REINIT,0,0);
				SendMessage(gl,WM_PAINT,0,0);
				//MessageBox(NULL,"COUPE...","???",NULL);
				break;
			case IDMP_RETOUR:
				SendMessage(hwnd_fen3,WM_DESTROY,0,0);
				break;
			}
			break;

		case WM_DESTROY:
			wglMakeCurrent(NULL, NULL); 
			if (rc_dess) wglDeleteContext(rc_dess); 
			ReleaseDC(hwnd,dess);
			PostQuitMessage(0);
			break;

	}

	return DefWindowProc(hwnd, message, wParam, lParam);									
}

#include <time.h>

// fonction principale... on créer une fenêtre mère qui contient une fenêtre opengl, 
// 1 bouton et une barre d'état...
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
	WNDCLASS wndclass3;
	WNDCLASS wndclass_gl;

	wndclass3.style = CS_HREDRAW | CS_VREDRAW ;//| CS_NOCLOSE ;
	wndclass3.lpfnWndProc = WndProc3;
	wndclass3.cbClsExtra = 0;
	wndclass3.cbWndExtra = 0;
	wndclass3.hInstance = hInstance;
	wndclass3.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wndclass3.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndclass3.hbrBackground = (HBRUSH) COLOR_BTNSHADOW;
	wndclass3.lpszMenuName = NULL;
	wndclass3.lpszClassName = "aff";
	

	if(RegisterClass(&wndclass3)==0)
		return 0;

	wndclass_gl.style = CS_HREDRAW|CS_VREDRAW;
	wndclass_gl.lpfnWndProc = WndProc_gl;
	wndclass_gl.cbClsExtra = 0;
	wndclass_gl.cbWndExtra = 0;
	wndclass_gl.hInstance = MyInstance;
	wndclass_gl.hIcon = NULL;
	wndclass_gl.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndclass_gl.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
	wndclass_gl.lpszMenuName = NULL;
	wndclass_gl.lpszClassName = "affichage";
	if(RegisterClass(&wndclass_gl)==0)
		return 0;

	fen3(hInstance, hPrevInstance, szCmdLine, iCmdShow,21);

	return 0;
}

// fonction de la fenetre principale
INT WINAPI fen3(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow,int choix)
{
	type_obj=choix;
	if (hwnd_fen3==NULL)
	{
		hwnd_fen3 = CreateWindow("aff",TEXT("Affichage"),WS_SYSMENU,GetSystemMetrics(SM_CXFULLSCREEN)/8,0,
							750,740,NULL,NULL,hInstance,NULL);
	}
	InitCommonControls();

	hwnd_be = CreateWindow(STATUSCLASSNAME,NULL,WS_CHILD|WS_VISIBLE|SBARS_SIZEGRIP,
		0,0,1,1,hwnd_fen3,(HMENU)ID_ETAT,MyInstance,NULL);

	SetWindowText(hwnd_be,"Affichage des informations concernant la scène...");
	
	MSG msg;

	MyInstance = hInstance;
	ShowWindow(hwnd_fen3,SW_SHOW);
	if (gl!=NULL) SendMessage(gl,WM_PAINT,0,0);
	UpdateWindow(hwnd_fen3);

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

// fonction des message pour la fenêtre principale
LRESULT CALLBACK WndProc3(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message)
	{
		case WM_CREATE:
			longueur = 1;
			largeur = 1;
			hauteur = 1;
			if (gl==NULL)
			{
				hwnd_button = CreateWindow(TEXT("Button"),"Retour",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
					0,HIWORD(lParam)-50,LOWORD(lParam),30,hwnd,(HMENU)ID_BUT,MyInstance,NULL);
				
				gl = CreateWindow( "affichage",NULL,WS_CHILD|WS_VISIBLE,
					0,0,1,1,hwnd,NULL,MyInstance,NULL);
				
			}
			else SendMessage(gl,WM_PAINT,0,0);
			if (gl==NULL)
				MessageBox(NULL,"la fenetre opengl n'a pas été créée","Problème",NULL);
			SendMessage(gl,WM_TYPEOBJ,0,(LPARAM)type_obj);

			SendMessage(hwnd,WM_SIZE,0,0);
			break;

		case WM_SIZE:
			MoveWindow( hwnd_button,0,HIWORD(lParam)-50,LOWORD(lParam),30,true);
			MoveWindow( hwnd_be,0,HIWORD(lParam)-20,LOWORD(lParam),20,true);
			MoveWindow( gl,0,0,LOWORD(lParam),HIWORD(lParam)-50,true);
			break;
		case WM_PAINT:
			SendMessage(gl,WM_PAINT,0,0);			
			break;

		case WM_KEYDOWN:
			if (wParam == VK_ESCAPE)
				SendMessage(hwnd_fen3,WM_DESTROY,0,0);
			break;
		case WM_MOUSEWHEEL:
			if (!mousing_m && !mousing)
			{
				int deplac = HIWORD(wParam);

				if (deplac == 120)
				{
					//MessageBox(NULL,"deplacement de la roulette vers l'avant","ouais",NULL);
					SendMessage(gl,WM_DEPL,0,1);
				}
				if (deplac == 65416)
				{
					//MessageBox(NULL,"deplacement de la roulette vers l'arrière","non",NULL);
					SendMessage(gl,WM_DEPL,0,2);
				}
			}
			break;

		case WM_COMMAND:
			switch(LOWORD(wParam))
			{
			case ID_BUT:
				SendMessage(hwnd,WM_DESTROY,0,0);
				break;
			}
			break;
		case WM_RBUTTONDOWN:
			break;
	
		case WM_DESTROY:
			ShowCursor(true);
			ShowWindow(hwnd,SW_HIDE);
			PostQuitMessage(0);
			break;

	}
	return DefWindowProc(hwnd, message, wParam, lParam);									
}

Conclusion :


c'est long ... c'est pas beau .... mais bon...
j'ai fait ça pour me défaire de gtk et ne pas utiliser glut...

Codes Sources

A voir également

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.