glScreen.bi with VBO and Shader OpenGL extension's

Post your FreeBASIC tips and tricks here. Please don’t post your code without including an explanation.
D.J.Peters
Posts: 7858
Joined: May 28, 2005 3:28

glScreen.bi with VBO and Shader OpenGL extension's

Postby D.J.Peters » Nov 08, 2012 11:46

glScreen([width=800] , [height=600] , [ColorBits=24] , [DepthBits=16] , [StencilBits=8] , [FullScreen=0])

file: glScreen.bi

Code: Select all

#ifndef __GLSCREEN_BI__
#define __GLSCREEN_BI__

#include once "fbgfx.bi"
#include once "GL/gl.bi"
#include once "GL/glext.bi"

' define OpenGL proc
#define glDef(n) dim shared as PFN##n##PROC n
' get OpenGL proc (abort if something goes wrong)
#define glProc(n) n = ScreenGLProc(#n) : if n = 0 then screen 0 : ? "error: " & #n : sleep: end 

' VBO
glDef(glBindBuffer)
glDef(glDeleteBuffers)
glDef(glGenBuffers)
glDef(glIsBuffer)
glDef(glBufferData)
glDef(glBufferSubData)
glDef(glGetBufferSubData)
glDef(glMapBuffer)
glDef(glUnmapBuffer)
glDef(glGetBufferParameteriv)
glDef(glGetBufferPointerv)

' Shader
glDef(glCreateProgram)
glDef(glDeleteProgram)
glDef(glCreateShader)
glDef(glDeleteShader)
glDef(glCompileShader)
glDef(glIsProgram)
glDef(glIsShader)
glDef(glShaderSource)
glDef(glGetShaderInfoLog)
glDef(glGetShaderiv)
glDef(glAttachShader)
glDef(glDetachShader)
glDef(glLinkProgram)
glDef(glUseProgram)

sub glScreen(w as integer=800, h as integer=600, b as integer=24, d as integer=16, s as integer=8, f as integer=0)
  if ScreenPtr() then screen 0
  ScreenControl FB.SET_GL_STENCIL_BITS,s
  ScreenControl FB.SET_GL_DEPTH_BITS,d
  ScreenRes w,h,b,,FB.GFX_OPENGL or iif(f<>0,FB.GFX_FULLSCREEN,0)
  flip

  ' VBO
  glProc(glBindBuffer)
  glProc(glDeleteBuffers)
  glProc(glGenBuffers)
  glProc(glIsBuffer)
  glProc(glBufferData)
  glProc(glBufferSubData)
  glProc(glGetBufferSubData)
  glProc(glMapBuffer)
  glProc(glUnmapBuffer)
  glProc(glGetBufferParameteriv)
  glProc(glGetBufferPointerv)
  ' shader
  glProc(glCreateProgram)
  glProc(glDeleteProgram)
  glProc(glCreateShader)
  glProc(glDeleteShader)
  glProc(glCompileShader)
  glProc(glIsProgram)
  glProc(glIsShader)
  glProc(glShaderSource)
  glProc(glGetShaderInfoLog)
  glProc(glGetShaderiv)
  glProc(glAttachShader)
  glProc(glDetachShader)
  glProc(glLinkProgram)
  glProc(glUseProgram)
end sub
 
#endif ' __GLSCREEN_BI__

Gonzo
Posts: 722
Joined: Dec 11, 2005 22:46

Re: glScreen.bi with VBO and Shader OpenGL extension's

Postby Gonzo » Nov 08, 2012 13:50

very nice, as long as fb handles the opengl window correctly
can you hide the mouse in fb (not talking about windows specific, since fb is multiplay)? if not, it could be a problem for games

also it would be a boon if you could set context-specific settings
there are many specific things you can and sometimes need to add to the initializer before the context is created
multisampling, stereoscopy, fullscreen, context version and core/compatibility mode

you'll also need to check that the window was successfully created, including the context
(and validate the internal format, since if you request RGBA16F and the format is not supported, you'll need to adjust to RGBA8)
D.J.Peters
Posts: 7858
Joined: May 28, 2005 3:28

Re: glScreen.bi with VBO and Shader OpenGL extension's

Postby D.J.Peters » Nov 08, 2012 14:35

I wonder me why fbgfx switch to 32 bit
if my system supports 24 bit in fullscreen mode ?

Joshy
FreeBASIC wrote:wish: 4096 x 4096 x 24 fullscreen 0
fit: 1680 x 1050 x 24 fullscreen 1 ' here this mode fits
final: 1680 x 1050 x 32 fullscreen 1 ' fbgfx use 32 bit why not 24 ?!?

new version of glScreen.bi:

Code: Select all

#ifndef __GLSCREEN_BI__
#define __GLSCREEN_BI__

#include once "fbgfx.bi"
#include once "GL/gl.bi"
#include once "GL/glext.bi"


#ifdef USE_DPRINT
#define dprint(msg) open err for output as #99 : print  #99,msg : close #99 :
#else
#define dprint(msg) :
#endif


type VIDEOMODE
  as integer w,h,b,s,f ' width,height,bits,size,fullscreen
end type
type PVIDEOMODE  as VIDEOMODE  ptr

type VideoModes
  declare constructor
  declare destructor
  declare sub Fit(byref w as integer, _
                  byref h as integer, _
                  byref b as integer, _
                  byref f as integer)
  as VIDEOMODE      Desktop
  as VIDEOMODE      Current
  as PVIDEOMODE ptr p15,p16,p24,p32
  as integer        n15,n16,n24,n32
end type

#macro GETMODES(X)
  Mode = ScreenList(X)
  if Mode then
    dprint("modes with " & #X & " bits:")
    While (Mode <> 0)
      ' expand the list for one member
      p##X = reallocate(p##X,(n##X+1)*sizeof(PVIDEOMODE))
      ' allocate item
      p##X[n##X] = allocate(sizeof(VIDEOMODE))
      p##X[n##X]->w = HiWord(Mode)
      p##X[n##X]->h = LoWord(Mode)
      p##X[n##X]->s = p##X[n##X]->w*p##X[n##X]->h
      p##X[n##X]->b = X
      dprint("mode: " & p##X[n##X]->w & " x " & p##X[n##X]->h & " x " & p##X[n##X]->b)
      n##X+=1
      Mode = ScreenList()
    wend
    dprint("")
  end if 
#endmacro 

#macro FREEMODES(X)
  if p##X then
    while n##X
      n##X-=1: if p##X[n##X] then deallocate p##X[n##X]
    wend
    deallocate p##X 
  end if
#endmacro

constructor VideoModes
  dim as integer Mode
  dprint("VideoModes()")
  With DeskTop
    dprint("")
    ScreenInfo .w,.h,.b
    .s = .w * .h
    dprint("Desktop " & .w & " x " & .h  & " x " & .b)
    dprint("")
  end with 
   
  GETMODES(15)
  GETMODES(16)
  GETMODES(24)
  GETMODES(32)
end constructor

destructor VideoModes
  dprint("VideoModes~")
  FREEMODES(15)
  FREEMODES(16)
  FREEMODES(24)
  FREEMODES(32)
end destructor

' get nearest video mode params
sub VideoModes.Fit(byref w as integer, _
                   byref h as integer, _
                   byref b as integer, _
                   byref f as integer)
  dim as integer size = w*h

  if b=32 andalso p32=0 then b=24
  if b=24 andalso p24=0 then b=16
  if b=16 andalso p16=0 then b=15
 
  if size>Desktop.s then f=1
  ' no fullscreen
  if f=0 then return
 
  dim as PVIDEOMODE ptr pList
  dim as integer        nModes
  select case b
    case 15 : pList = p15 : nModes = n15
    case 16 : pList = p16 : nModes = n16
    case 24 : pList = p24 : nModes = n24
    case 32 : pList = p32 : nModes = n32
  end select 
 
  ' search a fullscreen mode
  dim as integer diff = size
  dim as integer indx = -1
  for i as integer = 0 to nModes-1
    if abs(pList[i]->s - size)<diff then
      indx=i:diff=abs(pList[i]->s - size)
    end if
  next
  w=pList[indx]->w
  h=pList[indx]->h
end sub                     

dim shared as VideoModes Modes

' define OpenGL proc
#define glDef(n) dim shared as PFN##n##PROC n
' get OpenGL proc (abort if something goes wrong)
#define glProc(n) n = ScreenGLProc(#n) : if n = 0 then screen 0 : ? "error: " & #n : sleep: end 

' VBO
glDef(glBindBuffer)
glDef(glDeleteBuffers)
glDef(glGenBuffers)
glDef(glIsBuffer)
glDef(glBufferData)
glDef(glBufferSubData)
glDef(glGetBufferSubData)
glDef(glMapBuffer)
glDef(glUnmapBuffer)
glDef(glGetBufferParameteriv)
glDef(glGetBufferPointerv)

' Shader
glDef(glCreateProgram)
glDef(glDeleteProgram)
glDef(glCreateShader)
glDef(glDeleteShader)
glDef(glCompileShader)
glDef(glIsProgram)
glDef(glIsShader)
glDef(glShaderSource)
glDef(glGetShaderInfoLog)
glDef(glGetShaderiv)
glDef(glAttachShader)
glDef(glDetachShader)
glDef(glLinkProgram)
glDef(glUseProgram)

sub glScreen(w as integer=800, h as integer=600, b as integer=24, d as integer=16, s as integer=8, f as integer=0)
  if ScreenPtr() then screen 0
 
  dprint("wish: " & w & " x " & h & " x " & b  & " fullscreen " & f)
 
  dim as integer minW = iif(f<>0,640,320)
  dim as integer minH = iif(f<>0,480,200)
 
  if w<minW then w=minW
  if h<minH then h=minH
   
  if b<16 then
    b=15
  elseif b<24 then
    b=16
  elseif b<32 then
    b=24
  else
    b=32
  end if     
 
  if d<8 then
    d=0
  elseif d<16 then
    d=8
  elseif d<24 then
    d=16
  elseif d<32 then
    d=24
  else
    d=32
  end if
 
  if s<1 then
    s=0
  elseif s<8 then
    s=1
  elseif s<16 then
    s=8   
  else
    s=16
  end if
 
  Modes.Fit(w,h,b,f)
 
  dprint("fit: " & w & " x " & h & " x " & b & " fullscreen " & f)
 
  if s then ScreenControl FB.SET_GL_STENCIL_BITS,s
  if d then ScreenControl FB.SET_GL_DEPTH_BITS,d
  ScreenRes w,h,b,,FB.GFX_OPENGL or iif(f<>0,FB.GFX_FULLSCREEN,0)
  flip
  with Modes.Current
    ScreenInfo .w,.h,.b
    .f = iif(f<>0,1,0)
    dprint("final: " & .w & " x " & .h & " x " & .b & " fullscreen " & .f)
  end with 

  ' VBO
  glProc(glBindBuffer)
  glProc(glDeleteBuffers)
  glProc(glGenBuffers)
  glProc(glIsBuffer)
  glProc(glBufferData)
  glProc(glBufferSubData)
  glProc(glGetBufferSubData)
  glProc(glMapBuffer)
  glProc(glUnmapBuffer)
  glProc(glGetBufferParameteriv)
  glProc(glGetBufferPointerv)
  ' shader
  glProc(glCreateProgram)
  glProc(glDeleteProgram)
  glProc(glCreateShader)
  glProc(glDeleteShader)
  glProc(glCompileShader)
  glProc(glIsProgram)
  glProc(glIsShader)
  glProc(glShaderSource)
  glProc(glGetShaderInfoLog)
  glProc(glGetShaderiv)
  glProc(glAttachShader)
  glProc(glDetachShader)
  glProc(glLinkProgram)
  glProc(glUseProgram)
end sub
 
#endif ' __GLSCREEN_BI__



test.bas

Code: Select all

#define USE_DPRINT ' enable dprint()
#include "glScreen.bi"

glScreen(4096,4096)

while inkey=""
  flip
  sleep 10
wend

output here:

Code: Select all

VideoModes()

Desktop 1680 x 1050 x 32

modes with 15 bits:
mode: 640 x 480 x 15
mode: 800 x 600 x 15
mode: 1024 x 768 x 15
mode: 1152 x 864 x 15
mode: 1280 x 960 x 15
mode: 1280 x 1024 x 15
mode: 1440 x 900 x 15
mode: 1600 x 900 x 15
mode: 1680 x 1050 x 15

modes with 16 bits:
mode: 640 x 480 x 16
mode: 800 x 600 x 16
mode: 1024 x 768 x 16
mode: 1152 x 864 x 16
mode: 1280 x 960 x 16
mode: 1280 x 1024 x 16
mode: 1440 x 900 x 16
mode: 1600 x 900 x 16
mode: 1680 x 1050 x 16

modes with 24 bits:
mode: 640 x 480 x 24
mode: 800 x 600 x 24
mode: 1024 x 768 x 24
mode: 1152 x 864 x 24
mode: 1280 x 960 x 24
mode: 1280 x 1024 x 24
mode: 1440 x 900 x 24
mode: 1600 x 900 x 24
mode: 1680 x 1050 x 24

modes with 32 bits:
mode: 640 x 480 x 32
mode: 800 x 600 x 32
mode: 1024 x 768 x 32
mode: 1152 x 864 x 32
mode: 1280 x 960 x 32
mode: 1280 x 1024 x 32
mode: 1440 x 900 x 32
mode: 1600 x 900 x 32
mode: 1680 x 1050 x 32

wish: 4096 x 4096 x 24 fullscreen 0
fit: 1680 x 1050 x 24 fullscreen 1
final: 1680 x 1050 x 32 fullscreen 1
VideoModes~
Gonzo
Posts: 722
Joined: Dec 11, 2005 22:46

Re: glScreen.bi with VBO and Shader OpenGL extension's

Postby Gonzo » Nov 08, 2012 14:53

strange
my bet is that not many opengl implementations support these strange formats
just keep in mind, in openGL you have 4 channels regardless of what you ask for!

it could also fallback to software mode for 24bits, until it reaches 4096 and gives up, and gives you hardware 32bit instead
im just guessing here though
TJF
Posts: 3486
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: glScreen.bi with VBO and Shader OpenGL extension's

Postby TJF » Nov 08, 2012 18:05

D.J.Peters wrote:I wonder me why fbgfx switch to 32 bit
if my system supports 24 bit in fullscreen mode ?

Its a speed issue. GPUs are optimized to work on 32 bit allignments. On some platforms they work on 64 bit borders. See cairo_image_surface_create_for_data ()

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 3 guests