Page 3 of 4

Re: Small cross-platform OpenGL demo

Posted: Sun Jun 01, 2014 9:55 am
by Shardik
Due to the amazing new OpenGLGadget introduced with PB 5.30 Beta 1 my bare bones cross-platform example for drawing a triangle can now be stripped down to the following code (tested with Windows 7 x64 SP1 and Ubuntu 12.04 LTS x64 with KDE; MacOS test is currently impossible because of IDE bug in Beta 1). Compare that with the code of my first posting or that using a WindowedScreen! No CompilerSelect and Import statements are necessary anymore!

Code: Select all

EnableExplicit

OpenWindow(0, 270, 100, 640, 480, "Cross-platform OpenGL demo")
SetWindowColor(0, 0)
OpenGLGadget(0, 0, 0, WindowWidth(0) , WindowHeight(0))

Repeat
  glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
  glMatrixMode_(#GL_PROJECTION)
  glLoadIdentity_()
  gluPerspective_(30.0, Abs(WindowWidth(0) / WindowHeight(0)), 0.1, 500.0)
  glMatrixMode_(#GL_MODELVIEW)
  glLoadIdentity_()
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  glLoadIdentity_()
  glTranslatef_(0.0, 0.0, -8.0)
  glColor3f_(1.0, 1.0, 1.0)
  glBegin_(#GL_TRIANGLES)      ; Start drawing a triangle
  glColor3f_ ( 1.0,  0.0, 0.0) ; Set top point of triangle to Red
  glVertex3f_( 0.0,  1.0, 0.0) ; First point of the triangle
  glColor3f_ ( 0.0,  1.0, 0.0) ; Set left point of triangle to Green
  glVertex3f_(-1.0, -1.0, 0.0) ; Second point of the triangle
  glColor3f_ ( 0.0,  0.0, 1.0) ; Set right point of triangle to Blue
  glVertex3f_( 1.0, -1.0, 0.0) ; Third point of the triangle
  glEnd_()                     ; Done drawing the triangle
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
Until WaitWindowEvent() = #PB_Event_CloseWindow

Re: Small cross-platform OpenGL demo

Posted: Sun Jun 01, 2014 10:24 am
by Fred
It does look shorter indeed :)

Re: Small cross-platform OpenGL demo

Posted: Sun Jun 01, 2014 11:28 am
by luis
@shardik

It's a good thing because the code is now extremely simple (no initialization at all) and you are not depending anymore on the partially deprecated (at least for windowed applications) AGL API you were using on OSX (even if I don't know what PB uses).
It's a bad thing because you don't have control anymore on how the rendering context is created and you have to use what PB makes available.
Its specifics are not documented and we already saw in other tests differences were present on different plaftorms. At least using the opengl subsystem, I didn't verified on all platforms with the gadget but I expect it to be the same.
And for what we know those settings could also change in time, since not documented.
To draw a triangle it's no problem, to do more advanced stuff the RC settings can be important and being blind about that it's enough for me to not use it for "real" stuff.
Anyway, a lot of people will probably not encounter problems at all.

Re: Small cross-platform OpenGL demo

Posted: Sun Jun 01, 2014 8:00 pm
by applePi
here is the helix example i have posted before from the book "computer Graphics through OpenGL" copying the plotting routine in "rotatingHelix1.cpp" almost blindly and i don't know c/cpp more than morphological resemblance with basic . can be downloaded free from http://www.sumantaguha.com/

Code: Select all

EnableExplicit
Global RollAxisX.f
Global RollAxisY.f
Global RollAxisZ.f

Global RotateSpeedX.f = 2 ; The speed of the rotation For the 3 axis
Global RotateSpeedY.f = 2
Global RotateSpeedZ.f = 2

Global running = 1
Global angle.f, R.f, t.f, ZoomFactor.f = 1
Global rot.f = 3

Declare.l spiral_render()

OpenWindow(0, 30, 30, 640, 480, "Cross-platform OpenGL demo")
SetWindowColor(0, 0)
OpenGLGadget(0, 0, 0, WindowWidth(0) , WindowHeight(0))

Repeat
  spiral_render()        
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
Until WindowEvent() = #PB_Event_CloseWindow

Procedure.l spiral_render()

 glPushMatrix_()                  ; Save the original Matrix coordinates
  glMatrixMode_(#GL_MODELVIEW)

  glTranslatef_(0, 0, -120)  ;  move it forward a bit

  glRotatef_ (RollAxisX, 1.0, 0, 0) ; rotate around X axis
  glRotatef_ (RollAxisY, 0, 1.0, 0) ; rotate around Y axis
  glRotatef_ (RollAxisZ, 0, 0, 1.0) ; rotate around Z axis
 
  RollAxisX + RotateSpeedX 
  RollAxisY + RotateSpeedY 
  RollAxisZ + RotateSpeedZ 

  ; clear framebuffer And depth-buffer

  glClear_ (#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)

  
  glDisable_(#GL_LIGHTING)
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT) ;Clear The Screen And The Depth Buffer
  glLoadIdentity_() ;Reset The View
 
  glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
  glMatrixMode_(#GL_PROJECTION)
  glLoadIdentity_()
  ;gluPerspective_(90.0, Abs(WindowWidth(0) / WindowHeight(0)), 0.1, 1000.0)
  glFrustum_(-10.0, 10.0, -10.0, 10.0, 10.0, 1000.0); 
 
  
   R.f = 30.0; // Radius of helix.

   t.f = -10*#PI; // Angle parameter along helix.

   glClear_(#GL_COLOR_BUFFER_BIT);
   glColor3f_(1.0, 0.7, 0.0);
   glPushMatrix_();

   ;The Trick: To align the axis of the helix along the y-axis prior To rotation
   ;And then Return it To its original location.
   glTranslatef_(0.0, 0.0, -120+ZoomFactor);
   glRotatef_(angle, 1, 1, 1);
   glTranslatef_(0.0, 0.0, 60.0);
   ;glPointSize_(5);
   angle.f + rot

   glBegin_(#GL_LINE_STRIP);
   ;glBegin_(#GL_POINTS);
      
   While t <= 10 * #PI
     
       glVertex3f_(R * Cos(t), t, R * Sin(t) - 60.0);
       t = t+(#PI/40.0)
      
   Wend
 
 glEnd_();
 glPopMatrix_();
 
 glFinish_()
 
EndProcedure


Re: Small cross-platform OpenGL demo

Posted: Sun Jun 01, 2014 8:11 pm
by Demivec
applePi wrote:here is the helix example i have posted before from the book "computer Graphics through OpenGL" copying the plotting routine in "rotatingHelix1.cpp" almost blindly and i don't know c/cpp more than morphological resemblance with basic . can be downloaded free from http://www.sumantaguha.com/
If you change the event loop to this I think you will get better visual results:

Code: Select all

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

Re: Small cross-platform OpenGL demo

Posted: Wed Jun 04, 2014 12:15 pm
by Fred
luis wrote:@shardik

It's a good thing because the code is now extremely simple (no initialization at all) and you are not depending anymore on the partially deprecated (at least for windowed applications) AGL API you were using on OSX (even if I don't know what PB uses).
It's a bad thing because you don't have control anymore on how the rendering context is created and you have to use what PB makes available.
Its specifics are not documented and we already saw in other tests differences were present on different plaftorms. At least using the opengl subsystem, I didn't verified on all platforms with the gadget but I expect it to be the same.
And for what we know those settings could also change in time, since not documented.
To draw a triangle it's no problem, to do more advanced stuff the RC settings can be important and being blind about that it's enough for me to not use it for "real" stuff.
Anyway, a lot of people will probably not encounter problems at all.
Don't hesitate to make proposal about new flags we could set for the OpenGLGadget() creation, to make it more flexible.

Re: Small cross-platform OpenGL demo

Posted: Wed Jun 04, 2014 12:49 pm
by luis
Fred wrote: Don't hesitate to make proposal about new flags we could set for the OpenGLGadget() creation, to make it more flexible.
Fred, please see here -> http://www.purebasic.fr/english/viewtop ... =3&t=57157

I added some more info.

Re: Small cross-platform OpenGL demo

Posted: Wed Jun 04, 2014 1:52 pm
by Kuron
Fred wrote:Don't hesitate to make proposal about new flags we could set for the OpenGLGadget() creation, to make it more flexible.
A good suggestion would be to look at what is offered by IUP in it's GL Canvas:

http://www.tecgraf.puc-rio.br/iup/en/ct ... anvas.html

Re: Small cross-platform OpenGL demo

Posted: Tue Jun 17, 2014 9:52 am
by Shardik
This is another simple example demonstrating the cross-platform usage of the new OpenGLGadget. It's based on luis' Demo_Texture_2d.pb which is contained in the file swof.zip of his Simple OpenGL Windowed framework. luis' example (which is based on NeHe's texture mapping tutorial) was heavily modified and stripped down. It now loads a BMP file contained in the PB installation folder instead of luis' original png file because luis' example uses the WinAPI function GetDIBits_() which prevents a cross-platform usage. The BMP file is loaded into a buffer and used as a texture for a rotating 3D cube.

I have tested the example successfully with PB 5.30 Beta 3 on these operating systems (for MacOS there is still an ImportC block necessary because of some missing predefined OpenGL functions):

Windows
- Windows XP SP3
- Windows 7 x86 SP1
- Windows 7 x64 SP1 with PB x64

Linux
- ElementaryOS 0.2 x86 with Pantheon
- Fedora 10 x86 with Gnome 3
- Kubuntu 10.04 x86 with KDE
- Kubuntu 14.04 x86 with KDE
- Linux Mint 16 x86 with Cinnamon and MATE
- Linux Mint 17 x86 with Cinnamon
- Lubuntu 14.04 x86 with LXDE
- Manjaro 0.8.9 and 0.8.10 x86 with Xfce
- OpenSUSE 13.1 x86 with KDE
- PCLinuxOS 2014.05 MiniMe with KDE
- PearOS 8 x86 with Gnome 3
- Ubuntu 10.04 x86 with Gnome 2
- Ubuntu 12.04 x86 with Unity
- Ubuntu 12.04 x64 with KDE and Enlightenment E17
- Xubuntu 14.04 x86 with Xfce

MacOS
- 10.6.8 (Snow Leopard) with PB x86 and x64
- 10.9.2 (Mavericks) with PB x86

Update: I have removed the ImportC block for MacOS because beginning with PB 5.30 Beta 4 the additional OpenGL declarations aren't necessary anymore.

Code: Select all

EnableExplicit

#FPS = 60
#ImagePath = #PB_Compiler_Home + "examples/sources/Data/"
#ROTATION_TIME = 15.0 ; Full revolution time in seconds

UsePNGImageDecoder()

Define *BMPHeader
Define *BMPImage
Define Direction.I
Define ImageHeight.I
Define ImageSize.I
Define ImageWidth.I
Define ImagePath.S
Define TextureID.I
Define.F XRot, YRot, ZRot
Define.F XInc, YInc, ZInc

If ReadFile(0, #ImagePath + "Geebee2.bmp") = 0
  MessageRequester("Error", "Loading of texture image failed!")
  End
EndIf

*BMPHeader = AllocateMemory(54)
ReadData(0, *BMPHeader, MemorySize(*BMPHeader))
ImageWidth = PeekL(*BMPHeader + 18)
ImageHeight = PeekL(*BMPHeader + 22)
ImageSize = PeekL(*BMPHeader + 34)
FreeMemory(*BMPHeader)

*BMPImage = AllocateMemory(ImageSize)
ReadData(0, *BMPImage, ImageSize)
CloseFile(0)

OpenWindow(0, 270, 100, 400, 320, "Cross-platform OpenGL demo")
SetWindowColor(0, 0)
OpenGLGadget(0, 0, 0, WindowWidth(0) , WindowHeight(0))

; ----- Generate texture
glGenTextures_(1, @TextureID)
glBindTexture_(#GL_TEXTURE_2D, TextureID)
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, ImageHeight, 0, #GL_BGR_EXT, #GL_UNSIGNED_BYTE, *BMPImage)
FreeMemory(*BMPImage)

Direction = -1

glMatrixMode_(#GL_PROJECTION)
gluPerspective_(30.0, Abs(WindowWidth(0) / WindowHeight(0)), 0.1, 500.0)

Repeat
  XInc = (Direction * 360.0) / (#ROTATION_TIME * #FPS) 
  YInc = 360.0 / (#ROTATION_TIME   * #FPS)
  ZInc = (Direction * 360.0) / (#ROTATION_TIME * #FPS) / 1.5

  glMatrixMode_(#GL_MODELVIEW)
  glEnable_(#GL_CULL_FACE)

  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)   ; Clear screen and depth buffer
  glLoadIdentity_()                                       ; Reset current modelview matrix
  glTranslatef_(0.0, 0.0, -7.5)
  glRotatef_(XRot, 1.0, 0.0, 0.0)
  glRotatef_(YRot, 0.0, 1.0, 0.0)
  glRotatef_(ZRot, 0.0, 0.0, 1.0)
  glEnable_(#GL_TEXTURE_2D)                               ; Enable texture mapping 
  glBindTexture_(#GL_TEXTURE_2D, TextureID)
  
  glBegin_(#GL_QUADS)                                     ; Start drawing the cube
    glTexCoord2f_(1.0, 1.0) : glVertex3f_( 1.0, 1.0,-1.0) ; Top right of cube (Top)
    glTexCoord2f_(0.0, 1.0) : glVertex3f_(-1.0, 1.0,-1.0) ; Top left of cube (Top)
    glTexCoord2f_(0.0, 0.0) : glVertex3f_(-1.0, 1.0, 1.0) ; Bottom left of cube (Top)
    glTexCoord2f_(1.0, 0.0) : glVertex3f_( 1.0, 1.0, 1.0) ; Bottom right of cube (Top)
  
    glTexCoord2f_(1.0, 1.0) : glVertex3f_(-1.0, 1.0, 1.0) ; Top right of cube (left)
    glTexCoord2f_(0.0, 1.0) : glVertex3f_(-1.0, 1.0,-1.0) ; Top left of cube (left)
    glTexCoord2f_(0.0, 0.0) : glVertex3f_(-1.0,-1.0,-1.0) ; Bottom left of cube (left)
    glTexCoord2f_(1.0, 0.0) : glVertex3f_(-1.0,-1.0, 1.0) ; Bottom right of cube (left)
  
    glTexCoord2f_(1.0, 1.0) : glVertex3f_( 1.0, 1.0, 1.0) ; Top right of cube (Front)
    glTexCoord2f_(0.0, 1.0) : glVertex3f_(-1.0, 1.0, 1.0) ; Top left of cube (Front)  
    glTexCoord2f_(0.0, 0.0) : glVertex3f_(-1.0,-1.0, 1.0) ; Bottom left of cube (Front)
    glTexCoord2f_(1.0, 0.0) : glVertex3f_( 1.0,-1.0, 1.0) ; Bottom right of cube (Front)
  
    glTexCoord2f_(1.0, 1.0) : glVertex3f_(-1.0, 1.0,-1.0) ; Top right of cube (Back)
    glTexCoord2f_(0.0, 1.0) : glVertex3f_( 1.0, 1.0,-1.0) ; Top left of cube (Back)
    glTexCoord2f_(0.0, 0.0) : glVertex3f_( 1.0,-1.0,-1.0) ; Bottom left of cube (Back)
    glTexCoord2f_(1.0, 0.0) : glVertex3f_(-1.0,-1.0,-1.0) ; Bottom right of cube (Back)
  
    glTexCoord2f_(1.0, 1.0) : glVertex3f_( 1.0, 1.0,-1.0) ; Top right of cube (right)
    glTexCoord2f_(0.0, 1.0) : glVertex3f_( 1.0, 1.0, 1.0) ; Top left of cube (right)
    glTexCoord2f_(0.0, 0.0) : glVertex3f_( 1.0,-1.0, 1.0) ; Bottom left of cube (right)
    glTexCoord2f_(1.0, 0.0) : glVertex3f_( 1.0,-1.0,-1.0) ; Bottom right of cube (right)
  
    glTexCoord2f_(1.0, 1.0) : glVertex3f_( 1.0,-1.0, 1.0) ; Top right of cube (Bottom)
    glTexCoord2f_(0.0, 1.0) : glVertex3f_(-1.0,-1.0, 1.0) ; Top left of cube (Bottom)  
    glTexCoord2f_(0.0, 0.0) : glVertex3f_(-1.0,-1.0,-1.0) ; Bottom left of cube (Bottom)
    glTexCoord2f_(1.0, 0.0) : glVertex3f_( 1.0,-1.0,-1.0) ; Bottom right of cube (Bottom)
  glEnd_()

  YRot - YInc
  
  If YRot < -360.0
    YRot = 0.0   
  EndIf 
  
  XRot + XInc
  
  If XRot > 180.0
    Direction = - Direction 
  EndIf 
  
  If XRot < -180.0
    Direction = - Direction 
  EndIf 
  
  ZRot + ZInc
  
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)

  If WaitWindowEvent(10) = #PB_Event_CloseWindow
    glDeleteTextures_(1, @TextureID)
    Break
  EndIf
ForEver

Re: Small cross-platform OpenGL demo

Posted: Sun Jul 06, 2014 10:07 pm
by JHPJHP
Hi Shardik,

I used your code in a new example for a "community" project I was working on: PureBasic Interface to OpenCV.

Thank you for posting your script.

Cheers!

Re: Small cross-platform OpenGL demo

Posted: Mon Jul 07, 2014 7:04 am
by davido
@Shardik,

A lovely example. Thank you for sharing. :D

Re: Small cross-platform OpenGL demo

Posted: Sun Jul 20, 2014 1:03 pm
by applePi
i have noticed that we don't need OpenGL.pbi anymore in PB 5.30 beta 9, which usually we refer to like this :
IncludeFile #PB_Compiler_Home + "Examples\Sources - Advanced\OpenGL Cube\OpenGL.pbi"
and it is deleted. so i have edited all my examples posted this year , and it is working okay when we use the new OpenGLGadget.
P.S: also what is related to the glut, the glu32, glut32, opengl32, glaux libs are there inside the purebasic folder, but we don't need to IncludeFile "glu.pbi" anymore, as an example i have used glutWireDodecahedron_() in Example 4 in this demo http://purebasic.fr/english/viewtopic.php?f=36&t=59269 which used glu.pbi, now we don't need it. thats great and even makes the things simpler

Re: Small cross-platform OpenGL demo

Posted: Sat Jul 26, 2014 6:10 pm
by Ocean
Thanks ApplePi,

that's good to know - thank you for testing these features.

Cheers
Ocean

Re: Small cross-platform OpenGL demo

Posted: Wed Jul 30, 2014 1:21 pm
by Nituvious
It would be pretty cool if someone could convert this to modern opengl

Re: Small cross-platform OpenGL demo

Posted: Thu Jul 31, 2014 2:11 pm
by applePi
@Nituvious
this is an example of triangle with color and translation using the shader. it is from a tutorial here
http://web.archive.org/web/201309290452 ... rices.html
the examples for vs2012 can be downloaded from OpenGL 4 tutorials http://antongerdelan.net/opengl/book_info.html
i will try to do a rotation for the triangle and will post if successful, but texturing a cube like that of shardik - luis is still another issue.
the problem the Opengl developers removed most useful functions and then they ask you to reinvent the wheel such as the translation and rotation. but any way it seems we can do every thing related to modern opengl inside purebasic, and the following example is a proof. we just need to include the new functions needed
use the arrow keys, and A/Z to translate the triangle in 3D
here we do the translation by changing the values of the matrix(3,...)
also the code here should not run in unicode mode for the reasons described by luis here:
http://purebasic.fr/english/viewtopic.p ... 09#p446962
i want here in this specific code to focus on exact translation of Anton's tutorials examples
the constants below are taken from here: http://purebasic.fr/english/viewtopic.p ... 87#p348385
Image

newFunctions.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 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" )

Prototype PFNGLGETUNIFORMLOCATIONPROC ( program.i, name.p-ascii )
Global glGetUniformLocation.PFNGLGETUNIFORMLOCATIONPROC
glGetUniformLocation = wglGetProcAddress_( "glGetUniformLocation" )

Prototype PFNGLUNIFORMMATRIX4FVPROC ( location.i, count.i, transpose.b, *value )
Global glUniformMatrix4fv.PFNGLUNIFORMMATRIX4FVPROC
glUniformMatrix4fv = wglGetProcAddress_( "glUniformMatrix4fv" )

Code: needs PB v5.30

Code: Select all

#GL_ARRAY_BUFFER = $8892
#GL_STATIC_DRAW = $88E4
#GL_VERTEX_SHADER = $8B31
#GL_FRAGMENT_SHADER = $8B30

Structure TVertex
  x.f
  y.f
  z.f
EndStructure


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


Dim matrix.f(3,3)
matrix(0,0)=1:   matrix(0,1)=0:matrix(0,2)=0:matrix(0,3)=0 ;// first column
matrix(1,0)=0:   matrix(1,1)=1:matrix(1,2)=0:matrix(1,3)=0 ;// second column
matrix(2,0)=0:   matrix(2,1)=0:matrix(2,2)=1:matrix(2,3)=0 ; // third column
matrix(3,0)=0: matrix(3,1)=0:matrix(3,2)=0:matrix(3,3)=2 ;// fourth column

;the above is the simulation of this:
;GLfloat matrix[] = {
;		1.0f, 0.0f, 0.0f, 0.0f, // first column
;		0.0f, 1.0f, 0.0f, 0.0f, // second column
;		0.0f, 0.0f, 1.0f, 0.0f, // third column
;		-0.5f, 0.0f, 0.0f, 2.0f // fourth column
;	};

OpenWindow(0, 10, 10, 800, 600, "OpenGL demo ... color and translation with shader... use arrow keys and A/Z to translate in 3D space")
SetWindowColor(0, RGB(200,220,200))
OpenGLGadget(0, 20, 10, WindowWidth(0)-40 , WindowHeight(0)-20, #PB_OpenGL_Keyboard)

IncludeFile "newFunctions.pbi"


Global points_vbo.i, colors_vbo.i, vao.i
Dim Vertex.TVertex(2)
Dim color.Colors(2)
Vertex(0)\x = 0.0
Vertex(0)\y = 0.5
Vertex(0)\z = 0

Vertex(1)\x = 0.5
Vertex(1)\y = -0.5
Vertex(1)\z = 0

Vertex(2)\x = -0.5
Vertex(2)\y = -0.5
Vertex(2)\z = 0

color(0)\r = 1.0 :color(0)\g = 0.0 :color(0)\b = 0 
color(1)\r = 0.0 :color(1)\g = 1.0 :color(1)\b = 0
color(2)\r = 0.0 :color(2)\g = 0.0 :color(2)\b = 1

Define vertex_shader.s
Define fragment_shader.s
Define *vbuff

;vertex shader source code
    vertex_shader = "#version 420"+#CRLF$
    vertex_shader + "layout(location = 0) in vec3 vertex_position;"+#CRLF$
    vertex_shader + "layout(location = 1) in vec3 vertex_colour;"+#CRLF$
    vertex_shader + "uniform mat4 matrix; // our matrix"+#CRLF$
    vertex_shader + "out vec3 colour;"+#CRLF$
    vertex_shader + "void main() {"+#CRLF$
    vertex_shader + "colour = vertex_colour;"+#CRLF$
    vertex_shader + "gl_Position = matrix * vec4(vertex_position, 1.0);"+#CRLF$
    vertex_shader + "}"
    
           
    ;fragment shader source code
    fragment_shader = "#version 420"+#CRLF$
    fragment_shader + "in vec3 colour;"+#CRLF$
    fragment_shader + "out vec4 frag_colour;"+#CRLF$
    fragment_shader + "void main() {"+#CRLF$
    fragment_shader + "frag_colour = vec4 (colour, 1.0);"+#CRLF$
    fragment_shader + "}"
        
    *vbuff = @vertex_shader
    *fbuff = @fragment_shader
    
glEnable_(#GL_DEPTH_TEST); // enable depth-testing
;glDepthFunc_(#GL_LESS); // depth-testing interprets a smaller value as "closer"

Global points_vbo.i, colors_vbo.i, vao.i

;=================================================================================
glGenBuffers( 1, @points_vbo ) ; Vertex Buffer Object
glBindBuffer(#GL_ARRAY_BUFFER, points_vbo )
glBufferData(#GL_ARRAY_BUFFER,9 * SizeOf(float),@Vertex(0), #GL_STATIC_DRAW)

glGenBuffers (1, @colors_vbo);
glBindBuffer (#GL_ARRAY_BUFFER, colors_vbo);
glBufferData (#GL_ARRAY_BUFFER, 9 * SizeOf (float), @color(0), #GL_STATIC_DRAW);


glGenVertexArrays (1, @vao);
glBindVertexArray (vao);
glBindBuffer (#GL_ARRAY_BUFFER, points_vbo);
glVertexAttribPointer (0, 3, #GL_FLOAT, #GL_FALSE, 0, #Null);
glBindBuffer (#GL_ARRAY_BUFFER, colors_vbo);
glVertexAttribPointer (1, 3, #GL_FLOAT, #GL_FALSE, 0, #Null);
;ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
;=================================================================================

Global vs = glCreateShader(#GL_VERTEX_SHADER);
glShaderSource(vs, 1, @*vbuff, #Null) ;
glCompileShader(vs);
Global fs = glCreateShader(#GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, @*fbuff, #Null);
glCompileShader(fs)                          ;

Global shader_programme = glCreateProgram();
glAttachShader(shader_programme, fs);
glAttachShader(shader_programme, vs);
glLinkProgram(shader_programme)     ;


glEnable_(#GL_CULL_FACE); // cull face
	glCullFace_(#GL_BACK); // cull back face
	glFrontFace_(#GL_CW); // GL_CCW for counter clock-wise
	
	rot.f = 1	
	SetActiveGadget(0) 
	Repeat
	  
	  Event = WaitWindowEvent()
	  If Event = #PB_Event_Gadget And EventGadget() = 0 
   If EventType() = #PB_EventType_KeyDown
      
            key = GetGadgetAttribute(0,#PB_OpenGL_Key )
            ;If key = 38 ; Up arrow key
            If key = #PB_Shortcut_Up
               matrix(3,1) + 0.1 
               
               ElseIf key = #PB_Shortcut_Down ; Down arrow key  
                 matrix(3,1) - 0.1
               ElseIf key = #PB_Shortcut_Left ; Left arrow key 
                 matrix(3,0) - 0.1
               ElseIf key = #PB_Shortcut_Right ; Left arrow key 
                 matrix(3,0) + 0.1 
               ElseIf key = #PB_Shortcut_A ; Left arrow key 
                 matrix(3,3) - 0.1 
               ElseIf key = #PB_Shortcut_Z ; Left arrow key 
                 matrix(3,3) + 0.1     
            ElseIf key = #PB_Shortcut_Escape ;  Esc key to exit

             quit = 1
            EndIf  
     EndIf
   EndIf  
   
	  
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT);
  glRotatef_(rot, 0, 1, 0)                             ;
  matrix_location.l = glGetUniformLocation(shader_programme, "matrix");
	glUseProgram (shader_programme);
	glUniformMatrix4fv (matrix_location, 1, #GL_FALSE, @matrix(0,0));
	
	glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT);
	glViewport_(0, 0, 800, 600);
  ;glUseProgram(shader_programme)  
  glBindVertexArray(vao);
  ;draw points 0-3 from the currently bound VAO With current in-use shader
  glDrawArrays(#GL_TRIANGLES, 0, 3);
    
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
  Delay(16)
  
Until Event = #PB_Event_CloseWindow Or quit = 1