MiniB3D Thread 2
BlitzMax Modules Forums/MiniB3D/MiniB3D Thread 2
Thread 1V0.25 V0.26 is now available from
here.
I was going to add some more things before releasing a new version, but seeing as it was taking me so long (blame the World Cup and sunny weather for that) and the old version was so out-of-date, I've decided to release what I have right now.
It should be quite a bit faster than the previous version, although there is a still a lot more to be done in terms of speeding things up. As ever, let me know of any bugs/fixes/feature requests etc.
I found this to be *substantially* faster than the previous version, and represents some excellent coding!
Very well done and thanks for sharing
[edit] works great in linux too, real fast!
Thank you for sharing this simon
great work :-)
great job simon!
@simonh: Yes, great work! There is a significant speed improvement. No crashes on my Mac. However, the dwarf model still takes 33 seconds to load. I'll look into it to try to establish what is slowing it down.
Try commenting out UpdateNormals from the end of the LoadAnimB3D function, see if that effects anything.
Try commenting out UpdateNormals from the end of the LoadAnimB3D function, see if that effects anything.
Yes, that is the bottleneck. Commenting it out makes loading take 1 second. Thanks! Now we know what to optimize.
What's 'MiniB3D?' - will I like it? Is it anything to do with 'Blitz3D'?
It's a cut-down version of Blitz3D for BlitzMax.
JonasL - I've managed to reproduce the slowdown here with UpdateNormals and the Dwarf model (could have sworn it didn't happen before). I'll have a look at it.
I think this is some kind of sneaky trick to make me use BMax.
Well, I jolly-well won't.
I'll buy the 3D mod for Max - but I certainly will not be using it.
Blitz3D has got another 10 years in it - BMax will be dead and buried by then.
I've managed to reproduce the slowdown here with UpdateNormals and the Dwarf model (could have sworn it didn't happen before). I'll have a look at it.
Simon, we owe you big time for sharing MiniB3D. I will follow your example by releasing our cross BlitzMax /C++ game framework as open source as soon as we have v 0.1 ready. It was developed so I can prototype games in BlitzMax and then port them in no time to C++.
dude, this rules. Its pretty killer.
hmm, GLAdjustTexSize doesn't work here, becouse there is any bug with proxy textures.
See:
http://www.blitzbasic.com/Community/posts.php?topic=55157Please use:
Function AdjustTexSize(Width:Int Var, Height:Int Var)
Local MaxSize:Int
glGetIntegerv(GL_MAX_TEXTURE_SIZE, Varptr(MaxSize))
Width = Pow2Size(Width, MaxSize)
Height = Pow2Size(Height, MaxSize)
Function Pow2Size:Int(Size:Int, MaxSize:Int)
Local QuadSize:Int
QuadSize = 1
While QuadSize < Size And QuadSize < MaxSize
QuadSize = QuadSize Shl 1
Wend
Return QuadSize
End Function
End Function
What about shaders? Very easy to bind this in TBrush.
Like:
Type TFragmentProgram
Global MaxInstructions : Int
Global MaxLocalParams : Int
Global MaxEnvParams : Int
Global MaxTemporaries : Int
Global MaxParams : Int
Global MaxAttribs : Int
Global MaxTexInstructions : Int
Field ProgramID : Int
Method Delete()
glDeleteProgramsARB(1, Varptr(Self.ProgramID))
End Method
Method SetLocalParameter(Index:Int, X:Float, Y:Float, Z:Float, W:Float)
If Index => 0 And Index <= TFragmentProgram.MaxLocalParams Then
glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, Index, X, Y, Z, W)
Else
RuntimeError("FragmentProgram-Local-Parameter-Index out of range!")
EndIf
End Method
Function CreateFragmentProgram:TFragmentProgram(Program:String)
Local FragmentProgram:TFragmentProgram
FragmentProgram = New TFragmentProgram
glGenProgramsARB(1, Varptr(FragmentProgram.ProgramID))
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, FragmentProgram.ProgramID)
glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, ..
Program.Length, Program.ToCString())
If glGetError() = GL_INVALID_OPERATION Then
Local Error:String
Error = String.FromCString(Byte Ptr(glGetString(GL_PROGRAM_ERROR_STRING_ARB)))
RuntimeError("FragmentProgram Error: "+Error)
Return Null
Else
Return FragmentProgram
EndIf
End Function
Function SetEnvParameter(Index:Int, X:Float, Y:Float, Z:Float, W:Float)
If Index => 0 And Index <= TFragmentProgram.MaxEnvParams Then
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, Index, X, Y, Z, W)
Else
RuntimeError("FragmentProgram-Environment-Parameter-Index out of range!")
EndIf
End Function
Function GetInfo()
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, ..
Varptr(MaxInstructions))
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, ..
Varptr(MaxLocalParams))
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, ..
Varptr(MaxEnvParams))
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, ..
Varptr(MaxTemporaries))
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_PARAMETERS_ARB, ..
Varptr(MaxParams))
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ATTRIBS_ARB, ..
Varptr(MaxAttribs))
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB, ..
Varptr(MaxTexInstructions))
End Function
End Type
Type TVertexProgram
Global MaxInstructions : Int
Global MaxLocalParams : Int
Global MaxEnvParams : Int
Global MaxTemporaries : Int
Global MaxParams : Int
Global MaxAttribs : Int
Global MaxTexInstructions : Int
Field ProgramID : Int
Method Delete()
glDeleteProgramsARB(1, Varptr(Self.ProgramID))
End Method
Method SetLocalParameter(Index:Int, X:Float, Y:Float, Z:Float, W:Float)
If Index => 0 And Index <= TVertexProgram.MaxLocalParams Then
glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, Index, X, Y, Z, W)
Else
RuntimeError("VertexProgram-Local-Parameter-Index out of range!")
EndIf
End Method
Function CreateVertexProgram:TVertexProgram(Program:String)
Local VertexProgram:TVertexProgram
VertexProgram = New TVertexProgram
glGenProgramsARB(1, Varptr(VertexProgram.ProgramID))
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, VertexProgram.ProgramID)
glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, ..
Program.Length, Program.ToCString())
If glGetError() = GL_INVALID_OPERATION Then
Local Error:String
Error = String.FromCString(Byte Ptr(glGetString(GL_PROGRAM_ERROR_STRING_ARB)))
RuntimeError("VertexProgram Error: "+Error)
Return Null
Else
Return VertexProgram
EndIf
End Function
Function SetEnvParameter(Index:Int, X:Float, Y:Float, Z:Float, W:Float)
If Index => 0 And Index <= TFragmentProgram.MaxEnvParams Then
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, Index, X, Y, Z, W)
Else
RuntimeError("VertexProgram-Environment-Parameter-Index out of range!")
EndIf
End Function
Function GetInfo()
glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, ..
Varptr(MaxInstructions))
glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, ..
Varptr(MaxLocalParams))
glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, ..
Varptr(MaxEnvParams))
glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, ..
Varptr(MaxTemporaries))
glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_PARAMETERS_ARB, ..
Varptr(MaxParams))
glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ATTRIBS_ARB, ..
Varptr(MaxAttribs))
glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB, ..
Varptr(MaxTexInstructions))
End Function
End Type
Function CreateVertexProgram:TVertexProgram(Program:String)
Return TVertexProgram.CreateVertexProgram(Program)
End Function
Function VertexProgramLocalParameter(VP:TVertexProgram, Index:Int, ..
X:Float, Y:Float, Z:Float, W:Float)
VP.SetLocalParameter(Index, X, Y, Z, W)
End Function
Function VertexProgramEnvParameter(Index:Int, X:Float, Y:Float, Z:Float, W:Float)
TVertexProgram.SetEnvParameter(Index, X, Y, Z, W)
End Function
Function CreateFragmentProgram:TFragmentProgram(Program:String)
Return TFragmentProgram.CreateFragmentProgram(Program)
End Function
Function FragmentProgramLocalParameter(FP:TVertexProgram, Index:Int, ..
X:Float, Y:Float, Z:Float, W:Float)
FP.SetLocalParameter(Index, X, Y, Z, W)
End Function
Function FragmentProgramEnvParameter(Index:Int, X:Float, Y:Float, Z:Float, W:Float)
TFragmentProgram.SetEnvParameter(Index, X, Y, Z, W)
End Function(Shit big functionnames, but you can find a way to use like TShader)
Make a function like BrushVertexProgram(Brush:TBrush, VP:TVertexProgram) and BrushFragmentProgram(Brush:TBrush, FP:TFragmentProgram).
Render it with
glEnable(GL_VERTEX_PROGRAM_ARB)
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, VP.ProgramID)
and
glEnable(GL_FRAGMENT_PROGRAM_ARB)
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, FP.ProgramID)
cu olli
hmm..i gotta try this!
sorry i cant resist screenie time!

Notice the fps, b3d actually runs slightly slower on my system! this shot is an experiment of mine using simplified mesh display lists.
BMax will be dead and buried by then.
Keep saying stuff like that and you'll be dead and buried before then too ;]
gonna try this out later - thanks heaps :] ;)
no need to apologize Chris... as a matter of fact, thanks for the screenie... finally get to see what people are doing with minb3d...
i don't wanna turn the thread into a minib3D photoshoot, but anyone else got any screenshots of what they're doing with Simon's creation...
thx
--Mike
quickly, someone make a screenie of a 3D submarine for Red...
Thanks, Si.
I do get an error in the test-fog.bmx demo, though. It crashes right after opening the window with no debug on, and just says "Unhandled Exception:Unhandled Memory Exception Error" with debug on, highlighting RenderWorld.
Glad to see you're still working on this!
Wierd. Any chance you could step through Renderworld and narrow down where it crashes exactly?
Also, does it crash if you comment out the SetCameraFogMode command?
Woah... I'm away from the community for a while and simonh unleashes this! Fantastic stuff. I can't wait for the weekend to try this out. Many thanks Si!
You're welcome.
Going on holiday today for a week so I'll reply to any emails when I get back.
Sorry, Si, I forgot to check this thread, but I've just disabled ALL fog-related commands (and also commented out the cam2 stuff, which doesn't seem to be used), and I still get the error on RenderWorld, which is really weird because everything else works. I've tried debug/non-debug and quick build on/off.
I'll try and take a look in the next dew days and comment out a load of stuff until it works.
Enjoy your holiday!
I also failed to read what you said. I just stepped through RenderWorld, and here's the debug output:
Building test-fog
Compiling:MiniB3D.bmx
flat assembler version 1.64
4 passes, 0.3 seconds, 696393 bytes.
Compiling:test-fog.bmx
flat assembler version 1.64
3 passes, 11103 bytes.
Linking:test-fog.debug.exe
Executing:test-fog.debug.exe
DebugLog:BRUS
DebugLog:NODE
DebugLog:MESH
DebugLog:VRTS
DebugLog:TRIS
Process complete
It opens linkedlist.bmx, ending with the cursor on the NextObject -> "Return value" line here:
Type TListEnum
Field _link:TLink
Method HasNext()
Return _link._value<>_link
End Method
Method NextObject:Object()
Local value:Object=_link._value
Assert value<>_link
_link=_link._succ
Return value
End Method
End Type
I notice that in the Debug tab, under Function RenderWorld, the render_list is Null.
Seems like it's not specifically fog-related as far as I can see. I'll try to investigate more.
I cant seem to get B3d's loading very well. I wanted to load one B3d and it took forever to load and a few other B3ds I just get errors trying to load em. Is there a specific B3d exporter we're suppose to be using?
comment out line 5467
Hi,
UpdateNormals is slow because it's an O(N^2) algorithm.
Since a model has about as many verts as tris, the nested loops...
For each tri...
For each vert...
...can take a long, long time - eg: for 1,000 verts, there will be about 1,000,000 iterations!
Here's an alternative that uses a Map to speed things up ( This should be about O( N Log N ) complexity I think).
First you'll need to add a TVec type at the top:
Type TVec
Field x#,y#,z#
Const EPSILON=.0001
Method Compare( with:Object )
Local q:TVec=TVec(with)
If x-q.x>EPSILON Return 1
If q.x-x>EPSILON Return -1
If y-q.y>EPSILON Return 1
If q.y-y>EPSILON Return -1
If z-q.z>EPSILON Return 1
If q.z-z>EPSILON Return -1
Return 0
End Method
Method Normalize()
Local d#=1/Sqr(x*x+y*y+z*z)
x:*d
y:*d
z:*d
End Method
Function Create:TVec( x#,y#,z# )
Local t:TVec=New TVec
t.x=x
t.y=y
t.z=z
Return t
End Function
End Type
...nothing fancy, just enough for finding vertices in a map...
Method UpdateNormals()
For Local s=1 To CountSurfaces()
Local norm_map:TMap=New TMap
Local surf:TSurface=GetSurface( s )
For Local t=0 Until surf.CountTriangles()
Local nx#=surf.TriangleNX#(t)
Local ny#=surf.TriangleNY#(t)
Local nz#=surf.TriangleNZ#(t)
For Local c=0 Until 3
Local vx#=surf.VertexX#(surf.TriangleVertex(t,c))
Local vy#=surf.VertexY#(surf.TriangleVertex(t,c))
Local vz#=surf.VertexZ#(surf.TriangleVertex(t,c))
Local vert:TVec=TVec.Create( vx,vy,vz )
Local norm:TVec=TVec( norm_map.ValueForKey( vert ) )
If norm
norm.x:+nx
norm.y:+ny
norm.z:+nz
Else
norm_map.Insert vert,TVec.Create(nx,ny,nz)
EndIf
Next
Next
For Local norm:TVec=EachIn norm_map.Values()
norm.Normalize
Next
For Local v=0 Until surf.CountVertices()
Local vx#=surf.VertexX#( v )
Local vy#=surf.VertexY#( v )
Local vz#=surf.VertexZ#( v )
Local vert:TVec=TVec.Create( vx,vy,vz )
Local norm:TVec=TVec( norm_map.ValueForKey( vert ) )
If Not norm Continue
surf.vert_norm#[v*3+0]=norm.x
surf.vert_norm#[v*3+1]=norm.y
surf.vert_norm#[v*3+2]=norm.z
Next
Next
End Method
I haven't tested it thoroughly, but it's basically the same idea as B3D's so it should work.
Best of all, dwarf load time has gone from 18 secs to 1!
I added your code thanks mark but my error seems to be with renderworld. I get "Unhandled Exception: Attempt to index array element beyond Array Length" When I run it with Minib3d.bmx open it highlights this line.
If (surf.brush<>Null And surf.brush.tex[ix]<>Null) Or brush.tex[ix]<>Null
and debuglog shows
Building Main
Compiling:MiniB3D.bmx
flat assembler version 1.64
4 passes, 0.3 seconds, 702700 bytes.
Compiling:Main.bmx
flat assembler version 1.64
3 passes, 6521 bytes.
Linking:Main.debug.exe
Executing:Main.debug.exe
DebugLog:TEXS
DebugLog:BRUS
DebugLog:NODE
DebugLog:-NODE (parent= Group01)
DebugLog:-MESH
DebugLog:-VRTS
DebugLog:-TRIS
DebugLog:-TRIS
DebugLog:-TRIS
DebugLog:-TRIS
DebugLog:-TRIS
DebugLog:-NODE (parent= Group01)
DebugLog:-MESH
DebugLog:-VRTS
DebugLog:-TRIS
DebugLog:-NODE (parent= Group01)
DebugLog:-MESH
DebugLog:-VRTS
DebugLog:-TRIS
DebugLog:-NODE (parent= Group01)
DebugLog:-MESH
DebugLog:-VRTS
DebugLog:-TRIS
DebugLog:-NODE (parent= Group01)
DebugLog:-MESH
DebugLog:-VRTS
DebugLog:-TRIS
DebugLog:-NODE (parent= Group01)
DebugLog:-MESH
DebugLog:-VRTS
DebugLog:-TRIS
Process terminated
Wow, thanks for that contribution Mark! Much appreciated.
is minib3d faster as b3d on all systems ?
have anyone a test ?
no time to make my own :(
CKob,
It doesn't load all B3D's yet, it's pretty good though.
I keep meaning to get 5 minutes to go through and tweak the loader as I did with the first MiniB3D, i never released that though as my code was rushed and unclean.
From memory here (I don't have the source to look through and haven't done so for a month or so):
it needs to store vertex, tri and texture information and not build the mesh until it's got all information. With an unfound texture, a plain white texture would be applied instead.
I seem to remember our race track not loading because a missing texture threw the texture/brush index out.
Nice work Simon! and Cheers Mark!
Cygnus, Yeah that was my first guess was maybe I was missing a texture but that wasnt the case as I tried loading a model with a single texture and it didnt work. I am using 3d studio max and the B3d pipeline to export the mesh maybe thats causing the problems?
No idea.
I will see if I get some time to run over it, If Simon doesn't mind? Times sparse for me at the mo tho.
I think every surface has to have a texture, too....
every surface does have a texture, I was thinking maybe it had something to do with higher polycount? If I make a cube and export it then I can load it fine but when I tryed loading anything lets say 20k poly's up it craps out.
Ewie... No idea then.
If i get to give this a try over the weekend we will see if it works :)
thanks:)
Hi.
To marksibly:
The type TMap in BlitzMax is not balanced. The complexity is O(n). Test TMap whit previous ordered keys and take times.
The times aren very very very poor.
I pusblish in other thread one balanced TMap. It offer good eficiency O(log(n))
Bye,
Paposo
Sorry to post a so dummy question.. but is it possible to use Bmax graphical function over the 3D render (drawing 2d sprites by ex) ?
This would be GREAT !
@Pingus - for v2 of MiniB3D, with the help of the author i did get HighGUI working with MiniB3D with minor modifications so it is possible. i have not tried it yet with v2.5.
Gman,
Sounds interresting, how can I see more ? Is there is a link on your forum ?
I can confirm this problem im having seems to be with loading 3d studio max exports.
@pingus
I used a modified version of Fredborg's code. Unfortually it appers to only work correctly HighGUI3 ( it messes up stuff with alpha , and I really dont understand why :/ ).
heres Fredborg's code:
Function UseMax2D()
Local x,y,w,h
GetViewport(x,y,w,h)
glDisable(GL_LIGHTING)
glDisable(GL_DEPTH_TEST)
glDisable(GL_SCISSOR_TEST)
glDisable(GL_FOG)
glDisable(GL_CULL_FACE)
glMatrixMode GL_TEXTURE
glLoadIdentity
glMatrixMode GL_PROJECTION
glLoadIdentity
glOrtho 0,GraphicsWidth(),GraphicsHeight(),0,-1,1
glMatrixMode GL_MODELVIEW
glLoadIdentity
SetViewport x,y,w,h
'
' Clear textures
For Local Layer = 0 Until THardwareInfo.MaxTextures
glActiveTexture(GL_TEXTURE0+Layer)
glDisable(GL_TEXTURE_CUBE_MAP)
glDisable(GL_TEXTURE_GEN_S)
glDisable(GL_TEXTURE_GEN_T)
glDisable(GL_TEXTURE_GEN_R)
glDisable(GL_TEXTURE_2D)
Next
'
' Activate texture layer 0
glActiveTexture(GL_TEXTURE0)
'
' To reset states!
DrawRect -10,-10,5,5
EndFunction
I basically got rid of the bit about clearing textures.
It should load all .b3ds. If you have a file that doesn't work, send it to me and I'll have a look.
Thanks for the improved UpdateNormals function, Mark!
And James, I appreciate you looking into that further for me. Still no idea what the problem is mind!
well as I said it only happens if I export from 3d studio max but let me see if I can reproduce it and ill email you the model if thats ok?
is there a way to use this with maxGUI ?
Diablo,
Thanks but it does not work when included in one of the test apps. What is :THardwareInfo.MaxTextures ?
I got an error message when trying to compile test-anim with the UseMax2D function(identifier maxtextures not found).
Anyway, the first "getviewport" instruction crash the app.
Simonh,
Is the use of 2D native functions of Bmax is planned with miniB3D ?
Cheers ckob, I'll take a look at that later.
Pingus - not yet. Maybe in the future.
@Pingus - Thats just what Fredborg posted.
You'll have to change the sorce of MiniB3d.bmx
Change the line that says:
GLGraphics(width,height,depth,rate,GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER) 'windowed
to
SetGraphicsDriver (GLMax2DDriver())
Graphics(width,height,depth,rate,GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER) 'windowed
Also use this modified version of fredborg's code:
Function UseMax2D()
Local x,y,w,h
GetViewport(x,y,w,h)
glDisable(GL_LIGHTING)
glDisable(GL_DEPTH_TEST)
glDisable(GL_SCISSOR_TEST)
glDisable(GL_FOG)
glDisable(GL_CULL_FACE)
glMatrixMode GL_TEXTURE
glLoadIdentity
glMatrixMode GL_PROJECTION
glLoadIdentity
glOrtho 0,GraphicsWidth(),GraphicsHeight(),0,-1,1
glMatrixMode GL_MODELVIEW
glLoadIdentity
SetViewport x,y,w,h
'
' Clear textures
'
' Activate texture layer 0
glActiveTexture(GL_TEXTURE0)
'
' To reset states!
DrawRect -10,-10,5,5
EndFunction
Function EnableStates ()
glEnable(GL_LIGHTING)
glEnable(GL_DEPTH_TEST)
glEnable(GL_SCISSOR_TEST)
glEnable(GL_FOG)
glEnable(GL_CULL_FACE)
End Function
Use it like...
RenderWorld ()
UseMax2D ()
' 2D stuff
EnableStates ()
HoweverThis solution only dosent work correctly, so your'll best bet would be to wait for an offical function/support from simonh.
Hi Paposo,
The type TMap in BlitzMax is not balanced. The complexity is O(n)
You're right, and I've been meaning to fix it for ages.
I've posted a new version of TMap for testing in the 'BlitzMax Module Tweaks' forum.
I couldn't find the one you published, but I followed your lead and, erm, 'based' it on Java's Treemap too.
It looks very efficient to me, with less recursion than the current TMap implementation. This will hopefully make up for slightly more complex insertion/removal etc.
hate to ask again but maybe it was overlooked, can minib3d work inside a maxGUI canvas?
Hello Marksibly.
I read your code. Is very very similar to my code. Probably you read the source Java. I read it for my code :-)
After certain time i post in code forum any implementation abstract for an binary tree. Is a god base for Tmaps, queues, etc. Is a version 1.0. I coded a version 1.1 refactorized not published in forums.
Sorry my bad english. I only talk spanish
Bye,
Ramon
hate to ask again but maybe it was overlooked, can minib3d work inside a maxGUI canvas?
It can. Below is a quick hack to show it's possible. (put it in "tests" folder)
I'd really like MiniB3D support it natively.
SuperStrict
Import "../MiniB3D.bmx"
'based on Simple GL cube demo + simonh's primitives.bmx sample
'Written by Birdie
SetGraphicsDriver GLGraphicsDriver(),GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER
Global ax#, ay#,tim#
Local w:TGadget = CreateWindow("Easy Minib3d in a GUI window", 10, 10, 512, 512 )
Local c:TGadget = CreateCanvas(0,0,w.clientwidth(),w.clientheight(),w,0)
c.setlayout 1,1,1,1
''''''''''''''''''''''''''''''''
TGlobal.width = w.clientwidth()
TGlobal.height = w.clientheight()
TGlobal.depth=16
TGlobal.mode=0
TGlobal.rate=60
SetGraphics CanvasGraphics( c )
TTexture.TextureFilter("",9)
glewInit() ' required for glActiveTexture
glEnable(GL_LIGHTING)
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE)
glEnable(GL_NORMALIZE)
glEnable(GL_SCISSOR_TEST)
glEnable(GL_DEPTH_TEST)
glClearDepth(1.0)
glDepthFunc(GL_LEQUAL)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
glAlphaFunc(GL_GEQUAL,0.5)
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_COLOR_ARRAY)
glEnableClientState(GL_NORMAL_ARRAY)
glLineWidth(4)
Local cam:TCamera=CreateCamera()
PositionEntity cam,0,0,-10
Local light:TLight=CreateLight(1)
Local tex:TTexture=LoadTexture("media/Rock.bmp")
Local cube:TMesh=CreateCube()
Local sphere:TMesh=CreateSphere()
Local cylinder:TMesh=CreateCylinder()
Local cone:TMesh=CreateCone()
PositionEntity cube,-6,0,0
PositionEntity sphere,-2,0,0
PositionEntity cylinder,2,0,0
PositionEntity cone,6,0,0
EntityTexture cube,tex
EntityTexture sphere,tex
EntityTexture cylinder,tex
EntityTexture cone,tex
Local cx#=0
Local cy#=0
Local cz#=0
Local pitch#=0
Local yaw#=0
Local roll#=0
' used by fps code
Local old_ms:Int=MilliSecs()
Local renders:Int
Local fps:Int
''''''''''''''''''''''''''''''''''
CreateTimer( 60 )
While True
WaitEvent()
Select EventID()
Case EVENT_WINDOWCLOSE
End
Case EVENT_WINDOWSIZE
TGlobal.width = w.clientwidth()
TGlobal.height = w.clientheight()
cam.CameraViewport(0,0,w.ClientWidth() , w.clientheight())
DebugLog "EVENT_WINDOWSIZE"
Case EVENT_TIMERTICK
RedrawGadget c
Case EVENT_GADGETPAINT
SetGraphics CanvasGraphics( c )
MoveEntity cam,cx#*0.5,cy#*0.5,cz#*0.5
RotateEntity cam,pitch#,yaw#,roll#
cx#=0
cy#=0
cz#=0
TurnEntity cube,0,1,0
cx#=0
cy#=0
cz#=0
RenderWorld
Flip
EndSelect
Wend
Oh man. We're in a deep shit ;-)
I assumed that I can use Max2D and MiniB3D without any issues and it even didn't bother me if it is slow. So I scheduled a milestone thet ends up 2 weeks from know and requires Max2D and MiniB3D to work :(
I guess I can do some kind of workaround with MiniB3d cause all I need is to draw a background and couple mashes on it.
Man, I need to be more careful next time.
Thanks Peter
Thanks peter this should help :)
Sorry guys, never got a propper chance to look at the b3d loader :)
Simon might fix it too though. :)
yeah its no prob I sent simon a model exported from 3d studio max using the pipeline to show him the problem I was having.
Well im not sure why maybe its because Minib3d doesnt yet offically support using maxGUI but after getting my scene on to the canvas I cant interact with it at all via key input.
Thanks Diablo, it worked.
Unfortunatly, I realized that miniB3D requires OPenGL which is not very suitable for popular/casual game market.
Maybe there will be a DX7 version one day... ?
not sure what you mean about opengl I think the newest version of quake and doom 3 use opengl.
I still cant seem to get any input with canvas's
DX7? why not DX9?
because DX9 is probably overkill for MiniB3d. Let's leave it for Max3d.
Unfortunatly, I realized that miniB3D requires OPenGL which is not very suitable for popular/casual game market.
Well if by "popular/casual game market" you mean the type of games that sell on the portals then you wouldn't really need to be using minib3d anyway since there 99.9% 2D games and if a card can do DX7 direct3d at a speed worth running at then it should be able to do all the basic Opengl stuff thats equivalent to the DX7 stuff, it would only be some extension it might not be able to do.
@ckob : I hope you realize there is no keyhandling code in the sample I posted?. To put it in, you could start by adding some code to handle Case EVENT_KEYDOWN, Case EVENT_KEYUP.
@joncom2000: Yes, I mean popular/casual games. Because we are working on a game that would benefit a lot having player character rendered (3d) on "2d" prerendered screen then DX7 support would be nice to have (yes, this game is targeted at casual audience). I know it could do with OpenGL, but believe me, DX is still less hassle for those people.
Pete: I know but I started working on an editor in would like movement controls inside the editor, and I figured out that I have to use EVENT_KEYDOWN and it works but I have to tap the key in order to get it to work when I want to be able to hold it down any ideas on doing that?
@ckob, you lazy git :):
SuperStrict
Import "../MiniB3D.bmx"
'based on Simple GL cube demo + simonh's primitives.bmx sample
'Written by Birdie
SetGraphicsDriver GLGraphicsDriver(),GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER
Global ax#, ay#,tim#
Local w:TGadget = CreateWindow("Easy Minib3d in a GUI window", 10, 10, 512, 512 )
Local c:TGadget = CreateCanvas(0,0,w.clientwidth(),w.clientheight(),w,0)
c.setlayout 1,1,1,1
''''''''''''''''''''''''''''''''
TGlobal.width = w.clientwidth()
TGlobal.height = w.clientheight()
TGlobal.depth=16
TGlobal.mode=0
TGlobal.rate=60
SetGraphics CanvasGraphics( c )
TTexture.TextureFilter("",9)
glewInit() ' required for glActiveTexture
glEnable(GL_LIGHTING)
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE)
glEnable(GL_NORMALIZE)
glEnable(GL_SCISSOR_TEST)
glEnable(GL_DEPTH_TEST)
glClearDepth(1.0)
glDepthFunc(GL_LEQUAL)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
glAlphaFunc(GL_GEQUAL,0.5)
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_COLOR_ARRAY)
glEnableClientState(GL_NORMAL_ARRAY)
glLineWidth(4)
Local cam:TCamera=CreateCamera()
PositionEntity cam,0,0,-10
Local light:TLight=CreateLight(1)
Local tex:TTexture=LoadTexture("media/Rock.bmp")
Local cube:TMesh=CreateCube()
Local sphere:TMesh=CreateSphere()
Local cylinder:TMesh=CreateCylinder()
Local cone:TMesh=CreateCone()
PositionEntity cube,-6,0,0
PositionEntity sphere,-2,0,0
PositionEntity cylinder,2,0,0
PositionEntity cone,6,0,0
EntityTexture cube,tex
EntityTexture sphere,tex
EntityTexture cylinder,tex
EntityTexture cone,tex
Local cx#=0
Local cy#=0
Local cz#=0
Local pitch#=0
Local yaw#=0
Local roll#=0
' used by fps code
Local old_ms:Int=MilliSecs()
Local renders:Int
Local fps:Int
Local UpKey:Int
Local DownKey:Int
Local LeftKey:Int
Local RightKey:Int
''''''''''''''''''''''''''''''''''
CreateTimer( 60 )
While True
WaitEvent()
Select EventID()
Case EVENT_KEYDOWN
Select EventData()
Case KEY_ESCAPE
End
Case KEY_UP
UpKey = True
Case KEY_DOWN
DownKey = True
Case KEY_LEFT
LeftKey = True
Case KEY_RIGHT
RightKey = True
EndSelect
Case EVENT_KEYUP
Select EventData()
Case KEY_UP
UpKey = False
Case KEY_DOWN
DownKey = False
Case KEY_LEFT
LeftKey = False
Case KEY_RIGHT
RightKey = False
EndSelect
Case EVENT_WINDOWCLOSE
End
Case EVENT_WINDOWSIZE
TGlobal.width = w.clientwidth()
TGlobal.height = w.clientheight()
cam.CameraViewport(0,0,w.ClientWidth() , w.clientheight())
DebugLog "EVENT_WINDOWSIZE"
Case EVENT_TIMERTICK
If UpKey Then cz#=cz#+1.0
If LeftKey Then cx#=cx#-1.0
If RightKey Then cx#=cx#+1.0
If DownKey Then cz#=cz#-1.0
'If KeyDown(KEY_W) Then pitch#=pitch#-1.0
'If KeyDown(KEY_A) Then yaw#=yaw#+1.0
'If KeyDown(KEY_S) Then pitch#=pitch#+1.0
'If KeyDown(KEY_D) Then yaw#=yaw#-1.0
MoveEntity cam,cx#*0.5,cy#*0.5,cz#*0.5
RotateEntity cam,pitch#,yaw#,roll#
cx#=0
cy#=0
cz#=0
RedrawGadget c
Case EVENT_GADGETPAINT
SetGraphics CanvasGraphics( c )
TurnEntity cube,0,1,0
RenderWorld
Flip
EndSelect
Wend
Thanks peter, I actually almost had that I just didnt add the EVENT_Keyup bit and I think thats what did it.
@Anawiki,
----------------------
...would benefit a lot having player character rendered (3d) on "2d" prerendered screen then DX7 support would be nice to have (yes, this game is targeted at casual audience). I know it could do with OpenGL, but believe me, DX is still less hassle for those people.
-------------------------
Thanks, you said it better that I would have said it :)) (but exactly what I meant)
Having a tool allowing mix of 2D and 3D but keeping DX7 for the maximum audience would be great
Since I did the very clean/easy to use MD2 load/anim code, wouldn't it be an idea to integrate it into MiniB3D?
Actually these are also missing from the MiniB3D.htm:
# LoadMD2
# AnimateMD2
# MD2AnimTime
# MD2AnimLength
# MD2Animating
Hmmm. This is very good! Since the B3D terrain command doesn't seem to be implemented (at least as far as I could tell), what would be the best way to set up a simple terrain? Using the included mesh commands, splitting the terrain mesh into uniform-sized chunks and tiling it, perhaps? I wonder how Chris C did his in the screenshot up thread. I would hate to have to write an entire terrain system (which I probably am not skilled enough to do at this point, anyway, especially not from heightmaps) just to use this GREAT add-in. Any hints/shortcuts would be appreciated...
5 post up is code to terrain
Huh? 5 posts up is the code for keyhandling in a BlitzGUI window (which is useful). 5 posts up from where?
The way would be the same as with B3D normally as well: A very simple geomipmap based terrain implementation (terrain chunks basing on a heightmap)
Thanks, ckob! Fredborg's example is a GREAT starting point. Now to set up my tech-demo and get started with the programming...
simonh: any plans on adding a camerapick ? i notice you have entitypickmode but I couldnt find a camerapick.
Yeah I'd like to add CameraPick. I haven't spent a lot of time on MiniB3D recently due to holidays and starting a new job but I'm going to get back to it shortly.
will definately use this in future projects, is there any licensing things with this?
im using this in my current project but until I can get camerapick figured out or until its added im kind of at a stand still with my editor.
EdzUp - No.
What does camerapick do?
camerapick(cam,X,Y) Allows you to pick a 3d location
I'm testing miniB3d.
I have some trouble to load B3d mesh without texture
must be your mesh I load b3d's just fine.
and when i'm loading another b3d mesh with texture i have this.
inking:flee.debug.exe
Executing:flee.debug.exe
DebugLog:TEXS
DebugLog:BRUS
DebugLog:NODE
DebugLog:-NODE (parent= Exported by Gile[s] Version 1.17 at 00:04:40 on 05 Feb 2004 registered to Philippe Agnisola)
DebugLog:--NODE (parent= Exported by Gile[s] Version 1.16 at 00:32:35 on 03 Feb 2004 registered to Philippe Agnisola)
DebugLog:---NODE (parent= Scene Root)
DebugLog:---MESH
DebugLog:---VRTS
DebugLog:---TRIS
DebugLog:---TRIS
DebugLog:---TRIS
DebugLog:---NODE (parent= Scene Root)
DebugLog:---MESH
DebugLog:---VRTS
DebugLog:---TRIS
DebugLog:---NODE (parent= Scene Root)
DebugLog:---MESH
DebugLog:---VRTS
DebugLog:---TRIS
DebugLog:---NODE (parent= Scene Root)
DebugLog:---MESH
DebugLog:---VRTS
DebugLog:---TRIS
DebugLog:--NODE (parent= Exported by Gile[s] Version 1.16 at 00:32:35 on 03 Feb 2004 registered to Philippe Agnisola)
DebugLog:--NODE (parent= Exported by Gile[s] Version 1.16 at 00:32:35 on 03 Feb 2004 registered to Philippe Agnisola)
DebugLog:--NODE (parent= Exported by Gile[s] Version 1.16 at 00:32:35 on 03 Feb 2004 registered to Philippe Agnisola)
~>Unhandled Exception:Attempt to index array element beyond array length
~>
To ckob, patmaba and simonh, the error both ckob and patmaba are describing seems to be in the TMesh update method. The line:
For Local ix=0 To tex_count
should be:
For Local ix=0 Until tex_count
Hope that helps,
Chris
I didnt run into this problem after I started using b3d's exported from milkshape but I will change that thank you.
Falcon,
When I make that change (To into Until), some of my previously textured meshes no longer show textures. That is the only line I modified, so I'm not sure that is the fix to their problem (if it adds other problems). I change it back, and my terrain meshes show properly again...
Hmm, it could be a problem somewhere else as well then, because it looks like brushes exported from B3D pipeline define the number of texture layers as 8 which means in the line:
For Local ix=0 To tex_count
the variable 'ix' attempts to loop through 9 texture layers.
The LoadAnimB3D function uses the following line:
For Local ix=0 To b_no_texs-1
to loop through and assign texture indices to the brush so I'm not really sure where it's going wrong, but I'll have another poke and see what I find.
Maybe I am doing something wrong, but it seems to me that lights are not working correctly. Use this code to test (cone simulates light, use numpad 1-2, 4-5, 7-8 to movelight in x-y-z).
Import "../MiniB3D.bmx"
Local width=640,height=480,depth=16,mode=0
Graphics3D width,height,depth,mode
Local cam=CreateCamera()
PositionEntity cam,0,10,-25
Local light=CreateLight(2)
Local ent=LoadAnimMesh("media/zombie.b3d")
Local cx#=0
Local cy#=0
Local cz#=0
Local pitch#=0
Local yaw#=0
Local roll#=0
Local px#, py#, pz#, lx#, ly#, lz#
Local anim_time#=0
' used by fps code
Local old_ms=MilliSecs()
Local renders
Local fps
Local sp = createcone(32)
Local liteRange# = 25
lightrange light, liteRange
positionentity light, 0, 0, 0
positionentity sp, 0, 0, 0
While Not KeyDown(KEY_ESCAPE)
If KeyHit(KEY_ENTER) Then DebugStop
' control camera
If KeyDown(KEY_UP) Then cz#=cz#+1.0
If KeyDown(KEY_LEFT) Then cx#=cx#-1.0
If KeyDown(KEY_RIGHT) Then cx#=cx#+1.0
If KeyDown(KEY_DOWN) Then cz#=cz#-1.0
If KeyDown(KEY_W) Then pitch#=pitch#-1.0
If KeyDown(KEY_A) Then yaw#=yaw#+1.0
If KeyDown(KEY_S) Then pitch#=pitch#+1.0
If KeyDown(KEY_D) Then yaw#=yaw#-1.0
' MoveEntity cam,cx#*0.5,cy#*0.5,cz#*0.5
' RotateEntity cam,pitch#,yaw#,roll#
cx#=0
cy#=0
cz#=0
'
If KeyDown(KEY_MINUS) Then anim_time#=anim_time#-0.1
If KeyDown(KEY_EQUALS) Then anim_time#=anim_time#+0.1
SetAnimTime(ent,anim_time#)
MoveEntity cam,cx#,cy#,cz#
RotateEntity ent,pitch#,yaw#,roll#
cx#=0
cy#=0
cz#=0
If KeyDown(KEY_NUM1) Then px#=px#-1.0
If KeyDown(KEY_NUM2) Then px#=px#+1.0
If KeyDown(KEY_NUM4) Then py#=py#+1.0
If KeyDown(KEY_NUM5) Then py#=py#-1.0
If KeyDown(KEY_NUM7) Then pz#=pz#-1.0
If KeyDown(KEY_NUM8) Then pz#=pz#+1.0
If KeyHit(KEY_SPACE) Then liteRange:+2
lightrange light, liteRange
positionentity light, px, py, pz
positionentity sp, px, py, pz
pointentity light, ent
pointentity sp, ent
lx:+px ; ly:+py ; lz:+pz
' px = 0 ; py = 0 ; pz = 0
RenderWorld
renders=renders+1
' calculate fps
If MilliSecs()-old_ms>=1000
old_ms=MilliSecs()
fps=renders
renders=0
EndIf
DebugText 0,0,"+/- to animate"
DebugText 0,20,"FPS: "+String(fps)
DebugText 0,40,"anim_time#: "+String(anim_time#)
DebugText 0,100,"x: "+px
DebugText 0,120,"y: "+py
DebugText 0,140,"z: "+pz
DebugText 0,200,"LR: "+liteRange
Flip
Wend
End
Well. The light sample that comes with MiniB3D works for me :)
MiniB3D light sample doesn't show the issue. Test "my" code. Try to position the light that it will light the zombie from left-upper corner. Rotate the zombie - it looks to me that no matter how you position the light when you rotate zombie light is rotated too (or repositioned).
CKob: Camera pick idea: Yes, its a bit slow but it might get you working for now!
Take a render of the scene with every entity's colour set to its ID.Then just read the pixel from a certain X,Y position to retreive the Entity that is at that position :)
Later on you can replace this function with one that is more efficient.
cygnus: that would probebly work on an entity picking basis but if I want to pick xyz on a specific entity say terrain? to place a model.
Use GLUUnproject as shown in C code below:
CVector3 GetOGLPos(int x, int y)
{
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
GLdouble posX, posY, posZ;
glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetIntegerv( GL_VIEWPORT, viewport );
winX = (float)x;
winY = (float)viewport[3] - (float)y;
glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
return CVector3(posX, posY, posZ);
}
Note: This only implements polygon camerapick.
I think I remember there being box and sphere pics also.
These are simple to program though.
BTW: I would like to implement the MD2 functions from B3D.
Just wanted to see how I would go about doing that.
Since the MD2 functions are specialized functions in B3D, should i just make a TMD2Mesh class which derives from TEntity?
And then do the specialized functions below:
# LoadMD2
# AnimateMD2
# MD2AnimTime
# MD2AnimLength
# MD2Animating
Now MD2 files needed a specific texture set through EntityTexture, but did the brush functions work with MD2s in B3D? I'm on mac ATM, so I can't really test this, but maybe someone remembers?
I can see from the entity texture that it's meshes only for now, but we could do a typecheck there. Will be needed anyhoo when terrain support comes along ;)
Regards
yes they do
Ahh ok. Well that's no problem anyway. They just seem like a real special case in Blitz3D :) (MD2 that is)
Can anyone confirm or decline lights issue? It looks to me that entity is always lighted from the same direction when rotating.
Hmm. Zombie lighting looks like the light is coming from the opposite direction than it really is. But that could just be the depth perception of the cone tricking me. Otherwise it looks fine.
Could you explain in more detail?
I mean if the light is to the left of the zombie, then it should only be lighted from the left, not matter how you rotate the zombie.
That's right OZAK. Cone might be a little tricky, but "error" is to big to blame cone for it. Opposite direction and rotating object "rotates with light" is what I see. And that's not how it should look like.
If zombie is facing light then lighting looks ok, but when you rotate him 90 degrees (Y) then lighting is opposite.
woohoo, will try to port some of me other stuff to MiniB3d starting with me Asteroids3d :)
Hmm. Little sprite issue (might be just because I haven't used Blitz3D in forever, so I forget things). Copy and paste the following code [*disclaimer* the terrain code is not mine; this just shows the issue]:
Strict
Import "../MiniB3D.bmx"
Local width=800,height=600,depth=32,mode=0
Local move =2.0
Graphics3D width,height,depth,mode
Local cam:TEntity = CreateCamera()
PositionEntity cam,0,0,-10
Local spr:TSprite = LoadSprite("button_3.png",,cam)
PositionEntity spr,0,0,5
Local light:TEntity = CreateLight(1)
Local terrain:TEntity = LoadTerrain("terrtest.png")
Local tex:TTexture = LoadTexture("grass.png")
PositionEntity terrain,0,-100,0
ScaleEntity terrain,4,50,4
EntityTexture terrain,tex
Local cx#=0
Local cy#=0
Local cz#=0
Local pitch#=0
Local yaw#=0
Local roll#=0
' used by fps code
Local old_ms=MilliSecs()
Local renders
Local fps
While Not KeyDown(KEY_ESCAPE)
If KeyHit(KEY_ENTER) Then DebugStop
' control camera
If KeyDown(KEY_UP) Then cz#=cz#+move
If KeyDown(KEY_LEFT) Then cx#=cx#-move
If KeyDown(KEY_RIGHT) Then cx#=cx#+move
If KeyDown(KEY_DOWN) Then cz#=cz#-move
If KeyDown(KEY_W) Then pitch#=pitch#-1.0
If KeyDown(KEY_A) Then yaw#=yaw#+1.0
If KeyDown(KEY_S) Then pitch#=pitch#+1.0
If KeyDown(KEY_D) Then yaw#=yaw#-1.0
MoveEntity cam,cx#*0.5,cy#*0.5,cz#*0.5
RotateEntity cam,pitch#,yaw#,roll#
cx#=0
cy#=0
cz#=0
cx#=0
cy#=0
cz#=0
RenderWorld
renders=renders+1
' calculate fps
If MilliSecs()-old_ms>=1000
old_ms=MilliSecs()
fps=renders
renders=0
EndIf
DebugText 0,0,"FPS: "+String(fps)
Flip
Wend
End
Function LoadTerrain:TMesh(url:Object,parent:TEntity=Null)
Local pix:TPixmap
If TPixmap(url)
pix = TPixmap(url)
Else
pix = LoadPixmap(url)
If pix = Null Return Null
EndIf
Local mesh:TMesh = CreateMesh(parent)
Local surf:TSurface = CreateSurface(mesh,Null)
Local uscale:Float = 1.0/pix.width
Local vscale:Float = 1.0/pix.height
For Local x:Int = 0 Until pix.width
For Local y:Int = 0 Until pix.height
Local argb:Int = pix.ReadPixel(x,y)
Local height:Float = (((argb Shl 16) & $FF) + ((argb Shl 8) & $FF) + (argb & $FF))/(3.0*255.0)
Local v:Int = AddVertex(surf,x,height,y,x*uscale,y*vscale)
VertexNormal surf,v,0,0,0
Next
Next
For Local x:Int = 0 Until pix.width-1
For Local y:Int = 0 Until pix.height-1
Local v0:Int = x*pix.height + y
Local v1:Int = v0 + 1
Local v2:Int = v1 + pix.height
Local v3:Int = v0 + pix.height
Local t0:Int = AddTriangle(surf,v0,v1,v2)
Local t1:Int = AddTriangle(surf,v0,v2,v3)
'
' Simple normal fix
Local nx0:Float = surf.TriangleNX(t0)
Local ny0:Float = surf.TriangleNY(t0)
Local nz0:Float = surf.TriangleNZ(t0)
Local nx1:Float = surf.TriangleNX(t1)
Local ny1:Float = surf.TriangleNY(t1)
Local nz1:Float = surf.TriangleNZ(t1)
VertexNormal surf,v0,surf.VertexNX(v0)+nx0+nx1,surf.VertexNY(v0)+ny0+ny1,surf.VertexNZ(v0)+nz0+nz1
VertexNormal surf,v1,surf.VertexNX(v1)+nx0 ,surf.VertexNY(v1)+ny0 ,surf.VertexNZ(v1)+nz0
VertexNormal surf,v2,surf.VertexNX(v2)+nx0+nx1,surf.VertexNY(v2)+ny0+ny1,surf.VertexNZ(v2)+nz0+nz1
VertexNormal surf,v3,surf.VertexNX(v3)+nx1 ,surf.VertexNY(v3)+ny1 ,surf.VertexNZ(v3)+nz1
Next
Next
'
' Normalize vertex normals
For Local v:Int = 0 Until CountVertices(surf)
Local nx:Float = surf.VertexNX(v)
Local ny:Float = surf.VertexNY(v)
Local nz:Float = surf.VertexNZ(v)
Local d:Float = 1.0 / Sqr(nx*nx + ny*ny + nz*nz)
VertexNormal surf,v,nx*d,ny*d,nz*d
Next
Return mesh
End Function
You can get the 3 image files you need below (right-click/save image as):



OK. Now use the W key to pitch 360 degrees. For half of the trip, the parented sprite faces the camera. For the other half, it faces away (or is inverted). Is this a bug in MiniB3D (shouldn't a parented sprite always face its parent.... or the camera at least?), or is it something I'm missing?
Hmmmm. Am I just that incorrect, or is this expected behavior? How does this work in B3D?
I'll look into it and the other issues today.
Thank's Si. We have a deadline on Wednesday so any improvements are very welcomed :)
Regarding the lighting issue - it appears to be due to a screwy UpdateNormals - replace it with this one:
Method UpdateNormals()
Local max_shared_verts=3
For Local s=1 To CountSurfaces()
Local surf:TSurface=GetSurface(s)
For Local v=0 To surf.no_verts-1
Local shared_verts=0
Local vx1#=surf.vert_coords[v*3+0]
Local vy1#=surf.vert_coords[v*3+1]
Local vz1#=surf.vert_coords[v*3+2]
Local nx#=0
Local ny#=0
Local nz#=0
For Local t=0 To surf.no_tris-1
For Local c=0 To 2
Local tri_no=(t+1)*3
Local vx2#=surf.vert_coords[surf.tris[tri_no-(3-c)]*3+0]
Local vy2#=surf.vert_coords[surf.tris[tri_no-(3-c)]*3+1]
Local vz2#=surf.vert_coords[surf.tris[tri_no-(3-c)]*3+2]
If vx2#>vx1#-0.0001 And vx2#<vx1#+0.0001 And vy2#>vy1#-0.0001 And vy2#<vy1#+0.0001 And vz2#>vz1#-0.0001 And vz2#<vz1#+0.0001
shared_verts=shared_verts+1
Local v0=surf.tris[tri_no-3]
Local v1=surf.tris[tri_no-2]
Local v2=surf.tris[tri_no-1]
Local ax#=surf.vert_coords[v1*3+0]-surf.vert_coords[v0*3+0]
Local ay#=surf.vert_coords[v1*3+1]-surf.vert_coords[v0*3+1]
Local az#=surf.vert_coords[v1*3+2]-surf.vert_coords[v0*3+2]
Local bx#=surf.vert_coords[v2*3+0]-surf.vert_coords[v1*3+0]
Local by#=surf.vert_coords[v2*3+1]-surf.vert_coords[v1*3+1]
Local bz#=surf.vert_coords[v2*3+2]-surf.vert_coords[v1*3+2]
nx#=nx#+(ay#*bz#)-(az#*by#)
ny#=ny#+(az#*bx#)-(ax#*bz#)
nz#=nz#+(ax#*by#)-(ay#*bx#)
EndIf
Next
If shared_verts>=max_shared_verts Then Exit
Next
Local uv#=Sqr((nx#*nx#)+(ny#*ny#)+(nz#*nz#))
surf.vert_norm#[v*3+0]=nx#/uv#
surf.vert_norm#[v*3+1]=ny#/uv#
surf.vert_norm#[v*3+2]=nz#/uv#
Next
Next
End Method
This is quite a bit faster than the 0.25 version, and roughly about the same speed as Mark's version.
The r0nin - I've checked and B3D doesn't flip the sprite. The sprite orientation code really needs redoing - another problem at the moment is that sprites in the corner of the screen will appear to be tilted slightly.
Hmmm, does anything untoward happen when you run the code? When I run it (and just depress W and hold), the sprite goes from looking like the button is raised to looking like it is indented. Do you get the same effect?
Yes, the sprite is flipped when it shouldn't be.
OK. Sorry, didn't catch that you were talking about B3D above and not MiniB3D, so I didn't think you were getting the same effect. My Bad!
I've released a minor upgrade (0.26) which features fixes for the lighting and b3d loading issues.
Thanks a lot Si. Now it works so much better. I finally managed to mix 2d & 3d (although still not perfect)
will definately use this to test out BMax stuffs, got loads of projects that would benefit from stuff like this :).
Si ya should whack out a logo so we can include it with projects made with it
Another lighting issue. If I create more than one light objects lighting is broken. No matter how far I put the lights from the object is "overlighted". Even if I set light range for both lights to 0 it doesn't change a thing.
thans my mesh load correctly with the version 0.26.
well done.
Note, the texture with format dds doesn't work.
Hi simonh
It's a really great job you have made !! clap clap !!
i see that you continue to work on :) it's cool !
I notify too that you have solved the problem with
gile(s) lightmapped b3d file :) cool :)
I'm trying to make a freelook camera but i don't know
to code mousexspeed/mouseyspeed function ? do you plan to
add it under miniB3D ?
anawiki - OK, I'll look into that.
filax - Here's MouseSpeed functions - they return the pixel movement since they was last called.
Function MouseXSpeed()
Global oldmx
Local mxs=MouseX()-oldmx
oldmx=MouseX()
Return mxs
End Function
Function MouseYSpeed()
Global oldmy
Local mys=MouseY()-oldmy
oldmy=MouseY()
Return mys
End Function
anawiki - I couldn't replicate the multiple lights issue. Could you post an example?
Here's my own example - put it in the tests folder - has two lights, seems to work fine:
Import "../MiniB3D.bmx"
Local width=640,height=480,depth=16,mode=0
Graphics3D width,height,depth,mode
AmbientLight 32,32,32
Local cam=CreateCamera()
PositionEntity cam,0,0,-60
Local light=CreateLight(2)
LightColor light,255,0,0
LightRange light,5
PositionEntity light,0,0,0
Local light2=CreateLight(2)
LightColor light2,255,255,0
LightRange light2,5
PositionEntity light2,10,0,0
Local ent1=LoadAnimMesh("media/grid.b3d")
Local ent2=CopyEntity(ent1)
PositionEntity ent1,0,10,0
PositionEntity ent2,0,-10,0
RotateEntity ent1,180,0,0
Local ent3=CreateSphere(20)
Local ent4=CreateSphere(20)
PositionEntity ent3,-10,0,0
PositionEntity ent4,10,0,0
ScaleEntity ent3,4,4,4
ScaleEntity ent4,4,4,4
Local cx#=0
Local cy#=0
Local cz#=0
Local pitch#=0
Local yaw#=0
Local roll#=0
' used by fps code
Local old_ms=MilliSecs()
Local renders
Local fps
While Not KeyDown(KEY_ESCAPE)
If KeyHit(KEY_ENTER) Then DebugStop
' control camera
If KeyDown(KEY_UP) Then cz#=cz#+1.0
If KeyDown(KEY_LEFT) Then cx#=cx#-1.0
If KeyDown(KEY_RIGHT) Then cx#=cx#+1.0
If KeyDown(KEY_DOWN) Then cz#=cz#-1.0
If KeyDown(KEY_W) Then pitch#=pitch#-1.0
If KeyDown(KEY_A) Then yaw#=yaw#+1.0
If KeyDown(KEY_S) Then pitch#=pitch#+1.0
If KeyDown(KEY_D) Then yaw#=yaw#-1.0
MoveEntity cam,cx#*0.5,cy#*0.5,cz#*0.5
RotateEntity cam,pitch#,yaw#,roll#
cx#=0
cy#=0
cz#=0
'
RenderWorld
renders=renders+1
' calculate fps
If MilliSecs()-old_ms>=1000
old_ms=MilliSecs()
fps=renders
renders=0
EndIf
GLDrawText "FPS: "+String(fps),0,0
Flip
Wend
End
oops sorry ... :)
I'm experiencing the same problem as James, with test-fog.bmx crashing out on renderworld->update->gldrawelements. If I comment out the loading of media/grid.b3d it works so it may be a problem with that model.
If I load grid.b3d into the test-anim.bmx program, it locks up when you press +/- so maybe thats a clue.
If I load grid.b3d into the test-anim.bmx program, it locks up when you press +/- so maybe thats a clue.
No unfortunately it does that with every non animated mesh.
Does it work if you load the grid mesh, but don't scale it? Might be something to do with glEnable(GL_NORMALIZE) in TGlobal.Graphics3D
Also, does the grid load OK in light-test.bmx?
Found the lighting bug - to fix it, change line 1834, or TLight.Update line 29, from:
glLightfv(gl_light[no_lights-1],GL_LINEAR_ATTENUATION,light_range#)
To this:
glLightfv(gl_light[light_no-1],GL_LINEAR_ATTENUATION,light_range#)
I can reproduce test-fog.bmx crashing out on renderworld->update->gldrawelements (well somewhere in renderworld->update anyway ). if I set my hardware acceleration on my GFX card to "none". On "full" everything is ok ( Radeon 9600 XT )
That crashes every program - it will always stop at glActiveTextureARB. If you rem out those lines the fog demo still runs.
Sorry, thought I had something there, oh well.