OpenSceneGraph: Mengenkripsi Mesin OpenGL State

gambar

Pendahuluan


Sebagai aturan, ketika bekerja dengan parameter rendering, OpenGL bertindak sebagai mesin status. Status render adalah kumpulan atribut status, seperti sumber cahaya, bahan, tekstur, dan mode tampilan, dihidupkan dan dimatikan oleh fungsi glEnable () dan glDisable (). Ketika negara tertentu diatur, ia tetap berlaku sampai beberapa fungsi lain mengubahnya. Pipa OpenGL mendukung tumpukan keadaan untuk menyimpan dan memulihkan keadaan pada waktu tertentu. Mesin negara memberi pengembang kendali penuh atas status rendering saat ini dan yang disimpan pada stack.

Namun, pendekatan ini tidak nyaman ketika bekerja dengan OSG. Untuk alasan ini, mesin status OpenGL dienkapsulasi oleh kelas osg :: StateSet, yang menangani masalah stack negara dan mengaturnya dalam proses melintasi grafik adegan.

Sebuah instance dari kelas osg :: StateSet berisi subset dari berbagai status rendering dan dapat menerapkannya ke osg :: Node adegan node dan osg :: Objek geometris yang dapat digambar menggunakan metode setStateSet ()

osg::StateSet *stateset = new osg::StateSet; node->setStateSet(stateset); 

Cara yang lebih aman adalah dengan menggunakan metode getOrCreateStateSet (), yang menjamin kembalinya keadaan yang benar dan lampirannya ke node atau objek yang dapat digambar

 osg::StateSet *stateset = node->getOrCreateStateSet(); 

Osg :: Node dan osg :: Kelas Drawable mengontrol variabel anggota osg :: StateSet melalui penunjuk pintar osg :: ref_ptr <>. Ini berarti bahwa satu set negara dapat dibagi antara beberapa objek dalam adegan dan akan dihancurkan hanya ketika semua objek ini dihancurkan.

1. Atribut dan mode


OSG mendefinisikan kelas osg :: StateAttribute untuk menyimpan atribut rendering. Ini adalah kelas dasar virtual yang diwarisi oleh berbagai atribut render seperti cahaya, material, dan kabut.

Mode rendering berfungsi seperti sakelar yang dapat dihidupkan dan dimatikan. Selain itu, mereka terkait dengan enumerator, yang digunakan untuk menunjukkan jenis mode OpenGL. Terkadang mode rendering dikaitkan dengan atribut, misalnya, mode GL_LIGHTING mencakup variabel untuk sumber cahaya yang dikirim ke pipa OpenGL ketika dihidupkan, dan mematikan pencahayaan jika tidak.

Kelas osg :: StateSet membagi atribut dan mode menjadi dua kelompok: tekstur dan non-tekstur. Ini memiliki beberapa metode publik untuk menambahkan atribut dan mode non-tekstur ke serangkaian negara:

  1. setAttribute () - Menambahkan objek bertipe osg :: StateAttribute ke set state. Atribut dengan tipe yang sama tidak dapat hidup berdampingan di set status yang sama. Setpoint sebelumnya akan ditimpa dengan yang baru.
  2. setMode () - melampirkan enumerator mode ke set negara dan menetapkan nilainya ke osg :: StateAttribute :: ON atau osg :: StateAttribute :: OFF, yang berarti mengaktifkan atau menonaktifkan mode.
  3. setAttributeAndModes () - melampirkan atribut render dan mode yang terkait dan menetapkan nilai switch (default ke ON). Harus diingat bahwa tidak setiap atribut memiliki mode yang sesuai, tetapi Anda dapat menggunakan metode ini dalam hal apa pun.

Untuk mengatur atribut dan mode yang terkait, Anda dapat menggunakan kode ini

 stateset->setAttributeAndModes(attr, osg::StateAttribute::ON); 

Untuk mengatur atribut tekstur, parameter tambahan harus diberikan untuk menunjukkan tekstur yang harus diterapkan. Osg :: StateSet menyediakan beberapa metode publik lainnya untuk ini, seperti setTextureAttribute (), setTextureMode (), dan setTextureAttributeAndModes ()

 stateset->setTextureAttributeAndModes(0, textattr, osg::StateAttribute::ON); 

menerapkan atribut textattr ke tekstur dengan pengidentifikasi 0.

2. Mengatur mode tampilan poligon untuk node pemandangan


Kami menggambarkan teori di atas dengan contoh praktis - mengubah mode rasterisasi poligon OpenGL menggunakan kelas osg :: PolygonMode, yang diturunkan dari osg :: StateAttribute. Kelas ini mengenkapsulasi fungsi glPolygonMode () dan menyediakan antarmuka untuk mengatur mode tampilan poligon untuk node adegan tertentu.

Contoh polygonmode
main.h
 #ifndef MAIN_H #define MAIN_H #include <osg/PolygonMode> #include <osg/MatrixTransform> #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::Node> model = osgDB::readNodeFile("../data/cessna.osg"); osg::ref_ptr<osg::MatrixTransform> transform1 = new osg::MatrixTransform; transform1->setMatrix(osg::Matrix::translate(-25.0f, 0.0f, 0.0f)); transform1->addChild(model.get()); osg::ref_ptr<osg::MatrixTransform> transform2 = new osg::MatrixTransform; transform2->setMatrix(osg::Matrix::translate(25.0f, 0.0f, 0.0f)); transform2->addChild(model.get()); osg::ref_ptr<osg::PolygonMode> pm = new osg::PolygonMode; pm->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE); transform1->getOrCreateStateSet()->setAttribute(pm.get()); osg::ref_ptr<osg::Group> root = new osg::Group; root->addChild(transform1.get()); root->addChild(transform2.get()); osgViewer::Viewer viewer; viewer.setSceneData(root.get()); return viewer.run(); } 


Di sini kita mengunggah model cessna kita tercinta dan menerapkan transformasi padanya, kita mendapatkan dua contoh model cessna. Untuk salah satu dari mereka, di sebelah kiri, kami menerapkan atribut yang mengatur mode tampilan wireframe poligon

 osg::ref_ptr<osg::PolygonMode> pm = new osg::PolygonMode; pm->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE); transform1->getOrCreateStateSet()->setAttribute(pm.get()); 



Jika kita beralih ke spesifikasi OpenGL, kita dapat dengan mudah membayangkan opsi tampilan poligon apa yang akan tersedia bagi kita ketika menggunakan setMode () dalam kasus khusus ini. Parameter pertama dapat mengambil nilai osg :: PolygonMode :: FRONT, BACK dan FRONT_AND_BACK, sesuai dengan enumerator OpenGL GL_FRONT, GL_BACK, GL_FRONT_AND_BACK. Parameter kedua dapat mengambil nilai osg :: PolygonMode :: POINT, LINE dan FILL, yang sesuai dengan GL_POINT, GL_LINE dan GL_FILL. Tidak ada trik lain, seperti yang sering terjadi ketika mengembangkan OpenGL murni, tidak diperlukan di sini - OSG menangani sebagian besar pekerjaan. Mode tampilan poligon tidak memiliki mode terkait dan tidak perlu memanggil pasangan glEnable () / glDisable (). Metode setAttributeAndModes () akan berfungsi dengan baik dalam kasus ini juga, tetapi nilai parameter ketiga tidak akan berguna.

3. Warisan status render. Menerapkan Atribut dan Mode


Himpunan status simpul mempengaruhi simpul saat ini dan semua anak-anaknya. Misalnya, atribut osg :: PolygonMode yang ditetapkan untuk transform1 dari contoh sebelumnya akan diterapkan ke semua anak dari simpul ini. Namun, simpul anak dapat mengesampingkan atribut induk, yaitu, keadaan rendering akan diwarisi dari simpul induk jika simpul anak tidak mengubah perilaku.

Terkadang Anda perlu mendefinisikan kembali perilaku simpul dalam hal penggunaan atribut. Misalnya, di sebagian besar editor 3D, pengguna dapat memuat beberapa model dan mengubah mode tampilan untuk semua model yang dimuat pada waktu yang sama, terlepas dari bagaimana mereka ditampilkan sebelumnya. Dengan kata lain, semua model dalam editor harus mewarisi atribut tunggal, terlepas dari bagaimana mereka ditetapkan sebelumnya untuk masing-masing model. Di OSG, ini dapat diimplementasikan menggunakan flag osg :: StateAttribute :: OVERRIDE, misalnya

 stateset->StateAttribute(attr, osg::StateAttribute::OVERRIDE); 

Saat mengatur mode dan mode dengan atribut, operator ATAU bitwise digunakan

 stateset->StateAttributeAndModes(attr, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); 

Selain itu, atribut juga dapat dilindungi dari penggantian - untuk ini, atribut harus ditandai dengan osg :: StateAttribute :: flag PROTECTED.

Ada flag ketiga, osg :: StateAttribute :: INHERIT, yang digunakan untuk menunjukkan bahwa atribut ini harus diwarisi dari kumpulan state dari node induk.

Berikut adalah contoh singkat menggunakan flag OVERRIDE dan PROTECTED. Node root akan diatur ke OVERRIDE untuk memaksa semua node turunan mewarisi atribut dan modenya. Dalam kasus ini, child node akan mencoba mengubah statusnya dengan atau tanpa bantuan flag PROTECTED, yang akan menghasilkan hasil yang berbeda.

Mewarisi contoh teks
main.h
 #ifndef MAIN_H #define MAIN_H #include <osg/PolygonMode> #include <osg/MatrixTransform> #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::Node> model = osgDB::readNodeFile("../data/glider.osg"); osg::ref_ptr<osg::MatrixTransform> transform1 = new osg::MatrixTransform; transform1->setMatrix(osg::Matrix::translate(-0.5f, 0.0f, 0.0f)); transform1->addChild(model.get()); osg::ref_ptr<osg::MatrixTransform> transform2 = new osg::MatrixTransform; transform2->setMatrix(osg::Matrix::translate(0.5f, 0.0f, 0.0f)); transform2->addChild(model.get()); osg::ref_ptr<osg::Group> root = new osg::Group; root->addChild(transform1.get()); root->addChild(transform2.get()); transform1->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); transform2->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED); root->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); osgViewer::Viewer viewer; viewer.setSceneData(root.get()); return viewer.run(); } 




Untuk memahami apa yang terjadi, Anda perlu melihat seperti apa tampilan glider yang biasanya menyala dengan mengunduh osgviewer OSG penuh waktu

 $ osgviewer glider.osg 

Dalam contoh ini, kami mencoba mengubah mode pencahayaan untuk node transform1 dan transform2 dengan sepenuhnya mematikan pencahayaan.

 transform1->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); transform2->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED); 

Dalam hal ini, kita menyalakan mode pencahayaan untuk simpul root, dan menggunakan bendera OVERRIDE untuk semua simpul turunannya, sehingga mereka mewarisi keadaan simpul akar. Namun, trnsform2 menggunakan flag PROTECTED untuk mencegah pengaturan simpul root mempengaruhi.

 transform2->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED); 

Akibatnya, terlepas dari kenyataan bahwa kami mematikan pencahayaan di node transform1, hang glider kiri masih menyala, karena pengaturan root scene memblokir upaya kami untuk mematikan pencahayaan untuk itu. Glider hang kanan ditampilkan tanpa pencahayaan (kelihatannya lebih cerah hanya karena dibanjiri dengan warna yang sederhana tanpa memberikan pencahayaan), karena transform2 dilindungi dari mewarisi atribut dari node root.

4. Daftar Atribut OpenGL yang Didukung di OpenSceneGraph


OSG mendukung hampir semua atribut dan mode rendering yang didukung oleh OpenGL melalui kelas-kelas yang diturunkan dari osg :: StateAttribute. Tabel menunjukkan semua parameter mesin status OpenGL yang tersedia dari engine.
ID jenis atributNama kelasMode terkaitFungsi OpenGL Setara
ALPHEFUNCosg :: AlphaFuncGL_ALPHA_TESTglAlphaFunc ()
BLENDFUNCosg :: BlendFuncGL_BLENDglBlendFunc () dan glBlendFuncSeparate ()
KLIPPLANosg :: ClipPlaneGL_CLIP_PLANEi (i dari 1 hingga 5)glClipPlane ()
Colormaskosg :: ColorMask-glColorMask ()
CULLFACEosg :: CullFaceGL_CULLFACEglCullFace ()
Kedalamanosg :: KedalamanGL_DEPTH_TESTglDepthFunc (), glDepthRange () dan glDepthMask ()
KABUTosg :: KabutGL_FOGglFog ()
FRONTFACEosg :: FrontFace-glFrontFace ()
Ringanosg :: CahayaGL_LIGHTi (i dari 1 hingga 7)glLight ()
LIGHTMODELosg :: LightModel-glLightModel ()
LINESTRIPPLEosg :: LineStrippleGL_LINE_STRIPPLEglLineStripple ()
LINEWIDTHosg :: LineWidth-glLineWidht ()
LOGICOPosg :: LogicOpGL_COLOR_LOGIC_OPglLogicOp ()
BAHANosg :: Bahan-glMaterial () dan glColorMaterial ()
TITIKosg :: PoinGL_POINT_SMOOTHglPointParameter ()
POINTSPRITEosg :: PointSpriteGL_POINT_SPRITE_ARBFungsi untuk bekerja dengan sprite OpenGL
POLYGONMODEosg :: PolygonMode-glPolygonMode ()
POLYGONOFFSETosg :: PolygonOffsetGL_POLYGON_OFFSET_POINTglPolygonOffset ()
POLYGONSTRIPPLEosg :: PolygonStrippleGL_POLYGON_STRIPPLEglPolygonStripple ()
GUNTINGosg :: GuntingGL_SCISSOR_TESTglScissor ()
SHADEMODELosg :: ShadeModel-glShadeModel ()
STENCILosg :: StensilGL_STENCIL_TESTglStencilFunc (), glStencilOp () dan glStencilMask ()
Texenvosg :: TexEnv-glTexEnv ()
Texgenosg :: TexGenGL_TEXTURE_GEN_SglTexGen ()

Kolom ID tipe atribut menunjukkan pengidentifikasi OSG spesifik yang mengidentifikasi atribut ini di enumerator dari osg :: StateAttribute class. Ini dapat digunakan dalam metode getAttribute untuk mendapatkan nilai atribut tertentu.

 osg::PolygonMode *pm = dynamic_cast<osg::PolygonMode *>(stateset->getAttribute(osg::StateAttribute::POLYGONMODE)); 

Pointer yang valid menunjukkan bahwa atribut telah ditetapkan sebelumnya. Jika tidak, metode ini akan berbohong NULL. Anda juga bisa mendapatkan nilai mode saat ini menggunakan panggilan

 osg::StateAttribute::GLModeValue value = stateset->getMode(GL_LIGHTING); 

Di sini enumerator GL_LIGHTING digunakan untuk mengaktifkan / menonaktifkan pencahayaan di seluruh adegan.

5. Menerapkan kabut ke model di tempat kejadian


Mari kita kutip efek kabut sebagai cara ideal untuk menunjukkan cara bekerja dengan berbagai atribut dan mode rendering. OpenGL menggunakan satu persamaan linear dan dua eksponensial yang menggambarkan model kabut, didukung oleh kelas osg :: Fog.

Contoh kabut teks
main.h
 #ifndef MAIN_H #define MAIN_H #include <osg/Fog> #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::Fog> fog = new osg::Fog; fog->setMode(osg::Fog::LINEAR); fog->setStart(500.0f); fog->setEnd(2500.0f); fog->setColor(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f)); osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("../data/lz.osg"); model->getOrCreateStateSet()->setAttributeAndModes(fog.get()); osgViewer::Viewer viewer; viewer.setSceneData(model.get()); return viewer.run(); } 


Pertama, buat atribut kabut. Kami menggunakan model linier, sesuaikan rentang tampilan kabut dengan jarak ke model

 osg::ref_ptr<osg::Fog> fog = new osg::Fog; fog->setMode(osg::Fog::LINEAR); fog->setStart(500.0f); fog->setEnd(2500.0f); fog->setColor(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f)); 

Kami memuat sampel lansekap lz.osg dan menerapkan atribut ini padanya

 osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("../data/lz.osg"); model->getOrCreateStateSet()->setAttributeAndModes(fog.get()); 

Di jendela penampil, kita melihat lanskap buram, dan kita bisa melihat bagaimana kepadatan kabut berubah tergantung pada jarak ke model







6. Bekerja dengan sumber cahaya dan pencahayaan


Seperti halnya OpenGL, OSG mendukung hingga delapan sumber cahaya untuk secara langsung bertemu objek pemandangan. Seperti OpenGL, OSG tidak secara otomatis menghitung bayangan. Sinar cahaya datang dari sumber-sumber dalam garis lurus, dipantulkan dari objek dan disebarkan oleh mereka, setelah itu mereka dilihat oleh mata penonton. Untuk pemrosesan pencahayaan berkualitas tinggi, perlu mengatur sifat material, geometri objek normal, dll.

Osg :: Light class menyediakan metode untuk mengendalikan sumber cahaya, termasuk: setLightNum () dan getLightNum () - untuk bekerja dengan jumlah sumber; setAmbient () dan getAmbient () untuk mengontrol komponen di sekitarnya; setDiffuse () dan getDiffuse () - untuk bekerja dengan komponen yang tersebar, dll.

OSG juga menjelaskan kelas osg :: LightSource untuk menambahkan sumber cahaya ke TKP. Ini memberikan metode setLight () dan merupakan simpul daun dari grafik adegan dengan atribut tunggal. Semua node lain dari grafik adegan dipengaruhi oleh sumber cahaya jika mode yang sesuai untuk GL_LIGHTi diatur. Sebagai contoh:

 //   1 osg::ref_ptr<osg::Light> light = new osg::Light; light->setLightNum( 1 ); ... //       osg::ref_ptr<osg::LightSource> lightSource = new osg::LightSource; lightSource->setLight( light.get() ); ... //             root->addChild( lightSource.get() ); root->getOrCreateStateSet()->setMode( GL_LIGHT1, osg::StateAttribute::ON ); 

Solusi lain yang lebih nyaman adalah metode setStateSetModes (), dengan mana sumber cahaya dengan nomor yang diinginkan secara otomatis dilampirkan ke node root

 root->addChild( lightSource.get() ); lightSource->setStateSetModes( root->getOrCreateStateSet(), osg::StateAttribute::ON ); 

Anda dapat menambahkan node anak ke sumber cahaya, tetapi ini tidak berarti sama sekali, Anda akan menerangi subgraph yang terkait dengannya entah bagaimana dengan cara yang khusus. Ini akan diproses sebagai geometri, diwakili oleh bentuk fisik sumber cahaya.

Osg :: LightSource node dapat dilampirkan ke node transformasi, dan, misalnya, sumber cahaya titik dapat dipindahkan di ruang angkasa. Ini dapat dinonaktifkan dengan mengatur sistem koordinat absolut untuk sumber cahaya.

 lightSource->setReferenceFrame( osg::LightSource::ABSOLUTE_RF ); 

7. Membuat sumber cahaya di tempat kejadian


Secara default, OSG secara otomatis mengatur sumber cahaya ke angka 0, yang memancarkan cahaya arah seragam ke tempat kejadian. Namun, kapan saja Anda dapat menambahkan beberapa sumber cahaya tambahan, dan bahkan mengendalikannya menggunakan node transformasi koordinat. Hanya sumber posisi (sumber titik) yang dapat dipindahkan. Cahaya directional hanya memiliki arah (aliran sinar paralel yang datang dari tak terbatas) dan tidak terikat pada posisi tertentu di atas panggung. OpenGL dan OSG menggunakan komponen keempat dari parameter posisi untuk menentukan jenis sumber cahaya. Jika 0, maka cahaya dianggap sebagai diarahkan; dengan nilai 1 - posisi.

Pertimbangkan contoh kecil bekerja dengan pencahayaan.

Judul spoiler
main.h
 #ifndef MAIN_H #define MAIN_H #include <osg/MatrixTransform> #include <osg/LightSource> #include <osgDB/ReadFile> #include <osgViewer/Viewer> #endif 

main.cpp

 #include "main.h" //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ osg::Node *createLightSource(int num, const osg::Vec3 &trans, const osg::Vec4 &color) { osg::ref_ptr<osg::Light> light = new osg::Light; light->setLightNum(num); light->setDiffuse(color); light->setPosition(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); osg::ref_ptr<osg::LightSource> lightSource = new osg::LightSource; lightSource->setLight(light); osg::ref_ptr<osg::MatrixTransform> sourceTrans = new osg::MatrixTransform; sourceTrans->setMatrix(osg::Matrix::translate(trans)); sourceTrans->addChild(lightSource.get()); return sourceTrans.release(); } //------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ int main(int argc, char *argv[]) { (void) argc; (void) argv; osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("../data/cessna.osg"); osg::ref_ptr<osg::Group> root = new osg::Group; root->addChild(model.get()); osg::Node *light0 = createLightSource(0, osg::Vec3(-20.0f, 0.0f, 0.0f), osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f)); osg::Node *light1 = createLightSource(1, osg::Vec3(0.0f, -20.0f, 0.0f), osg::Vec4(0.0f, 1.0f, 1.0f, 1.0f)); root->getOrCreateStateSet()->setMode(GL_LIGHT0, osg::StateAttribute::ON); root->getOrCreateStateSet()->setMode(GL_LIGHT1, osg::StateAttribute::ON); root->addChild(light0); root->addChild(light1); osgViewer::Viewer viewer; viewer.setSceneData(root.get()); return viewer.run(); } 


Untuk membuat sumber cahaya, kami memiliki fungsi terpisah

 osg::Node *createLightSource(int num, const osg::Vec3 &trans, const osg::Vec4 &color) { osg::ref_ptr<osg::Light> light = new osg::Light; light->setLightNum(num); light->setDiffuse(color); light->setPosition(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); osg::ref_ptr<osg::LightSource> lightSource = new osg::LightSource; lightSource->setLight(light); osg::ref_ptr<osg::MatrixTransform> sourceTrans = new osg::MatrixTransform; sourceTrans->setMatrix(osg::Matrix::translate(trans)); sourceTrans->addChild(lightSource.get()); return sourceTrans.release(); } 

Dalam fungsi ini, pertama-tama kita menentukan parameter pencahayaan yang diberikan oleh sumber, sehingga menciptakan atribut GL_LIGHTi

 osg::ref_ptr<osg::Light> light = new osg::Light; //    light->setLightNum(num); //   light->setDiffuse(color); //  .     ,    light->setPosition(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 

Setelah itu, sumber cahaya dibuat dimana atribut ini diberikan.

 osg::ref_ptr<osg::LightSource> lightSource = new osg::LightSource; lightSource->setLight(light); 

Kami membuat dan mengkonfigurasi node transformasi, melewati sumber cahaya kami sebagai node anak

 osg::ref_ptr<osg::MatrixTransform> sourceTrans = new osg::MatrixTransform; sourceTrans->setMatrix(osg::Matrix::translate(trans)); sourceTrans->addChild(lightSource.get()); 

Kembalikan pointer ke node transformasi

 return sourceTrans.release(); 

Dalam tubuh program utama, kami memuat model tiga dimensi (sekali lagi, cessna favorit kami)

 osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("../data/cessna.osg"); osg::ref_ptr<osg::Group> root = new osg::Group; root->addChild(model.get()); 

Kami membuat dua sumber cahaya dengan angka 0 dan 1. Yang pertama akan bersinar kuning, yang kedua - biru-hijau

 osg::Node *light0 = createLightSource(0, osg::Vec3(-20.0f, 0.0f, 0.0f), osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f)); osg::Node *light1 = createLightSource(1, osg::Vec3(0.0f, -20.0f, 0.0f), osg::Vec4(0.0f, 1.0f, 1.0f, 1.0f)); 

Kami memberi tahu mesin status OpenGL bahwa perlu menyalakan 0 dan 1 sumber cahaya dan menambahkan sumber yang kami buat ke tempat kejadian

 root->getOrCreateStateSet()->setMode(GL_LIGHT0, osg::StateAttribute::ON); root->getOrCreateStateSet()->setMode(GL_LIGHT1, osg::StateAttribute::ON); root->addChild(light0); root->addChild(light1); 

Setelah menginisialisasi dan memulai penampil, kami mendapatkan gambar



Kesimpulan


Sangat tersentuh oleh perhatian orang-orang yang tertarik pada siklus ini. Tindakan ini tidak dimulai dengan banyak, tetapi saya merasa bahwa masyarakat membutuhkan artikel. Terima kasih atas semua jenis umpan balik positif.

Hari ini saya mencoba mempertimbangkan, sekali lagi, hal-hal yang agak mendasar dari mesin OSG. Tidak yakin apa yang keluar keren. Tetapi sejauh ini saya menetapkan hal-hal yang sangat primitif, di mana saya sendiri memahaminya. Saya memeriksa semua contoh secara pribadi, repositori saya tersedia di sini . Terima kasih, kawan-kawan terkasih, saya akan berusaha menjaga agar kisah ini terus berlanjut ...

Source: https://habr.com/ru/post/id430348/


All Articles