OSG中背景的设置
嘗試了兩種不同的方式設(shè)置背景。
創(chuàng)建HUD相機(jī)
圖片背景
主要是通過osg::Iamge讀取圖片文件后渲染到Texture2D,關(guān)聯(lián)到hud相機(jī)中子節(jié)點(diǎn)上,重點(diǎn)還是hud相機(jī)的設(shè)置:
osg::ref_ptr<osg::Group> group = new osg::Group;osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");group->addChild(node);//創(chuàng)建hud相機(jī)osg::ref_ptr<osg::Camera> hudCamera = new osg::Camera;osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;osg::ref_ptr<osg::Image> image = osgDB::readImageFile("E:/wallpaper/road.jpg");texture->setImage(image.get());osg::ref_ptr<osg::Drawable> quad = osg::createTexturedQuadGeometry(osg::Vec3(0.f, 0.f, 0.f), osg::Vec3(1.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 1.0f, 0.0f));quad->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture.get());osg::ref_ptr<osg::Geode> geode = new osg::Geode;geode->addDrawable(quad.get());geode->setNodeMask(1024);hudCamera->setClearMask(0);hudCamera->setCullingActive(false);hudCamera->setAllowEventFocus(false);hudCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);hudCamera->setRenderOrder(osg::Camera::POST_RENDER);hudCamera->setProjectionMatrix(osg::Matrix::ortho2D(0.0, 1.0, 0.0, 1.0));hudCamera->setViewport(0, 0, 800, 600);hudCamera->addChild(geode.get());osg::StateSet* ss = hudCamera->getOrCreateStateSet();ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);ss->setAttributeAndModes(new osg::Depth(osg::Depth::LEQUAL, 1.0, 1.0));group->addChild(hudCamera);osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;viewer->setSceneData(group);viewer->setUpViewInWindow(500, 500, 800, 600);return viewer->run();漸變色背景
漸變色背景的實(shí)現(xiàn)中hud的創(chuàng)建是一致的。顏色顯示也可以通過第一種方式去實(shí)現(xiàn),比如使用qt的qimage自定義填充后當(dāng)成一張圖片被osg讀入,也可以使用設(shè)置頂點(diǎn)數(shù)組和顏色數(shù)組的方式,如:
osg::ref_ptr<osg::Group> group = new osg::Group;osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");group->addChild(node);//創(chuàng)建hud相機(jī)osg::ref_ptr<osg::Camera> hudCamera = new osg::Camera;osg::ref_ptr<osg::Geometry> quad = new osg::Geometry;osg::ref_ptr<osg::Vec3Array> vertex = new osg::Vec3Array;vertex->push_back(osg::Vec3(0.0, 0.0, 0.0));vertex->push_back(osg::Vec3(1.0, 0.0, 0.0));vertex->push_back(osg::Vec3(1.0, 1.0, 0.0));vertex->push_back(osg::Vec3(0.0, 1.0, 0.0));quad->setVertexArray(vertex);osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array;color->push_back(osg::Vec4(0.0, 1.0, 1.0, 1.0));color->push_back(osg::Vec4(0.0, 1.0, 1.0, 1.0));color->push_back(osg::Vec4(0.0, 0.0, 1.0, 1.0));color->push_back(osg::Vec4(0.0, 0.0, 1.0, 1.0));quad->setColorArray(color, osg::Array::BIND_PER_VERTEX);quad->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));...節(jié)點(diǎn)的添加與hud相機(jī)的設(shè)置同上...shader
漸變色背景
通過使用shader創(chuàng)建一個(gè)全屏的三角形來充當(dāng)背景,原理是從opengl漸變背景這篇文章中看到的。
#define SHADER_HEADER "#version 330 core\n" #define SHADER_STR(x) #xint main() {osg::ref_ptr<osg::Geometry> geo = new osg::Geometry;const char* vs_src = (const char*)SHADER_HEADER SHADER_STR(out vec2 v_uv;void main(){uint idx = uint(gl_VertexID);gl_Position = vec4(idx & 1U, idx >> 1U, 0.0, 0.5) * 4.0 - 1.0;v_uv = vec2(gl_Position.xy * 0.5 + 0.5);});const char* fs_src = (const char*)SHADER_HEADER SHADER_STR(uniform vec4 top_color = vec4(0.0, 1.0, 1.0, 1.0);uniform vec4 bot_color = vec4(0.0, 0.0, 1.0, 1.0);in vec2 v_uv;out vec4 frag_color;void main(){frag_color = bot_color * (1 - v_uv.y) + top_color * v_uv.y;});osg::ref_ptr<osg::Shader> vertexShader = new osg::Shader(osg::Shader::VERTEX, vs_src);osg::ref_ptr<osg::Shader> fragmentShader = new osg::Shader(osg::Shader::FRAGMENT, fs_src);osg::ref_ptr<osg::Program> m_program = new osg::Program;m_program->addShader(vertexShader);m_program->addShader(fragmentShader);geo->getOrCreateStateSet()->setAttributeAndModes(m_program, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);//osg中還是需要傳遞頂點(diǎn),不然畫不出來osg::Vec3Array* vertices = new osg::Vec3Array;vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));vertices->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));vertices->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));geo->setVertexArray(vertices);geo->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, 3));geo->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);//小于0表示優(yōu)先繪制,處于底層geo->getOrCreateStateSet()->setRenderBinDetails(-2, "RenderBin");osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");osg::ref_ptr<osg::Group> group = new osg::Group;group->addChild(node);group->addChild(geo);osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;viewer->setSceneData(group);viewer->setUpViewInWindow(500, 500, 800, 600);return viewer->run(); }圖片背景
大體和上面一致,修改了shader來對紋理采樣:
#define SHADER_HEADER "#version 330 core\n" #define SHADER_STR(x) #xint main() {...同上...const char* fs_src = (const char*)SHADER_HEADER SHADER_STR(uniform sampler2D tex;in vec2 v_uv;out vec4 frag_color;void main(){vec4 tempColor = texture(tex, v_uv);frag_color = tempColor;});...shader的編譯和節(jié)點(diǎn)其他屬性的設(shè)置代碼同上...osg::ref_ptr<osg::Texture2D> tex2d = new osg::Texture2D;tex2d->setDataVariance(osg::Object::DYNAMIC);tex2d->setImage(osgDB::readImageFile("E:/wallpaper/road.jpg"));geo->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex2d, osg::StateAttribute::ON);...場景的設(shè)置和節(jié)點(diǎn)的添加代碼同上... }總結(jié)
- 上一篇: 直播平台开发直播特效的原理与难点
- 下一篇: Unity3D消消乐实现原理