"Ningún juego dura tanto hasta que te lo terminas como el que te programas tú mismo,
ninguno te absorbe tanto y ninguno te produce tanta satisfacción cuando lo has acabado"
Programacion de videojuegos
Inicio Curso de programación de juegos 16. Extensiones de OpenGL y versiones
Lunes 21 de Agosto del 2017

Menu principal
Colaborar (con PayPal)

Para continuar con el trabajo de esta Web y poder pagar el hosting, viene bien la ayuda que sea. Gracias a todos.

Importe: 

Ultimas descargas
19.Jan

Clase que permite dibujar texto en OpenGL con mucha facilidad.Usa FreeType2.Para ver que hace y c...


16. Extensiones de OpenGL y versiones Imprimir Correo electrónico
Videojuegos - Curso de Programación de juegos
Escrito por Vicengetorix   
Este capitulo sera mas teorico que otra cosa, aunque al final veremos algo de codigo.
El tema de las extensiones y versiones de OpenGL es uno de los mas equivocos en principio, para quienes se acercan a esta libreria grafica.
En este capitulo intentaremos que el tema quede claro y zanjado definitivamente para poder seguir avanzando sin problemas con OpenGL. A partir de aqui podremos usar cosas que son habituales pero que sin conocer el tema de las extensiones y versiones no estarian a nuestro alcance.

No es que hayamos visto todo de OpenGL 1.1 (el que viene con Windows y se puede usar sin extensiones) pero este curso no pretende ser exaustivo ni exclusivo de OpenGL. A pesar de todo, hay cosas mas modernas de OpenGL que nos vendran bien y para poder usarlas esta este capitulo.

Antes de empezar aviso que el tema es necesario conocerlo pero no nos complicaremos a la hora de hacer un programa porque hay maravillosas librerias que nos haran el trabajo. Nosotros usaremos GLee. Antes de eso hay que saber como se haria a mano.

Ya sabemos que OpenGL depende mucho de la tarjeta grafica de nuestro PC y sus drivers.

En Windows, en el directorio "system32" hay una dll llamada "opengl32.dll" que son las funciones de OpenGL implementadas hace muuuuuuchos años por Microsoft con la version 1.1 (luego Microsoft se desentendio de implementar nada mas y se centro en DirectX). La libreria "opengl32.lib" y el fichero "gl.h" son un interface para el acceso a las funciones de esta dll.
Las funciones de esta dll intentan, a traves del driver de la tarjeta de video, hacer las cosas por hardware (en vez de hacerlo la dll, le pasa el trabajo al driver de la tarjeta y este, por supuesto, se lo pasa a la propia tarjeta que hace lo que tenga que hacer por hardware). Si el driver de la tarjeta no implementa lo que la dll le pide, la dll lo intenta hacer por software.
Aqui vienen los problemas de tener una tarjeta antigua o los drivers antiguos o mal instalados.

Cuando, en su momento, definieron la especificacion de OpenGL (antes de la version 1.1), gracias a los cielos, tuvieron la prevision de implementar un sistema para ampliar las funciones de OpenGL sin tener que cambiar la implementacion de OpenGL que hiciera el sistema operativo (Windows en nuestro caso), y Microsoft cuando implemento las funciones de OpenGL 1.1 incluyo este metodo. Esto es lo que se llama el sistema de extensiones de OpenGL, que permite preguntar a la tarjeta de video si implementa una determinada funcion (extension) y obtener los punteros adecuados para llamar a las nuevas funciones de esa extension.

Permitidme un inciso historico para entender luego quien decide el tema de versiones y extensiones.
OpenGL fue inventado por Silicon Graphics Inc (SGI) para sus estaciones graficas. Luego libero la especificacion de OpenGL y paso a ser actualizada por un grupo llamado "OpenGL Architecture Review Board" (ARB), grupo formado por las empresas que tenian intereses en el sector de los graficos por ordenador, fabricantes de hardware sobre todo pero tambien de software (Microsoft dejo el grupo en el 2003).
Recientemente (2006) el ARB paso a formar parte del recien creado Grupo Khronos cuyo punto fuerte es OpenGL pero engloba otras especificaciones como COLLADA, OpenML, OpenMAX, ...

Tras el inciso historico vemos como se decide la modificacion de la especificacion de OpenGL y la inclusion de extensiones.
El ARB incluye a los fabricantes de tarjetas y empresas de software. Esta gente que tanto sabe de lo suyo, hace mejoras en sus productos y para que alguien las pueda aprovechar sacan drivers nuevos para sus nuevos productos. Define una extension de OpenGL para aprovechar esa funcion y presenta la expecificacion al ARB que opina da ideas y si al final todos estan de acuerdo se convierte en una extension oficial de OpenGL (ARB).
Los nombres de las extensiones cumplen una norma. Primero llevan un prefijo que depende de quien aprueba la extension (un fabricante, mas de uno o todo el ARB). Luego el nombre de la extension con las palabras separadas por "_". Unos ejemplos para que quede claro:

ARB_vertex_shader
ARB_multitexture
EXT_cull_vertex
NV_fog_distance
ATI_envmap_bumpmap


El prefijo es ARB si esta aprobada por todo el ARB, EXT si esta aprobada por varios fabricantes o el identificativo del fabricante si solo la usa el (ATI, NV, APPLE, IBM, SUN, ...)

Delante del prefijo del fabricante, cuando preguntamos a la tarjeta si soporta una extension, pondremos otro prefijo que determina el sistema en que es usada:
"GL_" las usadas por todos, "WGL_" usadas por Windows y "GLX_" por sistemas unix/linux.
Veamos ejemplos:

GL_ARB_texture_multisample
WGL_ARB_render_texture
GLX_ARB_framebuffer_sRGB


Aqui va el link al registro oficial de extensiones de OpenGL. Un vistazo a algunas especificaciones no esta mal para ir acostumbrandose (e ir practicando nuestro ingles).

Dicho lo anterior hay que puntualizar que una extension puede estar formada por una o varias funciones nuevas y por las constantes nuevas que se necesiten. La especificacion de la extension dice como deben ser esas funciones y que deben hacer, y cuales son los valores de las nuevas constantes y su significado..
Luego, los fabricantes implementan estas funciones en sus drivers y, para usarla solo tienes que definir esas constantes y obtener punteros a las funciones segun el metodo de OpenGL.

Las funciones y constantes de una extension tambien atienden a una nomenclatura.
Las constantes tendran la teminacion _ARB _EXT, _ATI, _NV, ... segun el prefijo del nombre de la extension, y las funciones tendran la terminacion ARB, EXT, ATI, ... ,sin el "_" pero tambien segun el prefijo de la extension.
El inicio de los nuevos nombres de constantes y funciones cambiara en base a si la extension es del tipo GL, WGL o GLX.
Un ejemplo de funciones y constantes de, por ejemplo, la extension "GL_ARB_vertex_program" que tiene muchas nuevas funciones y constantes:
Algunas funciones:

void VertexAttrib4NusvARB(uint index, const ushort *v);
void VertexAttrib4NuivARB(uint index, const uint *v);
void BindProgramARB(enum target, uint program);
void DeleteProgramsARB(sizei n, const uint *programs);


Algunas constantes con sus valores:

VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622
VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623
VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624


Este ejemplo esta sacado de la especificacion. En un programa definiriamos las funciones con gl delante y las constantes con GL_wgl y WGL_ delante.
delante (como todo en OpenGL). Si la extension fuera del tipo WGL pondriamos
Hasta ahora no hemos hablado de versiones de OpenGL de forma deliverada.
Las versiones, en realidad, son lo mismo que las extensiones.
Cada cierto tiempo el ARB se reune y decide que ya es hora de sacar una nueva version. Lo que hace es incluir las estensiones que cree oportuno en la especificacion de OpenGL y llama al resultado version 1.5 (por ejemplo). Las funciones y constantes de las extensiones que pasan a ser del cuerpo oficial de OpenGL pierden los sufijos (lo que se ponia detras de los nombres de funciones y constantes) y se les da la nomenclatura normal de OpenGL.
A partir de ese momento, las tarjetas graficas que soportan esa version de OpenGL, soportan tambien las extensiones incluidas en la version y con nombres de nomenclatura normal de OpenGL.

A fectos practicos, para nosotros, no hay mucha diferencia entre que una funcionalidad este soportada con una extension o por que la tarjeta soporta la version de OpenGL que la incluye porque la implementacion de OpenGL de nuestro sistema operativo, Windows, no soporta mas que la version 1.1 y tendremos de todas formas que obtener los punteros a las funciones y definir las constantes.
La unica diferecia sera que al definir los nombres de constantes y funciones, si somos puristas, las definiremos con sufijos si es una extension y sin sufijos si el driver soporta una version de OpenGL que la incluye.

Veremos ahora como se obtiene el puntero a una funcion de una extension o de una version de OpenGL superior a la 1.1 (en un programa real lo hara GLee por nosotros).
El metodo es farragoso por la nomenclatura C de punteros a funciones.

Lo primero sera preguntar a la tarjeta grafica que version de OpenGL soporta y que extensiones. Esto se hace con la funcion glGetString(GL_EXTENSIONS), que retorna un puntero a una cadena de caracteres muy larga con las extensiones que soporta separadas por espacios. El resultado seria algo asi (todo seguido):

GL_ARB_depth_texture GL_ARB_fragment_program GL_ARB_multitexture GL_ARB_point_parameters GL_ARB_shadow GL_ARB_texture_border_clamp GL_ARB_texture_compression GL_ARB_texture_cube_map GL_ARB_texture_env_add GL_ARB_texture_env_combine GL_ARB_texture_env_dot3 GL_ARB_texture_env_crossbar GL_ARB_transpose_matrix GL_ARB_vertex_buffer_object GL_ARB_vertex_program GL_ARB_window_pos GL_EXT_abgr GL_EXT_bgra GL_EXT_blend_color GL_EXT_blend_func_separate GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_clip_volume_hint GL_EXT_compiled_vertex_array GL_EXT_cull_vertex GL_EXT_draw_range_elements GL_EXT_fog_coord GL_EXT_multi_draw_arrays GL_EXT_packed_pixels GL_EXT_rescale_normal GL_EXT_secondary_color GL_EXT_separate_specular_color GL_EXT_shadow_funcs GL_EXT_stencil_two_side GL_EXT_stencil_wrap GL_EXT_texture_compression_s3tc GL_EXT_texture_env_add GL_EXT_texture_env_combine GL_EXT_texture_lod_bias GL_EXT_texture_filter_anisotropic GL_EXT_texture3D GL_3DFX_texture_compression_FXT1 GL_IBM_texture_mirrored_repeat GL_NV_blend_square GL_NV_texgen_reflection GL_SGIS_generate_mipmap GL_SGIS_texture_edge_clamp GL_SGIS_texture_lod GL_WIN_swap_hint

Si el nombre de la extension que buscamos esta entre las que aparecen en el chorizo de arriba, es que la extension esta soportada por la tarjeta y podemos seguir (Habria que hacer una funcion que busque un patron en una cadena de caracteres).

Para comprobar la version lo hariamos con la funcion glGetString(GL_VERSION), que retornaria algo asi:

1.4.0 - Build 7.14.10.4906

Con lo que deduciriamos que la version que soporta esta tarjeta es la 1.4.

Tambien se puede preguntar por el fabricante y el modelo de tarjeta con glGetString(GL_VENDOR) y glGetString(GL_RENDERER).

Una vez que sabemos que si podemos usar una funcionalidad por ser soportada via extensiones o version de OpenGL (es lo mismo), lo primero sera definir las constantes que se usaran. Estas son solo unas cuantas de la extension "GL_ARB_vertex_buffer_object":

1
2
3
4
5
6
7
8
9
10
11
12
#define GL_BUFFER_SIZE_ARB                       0x8764
#define GL_BUFFER_USAGE_ARB 0x8765
#define GL_ARRAY_BUFFER_ARB 0x8892
#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
.
.
.

Luego definimos los punteros a las funciones de acuerdo con la especificacion. Por ejemplo la funcion "glBindBufferARB":

1
2
typedef void (APIENTRY * PFNGLBINDBUFFERARBPROC) 
(GLenum target, GLuint buffer);

Es un puntero a una funcion que no retorna nada y acepta dos parametros, uno de tipo GLenum y otro de tipo GLuint (el nombre del puntero se las trae pero esa nomenclatura es la habitual).

Definimos un puntero del tipo que acabamos de definir:

1
PFNGLBINDBUFFERARBPROC glBindBufferARB;

Por ultimo obtenemos el puntero a la funcion con la funcion de OpenGL wglGetProcAddress(...), la encargada de buscar y retornar los punteros a las funciones de las extensiones o versiones superiores:

1
2
glBindBufferARB = 
(PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");

A partir de esto, ya podemos usar la funcion glBindBufferARB(...) como cualquier otra funcion de OpenGL.


GLee:
Esto se debe hacer con cada funcion de una extension, tambien definir las constantes, y algunas extensiones tienen bastantes funciones y constantes. Esto es un trabajo de chinos que con hacerlo una vez y guardarlo nos basta, asi que usaremos, como dijimos al principio, la libreria GLee que lo unico que nos obliga a hacer es incluir el fichero de cabecera en nuestro programa y el archivo de codigo en el proyecto. Una vez hecho esto tendremos en nuestras manos toda la potencia de la tarjeta grafica de nuestro PC, y sin habernos despeinado.

Asi pues lo unico que hay que hacer es bajarse la libreria, poner

1
#include "glee.h" 

al principio del codigo e incluir el fichero glee.c en nuestro proyecto.

Cuando queramos comprobar si una extension es soportada pondremos algo asi:

1
2
3
4
5
6
7
8
9
if (GLEE_ARB_multitexture)    // Si soporta multitextura
{
glMultiTexCoord2fARB(...); // Usamos las funciones
}
else
{
// Si no haremos otra cosa
}
 

Cuando queramos comprobar la version de OpenGL sera parecido a esto:

1
2
3
4
5
6
if (GLEE_VERSION_1_2)   // Si la version 1.2 es soportada
{
glBlendColor(...); // Podemos usar las funciones incluidas
} // en la version 1.2
 
 

Espero que tras esta explicacion hayamos comprendido que es una extension en OpenGL y como usarla, y tengamos claro lo referente a las versiones.
En el futuro, por ejemplo cuando veamos las multitexturas o la programacion de shaders, deberemos antes comprobar si podemos usarlo o no.





¡Sólo los usuarios registrados pueden escribir comentarios!
+/- Comentarios
Buscar
Jose  - Hola   |200.121.46.xxx |18-03-2010 07:56:58
Hola
recien lleog al a web y bueno recien voya comenzar ojala puedas poner mas
cosas de videojuegos saludos
Vicengetorix   |194.179.126.xxx |18-03-2010 20:52:25
Yo tambien estoy deseando un poco de tranquilidad para continuar con el curso y
la libreria.
lavz24  - Hola   |159.90.10.xxx |09-04-2010 15:54:45
Hola estoy empezando los tutoriales, es demasiado bueno todo. Excelente, espero
que puedas seguir subiendo tutos estan muy buenos.

3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved."

 


Banner
Spanish Chinese (Simplified) English French German Japanese Portuguese Russian