[futurebasic] Re: [FB] Tree Foliage Example Improvement - OpenGL

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : May 2009 : Group Archive : Group : All Groups

From: andy@...
Date: Fri, 22 May 2009 12:05:49 +0100 (BST)

As previously mentioned, I've now moved the Fractal Tree to OpenGL. The
code below can be entered in RP's (excellent) OpenGL testbed and set
_example to 24 in the main section. It is only 2D but can be easily
converted to 3D. However, it does rather hit the frame rate! I've reduced
the branch recursion down to essentially zero for low levels of detail. I
could install quads for the leaves rather than particles but I'd imagine
the frame rate would suffer even more.

I'm still scratching my head on the best way to insert lots of trees into
my game program that looks reasonable and at lowest impact to the
framerate.
I may return to my current method which uses textured quads.

As before this is FB4 I haven't tested in FB5 (but I will be moving my
code over to FB5 shortly).

/*
fractal trees

AP   May 2008
*/

#if _example == 24


local mode
local fn WindowSizeGL
dim as Point  size
size.h% = 32767
size.v% = 32767
end fn = size


begin globals
dim as GLdouble  sRotX, sRotY, sRotZ // static vars for DrawGL
dim as double radians#
dim gglList(1)  as GLuint
dim gstep//changed if you press SPACE
end globals




local fn leaves(x1 as double,y1 as double,myinc,col,lod)
dim as double x,y
dim i
for i=1 to 20
x=rnd(10)
y=rnd(10)
x=x1+x-5
y=y1+y-5
glpointsize(rnd(20-lod)+1)
if lod<0 then glcolor3d (0,0,0) else glcolor3d (rnd(50)/100,rnd(50)/100,0)
glbegin(_glPoints)
glVertex3f(x,y,0)
glend
next

end fn

local fn branch(x  as double,y  as double,myinc  as double,angle  as
double,col,lod)

dim as double x1
dim as double y1
dim as double newinc

x1=x+cos(angle*radians#)*myinc
y1=y+sin(angle*radians#)*myinc
glLineWidth( myinc/2 )
glcolor3d(0,0,0)
glBegin(_gllines)
glvertex3i(x,y,0)
glvertex3i(x1,y1,0)
glend
newinc=myinc-myinc*2/3
'long if newinc<lod/10
long if newinc<(7-lod)*2
fn leaves(x1,y1,myinc,col,lod)
xelse
fn branch(x1,y1,newinc,angle-rnd(45),col,lod)
fn branch(x1,y1,newinc,angle+rnd(45),col,lod)
end if
end fn

local fn maketree(x as double,y  as double,myinc  as double,lod)
dim i,j
dim as double h,x1,y1,myinc1


//draw trunk
x1=x
y1=y
myinc1=myinc
for i=1 to 3
h=y1+myinc1
glLineWidth( 17 )
glcolor3d(0,0,0)
glBegin(_gllines)
glvertex3i(x1+(4-i)*-1*.7,y1,0)
glvertex3i(x1+(4-i)*-1*.4,h,0)
glend
for j=(3-i)*-1 to 3-i
glLineWidth( 20 )
glcolor3d(0,0,0)
glBegin(_gllines)
glvertex3i(x1+j*.7,y1,0)
glvertex3i(x1+j*.4+rnd((4-i)*.8)-(4-i)*.4,h,0)
glend
next
glLineWidth( 17 )
glcolor3d(0,0,0)
glBegin(_gllines)
glvertex3i(x1+(4-i)*.7,y1,0)
glvertex3i(x1+(4-i)*.4,h,0)
glend
y1=h
myinc1=myinc1-myinc1/5
next

//draw branches
x1=x
y1=y
myinc1=myinc
for i=1 to 3
h=y1+myinc1
fn branch(x1,h,myinc1*.5,45+rnd(90),-1,lod)
fn branch(x1,h,myinc1,45,0,lod)
fn branch(x1,h,myinc1,180/3,0,lod)
fn branch(x1,h,myinc1,2*180/3,0,lod)
fn branch(x1,h,myinc1,135,0,lod)
fn branch(x1,h,myinc1*.5,70+rnd(40),0,lod)
y1=h
myinc1=myinc1-myinc1/5
next
glLineWidth( myinc1*10 )
fn branch(x,h,myinc1*1.3,85,0,lod+1)
fn branch(x,h,myinc1*1.3,95,0,lod+1)


end fn


local fn DrawGL
'~'1
dim i
glClear(_GLCOLORBUFFERBIT )
glColor3f (1.0, 0.0, 0.0)
glLoadIdentity() // Reset The Modelview Matrix
'glTranslatef(0.0, 0.0,-4.5 )   // Move Into The Screen 4.5



//press SPACE to change view
if inkey$=" " then gstep++:gglList(1) = 0
select gstep
case 1
long if gglList(1) = 0
gglList(1) = fn glGenLists( 1 )
glNewList( gglList(1), _GLCOMPILE )
for i=1to 6
fn maketree(i*15-50,-25-i,rnd(10)+12,i mod 5)
next
glEndList
end if
case 2
long if gglList(1) = 0
gglList(1) = fn glGenLists( 1 )
glNewList( gglList(1), _GLCOMPILE )
fn maketree(0,-50,15,1)
glEndList
end if
case 3
long if gglList(1) = 0
gglList(1) = fn glGenLists( 1 )
glNewList( gglList(1), _GLCOMPILE )
fn maketree(0,-50,15,3)
glEndList
end if
case 4
long if gglList(1) = 0
gglList(1) = fn glGenLists( 1 )
glNewList( gglList(1), _GLCOMPILE )
fn maketree(0,-50,15,5)
glEndList
end if
case else
gstep=1
end select
glCallList( gglList(1) )
end fn


local mode
dim as Rect       r
dim as long       w, h
dim as GLboolean  ok
local fn ResizeGL( ctx as ^AGLContext, wPort as CGrafPtr )
'~'1
ok = fn aglUpdateContext( ctx )
r  = fn GetPortBounds( wPort, r )
w = r.right - r.left
h = r.bottom - r.top

glViewport( 0, 0, w, h )

glMatrixMode(_GLPROJECTION)  // Select The Projection Matrix
glLoadIdentity()  // Reset The Projection Matrix

glOrtho(-50, 50, -50, 50, -50.0, 50.0)
glMatrixMode(_GLMODELVIEW)  // Select The Modelview Matrix
glLoadIdentity() // Reset The Modelview Matrix
end fn


local fn InitGL
'~'1
glClearColor( 0.0, 0.0, 0.3, 0.0 ) //  Background
radians#=atn(1)*4/180
end fn


#endif