
1. Introdução
Já dissemos que a classe osg :: Camera gerencia o contexto gráfico OpenGL associado. O contexto gráfico encapsula informações sobre como e onde os objetos são desenhados e quais atributos de estado são aplicados a eles. O contexto é entendido como uma janela gráfica, ou melhor, sua área de cliente, ou buffer de pixel OpenGL, que armazena dados de pixels sem transferi-los para o buffer de quadros.
O OSG usa a classe osg :: GraphicsContext para representar um contexto gráfico abstrato e a classe osg :: GraphicsWindow para representar uma janela gráfica abstrata. Este último possui um método getEventQueue () para gerenciar eventos a partir de elementos da GUI. De um modo geral, um contexto gráfico é um conceito específico de plataforma; portanto, o OSG cuida da maior parte do trabalho de criação de uma janela e associa seu contexto ao contexto OpenGL. Quando você chama o método createGraphicsContext () da classe osg :: GraphicsContext (), o código necessário (e muito, acredite!) Será gerado automaticamente pelo pré-processador, dependendo da plataforma. Tudo o que é necessário para nós é passar para esse método um argumento do tipo osg :: GraphicsContex :: Traits que contém uma descrição de qual janela queremos receber.
1. A classe osg :: DisplaySettings
O OSG permite que o desenvolvedor gerencie as configurações globais de exibição, com base nas câmeras, visualizadores e elementos da cena. Para isso, é utilizado o padrão singleton, ou seja, um objeto exclusivo contendo essas configurações, implementadas na forma da classe osg :: DisplaySettings, que pode ser acessada de qualquer lugar do programa. Portanto, em nosso aplicativo, podemos alterar essas configurações a qualquer momento.
osg::DisplaySettings *ds = osg::DisplaySettings::instance();
Singleton osg :: DisplaySettings contém as configurações que se aplicam aos dispositivos de renderização recém-criados, o contexto OpenGL da janela de desenho. Você pode variar os seguintes parâmetros:
- setDoubleBuffer () - ativa / desativa o buffer duplo. Ativado por padrão.
- setDepthBuffer () - ativa / desativa o buffer de profundidade. Ativado por padrão.
- Defina a largura do buffer alfa, buffer de estêncil e buffer de acumulação usando métodos como setMinimumNumAlphaBits (). Por padrão, todos os parâmetros são 0.
- Permissão para usar anti-aliasing e sua profundidade usando o método setNumMultiSamples (). O padrão é 0.
- Ative o modo estéreo. Desativado por padrão.
Considere o uso desse singleton no exemplo de suavização
Osg singleton example :: 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(); }
Essencial aqui é apenas um desafio.
osg::DisplaySettings::instance()->setNumMultiSamples(6);
- definir o parâmetro de suavização, que pode assumir os valores 2, 4 e 6, dependendo do dispositivo gráfico usado. Preste atenção na aparência da lâmina do parafuso cessna sem aplicar suavização

e após a sua aplicação

2. Alterne para o modo janela
A classe osgViewer :: Viewer pode ser reconfigurada muito rapidamente para ser exibida no modo janela. Como você notou, todos os nossos exemplos anteriores foram exibidos em tela cheia. Para alternar o visualizador para o modo janela, existe o método setUpViewInWindow (), que assume como parâmetros as coordenadas do canto superior esquerdo da janela, sua largura e altura em pixels
viewer.setUpViewInWindow(50, 50, 800, 600);
Opcionalmente, esse método aceita o quinto parâmetro - o número da tela na qual a janela deve ser exibida, caso você tenha mais de um monitor. Certamente, trabalhando com vários monitores no Windows, você observou que a cena se espalha para todos os monitores no modo de tela cheia (isso não é observado no Linux).
Além disso, nas configurações do projeto, você pode definir a variável de ambiente OSG_WINDOW dessa maneira

que será equivalente a chamar setUpViewInWindow (), que neste caso pode não ser executado.

Para especificar explicitamente a tela na qual o visualizador deve ser exibido no modo de tela inteira, você pode usar o método setUpViewOnSingleScreen () especificando o número da tela como um parâmetro (0 por padrão).
O OSG também suporta displays esféricos de demonstração. Você pode usar o método setUpViewFor3DSphericalDisplay () para personalizar a exibição em uma exibição.
3. Visualizador composto
A classe osgViewer :: Viewer controla uma única exibição exibindo um único gráfico de cena. Além disso, há uma classe osgViewer :: CompositeViewer que suporta várias visualizações e várias cenas. Possui os mesmos métodos run (), frame () e done () para controlar o processo de renderização, mas permite adicionar e remover visualizações independentes usando os métodos addView () e removeView (), além de obter visualizações por seu índice usando o método getView () O objeto view é descrito pela classe osgViewer :: View.
A classe osgViewer :: View é a classe base da classe osgViewer :: Viewer. Permite adicionar um nó raiz com dados da cena, um manipulador de câmera e manipuladores de eventos. A principal diferença entre essa classe (exibição) e a classe visualizador é que ela não permite renderizar a cena com chamadas run () ou frame (). Uma visualização típica que adiciona um cenário se parece com isso
osgViewer::CompositeViewer multiviewer; multiviewer.addView( view );
O visualizador composto permite exibir uma cena em ângulos diferentes, exibindo esses ângulos em janelas diferentes. Também permite exibir cenas independentes em diferentes janelas. Vamos escrever um exemplo simples de como usar um visualizador composto
Exemplo compostomain.h #ifndef MAIN_H #define MAIN_H #include <osgDB/ReadFile> #include <osgViewer/CompositeViewer> #endif
main.cpp #include "main.h"
Criaremos uma visão separada em uma função que assume como parâmetros a posição e o tamanho da janela, bem como a cena como um ponteiro para seu nó raiz.
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(); }
Aqui criamos uma visão controlada por um ponteiro inteligente para um objeto osgViewer :: View
osg::ref_ptr<osgViewer::View> view = new osgViewer::View;
defina os dados da cena exibida e o modo de exibição da janela na janela com a posição e tamanho especificados
view->setSceneData(scene); view->setUpViewInWindow(x, y, w, h);
Retornamos a visualização da função de acordo com as regras para retornar ponteiros inteligentes
return view.release();
Agora, no programa principal, carregamos três 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);
crie três 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);
crie um visualizador composto e inclua visualizações criadas anteriormente
osgViewer::CompositeViewer viewer; viewer.addView(view1); viewer.addView(view2); viewer.addView(view3);
e execute a renderização exatamente da mesma maneira que fizemos no caso de uma cena
return viewer.run();
Isso é tudo! Quando o programa é iniciado, temos três janelas diferentes. O conteúdo de cada janela pode ser controlado independentemente. Qualquer uma das janelas pode ser fechada da maneira padrão e sair completamente do aplicativo pressionando Esc.

3. A classe osg :: GraphicsContext :: Traits
A palavra "traços" na tradução do inglês significa "recursos". Portanto, a classe mencionada acima descreve os recursos da janela futura e contém todas as propriedades para descrever o contexto gráfico. Difere da classe osg :: DisplaySettings, que controla as características de todos os contextos gráficos das câmeras recém-criadas. As principais propriedades públicas desta classe estão listadas na tabela abaixo.
Atributo de classe | Tipo | Valor padrão | Descrição do produto |
---|
x | int | 0 0 | A posição horizontal inicial da janela |
y | int | 0 0 | A posição vertical inicial da janela |
largura | int | 0 0 | Largura da janela |
altura | int | 0 0 | Altura da janela |
windowName | std :: string | "" | Título da janela |
windowDecoration | bool | falsa | Sinalizador de exibição do título da janela |
vermelho | unsigned int | 8 | O número de bits de vermelho no buffer de cores OpenGL |
verde | unsigned int | 8 | O número de bits de verde no buffer de cores OpenGL |
azul | unsigned int | 8 | O número de bits de azul no buffer de cores OpenGL |
alfa | unsigned int | 8 | O número de bits no buffer alfa do OpenGL |
profundidade | unsigned int | 24 | O número de bits no buffer de profundidade do OpenGL |
estêncil | unsigned int | 0 0 | O número de bits no buffer de estêncil OpenGL |
doubleBuffer | bool | falsa | Use buffer duplo |
amostras | unsigned int | 0 0 | Número de suavização primitivo |
quadBufferStereo | bool | falsa | Use buffer estéreo quádruplo (para equipamento NVidia) |
herditedWindowData | osg :: ref_ptr | Nulo | Descritor de dados associado à janela |
Para inicializar o objeto Traits, execute o seguinte código
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; traits->x = 50; traits->y = 100; ...
4. Configure a janela do aplicativo OSG
Para criar uma janela com as características especificadas, você deve executar as seguintes etapas:
- Configure um objeto do tipo osg :: GraphicsContext :: Traits
- Criar um contexto de janela gráfica
- Vincule esse contexto gráfico à câmera
- Torne a câmera o visualizador principal
Exemplo de traçosmain.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 definir preferências de janela, crie uma instância da classe osg :: GraphicsContext :: Traits e inicialize-a com os parâmetros que precisamos
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;
Depois disso, criamos um contexto gráfico passando um ponteiro para traços como as configurações
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
Crie uma câmera
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
Associamos a câmera ao contexto gráfico criado
camera->setGraphicsContext(gc);
Configure a janela de visualização, defina a máscara de limpeza do buffer, defina a cor da limpeza
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 uma matriz de projeção em perspectiva
double aspect = static_cast<double>(traits->width) / static_cast<double>(traits->height); camera->setProjectionMatrixAsPerspective(30.0, aspect, 1.0, 1000.0);
Não se esqueça de ativar o teste de profundidade, para a exibição correta das faces
camera->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
Carregando modelo de aeronave
osg::ref_ptr<osg::Node> root = osgDB::readNodeFile("../data/cessna.osg");
Configuramos e iniciamos o visualizador, indicando a câmera que configuramos na qualidade da câmera principal
osgViewer::Viewer viewer; viewer.setCamera(camera.get()); viewer.setSceneData(root.get()); return viewer.run();
Na saída, temos uma janela com os parâmetros necessários

O título da janela não é exibido porque esta função está desativada nas configurações do meu gerenciador de janelas. Se você executar o exemplo no Windows ou Linux com configurações diferentes, o cabeçalho estará no seu lugar.
Para continuar ...