Draw onto OpenGL / Display fullscreen?

Everything related to 3D programming
User avatar
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Draw onto OpenGL / Display fullscreen?

Post by em_uk »

Hi again,

From what I have found is that a lot of normal drawing commands aren't compatible with an OpenGL screen.

How do I do the following when using OpenGL :

1> Open a full screen OpenGL screen? (swap between OpenGLGadget and fullscreen)

2> Do normal 2D graphics on an OpenGL screen, such as displaying text, images on top?

Thanks!

:lol: :lol:
----

R Tape loading error, 0:1
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Draw onto OpenGL / Display fullscreen?

Post by applePi »

em_uk , about the second question, i have tried it on an example posted before http://www.purebasic.fr/english/viewtop ... 00#p445685 which should display a helix, it seems something like:

Code: Select all

StartDrawing(WindowOutput(0))
  DrawText(10, 10, "hello world")
  For y=40 To 200
    For x=30 To 200
       Plot(x,y,RGB(Random(255), Random(255), Random(255)))
     Next
  Next
  StopDrawing()
Image

do the trick, such as display text or plot 2D shapes such as random points, line ,circle.
note that the plot are targeting the window in which the opengl gadget are part from but not the openglgadget alone.
but i saw examples which display text on opengl window, can't remember now. my approach above seems easier to do and to remember. i will post any other finding.
the first question: Draw onto OpenGL / Display fullscreen? i think yes, i will search the available examples, i never get bothered with full screen since it leaves the user in the dark especially if the example hang the computer

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, "OpenGL demo")
SetWindowColor(0, 0)
OpenGLGadget(0, 0, 0, WindowWidth(0) , WindowHeight(0))
glLineWidth_(3)
Repeat
  
  spiral_render() 
  StartDrawing(WindowOutput(0))
  DrawText(10, 10, "hello world")
  For y=40 To 80
    For x=30 To 70
       Plot(x,y,RGB(Random(255), Random(255), Random(255)))
      
    Next
  Next
  LineXY(600, 10, 600, 500 , RGB(0,255,0)) 
  Circle(100,200, 60, RGB(255,255,0))

  StopDrawing()
  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
User avatar
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Re: Draw onto OpenGL / Display fullscreen?

Post by em_uk »

Thanks applePi.

But I am getting inconsistent results. In your example, I can see the helix the random pixels and the hello world text, but no circle and no line.

Image

And then if I move the Window to my second screen, I get different results again (I see the circle flash for a second near the end)

I had constructed the same theory last night, but when I attach my glshader to the window it overtakes everything and I can't displaying any other items.

hmmm
----

R Tape loading error, 0:1
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Draw onto OpenGL / Display fullscreen?

Post by applePi »

it is displayed on my screen the helix ,points,line, circle. my vga card is nvidea Geforce GT 520. try to comment plot(...) since plotting points are heavy task.
but we can (cheat), make your opengl gadget smaller and draw the heavy working things outside the gl area: look this screen:
Image
and here we simulate the Full screen by using openwindow flags #PB_Window_Maximize | #PB_Window_BorderLess )
but then we need to enable opengl keys so to exit by pressing ESC:
OpenGLGadget(0, 100, 100, 600 , 600, #PB_OpenGL_Keyboard ); added #PB_OpenGL_Keyboard
SetActiveGadget(0); set opengl gadget as active
then add something like this routine to work with opengl gadget keys:

Code: Select all

If Event = #PB_Event_Gadget And EventGadget() = 0 
      If EventType() = #PB_EventType_KeyDown
      
        key = GetGadgetAttribute(0,#PB_OpenGL_Key )
        Select key
          
          Case #PB_Shortcut_Add; if pressing "+"
            ;some code
          Case #PB_Shortcut_Escape
            quit = 1
        EndSelect
           
      EndIf
   EndIf   
i forgot to add the Demivec advice in the previous code http://www.purebasic.fr/english/viewtop ... 00#p445686
the Demivec advice may be the cure to the line+circle disappearance problem on your computer
Note: me too want to put the glsl shapes inside something like a room, i will think about this later.

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()
ExamineDesktops()
OpenWindow(0, 30, 30, DesktopWidth(0), DesktopHeight(0), "OpenGL demo", #PB_Window_Maximize | #PB_Window_BorderLess )
SetWindowColor(0, RGB(100,100,0))
OpenGLGadget(0, 100, 100, 600 , 600, #PB_OpenGL_Keyboard )
glLineWidth_(3)


SetActiveGadget(0); set opengl gadget as active

Define event, quit
Repeat
  Repeat
    event = WindowEvent()
    If event = #PB_Event_CloseWindow
      quit = #True
    EndIf
    If Event = #PB_Event_Gadget And EventGadget() = 0 
      If EventType() = #PB_EventType_KeyDown
      
        key = GetGadgetAttribute(0,#PB_OpenGL_Key )
        Select key
          
          Case #PB_Shortcut_Add; if pressing "+"
            ;some code
          Case #PB_Shortcut_Escape
            quit = 1
        EndSelect
           
      EndIf
   EndIf   
    
  Until event = 0 Or quit = #True
  
  
  spiral_render()  
  StartDrawing(WindowOutput(0))
  DrawText(200, 110, "hello world")
  For y=40 To 80
    For x=30 To 70
       Plot(x,y,RGB(Random(255), Random(255), Random(255)))
      
    Next
  Next
  
   LineXY(300, 10, 300, 500 , RGB(0,255,0)) 
   Circle(100,200, 60, RGB(255,255,0))
   StopDrawing()
  SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
  Delay(10)
Until quit = #True

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_(-30.0, 0.0, -120);
   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
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Draw onto OpenGL / Display fullscreen?

Post by Samuel »

I don't think you should use Purebasic's draw commands directly on the OpenGLGadget.

Instead draw to an image created with Purebasic and then create an opengl texture out of it. You can then display that texture onto a quad and have opengl render it for you.
User avatar
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Re: Draw onto OpenGL / Display fullscreen?

Post by em_uk »

Ok, thanks again. Using the second example I can see the PB graphics and then glviewport, but the text flickers and so does the yellow circle.

I think having a smaller view port could be one solution, but I understand what Samuel is saying. Draw my graphics and then convert to a texture.

The idea is to be able to draw to the opengl screen directly. Seems when I invoke a glCreateShader, then after any normal attempt to draw to the screen are hidden.

I'm looking at a few c++ examples where opengl is used, a lot of the gl frameworks looks the same.

I don't know how to draw to a texture I'm afraid.
----

R Tape loading error, 0:1
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Draw onto OpenGL / Display fullscreen?

Post by Samuel »

I don't know how to draw to a texture I'm afraid.
Maybe this will help. It's using old school OpenGL (no shaders), but you should get the general idea.

Code: Select all

UsePNGImageDecoder()
UseJPEGImageDecoder()

#IMG_24 = 0
#IMG_32 = 1

Declare OGL_CreateTexture(ImageHandle.i, Type.i)
Declare OGL_Render(GadgetHandle.i)

WindowW = 800
WindowH = 600

Global.i Texture

If OpenWindow(0, 0, 0, WindowW, WindowH, "OpenGL Gadget Textures", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

  OpenGLGadget(0, 0, 0, WindowW, WindowH)
  
  glMatrixMode_(#GL_PROJECTION)
  gluPerspective_(60.0, WindowW/WindowH, 0.1, 300.0) 
  glMatrixMode_(#GL_MODELVIEW)
  
	glBlendFunc_(#GL_SRC_ALPHA, #GL_ONE_MINUS_SRC_ALPHA)
	glEnable_(#GL_BLEND)

  glEnable_(#GL_TEXTURE_2D)
  
  CreateImage(0, 128, 128, 24)
  StartDrawing(ImageOutput(0))
    Box(0, 0, 64, 64, RGB(255,0,0))
    Box(64, 0, 64, 64, RGB(0,255,0))
    Box(0, 64, 64, 64, RGB(0,0,255))
    Box(64, 64, 64, 64, RGB(255,255,255))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(10, 100, "Test", RGB(0,0,0))
  StopDrawing()
  
  Texture = OGL_CreateTexture(0, #IMG_24)
  
  Repeat
    
    Event = WindowEvent()
    
    OGL_Render(0)
  
  Until Event = #PB_Event_CloseWindow
  
EndIf
End

Procedure OGL_CreateTexture(ImageHandle.i, Type.i)
  
  Define.i ImageW, ImageH
  Define.i MemoryAddress
  Define.i TextureHandle

  If IsImage(ImageHandle) = 0
    ProcedureReturn #False
  EndIf
  
  StartDrawing(ImageOutput(ImageHandle))
    MemoryAddress = DrawingBuffer()
  StopDrawing()
  
  If MemoryAddress = 0
    ProcedureReturn #False
  EndIf
  
  glGenTextures_(1, @TextureHandle)
  glBindTexture_(#GL_TEXTURE_2D, TextureHandle)
  
  ImageW = ImageWidth(ImageHandle)
  ImageH = ImageHeight(ImageHandle)
  
  If Type = 1
    glTexImage2D_(#GL_TEXTURE_2D, 0, 4, ImageW, ImageH, 0, #GL_RGBA, #GL_UNSIGNED_BYTE, MemoryAddress)
  Else
    glTexImage2D_(#GL_TEXTURE_2D, 0, 3, ImageW, ImageH, 0, #GL_RGB, #GL_UNSIGNED_BYTE, MemoryAddress)
  EndIf
    
  glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR)
  glTexParameteri_(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR)
  
  ProcedureReturn TextureHandle
  
EndProcedure

Procedure OGL_Render(GadgetHandle.i)
  
  Define.d StartX, StartY, EndX, EndY
  
  StartX = -1
  StartY = -1
  EndX   = 1
  EndY   = 1
  
  SetGadgetAttribute(GadgetHandle, #PB_OpenGL_SetContext, #True)
  
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  glClearColor_(0.1, 0.1, 0.1, 1.0)

  glMatrixMode_(#GL_MODELVIEW)
  glPushMatrix_()
  
  glTranslatef_(0, 0, -10)
  
  glBindTexture_(#GL_TEXTURE_2D, Texture)
   
  glBegin_(#GL_QUADS)
    glNormal3f_  (0,0,1.0)
    glTexCoord2f_(0.0,0.0)
    glVertex3f_  (StartX,StartY,0)
    glTexCoord2f_(1.0,0.0)
    glVertex3f_  (EndX,StartY,0) 
    glTexCoord2f_(1.0,1.0)
    glVertex3f_  (EndX,EndY,0) 
    glTexCoord2f_(0.0,1.0)
    glVertex3f_  (StartX,EndY,0)
  glEnd_()
  
  glPopMatrix_()
  glFinish_()
  
  SetGadgetAttribute(GadgetHandle, #PB_OpenGL_FlipBuffers, #True)

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

Re: Draw onto OpenGL / Display fullscreen?

Post by applePi »

thanks Samuel for the example
regarding the glsl , strange that we don't see 'glUseProgram' in this forum except the previous thread "Shader coding with PB possible?" by em_uk
but there is a 2 other examples in purebasic here: "GLSL fragment/vertex shader"
http://purebasic.info/phpBB3ex/viewtopic.php?f=9&t=2327
shader2.rar + shader3.rar . the first display mandelbrot set, the second display something animated very good indeed and can cause nausia and eyes blurr.
and it works with PB 5.31. just correct vsId.i = pid.i=CallFunctionFast... to vsId.i=CallFunctionFast
and fsId.i = pid.i=CallFunctionFast... to fsId.i=CallFunctionFast...
but what annoys me is that there is a usage of ASM in shader3.rar.
another link which have a shader example using glUseProgram is for Freebasic here http://www.freebasic-portal.de/tutorial ... rn-27.html
it compiles but the exe can't run and it needs png lib, just for who want to look at.
and by the way: he uses in the first purebasic shader2.rar example the :
glRects_( -1, -1, 1, 1 );
instead of
glBegin_(#GL_QUADS)
...
glEnd_()
User avatar
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Re: Draw onto OpenGL / Display fullscreen?

Post by em_uk »

Thanks applePi for those links. I've just had quick look at the code and it seems to use the same methodology as Pjays (Pjays implemantation is much cleaner IMO)

I don't know how much you know of shader scripting, but from what I have ready to make these shader effects work goes as follows :

we need to use the vertex processor and the fragment processor of the GPU, so we compile a script for each one. vert/frag.

These two scripts are then compiled and attached to a link program on the GPU processor. Once attached it will then run enitrley on the GPU until you tell it to stop (or the program ends or something).

What I have found so far is once you attatch a shader script and make it run, it will over take any other graphics that the opengl context is using.

I've tried to use Samuels example to "merge" two views but it doesn't seem to work. As soon as the the frag shader is made live (glUseProgram) it takes over the viewport. I know that you can use textures with fragment shaders which will probably enable me to draw regular 2d images in 3d space but I don't know (yet) how to get that included into PB. This is possibly because of the way the vertex pipeline works and my theory from 2D graphics just do not apply in the world of OpenGL (which I am still trying to understand).
----

R Tape loading error, 0:1
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Draw onto OpenGL / Display fullscreen?

Post by applePi »

i know nothing about shaders scripting, and when i look at the syntax i feel too bad. but who know may be when reading this tutorials https://www.opengl.org/sdk/docs/tutoria ... pter_3.pdf i change my mind. but i am interested in its mechanical usage and implementation in purebasic , i have noticed that they are overwhelming the other graphics, as an example the author of the shader2.rar/shader3.rar above was trying to rotate the rectangle, look the example, but this fails, edit his code : comment the 2 lines 80-81 begins with (vsId.i=)... and (fsId.i=) and will see the red rectangle rotating, but who know may be there is a possiblity to cast the shader over a small rotating plane or a cube. more research needed
anyway i am happy you have posted your previous thread: 'Shader coding with PB possible?', which without the forum will be empty from a code content have glUseProgram keyword inside. now google know what to do.
regards
User avatar
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Re: Draw onto OpenGL / Display fullscreen?

Post by em_uk »

Cool, I'll post some examples of what I've been trying to do later on when I get back home.

This source also seems to be quite good at explaining what is going on with shaders :

http://ogldev.atspace.co.uk/www/tutoria ... ial04.html

That resource you found also looks good - I will read that too.

Thanks
----

R Tape loading error, 0:1
User avatar
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Re: Draw onto OpenGL / Display fullscreen?

Post by em_uk »

Here's a little example using BASS to stream M1live while affect floats in the shader :

https://www.dropbox.com/s/pqkb0ks8626i2 ... t.zip?dl=0

(warning, it goes full screen windowed and plays music)

Image
----

R Tape loading error, 0:1
Post Reply