SDK Multiplataforma en C logo

SDK Multiplataforma en C

OGL3D

❮ Anterior

Funciones

voidogl3d_start (void)
voidogl3d_finish (void)
OGLCtx*ogl3d_context (...)
voidogl3d_destroy (...)
voidogl3d_begin_draw (...)
voidogl3d_end_draw (...)
voidogl3d_set_size (...)
const char_t*ogl3d_err_str (...)

Tipos y Constantes

enumoglapi_t
enumoglerr_t
structOGLProps
structOGLCtx

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
Árbol de dependencias de la librería ogl3d.
Figura 1: Dependencias de OGL3D. Ver NAppGUI API.

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.
  • Gráfico que muestra los objetos asociados a un contexto OpenGL.
    Figura 2: Contexto OpenGL y objetos asociados.

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).

Listado 1: Creación de un contexto OpenGL, asociado con una ventana.
 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

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.

Listado 2: Dibujo en una vista, utilizando 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).

Listado 3: Inclusión de GLEW.
 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).

Listado 4: Comprobación de extensiones con GLEW.
1
2
3
4
5
6
7
8
9
if (glewIsSupported("GL_ARB_vertex_program"))
{
    // Extension available
}
...
if (GLEW_ARB_vertex_program)
{
    // Extension available
}
❮ Anterior

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 TRUE.

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 TRUE se intenta crear un contexto transparente.

shared

Contexto con el que compartir objectos gráficos. Normalmente NULL.


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. HWND en Windows, GtkWidget en Linux o NSView en macOS.

err

Código de error. Puede ser NULL.

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 NULL.


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.

❮ Anterior