Show
Ignore:
Timestamp:
11/01/05 18:07:55 (9 years ago)
Author:
robert
Message:

Added usage of image copy and modification.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgprerender/osgprerender.cpp

    r4571 r4647  
    55#include <osg/MatrixTransform> 
    66#include <osg/Texture2D> 
     7#include <osg/TextureRectangle> 
    78#include <osg/Stencil> 
    89#include <osg/ColorMask> 
     
    108109}; 
    109110 
    110 osg::Node* createPreRenderSubGraph(osg::Node* subgraph, unsigned tex_width, unsigned tex_height, osg::CameraNode::RenderTargetImplementation renderImplementation) 
     111struct 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 
     156osg::Node* createPreRenderSubGraph(osg::Node* subgraph, unsigned tex_width, unsigned tex_height, osg::CameraNode::RenderTargetImplementation renderImplementation, bool useImage, bool useTextureRectangle) 
    111157{ 
    112158    if (!subgraph) return 0; 
     
    116162 
    117163    // texture to render to and to use for rendering of flag. 
    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    }  
    123185 
    124186    // first create the geometry of the flag of which to view. 
     
    143205 
    144206        osg::Vec2Array* texcoords = new osg::Vec2Array; 
     207         
     208        // note, when we use TextureRectangle we have to scale the tex coords up to compensate. 
    145209        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); 
     210        osg::Vec2 top_texcoord(0.0f, useTextureRectangle ? tex_height : 1.0f); 
     211        osg::Vec2 dv_texcoord((useTextureRectangle ? tex_width : 1.0f)/(float)(noSteps-1),0.0f); 
    148212 
    149213        for(int i=0;i<noSteps;++i) 
     
    232296        camera->setRenderTargetImplementation(renderImplementation); 
    233297 
    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 
    236325 
    237326        // add subgraph to render 
     
    290379    while (arguments.read("--window")) { renderImplementation = osg::CameraNode::SEPERATE_WINDOW; } 
    291380 
     381    bool useImage = false; 
     382    while (arguments.read("--image")) { useImage = true; } 
     383     
     384    bool useTextureRectangle = false; 
     385    while (arguments.read("--texture-rectangle")) { useTextureRectangle = true; } 
     386     
    292387 
    293388    // any option left unread are converted into errors to write out later. 
     
    323418 
    324419    osg::Group* rootNode = new osg::Group(); 
    325     rootNode->addChild(createPreRenderSubGraph(loadedModelTransform,tex_width,tex_height, renderImplementation)); 
     420    rootNode->addChild(createPreRenderSubGraph(loadedModelTransform,tex_width,tex_height, renderImplementation, useImage, useTextureRectangle)); 
    326421 
    327422