| 110 | | osg::Node* createPreRenderSubGraph(osg::Node* subgraph, unsigned tex_width, unsigned tex_height, osg::CameraNode::RenderTargetImplementation renderImplementation) |
| | 111 | struct MyCameraPostDrawCallback : public osg::CameraNode::DrawCallback |
| | 112 | { |
| | 113 | MyCameraPostDrawCallback(osg::Image* image): |
| | 114 | _image(image) |
| | 115 | { |
| | 116 | } |
| | 117 | |
| | 118 | virtual void operator () (const osg::CameraNode& /*camera*/) const |
| | 119 | { |
| | 120 | if (_image && _image->getPixelFormat()==GL_RGBA && _image->getDataType()==GL_UNSIGNED_BYTE) |
| | 121 | { |
| | 122 | |
| | 123 | // we'll pick out the center 1/2 of the whole image, |
| | 124 | int column_start = _image->s()/4; |
| | 125 | int column_end = 3*column_start; |
| | 126 | |
| | 127 | int row_start = _image->t()/4; |
| | 128 | int row_end = 3*row_start; |
| | 129 | |
| | 130 | |
| | 131 | // and then invert these pixels |
| | 132 | for(int r=row_start; r<row_end; ++r) |
| | 133 | { |
| | 134 | unsigned char* data = _image->data(column_start, r); |
| | 135 | for(int c=column_start; c<column_end; ++c) |
| | 136 | { |
| | 137 | (*data) = 255; ++data; |
| | 138 | (*data) = (*data); ++data; |
| | 139 | (*data) = (*data); ++data; |
| | 140 | (*data) = 255; ++data; |
| | 141 | } |
| | 142 | } |
| | 143 | |
| | 144 | |
| | 145 | // dirty the image (increments the modified count) so that any textures |
| | 146 | // using the image can be informed that they need to update. |
| | 147 | _image->dirty(); |
| | 148 | } |
| | 149 | |
| | 150 | } |
| | 151 | |
| | 152 | osg::Image* _image; |
| | 153 | }; |
| | 154 | |
| | 155 | |
| | 156 | osg::Node* createPreRenderSubGraph(osg::Node* subgraph, unsigned tex_width, unsigned tex_height, osg::CameraNode::RenderTargetImplementation renderImplementation, bool useImage, bool useTextureRectangle) |
| 118 | | osg::Texture2D* texture = new osg::Texture2D; |
| 119 | | texture->setTextureSize(tex_width, tex_height); |
| 120 | | texture->setInternalFormat(GL_RGBA); |
| 121 | | texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); |
| 122 | | texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); |
| | 164 | osg::Texture* texture = 0; |
| | 165 | if (useTextureRectangle) |
| | 166 | { |
| | 167 | osg::TextureRectangle* textureRect = new osg::TextureRectangle; |
| | 168 | textureRect->setTextureSize(tex_width, tex_height); |
| | 169 | textureRect->setInternalFormat(GL_RGBA); |
| | 170 | textureRect->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); |
| | 171 | textureRect->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); |
| | 172 | |
| | 173 | texture = textureRect; |
| | 174 | } |
| | 175 | else |
| | 176 | { |
| | 177 | osg::Texture2D* texture2D = new osg::Texture2D; |
| | 178 | texture2D->setTextureSize(tex_width, tex_height); |
| | 179 | texture2D->setInternalFormat(GL_RGBA); |
| | 180 | texture2D->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); |
| | 181 | texture2D->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); |
| | 182 | |
| | 183 | texture = texture2D; |
| | 184 | } |
| 234 | | // attach the texture and use it as the color buffer. |
| 235 | | camera->attach(osg::CameraNode::COLOR_BUFFER, texture); |
| | 298 | |
| | 299 | if (useImage) |
| | 300 | { |
| | 301 | osg::Image* image = new osg::Image; |
| | 302 | image->allocateImage(tex_width, tex_height, 1, GL_RGBA, GL_UNSIGNED_BYTE); |
| | 303 | |
| | 304 | // attach the image so its copied on each frame. |
| | 305 | camera->attach(osg::CameraNode::COLOR_BUFFER, image); |
| | 306 | |
| | 307 | camera->setPostDrawCallback(new MyCameraPostDrawCallback(image)); |
| | 308 | |
| | 309 | // Rather than attach the texture directly to illustrate the texture's ability to |
| | 310 | // detect an image update and to subload the image onto the texture. You needn't |
| | 311 | // do this when using an Image for copying to, as a seperate camera->attach(..) |
| | 312 | // would suffice as well, but we'll do it the long way round here just for demonstation |
| | 313 | // purposes (long way round meaning we'll need to copy image to main memory, then |
| | 314 | // copy it back to the graphics card to the texture in one frame). |
| | 315 | // The long way round allows us to mannually modify the copied image via the callback |
| | 316 | // and then let this modified image by reloaded back. |
| | 317 | texture->setImage(0, image); |
| | 318 | } |
| | 319 | else |
| | 320 | { |
| | 321 | // attach the texture and use it as the color buffer. |
| | 322 | camera->attach(osg::CameraNode::COLOR_BUFFER, texture); |
| | 323 | } |
| | 324 | |