Hi Juan,
Sounds great. Your forum settings are not configured to accept
private messages. I'm interested in your work, if you're willing to
share some code with me drop me an email at fclXYZ.gvs<at> gmail.com
(replace 'XYZ' with 'aux')
I prefer sending them to everybody so they can be improved and maybe
include in trunk in the future.
Regards,
Juan
/* * -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
* Copyright (C) Juan Hernando Vieites 2011
* 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 <iostream>
#define GL_GLEXT_PROTOTYPES
#include <GL/glu.h>
#include "TextureBuffer.h"
namespace bbp
{
namespace RTNeuron
{
//static void checkGLErrors(const std::string &message)
//{
// GLenum error = glGetError();
// if (error != GL_NO_ERROR)
// std::cout << "OpenGL error detected: " << gluErrorString(error)
// << ", " << message << std::endl;
//}
/*
Helper classes
*/
void TextureBuffer::TextureBufferObject::bindBuffer(unsigned int contextID)
{
osg::BufferObject::Extensions* extensions =
osg::BufferObject::getExtensions(contextID, true);
if (_id == 0) {
extensions->glGenBuffers(1, &_id);
}
extensions->glBindBuffer(GL_TEXTURE_BUFFER_EXT, _id);
}
void TextureBuffer::TextureBufferObject::bindTextureBuffer
(osg::State &state, GLenum internalFormat)
{
glTexBufferEXT(GL_TEXTURE_BUFFER_EXT, internalFormat, _id);
}
/*
Member functions
*/
void TextureBuffer::apply(osg::State& state) const
{
const unsigned int contextID = state.getContextID();
TextureObject* to = getTextureObject(contextID);
TextureBufferObject *tbo = _textureBufferObjectsBuffer[contextID].get();
if (to != 0) {
if (_image.valid() &&
_modifiedCount[contextID] != _image->getModifiedCount()) {
/* Update the texture buffer */
tbo->bindBuffer(contextID);
glBufferSubData(GL_TEXTURE_BUFFER_EXT, 0,
_bufferSize, _image->data());
glBindBuffer(GL_TEXTURE_BUFFER_EXT, 0);
/* Update the modified tag to show that it is up to date. */
_modifiedCount[contextID] = _image->getModifiedCount();
} else if (_readPBuffer.valid()) {
std::cerr << "Unsupported operation" << std::endl;
}
/* Binding the texture and its texture buffer object as texture
storage. */
to->bind();
tbo->bindTextureBuffer(state, _internalFormat);
} else if (_image.valid() && _image->data()) {
/* Temporary copy */
osg::ref_ptr<osg::Image> image = _image;
/* Creating the texture object */
_textureObjectBuffer[contextID] = to =
generateTextureObject(contextID, GL_TEXTURE_BUFFER_EXT);
/* Creating the texture buffer object */
tbo = new TextureBufferObject();
_textureBufferObjectsBuffer[contextID] = tbo;
/* Compute the internal texture format,
this set the _internalFormat to an appropriate value. */
computeInternalFormat();
/* Computing the dimensions of the texture buffer */
_textureWidth = image->s();
_bufferSize = image->getImageSizeInBytes();
/* Binding TBO and copying data */
tbo->bindBuffer(contextID);
glBufferData(GL_TEXTURE_BUFFER_EXT, _bufferSize, _image->data(),
tbo->_usageHint);
to->setAllocated(true);
glBindBuffer(GL_TEXTURE_BUFFER_EXT, 0);
to->bind();
tbo->bindTextureBuffer(state, _internalFormat);
/* Update the modified tag to show that it is upto date. */
_modifiedCount[contextID] = image->getModifiedCount();
/* To consider */
//if (_unrefImageDataAfterApply && areAllTextureObjectsLoaded() &&
// image->getDataVariance() == STATIC)
//{
// Texture2D* non_const_this = const_cast<Texture2D*>(this);
// non_const_this->_image = 0;
//}
} else {
/* This texture type is input only (as far as I'm concerned), so
it doesn't work without an attached image. */
glBindBuffer(GL_TEXTURE_BUFFER_EXT, 0);
glBindTexture(GL_TEXTURE_BUFFER_EXT, 0);
}
}
void TextureBuffer::computeInternalFormat() const
{
if (_internalFormatMode != USE_USER_DEFINED_FORMAT) {
if (_internalFormatMode == USE_IMAGE_DATA_FORMAT) {
if (_image.valid())
_internalFormat = _image->getInternalTextureFormat();
} else {
std::cerr << "Unsupported internal format" << std::endl;
}
}
computeInternalFormatType();
}
}
}
/* * -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
* Copyright (C) Juan Hernando Vieites 2011
* 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 RTNEURON_TEXTUREBUFFER_H
#define RTNEURON_TEXTUREBUFFER_H
#define GL_GLEXT_PROTOTYPES
#include <osg/GL>
#include <stdlib.h>
#include <osg/BufferObject>
#include <osg/Texture>
#include <osg/Image>
namespace bbp
{
namespace RTNeuron
{
class TextureBuffer : public osg::Texture
{
/* Constructors */
public:
TextureBuffer() :
_textureWidth(0)
{}
/** Copy constructor using CopyOp to manage deep vs shallow copy. */
TextureBuffer(const TextureBuffer& other,
const osg::CopyOp& copyOp = osg::CopyOp::SHALLOW_COPY) :
osg::Texture(other),
_image(copyOp(other._image.get()))
{
abort();
}
/* Destructor */
protected:
/**
\todo Clean up of OpenGL object names used.
*/
virtual ~TextureBuffer() {};
/* Memer functions */
public:
META_StateAttribute(osg, TextureBuffer, TEXTURE);
int compare(const StateAttribute& sa) const
{
return -1;
}
virtual bool getModeUsage(StateAttribute::ModeUsage& usage) const
{
return false;
}
virtual GLenum getTextureTarget() const
{
return GL_TEXTURE_BUFFER_EXT;
}
/** Set the image */
void setImage(osg::Image *image)
{
_image = image;
_modifiedCount.setAllElementsTo(0);
}
/** Gets the texture image */
virtual osg::Image* getImage()
{
return _image.get();
}
/** Gets the const texture image */
virtual const osg::Image* getImage() const
{
return _image.get();
}
/** Sets the texture image, ignoring face. */
virtual void setImage(unsigned int, osg::Image* image)
{
setImage(image);
}
/** Gets the texture image, ignoring face. */
virtual osg::Image* getImage(unsigned int)
{
return _image.get();
}
/** Gets the const texture image, ignoring face. */
virtual const osg::Image* getImage(unsigned int) const
{
return _image.get();
}
/** Gets the number of images that can be assigned to the Texture. */
virtual unsigned int getNumImages() const { return 1; }
virtual int getTextureWidth() const
{
return _textureWidth;
}
virtual int getTextureHeight() const { return 1; }
virtual int getTextureDepth() const { return 1; }
/** Texture is a pure virtual base class, apply must be overridden. */
virtual void apply(osg::State& state) const;
protected:
virtual void computeInternalFormat() const;
virtual void allocateMipmap(osg::State& state) const {}
/* Member attributes */
protected:
class TextureBufferObject : public osg::Referenced
{
public:
TextureBufferObject() :
_id(0),
_usageHint(GL_DYNAMIC_DRAW)
{}
void bindBuffer(unsigned int contextID);
void bindTextureBuffer(osg::State &state, GLenum internalFormat);
public:
GLuint _id;
GLenum _usageHint;
};
osg::ref_ptr<osg::Image> _image;
typedef osg::buffered_object<osg::ref_ptr<TextureBufferObject> > TBOList;
mutable TBOList _textureBufferObjectsBuffer;
typedef osg::buffered_value<unsigned int> ImageModifiedCount;
mutable ImageModifiedCount _modifiedCount;
mutable GLsizei _textureWidth;
mutable GLsizei _bufferSize;
};
}
}
#endif
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org