Everything's finally plugged in (big pic!)

Miscellaneous Forums/General Discussion/Everything's finally plugged in (big pic!)

You tell me.

SuperStrict

Import "head.bmx"

Type IBuffer
    Method Lock:TBank( ) Abstract
    Method Unlock( ) Abstract
End Type

Type IVertexBuffer Extends IBuffer
    Field _vbo% = -1
    Field _size% = 0
    Field _locked% = 0
    Field _bank:TBank = Null
    Field _hw% = 0
    Field _dynamic% = 0
    
    Method New( )
        _bank = TBank.Create( 0 )
    End Method
    
    Method Delete( )
        If _hw Then
            glDeleteBuffersARB( 1, Varptr _vbo )
        Else
            _bank = Null
        EndIf
    End Method
    
    Method Lock:TBank( )
        _locked :+ 1
        If _locked = 1 And _hw Then
            _bank = TBank.Create( _size )
            Bind( )
            glGetBufferSubDataARB( GL_ARRAY_BUFFER_ARB, 0, _size, _bank.Buf( ) )
            Unbind( )
        EndIf
        Return _bank
    End Method
    
    Method Unlock( )
        Assert _locked>0, "Vertex buffer is not locked"
        _locked :- 1
        
        If _locked = 0 Then
            _size = _bank.Size( )
            If _size >= 3145728 And _dynamic = 0 Then _hw = 1
            If _hw Then
                Local _enum% = GL_STATIC_DRAW_ARB
                If _dynamic Then _enum = GL_DYNAMIC_DRAW_ARB
                If _vbo = -1 Then glGenBuffersARB( 1, Varptr _vbo )
                Bind( )
                glBufferDataARB( GL_ARRAY_BUFFER_ARB, _size, _bank.Buf( ), _enum )
                UnBind( )
                memset_( _bank.Buf( ), 0, _bank.Size( ) )
                _bank.Resize( 0 )
                _bank = Null
            Else
                If _vbo <> -1 Then glDeleteBuffersARB( 1, Varptr _vbo )
                _vbo = -1
            EndIf
        EndIf
    End Method
    
    Method Bind( )
        If _hw Then
            glBindBufferARB( GL_ARRAY_BUFFER_ARB, _vbo )
        EndIf
    End Method
    
    Method Unbind( )
        If _hw Then
            glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 )
        EndIf
    End Method
    
    Method Pointer@ Ptr( )
        If _hw Then Return Byte Ptr(0)
        Return _bank.Buf( )
    End Method
End Type

Type IIndexBuffer Extends IBuffer
    Field _ibo% = -1
    Field _primitives% = 0
    Field _size% = 0
    Field _locked% = 0
    Field _bank:TBank = Null
    Field _hw% = 0
    Field _dynamic% = 0
    
    Method New( )
        _bank = TBank.Create( 0 )
    End Method
    
    Method Delete( )
        If _hw Then
            glDeleteBuffersARB( 1, Varptr _ibo )
        Else
            _bank = Null
        EndIf
    End Method
    
    Method Lock:TBank( )
        _locked :+ 1
        If _locked = 1 And _hw Then
            _bank = TBank.Create( _size )
            Bind( )
            glGetBufferSubDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0, _size, _bank.Buf( ) )
            Unbind( )
        EndIf
        Return _bank
    End Method
    
    Method Unlock( )
        Assert _locked>0, "Vertex buffer is not locked"
        _locked :- 1
        
        If _locked = 0 Then
            _size = _bank.Size( )
            _primitives = _size/2
            If _primitives >= 262144 And _dynamic = 0 Then _hw = 1
            If _hw Then
                Local _enum% = GL_STATIC_DRAW_ARB
                If _dynamic Then _enum = GL_DYNAMIC_DRAW_ARB
                If _ibo = -1 Then glGenBuffersARB( 1, Varptr _ibo )
                Bind( )
                glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, _size, _bank.Buf( ), _enum )
                UnBind( )
                memset_( _bank.Buf( ), 0, _bank.Size( ) )
                _bank.Resize( 0 )
                _bank = Null
            Else
                If _ibo <> -1 Then glDeleteBuffersARB( 1, Varptr _ibo )
                _ibo = -1
            EndIf
        EndIf
    End Method
    
    Method Bind( )
        If _hw Then
            glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, _ibo )
        EndIf
    End Method
    
    Method Unbind( )
        If _hw Then
            glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 )
        EndIf
    End Method
    
    Method Draw( _type%=GL_TRIANGLES, off%=0, range%=-1 )
        If range = -1 Then
            range = _primitives
            off = 0
        EndIf
        
        If glDrawRangeElements Then
            glDrawRangeElements( _type, off, off+range, range, GL_UNSIGNED_SHORT, Pointer() )
        Else
            glDrawElements( _type, range, GL_UNSIGNED_SHORT, Pointer()+off )
        EndIf
    End Method
    
    Method Pointer@ Ptr( )
        If _hw Then Return Byte Ptr(0) ' I don't trust 'null'
        Return _bank.Buf( )
    End Method
End Type