
Introduccion
Ya hemos dicho que la clase osg :: Camera gestiona el contexto gráfico OpenGL asociado. El contexto gráfico encapsula información sobre cómo y dónde se dibujan los objetos y qué atributos de estado se les aplican. El contexto se entiende como una ventana gráfica, o más bien su área de cliente, o el búfer de píxeles de OpenGL, que almacena datos de píxeles sin transferirlos al búfer de cuadros.
OSG utiliza la clase osg :: GraphicsContext para representar un contexto gráfico abstracto y la clase osg :: GraphicsWindow para representar una ventana gráfica abstracta. Este último tiene un método getEventQueue () para administrar eventos desde elementos de la GUI. En términos generales, un contexto gráfico es un concepto específico de la plataforma, por lo que OSG se encarga de la mayor parte del trabajo de crear una ventana y asociar su contexto con el contexto OpenGL. Cuando se llama al método createGraphicsContext () de la clase osg :: GraphicsContext (), el preprocesador generará automáticamente el código requerido (y hay muchos, ¡créanme!), Dependiendo de la plataforma. Todo lo que se requiere de nosotros es pasar a este método un argumento del tipo osg :: GraphicsContex :: Traits que contenga una descripción de la ventana que queremos recibir.
1. La clase osg :: DisplaySettings
OSG permite al desarrollador administrar la configuración de visualización global, en función de qué cámaras, visores y elementos de escena se representan. Para esto, se utiliza el patrón singleton, es decir, un objeto único que contiene esta configuración, implementado en forma de la clase osg :: DisplaySettings, a la que se puede acceder desde cualquier parte del programa. Por lo tanto, desde nuestra aplicación, podemos cambiar esta configuración en cualquier momento.
osg::DisplaySettings *ds = osg::DisplaySettings::instance();
Singleton osg :: DisplaySettings contiene la configuración que se aplica a los dispositivos de renderizado recién creados, el contexto OpenGL de la ventana gráfica. Puede variar los siguientes parámetros:
- setDoubleBuffer () - habilita / deshabilita el doble buffering. Habilitado por defecto.
- setDepthBuffer () - activa / desactiva el búfer de profundidad. Habilitado por defecto.
- Establezca el ancho del búfer alfa, el búfer de la plantilla y el búfer de acumulación utilizando métodos como setMinimumNumAlphaBits (). Por defecto, todos los parámetros son 0.
- Permiso para usar anti-aliasing y su profundidad usando el método setNumMultiSamples (). El valor predeterminado es 0.
- Activa el modo estéreo. Desactivado por defecto.
Considere el uso de este singleton en el ejemplo de suavizado
Ejemplo singleton de Osg :: DisplaySettingsmain.h #ifndef MAIN_H #define MAIN_H #include <osgDB/ReadFile> #include <osgViewer/Viewer> #endif
main.cpp #include "main.h" int main(int argc, char *argv[]) { (void) argc; (void) argv; osg::DisplaySettings::instance()->setNumMultiSamples(6); osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("../data/cessna.osg"); osgViewer::Viewer viewer; viewer.setSceneData(model.get()); return viewer.run(); }
Lo esencial aquí es solo un desafío.
osg::DisplaySettings::instance()->setNumMultiSamples(6);
- establecer el parámetro de suavizado, que puede tomar los valores 2, 4 y 6, dependiendo del dispositivo gráfico utilizado. Preste atención a cómo se ve la cuchilla de tornillo Cessna sin aplicar suavizado

y luego de su aplicación

2. Cambiar al modo ventana
La clase osgViewer :: Viewer se puede reconfigurar muy rápidamente para mostrar en modo de ventana. Como notó, todos nuestros ejemplos anteriores se mostraron en pantalla completa. Para cambiar el visor al modo de ventana, existe el método setUpViewInWindow (), que toma como parámetros las coordenadas de la esquina superior izquierda de la ventana, su ancho y alto en píxeles
viewer.setUpViewInWindow(50, 50, 800, 600);
Opcionalmente, este método acepta el quinto parámetro: el número de la pantalla en la que se debe mostrar la ventana, en caso de que tenga más de un monitor. Seguramente trabajando con múltiples monitores en Windows, observó que la escena se extiende a todos los monitores en modo de pantalla completa (esto no se observa en Linux).
Además, en la configuración del proyecto, puede establecer la variable de entorno OSG_WINDOW de esta manera

que será equivalente a llamar a setUpViewInWindow (), que en este caso no se puede ejecutar.

Para especificar explícitamente la pantalla en la que se debe mostrar el visor en modo de pantalla completa, puede usar el método setUpViewOnSingleScreen () especificando el número de pantalla como un parámetro (0 por defecto).
OSG también admite pantallas esféricas de demostración. Puede usar el método setUpViewFor3DSphericalDisplay () para personalizar la pantalla en dicha pantalla.
3. Visor compuesto
La clase osgViewer :: Viewer controla una vista única que muestra un solo gráfico de escena. Además de esto, hay una clase osgViewer :: CompositeViewer que admite varias vistas y varias escenas. Tiene los mismos métodos run (), frame () y done () para controlar el proceso de renderizado, pero le permite agregar y eliminar vistas independientes usando los métodos addView () y removeView (), así como obtener vistas por su índice usando el método getView () El objeto de vista es descrito por la clase osgViewer :: View.
La clase osgViewer :: View es la clase base para la clase osgViewer :: Viewer. Le permite agregar un nodo raíz con datos de escena, un manipulador de cámara y controladores de eventos. La principal diferencia entre esta clase (vista) y la clase de visor es que no permite renderizar la escena con llamadas run () o frame (). Un escenario típico para agregar vistas se ve así
osgViewer::CompositeViewer multiviewer; multiviewer.addView( view );
El visor compuesto le permite mostrar una escena en diferentes ángulos, mostrando estos ángulos en diferentes ventanas. También le permite mostrar escenas independientes en diferentes ventanas. Escribamos un ejemplo simple de uso de un visor compuesto
Ejemplo compuestomain.h #ifndef MAIN_H #define MAIN_H #include <osgDB/ReadFile> #include <osgViewer/CompositeViewer> #endif
main.cpp #include "main.h"
Colocaremos la creación de una vista separada en una función que tome como parámetros la posición y el tamaño de la ventana, así como la escena como un puntero a su nodo raíz
osgViewer::View *createView(int x, int y, int w, int h, osg::Node *scene) { osg::ref_ptr<osgViewer::View> view = new osgViewer::View; view->setSceneData(scene); view->setUpViewInWindow(x, y, w, h); return view.release(); }
Aquí creamos una vista controlada por un puntero inteligente a un objeto osgViewer :: View
osg::ref_ptr<osgViewer::View> view = new osgViewer::View;
establecer los datos de la escena mostrada y el modo de visualización de la ventana en la ventana con la posición y el tamaño especificados
view->setSceneData(scene); view->setUpViewInWindow(x, y, w, h);
Devolvemos la vista desde la función de acuerdo con las reglas para devolver punteros inteligentes
return view.release();
Ahora en el programa principal cargamos tres modelos diferentes
osgViewer::View *view1 = createView(50, 50, 320, 240, model1); osgViewer::View *view2 = createView(380, 50, 320, 240, model2); osgViewer::View *view3 = createView(185, 330, 320, 240, model3);
crear tres tipos diferentes
osgViewer::View *view1 = createView(50, 50, 320, 240, model1); osgViewer::View *view2 = createView(380, 50, 320, 240, model2); osgViewer::View *view3 = createView(185, 330, 320, 240, model3);
crear un visor compuesto y agregarle vistas creadas previamente
osgViewer::CompositeViewer viewer; viewer.addView(view1); viewer.addView(view2); viewer.addView(view3);
y ejecuta el renderizado exactamente de la misma manera que lo hicimos en el caso de una escena
return viewer.run();
Eso es todo! Cuando se inicia el programa, obtenemos tres ventanas diferentes. El contenido de cada ventana se puede controlar de forma independiente. Cualquiera de las ventanas se puede cerrar de la manera estándar y salir completamente de la aplicación presionando Esc.

3. La clase osg :: GraphicsContext :: Traits
La palabra "rasgos" en la traducción del inglés significa "características". Entonces, la clase mencionada anteriormente describe las características de la ventana futura y contiene todas las propiedades para describir el contexto gráfico. Se diferencia de la clase osg :: DisplaySettings, que controla las características de todos los contextos gráficos para cámaras recién creadas. Las principales propiedades públicas de esta clase se enumeran en la tabla a continuación.
Atributo de clase | Tipo | Valor por defecto | Descripción |
---|
x | int | 0 0 | La posición horizontal inicial de la ventana. |
y | int | 0 0 | La posición vertical inicial de la ventana. |
ancho | int | 0 0 | Ancho de la ventana |
altura | int | 0 0 | Altura de la ventana |
windowName | std :: string | "" | Título de la ventana |
ventanaDecoración | bool | falso | Indicador de visualización del título de la ventana |
rojo | unsigned int | 8 | El número de bits de rojo en el búfer de color OpenGL |
verde | unsigned int | 8 | El número de bits de verde en el búfer de color OpenGL |
azul | unsigned int | 8 | El número de bits de azul en el búfer de color OpenGL |
alfa | unsigned int | 8 | El número de bits en el búfer alfa OpenGL |
profundidad | unsigned int | 24 | El número de bits en el búfer de profundidad OpenGL |
plantilla | unsigned int | 0 0 | El número de bits en el búfer de galería de símbolos OpenGL |
doubleBuffer | bool | falso | Usar doble tampón |
muestras | unsigned int | 0 0 | Número de suavizado primitivo |
quadBufferStereo | bool | falso | Utilice un búfer estéreo cuádruple (para equipos NVidia) |
inheritedWindowData | osg :: ref_ptr | Nulo | Descriptor de datos asociado a la ventana |
Para inicializar el objeto Traits, ejecute el siguiente código
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; traits->x = 50; traits->y = 100; ...
4. Configure la ventana de la aplicación OSG
Para crear una ventana con las características especificadas, debe realizar los siguientes pasos:
- Configure un objeto de tipo osg :: GraphicsContext :: Traits
- Crear un contexto de ventana gráfica
- Enlace este contexto gráfico a la cámara
- Haz de la cámara el espectador principal
Ejemplo de rasgosmain.h #ifndef MAIN_H #define MAIN_H #include <osg/GraphicsContext> #include <osgDB/ReadFile> #include <osgViewer/Viewer> #endif
main.cpp #include "main.h" int main(int argc, char *argv[]) { (void) argc; (void) argv; osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; traits->x = 50; traits->y = 50; traits->width = 800; traits->height = 600; traits->windowName = "OSG application"; traits->windowDecoration = true; traits->doubleBuffer = true; traits->samples = 4; osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get()); osg::ref_ptr<osg::Camera> camera = new osg::Camera; camera->setGraphicsContext(gc); camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) ); camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); camera->setClearColor( osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f) ); double aspect = static_cast<double>(traits->width) / static_cast<double>(traits->height); camera->setProjectionMatrixAsPerspective(30.0, aspect, 1.0, 1000.0); camera->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); osg::ref_ptr<osg::Node> root = osgDB::readNodeFile("../data/cessna.osg"); osgViewer::Viewer viewer; viewer.setCamera(camera.get()); viewer.setSceneData(root.get()); return viewer.run(); }
Para establecer las preferencias de la ventana, cree una instancia de la clase osg :: GraphicsContext :: Traits e inicialícela con los parámetros que necesitamos
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; traits->x = 50; traits->y = 50; traits->width = 800; traits->height = 600; traits->windowName = "OSG application"; traits->windowDecoration = true; traits->doubleBuffer = true; traits->samples = 4;
Después de eso, creamos un contexto gráfico pasando un puntero a los rasgos como la configuración
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
Crear una cámara
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
Asociamos la cámara con el contexto gráfico creado.
camera->setGraphicsContext(gc);
Configure la ventana gráfica, configure la máscara de limpieza del búfer, configure el color de limpieza
camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) ); camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); camera->setClearColor( osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f) );
Configurar una matriz de proyección en perspectiva
double aspect = static_cast<double>(traits->width) / static_cast<double>(traits->height); camera->setProjectionMatrixAsPerspective(30.0, aspect, 1.0, 1000.0);
No olvide habilitar la prueba de profundidad, para la correcta visualización de caras.
camera->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
Cargando modelo de avión
osg::ref_ptr<osg::Node> root = osgDB::readNodeFile("../data/cessna.osg");
Configuramos y lanzamos el visor, indicando la cámara que configuramos en la calidad de la cámara principal.
osgViewer::Viewer viewer; viewer.setCamera(camera.get()); viewer.setSceneData(root.get()); return viewer.run();
A la salida tenemos una ventana con los parámetros requeridos.

El título de la ventana no se muestra porque esta función está deshabilitada en la configuración de mi administrador de ventanas. Si ejecuta el ejemplo en Windows o Linux con configuraciones diferentes, el encabezado estará en su lugar.
Continuará ...