general rotation/scaling support for 2D drawings?

Just starting out? Need help? Post your questions and find answers here.
Rozek
User
User
Posts: 64
Joined: Thu Jul 05, 2007 12:19 pm
Location: Böblingen (Germany)

general rotation/scaling support for 2D drawings?

Post by Rozek »

Hello!

This might be a dumb question (and should already have been answered somewhere else in this forum - but I could not find it):

To my understanding, the "2D Drawing" functions do not generically support translation/scaling/rotation of graphics contexts - am I right? There are some special drawing commands, though (for rotated text and images) but nothing similar for rectangles, circles etc. I could not even find polygons at all (which - with partial transparency and/or line width support - are more complicated than just adding individual lines together!)

Is there a (cross-platform) add-on (or similar) which adds this capability to PB?

[edit]Hmmm, could OpenGL be "abused" for sophisticated (cross-platform!) 2D drawing? (I'm no an OpenGL expert!)[/edit]

Thanks in advance for any hint!
Kind regards,

Andreas Rozek
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: general rotation/scaling support for 2D drawings?

Post by netmaestro »

Is there a (cross-platform) add-on (or similar) which adds this capability to PB?
For cross-platform maybe cairo, for Windows gdiplus would be my choice.
BERESHEIT
Rozek
User
User
Posts: 64
Joined: Thu Jul 05, 2007 12:19 pm
Location: Böblingen (Germany)

Re: general rotation/scaling support for 2D drawings?

Post by Rozek »

That's an interesting idea (Cairo)

Thanks for the hint!
Kind regards,

Andreas Rozek
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: general rotation/scaling support for 2D drawings?

Post by applePi »

Hi
indeed opengl can be used in 2D graphics, here is an example from the book "python programming in opengl" /stan blank page 102 can be downloaded for educational http://new.math.uiuc.edu/math198/repo/illipython/
its picture like this converted to purebasic
Image

the most important in 2D plot is the gluOrtho2D_(left, right, bottom, top) this instruction project your virtual window (in our example -10,10,-10,10) to the real physical window dimension. you don't need to do anything it is automaticaly project glVertex2f_(x, y) to the corresponding physical window.
i have inserted a flag so the plot is once to ease for the system, of course the plot will be erased if covered by other windows.

Code: Select all

;IncludeFile "OpenGL.pbi"
Global run.i = 0
Global axrng.f = 10.0
Global x.f=0: Global y.f=0: Global r.f=0: Global count.f=0
;glist
Procedure MyWindowCallback(WindowID, Message, wParam, lParam)
  Result = #PB_ProcessPureBasicEvents
  If Message = #WM_SIZE
    
    glViewport_ (0, 0, 450, 450)
    ;glMatrixMode_(GL_PROJECTION);
    ;gluOrtho2D_(-axrng, axrng, -axrng, axrng);
    ;glMatrixMode_(GL_MODELVIEW)
    ;glLoadIdentity_()
    Result = 1
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure mathart(hdc) ; drawcube procedure
      glPushMatrix_() 
      glClear_(GL_COLOR_BUFFER_BIT);

	    glClearColor_(1.0, 1.0, 1.0, 1.0);
	   ; make the glist
        ;glist = glGenLists(1);
        ;glNewList(glist, GL_COMPILE)
        glLoadIdentity_()
        
        x=-axrng
        While x <= axrng
          x = x + 0.03
          ;MessageRequester("Information", StrF(x), #PB_MessageRequester_Ok)
          y=-axrng
          While y <= axrng
            y = y + 0.03
            count = count + 1
            r = Cos(x) + Sin(y)
            glColor3f_(Cos(y*r), Cos(x*y*r), Sin(r*x))
            glBegin_(GL_POINTS)
            glVertex2f_(x, y) 
    	      glEnd_() ; finished 
    	      
           Wend
         Wend
         ;glEndList()
         ;glutSwapBuffers
         glPopMatrix_()
         glFinish_()
         SwapBuffers_(hdc)
         run=2  
        
    
EndProcedure



Procedure HandleError (Result, Text$)
  If Result = 0
    MessageRequester("Error", Text$, 0)
    End
  EndIf
EndProcedure


pfd.PIXELFORMATDESCRIPTOR

FlatMode = 0         ; Enable Or disable the 'Flat' rendering

WindowWidth  = 480   ; The window & GLViewport dimensions
WindowHeight = 480

hWnd = OpenWindow(0, 10, 10, WindowWidth, WindowHeight, "OpenGl 2D Drawing")

ButtonGadget(1, 10, 5, 45, 20, "Run")

SetWindowCallback(@MyWindowCallback())


hdc = GetDC_(hWnd)

pfd\nSize        = SizeOf(PIXELFORMATDESCRIPTOR)
pfd\nVersion     = 1
pfd\dwFlags      = #PFD_SUPPORT_OPENGL | #PFD_DOUBLEBUFFER | #PFD_DRAW_TO_WINDOW
pfd\dwLayerMask  = #PFD_MAIN_PLANE
pfd\iPixelType   = #PFD_TYPE_RGBA
pfd\cColorBits   = 16
pfd\cDepthBits   = 16 

pixformat = ChoosePixelFormat_(hdc, pfd)

HandleError( SetPixelFormat_(hdc, pixformat, pfd), "SetPixelFormat()")

hrc = wglCreateContext_(hdc)

HandleError( wglMakeCurrent_(hdc,hrc), "vglMakeCurrent()")

glMatrixMode_(#GL_PROJECTION)
; *ADDED* set the perspective, calculate the aspect ratio, set the clipping panes
 
gluOrtho2D_(-axrng, axrng, -axrng, axrng)
;glViewport_ (0, 0, 450, 450)
; 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.

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. 

;HandleError( glViewport_ (0, 0, WindowWidth-30, WindowHeight-30), "GLViewPort()")  ;  A rectangle which define the OpenGL output zone 

; edited the above line to display the true correct way to do this in PureBasic.
; Thanks to PetrSchreiber and others on www.codingmonkeys.com

glViewport_ (0, 0, WindowWidth, WindowHeight)
If glGetError_() = #GL_INVALID_VALUE Or error = #GL_INVALID_OPERATION
  HandleError (0, "GLViewPort()")
EndIf

While Quit = 0

  Repeat 
    EventID = WindowEvent()
    
    Select EventID
      Case #PB_Event_Gadget
          If EventGadget() = 1
            run.i = 1
          EndIf
          
           
      Case #PB_Event_CloseWindow
        Quit = 1
    EndSelect
  
  Until EventID = 0
  If run = 1 
    mathart(hdc)
    Delay(1)
  EndIf
Wend

End
here is how to make the plot persistent on the screen ,it is the same as the first one but in an attempt to refresh the window we store the vertexes in a list called here glist, then in any need to refresh the window it will call that glist to reploting the window
first

Code: Select all

;IncludeFile "OpenGL.pbi"
Global flag.i = 0
Global axrng.f = 10.0
Global x.f=0: Global y.f=0: Global r.f=0: Global count.f=0
Global glist.l
Procedure MyWindowCallback(WindowID, Message, wParam, lParam)
  Result = #PB_ProcessPureBasicEvents
  If Message = #WM_SIZE
    
    glViewport_ (0, 0, 450, 450)
    glPushMatrix_()
    glCallList_(glist)
    glPopMatrix_();
    
    Result = 1
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure mathart(hdc) ; drawcube procedure
      glPushMatrix_() 
      glClear_(GL_COLOR_BUFFER_BIT);

       glClearColor_(1.0, 1.0, 1.0, 1.0);
      ; make the glist
         ;glGenLists_(glist.l)
        glist = glGenLists_(1)
        glNewList_(glist, GL_COMPILE_AND_EXECUTE)
        glLoadIdentity_()
        
        x=-axrng
        While x <= axrng
          x = x + 0.03
          ;MessageRequester("Information", StrF(x), #PB_MessageRequester_Ok)
          y=-axrng
          While y <= axrng
            y = y + 0.03
            count = count + 1
            r = Cos(x) + Sin(y)
            glColor3f_(Cos(y*r), Cos(x*y*r), Sin(r*x))
            glBegin_(GL_POINTS)
            glVertex2f_(x, y) 
            glEnd_() ; finished 
             
           Wend
         Wend
         glEndList_()
         glPopMatrix_()
         glFinish_()
         SwapBuffers_(hdc)
         flag=1  
        
    
EndProcedure



Procedure HandleError (Result, Text$)
  If Result = 0
    MessageRequester("Error", Text$, 0)
    End
  EndIf
EndProcedure


pfd.PIXELFORMATDESCRIPTOR

FlatMode = 1         ; Enable Or disable the 'Flat' rendering

WindowWidth  = 480   ; The window & GLViewport dimensions
WindowHeight = 480

hWnd = OpenWindow(0, 10, 10, WindowWidth, WindowHeight, "OpenGl 2D Drawing")

ButtonGadget(1, 10, 5, 45, 20, "Run")

SetWindowCallback(@MyWindowCallback())


hdc = GetDC_(hWnd)

pfd\nSize        = SizeOf(PIXELFORMATDESCRIPTOR)
pfd\nVersion     = 1
pfd\dwFlags      = #PFD_SUPPORT_OPENGL | #PFD_DOUBLEBUFFER | #PFD_DRAW_TO_WINDOW
pfd\dwLayerMask  = #PFD_MAIN_PLANE
pfd\iPixelType   = #PFD_TYPE_RGBA
pfd\cColorBits   = 16
pfd\cDepthBits   = 16 

pixformat = ChoosePixelFormat_(hdc, pfd)

HandleError( SetPixelFormat_(hdc, pixformat, pfd), "SetPixelFormat()")

hrc = wglCreateContext_(hdc)

HandleError( wglMakeCurrent_(hdc,hrc), "vglMakeCurrent()")

glMatrixMode_(#GL_PROJECTION)
; *ADDED* set the perspective, calculate the aspect ratio, set the clipping panes

gluOrtho2D_(-axrng, axrng, -axrng, axrng)
glMatrixMode_ (#GL_MODELVIEW)

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.

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


glViewport_ (0, 0, WindowWidth, WindowHeight)
If glGetError_() = #GL_INVALID_VALUE Or error = #GL_INVALID_OPERATION
  HandleError (0, "GLViewPort()")
EndIf

While Quit = 0

  Repeat 
    EventID = WindowEvent()
    
    Select EventID
      Case #PB_Event_Gadget
          If EventGadget() = 1
            flag.i = 1
          EndIf
          If EventGadget() = 2
            glPushMatrix_()
              glCallList_(glist)
            glPopMatrix_();
          EndIf
                  
           
      Case #PB_Event_CloseWindow
        Quit = 1
    EndSelect
  
  Until EventID = 0
  If flag = 1 
    mathart(hdc)
    Delay(1)
  EndIf
Wend

End


here is a perl code which have glCallList($glist); and it is working perfectly, i have converted it to exe so you do not need perl installed on your system, but need the opengl dlls in the window directory, its picture like this:
http://img717.imageshack.us/img717/3622/2dopengl2.jpg
can be downloaded from here:
https://sites.google.com/site/zak31415/ ... hArt-1.rar
Last edited by applePi on Sat Mar 21, 2015 10:45 am, edited 3 times in total.
Rozek
User
User
Posts: 64
Joined: Thu Jul 05, 2007 12:19 pm
Location: Böblingen (Germany)

Re: general rotation/scaling support for 2D drawings?

Post by Rozek »

Thanks for these examples!

To my current understanding, Cairo may also use OpenGL "under the hood" - am I right?

I've looked at Cairo and am quite impressed! I think, I'll go for that library - it's both powerful and easy to use
Kind regards,

Andreas Rozek
Post Reply