How to compile "Fluids" ?

Previous topic - Next topic

Qedo

Has anyone managed to compile the beautiful Gernot's "Fuilds" program?
http://www.glbasic.com/showroom.php?site=games&game=Fluids
I can't, too many mistakes.
I suspect that in INLINE / ENDLINE the two-dimensional matrices are not supported.
I wonder though that it was compiled because the exe is present.
Gernot what do you say?
Thank you
Qedo


Minion

WOW, I`d forgotten about that. I remember Gernot and I writting that. Didn`t realise it was over 10 years ago tho. How time flies.

bigsofty

This fixes it, although I have no idea why...  :D

I was writing a bit of test code to see have a look at how GLB uses 2D arrays in C and it seemed to make ALL the code compile?!? It seems like this code needs to have an existing GLB 2D array already defined?

Maybe Gernot could clear up this little mystery?

Anyways...

Code (glbasic) Select
// --------------------------------- //
// Project: Fluids
// Start: Saturday, March 24, 2007
// IDE Version: 4.136

TYPE poo
x
y
ENDTYPE

GLOBAL screenx, screeny, tst[] AS poo

LOCAL gridsize, mx, my, b1, b2
gridsize=4

DIM tst[10][10]

GETSCREENSIZE screenx, screeny
SetGrid(screenx/gridsize, screeny/gridsize)

LOCAL x,y
WHILE TRUE
MOUSESTATE mx, my, b1, b2
SetBorders()
Smooth()

IF b1
SetColor(mx/gridsize, my/gridsize, 255,0,0)
SetColor((screenx-mx)/gridsize, my/gridsize, 0,255,0)
SetColor(mx/gridsize, (screeny-my)/gridsize, 0,0,255)
SetColor((screenx-mx)/gridsize, (screeny-my)/gridsize, 255,200,64)
ENDIF

DRAWRECT 0,0,640,480,RGB(255,255,255)
ShowGrid()
PRINT "X", mx, my

SHOWSCREEN
WEND
END



// ----------------------------------
// This is so I'm out of MAIN rountine - I need global stuff before
// ----------------------------------
FUNCTION endmainfoo:
ENDFUNCTION

// ----------------------------------
// GLOBAL stuff
// ----------------------------------
INLINE
// http://mvb.saic.com/freeware/freewarev40/mesa/include/gl/gl.h

} // end namespace __GLBASIC__ - see manual for INLINE

// some constants - for more see:
// http://mvb.saic.com/freeware/freewarev40/mesa/include/gl/gl.h
extern "C"
{
// some of the GL constants
enum CONSTANTS{
GL_VERTEX_ARRAY = 0x8074,
GL_NORMAL_ARRAY = 0x8075,
GL_COLOR_ARRAY = 0x8076,
GL_INDEX_ARRAY = 0x8077,

GL_FLOAT = 0x1406,
GL_DOUBLE = 0x140A,
GL_UNSIGNED_INT = 0x1405,

GL_TRIANGLE_STRIP = 0x0005,

GL_COLOR_MATERIAL = 0x0B57,
GL_DITHER = 0x0BD0,
GL_SMOOTH = 0x1D01,
GL_FLAT = 0x1D00,

GL_CULL_FACE = 0x0B44
};
// the functions are all >>extern "C" __stdcall<<
extern void __stdcall glColorPointer(int size, int typ, int stride, const void *ptr );
extern void __stdcall glVertexPointer(int size, int typ, int stride, const void *ptr );
extern void __stdcall glDrawArrays( int mode, int first, int count );
extern void __stdcall glDrawElements( int mode, int count, int typ, const void *indices );
extern void __stdcall glEnable( int cap );
extern void __stdcall glDisable( int cap );
extern void __stdcall glShadeModel( int model );
extern void __stdcall glEnableClientState( int cap );
extern void __stdcall glDisableClientState( int cap );
}

// restore the namespace
namespace __GLBASIC__
{

// this is a point. Color in 3float format is the fastest for
// gfx card
struct cPOD
{
float x,y;
float vx,vy;
float col[3]; // rgb values
};
// 2 arrays for the background mesh
// a pointer to the current one
DGArray<cPOD> gcPODs1, gcPODs2, *pCurPODs;
// an array of mesh indices for faaaast drawing
DGArray<unsigned int>  gIndices;



ENDINLINE


// ----------------------------------
// Set the grid size
// ----------------------------------
FUNCTION SetGrid: w,h
INLINE
DIM(gIndices, w*h*2);
DIM(gcPODs1, w, h);

int j=0;
for (int y=0; y<h; ++y)
for (int x=0; x<w; ++x)
{
gcPODs1(x,y).x = x*screenx/w;
gcPODs1(x,y).y = y*screeny/h;
gIndices(j++) =  y*w +x;
gIndices(j++) = (y+1)*w +x;
}
gcPODs2 = gcPODs1;
pCurPODs = &gcPODs1;

ENDINLINE
ENDFUNCTION


// ----------------------------------
// Draw the whole background grid
// ----------------------------------
FUNCTION ShowGrid:
// Disable texturing
X_SETTEXTURE -1, -1
INLINE

int width = BOUNDS(gcPODs1, 0);
int height= BOUNDS(gcPODs1, 1);

// change rendering context to what we need
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_DITHER);
glShadeModel(GL_SMOOTH);
glDisable(GL_CULL_FACE);

// vertex arrays & color array
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

// set the data pointers
glVertexPointer(2, GL_FLOAT, sizeof(cPOD), (void*)&(*pCurPODs)(0,0).x);
glColorPointer (3, GL_FLOAT, sizeof(cPOD), (void*)&(*pCurPODs)(0,0).col[0]);

// for each "line" of the mesh
for(int i = 0; i < height - 1; ++i)
{
// whee
glDrawElements(GL_TRIANGLE_STRIP, width * 2, GL_UNSIGNED_INT, &gIndices(i * width * 2));
}

// restore what GLBasic would not do automatically
glShadeModel(GL_FLAT);
glDisable(GL_DITHER);
glDisable(GL_COLOR_MATERIAL);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
ENDINLINE
ENDFUNCTION


// ----------------------------------
// Set the color of a grid point
// ----------------------------------
FUNCTION SetColor: x,y,r,g,b
INLINE
(*pCurPODs)(x,y).col[0]=r;
(*pCurPODs)(x,y).col[1]=g;
(*pCurPODs)(x,y).col[2]=b;
ENDINLINE
ENDFUNCTION


// ----------------------------------
// Smooth the mesh
// ----------------------------------
FUNCTION Smooth:
INLINE
int width = BOUNDS(gcPODs1, 0);
int height= BOUNDS(gcPODs1, 1);
DGArray<cPOD>* pOther=&gcPODs1;
if(pOther == pCurPODs)
pOther = &gcPODs2;

for (int x=0; x<width-1; ++x)
for (int y=0; y<height-1;++y)
{
cPOD& p1=(*pCurPODs)(x,y);
cPOD& p2=(*pCurPODs)(MIN(width-1,x+1),y);
cPOD& p3=(*pCurPODs)(MAX(0,x-1),y);
cPOD& p4=(*pCurPODs)(x,MIN(height-1,y+1));
cPOD& p5=(*pCurPODs)(x,MAX(0,y-1));

cPOD& r= (*pOther)(x,y);

r.col[0] = (p1.col[0]*1.05 + p2.col[0] + p3.col[0]+p4.col[0]+p5.col[0])/5.1;
r.col[1] = (p1.col[1]*1.05 + p2.col[1] + p3.col[1]+p4.col[1]+p5.col[1])/5.1;
r.col[2] = (p1.col[2]*1.05 + p2.col[2] + p3.col[2]+p4.col[2]+p5.col[2])/5.1;
}
pCurPODs=pOther;
ENDINLINE
ENDFUNCTION


// ----------------------------------
// Set border pixels to black
// ----------------------------------
FUNCTION SetBorders:
INLINE
int width = BOUNDS(gcPODs1, 0);
int height= BOUNDS(gcPODs1, 1);
for(int i=0; i<width; ++i)
{
SetColor(i,0,0,0,0);
SetColor(i,height-1,0,0,0);
}
for(int i=0; i<height; ++i)
{
SetColor(0,i,0,0,0);
SetColor(width-1,i,0,0,0);
}
ENDINLINE
ENDFUNCTION






Cheers,

Ian.

"It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration."
(E. W. Dijkstra)

Qedo

bigsofty compliments you are great   :nw:,  even if can't understand why it was enough to insert a two-dimensional array (moreover not used in the programm) at the beginning to compile.
I thought computer science was an exact science but ...   :blink:  I was wrong.
Certainly Gernot could clear up this little strangeness.
Qedo

bigsofty

No problem Qedo, its actually a very insightful example on how to manipulate GLB arrays via inline C. I just wish I knew why the first part behaves as it did.  :blink:
Cheers,

Ian.

"It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration."
(E. W. Dijkstra)