#include #include #include #include #include #include #include #include using namespace osg; using namespace std; Image::Image() { _fileName = ""; _s = _t = _r = 0; _internalFormat = 0; _pixelFormat = (unsigned int)0; _dataType = (unsigned int)0; _packing = 4; _pixelSizeInBits = 0; _data = (unsigned char *)0L; _modifiedTag = 0; } Image::Image(const Image& image,const CopyOp& copyop): Object(image,copyop), _fileName(image._fileName), _s(image._s), _t(image._t), _r(image._r), _internalFormat(image._internalFormat), _pixelFormat(image._pixelFormat), _dataType(image._dataType), _packing(image._packing), _pixelSizeInBits(image._pixelSizeInBits), _data(0L), _modifiedTag(image._modifiedTag) { if (image._data) { int num_components = _pixelFormat == GL_LUMINANCE ? 1 : _pixelFormat == GL_LUMINANCE_ALPHA ? 2 : _pixelFormat == GL_RGB ? 3 : _pixelFormat == GL_RGBA ? 4 : 4; int size = _s*_t*_r*num_components; _data = (unsigned char*) malloc(size); memcpy(_data,image._data,size); } } Image::~Image() { if (_data) ::free(_data); } void Image::setFileName(const std::string& fileName) { _fileName = fileName; } void Image::computePixelSize() { // temporary code.. to be filled in properly ASAP. RO. _pixelSizeInBits=32; } void Image::setImage(const int s,const int t,const int r, const int internalFormat, const unsigned int pixelFormat, const unsigned int dataType, unsigned char *data, const int packing) { if (_data) ::free(_data); _s = s; _t = t; _r = r; _internalFormat = internalFormat; _pixelFormat = pixelFormat; _dataType = dataType; _data = data; if (packing<0) { if (_s%4==0) _packing = 4; else _packing = 1; } else _packing = packing; computePixelSize(); // test scaling... // scaleImageTo(16,16,_r); ++_modifiedTag; } void Image::readPixels(int x,int y,int width,int height, unsigned int pixelFormat,unsigned int dataType, const int packing) { if (width!=_s || height!=_s || _t != 1 || _pixelFormat!=pixelFormat || _dataType!=dataType) { if (_data) ::free(_data); _s = width; _t = height; _r = 1; _pixelFormat = pixelFormat; _dataType = dataType; if (packing<0) { if (_s%4==0) _packing = 4; else _packing = 1; } else _packing = packing; computePixelSize(); // need to sort out what size to really use... _data = (unsigned char *)malloc(2 * (_s+1)*(_t+1)*4); } glPixelStorei(GL_PACK_ALIGNMENT,_packing); glReadPixels(x,y,width,height,pixelFormat,dataType,_data); } void Image::scaleImage(const int s,const int t,const int /*r*/) { if (_data==NULL) return; // need to sort out what size to really use... unsigned char* newData = (unsigned char *)malloc(2 * (s+1)*(t+1)*4); glPixelStorei(GL_PACK_ALIGNMENT,_packing); glPixelStorei(GL_UNPACK_ALIGNMENT,_packing); GLint status = gluScaleImage((GLenum)_pixelFormat, _s, _t, (GLenum)_dataType, _data, s, t, (GLenum)_dataType, newData); if (status==0) { // free old image. ::free(_data); _s = s; _t = t; _data = newData; } else { ::free(newData); notify(WARN) << "Error Image::scaleImage() do not succeed : errorString = "<max_size) new_s = max_size; if (new_t>max_size) new_t = max_size; if (new_s!=_s || new_t!=_t) { if (!_fileName.empty()) notify(NOTICE) << "Scaling image '"<<_fileName<<"' from ("<<_s<<","<<_t<<") to ("<s(),image->t()); } Geode* osg::createGeodeForImage(osg::Image* image,const float s,const float t) { if (image) { if (s>0 && t>0) { float y = 1.0; float x = y*(s/t); // set up the texture. osg::Texture* texture = osgNew osg::Texture; texture->setImage(image); // set up the drawstate. osg::StateSet* dstate = osgNew osg::StateSet; dstate->setMode(GL_CULL_FACE,osg::StateAttribute::OFF); dstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF); dstate->setAttributeAndModes(texture,osg::StateAttribute::ON); // set up the geoset. osg::GeoSet* gset = osgNew osg::GeoSet; gset->setStateSet(dstate); osg::Vec3* coords = osgNew Vec3[4]; coords[0].set(-x,0.0f,y); coords[1].set(-x,0.0f,-y); coords[2].set(x,0.0f,-y); coords[3].set(x,0.0f,y); gset->setCoords(coords); osg::Vec2* tcoords = osgNew Vec2[4]; tcoords[0].set(0.0f,1.0f); tcoords[1].set(0.0f,0.0f); tcoords[2].set(1.0f,0.0f); tcoords[3].set(1.0f,1.0f); gset->setTextureCoords(tcoords); gset->setTextureBinding(osg::GeoSet::BIND_PERVERTEX); osg::Vec4* colours = osgNew Vec4[1]; colours->set(1.0f,1.0f,1.0,1.0f); gset->setColors(colours); gset->setColorBinding(osg::GeoSet::BIND_OVERALL); gset->setNumPrims(1); gset->setPrimType(osg::GeoSet::QUADS); // set up the geode. osg::Geode* geode = osgNew osg::Geode; geode->addDrawable(gset); return geode; } else { return NULL; } } else { return NULL; } }