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

C++:
  1. #include <windows.h>       
  2. #include <gl\gl.h>     
  3. #include <gl\glu.h>   
  4.  
  5. #pragma comment(lib,"opengl32.lib")
  6. #pragma comment(lib,"glu32.lib")
  7.  
  8. #define VENTANA_ANCHO 640
  9. #define VENTANA_ALTO  480
  10.  
  11. HDC   hdc=NULL;       
  12. HGLRC      hglrc=NULL;       
  13. HWND        hWnd=NULL;   
  14. HINSTANCE   hInstance;  
  15.  
  16. void inicializarGL(void)                                       
  17. {
  18.     glClearColor(0.0f, 0.0f, 0.0f, 0.5f);            
  19.     glMatrixMode (GL_PROJECTION);   
  20.     glViewport (0, 0, VENTANA_ANCHO , VENTANA_ALTO);   
  21.     gluPerspective(45.0f,VENTANA_ANCHO/VENTANA_ALTO,0.1f,100.0f);
  22.     gluLookAt( 0,0,160,0,0, 0,1,0);
  23.     glMatrixMode (GL_MODELVIEW);   
  24.     glLoadIdentity();                           
  25. }
  26.  
  27. void render(void)                           
  28. {
  29.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
  30.    
  31.     glBegin(GL_TRIANGLES);
  32.     glColor3f(0.0f,0.0f,1.0f);
  33.     glVertex3f(3.0f,-2.0f,0.0f);
  34.     glVertex3f(0.0f,1.0f,0.0f);
  35.     glVertex3f(-3.0f,-2.0f,0.0f);
  36.     glEnd();
  37. }
  38.  
  39. void deInicializar(void)                               
  40. {
  41.         wglMakeCurrent(NULL,NULL);         
  42.         wglDeleteContext(hglrc);                       
  43.         ReleaseDC(hWnd,hdc);                   
  44.         DestroyWindow(hWnd);                   
  45.         UnregisterClass("OpenGL",hInstance);   
  46. }
  47.  
  48. LRESULT CALLBACK WndProc(   HWND   hWnd,UINT  uMsg,WPARAM   wParam,    LPARAM  lParam)
  49. {
  50.     switch (uMsg)                              
  51.     {
  52.         case WM_CLOSE:               
  53.         {
  54.             PostQuitMessage(0);      
  55.             return 0;                        
  56.         }
  57.     }
  58.     return DefWindowProc(hWnd,uMsg,wParam,lParam);
  59. }
  60.  
  61. int WINAPI WinMain(HINSTANCE hinst,HINSTANCE hinstAnterior,LPSTR cadenaDeComandos,int parametroVentana)   
  62. {
  63.     MSG  mensaje;         
  64.     BOOL    continuar=TRUE;  
  65.     GLuint  PixelFormat;
  66.     WNDCLASS    Cwnd;                  
  67.  
  68.     hInstance         = GetModuleHandle(NULL);            
  69.     Cwnd.style      = CS_OWNDC;   
  70.     Cwnd.lpfnWndProc    = (WNDPROC) WndProc;                   
  71.     Cwnd.cbClsExtra  = 0;         
  72.     Cwnd.cbWndExtra  = 0;         
  73.     Cwnd.hInstance    = hInstance;             
  74.     Cwnd.hIcon      = NULL;         
  75.     Cwnd.hCursor        = LoadCursor(NULL, IDC_ARROW);     
  76.     Cwnd.hbrBackground  = NULL;                           
  77.     Cwnd.lpszMenuName   = NULL;                                   
  78.     Cwnd.lpszClassName  = "OpenGL";                        
  79.  
  80.     RegisterClass(&Cwnd);                        
  81.    
  82.     hWnd=CreateWindow(      "OpenGL",
  83.                             "Hola Mundo",
  84.                             WS_OVERLAPPEDWINDOW
  85.                             ,100, 100,
  86.                             VENTANA_ANCHO,
  87.                             VENTANA_ALTO,
  88.                             NULL,            
  89.                             NULL,            
  90.                             hInstance,     
  91.                             NULL);       
  92.    
  93.     static  PIXELFORMATDESCRIPTOR pfd=               
  94.     {
  95.         sizeof(PIXELFORMATDESCRIPTOR),     
  96.         1,                   
  97.         PFD_DRAW_TO_WINDOW |PFD_SUPPORT_OPENGL |PFD_DOUBLEBUFFER,            
  98.         PFD_TYPE_RGBA,
  99.         32,   
  100.         0, 0, 0, 0, 0, 0,            
  101.         0
  102.         0
  103.         0
  104.         0, 0, 0, 0,
  105.         32,  
  106.         0,   
  107.         0,   
  108.         0,
  109.         0,     
  110.         0, 0, 0  
  111.     };
  112.    
  113.     hdc=GetDC(hWnd);                           
  114.     PixelFormat=ChoosePixelFormat(hdc,&pfd);   
  115.     SetPixelFormat(hdc,PixelFormat,&pfd);      
  116.     hglrc=wglCreateContext(hdc);               
  117.     wglMakeCurrent(hdc,hglrc);       
  118.    
  119.     ShowWindow(hWnd,SW_SHOW);            
  120.     SetForegroundWindow(hWnd);       
  121.     SetFocus(hWnd);
  122.  
  123.     inicializarGL();                       
  124.    
  125.     while(continuar)                           
  126.     {
  127.         if (PeekMessage(&mensaje,NULL,0,0,PM_REMOVE))   
  128.         {
  129.             if (mensaje.message==WM_QUIT)            
  130.             {
  131.                 continuar=FALSE;                           
  132.             }
  133.             else                                   
  134.             {
  135.                 TranslateMessage(&mensaje);    
  136.                 DispatchMessage(&mensaje);       
  137.             }
  138.         }
  139.         else                                       
  140.         {
  141.                 render();               
  142.                 SwapBuffers(hdc);         
  143.         }
  144.     }
  145.  
  146.     deInicializar();                   
  147.     return (mensaje.wParam);               
  148. }

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.

COMENTARIOS

Dejar un comentario

:mrgreen: :| :twisted: :arrow: 8O :) :? 8) :evil: :D :idea: :oops: :P :roll: ;) :cry: :o :lol: :x :( :!: :?: