2024-02-21 22:19:01 +00:00
# include "Framebuffer.hpp"
# include "../helpers/Log.hpp"
# include <libdrm/drm_fourcc.h>
static uint32_t drmFormatToGL ( uint32_t drm ) {
switch ( drm ) {
case DRM_FORMAT_XRGB8888 :
case DRM_FORMAT_XBGR8888 : return GL_RGBA ; // doesn't matter, opengl is gucci in this case.
case DRM_FORMAT_XRGB2101010 :
case DRM_FORMAT_XBGR2101010 : return GL_RGB10_A2 ;
default : return GL_RGBA ;
}
return GL_RGBA ;
}
static uint32_t glFormatToType ( uint32_t gl ) {
return gl ! = GL_RGBA ? GL_UNSIGNED_INT_2_10_10_10_REV : GL_UNSIGNED_BYTE ;
}
2024-03-05 20:24:11 +00:00
bool CFramebuffer : : alloc ( int w , int h , bool highres ) {
2024-02-21 22:19:01 +00:00
bool firstAlloc = false ;
2024-03-05 20:24:11 +00:00
uint32_t glFormat = highres ? GL_RGBA16F : drmFormatToGL ( DRM_FORMAT_XRGB2101010 ) ; // TODO: revise only 10b when I find a way to figure out without sc whether display is 10b
uint32_t glType = highres ? GL_FLOAT : glFormatToType ( glFormat ) ;
2024-02-21 22:19:01 +00:00
if ( m_iFb = = ( uint32_t ) - 1 ) {
firstAlloc = true ;
glGenFramebuffers ( 1 , & m_iFb ) ;
}
if ( m_cTex . m_iTexID = = 0 ) {
firstAlloc = true ;
glGenTextures ( 1 , & m_cTex . m_iTexID ) ;
glBindTexture ( GL_TEXTURE_2D , m_cTex . m_iTexID ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
2024-02-22 00:31:33 +00:00
m_cTex . m_vSize = { w , h } ;
2024-02-21 22:19:01 +00:00
}
if ( firstAlloc | | m_vSize ! = Vector2D ( w , h ) ) {
glBindTexture ( GL_TEXTURE_2D , m_cTex . m_iTexID ) ;
2024-07-09 05:32:49 -04:00
glTexImage2D ( GL_TEXTURE_2D , 0 , glFormat , w , h , 0 , GL_RGBA , glType , nullptr ) ;
2024-02-21 22:19:01 +00:00
glBindFramebuffer ( GL_FRAMEBUFFER , m_iFb ) ;
glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 , GL_TEXTURE_2D , m_cTex . m_iTexID , 0 ) ;
if ( m_pStencilTex ) {
glBindTexture ( GL_TEXTURE_2D , m_pStencilTex - > m_iTexID ) ;
2024-07-09 05:32:49 -04:00
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_DEPTH24_STENCIL8 , w , h , 0 , GL_DEPTH_STENCIL , GL_UNSIGNED_INT_24_8 , nullptr ) ;
2024-02-21 22:19:01 +00:00
glBindFramebuffer ( GL_FRAMEBUFFER , m_iFb ) ;
glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_STENCIL_ATTACHMENT , GL_TEXTURE_2D , m_pStencilTex - > m_iTexID , 0 ) ;
}
auto status = glCheckFramebufferStatus ( GL_FRAMEBUFFER ) ;
if ( status ! = GL_FRAMEBUFFER_COMPLETE ) {
Debug : : log ( ERR , " Framebuffer incomplete, couldn't create! (FB status: {}) " , status ) ;
abort ( ) ;
}
2024-10-17 15:23:58 +01:00
Debug : : log ( TRACE , " Framebuffer created, status {} " , status ) ;
2024-02-21 22:19:01 +00:00
}
glBindTexture ( GL_TEXTURE_2D , 0 ) ;
glBindFramebuffer ( GL_FRAMEBUFFER , 0 ) ;
m_vSize = Vector2D ( w , h ) ;
return true ;
}
void CFramebuffer : : addStencil ( ) {
2024-07-09 05:32:49 -04:00
if ( ! m_pStencilTex ) {
Debug : : log ( ERR , " No stencil texture allocated. " ) ;
return ;
}
2024-02-21 22:19:01 +00:00
glBindTexture ( GL_TEXTURE_2D , m_pStencilTex - > m_iTexID ) ;
2024-07-09 05:32:49 -04:00
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_DEPTH24_STENCIL8 , m_vSize . x , m_vSize . y , 0 , GL_DEPTH_STENCIL , GL_UNSIGNED_INT_24_8 , nullptr ) ;
2024-02-21 22:19:01 +00:00
glBindFramebuffer ( GL_FRAMEBUFFER , m_iFb ) ;
glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_STENCIL_ATTACHMENT , GL_TEXTURE_2D , m_pStencilTex - > m_iTexID , 0 ) ;
auto status = glCheckFramebufferStatus ( GL_FRAMEBUFFER ) ;
2024-07-09 05:32:49 -04:00
RASSERT ( ( status = = GL_FRAMEBUFFER_COMPLETE ) , " Failed adding a stencil to fbo! (FB status: {}) " , status ) ;
2024-02-21 22:19:01 +00:00
glBindTexture ( GL_TEXTURE_2D , 0 ) ;
glBindFramebuffer ( GL_FRAMEBUFFER , 0 ) ;
}
void CFramebuffer : : bind ( ) const {
glBindFramebuffer ( GL_DRAW_FRAMEBUFFER , m_iFb ) ;
glViewport ( 0 , 0 , m_vSize . x , m_vSize . y ) ;
}
void CFramebuffer : : release ( ) {
if ( m_iFb ! = ( uint32_t ) - 1 & & m_iFb )
glDeleteFramebuffers ( 1 , & m_iFb ) ;
if ( m_cTex . m_iTexID )
glDeleteTextures ( 1 , & m_cTex . m_iTexID ) ;
2024-07-09 05:32:49 -04:00
if ( m_pStencilTex & & m_pStencilTex - > m_iTexID )
glDeleteTextures ( 1 , & m_pStencilTex - > m_iTexID ) ;
2024-02-21 22:19:01 +00:00
m_cTex . m_iTexID = 0 ;
m_iFb = - 1 ;
m_vSize = Vector2D ( ) ;
2024-07-09 05:32:49 -04:00
m_pStencilTex = nullptr ;
2024-02-21 22:19:01 +00:00
}
CFramebuffer : : ~ CFramebuffer ( ) {
release ( ) ;
}
2025-05-05 17:11:24 +02:00
bool CFramebuffer : : isAllocated ( ) const {
2024-02-21 22:19:01 +00:00
return m_iFb ! = ( GLuint ) - 1 ;
2025-05-05 17:11:24 +02:00
}