OpenGL (Canvas) Gadget

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

OpenGL (Canvas) Gadget

Post by grabiller »

An OpenGL (Canvas) Gadget, which works like the CanvasGadget (with input events), with Hints flags options upon initialization (version, core/compatibility profile, debug, etc..).

And the ability to have several OpenGLGadget at the same time in the same window.

I can't imagine PureBasic without it sooner or later.

Cheers,
Guy.
guy rabiller | radfac founder / ceo | raafal.org
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: OpenGL (Canvas) Gadget

Post by applePi »

i agree
in the mean time we can use the approach by Shardik which refers to luis work and the snippet from d.j.peters
http://www.purebasic.fr/english/viewtop ... 12&t=49583
_ set the subsystem to OpenGL before running
Image

Code: Select all

Declare DrawTriangle() :Declare DrawCube()
Global angle.f = 0 : Global ZoomFactor.f = -1 ; Distance of the camera. Negative value = zoom back 
run.b = 0
Enumeration
   #TextBox = 10
   #TrackBar
   #option1
   #option2
 EndEnumeration
IncludeFile #PB_Compiler_Home + "Examples\Sources - Advanced\OpenGL Cube\OpenGL.pbi"
InitKeyboard()
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  CompilerIf Subsystem("OpenGL") = #False
    MessageRequester("Error", "Please set the subsystem to OpenGL")
    End
  CompilerEndIf
CompilerEndIf

If InitSprite() = 0
  MessageRequester("Error", "Can't open screen & sprite environment!")
  End
EndIf
ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "slide the trackBar to rotate", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;SetWindowColor(0, 0)
OpenWindowedScreen(WindowID(0), 30, 10, DesktopWidth(0)-100, DesktopHeight(0)-120, 1, 40, 50)
HideWindow(0, #False)
TextGadget(#TextBox, 190, DesktopHeight(0)-70, 100, 25, "0")
TrackBarGadget(#TrackBar, 100, DesktopHeight(0)-70, 90, 20, 0, 360)
OptionGadget(#option1, 300, DesktopHeight(0)-80, 60, 20, "Triangle")
OptionGadget(#option2, 300, DesktopHeight(0)-60, 60, 20, "Cube ...")
SetGadgetState(#option2, 1)

If (FlatMode)
  glShadeModel_ (#GL_FLAT)
Else
  glShadeModel_ (#GL_SMOOTH)
EndIf


glEnable_ (#GL_DEPTH_TEST) 

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

glEnable_(#GL_LIGHTING);
glEnable_(#GL_LIGHT0);
glEnable_(#GL_DEPTH_TEST);


HideWindow(0, #False)

 
glMatrixMode_(#GL_PROJECTION)
; *ADDED* set the perspective, calculate the aspect ratio, set the clipping panes
;gluPerspective_(30.0, WindowWidth/WindowHeight, 1.0, 10.0)  

; position viewer

glMatrixMode_ (#GL_MODELVIEW)

; *CHANGED* changed -2.0 to -5.0
glTranslatef_ (0, 0, -5.0)

If (FlatMode)
  glShadeModel_ (#GL_FLAT)
Else
  glShadeModel_ (#GL_SMOOTH)
EndIf


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.
  
While Quit.b = 0

  Repeat 
    EventID = WindowEvent()
    Select EventID
      Case #PB_Event_Gadget
          If EventGadget() = 1
            run = 1
          EndIf
          If EventGadget() = #TrackBar
           angle = GetGadgetState(#TrackBar)
           SetGadgetText(#TextBox, Str(angle))
          EndIf
           
      Case #PB_Event_CloseWindow
        Quit = 1
    EndSelect
    ExamineKeyboard()
  
Until EventID = 0
  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_ ()
   ; viewing transformation  
   glTranslatef_(0.0, 0.0, -6.0); 
   ;gluLookAt_(5,5,5,0,1.5,0,0,1,0);
   gluLookAt_(0,1,1,0,0.5,0,0,1,0); from where and to where we look at
   opt = GetGadgetState(#option1)
   If opt=1
     DrawTriangle()
     Else
       DrawCube()
   EndIf
   FlipBuffers()
  
Wend

End
Procedure DrawTriangle() ; drawcube procedure
  glPushMatrix_()                  ; Save the original Matrix coordinates
  ;glMatrixMode_(#GL_MODELVIEW)
  glTranslatef_(0, 0, ZoomFactor)  ;  move it forward a bit
  glClear_ (#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  glDisable_(#GL_LIGHTING)
  glRotatef_(angle, 0.0, 1.0, 0.0)

glBegin_(#GL_TRIANGLES) ; start drawing a triangle
  glColor3f_(1.0, 0.0, 0.0);
  glVertex3f_( 0.0, 1.0, 0.0) ; top
  glColor3f_(0.0, 1.0, 0.0);
  glVertex3f_(-1.0,-1.0, 0.0) ; bottom left
  glColor3f_(0.0, 0.0, 1.0);
  glVertex3f_( 1.0,-1.0, 0.0) ; bottom right
glEnd_() ; finished 
  
glPopMatrix_()
glFinish_()

  ;SwapBuffers_(hdc)
EndProcedure

Procedure DrawCube() ; drawcube procedure

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

  glTranslatef_(0, 0, ZoomFactor)  ;  move it forward a bit

  glRotatef_ (0, 1.0, 0, 0) ; rotate around X axis
  glRotatef_ (angle, 0, 1.0, 0) ; rotate around Y axis
  glRotatef_ (0, 0, 0, 1.0) ; rotate around Z axis
  
  ; clear framebuffer And depth-buffer

  glClear_ (#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)

  ; draw the faces of a cube
  
  ; draw colored faces

  glDisable_(#GL_LIGHTING)
  glBegin_  (#GL_QUADS)
  
  ; Build a face, composed of 4 vertex ! 
  ; glBegin() specify how the vertexes are considered. Here a group of
  ; 4 vertexes (GL_QUADS) form a rectangular surface.

  ; Now, the color stuff: It's r,v,b but with float values which
  ; can go from 0.0 To 1.0 (0 is .. zero And 1.0 is full intensity) 
  
  glNormal3f_ (0,0,1.0)
  glColor3f_  (0,0,1.0)
  glVertex3f_ (0.5,0.5,0.5)   
  glColor3f_  (0,1.0,1.0)         
  glVertex3f_ (-0.5,0.5,0.5)
  glColor3f_  (1.0,1.0,1.0)
  glVertex3f_ (-0.5,-0.5,0.5)
  glColor3f_  (0,0,0)
  glVertex3f_ (0.5,-0.5,0.5) 

  ; The other face is the same than the previous one 
  ; except the colour which is nice blue To white gradiant

  glNormal3f_ (0,0,-1.0)
  glColor3f_  (0,0,1.0)
  glVertex3f_ (-0.5,-0.5,-0.5)
  glColor3f_  (0,0,1.0)
  glVertex3f_ (-0.5,0.5,-0.5)
  glColor3f_  (1.0,1.0,1.0)
  glVertex3f_ (0.5,0.5,-0.5)
  glColor3f_  (1.0,1.0,1.0)
  glVertex3f_ (0.5,-0.5,-0.5)
  
  glEnd_()
  
  ; draw shaded faces

  glEnable_(#GL_LIGHTING)
  glEnable_(#GL_LIGHT0)
  glBegin_ (#GL_QUADS)

  glNormal3f_ (   0, 1.0,   0)
  glVertex3f_ ( 0.5, 0.5, 0.5)
  glVertex3f_ ( 0.5, 0.5,-0.5)
  glVertex3f_ (-0.5, 0.5,-0.5)
  glVertex3f_ (-0.5, 0.5, 0.5)

  glNormal3f_ (0,-1.0,0)
  glVertex3f_ (-0.5,-0.5,-0.5)
  glVertex3f_ (0.5,-0.5,-0.5)
  glVertex3f_ (0.5,-0.5,0.5)
  glVertex3f_ (-0.5,-0.5,0.5)

  glNormal3f_ (1.0,0,0)
  glVertex3f_ (0.5,0.5,0.5)
  glVertex3f_ (0.5,-0.5,0.5)
  glVertex3f_ (0.5,-0.5,-0.5)
  glVertex3f_ (0.5,0.5,-0.5)

  glNormal3f_ (-1.0,   0,   0)
  glVertex3f_ (-0.5,-0.5,-0.5)
  glVertex3f_ (-0.5,-0.5, 0.5)
  glVertex3f_ (-0.5, 0.5, 0.5)
  glVertex3f_ (-0.5, 0.5,-0.5)

  glEnd_()

  glPopMatrix_()
  glFinish_()

  ;SwapBuffers_(hdc)
EndProcedure
User avatar
grabiller
Enthusiast
Enthusiast
Posts: 309
Joined: Wed Jun 01, 2011 9:38 am
Location: France - 89220 Rogny-Les-Septs-Ecluses
Contact:

Re: OpenGL (Canvas) Gadget

Post by grabiller »

The point of this feature request is not to find a workaround on how to set an OpenGL context and draw on it. We can do this already on any Window or Gadget (with the help of WindowID & GadgetID ), this is well known and it works perfectly well. Albeit having a native OpenGLGadget would ease the pain to setup an OpenGL context in a cross-platform application.

The point of this feature request is more to have a native OpenGLGadget which report user interactions events (mouse, keyboard, ..) like the CanvasGadget does.

Cheers,
Guy.
guy rabiller | radfac founder / ceo | raafal.org
Post Reply