Hola Complicado Mundo OpenGL-Win32

El código completo del programa,de 148 líneas de código es:


#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>

#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")

#define VENTANA_ANCHO 640
#define VENTANA_ALTO  480

HDC			hdc=NULL;
HGLRC		hglrc=NULL;
HWND		hWnd=NULL;
HINSTANCE	hInstance;

void inicializarGL(void)
{
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
	glMatrixMode (GL_PROJECTION);
	glViewport (0, 0, VENTANA_ANCHO , VENTANA_ALTO);
	gluPerspective(45.0f,VENTANA_ANCHO/VENTANA_ALTO,0.1f,100.0f);
	gluLookAt( 0,0,16,  0,0,0, 0,1,0);
	glMatrixMode (GL_MODELVIEW);
	glLoadIdentity();
}

void render(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glBegin(GL_TRIANGLES);
	glColor3f(0.0f,0.0f,1.0f);
	glVertex3f(3.0f,-2.0f,0.0f);
	glVertex3f(0.0f,1.0f,0.0f);
	glVertex3f(-3.0f,-2.0f,0.0f);
	glEnd();
}

void deInicializar(void)
{
		wglMakeCurrent(NULL,NULL);
		wglDeleteContext(hglrc);
		ReleaseDC(hWnd,hdc);
		DestroyWindow(hWnd);
		UnregisterClass("OpenGL",hInstance);
}

LRESULT CALLBACK WndProc(	HWND	hWnd,UINT	uMsg,WPARAM	wParam,	LPARAM	lParam)
{
	switch (uMsg)
	{
		case WM_CLOSE:
		{
			PostQuitMessage(0);
			return 0;
		}
	}
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

int WINAPI WinMain(HINSTANCE hinst,HINSTANCE hinstAnterior,LPSTR cadenaDeComandos,int parametroVentana)
{
	MSG		mensaje;
	BOOL	continuar=TRUE;
	GLuint  PixelFormat;
	WNDCLASS	Cwnd;

	hInstance			= GetModuleHandle(NULL);
	Cwnd.style			= CS_OWNDC;
	Cwnd.lpfnWndProc	= (WNDPROC) WndProc;
	Cwnd.cbClsExtra		= 0;
	Cwnd.cbWndExtra		= 0;
	Cwnd.hInstance		= hInstance;
	Cwnd.hIcon			= NULL;
	Cwnd.hCursor		= LoadCursor(NULL, IDC_ARROW);
	Cwnd.hbrBackground	= NULL;
	Cwnd.lpszMenuName	= NULL;
	Cwnd.lpszClassName	= "OpenGL";

	RegisterClass(&Cwnd);

	hWnd=CreateWindow(  	"OpenGL",
							"Hola Mundo",
							WS_OVERLAPPEDWINDOW
							,100, 100,
							VENTANA_ANCHO,
							VENTANA_ALTO,
							NULL,
							NULL,
							hInstance,
							NULL);

	static	PIXELFORMATDESCRIPTOR pfd=
	{
		sizeof(PIXELFORMATDESCRIPTOR),
		1,
		PFD_DRAW_TO_WINDOW |PFD_SUPPORT_OPENGL |PFD_DOUBLEBUFFER,
		PFD_TYPE_RGBA,
		32,
		0, 0, 0, 0, 0, 0,
		0,
		0,
		0,
		0, 0, 0, 0,
		32,
		0,
		0,
		0,
		0,
		0, 0, 0
	};

	hdc=GetDC(hWnd);
	PixelFormat=ChoosePixelFormat(hdc,&pfd);
	SetPixelFormat(hdc,PixelFormat,&pfd);
	hglrc=wglCreateContext(hdc);
	wglMakeCurrent(hdc,hglrc);

	ShowWindow(hWnd,SW_SHOW);
	SetForegroundWindow(hWnd);
	SetFocus(hWnd);

	inicializarGL();

	while(continuar)
	{
		if (PeekMessage(&mensaje,NULL,0,0,PM_REMOVE))
		{
			if (mensaje.message==WM_QUIT)
			{
				continuar=FALSE;
			}
			else
			{
				TranslateMessage(&mensaje);
				DispatchMessage(&mensaje);
			}
		}
		else
		{
				render();
				SwapBuffers(hdc);
		}
	}

	deInicializar();
	return (mensaje.wParam);
}

La aplicación luce así:

Captura

Aun este programa tiene que abarcar bastantes prestaciones no contempladas, por dar simpleza (de ser posible eso) al Hola Mundo. Entre estas prestaciones están:

  • Solicitar modo pantalla completa, que es muy común entre los videojuegos.
  • Atender a los errores en todo el proceso de creación de la ventana y asociación a OpenGL. Muchas de las funciones utilizadas en la aplicación tienen un retorno que indica si la función pudo llevarse a cabo o no.
  • Cambiar de tamaño la escena de OpenGL al cambiar el tamaño de la ventana. Esto se hace añadiendo los estilos CS_VREDRAW y CS_HREDRAW al WNDCLASS e interceptando el mensaje WM_SYSCOMMAND, Wparam SC_SIZE.
  • Pausar la aplicación cuando la ventana es puesta detrás de otra o minimizada.

También es importante aclarar que este ejemplo utiliza el driver de software de OpenGL creado por Microsoft en la década del 90 y que actualmente dicho driver no es mantenido y es muy ineficiente. Para utilizar el driver de OpenGL que proporciona la tarjeta gráfica, que tiene la ventaja de ser acelerado por hardware y mantenido constantemente (dependiendo de la tarjeta) se pueden usar las funciones WGL-ARB aprobadas en el año 2000 y que hacen actualmente parte del estándar, aunque siempre que se quieran usar, se debe comprobar su disponibilidad, ya que dependen de la implementación del estándar.

Finalmente es necesario señalar que esta es una de las maneras mas complicadas de hacer una aplicación con OpenGL para Windows, ya que se trabaja el API de win32 a muy bajo nivel y las funciones para ligar OpenGL con GDI no han sido actualizada en muchos años, de hecho el articulo relevante mas reciente que se puede encontrar en MSDN acerca de OpenGL data del año 1995.

download


Descargar:	hola-mundo-win32.zip
Version:	0.1
Actualizado:	December 22, 2009
Tamaño:		99.48 KB

1 2 3 4

Compartir esta entrada

DiggReddit
  • http://http.//dedolog.blogspot.com Debor

    Está chido pero no lo leí todo llevo prisa, pero si cae mal que pasen por tu log y no comenten 😉

  • http://dedolog.blogspot.com Debor

    Por cierto ando programando en luinux pero quiero exportar a win32 o 64 espero poder

  • Martin_395

    Muy completo y interesante, pero lleva tiempo entender todo(menos mal que soy joven y tengo tiempo).
    Gracias por el tutorial.

  • miguel365

    :O interesante, muy completo el post, desde hace tiempo he querido escribir una aplicacion sencilla de opengl pero que me permita manejar botones, menus etc. pero no encuentro un manual. Sabes si puedo preparar el contexto de opengl utlizando un picturebox de windows forms? agradezco tu respuesta por favor.