Ignore:
Timestamp:
09/09/14 20:08:33 (11 years ago)
Author:
epyon
Message:
  • texture types (1D,2D,Rect,3D,Cube - not all fully supported yet)
  • full framebuffer support
  • fixes to texture support
  • minor fixes
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gl/gl_context.cc

    r326 r331  
    2424nv::framebuffer nv::gl_context::create_framebuffer()
    2525{
    26         if ( is_gl_extension_loaded( GL_EXT_FRAMEBUFFER_OBJECT ) )
     26        if ( is_gl_extension_loaded( GL_EXT_FRAMEBUFFER_OBJECT ) && is_gl_extension_loaded( GL_EXT_FRAMEBUFFER_BLIT ) )
    2727        {
    2828                unsigned glid   = 0;
     
    3131                gl_framebuffer_info* info = m_framebuffers.get( result );
    3232                info->glid = glid;
     33                info->depth_rb_glid = 0;
    3334                info->color_attachment_count = 0;
    3435                return result;
     
    5758        {
    5859                // TODO: release textures?
    59                 glBindFramebuffer(GL_FRAMEBUFFER, 0);
    60                 glDeleteFramebuffers(1, &info->glid);
     60                glBindFramebuffer( GL_FRAMEBUFFER, 0 );
     61                glBindRenderbuffer( GL_RENDERBUFFER, 0 );
     62                if ( info->depth_rb_glid == 0 )
     63                        glDeleteRenderbuffers( 1, &info->depth_rb_glid );
     64                glDeleteFramebuffers( 1, &info->glid );
    6165        }
    6266}
     
    7781}
    7882
     83void nv::gl_context::attach( framebuffer f, output_slot slot, texture t )
     84{
     85        // TODO: framebuffer variable, so no re-binding?
     86        // TODO: support 1d, 3d textures, cubemaps or layers?
     87        // TODO: support GL_READ_FRAMEBUFFER?
     88        const gl_framebuffer_info* info  = m_framebuffers.get( f );
     89        const gl_texture_info*     tinfo = (gl_texture_info*)m_device->get_texture_info( t );
     90        if ( info )
     91        {
     92                glBindFramebuffer( GL_FRAMEBUFFER, info->glid );
     93                unsigned gl_type = texture_type_to_enum( tinfo->type );
     94
     95                if ( tinfo )
     96                {
     97                        //              if ( tinfo->size.y == 0 )
     98                                //                      glFramebufferTexture1D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+(unsigned)slot, GL_TEXTURE_1D, tinfo->glid, 0 );
     99                        glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+(unsigned)slot, gl_type, tinfo->glid, 0 );
     100                }
     101                else
     102                {
     103                        glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+(unsigned)slot, gl_type, 0, 0 );
     104                }
     105
     106        }
     107}
     108
     109void nv::gl_context::attach( framebuffer f, texture depth )
     110{
     111        // TODO: framebuffer variable, so no re-binding?
     112        // TODO: support GL_READ_FRAMEBUFFER?
     113        const gl_framebuffer_info* info  = m_framebuffers.get( f );
     114        const gl_texture_info*     tinfo = (gl_texture_info*)m_device->get_texture_info( depth );
     115        if ( info )
     116        {
     117                glBindFramebuffer( GL_FRAMEBUFFER, info->glid );
     118                unsigned gl_type = texture_type_to_enum( tinfo->type );
     119
     120                if ( tinfo )
     121                {
     122                        glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, gl_type, tinfo->glid, 0 );
     123                }
     124                else
     125                {
     126                        glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, gl_type, 0, 0 );
     127                }
     128        }
     129}
     130
     131void nv::gl_context::attach( framebuffer f, ivec2 size )
     132{
     133        // TODO: framebuffer variable, so no re-binding?
     134        // TODO: support GL_READ_FRAMEBUFFER?
     135        gl_framebuffer_info* info  = m_framebuffers.get( f );
     136        if ( info )
     137        {
     138                glBindFramebuffer( GL_FRAMEBUFFER, info->glid );
     139                if ( info->depth_rb_glid ) glDeleteRenderbuffers( 1, &(info->depth_rb_glid) );
     140                glGenRenderbuffers( 1, &(info->depth_rb_glid) );
     141                glBindRenderbuffer( GL_RENDERBUFFER, info->depth_rb_glid );
     142                glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size.x, size.y );
     143                glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, info->depth_rb_glid );
     144                glBindRenderbuffer( GL_RENDERBUFFER, 0 );
     145        }
     146
     147}
     148
     149void nv::gl_context::blit( framebuffer f, clear_state::buffers_type mask, ivec2 src1, ivec2 src2, ivec2 dst1, ivec2 dst2 )
     150{
     151        gl_framebuffer_info* info  = m_framebuffers.get( f );
     152        if ( info )
     153        {
     154                glBindFramebuffer( GL_FRAMEBUFFER, info->glid );
     155                unsigned filter = mask == clear_state::COLOR_BUFFER ? GL_LINEAR : GL_NEAREST;
     156                glBlitFramebuffer( src1.x, src1.y, src2.x, src2.y, dst1.x, dst1.y, dst2.x, dst2.y, clear_state_buffers_to_mask( mask ), filter );
     157        }
     158}
     159
     160
     161bool nv::gl_context::check( framebuffer_slot ft )
     162{
     163        if ( is_gl_extension_loaded( GL_EXT_FRAMEBUFFER_OBJECT ) && is_gl_extension_loaded( GL_EXT_FRAMEBUFFER_BLIT ) )
     164        {
     165                unsigned result = glCheckFramebufferStatus( framebuffer_slot_to_enum(ft) );
     166                if ( result == GL_FRAMEBUFFER_COMPLETE ) return true;
     167                switch ( result )
     168                {
     169                case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT         : NV_LOG( LOG_ERROR, "gl_context::check : Framebuffer incomplete attachment!" ); break;
     170                case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT : NV_LOG( LOG_ERROR, "gl_context::check : Framebuffer missing attachment!" ); break;
     171                case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS         : NV_LOG( LOG_ERROR, "gl_context::check : Framebuffer incomplete dimensions!" ); break;
     172                case GL_FRAMEBUFFER_INCOMPLETE_FORMATS            : NV_LOG( LOG_ERROR, "gl_context::check : Framebuffer incomplete formats!" ); break;
     173                case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER        : NV_LOG( LOG_ERROR, "gl_context::check : Framebuffer incomplete draw buffer!" ); break;
     174                case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER        : NV_LOG( LOG_ERROR, "gl_context::check : Framebuffer incomplete read buffer!" ); break;
     175                case GL_FRAMEBUFFER_UNSUPPORTED                   : NV_LOG( LOG_ERROR, "gl_context::check : Framebuffer format combination unsupported!" ); break;
     176                default : NV_LOG( LOG_ERROR, "gl_context::check : Unknown Framebuffer error! (" << result << ")" ); break;
     177                }
     178        }
     179        else
     180        {
     181                NV_LOG( LOG_ERROR, "gl_context::check : Framebuffer extensions not loaded!" );
     182        }
     183        return false;
     184}
     185
     186void nv::gl_context::bind( framebuffer f, framebuffer_slot ft /*= FRAMEBUFFER_BOTH */ )
     187{
     188        const gl_framebuffer_info* info = m_framebuffers.get( f );
     189        if ( info )
     190        {
     191                glBindFramebuffer( framebuffer_slot_to_enum(ft), info->glid );
     192        }
     193        else
     194        {
     195                glBindFramebuffer( framebuffer_slot_to_enum(ft), 0 );
     196        }
     197}
    79198
    80199void gl_context::bind( texture t, texture_slot slot )
     
    84203        {
    85204                glActiveTexture( GL_TEXTURE0 + static_cast< GLenum >( slot ) );
    86                 glBindTexture( GL_TEXTURE_2D, info->glid );
     205                glBindTexture( texture_type_to_enum( info->type ), info->glid );
    87206        }
    88207}
     
    151270}
    152271
    153 void nv::gl_context::bind( framebuffer f )
    154 {
    155         const gl_framebuffer_info* info = m_framebuffers.get( f );
    156         if ( info )
    157         {
    158                 glBindFramebuffer( GL_FRAMEBUFFER, info->glid );
    159         }
    160 }
    161 
    162272void nv::gl_context::unbind( program )
    163273{
     
    199309                glBindFramebuffer( GL_FRAMEBUFFER, 0 );
    200310        }
     311        glDrawBuffer( GL_BACK );
     312        glReadBuffer( GL_BACK );
    201313}
    202314
     
    206318        if ( info )
    207319        {
    208                 image_format format = info->format;
    209                 ivec2        size   = info->size;
    210 
    211                 glBindTexture( GL_TEXTURE_2D, info->glid );
    212                 glTexImage2D( GL_TEXTURE_2D, 0, (GLint)nv::image_format_to_enum(format.format), size.x, size.y, 0, nv::image_format_to_enum(format.format), nv::datatype_to_gl_enum(format.type), data );
     320                image_format format  = info->format;
     321                ivec2        size    = info->size;
     322                unsigned     gl_type = texture_type_to_enum( info->type );
     323
     324                glBindTexture( gl_type, info->glid );
     325                glTexImage2D( gl_type, 0, (GLint)nv::image_format_to_internal_enum(format.format), size.x, size.y, 0, nv::image_format_to_enum(format.format), nv::datatype_to_gl_enum(format.type), data );
    213326        }
    214327}
     
    290403                m_render_state.stencil_test.enabled = stencil.enabled;
    291404        }
    292 
     405       
    293406        if ( stencil.enabled )
    294407        {
     
    579692        : context( a_device ), m_handle( a_handle )
    580693{
     694        // TODO: configurable:
     695        load_gl_extensions( GL_EXT_FRAMEBUFFER_BLIT | GL_EXT_FRAMEBUFFER_OBJECT );
    581696        force_apply_render_state( m_render_state );
    582697}
     
    603718}
    604719
     720void nv::gl_context::set_draw_buffers( uint32 count, output_slot* slots )
     721{
     722        unsigned int buffers[8];
     723        count = glm::min<uint32>( count, 8 );
     724        for ( uint32 i = 0; i < count; ++i )
     725        {
     726                buffers[i] = output_slot_to_enum( slots[i] );
     727                if ( slots[i] > OUTPUT_7 ) buffers[i] = 0;
     728        }
     729        glDrawBuffers( count, buffers );
     730}
     731
     732void nv::gl_context::set_draw_buffer( output_slot slot )
     733{
     734        glDrawBuffer( output_slot_to_enum(slot) );
     735}
     736
     737void nv::gl_context::set_read_buffer( output_slot slot )
     738{
     739        glReadBuffer( output_slot_to_enum(slot) );
     740}
     741
    605742void gl_context::draw( primitive prim, const render_state& rs, program p, vertex_array va, size_t count )
    606743{
Note: See TracChangeset for help on using the changeset viewer.