PDA

View Full Version : Saving and reading binary geometry files with TBGL



Petr Schreiber
24-07-2013, 21:22
Rene's wish is to save geometry in form of ThinBASIC TBGL script and then load it by interpreting. While this is one of the possible approaches, there is one way which will probably will be slightly slower, but much more space efficient. Each TBGL command (for now just a few) is encoded using binary signature (4 byte) + all parameters are in binary form.

Take for example "TBGL_Vertex 1.100, 2.256, 3.456", this would take 32 bytes to save in script form. With binary form, it is packed to SizeOf(signature) + 3 * SizeOf(single) = 16 bytes.
We saved 50% on size and reading binary value does not involve string-to-number conversion, which speeds up the load time too.

I attach the unit file, fileformat_BG.tBasicU, + test script. The usage is as simple as:


#INCLUDE "fileFormat_BG.tBasicU"

Uses "TBGL"

$BG_FILE = APP_SourcePath + "test.bg"

Function TBMain()
Local hWnd As DWord
Local FrameRate As Double

' -- Create and show window
hWnd = TBGL_CreateWindowEx("Test of BG file format - press ESC to quit", 640, 480, 32, %TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX)
TBGL_ShowWindow

' -- Define geometry to file
BG_BeginSaveFile($BG_FILE)

BG_BeginPoly(%GL_TRIANGLES)
BG_Color(255, 0, 0)
BG_Vertex(-1,-1, 0)

BG_Color( 0, 255, 0)
BG_Vertex( 1,-1, 0)

BG_Color( 0, 0, 255)
BG_Vertex( 0, 1, 0)
BG_EndPoly

BG_BeginPoly(%GL_QUADS)
BG_Color(255, 255, 255)

BG_Vertex(-2, 2, -1)
BG_Vertex( 2, 2, -1)

BG_Color(0, 0, 0)
BG_Vertex( 2,-2, -1)
BG_Vertex(-2,-2, -1)
BG_EndPoly

BG_EndSaveFile()

' -- Load it back
%listHouse = BG_LoadFileToList($BG_FILE)

' -- Resets status of all keys
TBGL_ResetKeyState()

' -- Main loop
While TBGL_IsWindow(hWnd)
FrameRate = TBGL_GetFrameRate

TBGL_ClearFrame
TBGL_Camera(0, 0, 5, 0, 0, 0)

TBGL_CallList(%listHouse)

TBGL_DrawFrame

' -- ESCAPE key to exit application
If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While

Wend

TBGL_DestroyWindow
End Function


Of course, more features can be added, this is just a concept for possible expansion.


Petr

ReneMiner
26-07-2013, 15:46
Thanks Petr, this is a nice way to process data from a file. Now the "but":

It wouldn't make much difference to loading the file as tB-text and "interpret" it by parsing it and comparing the keywords, order them using "select case" or similar way - convert numbers in text to numerical values etc. and proceed the selected statement with the values - too much effort to create for al TBGL-keywords other names etc.

In the other thread you mentioned, oxygen could use the GL-headers, but - we know- it does not "know" the TBGL-function names - and would not "know" if the in the Declare-statement used names alias "real name" are TBGL-statements as TBGL_Vertex are named glVertex - and oxygen would not bother(?) if that function would exist "outside" in TBGL-module - so declare in oxygen like


DECLARE SUB TBGL_Vertex LIB "opengl32.dll" ALIAS "glVertex3d" (BYVAL x AS GLdouble, BYVAL y AS GLdouble, BYVAL z AS GLdouble)


- and... computer explodes...or oxygen "interprets" thinBasic on the fly :D

???

Petr Schreiber
26-07-2013, 18:53
Hehe,

wild idea. Sadly, this will not work. The module commands do not process parameters as stack, but they actively parse the commands.

The usage of ThinBASIC and Oxygen functions is the same, but they are different beasts.

But there is no problem in using native OpenGL commands, TBGL will understand them. So you can use glVertex3f and others in Oxy without issue.

So you can do:


TBGL_NewList 1

' -- Call Oxygen with native OpenGL commands

TBGL_EndList



Petr

ReneMiner
26-07-2013, 19:16
not in a way that i use the declarations under "false" names to those functions of gl that equal TBGL-functions - prepared for oxygen in a string in advance?
so if my tB code finds TBGL_BeginPoly it grabs the text until TBGL_EndPoly , hangs them behind those false-name declarations - just to use the functionality of "Alias" and oxygen reads "TBGL_Vertex 1,2,3" it calls "glVertex3d 1,2,3" since I declared it to be named like this? The advantage would be- i could still save to plain tB-script-text which can be copied and pasted into a script etc. I just had to create the loading routines for the rest of the text (like texture) and oxygen would "interpret" the rest at its best in a fast way - without need to sort nor convert numbers - maybe you understood wrongly:
I would just start oxygen to proceed the text - and if i write:


O2_Basic RawText
DECLARE SUB glVertex3d LIB "opengl32.dll" ALIAS "glVertex3d" (Double X, Double Y, Double Z)
'...
glVertex3d 1,2,3
'...
terminate
End RawText
O2_Exec

or this:


O2_Basic RawText
DECLARE SUB TBGL_Vertex LIB "opengl32.dll" ALIAS "glVertex3d" (Double X, Double Y, Double Z)
'...
TBGL_Vertex 1,2,3
'...
terminate
End RawText
O2_Exec

what would be the difference for oxygen? :confused: Would it draw vertices at wrong position? Or wrong color?

Petr Schreiber
26-07-2013, 20:09
This is what happens when I reply during dinner, you are right - doing such an alias would work.
But for example glBindTexture has different number of parameters than TBGL_BindTexture, so this could do some trouble.

Little warning - always use f variants of commands (that is glVertex3f with SINGLEs over glVertex3d with DOUBLEs). Why? Most current graphic cards do not have hardware support for graphic operations with DOUBLEs, so your numbers will get casted to SINGLE anyway (+/- OK) or they will try to maintain precision and performance will go down (baaad).


Petr

ReneMiner
31-07-2013, 17:38
the oxygen idea is not that good- since one had to stop other oxygen-stuff and restart it thereafter...

I think more about some passing data like below but i fear that won't be fast:



TBGL_NewList %myList
TBGL_BeginPoly %GL_Triangles
' all my... is supposed to be an "array"
TBGL_IndexBuffer myVertexIndices
TBGL_VertexBuffer myVertices
TBGL_IndexBuffer myColorIndices
TBGL_ColorBuffer myColors
TBGL_IndexBuffer myNormalIndices
TBGL_NormalBuffer myNormals
TBGL_IndexBuffer myUVIndices
TBGL_TexCoordBuffer myTexcoords
TBGL_EndPoly
TBGL_EndList


If no index-buffer specified, just go through in order - which might use up more memory of course.

Should work with virtual arrays over some heap also, maybe pass pointer to first index/vertex + count.
And not necessarily send data to Display-List - would fit even better directly to entity