display text in opengl

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
alfakilo
Posts: 117
Joined: Oct 02, 2009 9:18
Location: Estonia

display text in opengl

Post by alfakilo »

deleted
Last edited by alfakilo on Jul 07, 2014 18:32, edited 1 time in total.
dodicat
Posts: 7987
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: display text in opengl

Post by dodicat »

Thanks.
Basic text in opengl can be incorporated in about 100 lines of code (DOS fonts).

I have used code from the examples folder and added some text.

The text is written in ortho projection, so you have to dip into ortho to write it then get back out of ortho to your original set up.
The text can be rotated somewhat by a line angle, or the characters can be rotated by a character angle (small number of degrees perhaps to give Italic effect).
But I have only used straight text here.
Also the pipe thingy ( |) can be used for a new line.

Code: Select all

''
''	This is a quick port of NeHe lesson 4
''
''	Go to http://nehe.gamedev.net for his other great OpenGL tutorials!
''


#include "fbgfx.bi"
#include "GL/gl.bi"
#include "GL/glu.bi"
'====================  TEXT STUFF ===================
dim shared as integer xres,yres

Sub Save_projection
    glMatrixMode GL_PROJECTION
    glPushMatrix
    glMatrixMode GL_MODELVIEW
    glPushMatrix
End Sub

Sub Ortho_projection
    glMatrixMode GL_PROJECTION
    glLoadIdentity
    glOrtho 0, xres, yres, 0,-1, 1
    glMatrixMode GL_MODELVIEW
    glLoadIdentity
End Sub

Sub Restore_projection
    glMatrixMode GL_PROJECTION
    glPopMatrix
    glMatrixMode GL_MODELVIEW
    glPopMatrix
End Sub
Sub drawstring(xpos As Integer,ypos As Integer,text As String,col as uinteger,size As Single,textangle As Single=0,charangle As Single=0)
       
#define Red(c) ((c) Shr 16 And 255)/255 
#define Green(c) ((c) Shr  8 And 255)/255 
#define Blue(c) ((c) And 255)/255 
#define Alph(c) ((c) Shr 24)/255  
    glColor4f Red(col),Green(col),Blue(col),alph(col)
    glend
    glpointsize(1.1*size)
    glBegin (GL_POINTS)
    Type point2d
        As Single x,y
    End Type
    Dim As Integer flag,codenum=256 
    If Instr(text,"|") Then flag=1
    Static As Integer runflag
    Static As point2d infoarray()
    Redim Preserve As point2d infoarray(64,codenum) '64 = 8 x 8 pixel size
    If runflag=0 Then   '                  'scan codenum of codepage once
        Dim As Uinteger background=0
        Screenres 10,10  '8 x 8 pixels on this screen
        Dim count As Integer
        For ch As Integer=1 To codenum
            Cls
            Draw String(1,1),Chr(ch)
            For x As Integer=1 To 8  'scan for characters
                For y As Integer=1 To 8
                    If Point(x,y)<>background Then
                        count=count+1
                        infoarray(count,ch)=Type<point2d>(x,y)'save pixel position
                    End If 
                Next y
            Next x
            count=0
        Next ch
        runflag=1 
    End If
    If size=0 Then Exit Sub
    Dim As point2d temp(1 To 64,codenum),np
    Dim As Single cr= 0.01745329 'degs to radians
    #macro rotate(p1,p2,a,d)
    np.x=d*(Cos(a*cr)*(p2.x-p1.x)-Sin(a*cr)*(p2.y-p1.y)) +p1.x
    np.y=d*(Sin(a*cr)*(p2.x-p1.x)+Cos(a*cr)*(p2.y-p1.y)) +p1.y
    #endmacro
    
    Dim As point2d cpt(1 To 64),c=Type<point2d>(xpos,ypos),c2
    Dim As Integer dx=xpos,dy=ypos
    For z6 As Integer=1 To Len(text)
        Var asci=text[z6-1]
        If asci=124 Then 
            If charangle<>0 Then xpos=xpos+12*Sin(charangle*cr)
            dx=xpos:dy=dy+12:Goto skip 'pipe | for new line
        End If
        For _x1 As Integer=1 To 64
            temp(_x1,asci).x=infoarray(_x1,asci).x+dx
            temp(_x1,asci).y=infoarray(_x1,asci).y+dy
            rotate(c,temp(_x1,asci),textangle,size)
            cpt(_x1)=np
            Var copyy=np.y
            If charangle<>0 Then
                Dim As Integer p
                If flag Then  p=1 Else  p=(z6-1)
                c2=Type<point2d>(xpos+(size*8)*p*(Cos(textangle*cr)),ypos+(size*8)*p*(Sin(textangle*cr))) 
                rotate(c2,cpt(_x1),charangle,1)
                If flag Then np.y=copyy
                cpt(_x1)=np
            End If
            If infoarray(_x1,asci).x<>0 Then 'paint only relevant points
                If Abs(size)>0 Then
                    glVertex3f (cpt(_x1).x,(cpt(_x1).y),0)
                End If
            End If
        Next _x1
        dx=dx+8+4*(Sin(charangle*cr))*flag
        skip:
    Next z6 
    glend
End Sub
Sub init Constructor 'automatic loader
    drawstring(0,0,"",0,0)
    Screen 0
End Sub

'====================================================
        
	dim rtri as single, rquad as single
	
	screen 18, 32, , FB.GFX_OPENGL or FB.GFX_MULTISAMPLE
    screeninfo xres,yres  'text stuff
	
	glViewport 0, 0, 640, 480
	glMatrixMode GL_PROJECTION
	glLoadIdentity
	gluPerspective 45.0, 640.0/480.0, 0.1, 100.0
	glMatrixMode GL_MODELVIEW
	glLoadIdentity
	
	glShadeModel GL_SMOOTH
	glClearColor 0.0, 0.0, 0.0, 1.0
	glClearDepth 1.0
	glEnable GL_DEPTH_TEST
	glDepthFunc GL_LEQUAL
	glHint GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST
    
        var renderer=*glGetString(GL_RENDERER)
        var  vendor=*glGetString(GL_VENDOR)
        var version=*glGetString(GL_VERSION)
	
	do
		glClear GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT
		glLoadIdentity
		glTranslatef -1.5, 0.0, -6.0
		glRotatef rtri, 0, 1, 0
		glBegin GL_TRIANGLES
			glColor3f 1.0, 0.0, 0.0
			glVertex3f 0.0, 1.0, 0.0
			glColor3f 0.0, 1.0, 0.0
			glVertex3f -1.0, -1.0, 0.0
			glColor3f 0.0, 0.0, 1.0
			glVertex3f 1.0, -1.0, 0.0
		glEnd
		
		glLoadIdentity
		glTranslatef 1.5, 0.0, -6.0
		glColor3f 0.5, 0.5, 1.0
		glRotatef rquad, 1, 0, 0
		glBegin GL_QUADS
			glVertex3f -1.0, 1.0, 0.0
			glVertex3f 1.0, 1.0, 0.0
			glVertex3f 1.0, -1.0, 0.0
			glVertex3f -1.0, -1.0, 0.0
		glEnd
		rtri += 0.2
		rquad += 0.15
        'TEXT
        '======= Save projection/ go into ortho/ then restore =======
        save_projection
        ortho_projection
        drawstring(20,20,"Timer --> " &timer,rgb(0,200,0),1)
        drawstring(20,40,"Renderer " &renderer,rgb(200,0,0),1.5)
        drawstring(20,60,"Vendor " &vendor,rgb(0,0,200),1.5)
        drawstring(20,80,"OpenGL Version " &version,rgb(200,200,200),1.5)
        'Use | for a newline
        drawstring(5,400,"HIT any key to EXIT|Thank You",rgba(200,150,0,200),2)
        restore_projection
        '========================
		flip
	loop while inkey = ""
	
 
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: display text in opengl

Post by D.J.Peters »

Hi dodicat i played with your tiny and nice GL drawstring
I saw you calculate sin,cos and deg2rad for every pixel and i removed some other stuf
by the way you can use glColor4ub so there is no need for RGBA triple division by 255.

Looks like you missed glEnable(GL_BLEND) if alpha <>255 !

Joshy

Code: Select all

#lang "fb"
#include "fbgfx.bi"
#include "GL/gl.bi"
#include once "crt.bi"

' yes glFrustum works fine with double
sub Perspective(byval fov as double, byval ratio as double, byval zNear as double, byval zFar as double)
  dim as double fH = tan( fov / 360.0 * 3.1415926535897932384626433832795 ) * zNear
  dim as double fW = fH * ratio
  glFrustum(-fW, fW,-fH, fH, zNear, zFar)
end sub

sub TextMode(byval onoff as boolean)
  if onoff then
    glMatrixMode(GL_PROJECTION) : glPushMatrix()
    glMatrixMode(GL_MODELVIEW)  : glPushMatrix()
    glMatrixMode(GL_PROJECTION) : glLoadIdentity()
    dim as integer w,h
    screeninfo(w,h)
    glOrtho(0,w,h,0,-1, 1)
    glMatrixMode(GL_MODELVIEW)  : glLoadIdentity()
  else
    glMatrixMode GL_PROJECTION  : glPopMatrix()
    glMatrixMode GL_MODELVIEW   : glPopMatrix()
  end if
end sub

sub drawstring(byval xpos      as integer, _
               byval ypos      as integer, _
               byval text      as string, _
               byval col       as ulong  = &HFFFFFFFF, _
               byval size      as single = 1, _
               byval textangle as single = 0, _
               byval charangle as single = 0)
  static as boolean runflag=false
  static as single f(63,223,1)
  static as single t(63,223,1)
  static as single cpt(63,1)
  If runflag=false then
    screenres(8,8,8,,-1)
    for char as integer = 0 To 223
      draw string(0,0),chr(32+char)
      dim as Integer c
      for y as Integer =0 to 7
        for x as Integer =0 to 7
          if point(x,y) then
            f(c,char,0)=x
            f(c,char,1)=y
          else
            f(c,char,0)=-1
          end if
          c+=1
        next
      next
      cls
    next
    runflag=true
  End If

  var nChars = len(text)
  if nChars<1 then return
  if fabsf(size)<0.01 then size=0.01
  textangle *= 0.01745329
  charangle *= 0.01745329
  dim as single tc = cosf(textangle),ts=sinf(textangle)
  dim as single cc = cosf(charangle),cs=sinf(charangle)
  dim as single _x,_y
  #macro rotate(p1x,p1y,p2x,p2y,_c,_s,_r)
    _x=(p2x)-(p1x) : _y=(p2y)-(p1y)
    np(0)=p1x+((_c)*(_x)-(_s)*(_y))*(_r)
    np(1)=p1y+((_s)*(_x)+(_c)*(_y))*(_r)
  #endmacro
 
  var alpha_ = col shr 24
  if (alpha_<>255) then
    glEnable(GL_BLEND)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    glColor4ub(col shr 16, col shr 8, col, alpha_)
  else
    glColor3ub(col shr 16, col shr 8, col)
  end if

  glPointSize(size)
  glBegin(GL_POINTS)
  dim as single np(1)
  dim as single c(1)=>{xpos,ypos}
  dim as single c2(1)
  dim as integer dx=xpos,dy=ypos
  for n as integer = 0 to nChars-1
    var char = text[n]
    if (char<>124) then
      char-=32
      for x as integer = 0 To 63
        if f(x,char,0)>-1 then
          t(x,char,0)=f(x,char,0)+dx
          t(x,char,1)=f(x,char,1)+dy
          rotate(c(0),c(1),t(x,char,0),t(x,char,1),tc,ts,size)
          cpt(x,0)=np(0) : cpt(x,1)=np(1)
          if (charangle<>0.0f) then
            c2(0)=xpos+(size*8)*n*cosf(textangle)
            c2(1)=ypos+(size*8)*n*sinf(textangle)
            rotate(c2(0),c2(1),cpt(x,0),cpt(x,1),cc,cs,1)
            cpt(x,0)=np(0):cpt(x,1)=np(1)
          end if
          glVertex2fv(@cpt(x,0))
        end if
      next
      dx+=8
    else
     if (charangle<>0.0f) then xpos+=8*sinf(charangle)
     dx=xpos:dy+=8
    end if
  next
  glEnd()
  if (alpha_<>255) then glDisable(GL_BLEND)
  glPointSize(1)
End Sub

sub draw_init constructor ' automatic loader
  drawstring(0,0,"")
end Sub

'
' main
'
dim as single rtri,rquad,iFrames,iFPS
dim as double tNow,tLast
dim as integer w,h
dim as string renderer, vendor, version

screenres(800,600,32,,FB.GFX_OPENGL or FB.GFX_MULTISAMPLE) ' or FB.GFX_FULLSCREEN

screeninfo(w,h)
glViewport(0,0,w,h)
glMatrixMode(GL_PROJECTION) : glLoadIdentity()
Perspective(45.0, w/h, 0.1, 100.0)
glMatrixMode(GL_MODELVIEW) : glLoadIdentity()

glShadeModel(GL_SMOOTH)
glClearColor(0.0, 0.0, 0.0, 1.0)
glClearDepth(1.0)
glEnable(GL_DEPTH_TEST) : glDepthFunc(GL_LEQUAL)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)

renderer = *glGetString(GL_RENDERER)
vendor   = *glGetString(GL_VENDOR)
version  = *glGetString(GL_VERSION)

tLast = Timer()
while inkey() = ""
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
  glLoadIdentity()
  glTranslatef(-1.5, 0.0, -6.0)
  glRotatef(rtri, 0, 1, 0)
  glBegin(GL_TRIANGLES)
    glColor3f(1,0,0) : glVertex3f( 0, 1, 0)
    glColor3f(0,1,0) : glVertex3f(-1,-1, 0)
    glColor3f(0,0,1) : glVertex3f( 1,-1, 0)
  glEnd()

  glLoadIdentity()
  glTranslatef(1.5, 0.0, -6.0)
  glColor3f(0.5, 0.5, 1.0)
  glRotatef(rquad, 1, 0, 0)
  glBegin(GL_QUADS)
    glVertex3f(-1, 1, 0)
    glVertex3f( 1, 1, 0)
    glVertex3f( 1,-1, 0)
    glVertex3f(-1,-1, 0)
  glEnd()
  tNow = Timer()
  TextMode(true)
    drawstring(20, 20,"Timer "    & tNow,              rgb (  0,200,  0    ))
    drawstring(20, 40,"Renderer " & renderer,          rgb (200,  0,  0    ),1.5)
    drawstring(20, 60,"Vendor "   & vendor,            rgb (  0,  0,200    ),1.5,1,15)
    drawstring(20, 80,"OpenGL Version " & version,     rgb (200,200,200    ),1.5,15)
    drawstring(20,220,"Alpah Alpha Alpha Alpha Alpha" ,rgba(  0,255,255, 64),2.0)
    'Use | for a newline
    drawstring(50,350,"HIT any key to EXIT|    Thank You",rgb(200,150,  0),3.0,15)
  TextMode(false)
  rtri += 0.5 : rquad += 1
  iFrames+=1
  if iFrames mod 60=0 then
    iFPS=60.0/(tNow-tLast) : tLast=tNow
    WindowTitle("FPS: " & iFPS)
  end if
  flip : sleep (10)
wend 
Last edited by D.J.Peters on Apr 17, 2018 4:17, edited 4 times in total.
sero
Posts: 59
Joined: Mar 06, 2018 13:26
Location: USA

Re: display text in opengl

Post by sero »

Very sorry to bring up an old post but in studying and testing both examples provided above I encounter a problem. When the text size is 1.0 it appears nothing is drawn to the screen. If I send a size of 0.9 or 1.1 then things get drawn to the screen. Rotating the text or character will draw to the screen if size is 1.0

I'm new to learning about OpenGL and was looking for a draw text method similar to FreeBasic's custom Put function. I really appreciate this thread because it uses an array to store points that OpenGL reads to paint pixels on the screen using the assigned color.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: display text in opengl

Post by D.J.Peters »

I updated the old code and removed the lib glut and it's more cleaner now.

@sero It works as it should here
post an short example of the problem.

Joshy
sero
Posts: 59
Joined: Mar 06, 2018 13:26
Location: USA

Re: display text in opengl

Post by sero »

In this first image my laptop does not render the 1.0 problem when there is no rotation.
https://flic.kr/p/25b1R9E

In this second image from an alternate computer everything renders but the pixels look heavier.
https://flic.kr/p/23vcme1

*edit *
I installed Virtual Box with XP 32bit and finally got to see this code execute properly. Looks like my only two test machines are proving themselves fallible but at least now I have XP and soon Linux to fall back on. Maybe Spectre Meltdown has something to do with this or maybe it was a faulty Minecraft skin I downloaded from that sketchy website. Perhaps I should stick to my TI-84 if only I could use it to program with :P
Post Reply