first commit
This commit is contained in:
151
3rdparty/osgXR/src/XRFramebuffer.cpp
vendored
Normal file
151
3rdparty/osgXR/src/XRFramebuffer.cpp
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-only
|
||||
// Copyright (C) 2021 James Hogan <james@albanarts.com>
|
||||
|
||||
#include "XRFramebuffer.h"
|
||||
|
||||
#include <osg/FrameBufferObject>
|
||||
#include <osg/Image>
|
||||
#include <osg/State>
|
||||
#include <osg/Version>
|
||||
|
||||
using namespace osgXR;
|
||||
|
||||
#if(OSG_VERSION_GREATER_OR_EQUAL(3, 4, 0))
|
||||
typedef osg::GLExtensions OSG_GLExtensions;
|
||||
#else
|
||||
typedef osg::FBOExtensions OSG_GLExtensions;
|
||||
#endif
|
||||
|
||||
static const OSG_GLExtensions* getGLExtensions(const osg::State& state)
|
||||
{
|
||||
#if(OSG_VERSION_GREATER_OR_EQUAL(3, 4, 0))
|
||||
return state.get<osg::GLExtensions>();
|
||||
#else
|
||||
return osg::FBOExtensions::instance(state.getContextID(), true);
|
||||
#endif
|
||||
}
|
||||
|
||||
XRFramebuffer::XRFramebuffer(uint32_t width, uint32_t height,
|
||||
GLuint texture, GLuint depthTexture) :
|
||||
_width(width),
|
||||
_height(height),
|
||||
_depthFormat(GL_DEPTH_COMPONENT16),
|
||||
_fbo(0),
|
||||
_texture(texture),
|
||||
_depthTexture(depthTexture),
|
||||
_generated(false),
|
||||
_boundTexture(false),
|
||||
_boundDepthTexture(false),
|
||||
_deleteDepthTexture(false)
|
||||
{
|
||||
}
|
||||
|
||||
XRFramebuffer::~XRFramebuffer()
|
||||
{
|
||||
}
|
||||
|
||||
bool XRFramebuffer::valid(osg::State &state) const
|
||||
{
|
||||
if (!_fbo)
|
||||
return false;
|
||||
|
||||
const OSG_GLExtensions *fbo_ext = getGLExtensions(state);
|
||||
GLenum complete = fbo_ext->glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
|
||||
switch (complete)
|
||||
{
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
||||
return true;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
|
||||
OSG_WARN << "FBO Incomplete attachment" << std::endl;
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
|
||||
OSG_WARN << "FBO Incomplete missing attachment" << std::endl;
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
|
||||
OSG_WARN << "FBO Incomplete draw buffer" << std::endl;
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
|
||||
OSG_WARN << "FBO Incomplete read buffer" << std::endl;
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||
OSG_WARN << "FBO Incomplete unsupported" << std::endl;
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
|
||||
OSG_WARN << "FBO Incomplete multisample" << std::endl;
|
||||
break;
|
||||
default:
|
||||
OSG_WARN << "FBO Incomplete ??? (0x" << std::hex << complete << std::dec << ")" << std::endl;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void XRFramebuffer::bind(osg::State &state)
|
||||
{
|
||||
const OSG_GLExtensions *fbo_ext = getGLExtensions(state);
|
||||
|
||||
if (!_fbo && !_generated)
|
||||
{
|
||||
fbo_ext->glGenFramebuffers(1, &_fbo);
|
||||
_generated = true;
|
||||
}
|
||||
|
||||
if (_fbo)
|
||||
{
|
||||
fbo_ext->glBindFramebuffer(GL_FRAMEBUFFER_EXT, _fbo);
|
||||
if (!_boundTexture && _texture)
|
||||
{
|
||||
fbo_ext->glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, _texture, 0);
|
||||
_boundTexture = true;
|
||||
}
|
||||
if (!_boundDepthTexture)
|
||||
{
|
||||
if (!_depthTexture)
|
||||
{
|
||||
glGenTextures(1, &_depthTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, _depthTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, _depthFormat, _width, _height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, nullptr);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
_deleteDepthTexture = true;
|
||||
}
|
||||
|
||||
fbo_ext->glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, _depthTexture, 0);
|
||||
_boundDepthTexture = true;
|
||||
|
||||
valid(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XRFramebuffer::unbind(osg::State &state)
|
||||
{
|
||||
const OSG_GLExtensions *fbo_ext = getGLExtensions(state);
|
||||
|
||||
if (_fbo && _generated)
|
||||
fbo_ext->glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
|
||||
void XRFramebuffer::releaseGLObjects(osg::State &state)
|
||||
{
|
||||
// FIXME can we do it like RenderBuffer::releaseGLObjects?
|
||||
// FIXME better yet, switch to use FrameBufferObject, dynamically bound
|
||||
|
||||
// GL context must be current
|
||||
if (_fbo)
|
||||
{
|
||||
/*
|
||||
unsigned int contextID = state->getContextID();
|
||||
osg::get<GLFrameBufferObjectManager>(contextID)->scheduleGLObjectForDeletion(_fbo);
|
||||
*/
|
||||
const OSG_GLExtensions *fbo_ext = getGLExtensions(state);
|
||||
fbo_ext->glDeleteFramebuffers(1, &_fbo);
|
||||
_fbo = 0;
|
||||
}
|
||||
if (_deleteDepthTexture)
|
||||
{
|
||||
glDeleteTextures(1, &_depthTexture);
|
||||
_depthTexture = 0;
|
||||
_deleteDepthTexture = false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user