miniB3D: monkey 3d engine - part7

Monkey Programming Forums/User Modules/miniB3D: monkey 3d engine - part7

AdamRedwoods(Posted 2013) [#1]

Latest update v0.41


Win8 target:

Thread continued from:

- current branch: v0.41 requires Monkey V70+
- tested on glfw, android, macos, ios, xna, webgl, flash

- normals, textures, mipmaps, vertex buffers
- sprites and batch sprites
- context handling for mobile devices
- collisions and object/triangle picking
- animation, bone & vertex
- binary load for b3d files (base64)
- Load B3D, OBJ, MDD, PC2
- animated textures
- XNA, Win8 target (courtesy of Rone), HTML5, Flash
- Shaders, extendable shaders
- normal mapping (opengl2.0)
- mojo 2D integration
- Ouya target

To Do:
- collada
- Flash shaders
- bones to quat/matrix internals
- vector class to use src,dst (minimize GC)
- fix win8
- glow shaders, shadows
- physics
- terrain
- octree scene manager
- mobile neon optimizations

AdamRedwoods(Posted 2013) [#2]
nothing new yet (aside from bug fixes), the other thread was too long!

AdamRedwoods(Posted 2013) [#3]
Re: shaders

.. so really a copy of your Fullshader.

I instantiate it with:
TShader.LoadDefaultShader( new LightShader )

But I just see nothing then. Using the same command with your FullShader and FastBrightShader works just fine. Do I miss something here?

So that FullShader is integrated into the render routine (it doesn't have to be and i should change that), so it does some shader matrix selecting based on what states are needed.

I suggest using the "FullBright" shader as a starting point, it shows how the shader system works. also note you can keep your shader external by loading it in the New() constructor.

LoadShader( vp_filename, fp_filename )
it will link the shader for you, but you must request to link against the uniforms, if you want to use the built-in ones (which i suggest doing, otherwise you'd have to set it up yourself).

if you plan to use framebuffers, you'd initialize it here, too
'' fbo is a field to the shader
fbo = FrameBufferGL.CreateFBO(CreateTexture(256,256,3))

to render to the FBO, you first implement the IShaderProcess, which offer methods that are run before and after each camera:
Class MyShader Extends TShaderGLSL Implements IShaderProcess
and then in the PreProcess Method:
...and in the PostProcess Method:
'' and draw the quad if so desired:
SetShader( New FastBrightShader() ) ''we don't want to call NEW each frame, for example only
fbo.Draw(cam, 1.0) ''could even draw the quad using another shader

So you can see the flexibility here. Now, a deferred lighting shader would need to implement IShaderRender to interrupt the core TRender, set up each GBuffer and shader pass, and then call RenderCamera(cam) again. The texture would be quite large, depending on the resolution of the target (iPad3 retina = 2048x2048), unless you're ok with scaling.

also note, multiple render targets (MRTs) are not guaranteed for all devices.

Xaron(Posted 2013) [#4]
Ah well, thanks for that! I'll check it out.

Is render to texture possible as well?

AdamRedwoods(Posted 2013) [#5]
Is render to texture possible as well?

pretty much that is what the FBO is doing. since the shader is yours, you can add any extra methods you like:
Method SetTexture(mytex:Texture)
tex = mytex
setflag = true

Method PreProcess:int(cam:TCamera)
if (setflag) then fbo = FrameBufferGL.CreateFBO(tex); setflag = false

''main init code:
myShaderInstance = New MyShader()
SetShader (myShaderInstance)
myShaderInstance.SetTexture( some_tex_i_created )
PaintEntity( cube, some_tex_i_created )


...but i think the above code is dangerous, since i'm writing to a texture being read at the same time (bad, bad, bad)! a second texture would be needed (called ping-ponging textures)

Xaron(Posted 2013) [#6]
Ah well, thanks! Basically I just would like to render the entire camera to a texture to have something like a target cam.

AdamRedwoods(Posted 2013) [#7]
you could also create a second camera, parent it to something, and just set the viewport to a small square area.

Xaron(Posted 2013) [#8]
Ah now that's a nice idea! :)

Xaron(Posted 2013) [#9]
Hey Adam, when I call "mesh.FreeEntity()" (after Copymesh) I get an error in the debug version in line 272 of list.monkey:

If _succ._pred<>Self Error "Illegal operation on removed node"

EdzUp(Posted 2013) [#10]
Any news on the Linux front? :)

Xaron(Posted 2013) [#11]
No chance dude, I've blocked him with my collision requests. ;)

Seriously, what's the point of using Linux? No kidding, I'm just curious as it's more niche than Windows Phone and that's already below everyone's radar and for desktop stuff it's still better to use BMax? ;)

EdzUp(Posted 2013) [#12]
The reason for Linux is simply i can use it on me netbook which makes life easier when coding.

Xaron(Posted 2013) [#13]
Ah right, got it! I used a netbook as well in the past (with an Atom CPU) and it was really a pain!

EdzUp(Posted 2013) [#14]
Well its easier as i move around a lot so having a small netbook to code on makes it easier, it cant run windows 7 or 8 but runs linux perfectly. This is why i would like minib3d to work on linux so i can write android stuff on the move one thing max cant do :)

Xaron(Posted 2013) [#15]
Yeah I know what you mean, I sold my Netbook two years ago and I'm now more than happy with a powerful MacBook Air (core i7) which is quite powerful. :)

EdzUp(Posted 2013) [#16]
Yeah atm havent got the funds for such an item, so i use me linux netbook

Xaron(Posted 2013) [#17]
CameraViewPort does NOT work for Android (gles20).

Sammy(Posted 2013) [#18]
I was just wondering, has anyone used miniB3D in a commercial game yet? It looks pretty mature to me.

Sammy(Posted 2013) [#19]
Not sure if I am doing something wrong here. :P I would really appreciate it if somebody with miniB3D, could please confirm that the collision demo is working properly, esp. look out for the little test character sinking into the corners of the big cube?

I'm using the latest Monkey compiler.

Edit: Ignore this, it's a small buggete which Adam is working on to fix.

AdamRedwoods(Posted 2013) [#20]
yup, quick update, i'm working hard on fixing and improving collisions. i have multiple sphere collisions (customizable too) working now.

long term, i really need to port over a proper physics engine, but that's a year-long project. for now, i'll get these simple collisions updated soon.

Sammy(Posted 2013) [#21]
Thanks Adam. Yeah a proper physics engine would be amazing long term. The miniB3D collisions library is still great though for small projects.

EdzUp(Posted 2013) [#22]
@adam:any info on the Linux side of things I'm on Ubuntu 13.04 (32bit) with all the patches and updates :-)

Sammy(Posted 2013) [#23]
Quick question,format_code('Class MyGame Extends MiniB3DApp')
As I am new to miniB3D, what is the advantages to extending MiniB3DApp, as opposed to doing the slightly longer way via the usual extending of App?

computercoder(Posted 2013) [#24]
By extending MiniB3Dapp vs the standard App, it allows you to use the MiniB3DApp functions and access at them as if they were direct methods (because, in an OOP environment, when you extend a base class, you start off with the base class's methods, fields, etc)

Basically you are all set and ready to rock using the MiniB3DApp.

I'm by no means an expert on MiniB3D, but just explaining in an Object Oriented Programming language that this is how this works.

Hope this helps :)

Sammy(Posted 2013) [#25]
Thanks computercoder. One of the things I noticed with the extended demos is that they are fundamentally different in certain ways to the non-extended examples I have seen. For example, no direct calling of Init() or RenderWorld()? Also does Mojo emulation only work with the extended MiniB3DApp?

AdamRedwoods(Posted 2013) [#26]
what is the advantages to extending MiniB3DApp

extending MiniB3DApp will take care of init() and preloading properly (preload is need for html5 and flash). the problem is that i needed to remove the "On" part of "OnCreate" to get it to work (kindof a frustrating monkey thing).

use "Create" to do your preloading, and mesh loading.
use "Init" to create your cameras and meshes.
"Update" and "Render" are the same.

computercoder(Posted 2013) [#27]
No problem Sammy :)

I've notice the same things as you, but I am too new to Monkey to be able to answer your question. I would think that it would not matter either way just as long as your app covers the bases of making Mojo emulation work. What that is, I don't know tho. At least not right now.

Sammy(Posted 2013) [#28]
I like to go down the recommended route if that's what the developer himself is following.

Overall though, it's a lot clearer now. :)

Sammy(Posted 2013) [#29]
Worked fine(HTML5 can't find the GL context though?) in GLFW. I think it's now a lot cleaner looking for the end user Adam, much better IMHO, I like it. :)

AdamRedwoods(Posted 2013) [#30]
CameraViewPort does NOT work for Android (gles20).

works on Nexus 4 here. Android 4.1.1
cam.CameraViewport (x,y,w,h). please send me a screenshot if it seems wrong.

also i noticed: Android OpenGL 20 seems VERY slow when the zombie example fills the screen (ie, zombies are big). I don't know why this is since it should be the opposite. I think there may be a formula in the shader that slows Android waaay down, but i need to get a PowerVR profiler running on it. that'll take some time. i COULD place an adreno work-around, but i don't know how i could set up a runtime check to enable texture int values. ugh.

Sammy(Posted 2013) [#31]
That's bad news, Android is quite an important platform for me, I hope you track it down soon.

BTW is there a problem with texture filters? They dont seem to have any affect of GLFW for me?

AdamRedwoods(Posted 2013) [#32]

That's bad news, Android is quite an important platform for me, I hope you track it down soon.

the issue is with Android+opengles20. Android+opengles11 is faster.

also note, if one sets the gles20 global shader to fastbright ( LoadDefaultShader(New FastBrightShader)) then performance should be fast, but no lighting equations will be used and limited to one texture.

BTW is there a problem with texture filters?

Should work. I've only set it up to be used with LoadTexture() or LoadAnimTexture() it won't work with Sprites or Mesh Models. This can be changed, if needed.

Sammy(Posted 2013) [#33]
My main problem seems to be mip-mapping(flag 8), things are getting real chunky as they go into the distance. It may be a Z buffer problem though as I am also getting flickering textures if two planes are close together too, which gets worse the further they retreat into distance. I'll take another look, I'm probably doing something wrong.

AdamRedwoods(Posted 2013) [#34]
My main problem seems to be mip-mapping(flag 8), things are getting real chunky as they go into the distance.

yes, i've noticed this but haven't spent time on it. it's a user decision how to handle. resize for mipmaps is already smoothing, i wonder if i should add a blur flag to REALLY blur those small mipmaps and remove some chunkiness.

also, each texture has a smooth command:
this will turn on smoothing in hardware.

getting flickering textures if two planes are close together too

may be a different problem. if the z is the same, then they will flicker. a slight offset of +0.0001 usually helps.

Sammy(Posted 2013) [#35]
Thanks for the tips Adam.

Something still not quite right though, for example, if I place two cubes directly beside each other and move a camera around them, moving in and out, every now an then a seem(small gap) appears between the cubes, even though they are perfectly aligned, I would say that this is slightly worse the further away the camera is from the cubes. I recheck my code, if I can't find it, I'll wip up an example.

AdamRedwoods(Posted 2013) [#36]
if I place two cubes directly beside each other and move a camera around them, moving in and out, every now an then a seem(small gap) appears between the cubes, even though they are perfectly aligned,

yes, this is all computer graphics that are not anti-aliased.

you either need AA or the two cubes need to be connected. sometimes, you can get the cubes to be aligned to perfection and it's not noticeable.

EdzUp(Posted 2013) [#37]
I think one thing to consider is in some cases meshes at the same coordinated will get z fighting as the depth buffers cant always calculate which to draw first. As adam has suggested a small offset normally helps

Sammy(Posted 2013) [#38]
Adding 0.0001 helps the flickering textures but the seams are still showing with the cubes. I don't really want to join the meshes as I want the ability to remove a cube when I need to. Is there possibly a way to increase the resolution of the Z buffer?

EdzUp(Posted 2013) [#39]
They do say its to do with camera ranges, apparently if i got it right whole numbers are better than fractions door the near values of the camera

AdamRedwoods(Posted 2013) [#40]
cam.CameraRange(near,far) will increase depth buffer precision.

minib3d does not use polygon offset.

Sammy(Posted 2013) [#41]
@Adam: Interesting links there, thank you. It's a pity MiniB3D does not use glPolygonOffset, it looks quite handy for decals.

@ed: Changing the camera range does not seem to affect the Z buffer at all, only the clipping range, which is kinda weird TBH.

I may leave this for now and come back to it, the scene works, its a tiny bit glitchy but nothing that really too noticeable.

EdzUp(Posted 2013) [#42]
Nah what i meant was near ranges less than 1 can cause glitches

AdamRedwoods(Posted 2013) [#43]
Re: z-depth buffer and camera range:

when you use CameraRange(near,far) it shortens the clipping range IN ORDER TO increase the precision of the z-depth buffer.
12.050 Why is my depth buffer precision so poor?

The depth buffer precision in eye coordinates is strongly affected by the ratio of zFar to zNear, the zFar clipping plane, and how far an object is from the zNear clipping plane.

AdamRedwoods(Posted 2013) [#44]

Hi, update v0.40 for MiniB3D

- updated collisions: added Div Spheres for better collision shape and control
- collision bug fixes, accuracy
- collision debug tools: mesh.col_tree.DebugSphereTree(), mesh.col_tree.DebugNodeTree(node_level)
- added TrisRendered()
- Android vertex buffer optimizations for MojoEmulation
- some TEntity commands chainable

Basically, i've spent a lot of time perfecting collisions, although they still bounce, so I don't think they're perfect. i don't know if i can spend much more time on them, as i'd rather port a full physics engine over instead (CannonJS).

Anyhow, they seem to work except for a couple of bouncing situations.

*new* SphereTree (DivSpheres) usage (please ask and i'll explain more):
ship.CreateSphereTree(5, 0.8)
' ship.DebugSphereTree() ''optional, but important
what are these two line above?

1. CreateSphereTree( num of divSpheres, percentage difference from spheres)
this line is basically creating a Sphere field that covers every cubical area of the mesh, but using spheres. It will take the longest dimension and divide it by these number of spheres. the percentage number (1.0 being the norm) will increase or decrease the sizes of the spheres. a smaller sphere would be something like 0.7. larger would be 1.2. the nominal 1.0 is guaranteed to cover every part of the mesh.

2. DebugSphereTree( ent)
this will visually show the spheres created by CreateSphereTree() so we can see how the algorithm interpreted what we want.

3. SetDivSphere( sphere index number, radius, position )
will alter each sphere individually, rarely recommended, unless you have specific needs.

AdamRedwoods(Posted 2013) [#45]

Update v0.40 for MiniB3D:

Android optimizations i spent some time with DDMS profiling for miniB3D on android. turns out, TOO MUCH TIME was spent on DataBuffer.put(). yikes.

so i cached the MojoEmulation vertex operations and that seems to speed up rendering GUI and images considerably.

EdzUp(Posted 2013) [#46]
Brilliant stuff, will look to coding on windows for now and Linux for 2d games until it gets working on nix

AdamRedwoods(Posted 2013) [#47]

This is an example of a complex object using CreateSphereTree(). It is a careful balance of size and quantity for speed.

Why SphereTree?
Originally, miniB3D source objects for collisions were using only a large, single sphere. So if you object was long and thin, its collision radius would be a large sphere, resulting in poor collisions.
Using SphereTree, now the object's collision is more complex and tightly bound.

This isn't perfect. It is medium to VERY slow using POLYGON collisions, but faster using SPHERE or BOX. The ideal situation is a SphereTree to box collision.


My other thought is to create a capsule shape for collisions, but I didn't think of this until i was almost done debugging this. so perhaps in the future (FAR future) I will make capsule collisions. there are other more important issues to handle first (collada, win8, shadows, bugs, etc)

Sammy(Posted 2013) [#48]
Thank goodness you tracked down that Android problem.

There a lot of good stuff in this update, not least that you are considering a 3D physics port! :)

I'm not 100% on Div Spheres but I am sure I'll understand it better when I see the test code.

Many thanks!

Edit: the post above was just added... aaand now it sinks in! :D

Sammy(Posted 2013) [#49]
BTW I just look up CannonJS, that's an amazing piece of code for Javascript!

AdamRedwoods(Posted 2013) [#50]


I've just added a threshold value to CreateSphereTree(n,size,threshold).
The threshold is the minimum number of vertices it overlaps.

This seems to give much better results at higher n values. Compare this image with the same CreateSphereTree(8,1.0) from above.

EdzUp(Posted 2013) [#51]
@adam: any success on the Linux front?

Sammy(Posted 2013) [#52]
Unfortunately the new update seems to have broken my app. The following lines create an invisible box. This box is the very base for the level props.

Local floorEnt:= CreatePivot()
EntityBox(floorEnt, 0, -1, 0, ground.w, 1, ground.d)
EntityType(floorEnt, scene_type)

The player camera now falls through this entity, since the new update was applied?

AdamRedwoods(Posted 2013) [#53]
The following lines create an invisible box.

updated "tentity.monkey". it was pulling the initial test radius from a mesh cull_radius, which there was none. fixed, let me know if it worked.

AdamRedwoods(Posted 2013) [#54]
@adam: any success on the Linux front?

all i did was add "#define GL_GLEXT_PROTOTYPES" to this and it worked (ubuntu on vmplayer):

don't forget, add it to your monkey/target/glfw/templates/main.h folder, then delete your old .build file and rebuild.

EdzUp(Posted 2013) [#55]
Will try that weird i tried it before and it failed will have another look :)

Ironstorm(Posted 2013) [#56]
What's the difference between FreeTexture() and FreeTexture_()?
I mean, of course I see the code. But for me it looks like FreeTexture() only set the flag to -255 and FreeTexture_() delete it completely.

Sammy(Posted 2013) [#57]
Strange, my character is not falling through the floor now but he cant move(or fall), it's as if he has his collision flag stuck on true. I removed the above entity but it had no affect, the character cant move now. I'll test it some more tonight and try and narrow it down a bit Adam.

AdamRedwoods(Posted 2013) [#58]
FreeTexture() and FreeTexture_()

FreeTexture() sets the flag, so that the platform-specific routine ctaches the flag and deletes the texture in hardware, then calls FreeTexture_().

but he cant move(or fall)
hmmm, ok. if you can create a small example, it helps greatly. if found another collision bug, too, but seems unrelated.

Sammy(Posted 2013) [#59]
OK, np, I'll have a go within the next 30 mins or so.

EdzUp(Posted 2013) [#60]
@Adam: it compiles now but fails on 'opengles11.monkey' line 794 I dont know if its something to do with vbo's as this is a eeePC and the graphics are simple (Intel GMA900 IIRC).

Is there a define or variable I can set to true/false to disable VBO's completely?

Sammy(Posted 2013) [#61]
Some test code to show the problem that I described. I am intentionally not using the auto-scale to mesh bounds BTW, this is closer to my own code. The cube is only present to show the floor volume.

This works on the old miniB3d(0.37?) but does not work on the latest one.

Import mojo

Function Main:Int()
New MyGame()
Return 0

Class MyGame Extends MiniB3DApp
Field fpsRate:Int = 30
Field mesh:TMesh
Field cam:TCamera
Field light:TLight
Field playerEnt:TEntity

Method Create:Int()
Return 0

Method Init:Int()
''must add this to use mojo fonts
cam = CreateCamera()
cam.PositionEntity(5, 2, -20)
light = CreateLight

Local sphere:= CreateSphere()

playerEnt = CreatePivot()
mesh = CreateMiniB3DMonkey()
TranslateEntity(playerEnt, 5, 10, -5)

Local cube:= CreateCube()
cube.TranslateEntity(5, -1, -5)
cube.ScaleEntity(5, 1, 5)

Local floorEnt:= CreatePivot()
playerEnt.CollisionSetup(1, COLLISION_METHOD_BOX, 2)

EntityBox(floorEnt, 0, -2, -10, 10, 2, 10)
' floorEnt.CollisionSetup(2, COLLISION_METHOD_BOX, 0, -2, -10, 10, 2, 10)
EntityType(floorEnt, 2)



Method Update:Int()

If KeyHit(KEY_CLOSE) Or KeyHit(KEY_ESCAPE) Then Error""
playerEnt.TranslateEntity(0, -0.1, 0)
DebugLog "1)player XYZ = " + playerEnt.EntityX() + "," + playerEnt.EntityY() + "," + playerEnt.EntityZ()
DebugLog "2)player XYZ = " + playerEnt.EntityX() + "," + playerEnt.EntityY() + "," + playerEnt.EntityZ()
Return 0

Method Render:Int()
Return 0

Class FPSCounter Abstract
Global fpsCount:Int
Global startTime:Int
Global totalFPS:Int

Function Update:Void()
If Millisecs() - startTime >= 1000
totalFPS = fpsCount
fpsCount = 0
startTime = Millisecs()

Function Draw:Void(x% = 0, y% = 0, ax# = 0, ay# = 0)
DrawText("FPS: " + totalFPS, x, y, ax, ay)

AdamRedwoods(Posted 2013) [#62]
Some test code to show the problem that I described.

thanks for the example, updated github to fix that problem.

I dont know if its something to do with vbo's as this is a eeePC and the graphics are simple (Intel GMA900 IIRC).

yup, i took out non-VBO for now. i guess i can try to put them back in. (EDIT: maybe, if i have time. how bad do you need it?)

EdzUp(Posted 2013) [#63]
Well i use this laptop as my monkey platform, why take them out as its the only way to get minib3d working on old cards or some of the current netbooks?

Sammy(Posted 2013) [#64]
thanks for the example, updated github to fix that problem.

Thank you for the fix Adam, I'll give it a go tonight when I get back home. :)

Sammy(Posted 2013) [#65]
There's some progress here, as I no longer fall though the floor but the collisions are all off now. The collision volumes dont seem to match their meshes. I'm only using COLLISION_METHOD_BOX and COLLISION_RESPONSE_SLIDE for all the collision on the test level but as I said, the meshes no longer match the their collision volumes? Strange thing is I tried the collisions demo that comes with minib3d and that works fine.

EDIT: From my app I narrowed it down to this line:

format_code('cube.CollisionSetup(scene_type, COLLISION_METHOD_BOX,10)')

Which works in 0.37.

But removing the "10" and allowing it to do a mesh bounds check, seems to get it working in 0.40.

AdamRedwoods(Posted 2013) [#66]
if using CollisionSetup(t,COLLISION_METHOD_BOX,10), then the collision box will be 10x10x10. a COLLISION_METHOD_SPHERE or POLYGON will be radius 10.

If EntityBox() or EntityRadius() are used without parameters, then the radius or dimensions is based off of the largest width/height/depth of the model. then the collision sphere/box is always centered to 0,0,0, so some models may be offset if 0,0,0 is not their center.

now, as soon as Collisions(source_type, dst_type, method) is set, then the collision volume may change. example:
cone.CollisionSetup(2, COLLISION_METHOD_SPHERE,2 )
player.CollisionSetup(1, COLLISION_METHOD_POLYGON)
the above code will define a sphere radius of 2 for the cone, and a player radius of mesh bounds-- but it will test for a *BOX* collision for player and cone. so the box is going to be 2x2x2. the source collision volume is ALWAYS a sphere. (this is why i created SphereTree() to allow multi-spheres in the source).

i did change some things in 0.40, but i feel this is how it *should* be for now. does that clarify or is there still a problem?

Sammy(Posted 2013) [#67]
I understand Adam. I did realise that the 10 was for 10x10x10 and I am only using the one collision method throughout("COLLISION_METHOD_BOX"). TBH I am unsure why the collision volume seems to be getting calculated differently in 0.40 as I am not using any bounding spheres or polygons and the old working code has not been changed in any way.

I'll re-check my code, maybe I can spot something.

EdzUp(Posted 2013) [#68]
Does the collision system have rectangle as you don't always want to check for a perfect square or sphere.

Sammy(Posted 2013) [#69]
Yes, the single param is just an overload for a cube Ed. you can still use x,y,z,w,h,d instead of just 10 in my example(-5,-5,-5,10,10,10 I think).

EdzUp(Posted 2013) [#70]
Ah OK :)

Just need the non vbo version to work then its a go

Sammy(Posted 2013) [#71]
There seems to be a bug in AddTriangle(), probably in the creation of the VBO/Vertex Array.

To see the error, load up the animation_test.monkey file and add Wireframe(True) to the init. You will see the zombies have extra vertices connected. This is not a bug in the wireframe mode, the reason you don't see them is simply because they not make up a complete triangle.

I've seen this before while using C+OpenGL and I would hazard a rough guess that the first and last vertices in a triangle group are not being repeated for the VBO or Vertex Arrays. So there not marked(as degenerated vertices) as the end or beginning of a new triangle list when GL renders them.

This is the same if you create your own plane with only AddTriangle() too, so it's not unique to the model loader.

EdzUp(Posted 2013) [#72]
This 'problem' was inherent to blitz3d and minib3d too iirc

if you run through the vertices and triangles of a mesh you will sometimes get some bloody weird results, like some connected to vertex 65535 when the mesh is only 100 vertices

AdamRedwoods(Posted 2013) [#73]
i'm not so sure it's a bug.

"wireframe" in the version of miniB3D that i ported, is fake. it's actually lines drawn by GL_LINE_LOOP. i supply the vertex list and openGL draws them in order. since a line is two points and a triangle is three, there will be odd breaks that draw odd lines.

EdzUp(Posted 2013) [#74]
Nah in not talking about odd lines in talking about how b3d files are handled, in my experience from milkshape they have irregular vertices when created.

Sammy(Posted 2013) [#75]
I'm still pretty confident this may be a bug in the degenerate triangles of a mesh. You wont see this problem 99% of the time(maybe never with most meshes) but if the extra tri-line clashes(is parallel) with another tri-line the already exists on the mesh, it will cause zbuffer problems with that edge of the triangle, causing a very slight intermittent flicker of the edge(A problem I am having with my cubes).

Unfortunately without the use of glEnable(GL_LINES)(which treats degenerate triangles properly) it's pretty hard to prove. Hmmm, I'll have a think of a way to test it properly, if I prove myself wrong, all the better then there's no bug. :)

AdamRedwoods(Posted 2013) [#76]
minor update, but small details are important!

minib3d v0.41

bug fixes:
- FreeEntity() now works
- proper ALPHA_TESTING for textures (kept retro blitz3d "masked textures" although teminology isn't correct)
- Flash target: alpha testing, better point and directional lights, texture bug fix (still lots to do, need better shader)
- XNA: multiple cameras fix

Sammy(Posted 2013) [#77]
Good stuff Adam, I've had a lot of fun with your lib over the last week, thank you! :D

CodeGit(Posted 2013) [#78]
Thanks Adam. Much appreciated. :)

EdzUp(Posted 2013) [#79]
Good to see its being worked on :)

Sammy(Posted 2013) [#80]
Small problem with the HTML5 target when using the "Extends MiniB3DApp" technique?

format_code('Monkey Runtime Error : ReferenceError: gl is not defined
C:/Coding Folder/Middleware/Monkey Pro/modules/minib3d/opengl/opengles20.monkey<134>
C:/Coding Folder/Middleware/Monkey Pro/modules/minib3d/opengl/opengles20.monkey<916>
C:/Coding Folder/Middleware/Monkey Pro/modules/minib3d/opengl/opengles20.monkey<57>
C:/Coding Folder/Middleware/Monkey Pro/modules/minib3d/app.monkey<37>
C:/Coding Folder/Middleware/Monkey Pro/modules/mojo/app.monkey<49>')

My fault?

Sammy(Posted 2013) [#81]
So, should I avoid the HTML5 for now? I don't really use it TBH, I'm using GLFW mainly for testing but it would still be nice to know if it's something I'm not doing properly at my end.

AdamRedwoods(Posted 2013) [#82]
i'll look at it, after i fix this other bug.

Sammy(Posted 2013) [#83]
OK, thanks Adam. :)

AdamRedwoods(Posted 2013) [#84]
the first line in
#OPENGL_GLES20_ENABLED=0') is a pre Monkey v75 marker. it needs to be removed post v75. i'll make the change in the next update.

Sammy(Posted 2013) [#85]
Ah, many thanks for looking into that one for me Adam. I did try before-hand and fiddled with the GL Driver code but it kinda broke miniB3D, lol! :P Maybe I'll be more useful when I get more familiar with the code base.

Amon(Posted 2013) [#86]
I have recently bought a Samsung Galaxy Tab 3 10.1 and when I try MiniB3D on it it fails to find my 3D .obj objects and the textures.

All I get is a white square in the middle of the screen.

The models are definitely present in the .data folder.

I'm using Monkey 75d and the latest MiniB3D.

AdamRedwoods(Posted 2013) [#87]
it fails to find my 3D .obj objects and the textures.

happens to me often, but then i realize i need to do this at the top of my file:
hope that fixes it.

sionco(Posted 2013) [#88]
I think I've found a strange html5 problem (works in flash, GLFW)

The following code at the bottom of this post works.

But, if I comment out the following lines and don't texture the second entity, the game crashes in debug mode with the error codes shown below in the second code box, and in 'release' mode the first object doesn't appear at all, while the second object does:

'if I comment this out, it produces the error
object2Tex = LoadTexture("btcc2.png")

HTML5 debug mode error:

*glerror: 1282
...(^^repeated about 50 times)
Monkey Runtime Error : Max 50 Opengl Errors

It doesn't seem to matter if

Full Code
Import mojo
Import minib3d

Class Game Extends App

Field Camera:TCamera
Field Light:TLight
Field Started:Bool
Field object1Tex:TTexture
Field object1:TEntity
Field object2Tex:TTexture
Field object2:TEntity
Method OnCreate%()
SetUpdateRate 30
Return 0

Method OnUpdate%()
If KeyHit(KEY_CLOSE) Or KeyHit(KEY_ESCAPE) Then Error ""
If Not Started Then Return 0

Return 0

Method Init:Void()
If Started Then Return
If Not TPixmap.PreLoadPixmap(["silverstone2.png","btcc2.png"])
Started = True
Camera = CreateCamera()

object1 = LoadMesh("silverstone2.b3d")
object1Tex = LoadTexture("silverstone2.png")

object2 = LoadMesh("btcc2.b3d")
object2Tex = LoadTexture("btcc2.png")
object2.PositionEntity 0,0,10

Light.MoveEntity -10,10,10
Light.TurnEntity 35,-40,0

Method OnRender%()
If Not Started Then Return 0
Return 0

Function Main%()
New Game
Return 0

AdamRedwoods(Posted 2013) [#89]
interesting, you may need to send me some test files to awpiette at yahoo.
i'll if i can replicate this in the meantime.

sionco(Posted 2013) [#90]
it also happens if I just create an untextured cube instead of the first object, so I've sent an email with the second object I've been using.

Could it possibly be the moddeling software I use?

I use Wings3D > Export to .3ds > CharacterFX > export to .b3d


rebelas(Posted 2013) [#91]
Just a suggestion:
I would concentrate on shadows and physics and keep the rest as simple as possible. You spend lots of time on other things then when it comes to those two, you may shutdown the project.

AdamRedwoods(Posted 2013) [#92]
I had shadows working, but I'd rather get a collada importer working as that seems to be the biggest obstacle, getting assets into the engine. Collada static import does work, btw, but I also want animation and scenes for level creation. i imagine level creation using the blender.

AdamRedwoods(Posted 2013) [#93]
I think I've found a strange html5 problem (works in flash, GLFW)

I didn't find a problem, make sure to download the most recent version. I update things silently sometimes.

sionco(Posted 2013) [#94]
strange, never mind, thanks for looking into it.
I have the latest version of miniB3D and monkey installed.

Sammy(Posted 2013) [#95]
I've converted the Argyne Superemitter particle system, to miniB3D but it's still quite slow on Android. I started using sprites, then sprite batches but it's still killing the frame rate even with modest amount of particles. Has anyone got any tips on speeding particle systems up on miniB3D or batch rendering in general?

Nobuyuki(Posted 2013) [#96]
Sammy: Part of argyne's problem on Android has to do with objects instantiated en masse and then cleaned up by the GC thereafter. You can see the resources being used with logcat and the profiler. I believe that pooling the objects so that they're recycled more often and killed off less would improve performance -- I planned on doing this with the particle manager but never got around to it. I also seem to remember something while I was last working on it that got me caught up and set the optimizations aside having to do with inheritance of interfaces in an array/stack/something. I can't remember what it was, but it had some influence over Argyne's design that probably could've been done more optimally.

Anyway, brl.pool is probably the way to go in terms of optimizing Argyne's performance, although if I knew exactly how to go about using it to optimize the library, I would've probably started on it already. Feel free to make a pull request if you manage to incorporate object pooling into the particle manager :)

Sammy(Posted 2013) [#97]
Thanks for the tip Nobuyuki, I'll look into brl.pool documentation. If I get it to work I'll get back to you. Not sure it would fit in with the current Argyne without getting a new branch though as its now been changed throughout, to cope with the 3rd dimension mainly. I'll be happy to send you the code if I get it working in its miniB3D form + pooling.

BTW I am pretty new to Monkey, what profiler are you using to examine the object code execution?

Nobuyuki(Posted 2013) [#98]
I'm using ddms, which is depreciated, but Android Debug Monitor should be used for any new (within the last year or so) android device. The Traceview tool can be used in combination with ddms's method profiling to produce graphs of which functions spend a lot of time executing.

However... most likely the slowdown is due to the garbage collector, and can be confirmed using the Allocation Tracker tab in the main program. Look for any names resembling Particle that are getting created and destroyed a lot. Frequent GC runs means pooling will be a prime optimization path.

Anyway, feel free to post the 3d fork on Github, this is the first time I've known anyone to make a fork of my code, so it makes me happy to know someone got good use out of it. :)

AdamRedwoods(Posted 2013) [#99]
Android can be slow. the biggest factor i've discovered is working with the FloatBuffer, but i've switched to a native android function that can deal with bulk sets. make sure you have the latest version.

what profiler are you using to examine the object code execution

I use two:
1. HTML5, chrome and firefox have nice profilers. i use these to do very basic desktop profiling.
2. android "monitor" under the tools SDK. i use this only for android java.

Sammy(Posted 2013) [#100]
Ah, some nice tips there, thanks guys!

@Nobuyuki: No problem, I'll post it when I get it working. It's nice logical clean code BTW, which makes it much easier to hop into and modify, thank you for posting it. :)

EdzUp(Posted 2013) [#101]
@Adam: using the latest build it compiles and runs so I can see the 3d view but in the console output I get:
**OPENGL VERSION:1.3999999761581421
..max textures:71
..VBO Disabled
**TModelObj: Material obj file not found
**error: glCamera
and the **error: glCamera just keeps popping up every frame of the app, it does run though and looks brilliant the only thing is the glCamera line is slowing the app down.

Sammy(Posted 2013) [#102]
format_code('**TModelObj: Material obj file not found')

.MAT file missing or path not correct?

"glCamera" error is s little too non-specific, any ideas Adam?

EdzUp(Posted 2013) [#103]
Yeah the material problem is mine the camera error is the one that floods the console over and over which in turn slows the app down. Once that is sorted i will look at doing star rogue using minib3d and monkey as it was intended in the first place :)

AdamRedwoods(Posted 2013) [#104]
Does the firepaint3d example work or do you still get the error?

EdzUp(Posted 2013) [#105]
<snip>error dump removed

Sammy(Posted 2013) [#106]
Do you get this error on your non-Intel GPUs Ed?

EdzUp(Posted 2013) [#107]
ATM I only have Intel CPUs her two low grade laptops, ones Intel hd2000 graphics which I haven't had a chance of testing it on the other is my eeepc which is the one that errors.

EdzUp(Posted 2013) [#108]
<snip> error dump removed

Sammy(Posted 2013) [#109]
GLError 1280 is an GL_INVALID_ENUM error. Which basically means that your GL driver does not support the enum that was passed to it. In other words it looks like your intel drivers are causing the problem Ed.

AdamRedwoods(Posted 2013) [#110]
yeah, i'd have to go through step by step and find the offender, but since i can't do this... instead we're going to absorb the error! opengl ignores 1280, so this is ok. ** Note for Others: This is ONLY in Linux Opengl1.3 (works great 1.5 and above)**

download opengles11.monkey and try again.
also, do me a favor and remove the two big error dumps above, that'll help people scroll through the thread.

EdzUp(Posted 2013) [#111]
Done it :-)

Did they have OpenGL 1.5 I read somewhere they went to OpenGL 2 after that :)

Thanks for sorting the non vbo version though it has really done a lot for my coding with monkey and minib3d I should be able to make star rogue 3d now :)

AdamRedwoods(Posted 2013) [#112]
yeah, they did 1.5, it was the first of shader ARB coding, but was not widely supported. Older Macs, older intel (950) sometimes have software 1.5 support.

ok, good luck!

Grant(Posted 2013) [#113]
Hey guys :)

I have been messing around with minib3d and the examples run fine and dandy. After some more messing about i decided to 'try' and get a model from truespace into minib3d, this is where my nightmare began more than 48 hours ago, still no joy.

I'm literally pulling my hair out now, just about every combination of file format conversion has had some sort of problem with this file format for me. half the time I have a rogue triangle that's not present the original model. The rest of the time normals are flipped or the vertex colours are completley screwed up, or triangles are missing, depending on what the original format before conversion is, and what program does the actual conversion.

I have tried exporting from blender, DeleD and milkshape (.asc -> .b3d works but can't do materials) I even tried a program written in BB3D to do the conversion, it produces the rogue triangle as well.

I am now at a complete loss as to how to get models from truespace into minib3d, any help or suggestions that don't have me learning another 3d app are welcome.

just about everything can save a .X file without problems, the .X files are fine in BB3D when output from truespace. I'd really like to see this file format included in minib3d, even if it's just for static meshes. PLEASE!

Because the conversion path is so bloody convoluted It's nigh on impossible to track down where the real problem is. I'm sure i'm not the only person having serious problems with this file format.

cheers, Grant.

AdamRedwoods(Posted 2013) [#114]
I'm sure i'm not the only person having serious problems with this file format.

you're not.

if you have a problem with the model, you can always send the model to me (awpiette at yahoo), and i'll check it out.

also, i'm working on a collada importer. would that help you? i would be willing to do .x directx loader if that pleases other people as well, but would take a while. anyone else have thoughts?

Have you tried OBJ?

Grant(Posted 2013) [#115]
Hi Adam,

Thanks for making me try .obj again ;)

I was getting messed up normals with .obj exported from truespace, so I thought bugger it, I'll save a .3ds object from truespace with vertex colouring and load that into blender, then save it as a .OBJ... IT BLOODY WORKED BUD! :) I could shake your hand off right now, but I won't because it might be detrimental to the awesome klickity-klack you put in on this stuff.

Cheers muchly :) now i can go ahead and actually make something with your awesomesauce module.

Incidently m8, what about the .mtl files? I noticed an error so added .mtl to the binary list and it was happy days. .mtl file was included in the build and the error dissapeared from Teds output thingy.

AdamRedwoods(Posted 2013) [#116]
glad it worked!
FYI-- if your normals are flipped, you have two options:
mesh.FlipMesh() ''flips all your normals


mesh.UpdateNormals() ''re-calculates your normals

Sammy(Posted 2013) [#117]
I've managed to convert my model into (Max to .X, then .X to B3D) B3D format and it works great but when I animate it using "baddie.Animate(1," my FPS jump from 60 to 6 on my Android Tablet(Nexus 10). I would no say that it's overly complex either, approx 2.5k vertices.

I'm kinda stumped TBH.


Ignore that, I added...


It's weird that sometimes just writing out the problem produces the answer?!?

And this solved the problem, doh! I assumed that it was only Base64.txt files that need this. BTW is there a way to cache the vertex animations back to disk, as for me it takes about 15 secs per boned animated model to calculate. I think it would be better if I saved this to disk and read it back in?

AdamRedwoods(Posted 2013) [#118]
is there a way to cache the vertex animations back to disk

not from miniB3D, but mb3d will load PC2 or MDD files, so you can convert your model to these forms from any animation program (blender). your rest pose should be frame 0.

yes, so bone animation is *slow*. how many baddies did you have? i think android can really have one or two boned animations. at some point i will convert bones to use quaternions.

Sammy(Posted 2013) [#119]
*Double Post* :(

Sammy(Posted 2013) [#120]
I hadn't heard of MDD or MD2(Edit: "PC2!", I got Quake on the brain! :P) format before Adam, I'll look into them. Thanks for the tip.

how many baddies did you have?
Just the one unfortunately. Animation is becoming a real bugbear for me, if I use bones it's too slow, if I use vertex animation it's hogging a large amount if memory.

AdamRedwoods(Posted 2013) [#121]
if I use bones it's too slow

i've been thinking about writing a JNI for neon optimized bulk vertex transforms, maybe i need to look into that more.
the trick is to write it in c and let the compiler do the optimizing:

Sammy(Posted 2013) [#122]
Yes I agree, my small tinkering I've attempted with Neon assembly using the NDK proved to me that in this case, the compiler was far smarter at optimising C into Neon instruction than I ever could be using straight assembly! :P

If the NDK target is released for Android in general, then it would make messing about with compiler optimisation a lot more easier too IMHO.

BTW Adam, on the subject of your input format, I would take the 'easy' option and go with DirectX personally. Collada is great but it's massive scope is maybe OTT for MiniB3D in it's current state feature wise. That said, if your Collada work is further along then this point of view is mute of course.

EdzUp(Posted 2013) [#123]
@adam: i still get a couple of the glError 1280 but after that it goes quiet and itw fine :)

AdamRedwoods(Posted 2013) [#124]
i still get a couple of the glError 1280 but after that it goes quiet and itw fine :)

yes, i absorbed the error. 1280 won't really interfere.

EdzUp(Posted 2013) [#125]
Yeah just wanted to point out that with the latest files ya still get a couple of the errors :)

Sammy(Posted 2013) [#126]
Here is a little experiment. I've added a command to MB3D, "DupeMesh:TMesh(ent:TMesh, parent:TEntity = Null)", this creates an instance of an animated mesh.

The current CopyEntity() already does this but this command creates a completely new entity, complete with it's own vertex data. Mine does not create it's own data, it reuses the source data whenever possible and drops some other data, bones for example(no need after BoneToVertexAnim() has done it's stuff).

What's the advantages?

Memory mainly, the demo here goes from 850meg to 150meg(Zoom out and up to get max zombies in frustum though), by changing CopyEntity() to DupeEntity() with 2000 animated zombies. This is VERY important for mobile platforms, mine crashes quickly when only using a few copied animated meshes currently. The more dupes you use the more the disparity(try 10000 See "ZAmount" :P).

Speed also seems to be better, I'm getting 50%-100% speed increase, which I assume is due to the GPU reusing the same vertex buffer.

This is more of a long winded example for a possible future optimisation by Adam though. If you wish to try it for yourself here are the files.

You can swap out the old CopyEntity() by removing the remark and remarking the DupeEntity() in the zombie demo.

Add this to... functions.monkey

format_code('Function DupeMesh:TMesh(ent:TMesh, parent:TEntity = Null)
Return ent.DupeMesh(parent)

Add this to... tsurface.monkey (within TSurface Class)


Method Dupe:TSurface()

Local surf:TSurface=New TSurface


surf.tris = tris
surf.vert_data = vert_data

If brush<>Null
brush = brush.Copy()

surf.surf_id = surf_id



Return surf

End ')

Add this to... tmesh.monkey (within TMesh Class)

format_codebox('Method DupeMesh:TMesh(parent_ent:TEntity = Null)

Local mesh:TMesh = TMesh.CreateMesh(parent_ent)

' add to collision entity list
If collision.type <> 0 TCollisionPair.ent_lists[collision.type].AddLast(mesh)

' add to pick entity list
If pick_mode <> 0 mesh.pick_link = TPick.ent_list.AddLast(mesh)

' update matrix
If mesh.parent<>Null

' copy mesh info

mesh.loc_mat = loc_mat


mesh.gsx = gsx
mesh.gsy = gsy
mesh.gsz = gsz


mesh.anim_seqs_first = anim_seqs_first[ ..]
mesh.anim_seqs_last = anim_seqs_last[ ..]


mesh.collision = collision.Copy()
mesh.pick_mode = pick_mode

mesh.use_cam_layer = use_cam_layer
mesh.cam_layer = cam_layer

mesh.is_sprite = is_sprite
mesh.wireframe = wireframe

' For Local surf:= EachIn Self.surf_list
' mesh.surf_list.AddLast(surf)
' Next
mesh.surf_list = surf_list

mesh.anim_surf = Self.DupeAnimSurfs()

mesh.col_tree = col_tree

mesh.reset_bounds = reset_bounds

mesh.no_bones = 0
' mesh.bones = bones

Return mesh


'' DupeAnimSurfs()
'' -- full copy will keep new animation copies instead of pointer
Method DupeAnimSurfs:TSurface[]( fullcopy:Int =0 )

Local new_surf:TSurface[] = New TSurface[no_surfs] 'mesh.anim_surf[surf.surf_id]

For Local surf:TSurface=Eachin surf_list

Local id:Int = surf.surf_id
Local anim_surf2:TSurface = anim_surf[surf.surf_id] ''original anim_surf shortcut
If Not anim_surf2 Then Continue

' copy vertex, full copy
new_surf[id] = anim_surf2.Dupe()



new_surf[id].surf_id = anim_surf2.surf_id


new_surf[id].reset_vbo=-1 ' (-1 = all)

'' 1=bones, 2=vertanims
If anim=1 And fullcopy=0

'mesh.anim_surf = New TSurface[no_surfs]
'Local new_surf:TSurface=New TSurface
'Local new_surf:TSurface = mesh.anim_surf[surf.surf_id]

'' dont need below, since Copy() method does this
'new_surf.vert_coords = CopyFloatBuffer(anim_surf2.vert_coords, FloatBuffer.Create(anim_surf2.no_verts*3) )

' pointers to arrays, don't need separate copies unles fullcopy=1
new_surf[id].tris = anim_surf2.tris


Elseif anim=2

'mesh.anim_surf = New TSurface[no_surfs]
'Local new_surf:TSurface=New TSurface

'mesh.anim_surf[surf.surf_id] = anim_surf2.Copy()
'Local new_surf:TSurface = mesh.anim_surf[surf.surf_id]

new_surf[id].vert_anim = anim_surf2.vert_anim ''pointer to shared anim data



Return new_surf


And finaly the modified animation_test2.monkey demo ( copy to same dir as animation_test.monkey)

format_codebox('Import minib3d

Const ZAmount:Int = 2000

''note: if your models look weird, config.h depth buffer bits=32
Function Main()
New Game

Class Game Extends App

Field cam:TCamera

Field light:TLight
Field cube:TMesh, ground:TMesh
Field zombie:TMesh[ZAmount]
Field txt:TText

' used by fps code
Field old_ms:Int
Field renders:Int
Field fps:Int

Field a:Float=0, dir:Int=0, oldTouchX:Int, oldTouchY:Int, touchBegin:Int, lr#, ud#
Field anim_time:Int

Field redbrush:TBrush

Field init_gl:Bool = False

Field zombie_tex:TTexture

Method OnCreate()

SetUpdateRate 60


Method Init()

If init_gl Then Return

If Not TPixmap.PreLoadPixmap(["Zombie.jpg","mojo_font.png"])

init_gl = True

cam = CreateCamera()
cam.CameraClsColor(0, 10, 80)
cam.PositionEntity 0, 30, -10

zombie[0] = LoadAnimMesh("zombie_b3d_base64.txt")

Local speed:Float = 1.0
Local m:Int = - ( (Sqrt(ZAmount) / 2) * 3), xx:Int = -50, zx:Int = m
For Local zz:Int = 1 To ZAmount - 1

zombie[zz] = zombie[0].DupeMesh()'Swap me with...
' zombie[zz] = TMesh(zombie[0].CopyEntity())'!

zombie[zz].Animate(1, ( (xx - m) / 3) * 0.01)
zombie[zz].EntityColor(Rnd(155) + 100, Rnd(155) + 100, Rnd(155) + 10)
zombie[zz].TurnEntity(0, Rnd(360), 0)

Local r:Float = Rnd(0.5); zombie[zz].ScaleEntity(0.75 + r, 0.75 + r, 0.75 + r)
zombie[zz].PositionEntity(xx * 3, 0, zx * 3)
xx = xx + 3; If xx > 99 Then xx = m; zx += 3

zombie[0].Animate(1, 1)
ScaleEntity zombie[0], 2, 2, 2

anim_time = 0

light = CreateLight(1)
light.PositionEntity 0, 30, 300

cube.ScaleEntity(0.5,0.5,0.5) = "cube"
PositionEntity cube, -2, 20, 2

redbrush = New TBrush
cube.PaintEntity( redbrush)

txt = TText.CreateText2D()

ground = CreateGrid(10,10)
ground.ScaleEntity(100, 1.0, 100)



Print "main: init done"

Method OnUpdate()

If KeyHit(KEY_CLOSE) Or KeyHit(KEY_ESCAPE) Then Error ""

If Not init_gl Then Init(); Return

' control camera
Local cr:Float = KeyDown(KEY_LEFT)-KeyDown(KEY_RIGHT)
Local cu:Float = KeyDown(KEY_DOWN)-KeyDown(KEY_UP)

Local camin:Float = KeyDown(KEY_W)-KeyDown(KEY_S)
Local camup:Float = KeyDown(KEY_D)-KeyDown(KEY_A)

Local turnzx:Float = KeyDown(KEY_Z) - KeyDown(KEY_X)

If KeyDown(KEY_0)
SetAnimKey(zombie[1], 10)
MoveEntity cube, (lr) * 0.2, 0.1, ud * 0.1

If TouchDown(0) And Not TouchDown(1)
If Not touchBegin
oldTouchX = TouchX()
oldTouchY = TouchY()
touchBegin = 1
lr = (TouchX() - oldTouchX) * 0.5
ud = (-TouchY() + oldTouchY) *0.5
oldTouchX = TouchX()
oldTouchY = TouchY()
Elseif TouchDown(1)
If Not touchBegin
oldTouchX = TouchX()
oldTouchY = TouchY()
touchBegin = 1
camup = (-TouchX() + oldTouchX) * 0.1
camin = (-TouchY() + oldTouchY) *0.1
oldTouchX = TouchX()
oldTouchY = TouchY()
touchBegin = 0

TurnEntity cube,turnzx*2,0,0
MoveEntity cube,(lr)*0.2,0,ud*0.1'camup,0,camin

cam.MoveEntity camup,0,camin
cam.TurnEntity cu,cr,0

' For Local zz:Int = 1 To ZAmount - 1
' zombie[zz].AlignToVector(cube.EntityX(1) - zombie[zz].EntityX(1), 0,cube.EntityZ(1) - zombie[zz].EntityZ(1), 3,0.10)
' Next

' If Not zombie[0].Animating()
' Local speed# = 1.0
' For Local zz:Int = 0 To ZAmount - 1
' zombie[zz].Animate(2, speed)
' speed -= 0.0025
' Next
' Endif

If KeyDown(187)
anim_time += 1
If KeyDown(189)
anim_time -= 1

txt.SetText(fps+" fps ~nhow are you")

' calculate fps
If Millisecs()-old_ms >= 1000


Method OnRender()




AdamRedwoods(Posted 2013) [#127]
The current CopyEntity() already does this but this command creates a completely new entity, complete with it's own vertex data. Mine does not create it's own data, it reuses the source data whenever possible and drops some other data, bones for example(no need after BoneToVertexAnim() has done it's stuff).

Nice find!
Actually, CopyEntity() is *NOT* suppose to copy the mesh or vertex data. The only data it needs to duplicate is a vertex cache to hold animated data, since different meshes can be animated at different times, speeds, etc.

Cool, I'll look at this and see if CopyEntity() can incorporate this.

CopyMesh() is suppose to be the master copy-all.

Sammy(Posted 2013) [#128]
Thanks Adam.

Actually, although this may be specific to my needs, I've kept the same vertex cache for all the newly duplicated entities and still been able to maintain different animation speeds etc. See,
format_code('surf.tris = tris
surf.vert_data = vert_data')
You will notice that the zombies are actually animating at different rates in this new demo.

Increasing and decreasing the animated frame is just a pointer to a specific place within the preanimated vertex animation cache of the original mesh. So all that needs to be copied is the vertex animation key frame pointer stuff.

Dumping the bone data during the duplication process also saves some memory too.

IceVAN(Posted 2013) [#129]
Hi Adam

On Android I get this error when the method onResume() is called

E/AndroidRuntime( 5140): FATAL EXCEPTION: main
E/AndroidRuntime( 5140): java.lang.NullPointerException
E/AndroidRuntime( 5140): at com.deliriumstudios.smarthphonedriver.c_TTexture.m_ReloadAllTextures(
E/AndroidRuntime( 5140): at com.deliriumstudios.smarthphonedriver.bb_functions.g_ReloadAllTextures(
E/AndroidRuntime( 5140): at com.deliriumstudios.smarthphonedriver.c_MiniB3DApp.p_OnUpdate(
E/AndroidRuntime( 5140): at com.deliriumstudios.smarthphonedriver.c_GameDelegate.UpdateGame(
E/AndroidRuntime( 5140): at com.deliriumstudios.smarthphonedriver.BBGame.UpdateGame(
E/AndroidRuntime( 5140): at com.deliriumstudios.smarthphonedriver.BBAndroidGame.UpdateGame(
E/AndroidRuntime( 5140): at com.deliriumstudios.smarthphonedriver.BBAndroidGame$
E/AndroidRuntime( 5140): at android.os.Handler.handleCallback(
E/AndroidRuntime( 5140): at android.os.Handler.dispatchMessage(
E/AndroidRuntime( 5140): at android.os.Looper.loop(
E/AndroidRuntime( 5140): at
E/AndroidRuntime( 5140): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 5140): at java.lang.reflect.Method.invoke(
E/AndroidRuntime( 5140): at$
E/AndroidRuntime( 5140): at
E/AndroidRuntime( 5140): at dalvik.system.NativeStart.main(Native Method)

in html5 working properly.


AdamRedwoods(Posted 2013) [#130]
On Android I get this error when the method onResume() is called

this error is tougher than i thought. may take some time to figure out as OnResume()+ReloadAllSurfaces is hard-crashing my phone. (dumps the shaders, too, in opengles20)

Sammy(Posted 2013) [#131]
Some preloader questions:

Could someone give me a quick run down of why we need to PreLoad textures, just to clarify?

Is it required for all targets?

Do I need to do this for all data files or just textures?

Also, if the textures are being preloaded then when I try to load them again(it feels like your loading them twice here :P) after the preloading are the preloaded cached textures used instead of the one on the storage device?

If I free a texture, does it affect the preloaded one?

If I decide at some point later down the game to load in a new texture, do I have to stick in an Until loop for a new preload for that texture?

AdamRedwoods(Posted 2013) [#132]
Is it required for all targets?

no, just html5 and flash.

Do I need to do this for all data files or just textures?

just textures, unless DataBuffer goes asynchronous. which could happen.

the preloading are the preloaded cached textures used instead of the one on the storage device?

yes, it checks for the cached. it feels like it's loading twice because i wanted to keep the API simple and easily convert from the GLFW "load now/synchronously" style vs. the load asynchronously style.

If I free a texture, does it affect the preloaded one?

No, not yet, the next version i push will use a counter and release the pixmap when the texture is freed, if no other textures point to the pixmap.

do I have to stick in an Until loop for a new preload for that texture?

depends on your platform. if you are on html5, you can load asynchronously and you will need to check to see when the new set is loaded. use TPixmap.prelaoder.CheckAllLoaded() for each new PreLoad() that is used.
Now, for GLFW and other targets, I don't think they load asynchronously, so no Until loop is needed. this is a Monkey limitation. i had to write my own DataBuffer loader for HTML5 images, this is why. the Monkey implementation did not allow for me to resize images to power-of-two.

Sammy(Posted 2013) [#133]
For some reason I thought Android needed preloading too, doh! This is all handy info though.

Thanks for having the patience in answering my questions Adam.

EdzUp(Posted 2013) [#134]
Is there any special time to use the creation commands, when using procedural generation to make star systems and calling CreateSphere I get nothing but LoadSprite works everywhere.

just wondering as I get the same result on all hardware I've tested on.

Sammy(Posted 2013) [#135]
I keep most of my mesh creating to within the Init() method once preloading is complete and its not caused any problems so far Ed? Could the texture be missing for the Sphere, maybe check the the TTexture is not Null once loaded?

EdzUp(Posted 2013) [#136]
I will check that to see if its a problem but that would mean we can't have untextured meshes :/

Sammy(Posted 2013) [#137]
You should be still able to have untextured meshes, just don't apply a texture to a mesh and it should still appear as blank white(IIRC) mesh by default. My own(.B3D) meshes vanish if I have an error with their texture path. This may be unrelated to your problem though.

If you have the time, maybe a small piece of code illustrating your problem? Or hang back for Adam to have his word?

Sammy(Posted 2013) [#138]
One more question Adam...
no, just html5 and flash.

Why is it needed at all here, what prevents these targets from just loading in a texture normally? Is texture loading pushed onto another thread for example?

AdamRedwoods(Posted 2013) [#139]
calling CreateSphere I get nothing

Just make sure it's after SetRender().

this works for me in OnUpdate(). note that i'm even using a local variable, so it could be collected by the GC, but the master entity_list keeps the sphere in memory.
If KeyHit(KEY_A)
Local sp:=CreateSphere()

Why is it needed at all here, what prevents these targets from just loading in a texture normally?

HTML5 and flash will load all images asynchronously, even in Mojo. your browser controls it. while i could 'lock' the program while things load, this would make the end experience bad. in my opinion, ALL targets should load images and data asynchronously. should be default, but currently you would need to crate your own function by extending Thread.

EdzUp(Posted 2013) [#140]
Ah ok will give it a try was calling it in oncreate, unit and loads of other places but got nowhere. Once its working i will post a demo of it in operation once i clean it up some :)

AdamRedwoods(Posted 2013) [#141]
Should work in OnCreate(), too. make sure your entity is not hidden.

EdzUp(Posted 2013) [#142]
all I'm calling is CreateSphere that's all no state changes etc

Sammy(Posted 2013) [#143]
Could be your intel chipset again Ed? Another option would be to use a tiny 1 pixel white texture then set the colour of the entity IF textured spheres are working?

Sammy(Posted 2013) [#144]
Maybe an option to instal Mes3D( This is an OpenGL driver that can go completely software driven, allowing you to test you graphics off of your graphics card hardware & API for compatibility testing. So if it works in Mesa then it's your chipset.

EdzUp(Posted 2013) [#145]
normally I would agree but with one of me other games it works perfectly, this one calls createsphere in the oncreate method, in star rogue though I have a separate class with method that calls createsphere ( mainly for the generation system for the star systems). This is why I think its strange and why I wondered if there was something I'm doing wrong.

Sammy(Posted 2013) [#146]
Its sounds weird TBH Ed, maybe post some code as an example?


Getting quite a few heap errors errors with a mesh that has quite a lot of animations within it. The animations dont total a great amount(50 meg'ish after interpolated animation processing) but its too much for the puny Android heap. There is the largeheap manifest option but I am unsure if this is the best way to go? Memory problems have been my greatest bugbear with the Android target as of late.

Any suggestions on how to deal with this Adam?

AdamRedwoods(Posted 2013) [#147]
There is the largeheap manifest option but I am unsure if this is the best way to go?

use the android:largeHeap=true command for android 2.3+. i see no problem, since 3D apps take up quite a large amount of memory, and therefore should have memory priority over other apps.

another way would be to devise a fast compression/decompression algorithm for segments of the data.

is this after vertex animation conversion? i am thinking about adding optimized neon mults for bone skinning. will take time, though.

Sammy(Posted 2013) [#148]
Yep, vertex animation. Depending on the amount of frames I use, the following texture loading commands cause the OOM exception. I cut down the frames and resaved the model which cleared up the OOM errors. This was just to confirm where the problem lied though as I still need to get those animations back.

Thanks Adam.

AdamRedwoods(Posted 2013) [#149]
oh, textures? i was thinking about putting in rgb565 or even etc1 for android. that would help a lot if you don't mind quality loss.

let me know if you need that more, i can bump it up on the TODO.

Sammy(Posted 2013) [#150]
I think that the main problem for me is the size if the data that is being produced by conversion from bone animation to vertex animation. Textures merely exasperate the problem. I've tried without textures and still encountered problems.

That being said, smaller textures(or texture compression) would be a welcome feature. The only proviso would be if the actual format be selectable by the coder. So if the scene requires a super smooth high colour textures you could load that image format. Or if it's not required then a lower colour res format. If it was a choice of one or the other, I'd pick the lower colour image formats. Also they would probably be more efficient, speed of rendering wise on the mobile platforms.

It's a pity we can't have a method to force the textures from the heap to graphics ram during the loading process. I don't know if the GL binding commands do this by default?

Btw, talking of textures, I think mipmaps are borked currently, enabling them only makes matters worse quality wise as far as I can tell.

EdzUp(Posted 2013) [#151]
Ah i found the problem with Star Rogue (it will require a rewrite of the system generator) it seems that porting it over from blitzmax to monkey isn't a good idea as the scales are all off. Max minib3d can handle camera ranges of 1, 70000 but monkey minib3d doesn't like it so i will have to reduce the scales and adjust everything to correct it.

this is why the spheres weren't being rendered it seems scaling was giving weird results.

AdamRedwoods(Posted 2013) [#152]
camera ranges of 1, 70000 but monkey minib3d doesn't like it

odd, should work unless the depth buffer precision is rejecting it. glfw = 32bit depth buffer, but sometimes older cards will give 16-bit instead.

i just tested this and it seemed to work at 70000, but i did get some interesting side effects and things close to 70000 would disappear occasionlly.

It's a pity we can't have a method to force the textures from the heap to graphics ram during the loading process.

i've added pixmap.Free() to deal with this, but i'll need to place checks so it re-loads on a lost context, and to make sure it only dumps after a successful bind. i could also add a texture.FreeMemory() perhaps.

I think mipmaps are borked currently, enabling them only makes matters worse quality wise as far as I can tell.

it's an art.
you can try texture.ResizeSmooth() and texture.ResizeNoSmooth() before binding (do this right after creating or loading the texture).
also try texture.Smooth() and texture.NoSmooth() for different rendering approaches.

Rone pointed this out a while ago, and it may have something to do with the resizing algorithm. i almost think a soft blur would help for noisy mipmapped textures.

EdzUp(Posted 2013) [#153]
well I will recode the generator and sort it then I will release a new demo :)

AdamRedwoods(Posted 2013) [#154]
I think mipmaps are borked currently, enabling them only makes matters worse quality wise as far as I can tell.

whoops! turns out i wasn't turning the mipmaps ON! ugh.

Sammy(Posted 2013) [#155]
LOL, NP Adam, I've had one of those days today too! ;)

Sammy(Posted 2013) [#156]
Some of my assets come with normal maps, what's the best way to get these to work with the current mesh system?

Edit: Rather than start another thread.

My GLFW & Android 2D stuff were all looking a bit rough, fonts were distorted and my round buttons were a bit jaggy and distorted, it looked like bad scaling. I tracked the problem down to this line in "mojographics.monkey";-

format_code(' Method LoadTexture:Bool(path$, mesh:TMesh, device:MojoEmulationDevice)


which I changed to
format_code(' tex.ResizeSmooth')

This gave me much better 2D results. Fonts are now easier to read and my round buttons are back to being round and smooth.

AdamRedwoods(Posted 2013) [#157]
Some of my assets come with normal maps, what's the best way to get these to work with the current mesh system?

opengl2.0 targets allow normal maps in texture 0.
the tex flag TEXFLAG_NORMALMAP needs to be set for the texture.

i haven't tested this in a while, so not sure if it still works. if it's broken, let me know.

Sammy(Posted 2013) [#158]
OK, thanks Adam, I'll have to try it tomorrow I'm afraid as I'm off to bed just now. BTW do certain targets default to OpenGLES 2.0 or do I have to specify it?

AdamRedwoods(Posted 2013) [#159]
html5 defaults to opengl2.0. otherwise you must
import minib3d.opengl.opengles20
for android, ios, glfw.

Sammy(Posted 2013) [#160]
Gave it a good go, I tried various textures + normal map formats but it's a no-go I am afraid.

This could very well be down to me though as its the first time I've used normal mapping in MB3D and I may be fumbling something.

EdzUp(Posted 2013) [#161]
First pic of star rogue over at

Edit:forgot to mention its made using minib3d and its not a shameless plug to get me game noticed just a look what's possible sort of thing :)

blabz(Posted 2013) [#162]
Bond, James Bond.

Shaders, extendable shaders.

Sammy(Posted 2013) [#163]
A small edition to TBatchSprite to allow the reuse of existing textures.format_codebox(' Function LoadBatchTexture(tex:TTexture, id:Int = 0)

If id <= 0 Or id > total_batch Then id = total_batch
If id=0 Then id=1



' additive blend if sprite doesn't have alpha or masking flags set
If tex.flags & 6 = 0

mainsprite[id].EntityBlend 3



BTW Adam, did you manage to spot the normal map problem?

Also, is there any way to render to a texture?

AdamRedwoods(Posted 2013) [#164]
cool, i'll add it in.

BTW Adam, did you manage to spot the normal map problem?

i did, SetRender(RENDERFLAG_PERPIXELLIGHTING) needs to be on.
(a side note i'll also add EntityFX FXFLAG_PERPIXEL_LIGHTING to enable in conjunction with other vertex lighting.)

Also, is there any way to render to a texture?

FBO's see post #5 above. opengles 20.
i could fix the BackBufferToTex for an alternate. not sure why i never fixed it.

on another note, i finally fixed the opengl20 context loss. now rebuilds shaders. one more bug to go and i'll push an update.

Sammy(Posted 2013) [#165]
Good stuff Adam, I'm looking forward to giving this all a go tonight! :)

Not tried the shaders as of yet. So does this mean shaders will be available for Gles 2.0?

I wanted to use the render to texture to try and fudge a simple single plane shadow for my scene(use a projected camera view rendered to texture then multitextured onto the ground plane).

Sammy(Posted 2013) [#166]
Still concentrating on normal mapping. I seem to have run into a problem. If I create a cube and load its defuse texture to layer 1, then load in the normal map texture to layer 0 of the cube(1024 flag too ;)), it works and looks great, very pleased with the effect. But if I try and follow the same procedure for an (vertex)animated (.B3D) mesh, I don't get the same results. The texture is there but there is something wrong with the normal map and it affect the lighting of the layer 1 texture, the mesh does not receive lights(only ambient light but this has no affect on the normal mapping any ways).

So the animated character is dull looking and not reacting to the directional lights or any normals information by the looks of it?

AdamRedwoods(Posted 2013) [#167]
can you send a couple screenshots of the problem to awpiette at yahoo?

Sammy(Posted 2013) [#168]
Thanks for the offer of help Adam, I'll post them away just now.

Couple of minor niggles, they may or may not be related.

I would say that the lighting is a little duller in GLES 2.0 when compared to 1.1. That said, it definitely looks nicer with smoother tones I would say.

I'm getting this warning while using GLES 2.0 only.

g++ -I../glfw/include -I../glfw/lib -I../glfw/lib/win32 -I../openal/include -I../stb -c -o ../main.o ../main.cpp
../main.cpp:4184:0: warning: "GL_CLAMP_TO_EDGE" redefined [enabled by default]
../main.cpp:2808:0: note: this is the location of the previous definition')

Not in the slightest causing me any problems though.

EdzUp(Posted 2013) [#169]
Oops looks like someone is redefining a opengl define :)

Sammy(Posted 2013) [#170]
You could very well be right there Ed. I don't think its related to my normal map problems but I thought I'd mention it any ways. ;)

Sammy(Posted 2013) [#171]
Some more info on the normal mapping problem Adam.

HTML 5 works fine. The only other targets I've tried are Android and GLFW. Both display the animated mesh lighting problems.

This is the GLFW console compile output.
format_codebox('miniB3D OpenglES20
g++ -I../glfw/include -I../glfw/lib -I../glfw/lib/win32 -I../openal/include -I../stb -c -o ../main.o ../main.cpp
../main.cpp:4184:0: warning: "GL_CLAMP_TO_EDGE" redefined [enabled by default]
../main.cpp:2808:0: note: this is the location of the previous definition
g++ -Wl,--subsystem,windows -L../openal/libs/Win32 -o Debug/MonkeyGame ../glfw/lib/enable.o ../glfw/lib/fullscreen.o ../glfw/lib/glext.o ../glfw/lib/image.o ../glfw/lib/init.o ../glfw/lib/input.o ../glfw/lib/joystick.o ../glfw/lib/stream.o ../glfw/lib/tga.o ../glfw/lib/thread.o ../glfw/lib/time.o ../glfw/lib/window.o ../glfw/lib/win32/win32_dllmain.o ../glfw/lib/win32/win32_enable.o ../glfw/lib/win32/win32_fullscreen.o ../glfw/lib/win32/win32_glext.o ../glfw/lib/win32/win32_init.o ../glfw/lib/win32/win32_joystick.o ../glfw/lib/win32/win32_thread.o ../glfw/lib/win32/win32_time.o ../glfw/lib/win32/win32_window.o ../stb/stb_image.o ../stb/stb_vorbis.o ../main.o -lopengl32 -lOpenAL32 -lws2_32
Vertex info
0(5) : warning C7050: "nmLight" might be used before being initialized

Vertex info
0(5) : warning C7050: "nmLight" might be used before being initialized

Vertex info
0(5) : warning C7050: "nmLight" might be used before being initialized

Vertex info
0(5) : warning C7050: "nmLight" might be used before being initialized

Vertex info
0(5) : warning C7050: "nmLight" might be used before being initialized

Vertex info
0(5) : warning C7050: "nmLight" might be used before being initialized

Vertex info
0(5) : warning C7050: "nmLight" might be used before being initialized

Vertex info
0(5) : warning C7050: "nmLight" might be used before being initialized

Vertex info
0(5) : warning C7050: "nmLight" might be used before being initialized

..FullShader success

..FastBrightShader success ')

AdamRedwoods(Posted 2013) [#172]
HTML 5 works fine. The only other targets I've tried are Android and GLFW. Both display the animated mesh lighting problems.

"nmLight" is initialized, but nonetheless, i will give it a setting. you never know with these crazy shader compilers.

Sammy(Posted 2013) [#173]
Thanks Adam. Do I download the latest .ZIP from the GitHub repo to try your changes?

Android has the same normal map rendering problems as GLFW but also it's pretty slow too, 60fps drops to 8fps when I add per pixel lighting. It's quite a fast tablet(a Nexus 10), so I was a little surprised that it had such an impact on the frame-rate TBH.

Sammy(Posted 2013) [#174]
Quick question Adam. I have an idea for a simple LOD system. Basically, two pivots at the same position, one with some low geometry meshes the other with high geometry meshes associated with it. then simply hiding one pivot and revealing the other, depending on it's distance from the camera.

My question is this, do I need to worry about the hidden pivots with regards to any hidden child mesh(or collision zone) using up CPU time? Does the engine do anything with these extra entities that would impact on the speed of the non-hidden entities or are they completely ignored while hidden?

AdamRedwoods(Posted 2013) [#175]
do I need to worry about the hidden pivots with regards to any hidden child mesh(or collision zone) using up CPU time?

entity.HideEntity() will not send anything to the render queue, so no.

i have also been slowly thinking about a simple LOD solution, but your method would be just as acceptable.

Sammy(Posted 2013) [#176]
OK thanks Adam, that's a relief! :)

Sammy(Posted 2013) [#177]
@Nobuyuki: Still hitting my head off of Argyne. I have given it a good couple of goes with pooling the particle system but I am not seeing any real gains(It's worse! :P). First time I've used brl.pool so it's maybe time I get to know the Android profiler to see where I am going wrong. I'll post the code when I can get some usable speed out of it.

AdamRedwoods(Posted 2013) [#178]