[Solved] glDrawElements -> Invalid Memory Access

Everything related to 3D programming
User avatar
StarBootics
Enthusiast
Enthusiast
Posts: 716
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

[Solved] glDrawElements -> Invalid Memory Access

Post by StarBootics »

Hello everyone,

As the title says I get an Invalid Memory Access on glDrawElements() function call and I don't understand why.

EDIT : I have fond the problem it work now !

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Nom du projet : ThinMatrix's OpenGL Tutorials
; Nom du fichier : Tutorial 3 - Main.pb
; Version du fichier : 1.0.1
; Programmation : OK
; Programmé par : StarBootics
; Date : 11-10-2021
; Mise à jour : 11-10-2021
; Code PureBasic : V5.73 LTS
; Plateforme : Linux
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule OGL
  
  #GL_DEPTH_BUFFER_BIT                = $00000100
  #GL_COLOR_BUFFER_BIT                = $00004000
  #GL_TRIANGLES                       = $0004
  #GL_NONE                            = 0
  #GL_BLEND                           = $0BE2
  #GL_TEXTURE_2D                      = $0DE1   
  #GL_ARRAY_BUFFER                   = $8892
  #GL_ELEMENT_ARRAY_BUFFER           = $8893
  #GL_STREAM_DRAW                    = $88E0
  #GL_STATIC_DRAW                    = $88E4
  #GL_DYNAMIC_DRAW                   = $88E8
  #GL_RGBA                            = $1908
  #GL_NUM_EXTENSIONS                    = $821D
  #GL_SHADING_LANGUAGE_VERSION      = $8B8C
  
  #GL_DELETE_STATUS                = $8B80
  #GL_COMPILE_STATUS                 = $8B81
  #GL_LINK_STATUS                    = $8B82
  #GL_VALIDATE_STATUS                = $8B83
  #GL_INFO_LOG_LENGTH                = $8B84
  #GL_ATTACHED_SHADERS               = $8B85
  #GL_ACTIVE_UNIFORMS                = $8B86
  #GL_ACTIVE_UNIFORM_MAX_LENGTH      = $8B87
  #GL_SHADER_SOURCE_LENGTH           = $8B88
  #GL_ACTIVE_ATTRIBUTES              = $8B89
  #GL_FRAGMENT_SHADER                = $8B30
  #GL_VERTEX_SHADER                  = $8B31
  #GL_GEOMETRY_SHADER                = $8DD9
  
  #GL_NEAREST                         = $2600
  #GL_RGB8                            = $8051
  #GL_RGBA8 = 32856
  
  #GL_FRAMEBUFFER                 = $8D40
  #GL_RENDERBUFFER               = $8D41
  
  #GL_COLOR_ATTACHMENT0                             = $8CE0
  #GL_COLOR_ATTACHMENT1                             = $8CE1
  #GL_COLOR_ATTACHMENT2                             = $8CE2
  #GL_COLOR_ATTACHMENT3                             = $8CE3
  #GL_COLOR_ATTACHMENT4                             = $8CE4
  #GL_COLOR_ATTACHMENT5                             = $8CE5
  #GL_COLOR_ATTACHMENT6                             = $8CE6
  #GL_COLOR_ATTACHMENT7                             = $8CE7
  #GL_COLOR_ATTACHMENT8                             = $8CE8
  #GL_COLOR_ATTACHMENT9                             = $8CE9
  #GL_COLOR_ATTACHMENT10                            = $8CEA
  #GL_COLOR_ATTACHMENT11                            = $8CEB
  #GL_COLOR_ATTACHMENT12                            = $8CEC
  #GL_COLOR_ATTACHMENT13                            = $8CED
  #GL_COLOR_ATTACHMENT14                            = $8CEE
  #GL_COLOR_ATTACHMENT15                            = $8CEF
  #GL_DEPTH_ATTACHMENT                              = $8D00
  
  #GL_TEXTURE_CUBE_MAP                = $8513
  #GL_TEXTURE_BINDING_CUBE_MAP        = $8514
  #GL_TEXTURE_CUBE_MAP_POSITIVE_X     = $8515
  #GL_TEXTURE_CUBE_MAP_NEGATIVE_X     = $8516
  #GL_TEXTURE_CUBE_MAP_POSITIVE_Y     = $8517
  #GL_TEXTURE_CUBE_MAP_NEGATIVE_Y     = $8518
  #GL_TEXTURE_CUBE_MAP_POSITIVE_Z     = $8519
  #GL_TEXTURE_CUBE_MAP_NEGATIVE_Z     = $851A
  
  #GL_TEXTURE0                        = $84C0
  #GL_TEXTURE1                        = $84C1
  #GL_TEXTURE2                        = $84C2
  #GL_TEXTURE3                        = $84C3
  #GL_TEXTURE4                        = $84C4
  #GL_TEXTURE5                        = $84C5
  #GL_TEXTURE6                        = $84C6
  #GL_TEXTURE7                        = $84C7
  #GL_TEXTURE8                        = $84C8
  #GL_TEXTURE9                        = $84C9
  #GL_TEXTURE10                       = $84CA
  #GL_TEXTURE11                       = $84CB
  #GL_TEXTURE12                       = $84CC
  #GL_TEXTURE13                       = $84CD
  #GL_TEXTURE14                       = $84CE
  #GL_TEXTURE15                       = $84CF
  #GL_TEXTURE16                       = $84D0
  #GL_TEXTURE17                       = $84D1
  #GL_TEXTURE18                       = $84D2
  #GL_TEXTURE19                       = $84D3
  #GL_TEXTURE20                       = $84D4
  #GL_TEXTURE21                       = $84D5
  #GL_TEXTURE22                       = $84D6
  #GL_TEXTURE23                       = $84D7
  #GL_TEXTURE24                       = $84D8
  #GL_TEXTURE25                       = $84D9
  #GL_TEXTURE26                       = $84DA
  #GL_TEXTURE27                       = $84DB
  #GL_TEXTURE28                       = $84DC
  #GL_TEXTURE29                       = $84DD
  #GL_TEXTURE30                       = $84DE
  #GL_TEXTURE31                       = $84DF
  #GL_ACTIVE_TEXTURE                  = $84E0
  #GL_DEPTH_CLAMP                     = 34383
  #GL_TEXTURE_LOD_BIAS                = 34049
  #GL_DEPTH_COMPONENT                 = 6402
  #GL_DEPTH_COMPONENT16               = 33189
  #GL_DEPTH_COMPONENT24               = 33190
  #GL_MULTISAMPLE                     = 32925
  #GL_DRAW_FRAMEBUFFER                = 36009
  #GL_READ_FRAMEBUFFER                = 36008
  #GL_MAX_INTEGER_SAMPLES             = 37136 
  #GL_FRAMEBUFFER_COMPLETE            = 36053
  #GL_RG32F                           = 33328
  
  
  ImportC "-lGL" 
    
    glBindBuffer(Target.l, Buffer.l)
    
    glBindVertexArray(VertexArray.l)
    
    glBufferData(Target.l, size.i, *Data_, Usage.l)
    
    glClear(Mask.l)
    glClearColor(Red.f, Green.f, Blue.f, Alpha.f)
    
    glDeleteBuffers(n.l, *Buffers)
    
    glDeleteVertexArrays(n.l, *VertexArrays) ; OpenGL 3.0+
    
    glDisable(Capability.l)
    
    glDisableVertexAttribArray(Index.l)
    
    glDrawElements(Mode.l, Count.l, Type.l, *Indices)
    
    glEnable(Capability.l)
    glEnableVertexAttribArray(Index.l)
    
    glFinish()
    glGenBuffers(n.l, *buffers)
    glGenVertexArrays(n.l, *VertexArrays) ; OpenGL 3.0+
    
    glGetError()
    glGetString__(Name.l) As "glGetString"
    glGetStringi__(Name.l, Index.l) As "glGetStringi"
    
    glVertexAttribPointer(Index.l, Size.l, Type.l, Normalized.b, Stride.l, Pointer)
    glViewport(x.l, y.l, width.l, height.l)
    
  EndImport
  
  Declare.s glGetString(Name.l)
  Declare.s glGetStringi(Name.l, Index.l)
  Declare.s glGetErrorMessage(Flag = 0)
  
EndDeclareModule

Module OGL
  
  Procedure.s glGetString(Name.l)
    
    *Ptr = glGetString__(Name)
    
    If *Ptr <> #Null
      Output.s = PeekS(*Ptr, -1, #PB_Ascii)
    Else
      Output = glGetErrorMessage(1)
    EndIf
    
    ProcedureReturn Output
  EndProcedure
  
  Procedure.s glGetStringi(Name.l, Index.l)
    
    *Ptr = glGetStringi__(Name, Index)
    
    If *Ptr <> #Null
      Output.s = PeekS(*Ptr, -1, #PB_Ascii)
    Else
      Output = glGetErrorMessage(1)
    EndIf
    
    ProcedureReturn Output
  EndProcedure
  
  Procedure.s glGetErrorMessage(Flag = 0)
    
    Select glGetError()
        
      Case #GL_NO_ERROR
        ErrorMessage.s = "#GL_NO_ERROR (" + Str(#GL_NO_ERROR) + ")"
        
      Case #GL_INVALID_ENUM
        ErrorMessage = "#GL_INVALID_ENUM (" + Str(#GL_INVALID_ENUM) + ")"
        
      Case #GL_INVALID_VALUE
        ErrorMessage = "#GL_INVALID_VALUE (" + Str(#GL_INVALID_VALUE) + ")"
        
      Case #GL_INVALID_OPERATION
        ErrorMessage = "#GL_INVALID_OPERATION (" + Str(#GL_INVALID_OPERATION) + ")"
        
      Case #GL_STACK_OVERFLOW 
        ErrorMessage = "#GL_STACK_OVERFLOW (" + Str(#GL_STACK_OVERFLOW) + ")"
        
      Case #GL_STACK_UNDERFLOW
        ErrorMessage = "#GL_STACK_UNDERFLOW (" + Str(#GL_STACK_UNDERFLOW) + ")"
        
      Case #GL_OUT_OF_MEMORY 
        ErrorMessage = "#GL_OUT_OF_MEMORY (" + Str(#GL_OUT_OF_MEMORY) + ")"
        
    EndSelect
    
    If Flag = 1
      MessageRequester("OpenGL Error", ErrorMessage)
    EndIf
    
    ProcedureReturn ErrorMessage
  EndProcedure
  
EndModule

DeclareModule RawModel
  
  Interface RawModel
    
    GetVaoID.l()
    GetIndiceCount.l()
    Free()
    
  EndInterface
  
  Declare.i New(P_VaoID.l, P_IndiceCount.l)
  
EndDeclareModule

Module RawModel
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration de la Structure <<<<<

  Structure Private_Members
    
    VirtualTable.i
    VaoID.l
    IndiceCount.l
    
  EndStructure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les observateurs <<<<<

  Procedure.l GetVaoID(*This.Private_Members)
    
    ProcedureReturn *This\VaoID
  EndProcedure
  
  Procedure.l GetIndiceCount(*This.Private_Members)
    
    ProcedureReturn *This\IndiceCount
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Destructeur <<<<<

  Procedure Free(*This.Private_Members)
    
    FreeStructure(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Constructeur <<<<<

  Procedure.i New(P_VaoID.l, P_IndiceCount.l)
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
    
    *This\VaoID = P_VaoID
    *This\IndiceCount = P_IndiceCount
    
    ProcedureReturn *This
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les entrées de la table virtuelle <<<<<

  DataSection
    START_METHODS:
    Data.i @GetVaoID()
    Data.i @GetIndiceCount()
    Data.i @Free()
    END_METHODS:
  EndDataSection
  
EndModule

DeclareModule Loader
  
  Interface Loader
    
    LoadToVAO.i(Array Positions.f(1), Array Indices.l(1))
    CleanUp()
    Free()
    
  EndInterface
  
  Declare.i New()
  
EndDeclareModule

Module Loader
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration de la Structure <<<<<

  Structure Private_Members
    
    VirtualTable.i
    List VertexArrayObjects.l()
    List VertexBufferObjects.l()
    List IndicesBufferObjects.l()
    
  EndStructure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure.l Private_CreateVAO(*This.Private_Members)
    
    OGL::glGenVertexArrays(1, @VertexArrayObjectID.l)
    OGL::glBindVertexArray(VertexArrayObjectID)

    AddElement(*This\VertexArrayObjects())
    *This\VertexArrayObjects() = VertexArrayObjectID
    
    ProcedureReturn VertexArrayObjectID
  EndProcedure

  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure Private_StoreDataInAttributeList(*This.Private_Members, AttributeNumber.l, Array Floats.f(1))
    
    OGL::glGenBuffers(1, @VertexBufferObjectID.l)
    
    AddElement(*This\VertexBufferObjects())
    *This\VertexBufferObjects() = VertexBufferObjectID
    
    OGL::glBindBuffer(OGL::#GL_ARRAY_BUFFER, VertexBufferObjectID)
    OGL::glBufferData(OGL::#GL_ARRAY_BUFFER, (ArraySize(Floats()) + 1) * SizeOf(Float), @Floats(), OGL::#GL_STATIC_DRAW)
    OGL::glEnableVertexAttribArray(AttributeNumber)
    OGL::glVertexAttribPointer(AttributeNumber, 3, #GL_FLOAT, #GL_FALSE, 0, 0)
    OGL::glDisableVertexAttribArray(AttributeNumber)

  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure Private_BindIndicesBuffer(*This.Private_Members, Array Indices.l(1))
    
    OGL::glGenBuffers(1, @IndiceBufferObjectID.l)
    AddElement(*This\IndicesBufferObjects())
    *This\IndicesBufferObjects() = IndiceBufferObjectID
    
    OGL::glBindBuffer(OGL::#GL_ELEMENT_ARRAY_BUFFER, IndiceBufferObjectID)
    OGL::glBufferData(OGL::#GL_ELEMENT_ARRAY_BUFFER, (ArraySize(Indices()) + 1) * SizeOf(Long), @Indices(), OGL::#GL_STATIC_DRAW)

  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure.i LoadToVAO(*This.Private_Members, Array Positions.f(1), Array Indices.l(1))
    
    VAO.l = Private_CreateVAO(*This)
    
    Private_StoreDataInAttributeList(*This, 0, Positions())
    Private_BindIndicesBuffer(*This, Indices())
    
    OGL::glBindVertexArray(0)

    ProcedureReturn RawModel::New(VAO, ArraySize(Indices()) + 1)
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure CleanUp(*This.Private_Members)
    
    ForEach *This\VertexArrayObjects()
      OGL::glDeleteVertexArrays(1, @*This\VertexArrayObjects())
    Next
    
    ForEach *This\VertexBufferObjects()
      OGL::glDeleteBuffers(1, @*This\VertexBufferObjects())
    Next
    
    ForEach *This\IndicesBufferObjects()
      OGL::glDeleteBuffers(1, @*This\IndicesBufferObjects())
    Next

  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Destructeur <<<<<

  Procedure Free(*This.Private_Members)
    
    FreeStructure(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Constructeur <<<<<

  Procedure.i New()
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
    
    ProcedureReturn *This
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les entrées de la table virtuelle <<<<<

  DataSection
    START_METHODS:
    Data.i @LoadToVAO()
    Data.i @CleanUp()
    Data.i @Free()
    END_METHODS:
  EndDataSection
  
EndModule

DeclareModule Renderer
  
  Interface Renderer
    
    Prepare()
    Render(*Model.RawModel::RawModel)
    Free()
    
  EndInterface
  
  Declare.i New()
  
EndDeclareModule

Module Renderer
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration de la Structure <<<<<

  Structure Private_Members
    
    VirtualTable.i
    
  EndStructure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure Prepare(*This.Private_Members)
    
		OGL::glClearColor(1.0, 0.0, 0.0, 1.0)
		OGL::glClear(OGL::#GL_COLOR_BUFFER_BIT)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure Render(*This.Private_Members, *Model.RawModel::RawModel)
    
    OGL::glBindVertexArray(*Model\GetVaoID())
    OGL::glEnableVertexAttribArray(0)
    
    OGL::glDrawElements(OGL::#GL_TRIANGLES, *Model\GetIndiceCount(), #GL_UNSIGNED_INT, 0)
    
    OGL::glDisableVertexAttribArray(0)
    OGL::glBindVertexArray(0)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Destructeur <<<<<

  Procedure Free(*This.Private_Members)
    
    FreeStructure(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Constructeur <<<<<

  Procedure.i New()
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
    
    ProcedureReturn *This
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les entrées de la table virtuelle <<<<<

  DataSection
    START_METHODS:
    Data.i @Prepare()
    Data.i @Render()
    Data.i @Free()
    END_METHODS:
  EndDataSection
  
EndModule

If OpenWindow(0, 50, 50, 1034, 778, "ThinMatrix - Tutorial 03")
  
  OpenGLGadget(0, 5, 5, 1024, 768, #PB_OpenGL_8BitStencilBuffer|#PB_OpenGL_24BitDepthBuffer|#PB_OpenGL_32BitAccumulationBuffer)
  AddWindowTimer(0, 0, 32) ; about 30 fps
  
  OGL::glViewport(0, 0, 1024, 768)
 
  Loader.Loader::Loader = Loader::New()
  Renderer.Renderer::Renderer = Renderer::New()
  
  Dim Vertices.f(11)
  
  ; V0
  Vertices(0) = -0.5
  Vertices(1) = 0.5
  Vertices(2) = 0.0
  
  ; V1
  Vertices(3) = -0.5
  Vertices(4) = -0.5
  Vertices(5) = 0.0
  
  ; V2
  Vertices(6) = 0.5
  Vertices(7) = -0.5
  Vertices(8) = 0.0
  
  ; V3
  Vertices(9) = 0.5
  Vertices(10) = 0.5
  Vertices(11) = 0.0
  
  Dim Indices.l(5)
  
  Indices(0) = 0
  Indices(1) = 1
  Indices(2) = 3
  
  Indices(3) = 3
  Indices(4) = 1
  Indices(5) = 2
  
  Model.RawModel::RawModel = Loader\LoadToVAO(Vertices(), Indices())
  
  Repeat
    
    Select WaitWindowEvent()
        
      Case #PB_Event_Timer
        
        Select EventTimer()
            
          Case 0
            SetGadgetAttribute(0, #PB_OpenGL_SetContext, #True)
            
            Renderer\Prepare()
            Renderer\Render(Model)
            
            OGL::glFinish()
            
            SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True) 
            
        EndSelect 
        
      Case #PB_Event_Gadget
        
        Select EventGadget()
            
        EndSelect
        
      Case #PB_Event_CloseWindow
        
        Select EventWindow()
            
          Case 0
            Loader\CleanUp()
            Break

        EndSelect
        
    EndSelect
    
  ForEver
  
  Loader\Free()
  Renderer\Free()
  Model\Free()
  
  End
  
EndIf

; <<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< FIN DU FICHIER <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<
Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !