fbgfx versus opengl graphics

Post your FreeBASIC tips and tricks here. Please don’t post your code without including an explanation.
MrSwiss
Posts: 3610
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: fbgfx versus opengl graphics

Postby MrSwiss » Apr 09, 2020 21:22

"error 42: Variable not declared, SET_GL_2D_MODE"

fb.SET_GL_2D_MODE is only defined in FBC versions 1.06.0 or greater.
h4tt3n
Posts: 694
Joined: Oct 22, 2005 21:12
Location: Denmark

Re: fbgfx versus opengl graphics

Postby h4tt3n » Apr 10, 2020 6:49

SARG wrote:With lang fb it's in namespace FB

fb.GET_WINDOW_TITLE works.


That's it! Forgot the namespace. Should have learned by now not to code when tired.

So, to turn on open gl back end rendering, you simply calll:

Code: Select all

ScreenConrtol fb.SET_GL_2D_MODE


Without parameters? I tried the following before secreenres, but with no visible or measurable effect:

Code: Select all

   ScreenControl( fb.SET_GL_2D_MODE, fb.OGL_2D_AUTO_SYNC )
   ScreenControl( fb.SET_GL_SCALE, 0 )


It compiles but does nothing. Am I missing something?
badidea
Posts: 2149
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: fbgfx versus opengl graphics

Postby badidea » Apr 10, 2020 7:47

h4tt3n wrote:Without parameters? I tried the following before secreenres, but with no visible or measurable effect:

Code: Select all

   ScreenControl( fb.SET_GL_2D_MODE, fb.OGL_2D_AUTO_SYNC )
   ScreenControl( fb.SET_GL_SCALE, 0 )

It compiles but does nothing. Am I missing something?

You probably don't want to set the scale to 0.
Example from viewtopic.php?f=14&t=27886 :

Code: Select all

#define NO_BLUR 0 'change to 1

#include "fbgfx.bi"
using fb

screencontrol(SET_GL_2D_MODE, OGL_2D_MANUAL_SYNC)
screencontrol(SET_GL_SCALE, 3)
screenres 320, 200, 32, , GFX_OPENGL

#if (NO_BLUR = 1)
   #include "GL/gl.bi"
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
#endif

dim as integer w, h, d
dim as string driverName
screeninfo w, h, d, , , , driverName
print driverName & " @ " & str(w) & "x" + str(h) & "x" + str(d)
circle(320\2, 200\2), 90, rgb(200,200,0)

'' You need to poll flip() so the window doesn't become unresponsive
do
   sleep( 1, 1 )
   flip
loop until( len( inkey() ) )
coderJeff
Site Admin
Posts: 3316
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: fbgfx versus opengl graphics

Postby coderJeff » Apr 26, 2020 16:58

Very nice demo dodicat. Heres and elsewheres. I was working on understanding this feature in Jan 2020 before I had to step away for a while. This has been very helpful to test for bugs and try and clean up the original patch made. There's bugs with the autosync option; and still trying to derive it's purpose.

Bread crumbs:
Need new gfxlib driver for Windows 7, 8, 10
Tool for testing OpenGL blend modes.
Modern GL 2D game lib needed
Patch Rendering of FreeBasic graphic on OpenGL
angros47
Posts: 1673
Joined: Jun 21, 2005 19:04

Re: fbgfx versus opengl graphics

Postby angros47 » Apr 26, 2020 22:47

Since I developed the patch, I perhaps can answer about the autosync option: it allows OpenGL mode to work with no need to send the "flip" command to update the screen, so it will work like regular mode. Unfortunately, it also prevents using OpenGL commands, because the rendering happens in a separate thread, and OpenGL doesn't support multithreading at all: an OpenGL context can be used only in the same thread used to create it. So, what is the autosync mode good for? In my original intention, it would have allowed to use postfx shaders in Freebasic, with minimal changes to existing code (even commands like INPUT, that stop normal program flow, and would not allow to use FLIP, work normally in that mode). Unfortunately, the shaders should be loaded from the graphic thread, not from the main one: so, either we'd need to add a command for that (another option for ScreenControl, perhaps? The shader should be loaded while the graphic mode is set), or a callback, to allow users to write their own shader loading routine. Since FreeBasic is designed to use only the most basic features of OpenGL internally, I think a callback would be the best solution. But I wasn't sure, so I didn't implement it yet.

Still, at the moment, there is at least one feature implemented: the ability to rescale the screen size, using OpenGL (textures are pretty easy to scale).

If shaders could be implemented, they could be used, for example, to emulate different kind of screens (if an old game is ported to FreeBasic a shader could be used to simulate a CRT screen, for example)
dodicat
Posts: 6687
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: fbgfx versus opengl graphics

Postby dodicat » Apr 27, 2020 10:43

Thank you coder Jeff.
Good to see you back.
A little demo would not go amiss angros47.
Just to see the setup to get started using your textures, and we can see perhaps a simple line or circle by gfx and opengl together.
I have tried with no success, perhaps because I have Intel graphics on the motherboard, which can be problematic for opengl.
coderJeff
Site Admin
Posts: 3316
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: fbgfx versus opengl graphics

Postby coderJeff » Aug 01, 2020 20:18

o my gosh, 3 months later...

So, I have a fix for part of this sitting in my repo. I'm having a little trouble pulling the trigger to commit. I think because I wasn't original author. I have a feeling I will go ahead anyway and see what happens.... I wasn't able to fix or improve the 'auto' mode.
angros47
Posts: 1673
Joined: Jun 21, 2005 19:04

Re: fbgfx versus opengl graphics

Postby angros47 » Aug 04, 2020 19:53

I assume you ran in the same problems that forced me to leave the auto mode so limited?
coderJeff
Site Admin
Posts: 3316
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: fbgfx versus opengl graphics

Postby coderJeff » Aug 05, 2020 1:44

Not sure what problems you had exactly. I haven't seen your demo code for auto sync.

For Auto Sync:
- I think major design flaw is that SwapBuffers(hdc) in the main update loop is incorrect. If the main update loop just arbitrarily swaps buffers then there is no control of when drawing starts / stops / swaps. The only thing that make sense to me is some kind of copy-bufer-to-buffer if it's going to auto sync / update at regular intervals
- major bug: CreateThread handle is leaked. It doesn't get cleaned up.
- duplicated code, especially with setting up the attribs should be cleaned-up. It only differs by a *very* small amount.
- There's some bugs lurking having to do with the screen set-up through SCREENCONTROL. The values set should only affect the next screen mode created and have no effect on current mode, or will just crash.
- Maybe I don't understand the end goal, but SwapBuffers() doesn't seem right at all for auto sync. Swapping buffers only makes sense if there is some kind of sync with completion of drawing, and this main update loop just swaps all the time.

Code: Select all

   while (fb_win32.is_running)
   {
//fb_hWin32Lock();
      FB_GRAPHICS_LOCK( );
      fb_hGL_SetupProjection();
      SwapBuffers(hdc);
      driver_poll_events();
      FB_GRAPHICS_UNLOCK( );
//fb_hWin32Unlock();
      Sleep(10);
   }


In another effort, to deal with the context switching I tried modifying the main update loop and modifying SCREENLOCK/SCREENUNLOCK for Auto Sync:

Code: Select all

static void driver_lock(void)
{
   if (__fb_gl_params.mode_2d == DRIVER_OGL_2D_AUTO_SYNC){
      fb_hWin32Lock();
      fb_wgl.MakeCurrent(hdc, hglrc);
   }
}

static void driver_unlock(void)
{
   if (__fb_gl_params.mode_2d == DRIVER_OGL_2D_AUTO_SYNC){
      fb_wgl.MakeCurrent(NULL, NULL);
      fb_hWin32Unlock();
   }
}


Which kind of worked, but in my opinion was just replacing one synchronizing method: FLIP, for another SCREENLOCK/SCREENUNLOCK - and still has the same problems due to SwapBuffers().

I don't know man, it's not looking so good for auto sync. I'm tempted to drop the auto sync code and just work on stabalising the 'manual sync' feature. dodicat wrote a couple decent demos of mixing FBGFX and OGL commands to test with.
angros47
Posts: 1673
Joined: Jun 21, 2005 19:04

Re: fbgfx versus opengl graphics

Postby angros47 » Aug 06, 2020 18:55

- I think major design flaw is that SwapBuffers(hdc) in the main update loop is incorrect. If the main update loop just arbitrarily swaps buffers then there is no control of when drawing starts / stops / swaps. The only thing that make sense to me is some kind of copy-bufer-to-buffer if it's going to auto sync / update at regular intervals


There is no need to control drawing: in fact, any drawing made with OpenGL would be overwritten anyway when the texture quad is drawn, and the buffer swapping happens right after that
All drawing made with FreeBasic instruction happens on the texture, and the rendering/swapping just brings it on the screen, like it is supposed to happen in other modes like GDI/DirectX/X-Windows/Framebuffer

- Maybe I don't understand the end goal, but SwapBuffers() doesn't seem right at all for auto sync. Swapping buffers only makes sense if there is some kind of sync with completion of drawing, and this main update loop just swaps all the time.


If you want to sync with completion of drawing, you have to use manual sync. If you want to mix FreeBasic graphic and OpenGL graphic, you have to use manual sync. The end goal of autosync, actually, was to provide a method to use post processing shaders on Freebasic graphic. Since so far there is no way to load a shader (it should be loaded in the same context, hence in the same thread of the autosync, so it can't be loaded from the running Freebasic code), for now the autosync mode is pretty useless. I am aware of it. But if a way to load shaders is added in FreeBasic (I didn't do it because honestly I don't know how to add new commands), it would allow to have post processing (like... emulating a CRT monitor for retro-style games, or adding convolution filters, or hq2x upscaling for low res graphic)

I don't know man, it's not looking so good for auto sync. I'm tempted to drop the auto sync code and just work on stabalising the 'manual sync' feature.


I explained the reasons for the autosync code. I would suggest not to drop it, for those reasons, since in the future it can be expanded in a new set of features.
coderJeff
Site Admin
Posts: 3316
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: fbgfx versus opengl graphics

Postby coderJeff » Aug 16, 2020 22:35

Well, OK, I think I have fixed the worst bugs for this in fbc 1.08.0. I still think it has a ways to go, but I did leave in the auto sync stuff.

Here is a modified dodicat demo to play with. Run as-is to get as list of options. Or give it a command line argument of 1 to 7 to run the different options:

Code: Select all

#Include Once "GL/glu.bi"
#include once "fbgfx.bi"

using fb

Dim Shared As Integer xres,yres

Function Regulate(Byval MyFps As long,Byref fps As long) As long
    Static As Double timervalue,lastsleeptime,t3,frames
    Dim As Double t=Timer
    frames+=1
    If (t-t3)>=1 Then t3=t:fps=frames:frames=0
    Dim As long sleeptime=lastsleeptime+((1/myfps)-T+timervalue)*1000
    If sleeptime<1 Then sleeptime=1
    lastsleeptime=sleeptime
    timervalue=T
    Return sleeptime
End Function

Sub glsetup
    glShadeModel(GL_SMOOTH)                 ' Enables Smooth Color Shading
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
    glBlendFunc(GL_ONE,GL_ONE)
    glEnable GL_ALPHA
    glEnable GL_BLEND
    glViewport(0, 0, xres, yres)       ' Set the viewport
    glMatrixMode(GL_PROJECTION)        ' Change Matrix Mode to Projection
    glLoadIdentity                     ' Reset View
    gluPerspective(45.0, xres/yres, 1.0, 100.0)
    glMatrixMode(GL_MODELVIEW)         ' Return to the modelview matrix
    glLoadIdentity                     '  Reset View
    glclearcolor .2,0,0,1
End Sub

'Rotate and draw the cube with texturing on each face
Sub DrawGlCube(Byref rotangle As Single)
    glLoadIdentity()
    glTranslatef(0,0,-5)
    glRotatef(rotangle,1,.5,.25)           ' Rotate
    glBegin(GL_QUADS)
   
    glcolor3ub 255,0,0
    glVertex3f( 1.0, 1.0,-1.0)            ' Top right of the quad (top)
    glVertex3f(-1.0, 1.0,-1.0)            ' Top left of the quad (top)
    glVertex3f(-1.0, 1.0, 1.0)            ' Bottom left of the quad (top)
    glVertex3f( 1.0, 1.0, 1.0)            ' Bottom right of the quad (top)
   
    glcolor3ub 255,100,0
    glVertex3f( 1.0,-1.0, 1.0)            ' Top right of the quad (bottom)
    glVertex3f(-1.0,-1.0, 1.0)            ' Top left of the quad (bottom)
    glVertex3f(-1.0,-1.0,-1.0)            ' Bottom left of the quad (bottom)
    glVertex3f( 1.0,-1.0,-1.0)            ' Bottom right of the quad (bottom)
 
    glcolor3ub 255,0,255
    glVertex3f( 1.0, 1.0, 1.0)            ' Top right of the quad (front)
    glVertex3f(-1.0, 1.0, 1.0)            ' Top left of the quad (front)
    glVertex3f(-1.0,-1.0, 1.0)            ' Bottom left of the quad (front)
    glVertex3f( 1.0,-1.0, 1.0)            ' Bottom right of the quad (front)
   
    glcolor3ub 0,0,200
    glVertex3f( 1.0,-1.0,-1.0)            ' Bottom left of the quad (back)
    glVertex3f(-1.0,-1.0,-1.0)            ' Bottom right of the quad (back)
    glVertex3f(-1.0, 1.0,-1.0)            ' Top right of the quad (back)
    glVertex3f( 1.0, 1.0,-1.0)            ' Top left of the quad (back)
   
    glcolor3ub 0,255,0
    glVertex3f(-1.0, 1.0, 1.0)            ' Top right of the quad (left)
    glVertex3f(-1.0, 1.0,-1.0)            ' Top left of the quad (left)
    glVertex3f(-1.0,-1.0,-1.0)            ' Bottom left of the quad (left)
    glVertex3f(-1.0,-1.0, 1.0)            ' Bottom right of the quad (left)
   
    glcolor3ub 255,0,100
    glVertex3f( 1.0, 1.0,-1.0)            ' Top right of the quad (right)
    glVertex3f( 1.0, 1.0, 1.0)            ' Top left of the quad (right)
    glVertex3f( 1.0,-1.0, 1.0)            ' Bottom left of the quad (right)
    glVertex3f( 1.0,-1.0,-1.0)
    glend
End Sub
'=============== for ball only  =========
type pt
        as long x=100,y=100
        as single dx,dy
        as long kx,ky
    end type
sub ball()
    static as pt b
    static as long kx=1,ky=1
    b.dx=8
    b.dy=6.5
    b.x+=b.dx*kx:b.y+=b.dy*ky
    if b.x<50 or b.x>xres-50 then kx=-kx
    if b.y<50 or b.y>yres-50 then ky=-ky
    circle (b.x,b.y),50,rgb(0,100,255),,,,f
    end sub
'===============

dim as integer test = val( command(1) )


select case test
case 1
   '' plain ogl
case 2
   '' manual
   screencontrol SET_GL_2D_MODE ,OGL_2D_MANUAL_SYNC
case 3
   '' manual, scaling
   screencontrol SET_GL_2D_MODE ,OGL_2D_MANUAL_SYNC
   screencontrol SET_GL_SCALE,2
case 4, 6
   '' auto
   screencontrol SET_GL_2D_MODE ,OGL_2D_AUTO_SYNC

case 5, 7
   '' auto, scaling
   screencontrol SET_GL_2D_MODE ,OGL_2D_AUTO_SYNC
   screencontrol SET_GL_SCALE,2

case else
   print "1 - plain"
   print "2 - manual"
   print "3 - manual, scaling"
   print "4 - auto"
   print "5 - auto, scaling"
   print "6 - auto, screenlock"
   print "7 - auto, scaling, screenlock"
   end 1
end select

glsetup

Screenres 1024,512,32,,GFX_OPENGL
width 1024\8,512\16 'larger fonts
Screeninfo xres,yres

Dim As Single angle
dim as long fps
Do

   if( test >= 6 ) then
      screenlock
   end if

   if( test <> 4 and test <> 5 ) then
   
    ''glShadeModel(GL_SMOOTH)                 ' Enables Smooth Color Shading
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
    glBlendFunc(GL_ONE,GL_ONE)
    ''glEnable GL_ALPHA
    glEnable GL_BLEND
    glViewport(0, 0, xres, yres)       ' Set the viewport
    glMatrixMode(GL_PROJECTION)        ' Change Matrix Mode to Projection
    glLoadIdentity                     ' Reset View
    gluPerspective(45.0, xres/yres, 1.0, 100.0)
    glMatrixMode(GL_MODELVIEW)         ' Return to the modelview matrix
    glLoadIdentity                     '  Reset View
    glclearcolor .2,0,0,1

    angle=angle+1
    glClear(GL_COLOR_BUFFER_BIT)
 
    glEnable (GL_CULL_FACE)
    DrawGlcube(angle)
    gldisable (GL_CULL_FACE)

   end if
 
    cls
    glcolor3ub 255,255,255  'reset
    ball()
    draw string (20,20),"OpenGL cube with FreeBASIC ball and text",rgb(255,100,0)
    draw string (30,50),"Frames per second  = " &fps,rgb(255,255,255)
 
    if( test >= 6 ) then
      screenunlock
   end if

   if( test <= 3 ) then
      Flip
   end if

    Sleep regulate(30,fps),1

Loop Until Inkey=Chr(27)


for OGL_2D_AUTO_SYNC, the graphics window message pump lives in a separate thread. To acquire and release the opengl gfx context can use screenlock & screenunlock. There's no sync'ing going on in auto sync, so not sure of it's use.

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 3 guests