| 113 | | |
| 114 | | // create the quad to visualize. |
| 115 | | osg::Geometry* polyGeom = new osg::Geometry(); |
| 116 | | |
| 117 | | polyGeom->setSupportsDisplayList(false); |
| 118 | | |
| 119 | | osg::Vec3 origin(0.0f,0.0f,0.0f); |
| 120 | | osg::Vec3 xAxis(1.0f,0.0f,0.0f); |
| 121 | | osg::Vec3 yAxis(0.0f,0.0f,1.0f); |
| 122 | | osg::Vec3 zAxis(0.0f,-1.0f,0.0f); |
| 123 | | float height = 100.0f; |
| 124 | | float width = 200.0f; |
| 125 | | int noSteps = 20; |
| 126 | | |
| 127 | | osg::Vec3Array* vertices = new osg::Vec3Array; |
| 128 | | osg::Vec3 bottom = origin; |
| 129 | | osg::Vec3 top = origin; top.z()+= height; |
| 130 | | osg::Vec3 dv = xAxis*(width/((float)(noSteps-1))); |
| 131 | | |
| 132 | | osg::Vec2Array* texcoords = new osg::Vec2Array; |
| 133 | | osg::Vec2 bottom_texcoord(0.0f,0.0f); |
| 134 | | osg::Vec2 top_texcoord(0.0f,1.0f); |
| 135 | | osg::Vec2 dv_texcoord(1.0f/(float)(noSteps-1),0.0f); |
| 136 | | |
| 137 | | for(int i=0;i<noSteps;++i) |
| 138 | | { |
| 139 | | vertices->push_back(top); |
| 140 | | vertices->push_back(bottom); |
| 141 | | top+=dv; |
| 142 | | bottom+=dv; |
| 143 | | |
| 144 | | texcoords->push_back(top_texcoord); |
| 145 | | texcoords->push_back(bottom_texcoord); |
| 146 | | top_texcoord+=dv_texcoord; |
| 147 | | bottom_texcoord+=dv_texcoord; |
| 148 | | } |
| 149 | | |
| 150 | | |
| 151 | | // pass the created vertex array to the points geometry object. |
| 152 | | polyGeom->setVertexArray(vertices); |
| 153 | | |
| 154 | | polyGeom->setTexCoordArray(0,texcoords); |
| 155 | | |
| 156 | | |
| 157 | | osg::Vec4Array* colors = new osg::Vec4Array; |
| 158 | | colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); |
| 159 | | polyGeom->setColorArray(colors); |
| 160 | | polyGeom->setColorBinding(osg::Geometry::BIND_OVERALL); |
| 161 | | |
| 162 | | polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,0,vertices->size())); |
| 163 | | |
| 164 | | |
| 165 | | |
| 166 | | unsigned int tex_width = 2048; |
| 167 | | unsigned int tex_height = 2048; |
| 168 | | |
| 169 | | |
| 170 | | // new we need to add the texture to the Drawable, we do so by creating a |
| 171 | | // StateSet to contain the Texture StateAttribute. |
| 172 | | osg::StateSet* stateset = new osg::StateSet; |
| 173 | | |
| | 113 | |
| | 114 | // create a group to contain the flag and the pre rendering camera. |
| | 115 | osg::Group* parent = new osg::Group; |
| | 116 | |
| | 117 | // texture to render to and to use for rendering of flag. |
| 179 | | stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); |
| 180 | | |
| 181 | | polyGeom->setStateSet(stateset); |
| 182 | | |
| 183 | | polyGeom->setUpdateCallback(new MyGeometryCallback(origin,xAxis,yAxis,zAxis,1.0,1.0/width,0.2f)); |
| 184 | | |
| 185 | | osg::Geode* geode = new osg::Geode(); |
| 186 | | geode->addDrawable(polyGeom); |
| 187 | | |
| 188 | | |
| 189 | | osg::CameraNode* camera = new osg::CameraNode; |
| 190 | | |
| 191 | | // set up the background color and clear mask. |
| 192 | | camera->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f)); |
| 193 | | camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
| 194 | | |
| 195 | | const osg::BoundingSphere& bs = subgraph->getBound(); |
| 196 | | if (!bs.valid()) |
| 197 | | { |
| 198 | | return subgraph; |
| 199 | | } |
| 200 | | |
| 201 | | float znear = 1.0f*bs.radius(); |
| 202 | | float zfar = 3.0f*bs.radius(); |
| 203 | | |
| 204 | | // 2:1 aspect ratio as per flag geomtry below. |
| 205 | | float proj_top = 0.25f*znear; |
| 206 | | float proj_right = 0.5f*znear; |
| 207 | | |
| 208 | | znear *= 0.9f; |
| 209 | | zfar *= 1.1f; |
| 210 | | |
| 211 | | // set up projection. |
| 212 | | camera->setProjectionMatrixAsFrustum(-proj_right,proj_right,-proj_top,proj_top,znear,zfar); |
| 213 | | |
| 214 | | // set view |
| 215 | | camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); |
| 216 | | camera->setViewMatrixAsLookAt(bs.center()-osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); |
| 217 | | |
| 218 | | // set viewport |
| 219 | | camera->setViewport(0,0,tex_width,tex_height); |
| 220 | | |
| 221 | | // set the camera to render before the main camera. |
| 222 | | camera->setRenderOrder(osg::CameraNode::PRE_RENDER); |
| 223 | | |
| 224 | | // tell the camera to use OpenGL frame buffer object where supported. |
| 225 | | camera->setRenderTargetImplmentation(osg::CameraNode::FRAME_BUFFER_OBJECT); |
| 226 | | |
| 227 | | // attach the texture and use it as the color buffer. |
| 228 | | camera->attach(osg::CameraNode::COLOR_BUFFER, texture); |
| 229 | | |
| 230 | | // add subgraph to render |
| 231 | | camera->addChild(subgraph); |
| 232 | | |
| 233 | | |
| 234 | | // create a group to contain the flag and the pre rendering camera. |
| 235 | | osg::Group* parent = new osg::Group; |
| 236 | | |
| 237 | | parent->addChild(camera); |
| 238 | | parent->addChild(geode); |
| 239 | | |
| | 123 | |
| | 124 | // first create the geometry of the flag of which to view. |
| | 125 | { |
| | 126 | // create the to visualize. |
| | 127 | osg::Geometry* polyGeom = new osg::Geometry(); |
| | 128 | |
| | 129 | polyGeom->setSupportsDisplayList(false); |
| | 130 | |
| | 131 | osg::Vec3 origin(0.0f,0.0f,0.0f); |
| | 132 | osg::Vec3 xAxis(1.0f,0.0f,0.0f); |
| | 133 | osg::Vec3 yAxis(0.0f,0.0f,1.0f); |
| | 134 | osg::Vec3 zAxis(0.0f,-1.0f,0.0f); |
| | 135 | float height = 100.0f; |
| | 136 | float width = 200.0f; |
| | 137 | int noSteps = 20; |
| | 138 | |
| | 139 | osg::Vec3Array* vertices = new osg::Vec3Array; |
| | 140 | osg::Vec3 bottom = origin; |
| | 141 | osg::Vec3 top = origin; top.z()+= height; |
| | 142 | osg::Vec3 dv = xAxis*(width/((float)(noSteps-1))); |
| | 143 | |
| | 144 | osg::Vec2Array* texcoords = new osg::Vec2Array; |
| | 145 | osg::Vec2 bottom_texcoord(0.0f,0.0f); |
| | 146 | osg::Vec2 top_texcoord(0.0f,1.0f); |
| | 147 | osg::Vec2 dv_texcoord(1.0f/(float)(noSteps-1),0.0f); |
| | 148 | |
| | 149 | for(int i=0;i<noSteps;++i) |
| | 150 | { |
| | 151 | vertices->push_back(top); |
| | 152 | vertices->push_back(bottom); |
| | 153 | top+=dv; |
| | 154 | bottom+=dv; |
| | 155 | |
| | 156 | texcoords->push_back(top_texcoord); |
| | 157 | texcoords->push_back(bottom_texcoord); |
| | 158 | top_texcoord+=dv_texcoord; |
| | 159 | bottom_texcoord+=dv_texcoord; |
| | 160 | } |
| | 161 | |
| | 162 | |
| | 163 | // pass the created vertex array to the points geometry object. |
| | 164 | polyGeom->setVertexArray(vertices); |
| | 165 | |
| | 166 | polyGeom->setTexCoordArray(0,texcoords); |
| | 167 | |
| | 168 | |
| | 169 | osg::Vec4Array* colors = new osg::Vec4Array; |
| | 170 | colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); |
| | 171 | polyGeom->setColorArray(colors); |
| | 172 | polyGeom->setColorBinding(osg::Geometry::BIND_OVERALL); |
| | 173 | |
| | 174 | polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,0,vertices->size())); |
| | 175 | |
| | 176 | // new we need to add the texture to the Drawable, we do so by creating a |
| | 177 | // StateSet to contain the Texture StateAttribute. |
| | 178 | osg::StateSet* stateset = new osg::StateSet; |
| | 179 | |
| | 180 | stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); |
| | 181 | |
| | 182 | polyGeom->setStateSet(stateset); |
| | 183 | |
| | 184 | polyGeom->setUpdateCallback(new MyGeometryCallback(origin,xAxis,yAxis,zAxis,1.0,1.0/width,0.2f)); |
| | 185 | |
| | 186 | osg::Geode* geode = new osg::Geode(); |
| | 187 | geode->addDrawable(polyGeom); |
| | 188 | |
| | 189 | parent->addChild(geode); |
| | 190 | |
| | 191 | } |
| | 192 | |
| | 193 | |
| | 194 | // then create the camera node to do the render to texture |
| | 195 | { |
| | 196 | osg::CameraNode* camera = new osg::CameraNode; |
| | 197 | |
| | 198 | // set up the background color and clear mask. |
| | 199 | camera->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f)); |
| | 200 | camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
| | 201 | |
| | 202 | const osg::BoundingSphere& bs = subgraph->getBound(); |
| | 203 | if (!bs.valid()) |
| | 204 | { |
| | 205 | return subgraph; |
| | 206 | } |
| | 207 | |
| | 208 | float znear = 1.0f*bs.radius(); |
| | 209 | float zfar = 3.0f*bs.radius(); |
| | 210 | |
| | 211 | // 2:1 aspect ratio as per flag geomtry below. |
| | 212 | float proj_top = 0.25f*znear; |
| | 213 | float proj_right = 0.5f*znear; |
| | 214 | |
| | 215 | znear *= 0.9f; |
| | 216 | zfar *= 1.1f; |
| | 217 | |
| | 218 | // set up projection. |
| | 219 | camera->setProjectionMatrixAsFrustum(-proj_right,proj_right,-proj_top,proj_top,znear,zfar); |
| | 220 | |
| | 221 | // set view |
| | 222 | camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); |
| | 223 | camera->setViewMatrixAsLookAt(bs.center()-osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); |
| | 224 | |
| | 225 | // set viewport |
| | 226 | camera->setViewport(0,0,tex_width,tex_height); |
| | 227 | |
| | 228 | // set the camera to render before the main camera. |
| | 229 | camera->setRenderOrder(osg::CameraNode::PRE_RENDER); |
| | 230 | |
| | 231 | // tell the camera to use OpenGL frame buffer object where supported. |
| | 232 | camera->setRenderTargetImplmentation(renderImplementation); |
| | 233 | |
| | 234 | // attach the texture and use it as the color buffer. |
| | 235 | camera->attach(osg::CameraNode::COLOR_BUFFER, texture); |
| | 236 | |
| | 237 | // add subgraph to render |
| | 238 | camera->addChild(subgraph); |
| | 239 | |
| | 240 | parent->addChild(camera); |
| | 241 | |
| | 242 | } |