Vertex Buffer Objects - OpenGL examples with OpenGLGadget

Everything related to 3D programming
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Vertex Buffer Objects - OpenGL examples with OpenGLGadget

Post by applePi »

examples about Vertex Buffer Objects, and Vertex Array Objects. adapted from examples in chapter 3 of this book: Computer Graphics Through OpenGL 2014 (1)
only example 3 is a one to one translation of SquareAnnulusAndTriangleVAO.CPP
to change resolution change :
Global NbX=300
Global NbZ=300
to other values less than 300 X 300 since 90000 vertices connected with Quads can be too big for slow computers, the gain in speed depends on your graphics card quality and speed
Include file contains additional OpenGL functions:
GLFunctions.PBI

Code: Select all

;from luis reply http://purebasic.fr/english/viewtopic.php?f=13&t=45687&start=15#p446875
CompilerIf (#PB_Compiler_Processor = #PB_Processor_x86)
Import "Opengl32.lib" 
 wglGetProcAddress_(s.p-ascii) As "_wglGetProcAddress@4"
EndImport
 CompilerElse   
Import "Opengl32.lib" 
 wglGetProcAddress_(s.p-ascii) As "wglGetProcAddress"
EndImport
CompilerEndIf

Prototype PFNGLGENBUFFERSPROC ( n.i, *buffers)
Global glGenBuffers.PFNGLGENBUFFERSPROC
glGenBuffers = wglGetProcAddress_( "glGenBuffers" )
Prototype PFNGLBINDBUFFERPROC ( target.l, buffer.i)
Global glBindBuffer.PFNGLBINDBUFFERPROC
glBindBuffer = wglGetProcAddress_( "glBindBuffer" )
Prototype PFNGLBUFFERDATAPROC ( target.l, size.i, *Data_, usage.l)
Global glBufferData.PFNGLBUFFERDATAPROC
glBufferData = wglGetProcAddress_( "glBufferData" )
Prototype PFNGLBUFFERSUBDATAPROC ( target.l, offset.i, size.i, *Data_)
Global glBufferSubData.PFNGLBUFFERSUBDATAPROC
glBufferSubData = wglGetProcAddress_( "glBufferSubData" )

Prototype PFNGLGENVERTEXARRAYSPROC (n.i, *arrays)
Global glGenVertexArrays.PFNGLGENVERTEXARRAYSPROC
glGenVertexArrays = wglGetProcAddress_( "glGenVertexArrays" )

Prototype PFNGLBINDVERTEXARRAYPROC(n.i)
Global glBindVertexArray.PFNGLBINDVERTEXARRAYPROC
glBindVertexArray = wglGetProcAddress_( "glBindVertexArray" )

Prototype PFNGLENABLEVERTEXATTRIBARRAYPROC ( index.i )
Global glEnableVertexAttribArray.PFNGLENABLEVERTEXATTRIBARRAYPROC
glEnableVertexAttribArray = wglGetProcAddress_( "glEnableVertexAttribArray" )

Prototype PFNGLVERTEXATTRIBPOINTERPROC ( index.i, size.i, type.l, normalized.b, stride.i, *pointer )
Global glVertexAttribPointer.PFNGLVERTEXATTRIBPOINTERPROC
glVertexAttribPointer = wglGetProcAddress_( "glVertexAttribPointer" )

Prototype.i PFNGLCREATESHADERPROC ( type.l )
Global glCreateShader.PFNGLCREATESHADERPROC
glCreateShader = wglGetProcAddress_( "glCreateShader" )


Prototype PFNGLSHADERSOURCEPROC ( shader.i, count.i, *stringBuffer, *length )
Global glShaderSource.PFNGLSHADERSOURCEPROC
glShaderSource = wglGetProcAddress_( "glShaderSource" )


Prototype PFNGLCOMPILESHADERPROC ( shader.i )
Global glCompileShader.PFNGLCOMPILESHADERPROC
glCompileShader = wglGetProcAddress_( "glCompileShader" )


Prototype PFNGLATTACHSHADERPROC ( program.i, shader.i )
Global glAttachShader.PFNGLATTACHSHADERPROC
glAttachShader = wglGetProcAddress_( "glAttachShader" )


Prototype PFNGLLINKPROGRAMPROC ( program.i )
Global glLinkProgram.PFNGLLINKPROGRAMPROC
glLinkProgram = wglGetProcAddress_( "glLinkProgram" )

Prototype.i PFNGLCREATEPROGRAMPROC ( )
Global glCreateProgram.PFNGLCREATEPROGRAMPROC
glCreateProgram = wglGetProcAddress_( "glCreateProgram" )

Prototype PFNGLUSEPROGRAMPROC ( program.i )
Global glUseProgram.PFNGLUSEPROGRAMPROC
glUseProgram = wglGetProcAddress_( "glUseProgram" )

Prototype PFNGLDRAWARRAYSPROC ( mode.l, first.i, count.i )
Global glDrawArrays.PFNGLDRAWARRAYSPROC
glDrawArrays = wglGetProcAddress_( "glDrawArrays" )

;PFNGLINDEXPOINTERPROC) ( GLenum type, GLsizei stride, const GLvoid *ptr )

Prototype PFNGLINDEXPOINTERPROC ( enum.i, stride.i, *length )
Global glIndexPointer.PFNGLINDEXPOINTERPROC
glIndexPointer = wglGetProcAddress_( "glIndexPointer" )


Prototype PFNGLDELETEBUFFERSPROC ( n.i, *buffers)
Global glDeleteBuffers.PFNGLDELETEBUFFERSPROC
glDeleteBuffers = wglGetProcAddress_( "glDeleteBuffers" )


Prototype PFNGLDELETEVERTEXARRAYSPROC ( n.i, *buffers)
Global glDeleteVertexArrays.PFNGLDELETEVERTEXARRAYSPROC
glDeleteVertexArrays = wglGetProcAddress_( "glDeleteVertexArrays" )

Prototype PFNGLDISABLEVERTEXATTRIBARRAYPROC(index.i)
Global glDisableVertexAttribArray.PFNGLDISABLEVERTEXATTRIBARRAYPROC
glDisableVertexAttribArray = wglGetProcAddress_("glDisableVertexAttribArray")

Prototype PFNGLMAPBUFFERPROC(Target.i, Access.i)
Global glMapBuffer.PFNGLMAPBUFFERPROC
glMapBuffer = wglGetProcAddress_("glMapBuffer")

Prototype PFNGLUNMAPBUFFERPROC(Target.i)
Global glUnmapBuffer.PFNGLUNMAPBUFFERPROC
glUnmapBuffer = wglGetProcAddress_("glUnmapBuffer")


VBO example_1: 3D Function Plotting, here vertices positions, colors, texture info every one is stored in its own buffer

Code: Select all

#GL_ARRAY_BUFFER = $8892
#GL_ELEMENT_ARRAY_BUFFER = $8893
#GL_STATIC_DRAW = $88E4
#GL_DYNAMIC_DRAW = $88E8

Structure vertices
  x.f
  y.f
  z.f
EndStructure

Structure Colors
  r.f
  g.f
  b.f
EndStructure

Structure texture
  tx.f
  ty.f

EndStructure


Declare FPS(timer.l)
Declare FillArray()

UseJPEGImageDecoder()
UsePNGImageDecoder()

Declare FillArray()

Define event, quit

#ImagePath = #PB_Compiler_Home + "examples/3d/Data/Textures/"
LoadImage(1, #ImagePath+"MRAMOR6X6.jpg") ;ValetCoeur.jpg")
*Buffer = EncodeImage(1)
        
Define event, quit

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), ".. Up/Down: zoom in/out... 'W': wire frame... 'A'/'Z': change Camera view")
SetWindowColor(0, RGB(200,220,200))
OpenGLGadget(0, 10, 10, WindowWidth(0) , WindowHeight(0) , #PB_OpenGL_Keyboard)

;IncludeFile #PB_Compiler_Home + "Examples\Sources - Advanced\OpenGL Cube\OpenGL.pbi"
IncludeFile "GLFunctions.pbi"
;IncludeFile "GLEXT.pbi"


glMatrixMode_(#GL_PROJECTION)
glLoadIdentity_();
gluPerspective_(45.0, 800/600, 1.0, 60.0)
glMatrixMode_(#GL_MODELVIEW)
glTranslatef_(0, 0, -5)
glShadeModel_(#GL_SMOOTH) 
glEnable_(#GL_DEPTH_TEST)
;glEnable_(#GL_CULL_FACE) 
glColor3f_(1.0, 0.3, 0.0)
glViewport_(0, 0, 800, 600)

;resolution of the graphics grid
Global NbX=300
Global NbZ=300

Global VertexCount = (NbX+1)*(NbZ+1)
Global vbo.i, indexBuffer.i, vbcol.i, vbtex.i, TexID.i
;Global vbo.i(2)

Global Dim vertices.vertices(NbX,NbZ)
Global Dim colors.Colors(NbX,NbZ)
Global Dim tex.texture(NbX,NbZ)
Global Dim MeshDataInd(0)


glGenTextures_(1, @TexID)
glBindTexture_(#GL_TEXTURE_2D, TexID)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
glTexImage2D_(#GL_TEXTURE_2D, 0, 3, ImageWidth(1), ImageHeight(1), 0, #GL_BGR_EXT, #GL_UNSIGNED_BYTE, *Buffer+57)

FreeMemory(*Buffer)

glEnable_(#GL_TEXTURE_2D)   ; Enable texture mapping 
glBindTexture_(#GL_TEXTURE_2D, TexID) ; use texture number 1

Global indexsize
Global indexSizeInBytes

FillArray()

;wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww

glGenBuffers( 2, @vbo ) ; Vertex Buffer Object
glBindBuffer(#GL_ARRAY_BUFFER, vbo )
glBufferData(#GL_ARRAY_BUFFER,SizeOf(vertices)*VertexCount,@vertices(0,0), #GL_STATIC_DRAW)
glVertexPointer_(3, #GL_FLOAT,0,0)

glGenBuffers( 1, @vbcol );  color buffer
glBindBuffer(#GL_ARRAY_BUFFER, vbcol);
glBufferData(#GL_ARRAY_BUFFER, SizeOf(Colors)*VertexCount,@colors(0,0),#GL_STATIC_DRAW);
glColorPointer_(3, #GL_FLOAT, 0, 0)

glGenBuffers( 1, @vbtex );  texture buffer
glBindBuffer(#GL_ARRAY_BUFFER, vbtex);
glBufferData(#GL_ARRAY_BUFFER, SizeOf(texture)*VertexCount,@tex(0,0),#GL_STATIC_DRAW);
;glTexCoordPointer_(2, #GL_FLOAT, SizeOf(texture), @tex(0,0)\tx)
glTexCoordPointer_(2, #GL_FLOAT, 0,0)

glGenBuffers( 1, @indexBuffer );  
glBindBuffer(#GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(#GL_ELEMENT_ARRAY_BUFFER, indexSizeInBytes,@MeshDataInd(0),#GL_STATIC_DRAW);

rot.f = 1

;glTranslatef_(0.0, 0.0, -2)
glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
glPointSize_(3)

;the following is the camera or your eye, 0,2,3 your eyes__ 0,0,0; the object__ 0,1,0 direction
gluLookAt_( 0, 2, 3,
            0,  0, 0,
            0, 1,  0 )

;gluLookAt_( 0, 10, 30, ; the camera looking from position 0,10.30  to 0,0,0 from above
 ;           0,  0, 0,
  ;          0,  1,  0 ) 
SetActiveGadget(0) ; make the openGLgadget active so the keyboard can be used with it

glEnableClientState_(#GL_VERTEX_ARRAY )
  glEnableClientState_(#GL_COLOR_ARRAY)
  glEnableClientState_(#GL_TEXTURE_COORD_ARRAY)
  
a$=".. Up/Down: zoom in/out... 'W': wire frame... 'A'/'Z': change Camera view"  
  
Repeat
  
  fps$ = Str(FPS(1000))
  SetWindowTitle(0,"FPS  = " +fps$+ "  "+a$)
  ;glClearColor_(0.1, 0.1, 0.5, 1)
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  glRotatef_(rot/2, 0, 1, 0);

  ;glPointSize_(2)
  glDrawElements_(#GL_QUADS,indexsize,#GL_UNSIGNED_INT,0)
  
  
 Repeat
    event = WindowEvent()
    If event = #PB_Event_CloseWindow
      quit = #True
    EndIf
    If Event = #PB_Event_Gadget And EventGadget() = 0 
    If EventType() = #PB_EventType_KeyDown  ; like KeyboardReleased
            key = GetGadgetAttribute(0,#PB_OpenGL_Key )
            
               If key = #PB_Shortcut_Escape ;  Esc key to exit
               quit = 1
            
               ElseIf Key = #PB_Shortcut_W; display wire Frame or solid frame
               If fill = 0
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_LINE )
                fill ! 1
               Else
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_FILL)
                fill ! 1
              EndIf
              ElseIf Key = #PB_Shortcut_Up
                glScalef_(1.05,1.05,1.05)
              ElseIf Key = #PB_Shortcut_Down
                glScalef_(0.95,0.95,0.95)
              ElseIf Key = #PB_Shortcut_A
                glMatrixMode_(#GL_MODELVIEW);
                glLoadIdentity_()           ;
                ;gluLookAt_(0, 40, 14,  0,0,0,  0,1,0 ) 
                gluLookAt_(0, 5, 1,  0,0,0,  0,1,0 ) 
              ElseIf Key = #PB_Shortcut_Z
               glMatrixMode_(#GL_MODELVIEW);
                glLoadIdentity_();
                ;gluLookAt_(0, 0.3, 0.5,  0,0,0,  0,1,0 )  
                gluLookAt_(0, 3, 5,  0,0,0,  0,1,0 )  
                                
            EndIf
               
    EndIf
   EndIf
  Until event = 0 Or quit = #True
  
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
  
  Delay(1)
Until quit = #True
glDisableClientState_(#GL_TEXTURE_COORD_ARRAY)
  glDisableClientState_(#GL_COLOR_ARRAY)
  glDisableClientState_(#GL_VERTEX_ARRAY)

  
  Procedure FillArray()
 
;xMin.f = -1 : yMin.f = -1: zMin.f = -1 : xMax.f = 1: yMax = 1 : zMax = 1
;xMin.f = -0.5 : zMin.f = -0.5 : xMax.f = 0.5: zMax = 0.5
;xMin.f = -30 : yMin.f = -30: zMin.f = -30 : xMax.f = 30: yMax = 30 : zMax = 30
;xMin.f = -12 : yMin.f = -12: zMin.f = -12 : xMax.f = 12: yMax = 12 : zMax = 12
xMin.f = -2 : yMin.f = -2: zMin.f = -2 : xMax.f = 2: yMax = 2 : zMax = 2
;xMin.f = -20 : yMin.f = -20: zMin.f = -20 : xMax.f = 20: yMax = 20 : zMax = 20
;xMin.f = -10 : yMin.f = -10: zMin.f = -10 : xMax.f = 10: yMax = 10 : zMax = 10
;xMin.f = -0.5 : zMin.f = -0.5 : xMax.f = 0.5: zMax = 0.5
  range = xMax - xMin
  step1.f = range / NbX
  x.f = xMin: z.f = zMin : y.f = yMin : v.l = 0
    
  For b=0 To NbZ
   
    For a=0 To NbX
      
      y.f =(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z)) ; Mexican Hat
      ;y.f =5*(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z)) 
      ;y.f = ATan ((z*z*z)/4 - (x*x))
      ;y.f = 1/(15*(x*x+z*z))
      ;y.f = Sin(5*x)*Cos(5*z)/2 ; hills
      ;y.f = 2/Exp((x*5)*(x*5)*(z*5)*(z*5)) ; like '+'
      ;y.f = Log(x*x+z*z)+0.6 ; horn
      ;y.f = Sin(10*(x*x+z*z))/5 ; like waves
      ;y.f = x * x
      ;y.f = 1/(x*x+z*z)
      ;y.f = Cos(x*x+z*z)
      ;y.f = (x*x+z*z)/6
      ;y.f =6*(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z)) 
      ;y.f = Sin(Sqr(x*x+ z*z))*10 / Sqr(x*x + z*z)
      ;y.f = Sin(Sqr(x*x+ z*z))*10 / Sqr(x*x + z*z)
      ;y.f =Sqr(5*5-z*z-x*x); sphere real part; x2 + y2 + z2 = r2
      
      ;**********************************************************************            
      
      vertices(a,b)\x = x*1
      vertices(a,b)\y = y*1 ; just amplify the height
      vertices(a,b)\z = z*1
      
      tex(a,b)\tx = a/NbX
      tex(a,b)\ty = b/NbZ 
      
      If y > 0.5
        colors(a,b)\r = 0.9 :colors(a,b)\g = 0.0 :colors(a,b)\b = 0 
      ElseIf y>=-0.3
        colors(a,b)\r = 0.2 :colors(a,b)\g = 0.9 :colors(a,b)\b = 0 
        Else
        colors(a,b)\r = 1.0 :colors(a,b)\g = 1.0 :colors(a,b)\b = 0 
      EndIf
      
      x.f + step1
      ;Debug x      
    Next a
    
    x = xMin
    z.f + step1
    
  Next b
  
   ;ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
  
  Nb=NbX+1
  
  For b=0 To NbZ-1
    For a=0 To NbX-1
      
      P1=a+(b*Nb)
      P2=P1+1
      P3=a+(b+1)*Nb
      P4=P3+1

      MeshDataInd(indx) = P3
      ReDim MeshDataInd(indx+2)
      MeshDataInd(indx+1) = P4
      ReDim MeshDataInd(indx+3)
      MeshDataInd(indx+2) = P2
      ReDim MeshDataInd(indx+4)
      MeshDataInd(indx+3)= P1;P2
 
      indx+4
    Next
  Next
  indexsize = ArraySize(MeshDataInd()) + 1
  indexSizeInBytes = indexsize * SizeOf(Long)
  
EndProcedure

Procedure FPS(timer.l) ; the code are from the forum somewhere
  Static FPSCount.l, FPS.l
  Static delay.l
  Protected t.l
  If timer = 0
    ProcedureReturn -1
  EndIf
  t = ElapsedMilliseconds()
  If t-delay > timer
    FPS = FPSCount*1000/timer
    FPSCount = 0
    delay = t
  Else
    FPSCount+1
  EndIf
  ProcedureReturn FPS
EndProcedure
   
VBO example2: here the vertices, colors, textures info are all stored in one continuous buffer, we animate some points. we can access any vertex or color by a pointer look line 159 and below. the graph draw using #GL_POINTS 300 x 300 points

Code: Select all

Procedure.f RandF(Min.f, Max.f, Resolution.i = 10000)
  ProcedureReturn (Min + (Max - Min) * Random(Resolution) / Resolution)
EndProcedure

#GL_ARRAY_BUFFER = $8892
#GL_ELEMENT_ARRAY_BUFFER = $8893
#GL_STATIC_DRAW = $88E4
#GL_DYNAMIC_DRAW = $88E8
#GL_READ_ONLY = $88B8
#GL_WRITE_ONLY = $88B9
#GL_READ_WRITE = $88BA

Structure vertices
  x.f
  y.f
  z.f
EndStructure

Structure colors
  r.f
  g.f
  b.f
EndStructure

Structure texture
  tx.f
  ty.f

EndStructure


Declare FPS(timer.l)
Declare FillArray()


UseJPEGImageDecoder()
UsePNGImageDecoder()

Declare FillArray()

Define event, quit

#ImagePath = #PB_Compiler_Home + "examples/3d/Data/Textures/"
LoadImage(1, #ImagePath+"MRAMOR6X6.jpg") ;ValetCoeur.jpg")
*Buff = EncodeImage(1)
        
Define event, quit

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), ".. Up/Down: zoom in/out.... 'A'/'Z': change Camera view")
SetWindowColor(0, RGB(200,220,200))
OpenGLGadget(0, 10, 10, WindowWidth(0) , WindowHeight(0) , #PB_OpenGL_Keyboard)

;IncludeFile #PB_Compiler_Home + "Examples\Sources - Advanced\OpenGL Cube\OpenGL.pbi"
IncludeFile "GLFunctions.pbi"
;IncludeFile "GLEXT.pbi"


glMatrixMode_(#GL_PROJECTION)
glLoadIdentity_();
gluPerspective_(45.0, 800/600, 1.0, 60.0)
glMatrixMode_(#GL_MODELVIEW)
glTranslatef_(0, 0, -5)
glShadeModel_(#GL_SMOOTH) 
glEnable_(#GL_DEPTH_TEST)
;glEnable_(#GL_CULL_FACE) 
glColor3f_(1.0, 0.3, 0.0)
glViewport_(0, 0, 800, 600)

;resolution of the graphics grid
Global NbX=300
Global NbZ=300
;Global Nb
Global VertexCount = (NbX+1)*(NbZ+1)
Global vao.i, vbcol.i, vbtex.i, TexID.i
Global Dim buffer.i(2)

Global Dim vertices.vertices(NbX,NbZ)
Global Dim colors.colors(NbX,NbZ)
Global Dim tex.texture(NbX,NbZ)
Global Dim MeshDataInd(0)


glGenTextures_(1, @TexID)
glBindTexture_(#GL_TEXTURE_2D, TexID)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
glTexImage2D_(#GL_TEXTURE_2D, 0, 3, ImageWidth(1), ImageHeight(1), 0, #GL_BGR_EXT, #GL_UNSIGNED_BYTE, *Buff+57)

FreeMemory(*Buff)

glEnable_(#GL_TEXTURE_2D)   ; Enable texture mapping 
glBindTexture_(#GL_TEXTURE_2D, TexID) ; use texture number 1

Global indexsize
Global indexSizeInBytes

FillArray()
;Debug (SizeOf(vertices) + SizeOf(colors))*VertexCount
;Debug VertexCount
  ;wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
  ;Debug SizeOf(TVertex)

*p = #Null
glGenBuffers( 2, @buffer(0) ) ; Vertex Buffer Object
;// Enable two vertex arrays: co-ordinates And color.
glEnableClientState_(#GL_VERTEX_ARRAY);
glEnableClientState_(#GL_COLOR_ARRAY) ;
glEnableClientState_(#GL_TEXTURE_COORD_ARRAY)
glBindBuffer(#GL_ARRAY_BUFFER, buffer(0) )
;glBufferData(#GL_ARRAY_BUFFER,SizeOf(vertices)*VertexCount,@vertices(0,0), #GL_STATIC_DRAW)
glBufferData(#GL_ARRAY_BUFFER, (SizeOf(vertices)+SizeOf(colors)+SizeOf(texture))*VertexCount, #Null, #GL_STATIC_DRAW);
;// Copy vertex coordinates Data into first half of vertex buffer.
glBufferSubData(#GL_ARRAY_BUFFER, 0, SizeOf(vertices)*VertexCount, @vertices(0,0));

;// Copy vertex color Data into second half of vertex buffer.
glBufferSubData(#GL_ARRAY_BUFFER, SizeOf(vertices)*VertexCount, SizeOf(colors)*VertexCount, @colors(0,0));

glBufferSubData(#GL_ARRAY_BUFFER, (SizeOf(vertices)+SizeOf(colors))*VertexCount, SizeOf(texture)*VertexCount, @tex(0,0));

glBindBuffer(#GL_ELEMENT_ARRAY_BUFFER, buffer(1));
glBufferData(#GL_ELEMENT_ARRAY_BUFFER, indexSizeInBytes,@MeshDataInd(0),#GL_STATIC_DRAW);

glVertexPointer_(3, #GL_FLOAT, 0, 0);
glColorPointer_(3, #GL_FLOAT, 0, SizeOf(vertices)*VertexCount) ;(GLvoid*)(SizeOf(vertices)))
glTexCoordPointer_(2, #GL_FLOAT, 0,(SizeOf(vertices)+SizeOf(colors))*VertexCount)   

rot.f = 1

;glTranslatef_(0.0, 0.0, -2)
glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
glPointSize_(3)
;7684
;the following is the camera or your eye, 0,2,1 your eys__0,1,0; the object__0,1,0 direction
gluLookAt_( 0, 2, 3,
            0,  0, 0,
            0, 1,  0 )

;gluLookAt_( 0, 10, 30, ; the camera looking from position 0,0.3,0.5  to 0,0,0 from above
 ;           0,  0, 0,
  ;          0,  1,  0 ) 
SetActiveGadget(0) ; make the openGLgadget active so the keyboard can be used with it
;Debug indexSizeInBytes
;glPointSize_(3)
StartTime = ElapsedMilliseconds()
a$ = ".. Up/Down: zoom in/out.... 'A'/'Z': change Camera view"
Repeat
  ;Radius + 0.0001
  ;calculateFPS() ; using glutGet_(#GLUT_ELAPSED_TIME)
  fps$ = Str(FPS(1000))
  SetWindowTitle(0,"FPS  = " +fps$+ "  "+a$)
  ;glClearColor_(0.1, 0.1, 0.5, 1)
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  glRotatef_(rot/2, 0, 1, 0);
  ElapsedTime = ElapsedMilliseconds()-StartTime 
  If ElapsedTime >= 100
    StartTime = ElapsedMilliseconds()
    
    *bufferData.vertices = glMapBuffer(#GL_ARRAY_BUFFER, #GL_WRITE_ONLY);
    *vertexBuffer.vertices = *bufferData ;get the pointer to the vertices positions
    *bufferData + SizeOf(vertices)*VertexCount ; get pointer to the begining of colors section at the end of vertices section
    ;// Randomly change the color values.
    For i=VertexCount To VertexCount*2
      If *vertexBuffer\y > -0.1 And *vertexBuffer\y < 0.3
      *bufferData\x = randF(0,1); here it refers to color not position
      *bufferData\y = randF(0,1)
      *bufferData\z = randF(0,1)
      
      *vertexBuffer\x *1.001
      *vertexBuffer\z  *1.001
      
        ElseIf *vertexBuffer\y > 0.5
      *vertexBuffer\y + 0.002
      EndIf         
      *bufferData + SizeOf(vertices) ; jump to next triple of colors
      *vertexBuffer + SizeOf(vertices)
    Next 
  
    ;// Release the vertex buffer. 
    glUnmapBuffer(#GL_ARRAY_BUFFER);  
  EndIf
  
   glDrawElements_(#GL_POINTS,indexsize,#GL_UNSIGNED_INT,0)
     
  
 Repeat
    event = WindowEvent()
    If event = #PB_Event_CloseWindow
      quit = #True
    EndIf
    If Event = #PB_Event_Gadget And EventGadget() = 0 
    If EventType() = #PB_EventType_KeyDown  ; like KeyboardReleased
            key = GetGadgetAttribute(0,#PB_OpenGL_Key )
            
               If key = #PB_Shortcut_Escape ;  Esc key to exit
               quit = 1
            
               ElseIf Key = #PB_Shortcut_W; display wire Frame or solid frame
               If fill = 0
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_LINE )
                fill ! 1
               Else
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_FILL)
                fill ! 1
              EndIf
              ElseIf Key = #PB_Shortcut_Up
                glScalef_(1.05,1.05,1.05)
              ElseIf Key = #PB_Shortcut_Down
                glScalef_(0.95,0.95,0.95)
              ElseIf Key = #PB_Shortcut_A
                glMatrixMode_(#GL_MODELVIEW);
                glLoadIdentity_()           ;
                ;gluLookAt_(0, 40, 14,  0,0,0,  0,1,0 ) 
                gluLookAt_(0, 5, 1,  0,0,0,  0,1,0 ) 
              ElseIf Key = #PB_Shortcut_Z
               glMatrixMode_(#GL_MODELVIEW);
                glLoadIdentity_();
                ;gluLookAt_(0, 0.3, 0.5,  0,0,0,  0,1,0 )  
                gluLookAt_(0, 3, 5,  0,0,0,  0,1,0 )  
                                
            EndIf
               
    EndIf
   EndIf
  Until event = 0 Or quit = #True
  
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
  
  Delay(1)
Until quit = #True
glDisableClientState_(#GL_TEXTURE_COORD_ARRAY)
glDisableClientState_(#GL_COLOR_ARRAY)
glDisableClientState_(#GL_VERTEX_ARRAY)


  Procedure FillArray()
    ;xMin.f = -2 : yMin.f = -2: zMin.f = -2 : xMax.f = 2: yMax = 2 : zMax = 2
;xMin.f = -1 : yMin.f = -1: zMin.f = -1 : xMax.f = 1: yMax = 1 : zMax = 1
;xMin.f = -0.5 : zMin.f = -0.5 : xMax.f = 0.5: zMax = 0.5
;xMin.f = -30 : yMin.f = -30: zMin.f = -30 : xMax.f = 30: yMax = 30 : zMax = 30
;xMin.f = -12 : yMin.f = -12: zMin.f = -12 : xMax.f = 12: yMax = 12 : zMax = 12
xMin.f = -2 : yMin.f = -2: zMin.f = -2 : xMax.f = 2: yMax = 2 : zMax = 2
;xMin.f = -20 : yMin.f = -20: zMin.f = -20 : xMax.f = 20: yMax = 20 : zMax = 20
;xMin.f = -10 : yMin.f = -10: zMin.f = -10 : xMax.f = 10: yMax = 10 : zMax = 10
;xMin.f = -0.5 : zMin.f = -0.5 : xMax.f = 0.5: zMax = 0.5
  range = xMax - xMin
  step1.f = range / NbX
  x.f = xMin: z.f = zMin : y.f = yMin : v.l = 0
    
  For b=0 To NbZ
   
    For a=0 To NbX
      
      y.f =(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z)) ; Mexican Hat
      ;y.f =5*(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z)) 
      ;y.f = ATan ((z*z*z)/4 - (x*x))
      ;y.f = 1/(15*(x*x+z*z))
      ;y.f = Sin(5*x)*Cos(5*z)/2 ; hills
      ;y.f = 2/Exp((x*5)*(x*5)*(z*5)*(z*5)) ; like '+'
      ;y.f = Log(x*x+z*z)+0.6 ; horn
      ;y.f = Sin(10*(x*x+z*z))/5 ; like waves
      ;y.f = x * x
      ;y.f = 1/(x*x+z*z)
      ;y.f = Cos(x*x+z*z)
      ;y.f = (x*x+z*z)/6
      ;y.f =6*(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z)) 
      ;y.f = Sin(Sqr(x*x+ z*z))*10 / Sqr(x*x + z*z)
      ;y.f = Sin(Sqr(x*x+ z*z))*10 / Sqr(x*x + z*z)
      ;y.f =Sqr(5*5-z*z-x*x); sphere real part; x2 + y2 + z2 = r2
      
      ;**********************************************************************            
      
      vertices(a,b)\x = x*1
      vertices(a,b)\y = y*1 ; just amplify the height
      vertices(a,b)\z = z*1
      
      tex(a,b)\tx = a/NbX
      tex(a,b)\ty = b/NbZ 
      
      If y > 0.5
        colors(a,b)\r = 0.9 :colors(a,b)\g = 0.0 :colors(a,b)\b = 0 
      ElseIf y>=-0.3
        colors(a,b)\r = 0.2 :colors(a,b)\g = 0.9 :colors(a,b)\b = 0 
        Else
        colors(a,b)\r = 1.0 :colors(a,b)\g = 1.0 :colors(a,b)\b = 0 
      EndIf
      
      x.f + step1
      ;Debug x      
    Next a
    
    x = xMin
    z.f + step1
    
  Next b
  
   ;ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
  
  Nb=NbX+1
  
  For b=0 To NbZ-1
    For a=0 To NbX-1
      
      P1=a+(b*Nb)
      P2=P1+1
      P3=a+(b+1)*Nb
      P4=P3+1

      MeshDataInd(indx) = P3
      ReDim MeshDataInd(indx+2)
      MeshDataInd(indx+1) = P4
      ReDim MeshDataInd(indx+3)
      MeshDataInd(indx+2) = P2
      ReDim MeshDataInd(indx+4)
      MeshDataInd(indx+3)= P1;P2
 
      indx+4
    Next
  Next
  indexsize = ArraySize(MeshDataInd()) + 1
  indexSizeInBytes = indexsize * SizeOf(Long)
  ;Debug indexsize
  ;Debug indx
    EndProcedure
   
  Procedure FPS(timer.l) ; the code are from the forum
  Static FPSCount.l, FPS.l
  Static delay.l
  Protected t.l
  If timer = 0
    ProcedureReturn -1
  EndIf
  t = ElapsedMilliseconds()
  If t-delay > timer
    FPS = FPSCount*1000/timer
    FPSCount = 0
    delay = t
  Else
    FPSCount+1
  EndIf
  ProcedureReturn FPS
EndProcedure
VAO: example : equal to SquareAnnulusAndTriangleVAO.CPP in the book

Code: Select all

#GL_ARRAY_BUFFER = $8892
#GL_ELEMENT_ARRAY_BUFFER = $8893
#GL_STATIC_DRAW = $88E4
#GL_DYNAMIC_DRAW = $88E8

Structure vertices
  x.f
  y.f
  z.f
EndStructure

Structure colors
  r.f
  g.f
  b.f
EndStructure

Global Dim vertices1.vertices(7)
Global Dim vertices2.vertices(2)
Global Dim colors1.colors(7)
Global Dim colors2.colors(2)
Global Dim StripIndices.i(9)
Global Dim buffer.i(2)
Global Dim vao.i(2)

Global VERTICES.i = 0
Global INDICES.i = 1
Global ANNULUS.i = 0
Global TRIANGLE.i = 1
Global indexSizeInBytes = 10 * 4; 10 indices * 4 bytes

DataSection
  vertices1:
  Data.f 30,30,0, 10,10,0, 70,30,0, 90,10,0, 70,70,0, 90,90,0, 30,70,0, 10,90,0 ;3D vertices
  colors1:
  Data.f 0,0,0, 1,0,0, 0,1,0, 0,0,1, 1,1,0, 1,0,1, 0,1,1, 1,0,0 ; colors
  indices:
  Data.l 0, 1, 2, 3, 4, 5, 6, 7, 0, 1 ;stripIndices
  vertices2:
  Data.f 40, 40, 0, 60, 40, 0, 60, 60, 0
  colors2:
  Data.f 0, 1, 1, 1, 0, 0, 0, 1, 0
EndDataSection

Restore vertices1
For i=0 To 7: Read.f vertices1(i)\x:Read.f vertices1(i)\y:Read.f vertices1(i)\z: Next
Restore colors1
For i=0 To 7: Read.f colors1(i)\r:Read.f colors1(i)\g:Read.f colors1(i)\b: Next
Restore indices
For i=0 To 9: Read.l StripIndices(i): Next
Restore vertices2
For i=0 To 2: Read.f vertices2(i)\x:Read.f vertices2(i)\y:Read.f vertices2(i)\z: Next
Restore colors2
For i=0 To 2: Read.f colors2(i)\r:Read.f colors2(i)\g:Read.f colors2(i)\b: Next

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), ".. 'W': wire/solid frame... ")
SetWindowColor(0, RGB(200,220,200))
OpenGLGadget(0, 10, 10, WindowWidth(0) , WindowHeight(0) , #PB_OpenGL_Keyboard)

IncludeFile "GLFunctions.pbi"
;IncludeFile "GLEXT.pbi"

;=================================================================================
;=================================================================================

rot.f = 1


glEnable_ (#GL_DEPTH_TEST)   ; Enabled, it slowdown a lot the rendering. It's to be sure than the
                             ; rendered objects are inside the z-buffer.

;glEnable_ (#GL_CULL_FACE)    ; This will enhance the rendering speed as all the back face will be
                             ; ignored. This works only with CLOSED objects like a cube... Singles
                             ; planes surfaces will be visibles only on one side. 

width =600: height = 600
;ini(width, height)
glMatrixMode_(#GL_PROJECTION);
   glLoadIdentity_();
   ;glOrtho2D_(-5, 5.0, -5, 5, -1.0, 1.0);
   ;gluOrtho2D_(0, 100, 0, 100)
   glOrtho_(0.0, 100.0, 0.0, 100.0, -100.0, 100.0);
   ;glOrtho_(-100.0, 100.0, -100.0, 100.0, -100.0, 100.0);
   glMatrixMode_(#GL_MODELVIEW);
   glLoadIdentity_() 
   glViewport_ (0, 0, width, height) ;600,600
;setup()
;==================================

  glClearColor_(1.0, 1.0, 1.0, 0.0); 
  
   glGenVertexArrays(2, @vao(0)); // Generate VAO ids.
   ;// BEGIN bind VAO id vao[ANNULUS] To the set of vertex Array calls following.
   glBindVertexArray(vao(ANNULUS)); 
   
   glGenBuffers( 2, @buffer(0) ) ; // Generate buffer ids.
  
   ;// Enable two vertex arrays: co-ordinates And color.
   glEnableClientState_(#GL_VERTEX_ARRAY);
   glEnableClientState_(#GL_COLOR_ARRAY);

   ;// Bind vertex buffer And reserve space.
   glBindBuffer(#GL_ARRAY_BUFFER, buffer(VERTICES))
   glBufferData(#GL_ARRAY_BUFFER, (SizeOf(vertices) + SizeOf(colors))*8, #Null, #GL_STATIC_DRAW);
   
   ;// Copy vertex coordinates Data into first half of vertex buffer.
   glBufferSubData(#GL_ARRAY_BUFFER, 0, SizeOf(vertices)*8, @vertices1(0));
   
   ;// Copy vertex color Data into second half of vertex buffer.
   glBufferSubData(#GL_ARRAY_BUFFER, SizeOf(vertices)*8, SizeOf(colors)*8, @colors1(0));

   ;// Bind And fill indices buffer.
   glBindBuffer(#GL_ELEMENT_ARRAY_BUFFER, buffer(INDICES))
   glBufferData(#GL_ELEMENT_ARRAY_BUFFER, indexSizeInBytes , @stripIndices(0), #GL_STATIC_DRAW)

   ;// Specify vertex And color pointers To the start of the respective Data.
   glVertexPointer_(3, #GL_FLOAT, 0, 0);
   glColorPointer_(3, #GL_FLOAT, 0, SizeOf(vertices)*8) ; (GLvoid*)(SizeOf(vertices)))
   ;*************************// END bind VAO id vao[ANNULUS].********************
   
   ;// BEGIN bind VAO id vao[TRIANGLE] To the set of vertex Array calls following.
   glBindVertexArray(vao(TRIANGLE));

   glGenBuffers(1, @buffer(VERTICES)); // Generate buffer ids.

   ;// Enable two vertex arrays: co-ordinates And color.
   glEnableClientState_(#GL_VERTEX_ARRAY);
   glEnableClientState_(#GL_COLOR_ARRAY) ;
   
   ;// Bind vertex buffer And reserve space.
   glBindBuffer(#GL_ARRAY_BUFFER, buffer(VERTICES))
   glBufferData(#GL_ARRAY_BUFFER, (SizeOf(vertices) + SizeOf(colors))*3, #Null, #GL_STATIC_DRAW);
   
   ;// Copy vertex coordinates Data into first half of vertex buffer.
   glBufferSubData(#GL_ARRAY_BUFFER, 0, SizeOf(vertices)*3, @vertices2(0));
   
   ;// Copy vertex color Data into second half of vertex buffer.
   glBufferSubData(#GL_ARRAY_BUFFER, SizeOf(vertices)*3, SizeOf(colors)*3, @colors2(0));
   
   ;// Specify vertex And color pointers To the start of the respective Data.
   glVertexPointer_(3, #GL_FLOAT, 0, 0);
   glColorPointer_(3, #GL_FLOAT, 0, SizeOf(vertices)*3) ;(GLvoid*)(SizeOf(vertices)))

   
SetActiveGadget(0) ; make the openGLgadget active so the keyboard can be used with it

Repeat
  ;glClearColor_(0.0, 0.0, 0.0, 1)
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
    
  ;// Draw annulus.
   glBindVertexArray(vao(ANNULUS));
   glDrawElements_(#GL_TRIANGLE_STRIP, 10, #GL_UNSIGNED_INT, 0);

   ;// Draw triangle.
   glBindVertexArray(vao(TRIANGLE))
   glDrawArrays_(#GL_TRIANGLES, 0, 3);
   
     
Repeat
    event = WindowEvent()
    If event = #PB_Event_CloseWindow
      quit = #True
    EndIf
    If event = #PB_Event_Gadget And EventGadget() = 0 
    If EventType() = #PB_EventType_KeyDown  ; like KeyboardReleased
            key = GetGadgetAttribute(0,#PB_OpenGL_Key )
            
               If key = #PB_Shortcut_Escape ;  Esc key to exit
               quit = 1
            
               ElseIf Key = #PB_Shortcut_W; display wire Frame or solid frame
               If fill = 0
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_LINE )
                fill ! 1
               Else
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_FILL)
                fill ! 1
              EndIf
            EndIf
                        
               
    EndIf
   EndIf
  Until event = 0 Or quit = #True
  
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
  
  Delay(5)
Until quit = #True
glDisableClientState_(#GL_VERTEX_ARRAY);
glDisableClientState_(#GL_COLOR_ARRAY)

2D Plotting with VBO example:

Code: Select all

#GL_ARRAY_BUFFER = $8892
#GL_ELEMENT_ARRAY_BUFFER = $8893
#GL_STATIC_DRAW = $88E4
#GL_DYNAMIC_DRAW = $88E8

Structure vertices
  x.f
  y.f
  z.f
EndStructure

Structure colors
  r.f
  g.f
  b.f
EndStructure

Declare FillArray()
Define event, quit

OpenWindow(0, 10, 10, 800, 600, "OpenGL demo")
SetWindowColor(0, RGB(200,220,200))
OpenGLGadget(0, 20, 10, WindowWidth(0)-10 , WindowHeight(0)-10)

IncludeFile "GLFunctions.pbi"
;IncludeFile "GLEXT.pbi"

Global Dim Vertex.vertices(0)
Global Dim colorData.colors(0)
Global Dim index(0)
Global indexCount, indexsize
 

 glClearColor_(1.0, 1.0, 1.0, 1.0);
    glShadeModel_(#GL_SMOOTH);

    glMatrixMode_(#GL_PROJECTION);
    glLoadIdentity_();
    gluPerspective_(45.0, 800.0 / 600.0, 0.1, 100.0);

    glMatrixMode_(#GL_MODELVIEW);
    glLoadIdentity_();
    glTranslatef_(0.0, 0.0,-4.0);

    Global vbo.i,vbcol.i, vao.i, VertexCount.i = 5000
        
    FillArray()
 
;=================================================================================
;=================================================================================
glGenBuffers( 1, @vbo ) ; Vertex Buffer Object
glBindBuffer(#GL_ARRAY_BUFFER, vbo )
glBufferData(#GL_ARRAY_BUFFER,SizeOf(vertices)*VertexCount,@vertex(0), #GL_STATIC_DRAW)
glVertexPointer_(3, #GL_FLOAT,0,0)

glGenBuffers( 1, @vbcol );  Vertex Attribute Object
glBindBuffer(#GL_ARRAY_BUFFER, vbcol);
glBufferData(#GL_ARRAY_BUFFER, SizeOf(colors)*VertexCount,@colorData(0),#GL_STATIC_DRAW);
glColorPointer_(3, #GL_FLOAT, 0,0)

glGenBuffers( 1, @indx );  Vertex Attribute Object
glBindBuffer(#GL_ELEMENT_ARRAY_BUFFER, indx);
glBufferData(#GL_ELEMENT_ARRAY_BUFFER, VertexCount*4,@index(0),#GL_STATIC_DRAW);

glViewport_(0, 0, WindowWidth(0), WindowHeight(0))

glTranslatef_(0.0, 0.0, -2)
glPointSize_(2)
glLineWidth_(3)

rot.f = 1
Repeat

glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)

glRotatef_(rot/2, 0, 0, 1);
  
glEnableClientState_(#GL_VERTEX_ARRAY )
glEnableClientState_(#GL_COLOR_ARRAY)

;glDrawElements_(#GL_POINTS,indexCount,#GL_UNSIGNED_INT,0)
;glDrawElements_(#GL_LINES,indexCount,#GL_UNSIGNED_INT,0)
glDrawElements_(#GL_LINE_STRIP,indexCount,#GL_UNSIGNED_INT,0)

glDisableClientState_(#GL_COLOR_ARRAY)
glDisableClientState_(#GL_VERTEX_ARRAY)
  
  
 Repeat
    event = WindowEvent()
    If event = #PB_Event_CloseWindow
      quit = #True
    EndIf
  Until event = 0 Or quit = #True
  
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
  
  Delay(10)
Until quit = #True


Procedure FillArray()
  
  Protected.f x, y, z, t

  While t <= 2*#PI
  x.f = Cos(t) - Cos(6* t)/2 + Sin(14* t)/3
  y.f = Cos(14* t)/3 + Sin(t)- Sin(6* t)/2 
  z.f = 0
  
  ReDim vertex.vertices(a)
  vertex(a)\x = x
  vertex(a)\y = y
  vertex(a)\z = z

  ReDim colorData.colors(a)
  
  colorData(a)\r = Sin(t) :colorData(a)\g = Cos(t) :colorData(a)\b = 1
  a+1
  VertexCount = a
      
  ReDim index(a)
  index(a)=a
  indexCount = VertexCount ; it is not neccessary indexCount = VertexCount ;just in this shape         
       
  t + 0.005
      
  Wend

  
  indexsize = ArraySize(index())
  
EndProcedure
    
  
ref:
(1): download the full source code in c++ free from here
http://www.sumantaguha.com/downloads
(2) if you need other constants look luis include file here http://www.purebasic.fr/english/viewtop ... 87#p348385
or download it http://wikisend.com/download/107934/GLEXT.rar
Last edited by applePi on Wed Mar 07, 2018 8:25 pm, edited 4 times in total.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: more Graphics with OpenGLGadget

Post by IdeasVacuum »

Excellent work applePi 8)
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5345
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: more Graphics with OpenGLGadget

Post by Kwai chang caine »

Work nice in W7 v5.50 X86
Thanks ApplePI 8)
ImageThe happiness is a road...
Not a destination
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: more Graphics with OpenGLGadget

Post by applePi »

Thank you IdeasVacuum and Kwai chang caine
i have corrected some misleading comments and variables names in vbo example_1
in fact i am new to this subject, and i do experiments. it is too deep and vast subject, so i choose only parts of it. this is again example vbo_1 but trying to have insight about the buffer addresses. i want in example 1 to access the vertex positions buffer and the colors buffer and the texture buffer. and then to change its values, first we need every buffer address:

Code: Select all

glBindBuffer(#GL_ARRAY_BUFFER, vbo) ; vertex pos buffer
    *vertexBuffer.vertices = glMapBuffer(#GL_ARRAY_BUFFER, #GL_WRITE_ONLY);
    ;// Release the vertex buffer. 
    glUnmapBuffer(#GL_ARRAY_BUFFER);  
    glBindBuffer(#GL_ARRAY_BUFFER, vbcol) ; color buffer
    *colorBuffer.colors = glMapBuffer(#GL_ARRAY_BUFFER, #GL_WRITE_ONLY);
     ;// Release the color buffer. 
    glUnmapBuffer(#GL_ARRAY_BUFFER); 
    glBindBuffer(#GL_ARRAY_BUFFER, vbtex) ; texture buffer
    *textureBuffer.texture = glMapBuffer(#GL_ARRAY_BUFFER, #GL_WRITE_ONLY);
     ;// Release the texture buffer. 
    glUnmapBuffer(#GL_ARRAY_BUFFER)
(still don't convinced how glMapBuffer works and is it really return the address in GPU memory or something else ??)
once we catch the addresses of every buffer (whatever it is) we go to change it :
the top of the Hill grow until it resembles a mushroom:

Code: Select all

For i=0 To VertexCount
      If *vertexBuffer\y > 0.5 ;-0.1 And *vertexBuffer\y < 0.3
      
      *vertexBuffer\x *1.01
      *vertexBuffer\z  *1.01
      *vertexBuffer\y + 0.02
      *colorBuffer\r = 1
      *colorBuffer\g = 0.5
      *colorBuffer\b = 0
      *textureBuffer\tx = Sin(*textureBuffer\tx) ;randF(0,1)
      *textureBuffer\ty = Sin(*textureBuffer\ty) ;randF(0,1)
      EndIf         
      
      *vertexBuffer + SizeOf(vertices) 
      *colorBuffer + SizeOf(colors) ; jump to next triple of colors
      *textureBuffer + SizeOf(texture)
    Next 
the full code if vbo_example_1 deformed and animated
needs include file GLFunctions.PBI in the top of this page

Code: Select all

Procedure.f RandF(Min.f, Max.f, Resolution.i = 10000)
  ProcedureReturn (Min + (Max - Min) * Random(Resolution) / Resolution)
EndProcedure
#GL_ARRAY_BUFFER = $8892
#GL_ELEMENT_ARRAY_BUFFER = $8893
#GL_STATIC_DRAW = $88E4
#GL_DYNAMIC_DRAW = $88E8
#GL_WRITE_ONLY = $88B9
#GL_READ_WRITE = $88BA


Structure vertices
  x.f
  y.f
  z.f
EndStructure

Structure Colors
  r.f
  g.f
  b.f
EndStructure

Structure texture
  tx.f
  ty.f

EndStructure


Declare FPS(timer.l)
Declare FillArray()

UseJPEGImageDecoder()
UsePNGImageDecoder()

Declare FillArray()

Define event, quit

#ImagePath = #PB_Compiler_Home + "examples/3d/Data/Textures/"
LoadImage(1, #ImagePath+"MRAMOR6X6.jpg") ;ValetCoeur.jpg")
*Buffer = EncodeImage(1)
        
Define event, quit

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), ".. Up/Down: zoom in/out... 'W': wire frame... 'A'/'Z': change Camera view")
SetWindowColor(0, RGB(200,220,200))
OpenGLGadget(0, 10, 10, WindowWidth(0) , WindowHeight(0) , #PB_OpenGL_Keyboard)

;IncludeFile #PB_Compiler_Home + "Examples\Sources - Advanced\OpenGL Cube\OpenGL.pbi"
IncludeFile "GLFunctions.pbi"
;IncludeFile "GLEXT.pbi"


glMatrixMode_(#GL_PROJECTION)
glLoadIdentity_();
gluPerspective_(45.0, 800/600, 1.0, 60.0)
glMatrixMode_(#GL_MODELVIEW)
glTranslatef_(0, 0, -5)
glShadeModel_(#GL_SMOOTH) 
glEnable_(#GL_DEPTH_TEST)
;glEnable_(#GL_CULL_FACE) 
glColor3f_(1.0, 0.3, 0.0)
glViewport_(0, 0, 800, 600)

;resolution of the graphics grid
Global NbX=300
Global NbZ=300

Global VertexCount = (NbX+1)*(NbZ+1)
Global vbo.i, indexBuffer.i, vbcol.i, vbtex.i, TexID.i
;Global vbo.i(2)

Global Dim vertices.vertices(NbX,NbZ)
Global Dim colors.Colors(NbX,NbZ)
Global Dim tex.texture(NbX,NbZ)
Global Dim MeshDataInd(0)


glGenTextures_(1, @TexID)
glBindTexture_(#GL_TEXTURE_2D, TexID)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
glTexImage2D_(#GL_TEXTURE_2D, 0, 3, ImageWidth(1), ImageHeight(1), 0, #GL_BGR_EXT, #GL_UNSIGNED_BYTE, *Buffer+57)

FreeMemory(*Buffer)

glEnable_(#GL_TEXTURE_2D)   ; Enable texture mapping 
glBindTexture_(#GL_TEXTURE_2D, TexID) ; use texture number 1

Global indexsize
Global indexSizeInBytes

FillArray()

;wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww

glGenBuffers( 2, @vbo ) ; Vertex Buffer Object
glBindBuffer(#GL_ARRAY_BUFFER, vbo )
glBufferData(#GL_ARRAY_BUFFER,SizeOf(vertices)*VertexCount,@vertices(0,0), #GL_STATIC_DRAW)
glVertexPointer_(3, #GL_FLOAT,0,0)

glGenBuffers( 1, @vbcol );  color buffer
glBindBuffer(#GL_ARRAY_BUFFER, vbcol);
glBufferData(#GL_ARRAY_BUFFER, SizeOf(Colors)*VertexCount,@colors(0,0),#GL_STATIC_DRAW);
glColorPointer_(3, #GL_FLOAT, 0, 0)

glGenBuffers( 1, @vbtex );  texture buffer
glBindBuffer(#GL_ARRAY_BUFFER, vbtex);
glBufferData(#GL_ARRAY_BUFFER, SizeOf(texture)*VertexCount,@tex(0,0),#GL_STATIC_DRAW);
;glTexCoordPointer_(2, #GL_FLOAT, SizeOf(texture), @tex(0,0)\tx)
glTexCoordPointer_(2, #GL_FLOAT, 0,0)

glGenBuffers( 1, @indexBuffer );  
glBindBuffer(#GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(#GL_ELEMENT_ARRAY_BUFFER, indexSizeInBytes,@MeshDataInd(0),#GL_STATIC_DRAW);

rot.f = 1

;glTranslatef_(0.0, 0.0, -2)
glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
glPointSize_(3)

;the following is the camera or your eye, 0,2,3 your eyes__ 0,0,0; the object__ 0,1,0 direction
gluLookAt_( 0, 2, 3,
            0,  0, 0,
            0, 1,  0 )

;gluLookAt_( 0, 10, 30, ; the camera looking from position 0,10.30  to 0,0,0 from above
 ;           0,  0, 0,
  ;          0,  1,  0 ) 
SetActiveGadget(0) ; make the openGLgadget active so the keyboard can be used with it

glEnableClientState_(#GL_VERTEX_ARRAY )
  glEnableClientState_(#GL_COLOR_ARRAY)
  glEnableClientState_(#GL_TEXTURE_COORD_ARRAY)
  
a$=".. Up/Down: zoom in/out... 'W': wire frame... 'A'/'Z': change Camera view"  
  
Repeat
  
  fps$ = Str(FPS(1000))
  SetWindowTitle(0,"FPS  = " +fps$+ "  "+a$)
  ;glClearColor_(0.1, 0.1, 0.5, 1)
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  glRotatef_(rot/2, 0, 1, 0);
  ElapsedTime = ElapsedMilliseconds()-StartTime 
  If ElapsedTime >= 200
    StartTime = ElapsedMilliseconds()
    glBindBuffer(#GL_ARRAY_BUFFER, vbo) ; vertex pos buffer
    *vertexBuffer.vertices = glMapBuffer(#GL_ARRAY_BUFFER, #GL_WRITE_ONLY);
    ;// Release the vertex buffer. 
    glUnmapBuffer(#GL_ARRAY_BUFFER);  
    glBindBuffer(#GL_ARRAY_BUFFER, vbcol) ; color buffer
    *colorBuffer.colors = glMapBuffer(#GL_ARRAY_BUFFER, #GL_WRITE_ONLY);
     ;// Release the color buffer. 
    glUnmapBuffer(#GL_ARRAY_BUFFER); 
    glBindBuffer(#GL_ARRAY_BUFFER, vbtex) ; texture buffer
    *textureBuffer.texture = glMapBuffer(#GL_ARRAY_BUFFER, #GL_WRITE_ONLY);
     ;// Release the texture buffer. 
    glUnmapBuffer(#GL_ARRAY_BUFFER)
    
    ;// change the vertex positions and color values.
    For i=0 To VertexCount
      If *vertexBuffer\y > 0.5 ;-0.1 And *vertexBuffer\y < 0.3
      
      *vertexBuffer\x *1.01
      *vertexBuffer\z  *1.01
      *vertexBuffer\y + 0.02
      *colorBuffer\r = 1
      *colorBuffer\g = 0.5
      *colorBuffer\b = 0
      *textureBuffer\tx = Sin(*textureBuffer\tx) ;randF(0,1)
      *textureBuffer\ty = Sin(*textureBuffer\ty) ;randF(0,1)
      EndIf         
      
      *vertexBuffer + SizeOf(vertices) 
      *colorBuffer + SizeOf(colors) ; jump to next triple of colors
      *textureBuffer + SizeOf(texture)
    Next 
 
  EndIf
  ;glPointSize_(2)
  glDrawElements_(#GL_QUADS,indexsize,#GL_UNSIGNED_INT,0)
  ;glDrawElements_(#GL_POINTS,indexsize,#GL_UNSIGNED_INT,0)
  
  
 Repeat
    event = WindowEvent()
    If event = #PB_Event_CloseWindow
      quit = #True
    EndIf
    If Event = #PB_Event_Gadget And EventGadget() = 0 
    If EventType() = #PB_EventType_KeyDown  ; like KeyboardReleased
            key = GetGadgetAttribute(0,#PB_OpenGL_Key )
            
               If key = #PB_Shortcut_Escape ;  Esc key to exit
               quit = 1
            
               ElseIf Key = #PB_Shortcut_W; display wire Frame or solid frame
               If fill = 0
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_LINE )
                fill ! 1
               Else
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_FILL)
                fill ! 1
              EndIf
              ElseIf Key = #PB_Shortcut_Up
                glScalef_(1.05,1.05,1.05)
              ElseIf Key = #PB_Shortcut_Down
                glScalef_(0.95,0.95,0.95)
              ElseIf Key = #PB_Shortcut_A
                glMatrixMode_(#GL_MODELVIEW);
                glLoadIdentity_()           ;
                ;gluLookAt_(0, 40, 14,  0,0,0,  0,1,0 ) 
                gluLookAt_(0, 5, 1,  0,0,0,  0,1,0 ) 
              ElseIf Key = #PB_Shortcut_Z
               glMatrixMode_(#GL_MODELVIEW);
                glLoadIdentity_();
                ;gluLookAt_(0, 0.3, 0.5,  0,0,0,  0,1,0 )  
                gluLookAt_(0, 3, 5,  0,0,0,  0,1,0 )  
                                
            EndIf
               
    EndIf
   EndIf
  Until event = 0 Or quit = #True
  
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
  
  Delay(1)
Until quit = #True
glDisableClientState_(#GL_TEXTURE_COORD_ARRAY)
  glDisableClientState_(#GL_COLOR_ARRAY)
  glDisableClientState_(#GL_VERTEX_ARRAY)

  
  Procedure FillArray()
 
;xMin.f = -1 : yMin.f = -1: zMin.f = -1 : xMax.f = 1: yMax = 1 : zMax = 1
;xMin.f = -0.5 : zMin.f = -0.5 : xMax.f = 0.5: zMax = 0.5
;xMin.f = -30 : yMin.f = -30: zMin.f = -30 : xMax.f = 30: yMax = 30 : zMax = 30
;xMin.f = -12 : yMin.f = -12: zMin.f = -12 : xMax.f = 12: yMax = 12 : zMax = 12
xMin.f = -2 : yMin.f = -2: zMin.f = -2 : xMax.f = 2: yMax = 2 : zMax = 2
;xMin.f = -20 : yMin.f = -20: zMin.f = -20 : xMax.f = 20: yMax = 20 : zMax = 20
;xMin.f = -10 : yMin.f = -10: zMin.f = -10 : xMax.f = 10: yMax = 10 : zMax = 10
;xMin.f = -0.5 : zMin.f = -0.5 : xMax.f = 0.5: zMax = 0.5
  range = xMax - xMin
  step1.f = range / NbX
  x.f = xMin: z.f = zMin : y.f = yMin : v.l = 0
    
  For b=0 To NbZ
   
    For a=0 To NbX
      
      y.f =(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z)) ; Mexican Hat
      ;y.f =5*(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z)) 
      ;y.f = ATan ((z*z*z)/4 - (x*x))
      ;y.f = 1/(15*(x*x+z*z))
      ;y.f = Sin(5*x)*Cos(5*z)/2 ; hills
      ;y.f = 2/Exp((x*5)*(x*5)*(z*5)*(z*5)) ; like '+'
      ;y.f = Log(x*x+z*z)+0.6 ; horn
      ;y.f = Sin(10*(x*x+z*z))/5 ; like waves
      ;y.f = x * x
      ;y.f = 1/(x*x+z*z)
      ;y.f = Cos(x*x+z*z)
      ;y.f = (x*x+z*z)/6
      ;y.f =6*(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z)) 
      ;y.f = Sin(Sqr(x*x+ z*z))*10 / Sqr(x*x + z*z)
      ;y.f = Sin(Sqr(x*x+ z*z))*10 / Sqr(x*x + z*z)
      ;y.f =Sqr(5*5-z*z-x*x); sphere real part; x2 + y2 + z2 = r2
      
      ;**********************************************************************            
      
      vertices(a,b)\x = x*1
      vertices(a,b)\y = y*1 ; just amplify the height
      vertices(a,b)\z = z*1
      
      tex(a,b)\tx = a/NbX
      tex(a,b)\ty = b/NbZ 
      
      If y > 0.5
        colors(a,b)\r = 0.9 :colors(a,b)\g = 0.0 :colors(a,b)\b = 0 
      ElseIf y>=-0.3
        colors(a,b)\r = 0.2 :colors(a,b)\g = 0.9 :colors(a,b)\b = 0 
        Else
        colors(a,b)\r = 1.0 :colors(a,b)\g = 1.0 :colors(a,b)\b = 0 
      EndIf
      
      x.f + step1
      ;Debug x      
    Next a
    
    x = xMin
    z.f + step1
    
  Next b
  
   ;ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
  
  Nb=NbX+1
  
  For b=0 To NbZ-1
    For a=0 To NbX-1
      
      P1=a+(b*Nb)
      P2=P1+1
      P3=a+(b+1)*Nb
      P4=P3+1

      MeshDataInd(indx) = P3
      ReDim MeshDataInd(indx+2)
      MeshDataInd(indx+1) = P4
      ReDim MeshDataInd(indx+3)
      MeshDataInd(indx+2) = P2
      ReDim MeshDataInd(indx+4)
      MeshDataInd(indx+3)= P1;P2
 
      indx+4
    Next
  Next
  indexsize = ArraySize(MeshDataInd()) + 1
  indexSizeInBytes = indexsize * SizeOf(Long)
  
EndProcedure

Procedure FPS(timer.l) ; the code are from the forum somewhere
  Static FPSCount.l, FPS.l
  Static delay.l
  Protected t.l
  If timer = 0
    ProcedureReturn -1
  EndIf
  t = ElapsedMilliseconds()
  If t-delay > timer
    FPS = FPSCount*1000/timer
    FPSCount = 0
    delay = t
  Else
    FPSCount+1
  EndIf
  ProcedureReturn FPS
EndProcedure
   
in line 186 change #GL_QUADS to #GL_POINTS and see how it looks like
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: more Graphics with OpenGLGadget

Post by Samuel »

Nice example applePi. 8)
applePi wrote:still don't convinced how glMapBuffer works and is it really return the address in GPU memory or something else ??
Yes, glMapBuffers returns a pointer to the location in memory where your Buffer Object is stored.

I made a few changes to your example from your most recent post.

1.Instead of using a buffer object for vertex location, color, and texture coordinates. I combined them into a single buffer which is faster for the GPU to handle. There is still a separate buffer object for the indexes. To do this all you have to do is create a single structure that contains all the required data (x,y,z,r,g,b,tx,ty) and then set the appropriate offset and stride in the gl.....Pointer calls.

2.I set the vertex buffer object to #GL_STREAM_DRAW. You could also use #GL_DYNAMIC_DRAW, but I wouldn't recommend using #GL_STATIC_DRAW since your buffer is being updated every 200 milliseconds. The index buffer can remain static since it is not being updated.

3.When accessing a buffer make sure you use the appropriate access policy. In your repeat/until when updating your buffer you were using #GL_WRITE_ONLY, but the problem was you were also reading from the buffer when you compared the y value. So, glMapBuffer needed to be set to #GL_READ_WRITE otherwise you can get memory access errors/crashes.

Here's your updated example.

Code: Select all

Procedure.f RandF(Min.f, Max.f, Resolution.i = 10000)
  ProcedureReturn (Min + (Max - Min) * Random(Resolution) / Resolution)
EndProcedure

#GL_ARRAY_BUFFER = $8892
#GL_ELEMENT_ARRAY_BUFFER = $8893
#GL_STATIC_DRAW = $88E4
#GL_DYNAMIC_DRAW = $88E8
#GL_STREAM_DRAW = $88E0
#GL_WRITE_ONLY = $88B9
#GL_READ_WRITE = $88BA

Structure VertexData
  x.f
  y.f
  z.f
  r.f
  g.f
  b.f
  tx.f
  ty.f
EndStructure


Declare FPS(timer.l)
Declare FillArray()

UseJPEGImageDecoder()
UsePNGImageDecoder()

Declare FillArray()

Define event, quit

#ImagePath = #PB_Compiler_Home + "examples/3d/Data/Textures/"
LoadImage(1, #ImagePath+"MRAMOR6X6.jpg") ;ValetCoeur.jpg")
*Buffer = EncodeImage(1)
       
Define event, quit

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), ".. Up/Down: zoom in/out... 'W': wire frame... 'A'/'Z': change Camera view")
SetWindowColor(0, RGB(200,220,200))
OpenGLGadget(0, 10, 10, WindowWidth(0) , WindowHeight(0) , #PB_OpenGL_Keyboard)

;IncludeFile #PB_Compiler_Home + "Examples\Sources - Advanced\OpenGL Cube\OpenGL.pbi"
IncludeFile "GLFunctions.pbi"
;IncludeFile "GLEXT.pbi"


glMatrixMode_(#GL_PROJECTION)
glLoadIdentity_();
gluPerspective_(45.0, 800/600, 1.0, 60.0)
glMatrixMode_(#GL_MODELVIEW)
glTranslatef_(0, 0, -5)
glShadeModel_(#GL_SMOOTH)
glEnable_(#GL_DEPTH_TEST)
;glEnable_(#GL_CULL_FACE)
glColor3f_(1.0, 0.3, 0.0)
glViewport_(0, 0, 800, 600)

;resolution of the graphics grid
Global NbX=300
Global NbZ=300

Global VertexCount = (NbX+1)*(NbZ+1)
Global vbo.i, indexBuffer.i, vbcol.i, vbtex.i, TexID.i
;Global vbo.i(2)

Global Dim vertices.VertexData(NbX,NbZ)
Global Dim MeshDataInd(0)


glGenTextures_(1, @TexID)
glBindTexture_(#GL_TEXTURE_2D, TexID)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
glTexImage2D_(#GL_TEXTURE_2D, 0, 3, ImageWidth(1), ImageHeight(1), 0, #GL_BGR_EXT, #GL_UNSIGNED_BYTE, *Buffer+57)

FreeMemory(*Buffer)

glEnable_(#GL_TEXTURE_2D)   ; Enable texture mapping
glBindTexture_(#GL_TEXTURE_2D, TexID) ; use texture number 1

Global indexsize
Global indexSizeInBytes

FillArray()

;wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww

glGenBuffers(1, @vbo) ;Vertex Buffer Object
glBindBuffer(#GL_ARRAY_BUFFER, vbo)
;Changed the buffer type to stream since the entire buffer is being updated often.
glBufferData(#GL_ARRAY_BUFFER, SizeOf(VertexData)*VertexCount, @vertices(0,0), #GL_STREAM_DRAW)
glVertexPointer_(3, #GL_FLOAT, SizeOf(VertexData), 0) ;Vertex data is at the start of our structure VertexData
glColorPointer_(3, #GL_FLOAT, SizeOf(VertexData), 12) ;The color data is 12 bytes below the start
glTexCoordPointer_(2, #GL_FLOAT, SizeOf(VertexData), 24) ;The texture data is 12 bytes below the color start

glGenBuffers(1, @indexBuffer) ;Index Buffer Object
glBindBuffer(#GL_ELEMENT_ARRAY_BUFFER, indexBuffer)
;This buffer stays the same so it can remain a static buffer.
glBufferData(#GL_ELEMENT_ARRAY_BUFFER, indexSizeInBytes, @MeshDataInd(0), #GL_STATIC_DRAW)

rot.f = 1

;glTranslatef_(0.0, 0.0, -2)
glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
glPointSize_(3)

;the following is the camera or your eye, 0,2,3 your eyes__ 0,0,0; the object__ 0,1,0 direction
gluLookAt_( 0, 2, 3,
            0,  0, 0,
            0, 1,  0 )

;gluLookAt_( 0, 10, 30, ; the camera looking from position 0,10.30  to 0,0,0 from above
 ;           0,  0, 0,
  ;          0,  1,  0 )
SetActiveGadget(0) ; make the openGLgadget active so the keyboard can be used with it

glEnableClientState_(#GL_VERTEX_ARRAY )
  glEnableClientState_(#GL_COLOR_ARRAY)
  glEnableClientState_(#GL_TEXTURE_COORD_ARRAY)
 
a$=".. Up/Down: zoom in/out... 'W': wire frame... 'A'/'Z': change Camera view" 
 
Repeat
 
  fps$ = Str(FPS(1000))
  SetWindowTitle(0,"FPS  = " +fps$+ "  "+a$)
  ;glClearColor_(0.1, 0.1, 0.5, 1)
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  glRotatef_(rot/2, 0, 1, 0);
  ElapsedTime = ElapsedMilliseconds()-StartTime
  If ElapsedTime >= 200
    StartTime = ElapsedMilliseconds()
    glBindBuffer(#GL_ARRAY_BUFFER, vbo) ;vertex pos buffer
    ;Should not use #GL_WRITE_ONLY because you are also reading from the data when checking if *vertexBuffer\y > 0.5.
    ;Changed to #GL_READ_WRITE.
    *vertexBuffer.VertexData = glMapBuffer(#GL_ARRAY_BUFFER, #GL_READ_WRITE)
    ;// change the vertex positions and color values.
    For i=0 To VertexCount
      If *vertexBuffer\y > 0.5 ;-0.1 And *vertexBuffer\y < 0.3
        *vertexBuffer\x * 1.01
        *vertexBuffer\z * 1.01
        *vertexBuffer\y + 0.02
        *vertexBuffer\r = 1
        *vertexBuffer\g = 0.5
        *vertexBuffer\b = 0
        *vertexBuffer\tx = Sin(*vertexBuffer\tx) ;randF(0,1)
        *vertexBuffer\ty = Sin(*vertexBuffer\ty) ;randF(0,1)
      EndIf
      *vertexBuffer + SizeOf(VertexData)
    Next
    
    ;// Release the vertex buffer.
    glUnmapBuffer(#GL_ARRAY_BUFFER); 
  EndIf
  ;glPointSize_(2)
  glDrawElements_(#GL_QUADS, indexsize, #GL_UNSIGNED_INT, 0)
  ;glDrawElements_(#GL_POINTS,indexsize,#GL_UNSIGNED_INT,0)
 
 
 Repeat
    event = WindowEvent()
    If event = #PB_Event_CloseWindow
      quit = #True
    EndIf
    If Event = #PB_Event_Gadget And EventGadget() = 0
    If EventType() = #PB_EventType_KeyDown  ; like KeyboardReleased
            key = GetGadgetAttribute(0,#PB_OpenGL_Key )
           
               If key = #PB_Shortcut_Escape ;  Esc key to exit
               quit = 1
           
               ElseIf Key = #PB_Shortcut_W; display wire Frame or solid frame
               If fill = 0
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_LINE )
                fill ! 1
               Else
                glPolygonMode_(#GL_FRONT_AND_BACK, #GL_FILL)
                fill ! 1
              EndIf
              ElseIf Key = #PB_Shortcut_Up
                glScalef_(1.05,1.05,1.05)
              ElseIf Key = #PB_Shortcut_Down
                glScalef_(0.95,0.95,0.95)
              ElseIf Key = #PB_Shortcut_A
                glMatrixMode_(#GL_MODELVIEW);
                glLoadIdentity_()           ;
                ;gluLookAt_(0, 40, 14,  0,0,0,  0,1,0 )
                gluLookAt_(0, 5, 1,  0,0,0,  0,1,0 )
              ElseIf Key = #PB_Shortcut_Z
               glMatrixMode_(#GL_MODELVIEW);
                glLoadIdentity_();
                ;gluLookAt_(0, 0.3, 0.5,  0,0,0,  0,1,0 ) 
                gluLookAt_(0, 3, 5,  0,0,0,  0,1,0 ) 
                               
            EndIf
               
    EndIf
   EndIf
  Until event = 0 Or quit = #True
 
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
 
  Delay(1)
Until quit = #True
glDisableClientState_(#GL_TEXTURE_COORD_ARRAY)
  glDisableClientState_(#GL_COLOR_ARRAY)
  glDisableClientState_(#GL_VERTEX_ARRAY)

 
Procedure FillArray()
 
;xMin.f = -1 : yMin.f = -1: zMin.f = -1 : xMax.f = 1: yMax = 1 : zMax = 1
;xMin.f = -0.5 : zMin.f = -0.5 : xMax.f = 0.5: zMax = 0.5
;xMin.f = -30 : yMin.f = -30: zMin.f = -30 : xMax.f = 30: yMax = 30 : zMax = 30
;xMin.f = -12 : yMin.f = -12: zMin.f = -12 : xMax.f = 12: yMax = 12 : zMax = 12
xMin.f = -2 : yMin.f = -2: zMin.f = -2 : xMax.f = 2: yMax = 2 : zMax = 2
;xMin.f = -20 : yMin.f = -20: zMin.f = -20 : xMax.f = 20: yMax = 20 : zMax = 20
;xMin.f = -10 : yMin.f = -10: zMin.f = -10 : xMax.f = 10: yMax = 10 : zMax = 10
;xMin.f = -0.5 : zMin.f = -0.5 : xMax.f = 0.5: zMax = 0.5
  range = xMax - xMin
  step1.f = range / NbX
  x.f = xMin: z.f = zMin : y.f = yMin : v.l = 0
   
  For b=0 To NbZ
   
    For a=0 To NbX
     
      y.f =(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z)) ; Mexican Hat
      ;y.f =5*(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z))
      ;y.f = ATan ((z*z*z)/4 - (x*x))
      ;y.f = 1/(15*(x*x+z*z))
      ;y.f = Sin(5*x)*Cos(5*z)/2 ; hills
      ;y.f = 2/Exp((x*5)*(x*5)*(z*5)*(z*5)) ; like '+'
      ;y.f = Log(x*x+z*z)+0.6 ; horn
      ;y.f = Sin(10*(x*x+z*z))/5 ; like waves
      ;y.f = x * x
      ;y.f = 1/(x*x+z*z)
      ;y.f = Cos(x*x+z*z)
      ;y.f = (x*x+z*z)/6
      ;y.f =6*(1 - x*x -z*z) * Exp(-1/2 * (x*x + z*z))
      ;y.f = Sin(Sqr(x*x+ z*z))*10 / Sqr(x*x + z*z)
      ;y.f = Sin(Sqr(x*x+ z*z))*10 / Sqr(x*x + z*z)
      ;y.f =Sqr(5*5-z*z-x*x); sphere real part; x2 + y2 + z2 = r2
     
      ;**********************************************************************           
     
      vertices(a,b)\x = x*1
      vertices(a,b)\y = y*1 ; just amplify the height
      vertices(a,b)\z = z*1
     
      vertices(a,b)\tx = a/NbX
      vertices(a,b)\ty = b/NbZ
     
      If y > 0.5
        vertices(a,b)\r = 0.9 :vertices(a,b)\g = 0.0 :vertices(a,b)\b = 0
      ElseIf y>=-0.3
        vertices(a,b)\r = 0.2 :vertices(a,b)\g = 0.9 :vertices(a,b)\b = 0
        Else
        vertices(a,b)\r = 1.0 :vertices(a,b)\g = 1.0 :vertices(a,b)\b = 0
      EndIf
     
      x.f + step1
      ;Debug x     
    Next a
   
    x = xMin
    z.f + step1
   
  Next b
 
   ;ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
 
  Nb=NbX+1
 
  For b=0 To NbZ-1
    For a=0 To NbX-1
     
      P1=a+(b*Nb)
      P2=P1+1
      P3=a+(b+1)*Nb
      P4=P3+1

      MeshDataInd(indx) = P3
      ReDim MeshDataInd(indx+2)
      MeshDataInd(indx+1) = P4
      ReDim MeshDataInd(indx+3)
      MeshDataInd(indx+2) = P2
      ReDim MeshDataInd(indx+4)
      MeshDataInd(indx+3)= P1;P2
 
      indx+4
    Next
  Next
  indexsize = ArraySize(MeshDataInd()) + 1
  indexSizeInBytes = indexsize * SizeOf(Long)
 
EndProcedure

Procedure FPS(timer.l) ; the code are from the forum somewhere
  Static FPSCount.l, FPS.l
  Static delay.l
  Protected t.l
  If timer = 0
    ProcedureReturn -1
  EndIf
  t = ElapsedMilliseconds()
  If t-delay > timer
    FPS = FPSCount*1000/timer
    FPSCount = 0
    delay = t
  Else
    FPSCount+1
  EndIf
  ProcedureReturn FPS
EndProcedure
User avatar
Comtois
Addict
Addict
Posts: 1429
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: more Graphics with OpenGLGadget

Post by Comtois »

nice ApplePi.

Here ogre version (2D Plotting with VBO example:)

Code: Select all

#CameraSpeed = 1

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

Define.f KeyX, KeyY, MouseX, MouseY

If InitEngine3D()
  
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    
    ;- Material
    CreateMaterial(0, LoadTexture(0, "White.jpg"))
    DisableMaterialLighting(0, #True)
    
    ;- Mesh 
    CreateMesh(0, #PB_Mesh_LineStrip, #PB_Mesh_Static)
    Define.f x, y, z, t
    
    While t <= 2*#PI
      x.f = Cos(t) - Cos(6* t)/2 + Sin(14* t)/3
      y.f = Cos(14* t)/3 + Sin(t)- Sin(6* t)/2
      z.f = 0
            
      MeshVertexPosition(x, y, z)
      MeshVertexColor(RGB(127.5+Sin(t)*127.5,127.5+Cos(t)*127.5,255))

      t + 0.005
      
    Wend
        
    FinishMesh(#False)
    
    SetMeshMaterial(0, MaterialID(0))
    Plane = CreateNode(#PB_Any)
    AttachNodeObject(Plane, MeshID(0))
    
    ;-Camera
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 0, 5, #PB_Absolute)
    CameraFOV(0, 40)
    CameraLookAt(0, NodeX(Plane),  NodeY(Plane),  NodeZ(Plane))
    ;CameraBackColor(0, RGB(255, 255, 255))
    
    ;-Light
    CreateLight(0, RGB(255,255,255), -10, 60, 10)
    AmbientColor(RGB(90, 90, 90))
    
    Repeat
      Screen3DEvents()
      
      ExamineKeyboard()
      
      RotateNode(Plane, 0, 0, 1, #PB_Relative)
      
      RenderWorld()
      
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf

End
Please correct my english
http://purebasic.developpez.com/
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: more Graphics with OpenGLGadget

Post by applePi »

@Samuel thanks for the info and for the detailed comments besides the modifications, yes a one buffer with one big structure with one glBufferData function and the way glxxxPointer is used is more concise and constructive approach and gives more insights into the GPU memory access which is a tricky subject, so thanks for this.
@Comtois thanks for the much shorter Ogre version than the equivalent GL version, of course PB Ogre is designed to be used easily and straight forward.
for who ask about the strange looking 2D curve (2D Plotting with VBO example) GL and Ogre version above , it is called mystery curve look:
http://www.johndcook.com/blog/2015/06/03/mystery-curve/

Impossible Wallpaper and Mystery Curves:
https://blogs.scientificamerican.com/ro ... nk-farris/
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Vertex Buffer Objects - OpenGL examples with OpenGLGadge

Post by IdeasVacuum »

Hi ApplePi

How did you determine the Prototype values? I ask because I would like to include glGetString to find the current version of OpenGL supported on any given PC.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Vertex Buffer Objects - OpenGL examples with OpenGLGadge

Post by #NULL »

just try this (after OpenGLGadget())

Code: Select all

*p = glGetString_(#GL_VERSION)
Debug PeekS(*p, -1, #PB_Ascii)

#GL_SHADING_LANGUAGE_VERSION = $8b8c
*p = glGetString_(#GL_SHADING_LANGUAGE_VERSION)
Debug PeekS(*p, -1, #PB_Ascii)
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Vertex Buffer Objects - OpenGL examples with OpenGLGadge

Post by applePi »

Thanks #NULL , i have tried it but after preceding your code with:
InitSprite()
OpenWindow(0, 0, 0, 100, 100, " ")
OpenWindowedScreen(WindowID(0), 0, 0, 100, 100, 0, 0, 0)

for me i got :
4.3.0
4.30 NVIDIA via Cg compiler
============
@IdeasVacuum , the prototypes are from xorc1zt viewtopic.php?f=16&t=48667&start=0
they are found inside the file glbase.pb inside the zipped package can be downloaded from
http://s000.tinyupload.com/index.php?fi ... 1226221089

there is a talk about glGetString in the second page in the previous link
the functions which are not found in xorc1zt package can be added from glext.h from http://www.opengl.org/registry/api/GL/glext.h

look also my question to luis here viewtopic.php?f=13&t=45687#p446874
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Vertex Buffer Objects - OpenGL examples with OpenGLGadge

Post by Samuel »

IdeasVacuum wrote: How did you determine the Prototype values? I ask because I would like to include glGetString to find the current version of OpenGL supported on any given PC.
If you are unsure of which PB data type to use look at https://www.khronos.org/opengl/wiki/OpenGL_Type for comparison.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Vertex Buffer Objects - OpenGL examples with OpenGLGadge

Post by IdeasVacuum »

Hi Samuel

Actually I was referring to the "all caps" process name, which I just couldn't read before but I see it now :)

However, how do we know if a specific OpenGL function is actually in opengl32.lib - is there a man readable file too?

Edit: Also, PB already supports some functions, such as glDrawArrays. Is there a list of supported functions? Not in the help........

Edit Edit: This fails:

Code: Select all

;OpenGlVersionTest

#GL_VERSION              = $1F02
#GL_EXTENSIONS           = $1F03
#GL_NUM_EXTENSIONS       = $821D
#GL_MAJOR_VERSION        = $821B
#GL_MINOR_VERSION        = $821C

  OpenWindow(0, 10, 10, 640, 480, "Get OpenGL version")
OpenGLGadget(0,  0,  0, WindowWidth(0), WindowHeight(0))

CompilerIf (#PB_Compiler_Processor = #PB_Processor_x86)

               Import "opengl32.lib"

                              wglGetProcAddress_(s.p-ascii) As "_wglGetProcAddress@4"
               EndImport
CompilerElse

               Import "opengl32.lib"

                              wglGetProcAddress_(s.p-ascii) As "wglGetProcAddress"
               EndImport
CompilerEndIf

Prototype PfnGlGetStringProc(glenum.i)
Global glGetString.PfnGlGetStringProc
glGetString = wglGetProcAddress_("glGetString")

Debug glGetString(#GL_VERSION)
;Debug PeekS(glGetString(#GL_VERSION), -1, #PB_Ascii)
;[ERROR] Invalid memory access. (write error at address 0)
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Vertex Buffer Objects - OpenGL examples with OpenGLGadge

Post by applePi »

IdeasVacuum, it is possible that the opengl functions available natively for purebasic listed in binary files opengl.imp glut.imp glu.imp in Purebasic\PureLibraries\Windows\Ansi
just drop the file in notepad and search for some opengl function. it is also available in file APIFunctionListing.txt in Purebasic\Compilers.
we need only to import the functions from Opengl32.lib which are not listed in those files such as glGenBuffers
but glGetString is already listed in opengl.imp so we don't need to import it again from Opengl32.lib
regarding your last code gives error, it works if you replaced your code

Code: Select all

Debug glGetString(#GL_VERSION) 
with what #NULL have posted :

Code: Select all

*p = glGetString_(#GL_VERSION)
Debug PeekS(*p, -1, #PB_Ascii)
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Vertex Buffer Objects - OpenGL examples with OpenGLGadge

Post by IdeasVacuum »

Hi applePi

I did not know of the file "APIFunctionListing.txt". That is generally a handy list of functions and I see glGetString is there. A lot of "modern" OpenGL is missing, which is a shame. Vertex Buffer Objects for example have been available for years now and I think it would be difficult to find a PC that did not have support for VBO, but those that do not are most likely office machines with no need for OpenGL at all.

The code snippet from #Null works perfectly with my test code (as do your examples in the Forum Topic), but curiously, it fails in my actual program...... in fact all gl functions are failing :?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Post Reply