Tool for testing OpenGL blend modes.

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

Tool for testing OpenGL blend modes.

Postby D.J.Peters » Jan 30, 2020 15:23

There are 13*12 =156 possible combinations of glBlendFunc() arguments.

khronos: glBlendFunc

With cursor [LEFT] and [RIGHT] you can set all source argument and cursor [UP] and [DOWN] all destination argument.

Not all combinations makes sense nor produce any pixels !

Joshy

Code: Select all

#include once "GL/gl.bi"

#ifndef GL_BGRA
 #include once "GL/glext.bi"
#endif

#include once "fbgfx.bi"
#if __FB_LANG__ = "fb"
using FB
#endif

sub Perspective(fov as double, ratio as double, zNear as double=1, zFar as double=1000)
  if zNear<=0    then zNear=0.1
  if zFar<=zNear then zFar =zNear+100
  if fov<15      then fov  =15
  if fov>169     then fov  =160
  if ratio<=0    then ratio=1
  dim as double fH = tan( fov / 360.0 * 3.1415926535897932384626433832795 ) * zNear
  dim as double fW = fH * ratio
  glMatrixMode(GL_PROJECTION)
  glLoadIdentity()
  glFrustum(-fW,fW,-fH,fH,zNear,zFar)
end sub

sub LookAt(ex as double, ey as double, ez as double, _
           lx as double, ly as double, lz as double, _
           ux as double, uy as double, uz as double )
   dim as double z(2) = {ex-lx, _
                         ey-ly, _
                         ez-lz}
  dim as double l=z(0)*z(0)+z(1)*z(1)+z(2)*z(2)
  if (l) then l=1.0/sqr(l):z(0)*=l:z(1)*=l:z(2)*=l
 
  dim as double x(2)={ uy*z(2)-uz*z(1), _
                      -ux*z(2)+uz*z(0), _
                       ux*z(1)-uy*z(0)}
  l=x(0)*x(0)+x(1)*x(1)+x(2)*x(2)
  if (l) then l=1.0/sqr(l):x(0)*=l:x(1)*=l:x(2)*=l
 
  dim as double y(2)={ z(1)*x(2)-z(2)*x(1), _
                      -z(0)*x(2)+z(2)*x(0), _
                       z(0)*x(1)-z(1)*x(0)}

  l=y(0)*y(0)+y(1)*y(1)+y(2)*y(2)
  if (l) then l=1.0/sqr(l):y(0)*=l:y(1)*=l:y(2)*=l
 
  dim as double m4x4(15)=>{x(0),y(0),z(0),0, _
                           x(1),y(1),z(1),0, _
                           x(2),y(2),z(2),0, _
                              0,   0,   0,1}
  glMultMatrixd(@m4x4(0))
  glTranslated(-ex,-ey,-ez)
end sub

function initOpenGL(iWidth as integer=640,iHeight as integer=480,bFullscreen as boolean=false) as boolean
  if screenptr() then return false

screencontrol(SET_GL_2D_MODE ,OGL_2D_MANUAL_SYNC)
  screencontrol(SET_GL_SCALE, 1)
  Screenres iWidth,iHeight,32,,GFX_OPENGL or iif(bFullscreen,1,0)
  if screenptr()=0 then return false 
 
  var v = "OpenGL " & *glGetString(GL_VERSION) & " " & *glGetString(GL_VENDOR) & " " & *glGetString(GL_RENDERER)
   
  WindowTitle v
  ScreenInfo iWidth,iHeight
  Width iWidth\8,iHeight\16
  glViewport(0,0,iWidth,iHeight)
 
  Perspective(60,iWidth/iHeight)

  glMatrixMode(GL_MODELVIEW)
  glLoadIdentity()
 
  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
  glHint(GL_GENERATE_MIPMAP_HINT       , GL_NICEST)
  glHint(GL_FOG_HINT                   , GL_NICEST)
  glHint(GL_LINE_SMOOTH_HINT           , GL_NICEST)
  glHint(GL_POINT_SMOOTH_HINT          , GL_NICEST)
  glHint(GL_POLYGON_SMOOTH_HINT        , GL_NICEST)
 
  glShadeModel(GL_SMOOTH)
   
  glClearColor(0,.5,.5,1)
  glClearDepth(1)
  glEnable(GL_DEPTH_TEST)
 
  glFrontFace(GL_CCW)
  glCullFace(GL_FRONT)
  glEnable(GL_CULL_FACE) 

  return true
end function 


function CreateTexture() as gluint
  dim as ulong TextureName
  var img = ImageCreate(128,128,RGBA(128,128,128,255))
  if img=0 then return 0
 
  dim as any ptr pixels
  dim as integer w,h,bytes
  if ImageInfo(img,w,h,bytes,,pixels)<>0 or bytes<4 then
    ImageDestroy(img) : return 0
  end if
  ' define center of screen
  w/=2 : h/=2
  draw string img,(8,8),"RED",RGBA(255,0,0,255)
  draw string img,(128-6*8,8),"GREEN",RGBA(0,255,0,255)
  draw string img,(w-2*8,128-19),"BLUE",RGBA(0,0,255,255)
 
  circle img,(w,h),40,RGBA(0,0,0,0),,,,F
  draw string img,(w-8*2,h-16),"O NO",RGBA(255,255,255,255)
  draw string img,(w-8*4,h   ),"A HOLE !",RGBA(255,255,255,255)

  glGenTextures(1,@TextureName)
  if TextureName = 0 then ImageDestroy(img) : return 0
 
  glBindTexture(GL_TEXTURE_2D, TextureName)
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
 
  ' NOTE: if you create textures with FreeBASIC use GL_BGRA not GL_RGBA !
  glTexImage2D(GL_TEXTURE_2D, 0, 4, 128, 128, 0, GL_BGRA, GL_UNSIGNED_BYTE,pixels)
 
  glTexenvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
 
  ImageDestroy(img)
 
  return TextureName
end function


sub DrawCube
  static as gluint CubeList=0
  if CubeList=0 then
    CubeList = glGenLists(1)
    glNewList(CubeList, GL_COMPILE)
      glBegin(GL_QUADS)
     
        glNormal3f(0,0, 1) ' front
        glTexCoord2f(0,0) : glVertex3f(-.5, .5, .5)
        glTexCoord2f(0,1) : glVertex3f(-.5,-.5, .5)
        glTexCoord2f(1,1) : glVertex3f( .5,-.5, .5)
        glTexCoord2f(1,0) : glVertex3f( .5, .5, .5)

        glNormal3f(0,0,-1) ' back
        glTexCoord2f(0,0) : glVertex3f( .5, .5,-.5)
        glTexCoord2f(0,1) : glVertex3f( .5,-.5,-.5)
        glTexCoord2f(1,1) : glVertex3f(-.5,-.5,-.5)
        glTexCoord2f(1,0) : glVertex3f(-.5, .5,-.5)       

        glNormal3f(1,0,0) ' right
        glTexCoord2f(0,0) : glVertex3f( .5, .5, .5)
        glTexCoord2f(0,1) : glVertex3f( .5,-.5, .5)
        glTexCoord2f(1,1) : glVertex3f( .5,-.5,-.5)
        glTexCoord2f(1,0) : glVertex3f( .5, .5,-.5)       

        glNormal3f(-1,0,0) ' left
        glTexCoord2f(0,0) : glVertex3f(-.5, .5,-.5)
        glTexCoord2f(0,1) : glVertex3f(-.5,-.5,-.5)
        glTexCoord2f(1,1) : glVertex3f(-.5,-.5, .5)
        glTexCoord2f(1,0) : glVertex3f(-.5, .5, .5)

        glNormal3f(0,1,0) ' top
        glTexCoord2f(0,0) : glVertex3f(-.5, .5,-.5)
        glTexCoord2f(0,1) : glVertex3f(-.5, .5, .5)
        glTexCoord2f(1,1) : glVertex3f( .5, .5, .5)
        glTexCoord2f(1,0) : glVertex3f( .5, .5,-.5)

        glNormal3f(0,-1,0) ' bottom
        glTexCoord2f(0,0) : glVertex3f(-.5,-.5, .5)
        glTexCoord2f(0,1) : glVertex3f(-.5,-.5,-.5)
        glTexCoord2f(1,1) : glVertex3f( .5,-.5,-.5)
        glTexCoord2f(1,0) : glVertex3f( .5,-.5, .5)       

      glEnd()
    glEndList()
  end if
  if CubeList then glCallList(CubeList)
end sub

enum KeyCode
  K_NONE   =   0
  K_ESCAPE =  27
  K_UP     = 328 
  K_LEFT   = 331
  K_RIGHT  = 333
  K_DOWN   = 336
  K_CLOSE  = 363 ' close window
end enum

function GetKeyCode() as integer
  var s=inkey()
  var n=len(s)
  if n=0 then return 0
  n-=1
  return s[n] + n*256
end function

function BlendString(mode as ulong) as string
  #define defCase(_value_) case _value_ : return #_value_
  select case mode
  defCase(GL_ZERO)
  defCase(GL_ONE)
  defCase(GL_SRC_COLOR)
  defCase(GL_ONE_MINUS_SRC_COLOR)
  defCase(GL_DST_COLOR)
  defCase(GL_ONE_MINUS_DST_COLOR)
  defCase(GL_SRC_ALPHA)
  defCase(GL_ONE_MINUS_SRC_ALPHA)
  defCase(GL_DST_ALPHA)
  defCase(GL_ONE_MINUS_DST_ALPHA)
  defCase(GL_CONSTANT_COLOR)
  defCase(GL_ONE_MINUS_CONSTANT_COLOR)
  defCase(GL_CONSTANT_ALPHA)
  defCase(GL_ONE_MINUS_CONSTANT_ALPHA)
  defCase(GL_SRC_ALPHA_SATURATE)
 
  end select
#undef defCase
end function

sub FBGFX(bOn as boolean)
  if bOn then
    glDisable(GL_CULL_FACE)
    glEnable(GL_BLEND)
    glBlendFunc(GL_ONE,GL_ONE)
    glColor4f(1,1,1,1)
  else 
    glDisable(GL_BLEND)
    glEnable (GL_CULL_FACE)
  end if
end sub

'
' main
'
dim as ulong BlendSrc(...)=>{ _
  GL_ZERO,_
  GL_ONE, _
  GL_SRC_COLOR, _
  GL_ONE_MINUS_SRC_COLOR, _
  GL_SRC_ALPHA, _
  GL_ONE_MINUS_SRC_ALPHA, _
  GL_DST_ALPHA, _
  GL_ONE_MINUS_DST_ALPHA, _
  GL_CONSTANT_COLOR, _
  GL_ONE_MINUS_CONSTANT_COLOR, _
  GL_CONSTANT_ALPHA, _
  GL_ONE_MINUS_CONSTANT_ALPHA, _
  GL_SRC_ALPHA_SATURATE}
 
dim as ulong BlendDst(...)=>{ _
  GL_ZERO,_
  GL_ONE, _
  GL_DST_COLOR, _
  GL_ONE_MINUS_DST_COLOR, _
  GL_SRC_ALPHA, _
  GL_ONE_MINUS_SRC_ALPHA, _
  GL_DST_ALPHA, _
  GL_ONE_MINUS_DST_ALPHA, _
  GL_CONSTANT_COLOR, _
  GL_ONE_MINUS_CONSTANT_COLOR, _
  GL_CONSTANT_ALPHA, _
  GL_ONE_MINUS_CONSTANT_ALPHA} 
 
 

if InitOpenGL()=false then
  open err for output as #99
  print #88,"fatal error: can't create OpenGL context !"
  close #99
  beep : sleep : end 1
end if 

var TetureName = CreateTexture()
if TetureName=0 then
  open err for output as #99
  print #88,"fatal error: can't create Teture !"
  close #99
  beep : sleep : end 1
end if 

glEnable(GL_CULL_FACE)

' change it if you like !
var bUseLight = true

var a=1,b=5
glBlendFunc(BlendSrc(a),BlendDst(b))

' move the observer/camera
'glTranslatef(0,0,-2)
LookAt(0,0,2, 0,0,0, 0,1,0)

dim as single angle

var frame=0,fps=0
var key = GetKeyCode()
var tLast = timer()

' main loop
while key<>K_ESCAPE andalso key<>K_CLOSE
 
  key=GetKeyCode()
  if key then
    select case as const key
    case K_LEFT  : a-=1 : if a<0 then a=ubound(BlendSrc)
    case K_RIGHT : a+=1 : if a>ubound(BlendSrc) then a=0
    case K_DOWN  : b-=1 : if b<0 then b=ubound(BlendDst)
    case K_UP    : b+=1 : if b>ubound(BlendDst) then b=0
    end select
  end if 
   
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
  glPushMatrix() ' save current model matrix   

    ' disable features for background drawing
    glDisable(GL_TEXTURE_2D)
    glDisable(GL_LIGHTING)
    glDisable(GL_BLEND)   
   
    glBegin(GL_QUADS)
      ' left color background quad
      glColor4f(1,0,0,1) : glVertex3f(-2, .5, -1)
      glColor4f(0,1,0,1) : glVertex3f(-2,-.5, -1)
      glColor4f(0,0,1,1) : glVertex3f( 0,-.5, -1)
      glColor4f(0,0,0,1) : glVertex3f( 0, .5, -1)
      ' right white background quad
      glColor4f(1,1,1,1) : glVertex3f(0, .5, -1)
                           glVertex3f(0,-.5, -1)
                           glVertex3f(2,-.5, -1)
                           glVertex3f(2, .5, -1)
    glEnd()
   
    ' enable features for box drawing
    glEnable(GL_TEXTURE_2D)
    glBlendFunc(BlendSrc(a),BlendDst(b))
    glEnable(GL_BLEND)
   
    if bUseLight then
      glEnable(GL_LIGHTING)
      glEnable(GL_LIGHT0)
    else
      glDisable(GL_LIGHTING)
    end if 
       
    glRotatef(angle,0 ,1 ,0)
    glRotatef(angle,1 ,0 ,0)       
   
    ' draw front faces (counter clockwise)
    glFrontFace(GL_CCW)
    if bUseLight then glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,true)   
    drawCube()
   
    ' draw back faces (clockwise)
    glFrontFace(GL_CW)
    if bUseLight then glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,false)   
    drawCube()

    if bUseLight then glDisable(GL_LIGHTING)   
   
  glPopMatrix() ' restore the model matrix
   
  angle += .5

  frame+=1
  if frame mod 60=0 then
    ' update fps counter
    var tNow=Timer()
    fps=60/(tNow-tLast):tLast=tNow
  end if
   
  FBGFX(true) ' enable
  cls
  locate 2,2 : print "fps: " & fps
  locate 4,2 : print "[LEFT]<->[RIGHT] SRC: " & BlendString(BlendSrc(a))
  locate 5,2 : print "[DOWN]<->[UP]    DST: " & BlendString(BlendDst(b))
 
  flip
  sleep 10,1
  FBGFX(false) ' disable
 
wend
Last edited by D.J.Peters on Jan 31, 2020 3:50, edited 2 times in total.
badidea
Posts: 1764
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Tool for testing OpenGL blend modes.

Postby badidea » Jan 30, 2020 20:38

Here on linux, the screenres command results in (-exx):
"Aborting due to runtime error 1 (illegal function call) at line 69 of opengl01.bas::INITOPENGL()"
When using "ScreenControl(SET_GL_DEPTH_BITS ,32)"
Or when using "ScreenControl(SET_GL_NUM_SAMPLES , 2)" in some combination with "GFX_ACCUMULATION_BUFFER" or "GFX_MULTISAMPLE"
D.J.Peters
Posts: 7936
Joined: May 28, 2005 3:28

Re: Tool for testing OpenGL blend modes.

Postby D.J.Peters » Jan 31, 2020 3:24

Thank you for testing I removed the unnecessary stuff ;-)

Joshy
dodicat
Posts: 6139
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Tool for testing OpenGL blend modes.

Postby dodicat » Feb 01, 2020 0:22

What happened to your circle(x,y) . . . thing?
MrSwiss
Posts: 3348
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Tool for testing OpenGL blend modes.

Postby MrSwiss » Feb 01, 2020 0:56

dodicat wrote:What happened to your circle(x,y) . . . thing?

@dodicat, that is located in 'Beginners' ...

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 5 guests