Added osg::BufferObject and a made a number associated to accomodate this
new class. osg::BufferObject wraps up OpenGL pixel and array buffer objects. Currently implementation is work in progress.
This commit is contained in:
@@ -144,6 +144,10 @@ SOURCE=..\..\src\osg\BoundingSphere.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\osg\BufferObject.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\osg\ClearNode.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -556,6 +560,10 @@ SOURCE=..\..\include\osg\BoundsChecking
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\osg\BufferObject
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\osg\ClearNode
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -16,6 +16,26 @@
|
||||
|
||||
#include <osgGA/TrackballManipulator>
|
||||
|
||||
osg::ImageStream* s_imageStream = 0;
|
||||
class PostSwapFinishCallback : public Producer::Camera::Callback
|
||||
{
|
||||
public:
|
||||
|
||||
PostSwapFinishCallback() {}
|
||||
|
||||
virtual void operator()(const Producer::Camera& camera)
|
||||
{
|
||||
// osg::Timer_t start_tick = osg::Timer::instance()->tick();
|
||||
|
||||
osgProducer::OsgSceneHandler* sh = const_cast<osgProducer::OsgSceneHandler*>(dynamic_cast<const osgProducer::OsgSceneHandler*>(camera.getSceneHandler()));
|
||||
|
||||
if (s_imageStream && s_imageStream->getPixelBufferObject()) s_imageStream->getPixelBufferObject()->compileBuffer(*(sh->getSceneView()->getState()));
|
||||
// glFinish();
|
||||
|
||||
//osg::notify(osg::NOTICE)<<"callback after PBO "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
class MovieEventHandler : public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
@@ -77,7 +97,11 @@ protected:
|
||||
|
||||
inline void apply(osg::ImageStream* imagestream)
|
||||
{
|
||||
if (imagestream) _imageStreamList.push_back(imagestream);
|
||||
if (imagestream)
|
||||
{
|
||||
_imageStreamList.push_back(imagestream);
|
||||
s_imageStream = imagestream;
|
||||
}
|
||||
}
|
||||
|
||||
ImageStreamList& _imageStreamList;
|
||||
@@ -258,6 +282,13 @@ int main(int argc, char** argv)
|
||||
arguments.writeErrorMessages(std::cout);
|
||||
}
|
||||
|
||||
// set up a post swap callback to flush deleted GL objects and compile new GL objects
|
||||
for(unsigned int cameraNum=0;cameraNum<viewer.getNumberOfCameras();++cameraNum)
|
||||
{
|
||||
Producer::Camera* camera=viewer.getCamera(cameraNum);
|
||||
camera->addPostSwapCallback(new PostSwapFinishCallback());
|
||||
}
|
||||
|
||||
// set the scene to render
|
||||
viewer.setSceneData(geode);
|
||||
|
||||
|
||||
@@ -56,13 +56,15 @@ class SG_EXPORT Array : public Object
|
||||
Array(Type arrayType=ArrayType,GLint dataSize=0,GLenum dataType=0):
|
||||
_arrayType(arrayType),
|
||||
_dataSize(dataSize),
|
||||
_dataType(dataType) {}
|
||||
_dataType(dataType),
|
||||
_modifiedCount(0) {}
|
||||
|
||||
Array(const Array& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
|
||||
Object(array,copyop),
|
||||
_arrayType(array._arrayType),
|
||||
_dataSize(array._dataSize),
|
||||
_dataType(array._dataType) {}
|
||||
_dataType(array._dataType),
|
||||
_modifiedCount(0) {}
|
||||
|
||||
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Array*>(obj)!=NULL; }
|
||||
virtual const char* libraryName() const { return "osg"; }
|
||||
@@ -85,6 +87,15 @@ class SG_EXPORT Array : public Object
|
||||
virtual unsigned int getTotalDataSize() const = 0;
|
||||
virtual unsigned int getNumElements() const = 0;
|
||||
|
||||
/** Dirty the primitive, which increments the modified count, to force buffer objects to update. */
|
||||
inline void dirty() { ++_modifiedCount; }
|
||||
|
||||
/** Set the modified count value.*/
|
||||
inline void setModifiedCount(unsigned int value) { _modifiedCount=value; }
|
||||
|
||||
/** Get modified count value.*/
|
||||
inline unsigned int getModifiedCount() const { return _modifiedCount; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~Array() {}
|
||||
@@ -92,6 +103,7 @@ class SG_EXPORT Array : public Object
|
||||
Type _arrayType;
|
||||
GLint _dataSize;
|
||||
GLenum _dataType;
|
||||
unsigned int _modifiedCount;
|
||||
};
|
||||
|
||||
template<typename T, Array::Type ARRAYTYPE, int DataSize, int DataType>
|
||||
|
||||
259
include/osg/BufferObject
Normal file
259
include/osg/BufferObject
Normal file
@@ -0,0 +1,259 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSG_BUFFEROBJECT
|
||||
#define OSG_BUFFEROBJECT 1
|
||||
|
||||
#include <osg/State>
|
||||
#include <osg/buffered_value>
|
||||
|
||||
#ifndef GL_ARB_vertex_buffer_object
|
||||
|
||||
#define GL_ARB_vertex_buffer_object
|
||||
|
||||
// for compatibility with gl.h headers that don't support VBO,
|
||||
#if defined(_WIN64)
|
||||
typedef __int64 GLintptrARB;
|
||||
typedef __int64 GLsizeiptrARB;
|
||||
#elif defined(__ia64__) || defined(__x86_64__)
|
||||
typedef long int GLintptrARB;
|
||||
typedef long int GLsizeiptrARB;
|
||||
#else
|
||||
typedef int GLintptrARB;
|
||||
typedef int GLsizeiptrARB;
|
||||
#endif
|
||||
|
||||
#define GL_ARRAY_BUFFER_ARB 0x8892
|
||||
#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
|
||||
#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB
|
||||
#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC
|
||||
#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
|
||||
#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
|
||||
#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
|
||||
#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
|
||||
#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
|
||||
#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
|
||||
#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
|
||||
#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
|
||||
#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
|
||||
#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
|
||||
#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
|
||||
#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED
|
||||
#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF
|
||||
#define GL_STREAM_DRAW_ARB 0x88E0
|
||||
#define GL_STREAM_READ_ARB 0x88E1
|
||||
#define GL_STREAM_COPY_ARB 0x88E2
|
||||
#define GL_STATIC_DRAW_ARB 0x88E4
|
||||
#define GL_STATIC_READ_ARB 0x88E5
|
||||
#define GL_STATIC_COPY_ARB 0x88E6
|
||||
#define GL_DYNAMIC_DRAW_ARB 0x88E8
|
||||
#define GL_DYNAMIC_READ_ARB 0x88E9
|
||||
#define GL_DYNAMIC_COPY_ARB 0x88EA
|
||||
#define GL_READ_ONLY_ARB 0x88B8
|
||||
#define GL_WRITE_ONLY_ARB 0x88B9
|
||||
#define GL_READ_WRITE_ARB 0x88BA
|
||||
#define GL_BUFFER_SIZE_ARB 0x8764
|
||||
#define GL_BUFFER_USAGE_ARB 0x8765
|
||||
#define GL_BUFFER_ACCESS_ARB 0x88BB
|
||||
#define GL_BUFFER_MAPPED_ARB 0x88BC
|
||||
#define GL_BUFFER_MAP_POINTER_ARB 0x88BD
|
||||
|
||||
#endif
|
||||
|
||||
namespace osg
|
||||
{
|
||||
|
||||
class SG_EXPORT BufferObject : public Object
|
||||
{
|
||||
public:
|
||||
|
||||
BufferObject();
|
||||
|
||||
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
||||
BufferObject(const BufferObject& bo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
|
||||
|
||||
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const BufferObject*>(obj)!=NULL; }
|
||||
virtual const char* libraryName() const { return "osg"; }
|
||||
virtual const char* className() const { return "BufferObject"; }
|
||||
|
||||
struct BufferEntry
|
||||
{
|
||||
BufferEntry(): dataSize(0),offset(0) {}
|
||||
BufferEntry(const BufferEntry& be): modifiedCount(be.modifiedCount),dataSize(be.dataSize),offset(be.offset) {}
|
||||
|
||||
BufferEntry& operator = (const BufferEntry& be) { modifiedCount=be.modifiedCount; dataSize=be.dataSize; offset=be.offset; return *this; }
|
||||
|
||||
mutable buffered_value<unsigned int> modifiedCount;
|
||||
unsigned int dataSize;
|
||||
unsigned int offset;
|
||||
};
|
||||
|
||||
inline bool isBufferObjectSupported(unsigned int contextID) const { return getExtensions(contextID,true)->isBufferObjectSupported(); }
|
||||
|
||||
inline GLuint& buffer(unsigned int contextID) const { return _bufferObjectList[contextID]; }
|
||||
|
||||
inline void bindBuffer(unsigned int contextID) const
|
||||
{
|
||||
Extensions* extensions = getExtensions(contextID,true);
|
||||
extensions->glBindBuffer(_target,_bufferObjectList[contextID]);
|
||||
}
|
||||
|
||||
inline void unbindBuffer(unsigned int contextID) const
|
||||
{
|
||||
Extensions* extensions = getExtensions(contextID,true);
|
||||
extensions->glBindBuffer(_target,0);
|
||||
}
|
||||
|
||||
virtual bool needsCompile(unsigned int contextID) const = 0;
|
||||
|
||||
virtual void compileBuffer(State& state) const = 0;
|
||||
|
||||
void releaseBuffer(State* state) const;
|
||||
|
||||
|
||||
/** Use deleteVertexBufferObject instead of glDeleteBuffers to allow
|
||||
* OpenGL buffer objects to be cached until they can be deleted
|
||||
* by the OpenGL context in which they were created, specified
|
||||
* by contextID.*/
|
||||
static void deleteBufferObject(unsigned int contextID,GLuint globj);
|
||||
|
||||
/** flush all the cached display list which need to be deleted
|
||||
* in the OpenGL context related to contextID.*/
|
||||
void BufferObject::flushDeletedBufferObjects(unsigned int contextID,double /*currentTime*/, double& availableTime);
|
||||
|
||||
/** Extensions class which encapsulates the querying of extensions and
|
||||
* associated function pointers, and provide convenience wrappers to
|
||||
* check for the extensions or use the associated functions.*/
|
||||
class SG_EXPORT Extensions : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
Extensions();
|
||||
|
||||
Extensions(const Extensions& rhs);
|
||||
|
||||
void lowestCommonDenominator(const Extensions& rhs);
|
||||
|
||||
void setupGLExtenions();
|
||||
|
||||
bool isBufferObjectSupported() const { return _glGenBuffers!=0; }
|
||||
|
||||
void glGenBuffers (GLsizei n, GLuint *buffers) const;
|
||||
void glBindBuffer (GLenum target, GLuint buffer) const;
|
||||
void glBufferData (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) const;
|
||||
void glBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) const;
|
||||
void glDeleteBuffers (GLsizei n, const GLuint *buffers) const;
|
||||
GLboolean glIsBuffer (GLuint buffer) const;
|
||||
void glGetBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data) const;
|
||||
GLvoid* glMapBuffer (GLenum target, GLenum access) const;
|
||||
GLboolean glUnmapBuffer (GLenum target) const;
|
||||
void glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params) const;
|
||||
void glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params) const;
|
||||
|
||||
protected:
|
||||
|
||||
typedef void (APIENTRY * GenBuffersProc) (GLsizei n, GLuint *buffers);
|
||||
typedef void (APIENTRY * BindBufferProc) (GLenum target, GLuint buffer);
|
||||
typedef void (APIENTRY * BufferDataProc) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
|
||||
typedef void (APIENTRY * BufferSubDataProc) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
|
||||
typedef void (APIENTRY * DeleteBuffersProc) (GLsizei n, const GLuint *buffers);
|
||||
typedef GLboolean (APIENTRY * IsBufferProc) (GLuint buffer);
|
||||
typedef void (APIENTRY * GetBufferSubDataProc) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data);
|
||||
typedef GLvoid* (APIENTRY * MapBufferProc) (GLenum target, GLenum access);
|
||||
typedef GLboolean (APIENTRY * UnmapBufferProc) (GLenum target);
|
||||
typedef void (APIENTRY * GetBufferParameterivProc) (GLenum target, GLenum pname, GLint *params);
|
||||
typedef void (APIENTRY * GetBufferPointervProc) (GLenum target, GLenum pname, GLvoid* *params);
|
||||
|
||||
GenBuffersProc _glGenBuffers;
|
||||
BindBufferProc _glBindBuffer;
|
||||
BufferDataProc _glBufferData;
|
||||
BufferSubDataProc _glBufferSubData;
|
||||
DeleteBuffersProc _glDeleteBuffers;
|
||||
IsBufferProc _glIsBuffer;
|
||||
GetBufferSubDataProc _glGetBufferSubData;
|
||||
MapBufferProc _glMapBuffer;
|
||||
UnmapBufferProc _glUnmapBuffer;
|
||||
GetBufferParameterivProc _glGetBufferParameteriv;
|
||||
GetBufferPointervProc _glGetBufferPointerv;
|
||||
|
||||
};
|
||||
|
||||
/** Function to call to get the extension of a specified context.
|
||||
* If the Exentsion object for that context has not yet been created
|
||||
* and the 'createIfNotInitalized' flag been set to false then returns NULL.
|
||||
* If 'createIfNotInitalized' is true then the Extensions object is
|
||||
* automatically created. However, in this case the extension object is
|
||||
* only created with the graphics context associated with ContextID..*/
|
||||
static Extensions* getExtensions(unsigned int contextID,bool createIfNotInitalized);
|
||||
|
||||
/** setExtensions allows users to override the extensions across graphics contexts.
|
||||
* typically used when you have different extensions supported across graphics pipes
|
||||
* but need to ensure that they all use the same low common denominator extensions.*/
|
||||
static void setExtensions(unsigned int contextID,Extensions* extensions);
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~BufferObject();
|
||||
|
||||
unsigned int computeRequiredTotalSize() const;
|
||||
|
||||
typedef osg::buffered_value<GLuint> GLObjectList;
|
||||
|
||||
typedef std::pair< BufferEntry, ref_ptr<Array> > BufferEntryArrayPair;
|
||||
typedef std::pair< BufferEntry, ref_ptr<PrimitiveSet> > BufferEntryPrimitiveSetPair;
|
||||
|
||||
mutable GLObjectList _bufferObjectList;
|
||||
|
||||
GLenum _target;
|
||||
GLenum _usage;
|
||||
mutable unsigned int _totalSize;
|
||||
};
|
||||
|
||||
class Image;
|
||||
class SG_EXPORT PixelBufferObject : public BufferObject
|
||||
{
|
||||
public:
|
||||
|
||||
PixelBufferObject(osg::Image* image=0);
|
||||
|
||||
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
||||
PixelBufferObject(const PixelBufferObject& pbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Object(osg,PixelBufferObject);
|
||||
|
||||
typedef std::pair< BufferEntry, Image* > BufferEntryImagePair;
|
||||
|
||||
void setImage(osg::Image* image);
|
||||
|
||||
Image* getImage() { return _bufferEntryImagePair.second; }
|
||||
const Image* getImage() const { return _bufferEntryImagePair.second; }
|
||||
|
||||
unsigned int offset() const { return _bufferEntryImagePair.first.offset; }
|
||||
|
||||
virtual bool needsCompile(unsigned int contextID) const;
|
||||
|
||||
virtual void compileBuffer(State& state) const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~PixelBufferObject();
|
||||
|
||||
unsigned int computeRequiredTotalSize() const;
|
||||
|
||||
BufferEntryImagePair _bufferEntryImagePair;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -15,58 +15,11 @@
|
||||
#define OSG_DRAWABLE 1
|
||||
|
||||
#include <osg/BoundingBox>
|
||||
#include <osg/State>
|
||||
#include <osg/NodeVisitor>
|
||||
#include <osg/Shape>
|
||||
#include <osg/buffered_value>
|
||||
#include <osg/BufferObject>
|
||||
#include <osg/PrimitiveSet>
|
||||
|
||||
#ifndef GL_ARB_vertex_buffer_object
|
||||
|
||||
// for compatibility with gl.h headers that don't support VBO,
|
||||
#if defined(_WIN64)
|
||||
typedef __int64 GLintptrARB;
|
||||
typedef __int64 GLsizeiptrARB;
|
||||
#elif defined(__ia64__) || defined(__x86_64__)
|
||||
typedef long int GLintptrARB;
|
||||
typedef long int GLsizeiptrARB;
|
||||
#else
|
||||
typedef int GLintptrARB;
|
||||
typedef int GLsizeiptrARB;
|
||||
#endif
|
||||
|
||||
#define GL_ARRAY_BUFFER_ARB 0x8892
|
||||
#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
|
||||
#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
|
||||
#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
|
||||
#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
|
||||
#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
|
||||
#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
|
||||
#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
|
||||
#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
|
||||
#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
|
||||
#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
|
||||
#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
|
||||
#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
|
||||
#define GL_STREAM_DRAW_ARB 0x88E0
|
||||
#define GL_STREAM_READ_ARB 0x88E1
|
||||
#define GL_STREAM_COPY_ARB 0x88E2
|
||||
#define GL_STATIC_DRAW_ARB 0x88E4
|
||||
#define GL_STATIC_READ_ARB 0x88E5
|
||||
#define GL_STATIC_COPY_ARB 0x88E6
|
||||
#define GL_DYNAMIC_DRAW_ARB 0x88E8
|
||||
#define GL_DYNAMIC_READ_ARB 0x88E9
|
||||
#define GL_DYNAMIC_COPY_ARB 0x88EA
|
||||
#define GL_READ_ONLY_ARB 0x88B8
|
||||
#define GL_WRITE_ONLY_ARB 0x88B9
|
||||
#define GL_READ_WRITE_ARB 0x88BA
|
||||
#define GL_BUFFER_SIZE_ARB 0x8764
|
||||
#define GL_BUFFER_USAGE_ARB 0x8765
|
||||
#define GL_BUFFER_ACCESS_ARB 0x88BB
|
||||
#define GL_BUFFER_MAPPED_ARB 0x88BC
|
||||
#define GL_BUFFER_MAP_POINTER_ARB 0x88BD
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef GL_NV_occlusion_query
|
||||
|
||||
@@ -395,7 +348,7 @@ class SG_EXPORT Drawable : public Object
|
||||
* in the OpenGL context related to contextID.*/
|
||||
static void flushDeletedDisplayLists(unsigned int contextID,double& availableTime);
|
||||
|
||||
/** Use deleteVertexBufferObject instead of glDeleteList to allow
|
||||
/** Use deleteVertexBufferObject instead of glDeleteBuffers to allow
|
||||
* OpenGL buffer objects to be cached until they can be deleted
|
||||
* by the OpenGL context in which they were created, specified
|
||||
* by contextID.*/
|
||||
@@ -490,50 +443,6 @@ class SG_EXPORT Drawable : public Object
|
||||
virtual void accept(ConstAttributeFunctor&) const {}
|
||||
|
||||
|
||||
class PrimitiveFunctor
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~PrimitiveFunctor() {}
|
||||
|
||||
virtual void setVertexArray(unsigned int count,const Vec2* vertices) = 0;
|
||||
virtual void setVertexArray(unsigned int count,const Vec3* vertices) = 0;
|
||||
virtual void setVertexArray(unsigned int count,const Vec4* vertices) = 0;
|
||||
|
||||
virtual void drawArrays(GLenum mode,GLint first,GLsizei count) = 0;
|
||||
virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices) = 0;
|
||||
virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices) = 0;
|
||||
virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices) = 0;
|
||||
|
||||
virtual void begin(GLenum mode) = 0;
|
||||
virtual void vertex(const Vec2& vert) = 0;
|
||||
virtual void vertex(const Vec3& vert) = 0;
|
||||
virtual void vertex(const Vec4& vert) = 0;
|
||||
virtual void vertex(float x,float y) = 0;
|
||||
virtual void vertex(float x,float y,float z) = 0;
|
||||
virtual void vertex(float x,float y,float z,float w) = 0;
|
||||
virtual void end() = 0;
|
||||
};
|
||||
|
||||
class PrimitiveIndexFunctor
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~PrimitiveIndexFunctor() {}
|
||||
|
||||
virtual void setVertexArray(unsigned int count,const Vec2* vertices) = 0;
|
||||
virtual void setVertexArray(unsigned int count,const Vec3* vertices) = 0;
|
||||
virtual void setVertexArray(unsigned int count,const Vec4* vertices) = 0;
|
||||
|
||||
virtual void drawArrays(GLenum mode,GLint first,GLsizei count) = 0;
|
||||
virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices) = 0;
|
||||
virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices) = 0;
|
||||
virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices) = 0;
|
||||
|
||||
virtual void begin(GLenum mode) = 0;
|
||||
virtual void vertex(unsigned int pos) = 0;
|
||||
virtual void end() = 0;
|
||||
};
|
||||
|
||||
/** Return true if the Drawable subclass supports accept(PrimitiveFunctor&).*/
|
||||
virtual bool supports(PrimitiveFunctor&) const { return false; }
|
||||
|
||||
@@ -14,8 +14,7 @@
|
||||
#ifndef OSG_IMAGE
|
||||
#define OSG_IMAGE 1
|
||||
|
||||
#include <osg/Object>
|
||||
#include <osg/GL>
|
||||
#include <osg/BufferObject>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -72,7 +71,6 @@ class SG_EXPORT Image : public Object
|
||||
void setFileName(const std::string& fileName);
|
||||
inline const std::string& getFileName() const { return _fileName; }
|
||||
|
||||
|
||||
enum AllocationMode {
|
||||
NO_DELETE,
|
||||
USE_NEW_DELETE,
|
||||
@@ -134,9 +132,6 @@ class SG_EXPORT Image : public Object
|
||||
void copySubImage(int s_offset,int t_offset,int r_offset,osg::Image* source);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Width of image. */
|
||||
inline int s() const { return _s; }
|
||||
|
||||
@@ -190,6 +185,7 @@ class SG_EXPORT Image : public Object
|
||||
return _data+(column*getPixelSizeInBits())/8+row*getRowSizeInBytes()+image*getImageSizeInBytes();
|
||||
}
|
||||
|
||||
|
||||
/** Flip the image horizontally. */
|
||||
void flipHorizontal();
|
||||
|
||||
@@ -204,14 +200,14 @@ class SG_EXPORT Image : public Object
|
||||
*/
|
||||
void ensureValidSizeForTexturing(GLint maxTextureSize);
|
||||
|
||||
/** Dirty the image, which increments the modified flag, to force osg::Texture to reload the image. */
|
||||
inline void dirty() { ++_modifiedTag; }
|
||||
/** Dirty the image, which increments the modified count, to force osg::Texture to reload the image. */
|
||||
inline void dirty() { ++_modifiedCount; }
|
||||
|
||||
/** Set the modified tag value. Only used by osg::Texture when using texture subloading. */
|
||||
inline void setModifiedTag(unsigned int value) { _modifiedTag=value; }
|
||||
/** Set the modified count value. Used by osg::Texture when using texture subloading. */
|
||||
inline void setModifiedCount(unsigned int value) { _modifiedCount=value; }
|
||||
|
||||
/** Get modified tag value. Only used by osg::Texture when using texture subloading. */
|
||||
inline unsigned int getModifiedTag() const { return _modifiedTag; }
|
||||
/** Get modified count value. Used by osg::Texture when using texture subloading. */
|
||||
inline unsigned int getModifiedCount() const { return _modifiedCount; }
|
||||
|
||||
|
||||
static bool isPackedType(GLenum type);
|
||||
@@ -257,6 +253,15 @@ class SG_EXPORT Image : public Object
|
||||
/** Return true if this image is translucent - i.e. it has alpha values that are less 1.0 (when normalized). */
|
||||
bool isImageTranslucent() const;
|
||||
|
||||
/** Set the optional PixelBufferObject used to map the image memory efficiently to graphics memory. */
|
||||
void setPixelBufferObject(PixelBufferObject* buffer) { _bufferObject = buffer; if (_bufferObject.valid()) _bufferObject->setImage(this); }
|
||||
|
||||
/** Get the PixelBufferObject.*/
|
||||
PixelBufferObject* getPixelBufferObject() { return _bufferObject.get(); }
|
||||
|
||||
/** Get the const PixelBufferObject.*/
|
||||
const PixelBufferObject* getPixelBufferObject() const { return _bufferObject.get(); }
|
||||
|
||||
protected :
|
||||
|
||||
virtual ~Image();
|
||||
@@ -278,9 +283,11 @@ class SG_EXPORT Image : public Object
|
||||
|
||||
void setData(unsigned char *data,AllocationMode allocationMode);
|
||||
|
||||
unsigned int _modifiedTag;
|
||||
unsigned int _modifiedCount;
|
||||
|
||||
MipmapDataType _mipmapData;
|
||||
|
||||
ref_ptr<PixelBufferObject> _bufferObject;
|
||||
};
|
||||
|
||||
class Geode;
|
||||
|
||||
@@ -14,10 +14,63 @@
|
||||
#ifndef OSG_PRIMITIVESET
|
||||
#define OSG_PRIMITIVESET 1
|
||||
|
||||
#include <osg/Drawable>
|
||||
#include <osg/GL>
|
||||
#include <osg/Object>
|
||||
#include <osg/buffered_value>
|
||||
#include <osg/Vec2>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Vec4>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace osg {
|
||||
|
||||
class State;
|
||||
class PrimitiveFunctor
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~PrimitiveFunctor() {}
|
||||
|
||||
virtual void setVertexArray(unsigned int count,const Vec2* vertices) = 0;
|
||||
virtual void setVertexArray(unsigned int count,const Vec3* vertices) = 0;
|
||||
virtual void setVertexArray(unsigned int count,const Vec4* vertices) = 0;
|
||||
|
||||
virtual void drawArrays(GLenum mode,GLint first,GLsizei count) = 0;
|
||||
virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices) = 0;
|
||||
virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices) = 0;
|
||||
virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices) = 0;
|
||||
|
||||
virtual void begin(GLenum mode) = 0;
|
||||
virtual void vertex(const Vec2& vert) = 0;
|
||||
virtual void vertex(const Vec3& vert) = 0;
|
||||
virtual void vertex(const Vec4& vert) = 0;
|
||||
virtual void vertex(float x,float y) = 0;
|
||||
virtual void vertex(float x,float y,float z) = 0;
|
||||
virtual void vertex(float x,float y,float z,float w) = 0;
|
||||
virtual void end() = 0;
|
||||
};
|
||||
|
||||
class PrimitiveIndexFunctor
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~PrimitiveIndexFunctor() {}
|
||||
|
||||
virtual void setVertexArray(unsigned int count,const Vec2* vertices) = 0;
|
||||
virtual void setVertexArray(unsigned int count,const Vec3* vertices) = 0;
|
||||
virtual void setVertexArray(unsigned int count,const Vec4* vertices) = 0;
|
||||
|
||||
virtual void drawArrays(GLenum mode,GLint first,GLsizei count) = 0;
|
||||
virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices) = 0;
|
||||
virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices) = 0;
|
||||
virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices) = 0;
|
||||
|
||||
virtual void begin(GLenum mode) = 0;
|
||||
virtual void vertex(unsigned int pos) = 0;
|
||||
virtual void end() = 0;
|
||||
};
|
||||
|
||||
#ifndef _MSC_VER
|
||||
|
||||
typedef std::vector<GLsizei> VectorSizei;
|
||||
@@ -114,26 +167,31 @@ class PrimitiveSet : public Object
|
||||
|
||||
PrimitiveSet(Type primType=PrimitiveType,GLenum mode=0):
|
||||
_primitiveType(primType),
|
||||
_mode(mode) {}
|
||||
_mode(mode),
|
||||
_modifiedCount(0) {}
|
||||
|
||||
PrimitiveSet(const PrimitiveSet& prim,const CopyOp& copyop=CopyOp::SHALLOW_COPY):
|
||||
Object(prim,copyop),
|
||||
_primitiveType(prim._primitiveType),
|
||||
_mode(prim._mode) {}
|
||||
_mode(prim._mode),
|
||||
_modifiedCount(0) {}
|
||||
|
||||
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const PrimitiveSet*>(obj)!=NULL; }
|
||||
virtual const char* libraryName() const { return "osg"; }
|
||||
virtual const char* className() const { return "PrimitiveSet"; }
|
||||
|
||||
Type getType() const { return _primitiveType; }
|
||||
|
||||
Type getType() const { return _primitiveType; }
|
||||
virtual const GLvoid* getDataPointer() const { return 0; }
|
||||
virtual unsigned int getTotalDataSize() const { return 0; }
|
||||
virtual bool supportsBufferObject() const { return false; }
|
||||
|
||||
void setMode(GLenum mode) { _mode = mode; }
|
||||
GLenum getMode() const { return _mode; }
|
||||
|
||||
virtual void draw(State& state, bool useVertexBufferObjects) const = 0;
|
||||
|
||||
virtual void accept(Drawable::PrimitiveFunctor& functor) const = 0;
|
||||
virtual void accept(Drawable::PrimitiveIndexFunctor& functor) const = 0;
|
||||
virtual void accept(PrimitiveFunctor& functor) const = 0;
|
||||
virtual void accept(PrimitiveIndexFunctor& functor) const = 0;
|
||||
|
||||
virtual unsigned int index(unsigned int pos) const = 0;
|
||||
virtual unsigned int getNumIndices() const = 0;
|
||||
@@ -157,12 +215,22 @@ class PrimitiveSet : public Object
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Dirty the primitive, which increments the modified count, to force buffer objects to update. */
|
||||
inline void dirty() { ++_modifiedCount; }
|
||||
|
||||
/** Set the modified count value.*/
|
||||
inline void setModifiedCount(unsigned int value) { _modifiedCount=value; }
|
||||
|
||||
/** Get modified count value.*/
|
||||
inline unsigned int getModifiedCount() const { return _modifiedCount; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~PrimitiveSet() {}
|
||||
|
||||
Type _primitiveType;
|
||||
GLenum _mode;
|
||||
Type _primitiveType;
|
||||
GLenum _mode;
|
||||
unsigned int _modifiedCount;
|
||||
};
|
||||
|
||||
class SG_EXPORT DrawArrays : public PrimitiveSet
|
||||
@@ -206,8 +274,8 @@ class SG_EXPORT DrawArrays : public PrimitiveSet
|
||||
|
||||
virtual void draw(State& state, bool useVertexBufferObjects) const;
|
||||
|
||||
virtual void accept(Drawable::PrimitiveFunctor& functor) const;
|
||||
virtual void accept(Drawable::PrimitiveIndexFunctor& functor) const;
|
||||
virtual void accept(PrimitiveFunctor& functor) const;
|
||||
virtual void accept(PrimitiveIndexFunctor& functor) const;
|
||||
|
||||
virtual unsigned int getNumIndices() const { return _count; }
|
||||
virtual unsigned int index(unsigned int pos) const { return _first+pos; }
|
||||
@@ -262,8 +330,8 @@ class SG_EXPORT DrawArrayLengths : public PrimitiveSet, public VectorSizei
|
||||
|
||||
virtual void draw(State& state, bool useVertexBufferObjects) const;
|
||||
|
||||
virtual void accept(Drawable::PrimitiveFunctor& functor) const;
|
||||
virtual void accept(Drawable::PrimitiveIndexFunctor& functor) const;
|
||||
virtual void accept(PrimitiveFunctor& functor) const;
|
||||
virtual void accept(PrimitiveIndexFunctor& functor) const;
|
||||
|
||||
virtual unsigned int getNumIndices() const;
|
||||
virtual unsigned int index(unsigned int pos) const { return _first+pos; }
|
||||
@@ -319,10 +387,14 @@ class SG_EXPORT DrawElementsUByte : public PrimitiveSet, public VectorUByte
|
||||
virtual const char* libraryName() const { return "osg"; }
|
||||
virtual const char* className() const { return "DrawElementsUByte"; }
|
||||
|
||||
virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); }
|
||||
virtual unsigned int getTotalDataSize() const { return size(); }
|
||||
virtual bool supportsBufferObject() const { return false; }
|
||||
|
||||
virtual void draw(State& state, bool useVertexBufferObjects) const ;
|
||||
|
||||
virtual void accept(Drawable::PrimitiveFunctor& functor) const;
|
||||
virtual void accept(Drawable::PrimitiveIndexFunctor& functor) const;
|
||||
virtual void accept(PrimitiveFunctor& functor) const;
|
||||
virtual void accept(PrimitiveIndexFunctor& functor) const;
|
||||
|
||||
virtual unsigned int getNumIndices() const { return size(); }
|
||||
virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; }
|
||||
@@ -367,10 +439,14 @@ class SG_EXPORT DrawElementsUShort : public PrimitiveSet, public VectorUShort
|
||||
virtual const char* libraryName() const { return "osg"; }
|
||||
virtual const char* className() const { return "DrawElementsUShort"; }
|
||||
|
||||
virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); }
|
||||
virtual unsigned int getTotalDataSize() const { return 2*size(); }
|
||||
virtual bool supportsBufferObject() const { return false; }
|
||||
|
||||
virtual void draw(State& state, bool useVertexBufferObjects) const;
|
||||
|
||||
virtual void accept(Drawable::PrimitiveFunctor& functor) const;
|
||||
virtual void accept(Drawable::PrimitiveIndexFunctor& functor) const;
|
||||
virtual void accept(PrimitiveFunctor& functor) const;
|
||||
virtual void accept(PrimitiveIndexFunctor& functor) const;
|
||||
|
||||
virtual unsigned int getNumIndices() const { return size(); }
|
||||
virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; }
|
||||
@@ -414,10 +490,14 @@ class SG_EXPORT DrawElementsUInt : public PrimitiveSet, public VectorUInt
|
||||
virtual const char* libraryName() const { return "osg"; }
|
||||
virtual const char* className() const { return "DrawElementsUInt"; }
|
||||
|
||||
virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); }
|
||||
virtual unsigned int getTotalDataSize() const { return 4*size(); }
|
||||
virtual bool supportsBufferObject() const { return false; }
|
||||
|
||||
virtual void draw(State& state, bool useVertexBufferObjects) const;
|
||||
|
||||
virtual void accept(Drawable::PrimitiveFunctor& functor) const;
|
||||
virtual void accept(Drawable::PrimitiveIndexFunctor& functor) const;
|
||||
virtual void accept(PrimitiveFunctor& functor) const;
|
||||
virtual void accept(PrimitiveIndexFunctor& functor) const;
|
||||
|
||||
virtual unsigned int getNumIndices() const { return size(); }
|
||||
virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; }
|
||||
|
||||
@@ -53,10 +53,10 @@ class SG_EXPORT Texture1D : public Texture
|
||||
/** Gets the const texture image. */
|
||||
inline const Image* getImage() const { return _image.get(); }
|
||||
|
||||
inline unsigned int& getModifiedTag(unsigned int contextID) const
|
||||
inline unsigned int& getModifiedCount(unsigned int contextID) const
|
||||
{
|
||||
// get the modified tag for the current contextID.
|
||||
return _modifiedTag[contextID];
|
||||
// get the modified count for the current contextID.
|
||||
return _modifiedCount[contextID];
|
||||
}
|
||||
|
||||
|
||||
@@ -152,8 +152,8 @@ class SG_EXPORT Texture1D : public Texture
|
||||
|
||||
ref_ptr<SubloadCallback> _subloadCallback;
|
||||
|
||||
typedef buffered_value<unsigned int> ImageModifiedTag;
|
||||
mutable ImageModifiedTag _modifiedTag;
|
||||
typedef buffered_value<unsigned int> ImageModifiedCount;
|
||||
mutable ImageModifiedCount _modifiedCount;
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -53,10 +53,10 @@ class SG_EXPORT Texture2D : public Texture
|
||||
/** Gets the const texture image. */
|
||||
inline const Image* getImage() const { return _image.get(); }
|
||||
|
||||
inline unsigned int& getModifiedTag(unsigned int contextID) const
|
||||
inline unsigned int& getModifiedCount(unsigned int contextID) const
|
||||
{
|
||||
// get the modified tag for the current contextID.
|
||||
return _modifiedTag[contextID];
|
||||
// get the modified count for the current contextID.
|
||||
return _modifiedCount[contextID];
|
||||
}
|
||||
|
||||
|
||||
@@ -159,8 +159,8 @@ class SG_EXPORT Texture2D : public Texture
|
||||
|
||||
ref_ptr<SubloadCallback> _subloadCallback;
|
||||
|
||||
typedef buffered_value<unsigned int> ImageModifiedTag;
|
||||
mutable ImageModifiedTag _modifiedTag;
|
||||
typedef buffered_value<unsigned int> ImageModifiedCount;
|
||||
mutable ImageModifiedCount _modifiedCount;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -51,10 +51,10 @@ class SG_EXPORT Texture3D : public Texture
|
||||
/** Gets the const texture image. */
|
||||
inline const Image* getImage() const { return _image.get(); }
|
||||
|
||||
inline unsigned int& getModifiedTag(unsigned int contextID) const
|
||||
inline unsigned int& getModifiedCount(unsigned int contextID) const
|
||||
{
|
||||
// get the modified tag for the current contextID.
|
||||
return _modifiedTag[contextID];
|
||||
// get the modified count for the current contextID.
|
||||
return _modifiedCount[contextID];
|
||||
}
|
||||
|
||||
/** Sets the texture image, ignoring face. */
|
||||
@@ -221,8 +221,8 @@ class SG_EXPORT Texture3D : public Texture
|
||||
|
||||
ref_ptr<SubloadCallback> _subloadCallback;
|
||||
|
||||
typedef buffered_value<unsigned int> ImageModifiedTag;
|
||||
mutable ImageModifiedTag _modifiedTag;
|
||||
typedef buffered_value<unsigned int> ImageModifiedCount;
|
||||
mutable ImageModifiedCount _modifiedCount;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -65,10 +65,10 @@ class SG_EXPORT TextureCubeMap : public Texture
|
||||
/** Get the number of images that can be assigned to the Texture. */
|
||||
virtual unsigned int getNumImages() const { return 6; }
|
||||
|
||||
inline unsigned int& getModifiedTag(unsigned int face,unsigned int contextID) const
|
||||
inline unsigned int& getModifiedCount(unsigned int face,unsigned int contextID) const
|
||||
{
|
||||
// get the modified tag for the current contextID.
|
||||
return _modifiedTag[face][contextID];
|
||||
// get the modified count for the current contextID.
|
||||
return _modifiedCount[face][contextID];
|
||||
}
|
||||
|
||||
/** Set the texture width and height. If width or height are zero then
|
||||
@@ -176,8 +176,8 @@ class SG_EXPORT TextureCubeMap : public Texture
|
||||
|
||||
ref_ptr<SubloadCallback> _subloadCallback;
|
||||
|
||||
typedef buffered_value<unsigned int> ImageModifiedTag;
|
||||
mutable ImageModifiedTag _modifiedTag[6];
|
||||
typedef buffered_value<unsigned int> ImageModifiedCount;
|
||||
mutable ImageModifiedCount _modifiedCount[6];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -59,10 +59,10 @@ class SG_EXPORT TextureRectangle : public Texture
|
||||
/** Get the const texture image. */
|
||||
inline const Image* getImage() const { return _image.get(); }
|
||||
|
||||
inline unsigned int& getModifiedTag(unsigned int contextID) const
|
||||
inline unsigned int& getModifiedCount(unsigned int contextID) const
|
||||
{
|
||||
// get the modified tag for the current contextID.
|
||||
return _modifiedTag[contextID];
|
||||
// get the modified count for the current contextID.
|
||||
return _modifiedCount[contextID];
|
||||
}
|
||||
|
||||
|
||||
@@ -133,8 +133,8 @@ class SG_EXPORT TextureRectangle : public Texture
|
||||
|
||||
ref_ptr<SubloadCallback> _subloadCallback;
|
||||
|
||||
typedef buffered_value<unsigned int> ImageModifiedTag;
|
||||
mutable ImageModifiedTag _modifiedTag;
|
||||
typedef buffered_value<unsigned int> ImageModifiedCount;
|
||||
mutable ImageModifiedCount _modifiedCount;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
#ifndef OSG_TRIANGLEFUNCTOR
|
||||
#define OSG_TRIANGLEFUNCTOR 1
|
||||
|
||||
#include <osg/Drawable>
|
||||
#include <osg/PrimitiveSet>
|
||||
#include <osg/Notify>
|
||||
|
||||
namespace osg {
|
||||
|
||||
template<class T>
|
||||
class TriangleFunctor : public Drawable::PrimitiveFunctor, public T
|
||||
class TriangleFunctor : public PrimitiveFunctor, public T
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
#ifndef OSG_TRIANGLEINDEXFUNCTOR
|
||||
#define OSG_TRIANGLEINDEXFUNCTOR 1
|
||||
|
||||
#include <osg/Drawable>
|
||||
#include <osg/PrimitiveSet>
|
||||
#include <osg/Notify>
|
||||
|
||||
namespace osg {
|
||||
|
||||
template<class T>
|
||||
class TriangleIndexFunctor : public Drawable::PrimitiveIndexFunctor, public T
|
||||
class TriangleIndexFunctor : public PrimitiveIndexFunctor, public T
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
@@ -230,10 +230,10 @@ public:
|
||||
virtual void accept(osg::Drawable::ConstAttributeFunctor& af) const;
|
||||
|
||||
/** return true, osgText::Text does support accept(PrimitiveFunctor&) .*/
|
||||
virtual bool supports(osg::Drawable::PrimitiveFunctor&) const { return true; }
|
||||
virtual bool supports(osg::PrimitiveFunctor&) const { return true; }
|
||||
|
||||
/** accept a PrimtiveFunctor and call its methods to tell it about the interal primtives that this Drawable has.*/
|
||||
virtual void accept(osg::Drawable::PrimitiveFunctor& pf) const;
|
||||
virtual void accept(osg::PrimitiveFunctor& pf) const;
|
||||
|
||||
|
||||
// make Font a friend to allow it set the _font to 0 if the font is
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#ifndef OSGUTIL_STATISTICS
|
||||
#define OSGUTIL_STATISTICS 1
|
||||
|
||||
#include <osg/Referenced>
|
||||
#include <osg/PrimitiveSet>
|
||||
#include <osg/Drawable>
|
||||
|
||||
#include <map>
|
||||
@@ -34,7 +34,7 @@ namespace osgUtil {
|
||||
* each trifan or tristrip = (length-2) triangles and so on.
|
||||
*/
|
||||
|
||||
class Statistics : public osg::Drawable::PrimitiveFunctor
|
||||
class Statistics : public osg::PrimitiveFunctor
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
371
src/osg/BufferObject.cpp
Normal file
371
src/osg/BufferObject.cpp
Normal file
@@ -0,0 +1,371 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#include <osg/BufferObject>
|
||||
#include <osg/Notify>
|
||||
#include <osg/GLExtensions>
|
||||
#include <osg/Timer>
|
||||
#include <osg/Image>
|
||||
|
||||
#include <OpenThreads/ScopedLock>
|
||||
#include <OpenThreads/Mutex>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
// static cache of deleted display lists which can only
|
||||
// by completely deleted once the appropriate OpenGL context
|
||||
// is set. Used osg::BufferObject::deleteDisplayList(..) and flushDeletedBufferObjects(..) below.
|
||||
typedef std::multimap<unsigned int,GLuint> DisplayListMap;
|
||||
typedef std::map<unsigned int,DisplayListMap> DeletedBufferObjectCache;
|
||||
|
||||
static OpenThreads::Mutex s_mutex_deletedBufferObjectCache;
|
||||
static DeletedBufferObjectCache s_deletedBufferObjectCache;
|
||||
|
||||
void BufferObject::deleteBufferObject(unsigned int contextID,GLuint globj)
|
||||
{
|
||||
if (globj!=0)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedBufferObjectCache);
|
||||
|
||||
// insert the globj into the cache for the appropriate context.
|
||||
s_deletedBufferObjectCache[contextID].insert(DisplayListMap::value_type(0,globj));
|
||||
}
|
||||
}
|
||||
|
||||
/** flush all the cached display list which need to be deleted
|
||||
* in the OpenGL context related to contextID.*/
|
||||
void BufferObject::flushDeletedBufferObjects(unsigned int contextID,double /*currentTime*/, double& availableTime)
|
||||
{
|
||||
// if no time available don't try to flush objects.
|
||||
if (availableTime<=0.0) return;
|
||||
|
||||
const osg::Timer& timer = *osg::Timer::instance();
|
||||
osg::Timer_t start_tick = timer.tick();
|
||||
double elapsedTime = 0.0;
|
||||
|
||||
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedBufferObjectCache);
|
||||
|
||||
DeletedBufferObjectCache::iterator citr = s_deletedBufferObjectCache.find(contextID);
|
||||
if (citr!=s_deletedBufferObjectCache.end())
|
||||
{
|
||||
const Extensions* extensions = getExtensions(contextID,true);
|
||||
|
||||
unsigned int noDeleted = 0;
|
||||
|
||||
DisplayListMap& dll = citr->second;
|
||||
|
||||
DisplayListMap::iterator ditr=dll.begin();
|
||||
for(;
|
||||
ditr!=dll.end() && elapsedTime<availableTime;
|
||||
++ditr)
|
||||
{
|
||||
extensions->glDeleteBuffers(1,&(ditr->second));
|
||||
elapsedTime = timer.delta_s(start_tick,timer.tick());
|
||||
++noDeleted;
|
||||
}
|
||||
if (ditr!=dll.begin()) dll.erase(dll.begin(),ditr);
|
||||
|
||||
if (noDeleted!=0) notify(osg::INFO)<<"Number VBOs deleted = "<<noDeleted<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
availableTime -= elapsedTime;
|
||||
}
|
||||
|
||||
|
||||
BufferObject::BufferObject():
|
||||
_target(0),
|
||||
_usage(0),
|
||||
_totalSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
BufferObject::BufferObject(const BufferObject& bo,const CopyOp& copyop):
|
||||
Object(bo,copyop)
|
||||
{
|
||||
}
|
||||
|
||||
BufferObject::~BufferObject()
|
||||
{
|
||||
releaseBuffer(0);
|
||||
}
|
||||
|
||||
void BufferObject::releaseBuffer(State* state) const
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
unsigned int contextID = state->getContextID();
|
||||
if (_bufferObjectList[contextID])
|
||||
{
|
||||
deleteBufferObject(contextID,_bufferObjectList[contextID]);
|
||||
_bufferObjectList[contextID] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(unsigned int contextID=0;contextID<_bufferObjectList.size();++contextID)
|
||||
{
|
||||
if (_bufferObjectList[contextID])
|
||||
{
|
||||
deleteBufferObject(contextID,_bufferObjectList[contextID]);
|
||||
_bufferObjectList[contextID] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Extension support
|
||||
//
|
||||
|
||||
typedef buffered_value< ref_ptr<BufferObject::Extensions> > BufferedExtensions;
|
||||
static BufferedExtensions s_extensions;
|
||||
|
||||
BufferObject::Extensions* BufferObject::getExtensions(unsigned int contextID,bool createIfNotInitalized)
|
||||
{
|
||||
if (!s_extensions[contextID] && createIfNotInitalized) s_extensions[contextID] = new BufferObject::Extensions;
|
||||
return s_extensions[contextID].get();
|
||||
}
|
||||
|
||||
void BufferObject::setExtensions(unsigned int contextID,Extensions* extensions)
|
||||
{
|
||||
s_extensions[contextID] = extensions;
|
||||
}
|
||||
|
||||
BufferObject::Extensions::Extensions()
|
||||
{
|
||||
setupGLExtenions();
|
||||
}
|
||||
|
||||
BufferObject::Extensions::Extensions(const Extensions& rhs):
|
||||
Referenced()
|
||||
{
|
||||
_glGenBuffers = rhs._glGenBuffers;
|
||||
_glBindBuffer = rhs._glBindBuffer;
|
||||
_glBufferData = rhs._glBufferData;
|
||||
_glBufferSubData = rhs._glBufferSubData;
|
||||
_glDeleteBuffers = rhs._glDeleteBuffers;
|
||||
_glIsBuffer = rhs._glIsBuffer;
|
||||
_glGetBufferSubData = rhs._glGetBufferSubData;
|
||||
_glMapBuffer = rhs._glMapBuffer;
|
||||
_glUnmapBuffer = rhs._glUnmapBuffer;
|
||||
_glGetBufferParameteriv = rhs._glGetBufferParameteriv;
|
||||
_glGetBufferPointerv = rhs._glGetBufferPointerv;
|
||||
}
|
||||
|
||||
|
||||
void BufferObject::Extensions::lowestCommonDenominator(const Extensions& rhs)
|
||||
{
|
||||
if (!rhs._glGenBuffers) _glGenBuffers = rhs._glGenBuffers;
|
||||
if (!rhs._glBindBuffer) _glBindBuffer = rhs._glBindBuffer;
|
||||
if (!rhs._glBufferData) _glBufferData = rhs._glBufferData;
|
||||
if (!rhs._glBufferSubData) _glBufferSubData = rhs._glBufferSubData;
|
||||
if (!rhs._glDeleteBuffers) _glDeleteBuffers = rhs._glDeleteBuffers;
|
||||
if (!rhs._glIsBuffer) _glIsBuffer = rhs._glIsBuffer;
|
||||
if (!rhs._glGetBufferSubData) _glGetBufferSubData = rhs._glGetBufferSubData;
|
||||
if (!rhs._glMapBuffer) _glMapBuffer = rhs._glMapBuffer;
|
||||
if (!rhs._glUnmapBuffer) _glUnmapBuffer = rhs._glUnmapBuffer;
|
||||
if (!rhs._glGetBufferParameteriv) _glGetBufferParameteriv = rhs._glGetBufferParameteriv;
|
||||
if (!rhs._glGetBufferParameteriv) _glGetBufferPointerv = rhs._glGetBufferPointerv;
|
||||
}
|
||||
|
||||
void BufferObject::Extensions::setupGLExtenions()
|
||||
{
|
||||
_glGenBuffers = ((GenBuffersProc)osg::getGLExtensionFuncPtr("glGenBuffers","glGenBuffersARB"));
|
||||
_glBindBuffer = ((BindBufferProc)osg::getGLExtensionFuncPtr("glBindBuffer","glBindBufferARB"));
|
||||
_glBufferData = ((BufferDataProc)osg::getGLExtensionFuncPtr("glBufferData","glBufferDataARB"));
|
||||
_glBufferSubData = ((BufferSubDataProc)osg::getGLExtensionFuncPtr("glBufferSubData","glBufferSubDataARB"));
|
||||
_glDeleteBuffers = ((DeleteBuffersProc)osg::getGLExtensionFuncPtr("glDeleteBuffers","glDeleteBuffersARB"));
|
||||
_glIsBuffer = ((IsBufferProc)osg::getGLExtensionFuncPtr("glIsBuffer","glIsBufferARB"));
|
||||
_glGetBufferSubData = ((GetBufferSubDataProc)osg::getGLExtensionFuncPtr("glGetBufferSubData","glGetBufferSubDataARB"));
|
||||
_glMapBuffer = ((MapBufferProc)osg::getGLExtensionFuncPtr("glMapBuffer","glMapBufferARB"));
|
||||
_glUnmapBuffer = ((UnmapBufferProc)osg::getGLExtensionFuncPtr("glUnmapBuffer","glUnmapBufferARB"));
|
||||
_glGetBufferParameteriv = ((GetBufferParameterivProc)osg::getGLExtensionFuncPtr("glGetBufferParameteriv","glGetBufferParameterivARB"));
|
||||
_glGetBufferPointerv = ((GetBufferPointervProc)osg::getGLExtensionFuncPtr("glGetBufferPointerv","glGetBufferPointervARB"));
|
||||
}
|
||||
|
||||
void BufferObject::Extensions::glGenBuffers(GLsizei n, GLuint *buffers) const
|
||||
{
|
||||
if (_glGenBuffers) _glGenBuffers(n, buffers);
|
||||
else notify(WARN)<<"Error: glGenBuffers not supported by OpenGL driver"<<std::endl;
|
||||
}
|
||||
|
||||
void BufferObject::Extensions::glBindBuffer(GLenum target, GLuint buffer) const
|
||||
{
|
||||
if (_glBindBuffer) _glBindBuffer(target, buffer);
|
||||
else notify(WARN)<<"Error: glBindBuffer not supported by OpenGL driver"<<std::endl;
|
||||
}
|
||||
|
||||
void BufferObject::Extensions::glBufferData(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) const
|
||||
{
|
||||
if (_glBufferData) _glBufferData(target, size, data, usage);
|
||||
else notify(WARN)<<"Error: glBufferData not supported by OpenGL driver"<<std::endl;
|
||||
}
|
||||
|
||||
void BufferObject::Extensions::glBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) const
|
||||
{
|
||||
if (_glBufferSubData) _glBufferSubData(target, offset, size, data);
|
||||
else notify(WARN)<<"Error: glBufferData not supported by OpenGL driver"<<std::endl;
|
||||
}
|
||||
|
||||
void BufferObject::Extensions::glDeleteBuffers(GLsizei n, const GLuint *buffers) const
|
||||
{
|
||||
if (_glDeleteBuffers) _glDeleteBuffers(n, buffers);
|
||||
else notify(WARN)<<"Error: glBufferData not supported by OpenGL driver"<<std::endl;
|
||||
}
|
||||
|
||||
GLboolean BufferObject::Extensions::glIsBuffer (GLuint buffer) const
|
||||
{
|
||||
if (_glIsBuffer) return _glIsBuffer(buffer);
|
||||
else
|
||||
{
|
||||
notify(WARN)<<"Error: glIsBuffer not supported by OpenGL driver"<<std::endl;
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void BufferObject::Extensions::glGetBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data) const
|
||||
{
|
||||
if (_glGetBufferSubData) _glGetBufferSubData(target,offset,size,data);
|
||||
else notify(WARN)<<"Error: glGetBufferSubData not supported by OpenGL driver"<<std::endl;
|
||||
}
|
||||
|
||||
GLvoid* BufferObject::Extensions::glMapBuffer (GLenum target, GLenum access) const
|
||||
{
|
||||
if (_glMapBuffer) return _glMapBuffer(target,access);
|
||||
else
|
||||
{
|
||||
notify(WARN)<<"Error: glMapBuffer not supported by OpenGL driver"<<std::endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
GLboolean BufferObject::Extensions::glUnmapBuffer (GLenum target) const
|
||||
{
|
||||
if (_glUnmapBuffer) return _glUnmapBuffer(target);
|
||||
else
|
||||
{
|
||||
notify(WARN)<<"Error: glUnmapBuffer not supported by OpenGL driver"<<std::endl;
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void BufferObject::Extensions::glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params) const
|
||||
{
|
||||
if (_glGetBufferParameteriv) _glGetBufferParameteriv(target,pname,params);
|
||||
else notify(WARN)<<"Error: glGetBufferParameteriv not supported by OpenGL driver"<<std::endl;
|
||||
}
|
||||
|
||||
void BufferObject::Extensions::glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params) const
|
||||
{
|
||||
if (_glGetBufferPointerv) _glGetBufferPointerv(target,pname,params);
|
||||
else notify(WARN)<<"Error: glGetBufferPointerv not supported by OpenGL driver"<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PixelBufferObject::PixelBufferObject(osg::Image* image):
|
||||
BufferObject()
|
||||
{
|
||||
_target = GL_PIXEL_UNPACK_BUFFER_ARB;
|
||||
_usage = GL_STREAM_DRAW_ARB;
|
||||
_bufferEntryImagePair.second = image;
|
||||
}
|
||||
|
||||
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
||||
PixelBufferObject::PixelBufferObject(const PixelBufferObject& buffer,const CopyOp& copyop):
|
||||
BufferObject(buffer,copyop),
|
||||
_bufferEntryImagePair(buffer._bufferEntryImagePair)
|
||||
{
|
||||
}
|
||||
|
||||
PixelBufferObject::~PixelBufferObject()
|
||||
{
|
||||
}
|
||||
|
||||
void PixelBufferObject::setImage(osg::Image* image)
|
||||
{
|
||||
_bufferEntryImagePair.second = image;
|
||||
}
|
||||
|
||||
bool PixelBufferObject::needsCompile(unsigned int contextID) const
|
||||
{
|
||||
if (!_bufferEntryImagePair.second)
|
||||
return false;
|
||||
|
||||
if (_bufferEntryImagePair.first.modifiedCount[contextID]!=_bufferEntryImagePair.second->getModifiedCount())
|
||||
return true;
|
||||
|
||||
if (_bufferObjectList[contextID]==0) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PixelBufferObject::compileBuffer(State& state) const
|
||||
{
|
||||
unsigned int contextID = state.getContextID();
|
||||
if (!needsCompile(contextID)) return;
|
||||
|
||||
Extensions* extensions = getExtensions(contextID,true);
|
||||
|
||||
osg::Image* image = _bufferEntryImagePair.second;
|
||||
|
||||
|
||||
GLuint& pbo = buffer(contextID);
|
||||
if (pbo==0)
|
||||
{
|
||||
// building for the first time.
|
||||
extensions->glGenBuffers(1, &pbo);
|
||||
|
||||
extensions->glBindBuffer(_target, pbo);
|
||||
|
||||
_totalSize = image->getTotalSizeInBytes();
|
||||
|
||||
extensions->glBufferData(_target, _totalSize, NULL,
|
||||
_usage);
|
||||
}
|
||||
else
|
||||
{
|
||||
extensions->glBindBuffer(_target, pbo);
|
||||
|
||||
if (_totalSize != image->getTotalSizeInBytes())
|
||||
{
|
||||
_totalSize = image->getTotalSizeInBytes();
|
||||
extensions->glBufferData(_target, _totalSize, NULL,
|
||||
_usage);
|
||||
}
|
||||
}
|
||||
|
||||
// osg::Timer_t start_tick = osg::Timer::instance()->tick();
|
||||
|
||||
void* pboMemory = extensions->glMapBuffer(_target,
|
||||
GL_WRITE_ONLY_ARB);
|
||||
|
||||
memcpy(pboMemory, image->data(), _totalSize);
|
||||
|
||||
// Unmap the texture image buffer
|
||||
extensions->glUnmapBuffer(_target);
|
||||
|
||||
extensions->glBindBuffer(_target, 0);
|
||||
|
||||
_bufferEntryImagePair.first.modifiedCount[contextID] = image->getModifiedCount();
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"pbo _totalSize="<<_totalSize<<std::endl;
|
||||
// osg::notify(osg::NOTICE)<<"pbo "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl;
|
||||
}
|
||||
@@ -497,7 +497,7 @@ void Drawable::setUpdateCallback(UpdateCallback* ac)
|
||||
}
|
||||
}
|
||||
|
||||
struct ComputeBound : public Drawable::PrimitiveFunctor
|
||||
struct ComputeBound : public PrimitiveFunctor
|
||||
{
|
||||
ComputeBound():_vertices(0) {}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ CXXFILES =\
|
||||
Billboard.cpp\
|
||||
BoundingBox.cpp\
|
||||
BoundingSphere.cpp\
|
||||
BufferObject.cpp\
|
||||
BlendColor.cpp\
|
||||
BlendFunc.cpp\
|
||||
BlendEquation.cpp\
|
||||
|
||||
@@ -41,7 +41,7 @@ Image::Image()
|
||||
_allocationMode = USE_NEW_DELETE;
|
||||
_data = (unsigned char *)0L;
|
||||
|
||||
_modifiedTag = 0;
|
||||
_modifiedCount = 0;
|
||||
}
|
||||
|
||||
Image::Image(const Image& image,const CopyOp& copyop):
|
||||
@@ -53,7 +53,7 @@ Image::Image(const Image& image,const CopyOp& copyop):
|
||||
_dataType(image._dataType),
|
||||
_packing(image._packing),
|
||||
_data(0L),
|
||||
_modifiedTag(image._modifiedTag),
|
||||
_modifiedCount(image._modifiedCount),
|
||||
_mipmapData(image._mipmapData)
|
||||
{
|
||||
if (image._data)
|
||||
@@ -91,7 +91,7 @@ int Image::compare(const Image& rhs) const
|
||||
COMPARE_StateAttribute_Parameter(_pixelFormat)
|
||||
COMPARE_StateAttribute_Parameter(_dataType)
|
||||
COMPARE_StateAttribute_Parameter(_packing)
|
||||
COMPARE_StateAttribute_Parameter(_modifiedTag)
|
||||
COMPARE_StateAttribute_Parameter(_modifiedCount)
|
||||
|
||||
if (_data<rhs._data) return -1;
|
||||
if (_data>rhs._data) return 1;
|
||||
@@ -379,7 +379,7 @@ void Image::allocateImage(int s,int t,int r,
|
||||
_internalTextureFormat = 0;
|
||||
}
|
||||
|
||||
++_modifiedTag;
|
||||
++_modifiedCount;
|
||||
}
|
||||
|
||||
void Image::setImage(int s,int t,int r,
|
||||
@@ -403,7 +403,7 @@ void Image::setImage(int s,int t,int r,
|
||||
|
||||
_packing = packing;
|
||||
|
||||
++_modifiedTag;
|
||||
++_modifiedCount;
|
||||
|
||||
}
|
||||
|
||||
@@ -523,7 +523,7 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps
|
||||
extensions->glGetCompressedTexImage(textureMode, i, getMipmapData(i));
|
||||
}
|
||||
|
||||
++_modifiedTag;
|
||||
++_modifiedCount;
|
||||
|
||||
}
|
||||
else
|
||||
@@ -576,7 +576,7 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps
|
||||
glGetTexImage(textureMode,i,_pixelFormat,_dataType,getMipmapData(i));
|
||||
}
|
||||
|
||||
++_modifiedTag;
|
||||
++_modifiedCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,7 +639,7 @@ void Image::scaleImage(int s,int t,int r, GLenum newDataType)
|
||||
notify(WARN) << "Error Image::scaleImage() did not succeed : errorString = "<<gluErrorString((GLenum)status)<<std::endl;
|
||||
}
|
||||
|
||||
++_modifiedTag;
|
||||
++_modifiedCount;
|
||||
}
|
||||
|
||||
void Image::copySubImage(int s_offset,int t_offset,int r_offset,osg::Image* source)
|
||||
@@ -729,7 +729,7 @@ void Image::flipHorizontal()
|
||||
}
|
||||
}
|
||||
|
||||
++_modifiedTag;
|
||||
++_modifiedCount;
|
||||
}
|
||||
|
||||
void flipImageVertical(unsigned char* top, unsigned char* bottom, unsigned int rowSize)
|
||||
@@ -813,7 +813,7 @@ void Image::flipVertical()
|
||||
}
|
||||
}
|
||||
|
||||
++_modifiedTag;
|
||||
++_modifiedCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@ ImageStream::ImageStream():
|
||||
_loopingMode(LOOPING)
|
||||
{
|
||||
setDataVariance(DYNAMIC);
|
||||
#if 1
|
||||
setPixelBufferObject(new PixelBufferObject(this));
|
||||
#endif
|
||||
}
|
||||
|
||||
ImageStream::ImageStream(const ImageStream& image,const CopyOp& copyop):
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
#include <osg/PrimitiveSet>
|
||||
#include <osg/BufferObject>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
@@ -19,12 +20,12 @@ void DrawArrays::draw(State&, bool) const
|
||||
glDrawArrays(_mode,_first,_count);
|
||||
}
|
||||
|
||||
void DrawArrays::accept(Drawable::PrimitiveFunctor& functor) const
|
||||
void DrawArrays::accept(PrimitiveFunctor& functor) const
|
||||
{
|
||||
functor.drawArrays(_mode,_first,_count);
|
||||
}
|
||||
|
||||
void DrawArrays::accept(Drawable::PrimitiveIndexFunctor& functor) const
|
||||
void DrawArrays::accept(PrimitiveIndexFunctor& functor) const
|
||||
{
|
||||
functor.drawArrays(_mode,_first,_count);
|
||||
}
|
||||
@@ -41,7 +42,7 @@ void DrawArrayLengths::draw(State&, bool) const
|
||||
}
|
||||
}
|
||||
|
||||
void DrawArrayLengths::accept(Drawable::PrimitiveFunctor& functor) const
|
||||
void DrawArrayLengths::accept(PrimitiveFunctor& functor) const
|
||||
{
|
||||
GLint first = _first;
|
||||
for(VectorSizei::const_iterator itr=begin();
|
||||
@@ -53,7 +54,7 @@ void DrawArrayLengths::accept(Drawable::PrimitiveFunctor& functor) const
|
||||
}
|
||||
}
|
||||
|
||||
void DrawArrayLengths::accept(Drawable::PrimitiveIndexFunctor& functor) const
|
||||
void DrawArrayLengths::accept(PrimitiveIndexFunctor& functor) const
|
||||
{
|
||||
GLint first = _first;
|
||||
for(VectorSizei::const_iterator itr=begin();
|
||||
@@ -83,7 +84,7 @@ DrawElementsUByte::~DrawElementsUByte()
|
||||
{
|
||||
if (_vboList[i] != 0)
|
||||
{
|
||||
Drawable::deleteVertexBufferObject(i,_vboList[i]);
|
||||
BufferObject::deleteBufferObject(i,_vboList[i]);
|
||||
_vboList[i] = 0;
|
||||
}
|
||||
}
|
||||
@@ -93,7 +94,7 @@ void DrawElementsUByte::draw(State& state, bool useVertexBufferObjects) const
|
||||
{
|
||||
if (useVertexBufferObjects)
|
||||
{
|
||||
const Drawable::Extensions* extensions = Drawable::getExtensions(state.getContextID(), true);
|
||||
const BufferObject::Extensions* extensions = BufferObject::getExtensions(state.getContextID(), true);
|
||||
|
||||
GLuint& buffer = _vboList[state.getContextID()];
|
||||
if (!buffer)
|
||||
@@ -116,12 +117,12 @@ void DrawElementsUByte::draw(State& state, bool useVertexBufferObjects) const
|
||||
}
|
||||
}
|
||||
|
||||
void DrawElementsUByte::accept(Drawable::PrimitiveFunctor& functor) const
|
||||
void DrawElementsUByte::accept(PrimitiveFunctor& functor) const
|
||||
{
|
||||
if (!empty()) functor.drawElements(_mode,size(),&front());
|
||||
}
|
||||
|
||||
void DrawElementsUByte::accept(Drawable::PrimitiveIndexFunctor& functor) const
|
||||
void DrawElementsUByte::accept(PrimitiveIndexFunctor& functor) const
|
||||
{
|
||||
if (!empty()) functor.drawElements(_mode,size(),&front());
|
||||
}
|
||||
@@ -143,7 +144,7 @@ DrawElementsUShort::~DrawElementsUShort()
|
||||
{
|
||||
if (_vboList[i] != 0)
|
||||
{
|
||||
Drawable::deleteVertexBufferObject(i,_vboList[i]);
|
||||
BufferObject::deleteBufferObject(i,_vboList[i]);
|
||||
_vboList[i] = 0;
|
||||
}
|
||||
}
|
||||
@@ -153,7 +154,7 @@ void DrawElementsUShort::draw(State& state, bool useVertexBufferObjects) const
|
||||
{
|
||||
if (useVertexBufferObjects)
|
||||
{
|
||||
const Drawable::Extensions* extensions = Drawable::getExtensions(state.getContextID(), true);
|
||||
const BufferObject::Extensions* extensions = BufferObject::getExtensions(state.getContextID(), true);
|
||||
|
||||
GLuint& buffer = _vboList[state.getContextID()];
|
||||
if (!buffer)
|
||||
@@ -167,8 +168,8 @@ void DrawElementsUShort::draw(State& state, bool useVertexBufferObjects) const
|
||||
extensions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, buffer);
|
||||
}
|
||||
|
||||
glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, 0);
|
||||
extensions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
|
||||
glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -176,12 +177,12 @@ void DrawElementsUShort::draw(State& state, bool useVertexBufferObjects) const
|
||||
}
|
||||
}
|
||||
|
||||
void DrawElementsUShort::accept(Drawable::PrimitiveFunctor& functor) const
|
||||
void DrawElementsUShort::accept(PrimitiveFunctor& functor) const
|
||||
{
|
||||
if (!empty()) functor.drawElements(_mode,size(),&front());
|
||||
}
|
||||
|
||||
void DrawElementsUShort::accept(Drawable::PrimitiveIndexFunctor& functor) const
|
||||
void DrawElementsUShort::accept(PrimitiveIndexFunctor& functor) const
|
||||
{
|
||||
if (!empty()) functor.drawElements(_mode,size(),&front());
|
||||
}
|
||||
@@ -203,7 +204,7 @@ DrawElementsUInt::~DrawElementsUInt()
|
||||
{
|
||||
if (_vboList[i] != 0)
|
||||
{
|
||||
Drawable::deleteVertexBufferObject(i,_vboList[i]);
|
||||
BufferObject::deleteBufferObject(i,_vboList[i]);
|
||||
_vboList[i] = 0;
|
||||
}
|
||||
}
|
||||
@@ -213,7 +214,7 @@ void DrawElementsUInt::draw(State& state, bool useVertexBufferObjects) const
|
||||
{
|
||||
if (useVertexBufferObjects)
|
||||
{
|
||||
const Drawable::Extensions* extensions = Drawable::getExtensions(state.getContextID(), true);
|
||||
const BufferObject::Extensions* extensions = BufferObject::getExtensions(state.getContextID(), true);
|
||||
|
||||
GLuint& buffer = _vboList[state.getContextID()];
|
||||
if (!buffer)
|
||||
@@ -236,12 +237,12 @@ void DrawElementsUInt::draw(State& state, bool useVertexBufferObjects) const
|
||||
}
|
||||
}
|
||||
|
||||
void DrawElementsUInt::accept(Drawable::PrimitiveFunctor& functor) const
|
||||
void DrawElementsUInt::accept(PrimitiveFunctor& functor) const
|
||||
{
|
||||
if (!empty()) functor.drawElements(_mode,size(),&front());
|
||||
}
|
||||
|
||||
void DrawElementsUInt::accept(Drawable::PrimitiveIndexFunctor& functor) const
|
||||
void DrawElementsUInt::accept(PrimitiveIndexFunctor& functor) const
|
||||
{
|
||||
if (!empty()) functor.drawElements(_mode,size(),&front());
|
||||
}
|
||||
|
||||
@@ -1303,7 +1303,7 @@ class PrimitiveShapeVisitor : public ConstShapeVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
PrimitiveShapeVisitor(Drawable::PrimitiveFunctor& functor,const TessellationHints* hints):
|
||||
PrimitiveShapeVisitor(PrimitiveFunctor& functor,const TessellationHints* hints):
|
||||
_functor(functor),
|
||||
_hints(hints) {}
|
||||
|
||||
@@ -1320,7 +1320,7 @@ class PrimitiveShapeVisitor : public ConstShapeVisitor
|
||||
|
||||
virtual void apply(const CompositeShape&);
|
||||
|
||||
Drawable::PrimitiveFunctor& _functor;
|
||||
PrimitiveFunctor& _functor;
|
||||
const TessellationHints* _hints;
|
||||
};
|
||||
|
||||
|
||||
@@ -1026,6 +1026,23 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
|
||||
}
|
||||
|
||||
bool useHardwareMipMapGeneration = !image->isMipmap() && _useHardwareMipMapGeneration && generateMipMapSupported;
|
||||
|
||||
unsigned int dataMinusOffset=0;
|
||||
unsigned int dataPlusOffset=0;
|
||||
|
||||
const PixelBufferObject* pbo = image->getPixelBufferObject();
|
||||
if (pbo && pbo->isBufferObjectSupported(contextID) && !needImageRescale)
|
||||
{
|
||||
pbo->compileBuffer(state);
|
||||
pbo->bindBuffer(contextID);
|
||||
dataMinusOffset = (unsigned int) data;
|
||||
dataPlusOffset=pbo->offset(); // -dataMinusOffset+dataPlusOffset
|
||||
}
|
||||
else
|
||||
{
|
||||
pbo = 0;
|
||||
}
|
||||
|
||||
|
||||
if( _min_filter == LINEAR || _min_filter == NEAREST || useHardwareMipMapGeneration)
|
||||
{
|
||||
@@ -1045,7 +1062,7 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
|
||||
inwidth, inheight,
|
||||
(GLenum)image->getPixelFormat(),
|
||||
(GLenum)image->getDataType(),
|
||||
data );
|
||||
data - dataMinusOffset+dataPlusOffset);
|
||||
|
||||
}
|
||||
else if (extensions->isCompressedTexImage2DSupported())
|
||||
@@ -1058,7 +1075,7 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
|
||||
inwidth, inheight,
|
||||
(GLenum)image->getPixelFormat(),
|
||||
size,
|
||||
data );
|
||||
data + -dataMinusOffset+dataPlusOffset );
|
||||
}
|
||||
|
||||
if (hardwareMipMapOn) glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_FALSE);
|
||||
@@ -1087,7 +1104,7 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
|
||||
width, height,
|
||||
(GLenum)image->getPixelFormat(),
|
||||
(GLenum)image->getDataType(),
|
||||
image->getMipmapData(k));
|
||||
image->getMipmapData(k) -dataMinusOffset+dataPlusOffset);
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
@@ -1112,7 +1129,7 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
|
||||
width, height,
|
||||
(GLenum)image->getPixelFormat(),
|
||||
size,
|
||||
image->getMipmapData(k));
|
||||
image->getMipmapData(k) -dataMinusOffset+dataPlusOffset);
|
||||
|
||||
//state.checkGLErrors("after extensions->glCompressedTexSubImage2D(");
|
||||
|
||||
@@ -1196,6 +1213,11 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
|
||||
}
|
||||
}
|
||||
|
||||
if (pbo)
|
||||
{
|
||||
pbo->unbindBuffer(contextID);
|
||||
}
|
||||
|
||||
if (needImageRescale)
|
||||
{
|
||||
// clean up the resized image.
|
||||
|
||||
@@ -80,7 +80,7 @@ void Texture1D::setImage(Image* image)
|
||||
dirtyTextureObject();
|
||||
|
||||
_image = image;
|
||||
_modifiedTag.setAllElementsTo(0);
|
||||
_modifiedCount.setAllElementsTo(0);
|
||||
|
||||
}
|
||||
|
||||
@@ -105,12 +105,12 @@ void Texture1D::apply(State& state) const
|
||||
{
|
||||
_subloadCallback->subload(*this,state);
|
||||
}
|
||||
else if (_image.valid() && getModifiedTag(contextID) != _image->getModifiedTag())
|
||||
else if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount())
|
||||
{
|
||||
applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMipmapLevels);
|
||||
|
||||
// update the modified tag to show that it is upto date.
|
||||
getModifiedTag(contextID) = _image->getModifiedTag();
|
||||
// update the modified count to show that it is upto date.
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -149,8 +149,8 @@ void Texture1D::apply(State& state) const
|
||||
|
||||
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,1,1,0);
|
||||
|
||||
// update the modified tag to show that it is upto date.
|
||||
getModifiedTag(contextID) = _image->getModifiedTag();
|
||||
// update the modified count to show that it is upto date.
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
|
||||
if (_unrefImageDataAfterApply && areAllTextureObjectsLoaded() && _image->getDataVariance()==STATIC)
|
||||
{
|
||||
|
||||
@@ -92,7 +92,7 @@ int Texture2D::compare(const StateAttribute& sa) const
|
||||
void Texture2D::setImage(Image* image)
|
||||
{
|
||||
_image = image;
|
||||
_modifiedTag.setAllElementsTo(0);
|
||||
_modifiedCount.setAllElementsTo(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -119,13 +119,13 @@ void Texture2D::apply(State& state) const
|
||||
{
|
||||
_subloadCallback->subload(*this,state);
|
||||
}
|
||||
else if (_image.valid() && getModifiedTag(contextID) != _image->getModifiedTag())
|
||||
else if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount())
|
||||
{
|
||||
applyTexImage2D_subload(state,GL_TEXTURE_2D,_image.get(),
|
||||
_textureWidth, _textureHeight, _internalFormat, _numMipmapLevels);
|
||||
|
||||
// update the modified tag to show that it is upto date.
|
||||
getModifiedTag(contextID) = _image->getModifiedTag();
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ void Texture2D::apply(State& state) const
|
||||
|
||||
|
||||
// update the modified tag to show that it is upto date.
|
||||
getModifiedTag(contextID) = _image->getModifiedTag();
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
|
||||
|
||||
if (_unrefImageDataAfterApply && areAllTextureObjectsLoaded() && _image->getDataVariance()==STATIC)
|
||||
|
||||
@@ -88,7 +88,7 @@ void Texture3D::setImage(Image* image)
|
||||
// delete old texture objects.
|
||||
dirtyTextureObject();
|
||||
|
||||
_modifiedTag.setAllElementsTo(0);
|
||||
_modifiedCount.setAllElementsTo(0);
|
||||
|
||||
_image = image;
|
||||
}
|
||||
@@ -170,12 +170,12 @@ void Texture3D::apply(State& state) const
|
||||
{
|
||||
_subloadCallback->subload(*this,state);
|
||||
}
|
||||
else if (_image.get() && getModifiedTag(contextID) != _image->getModifiedTag())
|
||||
else if (_image.get() && getModifiedCount(contextID) != _image->getModifiedCount())
|
||||
{
|
||||
applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMipmapLevels);
|
||||
|
||||
// update the modified tag to show that it is upto date.
|
||||
getModifiedTag(contextID) = _image->getModifiedTag();
|
||||
// update the modified count to show that it is upto date.
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -219,8 +219,8 @@ void Texture3D::apply(State& state) const
|
||||
|
||||
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
|
||||
|
||||
// update the modified tag to show that it is upto date.
|
||||
getModifiedTag(contextID) = _image->getModifiedTag();
|
||||
// update the modified count to show that it is upto date.
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
|
||||
if (_unrefImageDataAfterApply && areAllTextureObjectsLoaded() && _image->getDataVariance()==STATIC)
|
||||
{
|
||||
|
||||
@@ -108,12 +108,12 @@ TextureCubeMap::TextureCubeMap(const TextureCubeMap& text,const CopyOp& copyop):
|
||||
_images[4] = copyop(text._images[4].get());
|
||||
_images[5] = copyop(text._images[5].get());
|
||||
|
||||
_modifiedTag[0].setAllElementsTo(0);
|
||||
_modifiedTag[1].setAllElementsTo(0);
|
||||
_modifiedTag[2].setAllElementsTo(0);
|
||||
_modifiedTag[3].setAllElementsTo(0);
|
||||
_modifiedTag[4].setAllElementsTo(0);
|
||||
_modifiedTag[5].setAllElementsTo(0);
|
||||
_modifiedCount[0].setAllElementsTo(0);
|
||||
_modifiedCount[1].setAllElementsTo(0);
|
||||
_modifiedCount[2].setAllElementsTo(0);
|
||||
_modifiedCount[3].setAllElementsTo(0);
|
||||
_modifiedCount[4].setAllElementsTo(0);
|
||||
_modifiedCount[5].setAllElementsTo(0);
|
||||
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ int TextureCubeMap::compare(const StateAttribute& sa) const
|
||||
void TextureCubeMap::setImage( unsigned int face, Image* image)
|
||||
{
|
||||
_images[face] = image;
|
||||
_modifiedTag[face].setAllElementsTo(0);
|
||||
_modifiedCount[face].setAllElementsTo(0);
|
||||
}
|
||||
|
||||
Image* TextureCubeMap::getImage(unsigned int face)
|
||||
@@ -223,10 +223,10 @@ void TextureCubeMap::apply(State& state) const
|
||||
for (int n=0; n<6; n++)
|
||||
{
|
||||
const osg::Image* image = _images[n].get();
|
||||
if (image && getModifiedTag((Face)n,contextID) != image->getModifiedTag())
|
||||
if (image && getModifiedCount((Face)n,contextID) != image->getModifiedCount())
|
||||
{
|
||||
applyTexImage2D_subload( state, faceTarget[n], _images[n].get(), _textureWidth, _textureHeight, _internalFormat, _numMipmapLevels);
|
||||
getModifiedTag((Face)n,contextID) = image->getModifiedTag();
|
||||
getModifiedCount((Face)n,contextID) = image->getModifiedCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -278,7 +278,7 @@ void TextureCubeMap::apply(State& state) const
|
||||
{
|
||||
applyTexImage2D_load( state, faceTarget[n], image, _textureWidth, _textureHeight, _numMipmapLevels);
|
||||
}
|
||||
getModifiedTag((Face)n,contextID) = image->getModifiedTag();
|
||||
getModifiedCount((Face)n,contextID) = image->getModifiedCount();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <osg/GLU>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <osg/Timer>
|
||||
|
||||
#ifndef GL_UNPACK_CLIENT_STORAGE_APPLE
|
||||
#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2
|
||||
#endif
|
||||
@@ -143,12 +145,12 @@ void TextureRectangle::apply(State& state) const
|
||||
{
|
||||
_subloadCallback->subload(*this, state);
|
||||
}
|
||||
else if (_image.valid() && getModifiedTag(contextID) != _image->getModifiedTag())
|
||||
else if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount())
|
||||
{
|
||||
applyTexImage_subload(GL_TEXTURE_RECTANGLE, _image.get(), state, _textureWidth, _textureHeight, _internalFormat);
|
||||
|
||||
// update the modified tag to show that it is upto date.
|
||||
getModifiedTag(contextID) = _image->getModifiedTag();
|
||||
// update the modified count to show that it is upto date.
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
}
|
||||
}
|
||||
else if (_subloadCallback.valid())
|
||||
@@ -221,8 +223,8 @@ void TextureRectangle::applyTexImage_load(GLenum target, Image* image, State& st
|
||||
const unsigned int contextID = state.getContextID();
|
||||
const Extensions* extensions = getExtensions(contextID,true);
|
||||
|
||||
// update the modified tag to show that it is upto date.
|
||||
getModifiedTag(contextID) = image->getModifiedTag();
|
||||
// update the modified count to show that it is upto date.
|
||||
getModifiedCount(contextID) = image->getModifiedCount();
|
||||
|
||||
// compute the internal texture format, sets _internalFormat.
|
||||
computeInternalFormat();
|
||||
@@ -240,13 +242,35 @@ void TextureRectangle::applyTexImage_load(GLenum target, Image* image, State& st
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int dataMinusOffset=0;
|
||||
unsigned int dataPlusOffset=0;
|
||||
|
||||
const PixelBufferObject* pbo = image->getPixelBufferObject();
|
||||
if (pbo && pbo->isBufferObjectSupported(contextID))
|
||||
{
|
||||
pbo->compileBuffer(state);
|
||||
pbo->bindBuffer(contextID);
|
||||
dataMinusOffset=(unsigned int)image->data();
|
||||
dataPlusOffset=pbo->offset(); // -dataMinusOffset+dataPlusOffset
|
||||
}
|
||||
else
|
||||
{
|
||||
pbo = 0;
|
||||
}
|
||||
|
||||
// UH: ignoring compressed for now.
|
||||
glTexImage2D(target, 0, _internalFormat,
|
||||
image->s(), image->t(), 0,
|
||||
(GLenum)image->getPixelFormat(),
|
||||
(GLenum)image->getDataType(),
|
||||
image->data());
|
||||
image->data() + -dataMinusOffset+dataPlusOffset);
|
||||
|
||||
|
||||
if (pbo)
|
||||
{
|
||||
pbo->unbindBuffer(contextID);
|
||||
}
|
||||
|
||||
inwidth = image->s();
|
||||
inheight = image->t();
|
||||
|
||||
@@ -273,21 +297,56 @@ void TextureRectangle::applyTexImage_subload(GLenum target, Image* image, State&
|
||||
// current OpenGL context.
|
||||
const unsigned int contextID = state.getContextID();
|
||||
|
||||
// update the modified tag to show that it is upto date.
|
||||
getModifiedTag(contextID) = image->getModifiedTag();
|
||||
// update the modified count to show that it is upto date.
|
||||
getModifiedCount(contextID) = image->getModifiedCount();
|
||||
|
||||
// compute the internal texture format, sets _internalFormat.
|
||||
computeInternalFormat();
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, image->getPacking());
|
||||
|
||||
#define DO_TIMING
|
||||
#ifdef DO_TIMING
|
||||
osg::Timer_t start_tick = osg::Timer::instance()->tick();
|
||||
osg::notify(osg::NOTICE)<<"glTexSubImage2D pixelFormat = "<<std::hex<<image->getPixelFormat()<<std::dec<<std::endl;
|
||||
#endif
|
||||
unsigned int dataMinusOffset=0;
|
||||
unsigned int dataPlusOffset=0;
|
||||
|
||||
const PixelBufferObject* pbo = image->getPixelBufferObject();
|
||||
if (pbo && pbo->isBufferObjectSupported(contextID))
|
||||
{
|
||||
pbo->compileBuffer(state);
|
||||
pbo->bindBuffer(contextID);
|
||||
dataMinusOffset=(unsigned int)image->data();
|
||||
dataPlusOffset=pbo->offset(); // -dataMinusOffset+dataPlusOffset
|
||||
|
||||
#ifdef DO_TIMING
|
||||
osg::notify(osg::NOTICE)<<"after PBO "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
pbo = 0;
|
||||
}
|
||||
|
||||
// UH: ignoring compressed for now.
|
||||
glTexSubImage2D(target, 0,
|
||||
0,0,
|
||||
image->s(), image->t(),
|
||||
(GLenum)image->getPixelFormat(),
|
||||
(GLenum)image->getDataType(),
|
||||
image->data());
|
||||
image->data() + -dataMinusOffset+dataPlusOffset);
|
||||
|
||||
if (pbo)
|
||||
{
|
||||
pbo->unbindBuffer(contextID);
|
||||
}
|
||||
|
||||
#ifdef DO_TIMING
|
||||
osg::notify(osg::NOTICE)<<"glTexSubImage2D "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -111,14 +111,14 @@ Node* osgDB::readNodeFiles(std::vector<std::string>& commandLine,const ReaderWri
|
||||
Node* osgDB::readNodeFiles(osg::ArgumentParser& arguments,const ReaderWriter::Options* options)
|
||||
{
|
||||
|
||||
typedef std::vector<osg::Node*> NodeList;
|
||||
typedef std::vector< osg::ref_ptr<osg::Node> > NodeList;
|
||||
NodeList nodeList;
|
||||
|
||||
std::string filename;
|
||||
while (arguments.read("--image",filename))
|
||||
{
|
||||
osg::Image* image = readImageFile(filename.c_str(), options);
|
||||
if (image) nodeList.push_back(osg::createGeodeForImage(image));
|
||||
osg::ref_ptr<osg::Image> image = readImageFile(filename.c_str(), options);
|
||||
if (image.valid()) nodeList.push_back(osg::createGeodeForImage(image.get()));
|
||||
}
|
||||
|
||||
while (arguments.read("--dem",filename))
|
||||
@@ -156,7 +156,7 @@ Node* osgDB::readNodeFiles(osg::ArgumentParser& arguments,const ReaderWriter::Op
|
||||
|
||||
if (nodeList.size()==1)
|
||||
{
|
||||
return nodeList.front();
|
||||
return nodeList.front().release();
|
||||
}
|
||||
else // size >1
|
||||
{
|
||||
@@ -165,7 +165,7 @@ Node* osgDB::readNodeFiles(osg::ArgumentParser& arguments,const ReaderWriter::Op
|
||||
itr!=nodeList.end();
|
||||
++itr)
|
||||
{
|
||||
group->addChild(*itr);
|
||||
group->addChild((*itr).get());
|
||||
}
|
||||
|
||||
return group;
|
||||
|
||||
@@ -51,7 +51,7 @@ void Image::write(DataOutputStream* out)
|
||||
out->writeInt(getPacking());
|
||||
|
||||
// Write modified tag.
|
||||
out->writeInt(getModifiedTag());
|
||||
out->writeInt(getModifiedCount());
|
||||
|
||||
// Write mipmapdata vector
|
||||
int size = _mipmapData.size();
|
||||
@@ -103,7 +103,7 @@ void Image::read(DataInputStream* in)
|
||||
unsigned int packing = (unsigned int)in->readInt();
|
||||
|
||||
// Read modified tag.
|
||||
setModifiedTag((unsigned int)in->readInt());
|
||||
setModifiedCount((unsigned int)in->readInt());
|
||||
|
||||
// Read mipmapdata vector
|
||||
int size = in->readInt();
|
||||
|
||||
@@ -164,13 +164,13 @@ void MpegImageStream::load(const char* fileName)
|
||||
|
||||
|
||||
// Allocate image data
|
||||
// maybe use BGR888 and save some conversion somewhere?
|
||||
unsigned char* data = new unsigned char [s * t * 3];
|
||||
_videoWriteData = new unsigned char [s * t * 3];
|
||||
// maybe use BGRA888 and save some conversion somewhere?
|
||||
unsigned char* data = new unsigned char [s * t * 4];
|
||||
_videoWriteData = new unsigned char [s * t * 4];
|
||||
|
||||
setImage(s, t, 0,
|
||||
setImage(s, t, 1,
|
||||
GL_RGB,
|
||||
GL_RGB, GL_UNSIGNED_BYTE, data,
|
||||
GL_BGRA, GL_UNSIGNED_BYTE, data,
|
||||
osg::Image::USE_NEW_DELETE);
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ void MpegImageStream::swapData()
|
||||
for (int i = 0; i < t(); i++)
|
||||
{
|
||||
_rows[t()-i-1] = dp;
|
||||
dp += (s() * 3);
|
||||
dp += (s() * 4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ void MpegImageStream::run()
|
||||
mpeg3_read_frame(mpg, _rows,
|
||||
0, 0, _s, _t,
|
||||
_s, _t,
|
||||
MPEG3_RGB888, str);
|
||||
MPEG3_RGBA8888, str);
|
||||
|
||||
swapData();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// (C) Robert Osfield, Feb 2004.
|
||||
// GPL'd.
|
||||
|
||||
#include <osg/Image>
|
||||
#include <osg/ImageStream>
|
||||
#include <osg/Notify>
|
||||
#include <osg/Geode>
|
||||
#include <osg/GL>
|
||||
@@ -23,8 +23,9 @@ static void my_render_frame(uint32_t width, uint32_t height, void* data, void* u
|
||||
{
|
||||
osg::Image* imageStream = (osg::Image*) userData;
|
||||
|
||||
GLenum pixelFormat = GL_BGR;
|
||||
|
||||
GLenum pixelFormat = GL_BGRA;
|
||||
|
||||
#if 0
|
||||
if (!ready)
|
||||
{
|
||||
imageStream->allocateImage(width,height,1,pixelFormat,GL_UNSIGNED_BYTE,1);
|
||||
@@ -39,14 +40,14 @@ static void my_render_frame(uint32_t width, uint32_t height, void* data, void* u
|
||||
|
||||
|
||||
imageStream->dirty();
|
||||
/*
|
||||
#else
|
||||
imageStream->setImage(width,height,1,
|
||||
GL_RGB,
|
||||
pixelFormat,GL_UNSIGNED_BYTE,
|
||||
(unsigned char *)data,
|
||||
osg::Image::NO_DELETE,
|
||||
1);
|
||||
*/
|
||||
#endif
|
||||
ready = 1;
|
||||
}
|
||||
|
||||
@@ -99,12 +100,12 @@ class ReaderWriterXine : public osgDB::ReaderWriter
|
||||
osg::notify(osg::NOTICE)<<"ReaderWriterXine::readImage "<< file<< std::endl;
|
||||
|
||||
//XineImageStream* imageStream = new XineImageStream(file.c_str());
|
||||
osg::Image* imageStream = new osg::Image;
|
||||
osg::Image* imageStream = new osg::ImageStream;
|
||||
|
||||
// create visual
|
||||
rgbout_visual_info_t* visual = new rgbout_visual_info_t;
|
||||
visual->levels = PXLEVEL_ALL;
|
||||
visual->format = PX_BGR24;
|
||||
visual->format = PX_RGB32;
|
||||
visual->user_data = imageStream;
|
||||
visual->callback = my_render_frame;
|
||||
|
||||
|
||||
@@ -866,7 +866,7 @@ void Text::accept(osg::Drawable::ConstAttributeFunctor& af) const
|
||||
}
|
||||
}
|
||||
|
||||
void Text::accept(osg::Drawable::PrimitiveFunctor& pf) const
|
||||
void Text::accept(osg::PrimitiveFunctor& pf) const
|
||||
{
|
||||
for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin();
|
||||
titr!=_textureGlyphQuadMap.end();
|
||||
|
||||
Reference in New Issue
Block a user