Dark Bit Factory & Gravity

PROGRAMMING => Freebasic => Topic started by: ninogenio on July 08, 2007

Title: trying to port tajs trinnity example
Post by: ninogenio on July 08, 2007
hey all im trying to port tajs trinnity 1k example to fb but im having trouble converting these two lines.

Code: [Select]
// the vertex shader where most of the work is done...
const GLchar *vsh="\
varying vec4 c;\
void main(){\
gl_Position=gl_Vertex+\
vec4(gl_Normal,1)*\
abs(dot(sin((gl_Vertex+ftransform())*9.9),vec4(4)));\
c=cos(gl_Position*0.04)*length(gl_Position*0.04);\
}";

// the fragment shader - do as litte as possible here...
// take c and interpolate and ssign to the ouput fragcolor...
const GLchar *fsh="\
varying vec4 c;\
void main(){\
gl_FragColor=c;\
}";

and heres where ive got to
Code: [Select]
Dim Shared As GLchar Ptr Vsh = " varying vec4 c; void main(){ gl_Position=gl_Vertex+vec4(gl_Normal,1)*abs(dot(sin((gl_Vertexftransform())*9.9),vec4(4))); c=cos(gl_Position*0.04)*length(gl_Position*0.04); }"

' the fragment shader - do as litte as possible here...
' take c and interpolate and ssign to the ouput fragcolor...
Dim Shared As GLchar Ptr Fsh = " varying vec4 c; void main(){ gl_FragColor=c; }"

i know this isnt right but i cant get it figured it out.
Title: subject
Post by: Jim on July 09, 2007
Best I can do is this
Code: [Select]
defint a-z
option explicit

#include "gl/gl.bi"
#include "gl/glext.bi"

Dim shared Vsh As wstring * 169 => "varying vec4 c;void main(){gl_Position=gl_Vertex+vec4(gl_Normal,1)*abs(dot(sin((gl_Vertexftransform())*9.9),vec4(4)));c=cos(gl_Position*0.04)*length(gl_Position*0.04);}"

print len(Vsh)
print "|";
print Vsh;
print "|"
169 is the length of the string+1.

Which means you'll have to cast Vsh to GLchar Ptr when you use it.
I can't get FB to initialise anything except a built-in string type from a string.

Jim
Title: Re: trying to port tajs trinnity example
Post by: Jim on July 09, 2007
Actually, it's going to be better if it's a zstring
Code: [Select]
Dim shared Vsh As zstring * 169 => "varying vec4 c;void main(){gl_Position=gl_Vertex+vec4(gl_Normal,1)*abs(dot(sin((gl_Vertexftransform())*9.9),vec4(4)));c=cos(gl_Position*0.04)*length(gl_Position*0.04);}"



Jim
Title: Re: trying to port tajs trinnity example
Post by: ninogenio on July 09, 2007
cool thank you jim!
Title: Re: trying to port tajs trinnity example
Post by: ninogenio on July 09, 2007
right ive got the whole trinity example ported with help from jim to fb here we go

Code: [Select]

' sek the intro fairy...
' use and abuse but a credit is a wonderful thing
' t2 sek would do.

' modifiyed for fb by nino

#include "windows.bi"
#include "GL/gl.bi"
#include "GL/glu.bi"
#include "GL/glext.bi"

Dim shared Vsh As zstring * 169 => "varying vec4 c;void main(){gl_Position=gl_Vertex+vec4(gl_Normal,1)*abs(dot(sin((gl_Vertexftransform())*9.9),vec4(4)));c=cos(gl_Position*0.04)*length(gl_Position*0.04);}"

' the fragment shader - do as litte as possible here...
' take c and interpolate and ssign to the ouput fragcolor...
Dim Shared Fsh As Zstring * 47 => "varying vec4 c; void main(){ gl_FragColor=c; }"

Type GenFP As Sub () Ptr
Dim Shared As GenFP glFP(7)

Dim Shared As String glnames(7)
glnames(0) = "glCreateShader"
glnames(1) = "glShaderSource"
glnames(2) = "glCompileShader"
glnames(3) = "glCreateProgram"
glnames(4) = "glAttachShader"
glnames(5) = "glLinkProgram"
glnames(6) = "glUseProgram"

Dim As GLuint V , F , P

Sub setShaders()

         Dim As Integer i
         Dim T As Zstring Ptr

         For i = 0 To 6
                 glFP( I ) = Cast( GenFP , wglGetProcAddress( glnames( I ) ) )
         Next

         V = Cast( PFNGLCREATESHADERPROC , glFP( 0 ) ) ( GL_VERTEX_SHADER )
         F = Cast( PFNGLCREATESHADERPROC , glFP( 0 ) ) ( GL_FRAGMENT_SHADER )
         P = Cast( PFNGLCREATEPROGRAMPROC , glFP( 3 ) ) ( )

         T = @vsh
         Cast( PFNGLSHADERSOURCEPROC , glFP(1) ) ( v , 1 , Cast( Byte Ptr Ptr , @T ) , NULL )
         Cast( PFNGLCOMPILESHADERPROC , glFP(2) ) ( v )

         T = @Fsh
         Cast( PFNGLSHADERSOURCEPROC , glFP(1) ) ( f , 1 , Cast( Byte Ptr Ptr , @T ) , NULL )
         Cast( PFNGLCOMPILESHADERPROC , glFP(2) ) ( f )

         Cast( PFNGLATTACHSHADERPROC , glFP(4) ) ( p , v )
         Cast( PFNGLATTACHSHADERPROC , glFP(4) ) ( p , f )

         Cast( PFNGLLINKPROGRAMPROC , glFP(5) ) ( p )
         Cast( PFNGLUSEPROGRAMPROC , glFP(6) ) ( p )

End Sub


Dim Shared As PIXELFORMATDESCRIPTOR pfd
Function WinMainCRTStartup() As Integer

   ' minimal windows setup code for opengl
   pfd.cColorBits = pfd.cDepthBits = 32
   pfd.dwFlags    = PFD_SUPPORT_OPENGL Or PFD_DOUBLEBUFFER

   Dim As HDC hDC
   hDC = GetDC ( CreateWindow("edit", 0, WS_POPUP Or WS_VISIBLE Or WS_CLIPSIBLINGS Or WS_CLIPCHILDREN Or WS_MAXIMIZE , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) )
   SetPixelFormat ( hDC, ChoosePixelFormat ( hDC, @pfd) , @pfd )
   wglMakeCurrent ( hDC, wglCreateContext(hDC) )

   setShaders()
   ShowCursor(FALSE)

   do
         ' we draw 3 spheres using the same shader which is *very* senesitive to radius
         ' so we see a 3 fold effect ... a trinity
         glRotatef(3,3,3,3)
         gluSphere( gluNewQuadric() , 1.6 , 200 , 200 )
         gluSphere(gluNewQuadric(),1.04,200,200)
         gluSphere(gluNewQuadric(),0.4,200,200)
       SwapBuffers ( hDC )
   Loop while ( GetAsyncKeyState(VK_ESCAPE) = 0 )

   Return 0

End Function


End WinMainCRTStartup()

but there is a problem it doesnt look like its setting up the shaders? could some of you guys test it on your comps to let me know if it works ok.

ive not went through the tiny afying process yet because it isnt working right.
Title: Re: trying to port tajs trinnity example
Post by: Shockwave on July 09, 2007
Ah, unfortunately it doesn't compile at all here.
What version of FB are you using mate?
Title: Re: trying to port tajs trinnity example
Post by: ninogenio on July 09, 2007
im using v0.16b what errors do you get during the build.

here is the exe.
Title: Re: trying to port tajs trinnity example
Post by: Shockwave on July 09, 2007
Code: [Select]
Command executed:
"C:\FreeBasic\fbc.exe"  "C:\FreeBasic\FBIDETEMP.bas"

Compiler output:
C:\FreeBasic\inc\GL/glu.bi(192) : error 6: Expected '(', found: 'max'
declare function gluBuild1DMipmapLevels alias "gluBuild1DMipmapLevels" (byval target as GLenum, byval internalFormat as GLint, byval width as GLsizei, byval format as GLenum, byval type as GLenum, byval level as GLint, byval base as GLint, byval max as GLint, byval data as any ptr) as GLint
                                                                                                                                                                                                                                                          ^

Results:
Compilation failed

System:
FBIde: 0.4.6
fbc:   FreeBASIC Compiler - Version 0.15 for win32 (target:win32)
OS:    Windows XP (build 2600, Service Pack 2)

The exe you posted there runs but it is mashed up. I get a flickering white circle here.
Title: Re: trying to port tajs trinnity example
Post by: Shockwave on July 09, 2007
(fails in glu.bi)
Title: Re: trying to port tajs trinnity example
Post by: ninogenio on July 09, 2007
right i think your glu is conflicting with your windows header, what version of freebasic have you got? try changing max in your glu.h to smax might not work but it might.

and the results you see from the exe are the same as mine so there is something went wrong.

cheers for testing it.
Title: Re: trying to port tajs trinnity example
Post by: Jim on July 09, 2007
Two bugs Nino.
First, you've lost a + somewhere in the vertex shader.  Should read
Code: [Select]
Dim shared Vsh As zstring * 170 => "varying vec4 c;void main(){gl_Position=gl_Vertex+vec4(gl_Normal,1)*abs(dot(sin((gl_Vertex+ftransform())*9.9),vec4(4)));c=cos(gl_Position*0.04)*length(gl_Position*0.04);}"


Second, V,F,P should be shared
Code: [Select]
Dim shared As GLuint V , F , PAfter that it works fine with 0.16b and 0.17b :):)

Jim
Title: Re: trying to port tajs trinnity example
Post by: ninogenio on July 09, 2007
ahh thanks jim i really need to start yousing option explicit and i never even noticed i had lost a + there i went over it a good few times.

now im going to start the process of making it tiny to see if this one comes under 1k.
Title: Re: trying to port tajs trinnity example
Post by: Jim on July 09, 2007
Yeah, option explicit helps, but then when you move to 0.17b it won't compile because it uses explicit by default and option explicit becomes an error (duh! it should just be ignored).

Jim
Title: Re: trying to port tajs trinnity example
Post by: ninogenio on July 10, 2007
right heres where its at tonight the exe works and after making it tiny it goes to 1028 bytes.

Code: [Select]
' sek the intro fairy...
' use and abuse but a credit is a wonderful thing
' t2 sek would do.

' modifiyed for fb by nino

#include "windows.bi"
#include "GL/gl.bi"
#include "GL/glu.bi"
#include "GL/glext.bi"

declare Sub WinMainCRTStartup alias "WinMainCRTStartup"

Dim shared Vsh As zstring * 170 => "varying vec4 c;void main(){gl_Position=gl_Vertex+vec4(gl_Normal,1)*abs(dot(sin((gl_Vertex+ftransform())*9.9),vec4(4)));c=cos(gl_Position*0.04)*length(gl_Position*0.04);}"

' the fragment shader - do as litte as possible here...
' take c and interpolate and ssign to the ouput fragcolor...
Dim Shared Fsh As Zstring * 47 => "varying vec4 c; void main(){ gl_FragColor=c; }"

Type GenFP As Sub () Ptr
Dim Shared As GenFP glFP(7)

dim shared glnames(6) as zstring * 16 => {"glCreateShader", "glShaderSource", "glCompileShader", "glCreateProgram", "glAttachShader", "glLinkProgram", "glUseProgram"}


Dim Shared As GLuint V , F , P
Dim Shared As Integer i
Dim Shared Ts As Zstring Ptr
Dim Shared As PIXELFORMATDESCRIPTOR pfd
Dim Shared As HDC hDC

Sub WinMainCRTStartup()

   ' minimal windows setup code for opengl
   pfd.cColorBits = pfd.cDepthBits = 32
   pfd.dwFlags    = PFD_SUPPORT_OPENGL Or PFD_DOUBLEBUFFER

   hDC = GetDC ( CreateWindow("edit", 0, WS_POPUP Or WS_VISIBLE Or WS_CLIPSIBLINGS Or WS_CLIPCHILDREN Or WS_MAXIMIZE , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) )
   SetPixelFormat ( hDC, ChoosePixelFormat( hDC, @pfd) , @pfd )
   wglMakeCurrent ( hDC, wglCreateContext(hDC) )

   For i = 0 To 6
           glFP( I ) = Cast( GenFP , wglGetProcAddress( glnames( I ) ) )
   Next

   V = Cast( PFNGLCREATESHADERPROC , glFP( 0 ) ) ( GL_VERTEX_SHADER )
   F = Cast( PFNGLCREATESHADERPROC , glFP( 0 ) ) ( GL_FRAGMENT_SHADER )
   P = Cast( PFNGLCREATEPROGRAMPROC , glFP( 3 ) ) ( )

   Ts = @vsh
   Cast( PFNGLSHADERSOURCEPROC , glFP(1) ) ( v , 1 , Cast( Byte Ptr Ptr , @Ts ) , NULL )
   Cast( PFNGLCOMPILESHADERPROC , glFP(2) ) ( v )

   Ts = @Fsh
   Cast( PFNGLSHADERSOURCEPROC , glFP(1) ) ( f , 1 , Cast( Byte Ptr Ptr , @Ts ) , NULL )
   Cast( PFNGLCOMPILESHADERPROC , glFP(2) ) ( f )

   Cast( PFNGLATTACHSHADERPROC , glFP(4) ) ( p , v )
   Cast( PFNGLATTACHSHADERPROC , glFP(4) ) ( p , f )

   Cast( PFNGLLINKPROGRAMPROC , glFP(5) ) ( p )
   Cast( PFNGLUSEPROGRAMPROC , glFP(6) ) ( p )

   ShowCursor(FALSE)

   do
         ' we draw 3 spheres using the same shader which is *very* senesitive to radius
         ' so we see a 3 fold effect ... a trinity
         glRotatef(3,3,3,3)
         gluSphere( gluNewQuadric() , 1.6 , 200 , 200 )
         gluSphere( gluNewQuadric() , 1.04 , 200 , 200 )
         gluSphere( gluNewQuadric() , 0.4 , 200 , 200 )
       SwapBuffers ( hDC )
   Loop while ( GetAsyncKeyState(VK_ESCAPE) = 0 )

End Sub

exe and project folder attached.
Title: Re: trying to port tajs trinnity example
Post by: Stonemonkey on July 10, 2007
Verrry cool, I've only run it from the IDE.
Title: Re: trying to port tajs trinnity example
Post by: Jim on July 10, 2007
Excellent, it should be easy to knock 4 bytes off for the magic 1Kb!
Title: Re: trying to port tajs trinnity example
Post by: ninogenio on July 10, 2007
@fryer yeah it really is a cool demo and i just like to thank taj for giving his source to the forum.

@jim ive tried like mad to knock 4 bytes off but i cant figuare out how to get any more out of it any ideas?
Title: Re: trying to port tajs trinnity example
Post by: ninogenio on July 10, 2007
done it!

i took out the spaces in the fragment program and reduced the string size and now its 1023 bytes yay 1k  :|| :||
Title: Re: trying to port tajs trinnity example
Post by: Stonemonkey on July 10, 2007
Do the spaces in this take up any room?

Dim Shared Fsh As Zstring * 47 => "varying vec4 c; void main(){ gl_FragColor=c; }"

edit: DOH!

Well done.
Title: Re: trying to port tajs trinnity example
Post by: ninogenio on July 10, 2007
cheers fryer, it actually probably took me far longer to spot that than you  ;)
Title: Re: trying to port tajs trinnity example
Post by: Stonemonkey on July 10, 2007
I was in the middle of replying with something about having had a look to see if I could do the loops differently but couldn't find anything that made any difference when I noticed that.
Title: Re: trying to port tajs trinnity example
Post by: ninogenio on July 10, 2007
ive actually just got the size down to 1012 bytes by writing these bits out long hand.

Code: [Select]
Dim Shared As ZString * 15 glnameA => "glCreateShader"
Dim Shared As ZString * 15 glnameB => "glShaderSource"
Dim Shared As ZString * 16 glnameC => "glCompileShader"
Dim Shared As ZString * 16 glnameD => "glCreateProgram"
Dim Shared As ZString * 15 glnameE => "glAttachShader"
Dim Shared As ZString * 14 glnameF => "glLinkProgram"
Dim Shared As ZString * 13 glnameG => "glUseProgram"

Code: [Select]
glFP( 0 ) = Cast( GenFP , wglGetProcAddress( glnameA ) )
glFP( 1 ) = Cast( GenFP , wglGetProcAddress( glnameB ) )
glFP( 2 ) = Cast( GenFP , wglGetProcAddress( glnameC ) )
glFP( 3 ) = Cast( GenFP , wglGetProcAddress( glnameD ) )
glFP( 4 ) = Cast( GenFP , wglGetProcAddress( glnameE ) )
glFP( 5 ) = Cast( GenFP , wglGetProcAddress( glnameF ) )
glFP( 6 ) = Cast( GenFP , wglGetProcAddress( glnameG ) )
Title: Re: trying to port tajs trinnity example
Post by: taj on July 10, 2007
Utterly awesome work - karma++! I would never have believed it - a basic glsl program in <1k.

heres a wild idea that might save a few more bytes. Try changing:

Code: [Select]
gluSphere( gluNewQuadric() , 1.6 , 200 , 200 )
gluSphere( gluNewQuadric() , 1.04 , 200 , 200 )
gluSphere( gluNewQuadric() , 0.4 , 200 , 200 )

to
Code: [Select]
gluSphere( gluNewQuadric() , 1.6015625000f , 200 , 200 )
gluSphere( gluNewQuadric() , 1.0390625000f , 200 , 200 )
gluSphere( gluNewQuadric() , 0.4003906250f , 200 , 200 )

In theory this makes the code easier to compress, but it doesnt work for me. Then again, your trick of writing out the loop doesnt work for me so its all a bit black magic.
Chris
Title: Re: trying to port tajs trinnity example
Post by: ninogenio on July 10, 2007
wow that takes me down to 1003 bytes thanks chris! k+


Title: Re: trying to port tajs trinnity example
Post by: Jim on July 10, 2007
Can you try changing the loop to while/wend?
Code: [Select]
while GetAsyncKeyState(VK_ESCAPE) = 0
wend
And unfortunately, for Vista, you need to add
Code: [Select]
ExitProcess(0)
at the very end, otherwise it won't quite properly :(

Jim
Title: Re: trying to port tajs trinnity example
Post by: ninogenio on July 10, 2007
yeah no probs jim here you go.

its went back up to 1012 bytes with that.
Title: Re: trying to port tajs trinnity example
Post by: Jim on July 10, 2007
I just wanted to see if do/while was smaller than while/wend.  Some compilers optimise one better than the other.

If you disassemble these .o files you can see there's a chunk of stuff that looks like this
Code: [Select]
jmp fb_static_initialisers
nop
nop
nop
...
nop
fb_static_initialisers:
jmp fb_RtInit
The fbc compiler always adds this to bring in the runtime libraries.
That's a real shame as it's quite probably wasting 10 or 20 bytes compared with the C version.  Maybe I could try to blank that out of the .o before sending it to crinkler.

Jim
Title: Re: trying to port tajs trinnity example
Post by: ninogenio on July 10, 2007
ahh i see if you can save between 10 to 20 bytes that would be really cool!

i cant belive benny got this down to 990 bytes with visual studio although i think we are beating dev c as the original trinity is 1024 bytes so we are in between the two.

-edit just tested the while/wend without exit process and it goes from 1003 to 1007 bytes so it is actually a little more expensive.
Title: Re: trying to port tajs trinnity example
Post by: taj on July 10, 2007
Nino, Jim, I guess the NOPS are completely optimised out by the compressor.
Still 1012 is bloody brilliant. Is this the first 1k BASIC exe ever?

Chris
Title: Re: trying to port tajs trinnity example
Post by: Jim on July 10, 2007
Quote
Is this the first 1k BASIC exe ever?
I would think so :)

Jim
Title: Re: trying to port tajs trinnity example
Post by: Shockwave on July 10, 2007
Mindblowing :D

Now a 1KB must be released with Freebasic. K+ Nino, great port!!!! (Yes it works here now )
Title: Re: trying to port tajs trinnity example
Post by: ninogenio on July 10, 2007
cheers for your feedback guys, but really this is all down to jim its all his fb tiny hacking im using and without it this couldnt be done so thanks big guy  :cheers:

if jim finds a way to save any more bytes ill update this and in the mean time ill see if i can come up with an original fb 1k worthy of a release *gulp*.
Title: Re: trying to port tajs trinnity example
Post by: ninogenio on July 10, 2007
@jim how would i go about dissasembling the .o files id quite like to have a little mess around?
Title: Re: trying to port tajs trinnity example
Post by: Stonemonkey on July 10, 2007
The compiler option -r should give you the asm output iirc.