156 lines
3.8 KiB
C++
156 lines
3.8 KiB
C++
#include "externals.hh"
|
|
#include "rendertarget.hh"
|
|
|
|
|
|
T_RendertargetSetup::T_RendertargetSetup( )
|
|
: hasAttachments_( false )
|
|
{ }
|
|
|
|
T_RendertargetSetup& T_RendertargetSetup::add(
|
|
__rw__ T_Texture& texture ,
|
|
__rd__ const uint32_t level )
|
|
{
|
|
checkAttachment( texture , level );
|
|
colorAttachments_.add( T_Attachment_{ texture , level } );
|
|
return *this;
|
|
}
|
|
|
|
|
|
T_RendertargetSetup& T_RendertargetSetup::depth(
|
|
__rw__ T_Texture& texture )
|
|
{
|
|
assert( !depthAttachment_.present( ) );
|
|
checkAttachment( texture , 0 );
|
|
depthAttachment_.setNew( texture , 0 );
|
|
return *this;
|
|
}
|
|
|
|
|
|
void T_RendertargetSetup::checkAttachment(
|
|
__rw__ T_Texture const& texture ,
|
|
__rd__ const uint32_t level )
|
|
{
|
|
const uint32_t tw( texture.width( ) >> level ) ,
|
|
th( texture.height( ) >> level );
|
|
if ( hasAttachments_ ) {
|
|
assert( tw == width_ );
|
|
assert( th == height_ );
|
|
} else {
|
|
width_ = tw;
|
|
height_ = th;
|
|
hasAttachments_ = true;
|
|
}
|
|
}
|
|
|
|
|
|
T_Rendertarget T_RendertargetSetup::create( )
|
|
{
|
|
const auto nca( colorAttachments_.size( ) );
|
|
assert( hasAttachments_ );
|
|
assert( nca != 0 );
|
|
|
|
// Generate / setup the GL framebuffer
|
|
GLuint id( 0 );
|
|
glGenFramebuffers( 1 , &id );
|
|
glBindFramebuffer( GL_FRAMEBUFFER , id );
|
|
for ( auto i = 0u ; i < nca ; i ++ ) {
|
|
#ifdef INTRUSIVE_TRACES
|
|
printf( "init %p fb %d att %d tx %p level %d\n" ,
|
|
this , id , i ,
|
|
colorAttachments_[ i ].texture ,
|
|
colorAttachments_[ i ].level );
|
|
#endif
|
|
glFramebufferTexture( GL_FRAMEBUFFER ,
|
|
GL_COLOR_ATTACHMENT0 + i ,
|
|
colorAttachments_[ i ].texture->id( ) ,
|
|
colorAttachments_[ i ].level );
|
|
}
|
|
if ( depthAttachment_.present( ) ) {
|
|
T_Attachment_ const& de( depthAttachment_ );
|
|
glFramebufferTexture( GL_FRAMEBUFFER ,
|
|
GL_DEPTH_ATTACHMENT ,
|
|
de.texture->id( ) ,
|
|
de.level );
|
|
}
|
|
assert( glCheckFramebufferStatus( GL_FRAMEBUFFER ) == GL_FRAMEBUFFER_COMPLETE );
|
|
glBindFramebuffer( GL_FRAMEBUFFER , 0 );
|
|
|
|
assert( glGetError( ) == GL_NO_ERROR );
|
|
|
|
// Reset config
|
|
hasAttachments_ = false;
|
|
colorAttachments_.clear( );
|
|
depthAttachment_.clear( );
|
|
|
|
return T_Rendertarget( id , nca , width_ , height_ );
|
|
}
|
|
|
|
/*============================================================================*/
|
|
|
|
T_Rendertarget::T_Rendertarget(
|
|
__rd__ const uint32_t id ,
|
|
__rd__ const uint32_t nCats ,
|
|
__rd__ const uint32_t width ,
|
|
__rd__ const uint32_t height )
|
|
: id_( id ) , nCats_( nCats ) , width_( width ) , height_( height )
|
|
{ }
|
|
|
|
T_Rendertarget::T_Rendertarget(
|
|
__rw__ T_Rendertarget&& other ) noexcept
|
|
: id_( 0 ) , nCats_( other.nCats_ ) , width_( other.width_ ) ,
|
|
height_( other.height_ )
|
|
{
|
|
swap( id_ , other.id_ );
|
|
}
|
|
|
|
T_Rendertarget& T_Rendertarget::operator =(
|
|
__rw__ T_Rendertarget&& other ) noexcept
|
|
{
|
|
swap( id_ , other.id_ );
|
|
swap( nCats_ , other.nCats_ );
|
|
swap( width_ , other.width_ );
|
|
swap( height_ , other.height_ );
|
|
return *this;
|
|
}
|
|
|
|
T_Rendertarget::~T_Rendertarget( )
|
|
{
|
|
if ( id_ != 0 ) {
|
|
glDeleteFramebuffers( 1 , &id_ );
|
|
}
|
|
}
|
|
|
|
bool T_Rendertarget::activate( )
|
|
{
|
|
if ( id_ != 0 ) {
|
|
#ifdef INTRUSIVE_TRACES
|
|
printf( "ACTIVATING FB %d (%dx%d, %d c.a.)\n" ,
|
|
id_ , width_ , height_ , nCats_ );
|
|
#endif
|
|
if ( nCats_ != buffers_.size( ) ) {
|
|
buffers_.clear( );
|
|
for ( auto i = 0u ; i < nCats_ ; i ++ ) {
|
|
buffers_.add( GL_COLOR_ATTACHMENT0 + i );
|
|
}
|
|
#ifdef INTRUSIVE_TRACES
|
|
printf( "fb %d: created buffers (%d items)\n" , id_ ,
|
|
int( buffers_.size( ) ) );
|
|
#endif
|
|
}
|
|
glBindFramebuffer( GL_FRAMEBUFFER , id_ );
|
|
glViewport( 0 , 0 , width_ , height_ );
|
|
glDrawBuffers( nCats_ , &buffers_[ 0 ] );
|
|
|
|
assert( glCheckFramebufferStatus( GL_FRAMEBUFFER )
|
|
== GL_FRAMEBUFFER_COMPLETE );
|
|
assert( glGetError( ) == GL_NO_ERROR );
|
|
}
|
|
return id_ != 0;
|
|
}
|
|
|
|
void T_Rendertarget::MainOutput( )
|
|
{
|
|
auto const& dspSize( ImGui::GetIO( ).DisplaySize );
|
|
glBindFramebuffer( GL_FRAMEBUFFER , 0 );
|
|
glViewport( 0 , 0 , (int) dspSize.x, (int) dspSize.y );
|
|
}
|