OGL3D
Funciones
void | ogl3d_start (void) |
void | ogl3d_finish (void) |
OGLCtx* | ogl3d_context (...) |
void | ogl3d_destroy (...) |
void | ogl3d_begin_draw (...) |
void | ogl3d_end_draw (...) |
void | ogl3d_set_size (...) |
const char_t* | ogl3d_err_str (...) |
Tipos y Constantes
enum | oglapi_t |
enum | oglerr_t |
struct | OGLProps |
struct | OGLCtx |
La librería OGL3D nos permitirá crear contextos OpenGL multiplataforma, sin tenernos que preocupar de la implementación particular en cada sistema operativo (Figura 1). Si bien el API de OpenGL es totalmente portable, la manera de crear contextos gráficos y vincularlos con una ventana es dependiente de cada plataforma. En ¡Hola Gráficos 3D! tienes una aplicación de ejemplo.
Importante. Para utilizar OGL3D en tus proyectos, tendrás que enlazar la librería de forma explícita en el CMakeLists.txt
de tu aplicación.
1 2 |
nap_desktop_app(GLHello "" NRC_EMBEDDED) nap_link_opengl(GLHello) |
Importante. En Linux necesitarás instalar las librerías de desarrollo de Mesa.
1 |
sudo apt-get install mesa-common-dev libeg1-mesa-dev |
1. Contextos 3D
Utiliza ogl3d_context para crear un contexto.
Utiliza ogl3d_destroy para destruir un contexto.
Un contexto 3D representa un conjunto de estados y objetos dentro del cual se realizan las operaciones de dibujo con OpenGL (Figura 2). Básicamente un contexto incluye:
- Estados: Configuraciones actuales como el modo de proyección, matrices de transformación, opciones de iluminación, etc.
- Shaders: Programas que permiten personalizar el renderizado dentro de la GPU.
- Geometría y texturas: Recursos gráficos que representan los objetos a renderizar.
- Buffers gráficos: Color, profundidad, stencil, y otros que se usan para almacenar la información de los píxeles durante el proceso de renderizado.
- Ventanas: La integración con el sistema operativo para dibujar en una ventana específica.
Para crear un contexto necesitarás el identificador nativo de la vista asociada. Es decir, un objeto HWND
en Windows, un GtkWidget
en Linux o un NSView
en macOS. En NAppGUI, esto lo proporciona la función view_native (Listado 1).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
View *view = .... void *nview = view_native(view); OGLCtx *oglctx = NULL; OGLProps props; oglerr_t err; props.api = ekOGL_3_3; props.hdaccel = TRUE; props.color_bpp = 32; props.depth_bpp = 0; props.stencil_bpp = 0; props.aux_buffers = 0; props.transparent = FALSE; props.shared = NULL; oglctx = ogl3d_context(&props, nview, &err); if (oglctx == NULL) { bstd_printf("Error: %s\n", ogl3d_err_str(err)); } |
2. Operación de dibujo
- Utiliza ogl3d_begin_draw al iniciar el renderizado.
- Utiliza ogl3d_end_draw al terminar el renderizado.
El objeto View
, lanzará un evento OnDraw
cada vez que necesite actualizar el área de dibujo (Dibujar en vistas). En en manejador a este evento, deberemos incluir el código OpenGL.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
static void i_OnDraw(App *app, Event *e) { const EvDraw *p = event_params(e, EvDraw); ogl3d_begin_draw(app->oglctx); // OpenGL Code (cross-platform) glViewport(0, 0, (GLsizei)p->width, (GLsizei)p->height); glClearColor(.8f, .8f, .8f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glBegin(GL_TRIANGLES); glColor3f(1, 0, 0); glVertex3f(0, 1, 0); glColor3f(0, 1, 0); glVertex3f(-1, -1, 0); glColor3f(0, 0, 1); glVertex3f(1, -1, 0); glEnd(); ogl3d_end_draw(ogl->ctx); } ... view_OnDraw(view, listener(app, i_OnDraw, App)); |
3. GLEW
OpenGL permite la incorporación de extensiones opcionales que no están incluidas en el núcleo del estándar. Estas extensiones permiten a los fabricantes de hardware (como NVIDIA, AMD, Intel, etc.) y a los desarrolladores de software agregar nuevas funcionalidades o mejorar el rendimiento de las características existentes. En general, detectar si una extensión está presente o no al crear un contexto implica una gran sobrecarga de trabajo para el programador, por lo que diferentes librerías se han creado para este cometido.
OGL3D incluye una copia de GLEW (OpenGL Extension Wrangler Library) que facilita enormemente esta tarea. Su inicialización llamando a glewInit()
se realiza automáticamente al crear el objecto OGLCtx
. Tan solo deberemos incluir esta cabecera antes de realizar cualquier llamada a OpenGL (Listado 3).
1 2 3 4 5 6 7 8 9 10 11 |
// Include OpenGL and GLEW #include "nowarn.hxx" #include <ogl3d/glew.h> #include "warn.hxx" ... // OpenGL calls glViewport(0, 0, (GLsizei)width, (GLsizei)height); glClearColor(.8f, .8f, .8f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); ... |
Para comprobar si una extensión está presente, podemos utilizar glewIsSupported()
o las diferentes macros que proporciona GLEW (Listado 4).
1 2 3 4 5 6 7 8 9 |
if (glewIsSupported("GL_ARB_vertex_program")) { // Extension available } ... if (GLEW_ARB_vertex_program) { // Extension available } |
enum oglapi_t
Versión de OpenGL.
enum oglapi_t
{
ekOGL_1_1,
ekOGL_1_2,
ekOGL_1_2_1,
ekOGL_1_3,
ekOGL_1_4,
ekOGL_1_5,
ekOGL_2_0,
ekOGL_2_1,
ekOGL_3_0,
ekOGL_3_1,
ekOGL_3_2,
ekOGL_3_3,
ekOGL_4_0,
ekOGL_4_1,
ekOGL_4_2,
ekOGL_4_3,
ekOGL_4_4,
ekOGL_4_5,
ekOGL_4_6
};
ekOGL_1_1 | OpenGL 1.1. |
ekOGL_1_2 | OpenGL 1.2. |
ekOGL_1_2_1 | OpenGL 1.2.1. |
ekOGL_1_3 | OpenGL 1.3. |
ekOGL_1_4 | OpenGL 1.4. |
ekOGL_1_5 | OpenGL 1.5. |
ekOGL_2_0 | OpenGL 2.0. |
ekOGL_2_1 | OpenGL 2.1. |
ekOGL_3_0 | OpenGL 3.0. |
ekOGL_3_1 | OpenGL 3.1. |
ekOGL_3_2 | OpenGL 3.2. |
ekOGL_3_3 | OpenGL 3.3. |
ekOGL_4_0 | OpenGL 4.0. |
ekOGL_4_1 | OpenGL 4.1. |
ekOGL_4_2 | OpenGL 4.2. |
ekOGL_4_3 | OpenGL 4.3. |
ekOGL_4_4 | OpenGL 4.4. |
ekOGL_4_5 | OpenGL 4.5. |
ekOGL_4_6 | OpenGL 4.6. |
enum oglerr_t
Códigos de error en OpenGL.
enum oglerr_t
{
ekOGLAPIVERS,
ekOGLFULLSCN,
ekOGLVIEW,
ekOGLPIXFORMAT,
ekOGLCONTEXT,
ekOGLGLEW,
ekOGLOK
};
ekOGLAPIVERS | Versión no soportada. |
ekOGLFULLSCN | Modo a pantalla completa no soportado. |
ekOGLVIEW | Error al vincular el contexto con la vista. |
ekOGLPIXFORMAT | Formato de píxel no soportado. |
ekOGLCONTEXT | Error al crear el contexto. |
ekOGLGLEW | Error al inicializar GLEW. |
ekOGLOK | Sin error. |
struct OGLProps
Propiedades del contexto OpenGL, necesarias para la creación del mismo.
struct OGLProps { oglapi_t api; bool_t hdaccel; uint32_t color_bpp; uint32_t depth_bpp; uint32_t stencil_bpp; uint32_t aux_buffers; bool_t transparent; OGLCtx* shared; };
api | Versión del API requerida. |
hdaccel | Aceleración 3D por hardware requerida. Normalmente |
color_bpp | Número de bits por píxel del búfer de color. Normalmente 32. |
depth_bpp | Número de bits por píxel del búfer de profundidad. 8, 16, 24, 32. Si 0, se deshabilita el búfer. |
stencil_bpp | Número de bits por píxel del búfer de stencil. 8, 16, 24, 32. Si 0, se deshabilita el búfer. |
aux_buffers | Número de búferes de color auxiliares. Normalmente 0. |
transparent | Si |
shared | Contexto con el que compartir objectos gráficos. Normalmente |
struct OGLCtx
Contexto OpenGL.
struct OGLCtx;
ogl3d_start ()
Inicia la librería OGL3D.
void
ogl3d_start(void);
Observaciones
Llamar a esta función antes de cualquier otra en OGL3D.
ogl3d_finish ()
Finaliza la librería OGL3D.
void
ogl3d_finish(void);
Observaciones
Llamar a esta función antes de cerrar el programa o cuando ya no se necesite utilizar OGL3D.
ogl3d_context ()
Crea un contexto OpenGL y lo asocia a una vista.
OGLCtx* ogl3d_context(const OGLProps *props, void *view, oglerr_t *err);
props | Propiedades deseadas para el contexto. |
view | Manejador nativo de la vista. |
err | Código de error. Puede ser |
Retorna
Contexto recién creado o NULL
si ha habido algún error.
Observaciones
Ver Contextos 3D.
ogl3d_destroy ()
Destruye un contexto OpenGL.
void ogl3d_destroy(OGLCtx **ogl);
ogl | Contexto a destruir. El puntero será puesto a |
ogl3d_begin_draw ()
Inicia una operación de dibujo con OpenGL.
void ogl3d_begin_draw(OGLCtx *ogl);
ogl | Contexto. |
Observaciones
Ver Operación de dibujo.
ogl3d_end_draw ()
Finaliza una operación de dibujo con OpenGL.
void ogl3d_end_draw(OGLCtx *ogl);
ogl | Contexto. |
Observaciones
Ver Operación de dibujo.
ogl3d_set_size ()
Actualiza el tamaño del contexto en píxeles. Esta función se debe llamar cada vez que se redimensione la vista.
void ogl3d_set_size(OGLCtx *ogl, const uint32_t width, const uint32_t height);
ogl | Contexto. |
width | Ancho de la vista en píxeles. |
height | Alto de la vista en píxeles. |
ogl3d_err_str ()
Retorna un texto explicativo, asociado a un código de error.
const char_t* ogl3d_err_str(const oglerr_t err);
err | Código de error. |
Retorna
Cadena de texto con el error.