Emmanuel BENOîT
3de255aad0
The program is loaded and its init part is run. Many bugs were fixed in the process, including various new bugs in the shaders manager.
194 lines
4.5 KiB
C++
194 lines
4.5 KiB
C++
#include "externals.hh"
|
|
#include "rendertarget.hh"
|
|
|
|
|
|
T_RendertargetSetup::T_RendertargetSetup( )
|
|
: hasAttachments_( false )
|
|
{ }
|
|
|
|
T_RendertargetSetup& T_RendertargetSetup::add(
|
|
T_Texture& texture ,
|
|
const uint32_t level )
|
|
{
|
|
checkAttachment( texture , level );
|
|
colorAttachments_.add( T_Attachment_{ texture , level } );
|
|
return *this;
|
|
}
|
|
|
|
|
|
T_RendertargetSetup& T_RendertargetSetup::depth(
|
|
T_Texture& texture )
|
|
{
|
|
assert( !depthAttachment_ );
|
|
checkAttachment( texture , 0 );
|
|
depthAttachment_.setNew( texture , 0 );
|
|
return *this;
|
|
}
|
|
|
|
|
|
void T_RendertargetSetup::checkAttachment(
|
|
T_Texture const& texture ,
|
|
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_ ) {
|
|
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( )
|
|
{
|
|
glGenFramebuffers( 1 , &id_ );
|
|
nCats_ = width_ = height_ = 0;
|
|
}
|
|
|
|
void T_Rendertarget::attach(
|
|
T_Texture const& texture ,
|
|
const uint32_t lod ,
|
|
const uint32_t id )
|
|
{
|
|
const uint32_t attId( id ? ( GL_COLOR_ATTACHMENT0 + id - 1 ) : GL_DEPTH_ATTACHMENT );
|
|
glFramebufferTexture( GL_FRAMEBUFFER ,
|
|
attId ,
|
|
texture.id( ) ,
|
|
lod );
|
|
if ( width_ == 0 ) {
|
|
width_ = texture.width( ) >> lod;
|
|
height_ = texture.width( ) >> lod;
|
|
}
|
|
}
|
|
|
|
T_Rendertarget::T_Rendertarget(
|
|
const uint32_t id ,
|
|
const uint32_t nCats ,
|
|
const uint32_t width ,
|
|
const uint32_t height )
|
|
: id_( id ) , nCats_( nCats ) , width_( width ) , height_( height )
|
|
{ }
|
|
|
|
T_Rendertarget::T_Rendertarget(
|
|
T_Rendertarget&& other ) noexcept
|
|
: id_( 0 ) , nCats_( other.nCats_ ) , width_( other.width_ ) ,
|
|
height_( other.height_ )
|
|
{
|
|
swap( id_ , other.id_ );
|
|
}
|
|
|
|
T_Rendertarget& T_Rendertarget::operator =(
|
|
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::toggle(
|
|
const uint32_t id ,
|
|
const bool active )
|
|
{
|
|
const auto realId( GL_COLOR_ATTACHMENT0 + id );
|
|
const int32_t idx( buffers_.indexOf( realId ) );
|
|
if ( active && idx < 0 ) {
|
|
buffers_.add( realId );
|
|
} else if ( !active && idx >= 0 ) {
|
|
buffers_.removeSwap( idx );
|
|
} else {
|
|
return;
|
|
}
|
|
glDrawBuffers( buffers_.size( ) , &buffers_[ 0 ] );
|
|
}
|
|
|
|
void T_Rendertarget::MainOutput( )
|
|
{
|
|
auto const& dspSize( ImGui::GetIO( ).DisplaySize );
|
|
glBindFramebuffer( GL_FRAMEBUFFER , 0 );
|
|
glViewport( 0 , 0 , (int) dspSize.x, (int) dspSize.y );
|
|
}
|