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 <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<
StarBootics