Further work on trying to get glGenerateMipMapEXT working in conjunction with

frame buffer objects.  Still don't work under Linux yet through :-|
This commit is contained in:
Robert Osfield 2005-07-27 11:27:44 +00:00
parent 72a59527f5
commit 4e69d46289
9 changed files with 77 additions and 69 deletions

View File

@ -263,6 +263,7 @@ namespace osg
FrameBufferAttachment &operator = (const FrameBufferAttachment &copy);
void createRequiredTexturesAndApplyGenerateMipMap(State &state, const FBOExtensions* ext) const;
void attach(State &state, GLenum attachment_point, const FBOExtensions* ext) const;
int compare(const FrameBufferAttachment &fa) const;

View File

@ -207,6 +207,15 @@ class OSG_EXPORT Texture : public osg::StateAttribute
virtual bool isTextureAttribute() const { return true; }
virtual GLenum getTextureTarget() const = 0;
virtual bool getModeUsage(ModeUsage& usage) const
{
usage.usesTextureMode(getTextureTarget());
return true;
}
enum WrapParameter {
WRAP_S,
WRAP_T,

View File

@ -38,11 +38,7 @@ class OSG_EXPORT Texture1D : public Texture
/** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
virtual int compare(const StateAttribute& rhs) const;
virtual bool getModeUsage(ModeUsage& usage) const
{
usage.usesTextureMode(GL_TEXTURE_1D);
return true;
}
virtual GLenum getTextureTarget() const { return GL_TEXTURE_1D; }
/** Sets the texture image. */
void setImage(Image* image);

View File

@ -38,11 +38,7 @@ class OSG_EXPORT Texture2D : public Texture
/** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
virtual int compare(const StateAttribute& rhs) const;
virtual bool getModeUsage(ModeUsage& usage) const
{
usage.usesTextureMode(GL_TEXTURE_2D);
return true;
}
virtual GLenum getTextureTarget() const { return GL_TEXTURE_2D; }
/** Sets the texture image. */
void setImage(Image* image);

View File

@ -36,11 +36,7 @@ class OSG_EXPORT Texture3D : public Texture
/** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
virtual int compare(const StateAttribute& rhs) const;
virtual bool getModeUsage(ModeUsage& usage) const
{
usage.usesTextureMode(GL_TEXTURE_3D);
return true;
}
virtual GLenum getTextureTarget() const { return GL_TEXTURE_3D; }
/** Sets the texture image. */
void setImage(Image* image);

View File

@ -47,11 +47,7 @@ class OSG_EXPORT TextureCubeMap : public Texture
/** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
virtual int compare(const StateAttribute& rhs) const;
virtual bool getModeUsage(ModeUsage& usage) const
{
usage.usesTextureMode(GL_TEXTURE_CUBE_MAP);
return true;
}
virtual GLenum getTextureTarget() const { return GL_TEXTURE_CUBE_MAP; }
enum Face {
POSITIVE_X=0,

View File

@ -44,11 +44,7 @@ class OSG_EXPORT TextureRectangle : public Texture
/** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
virtual int compare(const StateAttribute& rhs) const;
virtual bool getModeUsage(ModeUsage& usage) const
{
usage.usesTextureMode(GL_TEXTURE_RECTANGLE);
return true;
}
virtual GLenum getTextureTarget() const { return GL_TEXTURE_RECTANGLE; }
/** Set the texture image. */
void setImage(Image* image);

View File

@ -272,7 +272,7 @@ FrameBufferAttachment &FrameBufferAttachment::operator = (const FrameBufferAttac
return *this;
}
void FrameBufferAttachment::attach(State &state, GLenum attachment_point, const FBOExtensions* ext) const
void FrameBufferAttachment::createRequiredTexturesAndApplyGenerateMipMap(State &state, const FBOExtensions* ext) const
{
unsigned int contextID = state.getContextID();
@ -285,6 +285,36 @@ void FrameBufferAttachment::attach(State &state, GLenum attachment_point, const
{
_ximpl->textureTarget->compileGLObjects(state);
tobj = _ximpl->textureTarget->getTextureObject(contextID);
}
if (!tobj || tobj->_id == 0)
return;
Texture::FilterMode minFilter = _ximpl->textureTarget->getFilter(Texture::MIN_FILTER);
if (minFilter==Texture::LINEAR_MIPMAP_LINEAR ||
minFilter==Texture::LINEAR_MIPMAP_NEAREST ||
minFilter==Texture::NEAREST_MIPMAP_LINEAR ||
minFilter==Texture::NEAREST_MIPMAP_NEAREST)
{
ext->glGenerateMipmapEXT(_ximpl->textureTarget->getTextureTarget());
}
}
}
void FrameBufferAttachment::attach(State &state, GLenum attachment_point, const FBOExtensions* ext) const
{
unsigned int contextID = state.getContextID();
Texture::TextureObject *tobj = 0;
if (_ximpl->textureTarget.valid())
{
tobj = _ximpl->textureTarget->getTextureObject(contextID);
if (!tobj || tobj->_id == 0)
{
_ximpl->textureTarget->compileGLObjects(state);
tobj = _ximpl->textureTarget->getTextureObject(contextID);
}
if (!tobj || tobj->_id == 0)
return;
@ -379,7 +409,20 @@ void FrameBufferObject::apply(State &state) const
notify(WARN) << "Warning: FrameBufferObject: could not create the FBO" << std::endl;
return;
}
dirtyAttachmentList = 1;
}
if (dirtyAttachmentList)
{
// create textures and mipmaps before we bind the frame buffer object
for (AttachmentMap::const_iterator i=_attachments.begin(); i!=_attachments.end(); ++i)
{
const FrameBufferAttachment &fa = i->second;
fa.createRequiredTexturesAndApplyGenerateMipMap(state, ext);
}
}
ext->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);

View File

@ -16,6 +16,7 @@
#include <osg/Texture3D>
#include <osg/TextureRectangle>
#include <osg/TextureCubeMap>
#include <osg/Notify>
using namespace osg;
using namespace osgUtil;
@ -43,35 +44,12 @@ void RenderToTextureStage::reset()
RenderStage::reset();
}
class GenerateMipMapHelper : public StateAttribute::ModeUsage
{
public:
GenerateMipMapHelper(osg::FBOExtensions* fbo_ext):
_fbo_ext(fbo_ext) {}
virtual ~GenerateMipMapHelper() {}
virtual void usesMode(StateAttribute::GLMode)
{
}
virtual void usesTextureMode(StateAttribute::GLMode mode)
{
_fbo_ext->glGenerateMipmapEXT((GLenum)mode);
}
osg::FBOExtensions* _fbo_ext;
};
void RenderToTextureStage::draw(osg::State& state,RenderLeaf*& previous)
{
if (_stageDrawnThisFrame) return;
state.checkGLErrors("beginning of RenderToTextureStage::draw()");
//cout << "begining RTTS draw "<<this<< " "<<_viewport->x()<<","<< _viewport->y()<<","<< _viewport->width()<<","<< _viewport->height()<<std::endl;
osg::State* useState = &state;
@ -148,22 +126,6 @@ void RenderToTextureStage::draw(osg::State& state,RenderLeaf*& previous)
_image->readPixels(_viewport->x(),_viewport->y(),_viewport->width(),_viewport->height(),_imageReadPixelFormat,_imageReadPixelDataType);
}
if (fbo_supported && _camera)
{
// now generate mipmaps if they are required.
const osg::CameraNode::BufferAttachmentMap& bufferAttachements = _camera->getBufferAttachmentMap();
for(osg::CameraNode::BufferAttachmentMap::const_iterator itr = bufferAttachements.begin();
itr != bufferAttachements.end();
++itr)
{
if (itr->second._texture.valid() && itr->second._mipMapGeneration)
{
itr->second._texture->apply(*useState);
GenerateMipMapHelper generateMipMap(fbo_ext);
itr->second._texture->getModeUsage(generateMipMap);
}
}
}
if (_camera && _camera->getPostDrawCallback())
{
@ -177,6 +139,22 @@ void RenderToTextureStage::draw(osg::State& state,RenderLeaf*& previous)
fbo_ext->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
if (fbo_supported && _camera)
{
// now generate mipmaps if they are required.
const osg::CameraNode::BufferAttachmentMap& bufferAttachements = _camera->getBufferAttachmentMap();
for(osg::CameraNode::BufferAttachmentMap::const_iterator itr = bufferAttachements.begin();
itr != bufferAttachements.end();
++itr)
{
if (itr->second._texture.valid() && itr->second._mipMapGeneration)
{
itr->second._texture->apply(*useState);
// fbo_ext->glGenerateMipmapEXT(itr->second._texture->getTextureTarget());
}
}
}
if (callingContext && useContext != callingContext)
{
// restore the graphics context.
@ -184,8 +162,5 @@ void RenderToTextureStage::draw(osg::State& state,RenderLeaf*& previous)
glReadBuffer(GL_BACK);
}
state.checkGLErrors("end of RenderToTextureStage::draw()");
}