En. Another problem I think there will be. many 3d model files may have 
reference to image on local disk. so how can I save the image(write a 
NodeVisitor is a solution?), and then How I read that. ---MingWei---   
在2007-08-30,"赵明伟" <[EMAIL PROTECTED]> 写道:
 Thank you very much. That's just what I meed.Thanks again for your help. 
---MingWei---  
在2007-08-29,"Thibault Genessay" <[EMAIL PROTECTED]> 写道:
Hi
On 8/28/07,赵明伟 <[EMAIL PROTECTED]> wrote:I find the ReadWriter's virtual 
function read/write Object/Image/Node from file and also from the memory by 
istream. I think That's what I want. But It seems to only the osg plugin 
implement the function completely.
I think we kinda float the same boat :)
First, my situation: I have stuffed images in a database by loading the files 
into memory buffers, and saving them in my DB. The table has a row that 
contains the image name, extension (essential!) and the binary data (stored as 
a PostgreSQL 'bytea' data type). Until today, I was loading the row, saving it 
to a file and reloading it with osgDB::readImageFile(). This worked but was 
ugly.
Now the solution I ended up with: of course, we want to load the images 
directly from memory. Idea: osg::ReaderWriter provides a virtual method 
readImage(std::istream& fin) that can read from streams. If we can create an 
ad-hoc stream from our memory buffer, we're done (provided that the specific 
plugins you are interested in, i.e. 3ds and OpenFlight, do implement this 
method). Now, the C++ does not have a built-in way to create a stream from a 
buffer. So, after googling for a couple of hours, I have written (ahem ... 
copy-pasted :) a custom std::streambuf that can read from our memory buffer. It 
goes like this:
template <class cT, class traits = std::char_traits<cT> >
class basic_membuf : public std::basic_streambuf<cT, traits> {
public:
    basic_membuf(cT * mem, std::streamsize sz) {
        setg(mem, mem, mem + sz);
    }
};
typedef basic_membuf<char, std::char_traits<char> > membuf;
[ Credits go to Dietmar Kühl. See the thread that comes first while searching 
'memory mapped istream' in google groups for ' comp.lang.c++.moderated'. ]
Let's assume your image data is:
char* memory_mapped_file = read_the_data_from_the_database();
size_t length = ... // you have to know the size, but that should not be tricky
const char* extension = "png"; // for instance
Now, we can create a stream for our memory-mapped file:
membuf my_buf(memory_mapped_file, length);
std::istream stream(&my_buf);
If we add the OSG stuff, we have the following function:
osg::Image* getImageFromBuffer(char* buffer, size_t length, const char* 
extension)
{
    osgDB::ReaderWriter* rw = 
osgDB::Registry::instance()->getReaderWriterForExtension(extension);
    if (rw)
    {
        membuf sb(buffer, length);
        std::istream stream(&sb);
        osgDB::ReaderWriter::ReadResult rr = rw->readImage(stream);
        return rr.takeImage();
    }
}
And you are done.
Thibault
2007 年 最 受 期 待 大 型 网 游 《大 话 西 游 3》震 撼 公 测! 点 此 抢 先 免 费 体 验 >>
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to