From 360247225ee878174746b994aa5c6af5cc9ae9ca Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 10 Apr 2002 21:51:34 +0000 Subject: [PATCH] Added new osg::DrawPixels class with encapsulates glDrawPixels as and osg::Drawable. Added osg::Image::readPixels to osg::Image. Made osg::LightSource to default to cullActive set to false to that LightSource nodes don't get culled by default. --- Make/makedefs | 2 +- VisualStudio/osg/osg.dsp | 8 +++ include/osg/DrawPixels | 74 ++++++++++++++++++++ include/osg/Image | 29 ++++++-- include/osg/MemoryManager | 2 + src/Demos/osgtexture/osgtexture.cpp | 18 +++++ src/osg/DrawPixels.cpp | 100 ++++++++++++++++++++++++++++ src/osg/Image.cpp | 52 +++++++++++++++ src/osg/LightSource.cpp | 3 +- src/osg/Makefile | 1 + src/osgUtil/SceneView.cpp | 8 --- 11 files changed, 282 insertions(+), 15 deletions(-) create mode 100644 include/osg/DrawPixels create mode 100644 src/osg/DrawPixels.cpp diff --git a/Make/makedefs b/Make/makedefs index ab27547bf..91e56edcf 100644 --- a/Make/makedefs +++ b/Make/makedefs @@ -146,7 +146,7 @@ ifeq ($(OS),Linux) INC += DEF += -W -Wall OPTF = -O2 - DBGF = "-g -DUSE_MEMORY_MANAGER" + DBGF = "-g -DOSG_USE_MEMORY_MANAGER" SHARED = -shared ARCHARGS = LINKARGS = -L/usr/X11R6/lib diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index 3b5bb6c14..50cb206a3 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -145,6 +145,10 @@ SOURCE=..\..\src\osg\Drawable.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osg\DrawPixels.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osg\EarthSky.cpp # End Source File # Begin Source File @@ -405,6 +409,10 @@ SOURCE=..\..\Include\Osg\Drawable # End Source File # Begin Source File +SOURCE=..\..\Include\Osg\DrawPixels +# End Source File +# Begin Source File + SOURCE=..\..\include\osg\EarthSky # End Source File # Begin Source File diff --git a/include/osg/DrawPixels b/include/osg/DrawPixels new file mode 100644 index 000000000..106906fdb --- /dev/null +++ b/include/osg/DrawPixels @@ -0,0 +1,74 @@ +//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield +//Distributed under the terms of the GNU Library General Public License (LGPL) +//as published by the Free Software Foundation. + +#ifndef OSG_DRAWPIXELS +#define OSG_DRAWPIXELS 1 + +#include +#include +#include + +namespace osg { + +/** DrawPixels is an osg::Drawable subclass which encapsulates the drawing of + * images using glDrawPixels.*/ +class SG_EXPORT DrawPixels : public Drawable +{ + public: + + DrawPixels(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + DrawPixels(const DrawPixels& drawimage,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + virtual Object* cloneType() const { return osgNew DrawPixels(); } + + virtual Object* clone(const CopyOp& copyop) const { return osgNew DrawPixels(*this,copyop); } + + virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } + + virtual const char* className() const { return "DrawPixels"; } + + + void setPosition(const osg::Vec3& position); + + osg::Vec3& getPosition() { return _position; } + const osg::Vec3& getPosition() const { return _position; } + + void setImage(osg::Image* image) { _image = image; } + + osg::Image* getImage() { return _image.get(); } + const osg::Image* getImage() const { return _image.get(); } + + void setUseCompleteImage() { _useSubImage = false; } + + void setSubImageDimensions(unsigned int offsetX,unsigned int offsetY,unsigned int width,unsigned int height); + + void getSubImageDimensions(unsigned int& offsetX,unsigned int& offsetY,unsigned int& width,unsigned int& height) const; + + const bool getUseSubImage() const { return _useSubImage; } + + + virtual void drawImmediateMode(State& state); + + + protected: + + DrawPixels& operator = (const DrawPixels&) { return *this;} + + virtual ~DrawPixels(); + + virtual const bool computeBound() const; + + Vec3 _position; + ref_ptr _image; + + bool _useSubImage; + unsigned int _offsetX, _offsetY, _width, _height; + +}; + +} + +#endif diff --git a/include/osg/Image b/include/osg/Image index 36c56beda..2d5e6421e 100644 --- a/include/osg/Image +++ b/include/osg/Image @@ -33,6 +33,11 @@ class SG_EXPORT Image : public Object inline const std::string& getFileName() const { return _fileName; } void setFileName(const std::string& fileName); + + void createImage(const int s,const int t,const int r, + const unsigned int pixelFormat,const unsigned int dataType); + + /** set the image data and format. * note, when the packing value is negative (the default is -1) this method assumes * a _packing width of 1 if the width is not a multiple of 4, @@ -40,11 +45,17 @@ class SG_EXPORT Image : public Object * value of packing is supplied than _packing is simply set to that value. */ void 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=-1); + const int internalFormat,const unsigned int pixelFormat,const unsigned int dataType, + unsigned char *data, + const int packing=-1); + + /** readPixels from screen at specified position and size, using glReadPixels. + * Create memory for storage if required, reuse existing pixel coords if possible. + * if pixelFormat or dataType*/ + void readPixels(int x,int y,int width,int height, + unsigned int pixelFormat,unsigned int dataType, + const int packing=-1); + /** Width of image.*/ inline const int s() const { return _s; } @@ -54,10 +65,15 @@ class SG_EXPORT Image : public Object inline const int r() const { return _r; } inline const int internalFormat() const { return _internalFormat; } + inline const unsigned int pixelFormat() const { return _pixelFormat; } + inline const unsigned int dataType() const { return _dataType; } + inline const unsigned int packing() const { return _packing; } + inline const unsigned int pixelSizeInBits() const { return _pixelSizeInBits; } + /** raw image data.*/ inline unsigned char *data() { return _data; } @@ -88,12 +104,15 @@ class SG_EXPORT Image : public Object Image& operator = (const Image&) { return *this; } + void computePixelSize(); + std::string _fileName; int _s, _t, _r; int _internalFormat; unsigned int _pixelFormat; unsigned int _dataType; unsigned int _packing; + unsigned int _pixelSizeInBits; unsigned char *_data; unsigned int _modifiedTag; diff --git a/include/osg/MemoryManager b/include/osg/MemoryManager index d893c577e..0eb446bc2 100644 --- a/include/osg/MemoryManager +++ b/include/osg/MemoryManager @@ -21,7 +21,9 @@ // For systems that don't have the __FUNCTION__ variable, we can just define it here // --------------------------------------------------------------------------------------------------------------------------------- +#ifndef __FUNCTION__ #define __FUNCTION__ "??" +#endif // --------------------------------------------------------------------------------------------------------------------------------- // Types diff --git a/src/Demos/osgtexture/osgtexture.cpp b/src/Demos/osgtexture/osgtexture.cpp index 4696b91b9..1bcdd118d 100644 --- a/src/Demos/osgtexture/osgtexture.cpp +++ b/src/Demos/osgtexture/osgtexture.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -165,6 +166,23 @@ osg::Node* createLayer(const osg::Vec3& offset,osg::Image* image,osg::Node* geom osg::Vec3 local_offset(0.0f,0.0f,0.0f); osg::Vec3 local_delta(3.0f,0.0f,0.0f); +// // use DrawPixels drawable to draw a pixel image. +// { +// +// osg::DrawPixels* drawimage = osgNew osg::DrawPixels; +// drawimage->setPosition(local_offset); +// drawimage->setImage(image); +// +// osg::Geode* geode = osgNew osg::Geode; +// geode->addDrawable(drawimage); +// +// // add the transform node to root group node. +// top_transform->addChild(geode); +// +// local_offset += local_delta; +// } + + // defaults mipmapped texturing. { // create the texture attribute diff --git a/src/osg/DrawPixels.cpp b/src/osg/DrawPixels.cpp new file mode 100644 index 000000000..4bc6d3832 --- /dev/null +++ b/src/osg/DrawPixels.cpp @@ -0,0 +1,100 @@ +#include + +using namespace osg; + +DrawPixels::DrawPixels() +{ + // turn off display lists right now, just incase we want to modify the projection matrix along the way. + setSupportsDisplayList(false); + + _position.set(0.0f,0.0f,0.0f); + + _useSubImage = false; + _offsetX = 0; + _offsetY = 0; + _width = 0; + _height = 0; +} + +DrawPixels::DrawPixels(const DrawPixels& drawimage,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + Drawable(drawimage,copyop), + _position(drawimage._position), + _image(drawimage._image), + _useSubImage(drawimage._useSubImage), + _offsetX(drawimage._offsetX), + _offsetY(drawimage._offsetY), + _width(drawimage._width), + _height(drawimage._height) +{ +} + +DrawPixels::~DrawPixels() +{ + // image will delete itself thanks to ref_ptr :-) +} + +void DrawPixels::setPosition(const osg::Vec3& position) +{ + _position = position; + dirtyBound(); +} + +void DrawPixels::setSubImageDimensions(unsigned int offsetX,unsigned int offsetY,unsigned int width,unsigned int height) +{ + _useSubImage = true; + _offsetX = offsetX; + _offsetY = offsetY; + _width = width; + _height = height; +} + +void DrawPixels::getSubImageDimensions(unsigned int& offsetX,unsigned int& offsetY,unsigned int& width,unsigned int& height) const +{ + offsetX = _offsetX; + offsetY = _offsetY; + width = _width; + height = _height; +} + + +const bool DrawPixels::computeBound() const +{ + // really needs to be dependant of view poistion and projection... will implement simple version right now. + _bbox.init(); + float diagonal = 0.0f; + if (_useSubImage) + { + diagonal = sqrtf(_width*_width+_height*_height); + } + else + { + diagonal = sqrtf(_image->s()*_image->s()+_image->t()*_image->t()); + } + + _bbox.expandBy(_position-osg::Vec3(diagonal,diagonal,diagonal)); + _bbox.expandBy(_position+osg::Vec3(diagonal,diagonal,diagonal)); + _bbox_computed = true; + return true; +} + +void DrawPixels::drawImmediateMode(State&) +{ + glRasterPos3f(_position.x(),_position.y(),_position.z()); + + if (_useSubImage) + { + const GLvoid* pixels = _image->data(); + glDrawPixels(_width,_height, + (GLenum)_image->pixelFormat(), + (GLenum)_image->dataType(), + pixels); + } + else + { + glDrawPixels(_image->s(), _image->t(), + (GLenum)_image->pixelFormat(), + (GLenum)_image->dataType(), + _image->data() ); + } +} + diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index 2be3ba092..91682e347 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -21,6 +21,7 @@ Image::Image() _pixelFormat = (unsigned int)0; _dataType = (unsigned int)0; _packing = 4; + _pixelSizeInBits = 0; _data = (unsigned char *)0L; @@ -35,6 +36,7 @@ Image::Image(const Image& image,const CopyOp& copyop): _pixelFormat(image._pixelFormat), _dataType(image._dataType), _packing(image._packing), + _pixelSizeInBits(image._pixelSizeInBits), _data(0L), _modifiedTag(image._modifiedTag) { @@ -64,6 +66,12 @@ void Image::setFileName(const std::string& 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, @@ -92,6 +100,8 @@ void Image::setImage(const int s,const int t,const int r, } else _packing = packing; + + computePixelSize(); // test scaling... // scaleImageTo(16,16,_r); @@ -100,10 +110,52 @@ void Image::setImage(const int s,const int t,const int r, } +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); diff --git a/src/osg/LightSource.cpp b/src/osg/LightSource.cpp index 5ebd3158e..f7c1bc0a2 100644 --- a/src/osg/LightSource.cpp +++ b/src/osg/LightSource.cpp @@ -4,7 +4,8 @@ using namespace osg; LightSource::LightSource() { - _bsphere_computed = false; + // switch off culling of light source nodes by default. + setCullingActive(false); } diff --git a/src/osg/Makefile b/src/osg/Makefile index 797720197..086ad9d5b 100644 --- a/src/osg/Makefile +++ b/src/osg/Makefile @@ -16,6 +16,7 @@ CXXFILES =\ Depth.cpp\ DisplaySettings.cpp\ Drawable.cpp\ + DrawPixels.cpp\ EarthSky.cpp\ Fog.cpp\ FrameStamp.cpp\ diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index 07c7b531b..c339cf92b 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -236,13 +236,6 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor osg::Matrix* projection = osgNew osg::Matrix(camera->getProjectionMatrix()); osg::Matrix* modelview = osgNew osg::Matrix(camera->getModelViewMatrix()); - - // take a copy of camera, and init it home - osg::Camera* local_camera = osgNew Camera(*camera); - local_camera->home(); - local_camera->attachTransform(osg::Camera::NO_ATTACHED_TRANSFORM); - - cullVisitor->setLODBias(_lodBias); cullVisitor->setEarthSky(NULL); // reset earth sky on each frame. @@ -347,7 +340,6 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor _far_plane = 1000.0f; } - local_camera->setNearFar(_near_plane,_far_plane); camera->setNearFar(_near_plane,_far_plane); }