2) Cómo inicializar OpenGL

2.1) Visual C++ y MFC

En este curso se asume que el lector tiene una idea de programación, al menos lo suficiente como para crear un programa sencillo en Visual C++ usando MFC. Si no es así, le recomendamos consultar los primeros capítulos del Curso de Visual C++ con MFC de este mismo site.

Se asume también que el lector tiene instalado el Visual C++ (versión 5.0 en adelante) en su máquina, y que sabe crear un nuevo proyecto MFC (por detalles, consultar el primer capítulo del curso antes mencionado).

2.2) Inicialización, paso a paso, de un proyecto 2D

Para los apurados de siempre, les aviso que pueden saltearse toda esta sección e ir directamente a la sección siguiente (2.3: Inicialización, paso a paso, de un proyecto 3D). Sin embargo, es aconsejable para los que no tengan experiencia previa con gráficos 3D que dediquen el par de horas necesarias para seguir esta sección: luego la parte 3D va a deslizarse más fácil. Ustedes deciden...

Paso 1) Crear un nuevo proyecto de tipo "MFC AppWizard (EXE)" en Visual C++ (hay que elegirle un nombre, es recomendable usar "open2", que es el que voy a usar en el resto de este tutorial)
Elegir las siguientes opciones durante la definición del proyecto:
- Single Document
- Database Support: Ninguno
- OLE Support: Ninguno
- Docking Toolbar, Initial Status Bar, Printing and Print Preview, Context-Sensitive Help, 3D Controls: opcionales (se recomienda poner todas en OFF)
- Generate Source File Comments: Sí
- Usar la librería MFC como: DLL compartida (shared dll)
- Para lo demás tomar los valores por defecto y terminar

Paso 2) Incluir en el proyecto las librerías OpenGL:

- opengl32.lib
- glu32.lib
- glaux.lib

Esto se hace seleccionando la opción Settings dentro del menú Project en Visual C++; allí, seleccionar la pastilla Link y agregar la siguiente línea en donde dice "Object/library modules":

opengl32.lib glu32.lib glaux.lib

Para terminar, hay que editar el archivo stdafx.h (que fue creado automáticamente por MFC) para que la parte inicial (donde están los include) quede así:

#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers

#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <gl\gl.h>
#include <gl\glu.h>
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows 95 Common Controls

#endif // _AFX_NO_AFXCMN_SUPPORT

Paso 3) OpenGL necesita que los estilos de ventana sean WS_CLIPCHILDREN y WS_CLIPSIBLINGS
Esto se logra editando OnPreCreate del Class Wizard (para la clase View), para que quede así:

BOOL Copen2View::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS);

return CView::PreCreateWindow(cs);
}

Hasta aquí nos hemos concentrado en preparativos generales. Ahora entraremos en detalles más específicos de OpenGL

Paso 4) Crear un RC: OpenGL necesita crear un RC ("Rendering Context", Contexto de Rendering). Qué es un RC lo veremos más tarde, por el momento lo importante es saber que OpenGL necesita uno y que hay que crearlo. Esto se hace en tres etapas:

1°) Setear un PIXEL FORMAT
2°) Crear el RC propiamente dicho
3°) Hacer que el RC sea current

Para empezar, seteamos el PIXEL FORMAT. ¿Qué es un PIXEL FORMAT? Es un conjunto de parámetros que establecen cómo guarda internamente cada ventana los gráficos que muestra en pantalla. Por ejemplo, cuántos bits se utilizan para guardar la componente roja de un pixel; cada ventana tiene asociado un valor diferente, y eso es lo que se establece en el PIXEL FORMAT

La siguiente función (que debe ser agregada como "protected" en la clase VIEW) se encarga de hacerlo:

BOOL CGLSample1View::SetWindowPixelFormat(HDC hDC)
{
PIXELFORMATDESCRIPTOR pixelDesc;

pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pixelDesc.nVersion = 1;

pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_DRAW_TO_BITMAP |
PFD_SUPPORT_OPENGL |
PFD_SUPPORT_GDI |
PFD_STEREO_DONTCARE;

pixelDesc.iPixelType = PFD_TYPE_RGBA;
pixelDesc.cColorBits = 32;
pixelDesc.cRedBits = 8;
pixelDesc.cRedShift = 16;
pixelDesc.cGreenBits = 8;
pixelDesc.cGreenShift = 8;
pixelDesc.cBlueBits = 8;
pixelDesc.cBlueShift = 0;
pixelDesc.cAlphaBits = 0;
pixelDesc.cAlphaShift = 0;
pixelDesc.cAccumBits = 64;
pixelDesc.cAccumRedBits = 16;
pixelDesc.cAccumGreenBits = 16;
pixelDesc.cAccumBlueBits = 16;
pixelDesc.cAccumAlphaBits = 0;
pixelDesc.cDepthBits = 32;
pixelDesc.cStencilBits = 8;
pixelDesc.cAuxBuffers = 0;
pixelDesc.iLayerType = PFD_MAIN_PLANE;
pixelDesc.bReserved = 0;
pixelDesc.dwLayerMask = 0;
pixelDesc.dwVisibleMask = 0;
pixelDesc.dwDamageMask = 0;

m_GLPixelIndex = ChoosePixelFormat( hDC, &pixelDesc);
if (m_GLPixelIndex==0) // Elegimos un índice por defecto.
{
m_GLPixelIndex = 1;
if (DescribePixelFormat(hDC, m_GLPixelIndex,
sizeof(PIXELFORMATDESCRIPTOR), &pixelDesc)==0)
{
return FALSE;
}
}

if (SetPixelFormat( hDC, m_GLPixelIndex, &pixelDesc)==FALSE)
{
return FALSE;
}

return TRUE;

}

Conviene detenerse un momento para ver con detalle cómo funciona la función anterior. En especial, el objeto pixelDesc de tipo PIXELFORMATDESCRIPTOR. Más adelante podrá volverse con mayor detalle a esto, pero lo importante por ahora es observar que se pueden establecer muchas cosas alterando los parámetros del PIXELFORMATDESCRIPTOR definido aquí.

2.3) Inicialización, paso a paso, de un proyecto 3D

- OpenGL es portable: existen APIs de OpenGL para C++, Java y Visual Basic (entre otros), y el código es portable (si el programador es suficientemente cuidadoso) incluso a distintos sistemas operativos. OpenGL corre bajo Windows, Linux, Unix, etc.

- OpenGL es el estándar actual en la industria de los gráficos 3D (aunque Microsoft siga luchando para mantener a DirectX en competencia...). ¿Han escuchado hablar de juegos como el Quake o el Half Life? Bueno, adivinen qué paquetes gráficos usan...

- OpenGL maneja los gráficos a muy bajo nivel (por algo se lo conoce como el "Assembler" de los gráficos 3D). Esto explica por qué es hasta 10 veces más rápido que otros paquetes, pero sobre todo proporciona una gran libertad de acción al programador. Además, es muy fácil de usar (mucho más que otras librerías!)

1.2) Cómo funciona

El secreto de la eficiencia y portabilidad de OpenGL es que funciona como una interfaz entre el programador y el Sistema Operativo. Es decir, OpenGL no "hace" los dibujos, simplemente le indica al sistema operativo lo que hay que hacer. Podría esquematizarse su funcionamiento así:

Programa -----> OpenGL ------> Sistema Operativo -----> Gráficos en Pantalla.

La ventaja de esta aproximación es que el Sistema Operativo sabe mejor que nadie cómo hacer las cosas. En Windows 95/98/NT/2000, de la interfaz entre OpenGL y el OS se ocupa opengl32.dll. Cada tarjeta gráfica 3D tiene su propia versión de opengl32.dll, que suele venir optimizada para obtener un mejor rendimiento de los comandos OpenGL para esa tarjeta. Por lo tanto, el programador simplemente escribe los comandos OpenGL y puede confiar en que su versión de opengl32.dll se ocupará de ejecutarlos en la forma más eficiente para su propia tarjeta gráfica. En el caso de otros sistemas operativos, la librería vendrá de otra forma, pero la idea es la misma.

1.3) Un ejemplo

Un ejemplo de código OpenGL puede dar una idea de cómo se usa. Supongamos que ya tenemos todo pronto para programar bajo OpenGL, que ya fijamos las condiciones de iluminación, la posición de la cámara, y el área del "mundo virtual" que estará visible en pantalla (en los capítulos siguientes iremos viendo cómo hacer todo esto). Ahora queremos dibujar un triángulo. Nada más fácil; el siguiente código lo hace (y creo que se explica solo):

glBegin(GL_TRIANGLE);
glVertex3f(3.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 3.0, 0.0);
glEnd();

"glBegin .... glEnd" indican que se está definiendo un objeto geométrico. GL_TRIANGLE indica que es un triángulo. Y glVertex permite especificar la coordenada de cada uno de los (tres) vértices del triángulo. En cuanto al apéndice "3f" en "glVertex3f", por ahora no es importante y más adelante vamos a ver de qué se trata.



Algunos links...

Página anterior: Curso de OpenGL

Página siguiente: 2: Cómo inicializar OpenGL

Volver a la página principal

Puedes enviar tus comentarios, sugerencias, insultos y demás a: Feedback Programación