osg fbo(一),生成颜色缓冲区图片

2023-10-30

由于工作需要,重新捡了下shader。很明显,fbo是重中之重。好记性不如烂笔头,先记录下

1,生成一个颜色纹理(为了省事,可以将纹理宽高=屏幕宽高)

osg::ref_ptr<osg::Texture2D> tex = createFloatRectangleTexture(texWidth, texHeight);

2,采样摄像机添加场景根,并把场景根的颜色缓冲区与纹理关联,

	sampleCamera->addChild(sceneRoot);
	sampleCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); //这句话使内容不渲染到屏幕上
	sampleCamera->attach(osg::Camera::COLOR_BUFFER0, tex); //关联颜色贴图

3,将纹理关联到面片上,以方便加载使用

osg::ref_ptr<osg::Geode> panelGeode = createTexturePanelGeode();
osg::ref_ptr<osg::StateSet> ss = panelGeode->getOrCreateStateSet();
ss->setTextureAttributeAndModes(0, tex);

4,这个面片关联的纹理,由于是在摄像机坐标系下,所以要规格化坐标系,位置【-1,1】
纹理坐标【0,1】

osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
vertices->push_back(osg::Vec3(-1.0f, -1.0f, 0.0f));
vertices->push_back(osg::Vec3(1.0f, -1.0f, 0.0f));
vertices->push_back(osg::Vec3(1.0f, 1.0f, 0.0f));
vertices->push_back(osg::Vec3(-1.0f, 1.0f, 0.0f));

osg::ref_ptr<osg::Vec2Array> texCoord = new osg::Vec2Array;
texCoord->push_back(osg::Vec2(0.0, 0.0));
texCoord->push_back(osg::Vec2(1.0, 0.0));
texCoord->push_back(osg::Vec2(1.0, 1.0));
texCoord->push_back(osg::Vec2(0.0, 1.0));

4,三维转二维,就是贴图片的过程,FBO中的图片一般还要进行一个图像处理,所以要设置一个passRoot,用于显示。这个passroot要同时包含采样摄像机和面片才行。

passRoot->addChild(sampleCamera); //将摄像机加入场景
passRoot->addChild(panelGeode);
viewer->setSceneData(passRoot);

运行结果如下:
在这里插入图片描述
代码如下:

#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <osg/CoordinateSystemNode>

#include <osg/Switch>
#include <osg/Types>
#include <osgText/Text>

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <osgGA/SphericalManipulator>

#include <osgGA/Device>
#include <osg/Shader>

osg::ref_ptrosg::Texture2D createFloatRectangleTexture(int width, int height)
{
osg::ref_ptrosg::Texture2D tex2D = new osg::Texture2D;
tex2D->setTextureSize(width, height);
tex2D->setInternalFormat(GL_RGBA16F_ARB);
tex2D->setSourceFormat(GL_RGBA);
tex2D->setSourceType(GL_FLOAT);
return tex2D.release();
}
osg::ref_ptrosg::Geode createTexturePanelGeode()
{
osg::ref_ptrosg::Vec3Array vertices = new osg::Vec3Array;
vertices->push_back(osg::Vec3(-1.0f, -1.0f, 0.0f));
vertices->push_back(osg::Vec3(1.0f, -1.0f, 0.0f));
vertices->push_back(osg::Vec3(1.0f, 1.0f, 0.0f));
vertices->push_back(osg::Vec3(-1.0f, 1.0f, 0.0f));

osg::ref_ptr<osg::Vec2Array> texCoord = new osg::Vec2Array;
texCoord->push_back(osg::Vec2(0.0, 0.0));
texCoord->push_back(osg::Vec2(1.0, 0.0));
texCoord->push_back(osg::Vec2(1.0, 1.0));
texCoord->push_back(osg::Vec2(0.0, 1.0));

osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
geom->setVertexArray(vertices);
geom->setTexCoordArray(0, texCoord);
geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));

osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(geom);
osg::ref_ptr<osg::StateSet> set1 = geode->getOrCreateStateSet();
set1->setMode(GL_LIGHTING, osg::StateAttribute::OFF); //设置不受光照影响,不然太暗了就看不清楚
return geode;

}

int main()
{
osg::ref_ptrosgViewer::Viewer viewer = new osgViewer::Viewer;
std::string strFileName = “D:/OpenSceneGraph-master/OpenSceneGraph-Data-master/cow.osg”;
//pass1的根
osg::ref_ptrosg::Group passRoot = new osg::Group();
//场景根
osg::ref_ptrosg::Group sceneRoot = new osg::Group();
osg::ref_ptrosg::Node node = osgDB::readNodeFile(strFileName);
sceneRoot->addChild(node);

//获取系统分辨率
unsigned int screenWidth, screenHeight;
osg::GraphicsContext::WindowingSystemInterface * wsInterface = osg::GraphicsContext::getWindowingSystemInterface();
if (!wsInterface)
{
	return -1;
}
wsInterface->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), screenWidth, screenHeight);
int texWidth = screenWidth;
int texHeight = screenHeight;
osg::ref_ptr<osg::Texture2D> tex = createFloatRectangleTexture(texWidth, texHeight);
//绑定采样摄像机
osg::ref_ptr<osg::Camera> sampleCamera = new osg::Camera;
{
	sampleCamera->addChild(sceneRoot);
	sampleCamera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
	sampleCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); //这句话使内容不渲染到屏幕上
	sampleCamera->attach(osg::Camera::COLOR_BUFFER0, tex); //关联颜色贴图
	//摄像机关联视口
	sampleCamera->setViewport(0, 0, screenWidth, screenHeight);

}
osg::ref_ptr<osg::Geode> panelGeode = createTexturePanelGeode();
osg::ref_ptr<osg::StateSet> ss = panelGeode->getOrCreateStateSet();
ss->setTextureAttributeAndModes(0, tex);

;
passRoot->addChild(sampleCamera); //将摄像机加入场景
passRoot->addChild(panelGeode);
viewer->setSceneData(passRoot);
viewer->run();
return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

osg fbo(一),生成颜色缓冲区图片 的相关文章

  • osg--读写

    文件I O 命名规则 osgdb xxx 比如 osgdb osg osgdb jpeg 关联文件后缀和加载器 osgDB Registry instance gt addFileExtensionAlias jpeg jpeg osgDB
  • 调试最长的一帧(第19天)

    这个主要是理论了 抄一抄 最常用到场景管理方式时场景节点树结构 场景树顶点的叶节点osg Geode包含了各种需要渲染的几何体的顶点和渲染状态信息 而组节点osg Group及其派生出的各种特殊功能节点则作为场景树的各个枝节节点 它们也可以
  • WIN7 64位操作系统 编译64位OSG的方法

    1 在OSG官网上下载OSG源代码 本人下载的是OSG3 4 0 http www openscenegraph org index php download section stable releases 2 下载第三方包 http ww
  • osgEarth的Rex引擎原理分析(四十四)如何控制父子TileNode节点的显隐

    目标 三十七 中的105 rex渲染出的地球是靠一块块TileNode瓦片拼接起来的 瓦片之间存在父子关系 一般显示父TileNode就不应显示子TileNode 反之亦然 那么rex是如何做这种显隐控制呢 1 每一个TileNode瓦片在
  • qedl中的fixDepth()简化

    如果将PerspectiveMode的设置为1 则会传递zNear和Zfar 在fixDepth 中 而将perspectiveMode 0 则大大简化fixDepth float fixDepth float depth return c
  • SingleThreaded是如何进入cull_draw()的?

    正如以前所说 单线程模式是通过cull draw 进行剔除绘制的 如何进入的呢 其实很简单 逆推下 最后 回到梦开始的地方
  • osgearth消除近裁剪平面离物体太近时的裁剪问题

    This will mitigate near clip plane issues if you zoom in close to the ground LogarithmicDepthBuffer buf buf install view
  • 调试最长的一帧(第12天)

    先看看总体 流程走到了更新分页数据库 分页数据库的数据流图 先找上图的4个成员变量 上图中 左侧的图框表示数据的检索和输入 中间的白色图框表示用于数据存储的内存空间 而右边的图框表示存储数据的输出 此外 蓝绿色图框表示可以在DataBase
  • osgFBO(九)多pass---2,pass2,shader将背景从红色变为绿色

    二 pass2是比较完整的 同时有输入纹理和输出纹理 与pass1类似 这里只列出不同的地方 1 pass2摄像机输入tex1 osg ref ptr
  • osgEarth的Rex引擎原理分析(二十三)PagerLoader的traverse过程详解

    目标 十七 中问题48 主要包含两个过程 1 已处理过请求的加载 这是真正意义上的加载 刚创建出来的请求是从缓存或文件没有关联影像 高程等数据的 需要经过多线程处理后才有数据 详见 十七 对于这些处理过的请求 在PagerLoader的更新
  • osgEarth的Rex引擎原理分析(三十三)分页瓦片卸载器子节点的作用

    目标 十二 中的问题22 分页瓦片卸载器是在Rex引擎的setMap函数中创建的 创建之初就关联了活跃瓦片寄存器和资源释放器 作用见下面分析 osgEarthDrivers engine rex RexTerrainEngineNode c
  • 调试最长的一帧(第16天)

    终于到达绘制了 先看总体流程阶段 然而 从并行堆栈上看 已经有渲染线程开启了 跟着电子书走 先是介绍 抄一抄 加深印象 osg的场景渲染过程可以简单地分为三个阶段 用户APP阶段 更新用户数据 负责场景对象的运动和管理等 筛选cull阶段
  • osg报错:错误(活动) E0757 变量 “GLenum“ 不是类型名

    前言 osg报错 错误 活动 E0757 变量 GLenum 不是类型名 原因 osg中封装了openGL的库 感觉vs2019无法识别openGL相关的部分 解决 vs2019中配置 预处理器
  • 调试最长的一帧(第14天)

    看看流程 可见分页数据库的更新也是和场景的筛选绘制是同时进行的 再看看大图 第14天要进行左下角的 依照惯例 跟过去 现在开始步入正轨 发现第0个fileName为空 这是有问题的 创建pagelod时修正为 这次进来了 在这里删除 放入r
  • VS2010+Qt5+OSG3.0开发环境搭建

    一 VS2010 VS2010的安装网上教程很多 不再叙述 二 Qt 在VS中开发程序 需要下载Qt安装包和Qt的VS插件 我用的版本是Qt5 1 1 for Windows VS2010 OpenGL VisualStudio Add i
  • osgEarth的Rex引擎原理分析(六)earth文件如何解析成Config

    目标 解决 一 中的问题 构建地图节点的依据是Config osgEarthDrivers earth EarthFileSerialize2 cpp osg Node EarthFileSerializer2 deserialize co
  • qt5+osg多线程的解决方案

    问题描述 Cannot make QOpenGLContext current in a different thread 解决思路 在主线程中将qt窗体中的QOpenglContext moveToThread到窗体线程中 这样窗体线程在
  • 第38.2节 osg加载大tif-10.20活动直播资源&中秋活动参赛源码

    目录 本节内容 本节内容 根据2021 10 20直播活动的内容 使用VPB处理影像高程的示例 将资源进行打包 里面使用的是VS2019 若使用其它版本的VS 则需要对应的OSG编译包 则在此链接获取 osgChina权威发布 vs各版本第
  • 第36.1节 动画-刚体动画控制

    目录 本节功能 具体实现 存放动画 寻找动画 播放 暂停 复位 加速 减速 最后用一个事件响应来联接这一切 所有代码 本节功能 本节后几个章节会介绍和动画有关的课程 本节实现一个从3DMAX导出的地板破碎的动画的控制 这类动画叫做刚体动画
  • AABB和OBB包围盒简介

    一 AABB立方体边界框检测 用球体去近似地代表物体运算量很小 但在游戏中的大多数物体是方的或者长条形的 应该用方盒来代表物体 另一种常见的检测模型是立方体边界框 如图10 31展示了一个AABB检测盒和它里面的物体 坐标轴平行 Axial

随机推荐