
Einführung
Wir haben bereits gesagt, dass die Klasse osg :: Camera den zugehörigen OpenGL-Grafikkontext verwaltet. Der Grafikkontext enthält Informationen darüber, wie und wo Objekte gezeichnet werden und welche Statusattribute auf sie angewendet werden. Unter Kontext wird ein Grafikfenster bzw. ein Client-Bereich oder ein OpenGL-Pixelpuffer verstanden, in dem Pixeldaten gespeichert werden, ohne sie in den Bildspeicher zu übertragen.
OSG verwendet die Klasse osg :: GraphicsContext, um einen abstrakten Grafikkontext darzustellen, und die Klasse osg :: GraphicsWindow, um ein abstraktes Grafikfenster darzustellen. Letzteres verfügt über eine getEventQueue () -Methode zum Verwalten von Ereignissen aus GUI-Elementen. Im Allgemeinen ist ein grafischer Kontext ein plattformspezifisches Konzept, sodass OSG den größten Teil der Arbeit zum Erstellen eines Fensters und zum Verknüpfen seines Kontexts mit dem OpenGL-Kontext übernimmt. Wenn Sie die Methode createGraphicsContext () der Klasse osg :: GraphicsContext () aufrufen, wird der erforderliche Code (und es gibt viele davon, glauben Sie mir!) Abhängig von der Plattform automatisch vom Präprozessor generiert. Alles, was wir tun müssen, ist ein Argument an diese Methode vom Typ osg :: GraphicsContex :: Traits zu übergeben, die eine Beschreibung des Fensters enthält, das wir erhalten möchten.
1. Die osg-Klasse :: DisplaySettings
Mit OSG kann der Entwickler globale Anzeigeeinstellungen verwalten, auf deren Grundlage Kameras, Betrachter und Szenenelemente gerendert werden. Hierzu wird das Singleton-Muster verwendet, dh ein eindeutiges Objekt, das diese Einstellungen enthält und in Form der Klasse osg :: DisplaySettings implementiert ist, auf die von überall im Programm zugegriffen werden kann. Daher können wir diese Einstellungen in unserer Anwendung jederzeit ändern.
osg::DisplaySettings *ds = osg::DisplaySettings::instance();
Singleton osg :: DisplaySettings enthält die Einstellungen, die für neu erstellte Rendergeräte gelten, den OpenGL-Kontext des Grafikfensters. Sie können die folgenden Parameter variieren:
- setDoubleBuffer () - Aktiviert / deaktiviert die doppelte Pufferung. Standardmäßig aktiviert.
- setDepthBuffer () - Tiefenpuffer aktivieren / deaktivieren. Standardmäßig aktiviert.
- Stellen Sie die Breite des Alpha-Puffers, des Schablonenpuffers und des Akkumulationspuffers mit Methoden wie setMinimumNumAlphaBits () ein. Standardmäßig sind alle Parameter 0.
- Berechtigung zur Verwendung von Anti-Aliasing und seiner Tiefe mit der Methode setNumMultiSamples (). Der Standardwert ist 0.
- Schalten Sie den Stereomodus ein. Standardmäßig deaktiviert.
Betrachten Sie die Verwendung dieses Singletons am Beispiel der Glättung
Osg Singleton Beispiel :: 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(); }
Wesentlich ist hier nur eine Herausforderung.
osg::DisplaySettings::instance()->setNumMultiSamples(6);
- Einstellen des Glättungsparameters, der je nach verwendetem Grafikgerät die Werte 2, 4 und 6 annehmen kann. Achten Sie darauf, wie die Cessna-Schraubenklinge aussieht, ohne sie zu glätten

und nach seiner Anwendung

2. Wechseln Sie in den Fenstermodus
Die osgViewer :: Viewer-Klasse kann sehr schnell neu konfiguriert werden, um im Fenstermodus angezeigt zu werden. Wie Sie bemerkt haben, wurden alle unsere vorherigen Beispiele im Vollbildmodus angezeigt. Um den Viewer in den Fenstermodus zu schalten, gibt es eine setUpViewInWindow () -Methode, die die Koordinaten der oberen linken Ecke des Fensters, ihre Breite und Höhe in Pixel als Parameter verwendet
viewer.setUpViewInWindow(50, 50, 800, 600);
Optional akzeptiert diese Methode den fünften Parameter - die Nummer des Bildschirms, auf dem das Fenster angezeigt werden soll, falls Sie mehr als einen Monitor haben. Bei der Arbeit mit mehreren Monitoren in Windows haben Sie festgestellt, dass sich die Szene im Vollbildmodus auf alle Monitore ausbreitet (dies wird unter Linux nicht beobachtet).
Außerdem können Sie in den Projekteinstellungen auf diese Weise die Umgebungsvariable OSG_WINDOW festlegen

Dies entspricht dem Aufruf von setUpViewInWindow (), der in diesem Fall möglicherweise nicht ausgeführt wird.

Um den Bildschirm, auf dem der Viewer im Vollbildmodus angezeigt werden soll, explizit anzugeben, können Sie die Methode setUpViewOnSingleScreen () verwenden, indem Sie die Bildschirmnummer als Parameter angeben (Standard 0).
OSG unterstützt auch sphärische Demo-Displays. Sie können die Methode setUpViewFor3DSphericalDisplay () verwenden, um die Anzeige auf einer solchen Anzeige anzupassen.
3. Composite Viewer
Die Klasse osgViewer :: Viewer steuert eine einzelne Ansicht, in der ein einzelnes Szenendiagramm angezeigt wird. Darüber hinaus gibt es eine Klasse osgViewer :: CompositeViewer, die mehrere Ansichten und mehrere Szenen unterstützt. Es verfügt über dieselben Methoden run (), frame () und done () zur Steuerung des Renderprozesses, ermöglicht jedoch das Hinzufügen und Entfernen unabhängiger Ansichten mithilfe der Methoden addView () und removeView () sowie das Abrufen von Ansichten anhand ihres Index mithilfe der Methode getView (). Das Ansichtsobjekt wird von der Klasse osgViewer :: View beschrieben.
Die Klasse osgViewer :: View ist die Basisklasse für die Klasse osgViewer :: Viewer. Sie können einen Stammknoten mit Szenendaten, einen Kameramanipulator und Ereignishandler hinzufügen. Der Hauptunterschied zwischen dieser Klasse (Ansicht) und der Viewer-Klasse besteht darin, dass das Rendern der Szene mit run () - oder frame () -Aufrufen nicht möglich ist. Ein typisches Szenario zum Hinzufügen von Ansichten sieht folgendermaßen aus
osgViewer::CompositeViewer multiviewer; multiviewer.addView( view );
Mit Composite Viewer können Sie eine Szene in verschiedenen Winkeln anzeigen und diese Winkel in verschiedenen Fenstern anzeigen. Außerdem können Sie unabhängige Szenen in verschiedenen Fenstern anzeigen. Schreiben wir ein einfaches Beispiel für die Verwendung eines zusammengesetzten Viewers
Zusammengesetztes Beispielmain.h #ifndef MAIN_H #define MAIN_H #include <osgDB/ReadFile> #include <osgViewer/CompositeViewer> #endif
main.cpp #include "main.h"
Wir werden die Erstellung einer separaten Ansicht in eine Funktion einfügen, die die Position und Größe des Fensters sowie die Szene als Zeiger auf ihren Wurzelknoten als Parameter verwendet
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(); }
Hier erstellen wir eine Ansicht, die von einem intelligenten Zeiger auf ein osgViewer :: View-Objekt gesteuert wird
osg::ref_ptr<osgViewer::View> view = new osgViewer::View;
Stellen Sie die Daten der angezeigten Szene und den Fensteranzeigemodus im Fenster mit der angegebenen Position und Größe ein
view->setSceneData(scene); view->setUpViewInWindow(x, y, w, h);
Wir geben die Ansicht von der Funktion gemäß den Regeln für die Rückgabe von intelligenten Zeigern zurück
return view.release();
Jetzt laden wir im Hauptprogramm drei verschiedene Modelle
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);
Erstellen Sie drei verschiedene Typen
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);
Erstellen Sie einen zusammengesetzten Viewer und fügen Sie zuvor erstellte Ansichten hinzu
osgViewer::CompositeViewer viewer; viewer.addView(view1); viewer.addView(view2); viewer.addView(view3);
und führen Sie das Rendering genauso aus wie bei einer Szene
return viewer.run();
Das ist alles! Wenn das Programm startet, erhalten wir drei verschiedene Fenster. Der Inhalt jedes Fensters kann unabhängig gesteuert werden. Jedes der Fenster kann wie gewohnt geschlossen werden und die Anwendung durch Drücken von Esc vollständig beenden.

3. Die Klasse osg :: GraphicsContext :: Traits
Das Wort "Merkmale" in der Übersetzung aus dem Englischen bedeutet "Merkmale". Die oben genannte Klasse beschreibt also die Funktionen des zukünftigen Fensters und enthält alle Eigenschaften zur Beschreibung des grafischen Kontexts. Es unterscheidet sich von der Klasse osg :: DisplaySettings, die die Eigenschaften aller Grafikkontexte für neu erstellte Kameras steuert. Die wichtigsten öffentlichen Eigenschaften dieser Klasse sind in der folgenden Tabelle aufgeführt.
Klassenattribut | Typ | Standardwert | Beschreibung |
---|
x | int | 0 | Die anfängliche horizontale Position des Fensters |
y | int | 0 | Die anfängliche vertikale Position des Fensters |
Breite | int | 0 | Fensterbreite |
Höhe | int | 0 | Fensterhöhe |
Fenstername | std :: string | "" | Fenstertitel |
Fensterdekoration | Bool | falsch | Fenstertitel-Anzeigeflag |
rot | unsigned int | 8 | Die Anzahl der roten Bits im OpenGL-Farbpuffer |
grün | unsigned int | 8 | Die Anzahl der grünen Bits im OpenGL-Farbpuffer |
blau | unsigned int | 8 | Die Anzahl der blauen Bits im OpenGL-Farbpuffer |
Alpha | unsigned int | 8 | Die Anzahl der Bits im OpenGL-Alpha-Puffer |
Tiefe | unsigned int | 24 | Die Anzahl der Bits im OpenGL-Tiefenpuffer |
Schablone | unsigned int | 0 | Die Anzahl der Bits im OpenGL-Schablonenpuffer |
doubleBuffer | Bool | falsch | Verwenden Sie einen doppelten Puffer |
Proben | unsigned int | 0 | Primitive Glättungszahl |
quadBufferStereo | Bool | falsch | Verwenden Sie einen Quad-Stereopuffer (für NVidia-Geräte). |
geerbte Windows-Daten | osg :: ref_ptr | Null | Fenster zugeordneter Datendeskriptor |
Führen Sie den folgenden Code aus, um das Traits-Objekt zu initialisieren
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; traits->x = 50; traits->y = 100; ...
4. Richten Sie das OSG-Anwendungsfenster ein
Um ein Fenster mit den angegebenen Merkmalen zu erstellen, müssen Sie die folgenden Schritte ausführen:
- Konfigurieren Sie ein Objekt vom Typ osg :: GraphicsContext :: Traits
- Erstellen Sie einen grafischen Fensterkontext
- Verknüpfen Sie diesen Grafikkontext mit der Kamera
- Machen Sie die Kamera zum Hauptbetrachter
Beispiel für Eigenschaftenmain.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(); }
Erstellen Sie zum Festlegen der Fenstereinstellungen eine Instanz der Klasse osg :: GraphicsContext :: Traits und initialisieren Sie sie mit den erforderlichen Parametern
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;
Danach erstellen wir einen grafischen Kontext, indem wir einen Zeiger auf Merkmale als Einstellungen übergeben
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
Erstellen Sie eine Kamera
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
Wir verknüpfen die Kamera mit dem erstellten grafischen Kontext
camera->setGraphicsContext(gc);
Richten Sie das Ansichtsfenster ein, legen Sie die Pufferreinigungsmaske und die Reinigungsfarbe fest
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) );
Richten Sie eine perspektivische Projektionsmatrix ein
double aspect = static_cast<double>(traits->width) / static_cast<double>(traits->height); camera->setProjectionMatrixAsPerspective(30.0, aspect, 1.0, 1000.0);
Vergessen Sie nicht, den Tiefentest für die korrekte Anzeige von Gesichtern zu aktivieren
camera->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
Laden des Flugzeugmodells
osg::ref_ptr<osg::Node> root = osgDB::readNodeFile("../data/cessna.osg");
Wir konfigurieren und starten den Viewer und geben die Kamera an, die wir in der Qualität der Hauptkamera konfiguriert haben
osgViewer::Viewer viewer; viewer.setCamera(camera.get()); viewer.setSceneData(root.get()); return viewer.run();
Am Ausgang haben wir ein Fenster mit den erforderlichen Parametern

Der Fenstertitel wird nicht angezeigt, da diese Funktion in den Einstellungen meines Fenstermanagers deaktiviert ist. Wenn Sie das Beispiel unter Windows oder Linux mit unterschiedlichen Einstellungen ausführen, wird der Header an seiner Stelle platziert.
Fortsetzung folgt...