Openb3d wrapper (Part 2)

BlitzMax Forums/MiniB3D Module/Openb3d wrapper (Part 2)

markcw(Posted 2014) [#1]
Since the original thread has now exceeded 250 posts I thought I should start a new thread. So please post new issues here. Thanks.

Download: the latest version of the wrapper with examples and my small fixes to the C++ source is available HERE courtesy of GitHub.
You can find the official Openb3d libraries and source HERE.

To install MinGW follow this guide.

The original thread about Openb3d is here and the Freebasic thread is here.
Other Openb3d wrapper threads: 1st, 3rd.

New for version 1.0:
V1.0
Added:
-LoadAnimSeq
-SetAnimKey: it's now possible to create custom animation (both vertex morphing and skeletal-based animations are supported)
-CreateBone: create a new bone
-SkinMesh: used to attach a bone to a mesh: surface and mode must be provided as integers, not as handles (the first bone is 1, not the number returned by CreateBone)
-Isosurfaces (created by CreateFluid) can be built using arrays (FluidArray), or by using custom functions
-Particle system: with SpriteRenderMode ..,3 sprites are rendered as particles: they are much faster than normal sprites, and can have a trail: trail length can be set with ParticleTrail, and it can move toward a direction with ParticleVector (useful for fire/smoke effects); also, ParticleColor can be used to set the fading color.

Fixed
-Transitional animations now works with MD2 animations, and with manual mode skeletal animations.
-Vertex shaders can be used on terrains and geospheres: compiling for GLES2 should be easier
-bug in AddMesh: textures sometimes were changed.
-Matrices are now allocated in the stack, and no more in the heap (faster)



daaan(Posted 2014) [#2]
I'm having difficulties compiling on OS X 10.9.5. Here is the compile time error:

Compile Error

24: error: variable length array of non-POD element type 'string' (aka 'basic_string<char>') string brushnames[matlist.size()]; ^


Brucey(Posted 2014) [#3]
variable length array of non-POD element type...

Yes, you can't use string arrays like that with the latest versions of clang-based XCode.

Better to use string vectors or some such instead :o)


daaan(Posted 2014) [#4]
I was trying to compile via BlitzMax IDE. The error was in the Openb3d file and not my own. I thought I read that this was Mac compatible. What do I need to do to get it to work? What information can I provide that would help?


Brucey(Posted 2014) [#5]
Some parts of x.cpp need to be fixed to use string vectors instead of variable length string arrays, which clang-based XCode does not support.

Munch should be able to sort it for you via my copy of the file. :-)


daaan(Posted 2014) [#6]
Thanks a ton Brucey. :D

Also thanks another to munch for your work. This looks really neat and I look forward to trying it out.


markcw(Posted 2014) [#7]
Daaan, x.cpp source is updated. Thanks Brucey.

I use Xcode 3.2.2 on Mac 10.6 which seems to compile the string arrays fine.

Btw, only text-based version 3.2 of x files is supported by Openb3d, see here.

Brucey, I see you have implemented TPtrMap in bmx.ng!


daaan(Posted 2014) [#8]
Thanks! This is going to breath some much needed life into my programming. Shader support, woot woot!


Sonic(Posted 2014) [#9]
looking forward to trying this out as i have run into several technical issues with a sprawling BMax+MiniB3D project...


Sashkakuhta(Posted 2014) [#10]
Im got some really wierd problems with bumpmap shaders. The point of problem in one screenshot:

This happens on AMD Radeon HD 6470M, but on nvidia gtx 670 everything is working as it should.

P.S. sorry for my English


markcw(Posted 2014) [#11]
I've had similar results using OpenGL 1.2 on Win XP. I doubt you have this setup though. The shader bumpmap1.glsl still (kind of) worked but the other 2 went like that (shaders came in with OpenGL 2.0). I really don't know, it could be an error in the shader code like something not defined. Try other shaders.


angros47(Posted 2014) [#12]
About using OpenB3D in GLES 2.0, maybe the simplest solution is this one:

https://code.google.com/p/gles2-bc/

or this other:

https://github.com/p3/regal

Actually, rendering using only programmable pipeline is already possible, although a bit tricky: it's possible to use the command UseSurface to pass surface data to a shader, and UseMatrix to pass matrix data. UseSurface, at the moment, is a bit limited: in fact, you have to explicitly set a surface, and this means that for every surface you'd need a different shader; anyway, I already made a fix, that will come with next version; also, currently no surface data are passed when the shader is used on a terrain (or a geosphere), in the next version it will.

Anyway, there is still a big issue: replacing all the fixed functions with shader would bloat the library (the shaders need to be stored as text, to be compiled just in time), and customizing them would be trickier; also, many shaders built for OpenGL 2.0 would not work anyway, because some commands are deprecated (like gl_Vertex)


angros47(Posted 2015) [#13]
I'm improving shader support; UseMatrix will be able to pass not just modelview or projection (like in current version), but model, view, projection, and modelview (model * view).

Also, I found a way to build these matrix without relying on GL_MODELVIEW_MATRIX and GL_PROJECTION_MATRIX commands (these commands are still used in other sections, but they can be removed to build a version compatible with GLES 2.0)


feeble1(Posted 2015) [#14]
I'm having a bit of an issue freeing lights. Here's an example.




feeble1(Posted 2015) [#15]
It seems that lights are not being stored in a list, so FreeEntity's list.remove(this) won't work on them.


angros47(Posted 2015) [#16]
You've just found a bug... here is the fix:

in "light.cpp", locate the "FreeEntity" function, and change it to:

void Light::FreeEntity(){

	Entity::FreeEntity();

	for (int i=0; i<no_lights;i++){
		glDisable(gl_light[i]);
		if (light_list[i]==this){
			light_list.erase(light_list.begin()+i);
			break;
		}
	}

	no_lights=no_lights-1;

	
	delete this;
	
	return;

}



feeble1(Posted 2015) [#17]
That works great, much better than my terrible attempt to rewrite light.cpp. I broke the shadows quite effectively.

Thanks for the effort.


feeble1(Posted 2015) [#18]
I did change it slightly. Just because I like lists. But you would have to change the Vector declaration to list in Light.cpp, Light.h, Camera.cpp, and Shadow.cpp

void Light::FreeEntity(){

	Entity::FreeEntity();

	for (int i=0; i<no_lights;i++){
		glDisable(gl_light[i]);

		light_list.remove(this);
		break;

	}

	no_lights=no_lights-1;

	
	delete this;

	return;

}



feeble1(Posted 2015) [#19]
Here is a further example ( the basis of which was found on these forums ) that demonstrates another odd behavior.

It is pretty lengthy for an example, but I think it displays this issue well.




angros47(Posted 2015) [#20]
As you might know, I don't have BlitzMax installed, so I can't test; what is the odd behavior you experienced?


feeble1(Posted 2015) [#21]
Essentially, if you create multiple lights and attempt to free them, it seems to only free the last light created.


feeble1(Posted 2015) [#22]
Here is a simpler example, if it helps.

Import angros.b3dglgraphics
'Import sidesign.minib3d

Graphics3D 800,600,0,2

Local camera:TCamera=CreateCamera()
PositionEntity camera, 0,0,-10
Local light:TLight=CreateLight()
Local light2:TLight=CreateLight()
Local cube:TEntity=CreateCube()

While Not KeyHit(KEY_ESCAPE) And Not AppTerminate()
	Cls

	If KeyHit(KEY_SPACE)
		FreeEntity light
		FreeEntity light2
	EndIf
	
	UpdateWorld
	RenderWorld
	
	Flip
Wend
End




markcw(Posted 2015) [#23]
Hi guys! Angros47's code just needs a tiny tweak. Remove the line that has the 'break' and it works fine.

Edit: another issue, when you try to FreeEntity on something that has already been freed I get a segmentation fault in ubuntu.


feeble1(Posted 2015) [#24]
Have you tried setting the freed entities handle to Null?


markcw(Posted 2015) [#25]
Hi, yes that works but my point was that minib3d doesn't need this check.

I just tested in Win7 and I get a MAV (on pressing Space twice) with feeble1's first sample. The second sample (which is pretty cool btw) doesn't MAV because the code removes it from the linked list. The third sample with 2 lights gives an EXCEPTION_PRIV_INSTRUCTION (which seems to be another type of MAV).


angros47(Posted 2015) [#26]
@feeble1
Try this patch in light.cpp:

void Light::FreeEntity(){

	Entity::FreeEntity();

	int erased=0;

	for (int i=0; i<no_lights;i++){
		glDisable(gl_light[i]);
		if (!erased && light_list[i]==this){
			light_list.erase(light_list.begin()+i);
			erased=1;
		}
	}

	no_lights=no_lights-1;

	
	delete this;
	
	return;

}


This works if you use vectors; if you are going to use lists, just remove the "break" instruction, as munch stated, or it will remove only the first light (and put the "light_list.remove(this);" outside the for cycle... you only need to do it once).

@munch
In fact you shouldn't use FreeEntity twice: it's a wrong way to code, because when an entity is freed the handler points to unallocated memory, and trying to access it again will have undefined behavior. And, since the handler is passed to OpenB3D by value, not by reference, OpenB3D cannot set it to null.

Minib3d is written in BlitzMax, and it allows you to use the handler to a freed entity, because it does not deallocate memory: the garbage collector included in BlitzMax will take good care of this (and, as long as you still have an handler to that entity, the garbage collector won't deallocate it).

OpenB3D is written in C++, and C++ has no garbage collector: so, all memory needs to be deallocated by OpenB3D itself: deallocation is obtained by the "delete this;" instruction: after that, any attempt to access the entity might crash the software. There is no work around, unless you implement a garbage collector in C++; as long as the programmer doesn't try to perform "forbidden" things, he won't need a garbage collector anyway, because OpenB3D and minib3d will behave in the same way.


Brucey(Posted 2015) [#27]
In fact you shouldn't use FreeEntity twice

It shouldn't matter if the "glue" code is written properly. A second call could just do nothing. If the underlying library doesn't support it, you kind of need to handle it in the glue - or you specify in the BlitzMax documentation that after calling FreeEntity status/use of the object is undefined.

it's a wrong way to code

Indeed it is.


markcw(Posted 2015) [#28]
Okay I see, thanks for the explanation. So assuming users in Max will use lists then the change to light.cpp should be this?

void Light::FreeEntity(){

	Entity::FreeEntity();

	for (int i=0; i<no_lights;i++){
		glDisable(gl_light[i]);
		if (light_list[i]==this)
			light_list.erase(light_list.begin()+i);
	}

	no_lights=no_lights-1;

	light_list.remove(this);
	delete this;
	
	return;

}



feeble1(Posted 2015) [#29]
Vectors and lists, in this area, are pretty much a matter of preference. They can both do this job, but the creator of iMiniB3D eventually switched lights over to a list. That is really the only reason that I would like to do so.

Either way, I believe this light bug is squashed. Thank you all for your work!


markcw(Posted 2015) [#30]
Okay, so Openb3d is using a vector in light.cpp "vector<Light*> Light::light_list;" so I don't need the "light_list.remove(this);" line.


feeble1(Posted 2015) [#31]
You only need to use list commands if you have changed the Light declaration from a Vector to a List.
I only changed mine to a list because I was attempting to add some of Simon's most recent additions to iMiniB3D.


markcw(Posted 2015) [#32]
Hi Angros, I've just been trying to replicate Nehe 26 (Clipping & Reflections Using The Stencil Buffer) with Openb3d but I'm stuck. I don't know how the rendering is supposed to work - how do you render the rest of the scene after you render the reflection? And I'm getting strange clipping results with the ball. Here is what I have... Also I'm not sure what StencilAlpha is supposed to do. Thanks.
removed, see below



angros47(Posted 2015) [#33]
The command UseStencil will affect all RenderWorlds performed after it: to restore the default behavior just use "UseStencil 0" (you don't need glDisable).

The third parameter of StencilMesh should not be 0, otherwise the mesh would not affect the stencil at all (that's why your example doesn't work); try with a value of 1.

To render the rest of the scene, your use of StencilMode seems to be correct ("StencilMode( stencil, 1, 0 )" will draw only where the stencil is not enabled, while "StencilMode( stencil, 1, 1 )" does the opposite)


markcw(Posted 2015) [#34]
Hi angros, thanks for that great info, but I still can't render both the reflection and rest of the scene together. This is as far as I get. Any ideas?
removed, see below



angros47(Posted 2015) [#35]
You should add the command "cameraclsmode camera,1,1" before "UseStencil (null)", and the command "cameraclsmode camera,0,0" before "UseStencil (Stencil)": in fact, by default RenderWorld clears the screen (ALL of it, not only the stencil portion), so when you render the stencil the rest of the scene is erased: the command "cameraclsmode ..,0,0" disables that behavior, and the "cameraclsmode ...,1,1" restore the default settings.


markcw(Posted 2015) [#36]
Thanks angros, that was it!

One more thing, how do I use the clip plane to prevent the ball coming out of the reflective surface? I tried with glEnable(GL_CLIP_PLANE0), glClipPlane(GL_CLIP_PLANE0, eqr) but couldn't get it to work.

Here is what I have now.
removed, see below



Ferret(Posted 2015) [#37]
I have a problem with transparancy.

I'm using a png texture with alpha to texture a sprite, but wathever the texture flags or blend mode, no transparancy.


markcw(Posted 2015) [#38]
Are you using EntityFX(ent,32)?


markcw(Posted 2015) [#39]
I got the clip plane working. I had to change the height to the right amount. It seems there are some flickering polys though which the Nehe tut doesn't have. I wonder what could cause that. Edit: it's z-fighting, but I don't think I can fix it.



Also, I've been wondering angros, are you accepting donations for development of Openb3d? I would like to contribute something but your site doesn't have a donate button.


Ferret(Posted 2015) [#40]
I wrote a test app with only the basics and it worked.
Verry wierd because i did the exact same thing.

So i started to delete code to find out what was causing this.
Line below was the problem.

Text(10,10,"FPS:"+FPS)


markcw(Posted 2015) [#41]
Not sure what's wrong there but try replacing Text with:

BeginMax2D()
DrawText "FPS"+FPS,10,10
EndMax2D()


markcw(Posted 2015) [#42]
Just testing out the voxel commands and got stuck on how to mask the texture to get transparency.



Edit: I found out. The image needs an alpha channel and flag 4 set in LoadMaterial. How? In Photoshop you use the magic wand, c&p to remove the background then save as png. Also I had to make either the first or last image blank as they were getting blended.


Ferret(Posted 2015) [#43]
I have full bright quads that are affected by lights.

quad:TMesh = CreateQuad()
EntityFX(quad,1+32)


Ferret(Posted 2015) [#44]
I just updated to 0.9 but now every example crashes.

I deleted the old mod
Installed the new mod
Build Modules with no error


markcw(Posted 2015) [#45]
Don't know why it's doing that. Sorry.


Ferret(Posted 2015) [#46]
Bah, i was making good progress and now this.

If i'm the only one that reported this, it must be my system.

Blitzmax and mi drivers are up to date.
Does the version of MinGW matter?


Ferret(Posted 2015) [#47]
I did a clean install of BMax and the mod, no other mods, but it still crashes.

Now i'm trying the dll but got this error,

Error: Can't find symbol:DepthBufferToTex


markcw(Posted 2015) [#48]
Looks like something needs to be updated there. I doubt anybody uses the DLL stuff now due to the new license agreement so it's not been updated. I don't think you need any special MinGW. I use Linux so maybe the Win version has an error. I'll have a look soon.


markcw(Posted 2015) [#49]
@Ferret

I checked and Win builds fine here Max 1.50+Mingw 4.6.1. The dll option is borked now since moving to glew so you can't build a dll from my version of the makefile because of compiler errors (not being able to build glew.o basically). I should probably just remove the dll wrapper. You can comment all references to DepthBufferToTex in the wrapper to get it to run with the official dll if your stuck.


Ferret(Posted 2015) [#50]
Woohoo, got it to work using the static lib.

I did a clean install of,
BMax 1.50
Openb3d 0.9
MinGW 32-bit 4.7.1, using this tutorial (http://www.blitzbasic.com/Community/posts.php?topic=95220)
Nvidia drivers with default card settings.

I think it had something to do with mi card settings.

Thank you for trying to help Munch, i really appreciate it!


markcw(Posted 2015) [#51]
Great stuff! Sorry I was a bit slow in response, it's been a while since I tinkered with Bmax.


Hezkore(Posted 2015) [#52]
Is this still being developed?

The sl_cubemap example crashes and sl_dof example doesn't seem to do much.



angros47(Posted 2015) [#53]
Yes. I'm still working on it


markcw(Posted 2015) [#54]
sl_cubemap works fine here, sl_dof is unfinished. If you want to debug try loading one cubemap shader at a time (the demo loads 4) and see which ones crash (just change the string names rather than comment out the variables).


Hezkore(Posted 2015) [#55]
I'll give that a go later and report back here.

I have noticed some weird behaviour with AddMesh too.
Here's how it looks (and should look) with normal MiniB3D


And here's how it looks with OpenB3D


The test uses chunks with its own mesh, and it seems like OpenB3D only allows for one texture per mesh when using AddMesh?
Something like that atleast.


angros47(Posted 2015) [#56]
Maybe you have two textures with the same name.


Hezkore(Posted 2015) [#57]
It's two different cube meshes that are being added to the cunk mesh.
One's using the texture "grass.png" and the other one "sand.png"
It works fine with MiniB3D, it's only OpenB3D that does this.


Hezkore(Posted 2015) [#58]
Regarding the cubemap demo not working.
The error is caused by line 179 - BackBufferToTex tex
Even if I do "If tex Then BackBufferToTex tex" it still crashes there.


angros47(Posted 2015) [#59]
About cubemap, you should use "CameraToTex texture, camera"


angros47(Posted 2015) [#60]
About AddMesh, try uncommenting the line:

if(brush1->tex[i]->texture!=brush2->tex[i]->texture) return false;


in "brush.cpp"


markcw(Posted 2015) [#61]
Strange, BackBufferToTex is also in cubemap.bmx and tex_render.bmx so it should crash there too. I used BackBufferToTex instead of CameraToTex as it was faster.


angros47(Posted 2015) [#62]
@Hezkore

Please, could you tell me if uncommenting that line fixed your issue, so I can declare the bug closed in the next release?


markcw(Posted 2015) [#63]
Hezkore, I think it crashes in sl_cubemap.bmx at BackBufferToTex not because there's anything wrong with that command but because the shader code is not compliant with your setup. I have made the shaders compatible with GLSL version 110 but there may be a mistake somewhere. Shaders are difficult to debug because every time there is an error in the code it will just crash and there is no error report. If you could find out which of the cubemap shaders (1 to 4) crashes (see my previous post) that would help narrow it down.


AdamStrange(Posted 2015) [#64]
Shaders are difficult to debug because every time there is an error in the code it will just crash and there is no error report.

Munch I've got some shader compile code that does report errors, error line, etc if you want to look at it (blitzmax though)?


markcw(Posted 2015) [#65]
I didn't realize that was possible AdamStrange. Yes, I'd like to see that!


AdamStrange(Posted 2015) [#66]
ok I'm including the whole shader file code here and a quick demo after it
the (not) included Folder.bmx is just about getting correct folders, so it can be removed. There are lots of prints and comments throughout as well

'**********************************************
'******	MGLShader.bmx
'**********************************************

SuperStrict


Import "MFolder.bmx"

Global ShaderDir:String = AppResourceDir + "shaders/"
If FileType(ShaderDir) <> 2 Then ShaderDir = AppDir$ + "/resources/shaders/"


'shader error types
Const SHERROR_NONE:Int = - 1
Const SHERROR_VERTEX:Int = 0
Const SHERROR_FRAGMENT:Int = 1
Const SHERROR_LINK:Int = 2
Const SHERROR_VARIABLE:Int = 3




'Const RADIANS_TO_DEGREES:Float = 180.0 / Pi
'Const DEGREES_TO_RADIANS:Float = Pi / 180.0





Type TGLShader
	Field ProgramObject:Int
	Field Error:Int
	Field ErrorShader:Int
	Field ErrorLine:Int
	Field ErrorMessage:String	
	
	
	Method Load:TGLShader(VertexPath:String, FragmentPath:String)
		ProgramObject = -1
		Error = False
		ErrorShader = SHERROR_NONE
		ErrorLine = SHERROR_NONE
		ErrorMessage = ""	

		Local VertexCode:String, FragmentCode:String
		

		Try
			Print "Loading vertex file "+ vertexpath
			VertexCode   = LoadText(VertexPath)
			Print "Loading fragment file "+fragmentpath
			FragmentCode = LoadText(FragmentPath)
		Catch Dummy:Object
			Return Null
		EndTry
		
'		Print " Compiling "+VertexPath+" & "+FragmentPath
		Compile(VertexCode, FragmentCode)
		
		Return Self
	End Method
	
	
	
	Method Compile:TGLShader(VertexCode:String, FragmentCode:String)
'		Print "Creating program object"
'		If Not ProgramObject Or ProgramObject < 0 Then ProgramObject = glCreateProgramObjectARB()
		If Not ProgramObject Or ProgramObject < 0 Then
			Print " compile Create ProgramObject"
			glewInit() 'must be done AFTER window creation
			ProgramObject = glCreateProgramObjectARB()
		End If	
		
		Local VertexShader  :Int = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)
		Local FragmentShader:Int = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB)
		
		Print "loading vertex..."
		_LoadShader(VertexCode, VertexShader)
		Print "compiling vertex..."
		glCompileShaderARB(VertexShader)
		
		If _CheckForErrors(VertexShader, ErrorMessage) Then
			glDeleteObjectARB(VertexShader)
			
			Error = True
			ErrorShader = SHERROR_VERTEX
			Return Null
			Throw ErrorMessage
		EndIf
		
		Print "loading fragment..."
		_LoadShader(FragmentCode, FragmentShader)
		Print "compiling fragment..."
		glCompileShaderARB(FragmentShader)
		
		If _CheckForErrors(FragmentShader, ErrorMessage) Then
			glDeleteObjectARB(VertexShader)
			glDeleteObjectARB(FragmentShader)

			Error = True
			ErrorShader = SHERROR_FRAGMENT
			
			Return Null
			Throw ErrorMessage
		EndIf
		
		glAttachObjectARB(ProgramObject, VertexShader)
		glAttachObjectARB(ProgramObject, FragmentShader)
		
		glDeleteObjectARB(VertexShader)
		glDeleteObjectARB(FragmentShader)

		Error = False
		Print "compile ok"
		Return Self
	End Method
	
	
	
		
	Method link:TGLShader()	
		If Not ProgramObject Or ProgramObject < 0 Then
			Print " link Create ProgramObject"
			glewInit() 'must be done AFTER window creation
			ProgramObject = glCreateProgramObjectARB()
		End If	
		
		Print "  Linking… Program="+ProgramObject
		
		glLinkProgramARB(ProgramObject)
		Print "link 2"
		If _CheckForLinkErrors(ProgramObject, ErrorMessage, False) Then

			Print "link 3"
			Error = True
			ErrorShader = SHERROR_LINK

			Return Null
			Throw ErrorMessage
		End If	
		
		Error = False
		Print " Shader linked OK"
		Return Self
	End Method



	Method ErrorReport()
		Select ErrorShader
			Case SHERROR_VERTEX
				Print "Error in vertex shader. Line " + ErrorLine
			Case SHERROR_FRAGMENT
				Print "Error in fragment shader. Line " + ErrorLine
			Case SHERROR_LINK
				Print "Error in linking vertex and fragment shaders. Line " + errorLine
		End Select		
		Print " - "+ErrorMessage
'		End
	End Method
	
		
	
	Method Enable()
'		Print "ProgramObject="+ProgramObject
		glUseProgramObjectARB(ProgramObject)
	End Method


	
	Method Disable()
		glUseProgramObjectARB(0)
	End Method


	
	Method GetUniformLocation:Int(Name:String)
		Return glGetUniformLocationARB(ProgramObject, Name)
	End Method


	
	Method Delete()
		glDeleteObjectARB(ProgramObject)
	End Method



	Method setUniformFloatArray1:Int(name:String, count:Int, val:Float Ptr)
		Local loc:Int = glGetUniformLocationARB(ProgramObject, name.ToCString())

		If loc < 0 Then
			Error = True
			ErrorShader = SHERROR_VARIABLE
			ErrorMessage = "Problem Setting Uniform Float Array Var '"+name+"'"
			Return False
		End If

		glUniform1fv(loc, count, val)
		
		Return True
	End Method



	Method setUniformMatrix4:Int(name:String, count:Int, transpose:Int, mat:Float Ptr)
		Local loc:Int = glGetUniformLocationARB(ProgramObject, name.ToCString())

		If loc < 0 Then
			Error = True
			ErrorShader = SHERROR_VARIABLE
			ErrorMessage = "Problem Setting Uniform Float Array Var '"+name+"'"
			Return False
		End If

		glUniformMatrix4fv(loc, count, transpose, mat)
		
		Return True
	End Method



	Method setUniformFloat1:Int(name:String, val:Float)
		Local loc:Int = glGetUniformLocationARB(ProgramObject, name.ToCString())

		If loc < 0 Then
			Error = True
			ErrorShader = SHERROR_VARIABLE
			ErrorMessage = "Problem Setting Uniform Var '"+name+"'"
			Return False
		End If

		glUniform1fARB(loc, val)
		
		Return True
	End Method



	Method setUniformFloat2:Int(name:String, val1:Float, val2:Float)
		Local loc:Int = glGetUniformLocationARB(ProgramObject, name.ToCString())

		If loc < 0 Then
			Error = True
			ErrorShader = SHERROR_VARIABLE
			ErrorMessage = "Problem Setting Uniform Var '"+name+"'"
			Return False
		End If

		glUniform2fARB(loc, val1, val2)
		
		Return True
	End Method



	Method setUniformFloat3:Int(name:String, val1:Float, val2:Float, val3:Float)
		Local loc:Int = glGetUniformLocationARB(ProgramObject, name.ToCString())

		If loc < 0 Then
			Error = True
			ErrorShader = SHERROR_VARIABLE
			ErrorMessage = "Problem Setting Uniform Var '"+name+"'"
			Return False
		End If

		glUniform3fARB(loc, val1, val2, val3)
		
		Return True
	End Method



	Method setUniformFloat4:Int(name:String, val1:Float, val2:Float, val3:Float, val4:Float)
		Local loc:Int = glGetUniformLocationARB(ProgramObject, name.ToCString())

		If loc < 0 Then
			Error = True
			ErrorShader = SHERROR_VARIABLE
			ErrorMessage = "Problem Setting Uniform Var '"+name+"'"
			Return False
		End If

		glUniform4fARB(loc, val1, val2, val3, val4)
		
		Return True
	End Method



	' Set Uniform Variable Integer(s)
	Method setUniformInt1:Int(name:String, val:Int)
		Local loc:Int = glGetUniformLocationARB(ProgramObject, name.ToCString())

		If loc < 0 Then
			Error = True
			ErrorShader = SHERROR_VARIABLE
			ErrorMessage = "Problem Setting Uniform (int) Var '"+name+"'"
			Return False
		End If

		glUniform1iARB(loc, val)

		Return True
	End Method



	Method setUniformInt2:Int(name:String, val1:Int, val2:Int)
		Local loc:Int = glGetUniformLocationARB(ProgramObject, name.ToCString())

		If loc < 0 Then
			Error = True
			ErrorShader = SHERROR_VARIABLE
			ErrorMessage = "Problem Setting Uniform (int) Var '"+name+"'"
			Return False
		End If

		glUniform2iARB(loc, val1, val2)
		
		Return True
	End Method



	Method setUniformInt3:Int(name:String, val1:Int, val2:Int, val3:Int)
		Local loc:Int = glGetUniformLocationARB(ProgramObject, name.ToCString())

		If loc < 0 Then
			Error = True
			ErrorShader = SHERROR_VARIABLE
			ErrorMessage = "Problem Setting Uniform (int) Var '"+name+"'"
			Return False
		End If

		glUniform3iARB(loc, val1, val2, val3)
		
		Return True
	End Method



	Method setUniformInt4:Int(name:String, val1:Int, val2:Int, val3:Int, val4:Int)
		Local loc:Int = glGetUniformLocationARB(ProgramObject, name.ToCString())

		If loc < 0 Then
			Error = True
			ErrorShader = SHERROR_VARIABLE
			ErrorMessage = "Problem Setting Uniform (int) Var '"+name+"'"
			Return False
		End If

		glUniform4iARB(loc, val1, val2, val3, val4)
		
		Return True
	End Method


	
	Function _LoadShader(ShaderCode:String, ShaderObject:Int)
		Local ShaderCodeC:Byte Ptr = ShaderCode.ToCString()
		Local ShaderCodeLen:Int    = ShaderCode.Length
		
		glShaderSourceARB(ShaderObject, 1, Varptr ShaderCodeC, Varptr ShaderCodeLen)
		
		MemFree(ShaderCodeC)
	End Function


	
	Method _CheckForErrors:Int(ShaderObject:Int, ErrorString:String Var, Compiled:Int = True)
		Local Successful:Int
		
		If Compiled Then
			glGetShaderiv (ShaderObject, GL_COMPILE_STATUS, Varptr Successful)
		Else
			glGetProgramiv(ShaderObject, GL_LINK_STATUS,    Varptr Successful)
		EndIf
		
		If Not Successful Then
			Local ErrorLength:Int
			glGetObjectParameterivARB(ShaderObject, GL_OBJECT_INFO_LOG_LENGTH_ARB, Varptr ErrorLength)
			
			Local Message:Byte Ptr = MemAlloc(ErrorLength), Dummy:Int
			
			glGetInfoLogARB(ShaderObject, ErrorLength, Varptr Dummy, Message)
			
			ErrorString = String.FromCString(Message)
			MemFree(Message)

			'strip the "ERROR: 0:" from the beginning
			ErrorString = Right(ErrorString, ErrorString.length - 9)
			
			'get the line number
			Local pos:Int = Instr(ErrorString, ":", 1)
			Local line:String = Left(ErrorString, pos - 1)
			ErrorLine = line.toint()
			
			'strip the errorline
			ErrorString = Right(ErrorString, ErrorString.length-pos-1)
			
			Return -1
		EndIf
		
		Return 0
	End Method



	Method _CheckForLinkErrors:Int(ShaderObject:Int, ErrorString:String Var, Compiled:Int = True)
		Local Successful:Int
		
		If Compiled Then
			glGetShaderiv (ShaderObject, GL_COMPILE_STATUS, Varptr Successful)
		Else
			glGetProgramiv(ShaderObject, GL_LINK_STATUS,    Varptr Successful)
		EndIf
		
		If Not Successful Then
'			Return -1
			Local ErrorLength:Int
			glGetObjectParameterivARB(ShaderObject, GL_OBJECT_INFO_LOG_LENGTH_ARB, Varptr ErrorLength)
			
			Local Message:Byte Ptr = MemAlloc(ErrorLength), Dummy:Int
			
			glGetProgramInfoLog(ShaderObject, ErrorLength, Varptr Dummy, Message);
'			glGetInfoLogARB(ShaderObject, ErrorLength, Varptr Dummy, Message)
			
			ErrorString = String.FromCString(Message)
			MemFree(Message)

			'strip the "ERROR: 0:" from the beginning
			ErrorString = Right(ErrorString, ErrorString.length - 9)
			
			'get the line number
			Local pos:Int = Instr(ErrorString, ":", 1)
			Local line:String = Left(ErrorString, pos - 1)
			ErrorLine = line.toint()
			
			'strip the errorline
			ErrorString = Right(ErrorString, ErrorString.length-pos-1)
			
			Return -1
		EndIf
		
		Return 0
	End Method


	
	Function CheckCompability:Int()
		Local Extensions:String = String.FromCString(Byte Ptr glGetString(GL_EXTENSIONS))
		Local GLVersion:String  = String.FromCString(Byte Ptr glGetString(GL_VERSION))
		Local GLVersionInt:Int  = GLVersion[.. 3].Replace(".", "").ToInt()
		
		If Extensions.Find("GL_ARB_shader_objects" ) >= 0 And ..
		   Extensions.Find("GL_ARB_vertex_shader"  ) >= 0 And ..
		   Extensions.Find("GL_ARB_fragment_shader") >= 0 Or GLVersionInt >= 20 Then Return True
		
		Return False
	End Function
End Type



AdamStrange(Posted 2015) [#67]
to use:
Method InitShaders()
		Local ok:Int = True
		'this is the deferred renderer
		Shader.Load(ShaderDir+fboShaderNAme+"vert.c", ShaderDir+fboshaderNAme+"frag.c")
		If Shader.Error Then
			Shader.ErrorReport()
			ok = False
		End If
		Shader.Link()
		If Shader.Error Then
			Shader.ErrorReport()
			ok = False
		End If

	ShadersLoaded = ok
End Method


when you resize the screen you will need to init()

			'lets have a new shader
				If Not(ShadersLoaded) Then
					InitShaders()
				End If


i'm going to also give you part of my render code:

		'!!!!!!!!!!!!!!!!! MUST ACTIVE SHADER FIRST !!!!!!!!!!!!!!!!!
		'render To FBO bound textures with shader - all off screen
			Shader.Enable()

'<snip>do stuff

		shader.setUniformfloat1("Distance", 5)

		Shader.SetUniformFloat1("time", Float(MilliSecs()) * 0.0001)
		
		Shader.SetUniformFloat4("lightPos", 0,5,0, 1)
		Shader.SetUniformFloat4("lightLookat", 0,0,0,1)

'<snip> draw stuff

		Shader.Disable()


this will help you with initialising, sending variables, etc :)


markcw(Posted 2015) [#68]
Thank you AdamStrange. That looks pretty clever. I'll see if I can get it working. :)


AdamStrange(Posted 2015) [#69]
just give me a shout if you're having problems ;)


angros47(Posted 2015) [#70]
Version 1.0 is online:

Added:
-LoadAnimSeq
-SetAnimKey: it's now possible to create custom animation (both vertex morphing and skeletal-based animations are supported)
-CreateBone: create a new bone
-SkinMesh: used to attach a bone to a mesh: surface and mode must be provided as integers, not as handles (the first bone is 1, not the number returned by CreateBone)
-Isosurfaces (created by CreateFluid) can be built using arrays (FluidArray), or by using custom functions
-Particle system: with SpriteRenderMode ..,3 sprites are rendered as particles: they are much faster than normal sprites, and can have a trail: trail length can be set with ParticleTrail, and it can move toward a direction with ParticleVector (useful for fire/smoke effects); also, ParticleColor can be used to set the fading color.

Fixed
-Transitional animations now works with MD2 animations, and with manual mode skeletal animations.
-Vertex shaders can be used on terrains and geospheres: compiling for GLES2 should be easier
-bug in AddMesh: textures sometimes were changed.
-Matrices are now allocated in the stack, and no more in the heap (faster)


Brucey(Posted 2015) [#71]
Excellent! Thanks! :-)


markcw(Posted 2015) [#72]
Yes, great work Angros. That looks like all the essential remaining functions are now in. Version 1.0 at last! Have you tested the AddMesh bug?


angros47(Posted 2015) [#73]
Since Hezkore hasn't submitted the code that exposed the bug, I can't test anything.

I figure that the cause is in CompareBrush internal function, as I reported (it's the only thing that is different in OpenB3D and MiniB3D, and Hezkore told that MiniB3D worked). I don't even remember why I had commented out that line (maybe I did in the first, prerelease version, when I had not yet included stbi_load, and forgot to set it back). Now I fixed it.

Since Hezkore seems to be the only one to complain until now, I'll wait for a feedback: if he doesn't answer, I'll have to think it worked for him.


markcw(Posted 2015) [#74]
Ok, I have some code that tests the AddMesh bug. It is just taken from the B3D AddMesh example with brush textures added. In the demo, Openb3d used the first texture for the tree trunk when it should use the second. Uncommenting that line in brush.cpp fixed it.




angros47(Posted 2015) [#75]
Thank you for testing (assuming that the bug you tested is the same bug reported by Hezkore ... )

In version 1.0 of OpenB3D the line is uncommented, so it should work.


Hezkore(Posted 2015) [#76]
Sorry for not replying, this forum is a bit wonky and refuses to send me emails even though I've subscribed to this post.

I think it crashes in sl_cubemap.bmx at BackBufferToTex not because there's anything wrong with that command but because the shader code is not compliant with your setup.

It doesn't matter what shader I remove, it always crashes at that function.
I'm not sure what you mean with "compliant with your setup".
I have an AMD Radeon R9 290X GPU if that's what you're wondering.

Anyways... I don't have the add mesh "example" anymore, it was part of an ongoing project.
I'm waiting for munch to update his GitHub to the new version before I can test if it's fixed.

I have however noticed some other weird stuff.
If you use Max2D (BeginMax2D) on a resizeable MaxGUI window, the offset/viewport is all wrong after resizing.

The "maxgui.bmx" example is working great, but if I add some text with
BeginMax2D()
DrawText("Hello World", 0, 0)
EndMax2D()
after RenderWorld and start resizing the window, the text doesn't stay in the corner.




If I instead use
Text(0,0,"Hello World")
everything works correctly, even after resizing the window.



So there must be something up with BeginMax2D causing this.


markcw(Posted 2015) [#77]
I have updated my Github for version 1.0 now. I added a new demo, stencil.bmx.

Hezkore, I added sl_error.bmx which will post an error report of all the cubemap shaders (using AdamStrange's code). So let me know what that says in the output window.

I'm not sure what's wrong with maxgui.bmx and Max2d, but it seems this demo has broken on Mac since a while ago. I couldn't trace either of these bugs unfortunately.


Hezkore(Posted 2015) [#78]
Nice stencil demo!
I actually needed this.

Here's the output from sl_error.bmx
Loading vertex file shaders/cubemap.vert.glsl

Loading fragment file shaders/cubemap.frag.glsl

 compile Create ProgramObject

loading vertex...

compiling vertex...

loading fragment...

compiling fragment...

compile ok

  Linking… Program=1

link 2

 Shader linked OK

Loading vertex file shaders/cubemap2.vert.glsl

Loading fragment file shaders/cubemap2.frag.glsl

 compile Create ProgramObject

loading vertex...

compiling vertex...

loading fragment...

compiling fragment...

compile ok

  Linking… Program=4

link 2

 Shader linked OK

Loading vertex file shaders/cubemap3.vert.glsl

Loading fragment file shaders/cubemap3.frag.glsl

 compile Create ProgramObject

loading vertex...

compiling vertex...

loading fragment...

compiling fragment...

compile ok

  Linking… Program=7

link 2

 Shader linked OK

Loading vertex file shaders/cubemap4.vert.glsl

Loading fragment file shaders/cubemap4.frag.glsl

 compile Create ProgramObject

loading vertex...

compiling vertex...

loading fragment...

compiling fragment...

compile ok

  Linking… Program=10

link 2

 Shader linked OK
cubemap demo still crashes on BackBufferToTex.
But I can get it working by calling
CameraToTex(tex, camera)
once at the start of the function UpdateCubemap.

A real shame about Max2D not working.
It's a really important part, and I really needed it for doing my interface.


markcw(Posted 2015) [#79]
Thanks Hezkore. So it seems it's not a problem with the shaders then! My bad. I wonder then if you can call once before the main loop:
CameraToTex(cubetex, cube_cam)

This would be much faster.

I'll keep trying to solve the maxgui max2d bug.


Hezkore(Posted 2015) [#80]
Yeah before the main loop works just fine!

Thanks for having a look at the MaxGUI part.
It's the only thing holding me back from using this module right now.

Are there any plans to support anything else than B3D?
It's hard to convert todays formats to B3D (without Ultimate Unwrap 3D and even then it's not that good)
FBX, DAE or something like that would be good.


Brucey(Posted 2015) [#81]
Doesn't assimp support fbx?


Hezkore(Posted 2015) [#82]
It does, but the module for it doesn't support animations.
And it loads models weird with way too strong shading.


Brucey(Posted 2015) [#83]
but the module for it doesn't support animations.

That can probably be fixed.

And it loads models weird with way too strong shading.

This can't be a bug with assimp, otherwise everyone would be complaining about it?


Hezkore(Posted 2015) [#84]
No it's probably all the modules fault and it's probably possible to fix it all.


markcw(Posted 2015) [#85]
Ultimate unwrap 3d is also a great texture mapping tool and I would recommend buying it as it's very cheap. The Assimp wrapper may never support animations, it will be up to the legendary Brucey to sort that one out I think!

A new update, I managed to fix the maxgui max2d bugs! :)

The first was with CameraViewport, I had incorrectly inverted its y parameter which caused screen garbage in the maxgui demo on Mac. I think I have fixed it now. The second was the problem Hezkore posted about with DrawText moving from it's y position on resizing. This was because you need to pop the max2d states to update them and then push them again. The third bug was in Linux where DrawText wasn't even visible. This was because there is no EVENT_WINDOWSIZE at init in Linux. Those changes are in maxgui.bmx.

It seems a bit odd but you need to call beginmax2d in EVENT_WINDOWSIZE and endmax2d in EVENT_GADGETPAINT for it to work, this is because the size values have not been updated yet when WINDOWSIZE is called. Also SetViewport needs to be called inside the max2d functions.


Hezkore(Posted 2015) [#86]
Well done munch!
Can't you add your own hook for window resizes, so that the user doesn't have to do BeginMax2D() at EVENT_WINDOWSIZE?


markcw(Posted 2015) [#87]
Hmm, I guess so. I updated the example with the resize hook stuff. I couldn't hook the event_gadgetpaint for some reason so the push/end part went in a resizeviewport method, and I ended up putting the whole demo in a type so now it should be less confusing. :)


markcw(Posted 2015) [#88]
I've updated the maxgui example again. I decided it needed to be flexible, so I took the rest of the code out of the type. I had to remove the hook stuff as although it worked sometimes it would fail to be called, so I just kept it simple and now all you need is 3 lines of code.


markcw(Posted 2015) [#89]
Angros, I translated the octree example but I really don't understand how to use the commands. I understand the theory, that it optimizes a scene for collisions or LOD, I'm not sure if Openb3d supports LOD. I tested the example but couldn't find any noticable speed increase from octree collisions.

I don't understand why octreeblock scales everything depending on the level parameter, apart from that I can't see any difference between it and octreemesh. I wanted to create a scene with lots of trees and LOD them to show how octrees can do that but nothing I tried worked properly.


angros47(Posted 2015) [#90]
OctreeMesh just places a mesh into a node of the octree. Octree is then used to determine if it is visible or not. You'd have to scale the mesh by hand. Of course, that mesh can be only in one position at the same time: if you use the command OctreeMesh twice on the same mesh, result is undefined. If you want to have two identical mesh, you'd have to use CopyEntity, CopyMesh, RepeatMesh or something similar.

But in an octree there are elements that might be needed many times: a brick of wall, a tile of the floor, and so on. Most of these elements are just cubes with a different texture. Using copymesh/copyentity would be a waste... why creating a different entity for every brick, since they will never be moved again?

OctreeBlock is for that: if you place a mesh with octreeBlock, you can place it in more than one place inside the octree, and it will be automatically "duplicated", using no more memory. Since they are no new entities, they can't have a position, a rotation or a scale; they will use the same rotation of the octree, and the scale and position of the node they are linked to: a mesh that has the size of 2,2,2 (like a cube as it's made by CreateCube) will fit exactly in a cell of the octree. Of course, the higher the level, the smaller the cell, that's why scale depends on the level parameter.

About the LOD level, you should use the last two (optional) parameters of OctreeBlock and OctreeMesh: Near and Far.

"Near" is the minimum distance at which that node is visible: if set to 0, that node is always visible, if higher than 0, the mesh/block won't be rendered when it's closer (but the node will still be processed, and its child could be rendered); use it with nodes that contains a big, low-res version of the model, to hide it when the object is too close to the camera. By default, it is set to 0.

"Far" parameter is the maximum distance at which the node can be split in children: if it's set at the same range of the camera, the node will be always be split (if it has any child, of course); if the node has no child, this parameter is useless. A low value means that, if the node is at a bigger distance from the camera, its children won't be processed or rendered (if they contained an high-res version of the model, they won't be visible). By default this parameter is set to 1000.

So, to achieve LOD, you'd need to split your model in many parts, and put them in high level (smaller) nodes: only parts that are in view will be rendered; on lower level (bigger) node you can attach a whole, low resolution version of the model. Let's say you have a model of an house, made by many "bricks"; you can store at zero level a model of the whole house, setting both near and far to 100; then, you build a more accurate model, made by blocks (a sort of a 3d version of a tile map) using higher lever nodes: when the house is at a distance greater than 100, you'll be able to see the external model, but not the smaller blocks (since the "Far" parameter is 100, they are not processed); if you get closer, you won't be able to see the complete model (since the "Near" parameter is 100, when you get closer it won't be rendered anymore), but you'd be able to see the various block that build the house, including interiors (there are many blocks, but only the one that are in camera view will be rendered).

Producing appropriate box models is up to you (in theory, you could "slice" a bigger mesh using a cube and CSG features, but it might be complicate); you'd have to store the same model at different resolutions.

Of course, you can applies the LOD to just a part of an octree, not to the whole octree.


markcw(Posted 2015) [#91]
Wow! What a complete answer! Thank you Angelo! :)


markcw(Posted 2015) [#92]
Well I can get the LOD method working but only at 0,0,0 world position. When I move the mesh to say 10,0,10 the octree still thinks it's 0,0,0.

Local cone:TMesh=CreateCone()
Local cube:TMesh=CreateCube(cone)

MoveEntity cube,0,1,0
MoveEntity cone,0,2,0

Local x:TOcTree=CreateOcTree(20,20,20)
OctreeMesh x,cube,0,0,0,0,20,20
OctreeMesh x,cone,1,0,0,0,0,0



angros47(Posted 2015) [#93]
Because you attached it at node in position 0,0,0.


markcw(Posted 2015) [#94]
I've tried attaching it at 10,0,10 and it still thinks it's at 0,0,0.


angros47(Posted 2015) [#95]
Try attaching at 1,1,1


markcw(Posted 2015) [#96]
Still at 0,0,0. Do you mean to "attach" cone at 1,1,1 (being x,y,z) or cube or both (cube is a child of cone).


Brucey(Posted 2015) [#97]
Do you have some example code of it working as you expect, angros? (in whichever end-language you are using - doesn't need to be Blitzy, as the important APIs are the same).

"Try this" and "try that" answers generally take an order of magnitude longer to solve :-)


markcw(Posted 2015) [#98]
Here is my tranlation of the octree example posted by Angros on Freebasic's forum. It's got a few extra bits but is still the same code.



markcw(Posted 2015) [#99]
Just updated the wrapper. It has method versions of all functions. The examples alphamap and sl_usematrix are borked for some reason (but sl_alphamap works). Apart from that it's a big improvement.

Next to wrap the data members/fields, everything will be a pointer except lists where you'll have to call obj.CopyList(list) before iterating through it.


markcw(Posted 2015) [#100]
New update which adds some docs for stencil functions and fixes the issue with sl_usematrix (Angros had changed the usematrix function).

The alphamap example I see is not actually released as I think you need an image with an alpha channel for it to work, and then set flag 2 or 4 for LoadTexture.


Chapman7(Posted 2015) [#101]
Keep up the good work guys!


markcw(Posted 2015) [#102]
Thanks for the encouragement Chapman7! It is appreciated.

Angros, I hope I didn't offend you by my comments on octrees. I don't want to annoy you since you're doing really a top job with Openb3d and not getting paid for it. So truly sorry if that was the case... I was wondering if you can tell us what's the story about the commands not yet implemented: AntiAlias, EntityAutoFade, PaintEntity and TextureFilter. Are they to be added in the next version?

Progress report: I am currently having fun wrapping all the internal functions/methods and am making good progress wrapping the variables. I have decided to wrap all fields with perhaps the exception of object arrays since they require too much work compared to simply returning the value in a function. So I think I'll do that instead for them.

Also TVector is not used directly anywhere, so rather than wrap the Vector class with all it's complex operator syntax, I will just use minib3d code. I'm not entirely sure what to do about TQuaternion, all it needs is a slight modification to TMatrix stuff to work. Looking at the newton demo it appears I should perhaps use minib3d code for it. All this should take me a few weeks at least, depending on how much real life gets in the way.


angros47(Posted 2015) [#103]
I am not offended at all. Your comments are constructive, so they are appreciated.

AntiAlias has been removed, because it was too slow: it rendered the same scene many times, and use the accum buffer (preventing it to be used for other things); also, antialias can be set with apposite flags when configuring openGL context, so a command in OpenB3D was unnecessary.

EntityAutoFade added a lot of checks for every entity... even if it was seldom used; the only use for it is to configure a sort of hand made LOD .... but terrains and octrees are better solution, in my opinion

PaintEntity... well, in the first version the only entities that could be painted were meshes (there were not yet terrains, and other texturable objects), so PaintEntity was just an duplicate of PaintMesh; I forgot to re-enable it (but the code, inside the class, is available)

TextureFilter needs to be enabled, yet...

The quaternion file was used in the original minib3d, only inside bone movements (bones required quaternions, otherwise all animations would have been wrong). When I used warner's code to add quaternions to everything, it became possible to use it inside animations, too (in fact, warner wrote also a new engine that works in that way)... but I left the original code (at least, I was sure it worked). Messing with TMatrix stuff could introduce bugs everywhere, and would have not introduced any real improvements... my rule is "if it already works, don't change it".


markcw(Posted 2015) [#104]
Thanks angros. Good to know you are cool about that...

Antialias is to remove "jaggies" (technical term - actually the real technical term is called multisampling) but I have never really noticed this myself. Some people have said it is particularly noticable on certain gfx cards, not sure which. Not sure how I would set this up via the context though.

I never used EntityAutoFade but it sounds quite good, fade out and then when nearly invisible hide it. I was thinking about how to optimize a LOD effect and decided you would need a system of blocks which held x (say 100) objects which would then only get checked if the camera was in range.

PaintEntity seems unnecessary given PaintMesh, so really no need for it. I have found that many XEntity commands are not needed with XMesh being more appropriate. Scaling for example. The entity system is nice though.

I have decided to use TVector, TQuaternion and TMatrix from minib3d but also to add TMatrix_ for openb3d since minib3d objects use TMatrix and it is necessary to provide that data. At the same time it is useful to have a minib3d Matrix for Bmx code so there is an overlap in this case.

I do agree with the philosophy "if it is not broke don't fix it" but I find that to provide a wrapper that can handle serious projects such as a physics wrapper, the access to all data is very important. So I am covering all variables and functions/methods to make it fully-functional.

Also, I note since my previous post that I *can* access object arrays using an extra parameter called index which simplifies access.

Again, thanks Angelo for your great work. :)


angros47(Posted 2015) [#105]
Antialias can also be achieved by using the ARB_multisample extension of OpenGl (the advantage is that, on slow system, it is just not used, so no slow down is experienced)

The system of blocks you are describing is complicate to do with EntityAutoFade... but could be done with an OcTree.

Scaling an entity, and scaling a mesh, are two different things (scaling a mesh does not scale its children, not even bones, so for an animated mesh it's a disaster)


angros47(Posted 2015) [#106]
Here are PaintEntity and TextureFilter: just fix them in functions.cpp

void TextureFilter(char* match_text,int flags){
	Texture::AddTextureFilter(match_text,flags);
}

void PaintEntity(Entity* ent,Brush* brush){
	ent->PaintEntity(*brush);
}



Cocopino(Posted 2015) [#107]
Hi,
are there any prerequisites to the module? After building all the modules in angros.mod I tried to run a simple program:

Import angros.b3dglgraphics

Notify "Hello World"

Graphics3D 800, 600
While Not KeyHit(KEY_ESCAPE)
Wend


It compiles and creates an executable without any errors or warnings but no window is being built. Furthermore, the notify never occurs so I assume the compiler will just get "stuck" somewhere in the b3dglgraphics module.

Same happens with every example in the openb3d.mod/examples folder. Am I missing something/some files?

Thanks!


markcw(Posted 2015) [#108]
Openb3d only uses official modules from brl or pub.

It's fine here so I think your problem is you don't have MinGW installed (or installed properly) and so can't compile any modules. Openb3d doesn't provide the library files, only source code.

Follow Brucey's MinGW guide HERE rather than the old, confusing one by ziggy.

The main issue in Windows is you need to run a batch file (with extension .bat) so the files in lib and bin are the same version as the installed MinGW ones (to run the batch just type the filename from command prompt).


Cocopino(Posted 2015) [#109]
Ah, that was it, thanks a lot!

I browsed through all the examples, good stuff! The only thing not working was the "bones" example, it gave me an E.A.V. on LoadAnimMesh() and pointed me to TMesh.bmx, line 137.
The zombie.b3d file is in the correct folder, because when removing it from the media folder I got a different error (Cannot find resource).

Also replacing it by other b3d files (that are working in minib3d) yields the same error.


Edit: hmmm... after further inspection it looks like it has something to do with the textures, not so much with the loading of the model itself. After removing the texture and then re-saving the model, the model will load.


markcw(Posted 2015) [#110]
Must be something todo with the loading textures from subfolders fix. Openb3d doesn't do that so all textures have to be in the root folder. I wrote a fix but it seems something is wrong there, not sure what, but it should be a fail in the filepath code.

Edit: just to add I can't reproduce this which is why I'm not sure what's gone wrong.


markcw(Posted 2015) [#111]
Hi Cocopino, if you could edit texture.cpp to see what you're getting from StripFile that would be great.

Just add the debug line here:
string Texture::NewFilePath(string filepath, string filename){
	string fpath=StripFile(filepath);	
	string fname=Strip(filename);
	ifstream ifs;

	cout << "Debug fpath:"+fpath+" fname:"+fname << endl;



Cocopino(Posted 2015) [#112]
Hi munch, thanks for the support, much appreciated!

When the model location is media/zombie.b3d relative to my exe:
fpath=media
fname:zombie.png

When the model is in the same folder as the exe:
fpath=zombie.b3d
fname=zombie1.png

So it looks like the first example should be
fpath = media/zombie.b3d

?


markcw(Posted 2015) [#113]
Hi Cocopino, thanks for testing.

I'm wondering why it's zombie.png and then zombie1.png when the file I have is Zombie.jpg. Did you edit zombie.b3d? Do you have zombie.png or zombie1.png files?

For subfolders fpath is correct (since it's just path not filename). For same folder fpath shouldn't be anything so that is a bug I need to fix - the code just assumes there is a \ or / somewhere.

Also, textures must be in the same folder as the model.


Cocopino(Posted 2015) [#114]
Arghhh... sorry about that, typo!

Both of the examples (same and higher level folder) crash btw. I will test some more tomorrow (try some other models, change textures, move to other folders et cetera).


Cocopino(Posted 2015) [#115]
Hi munch,
tried several models, folders and textures but unless I uncheck "textures" in UUnwrap during my b3d export, the program crashes.

It has to do something with the ifstream code in NewFilePath I think, because the "can't find resource file" error will never trigger, and immediately returning a hard path to an existing image did work correctly.

I've now "fixed" it by rewriting NewFilePath to simply:
string Texture::NewFilePath(string filepath, string filename){

	return StripFile(filepath) + "/" + filename;
}


but this will probably not work on pre Windows7 machines.
Also, now the model must be in a subfolder :)


markcw(Posted 2015) [#116]
Brilliant! Thanks for the fix Cocopino, it didn't occur to me it could be ifstream. I will rip that out and try using file.cpp functions instead.

NewFilePath is to just check the file is there and the path is ok. I have fixed StripFile so it works with models in the exe folder.


Cocopino(Posted 2015) [#117]
Thanks!

What I did not know beforehand but found out during testing this new solution is that the model will now always load, albeit untextured if the texture file does not exist. I like that better to be honest than crashing the game with an EAV :)

This renderer/engine is looking mighty fine... I will test some more and am probably going to use this for my next game. Another thanks for all the hard work you've undoubtedly already put in!


markcw(Posted 2015) [#118]
I've just updated the repo with the data/methods update I have been working on for the last few weeks. Also included is a simple example for toon/cel shading and the fix for the NewFilePath bug.

Cocopino, I removed the ifstream stuff and while testing in Win I noticed there was something wrong with StripFile. I think I've fixed it but if you could confirm it works that would be great. I actually got the EAV you were talking about but then it disappeared so I'm not sure if it was ifstream or not now but better to use file.cpp functions anyway.

The toon example has 2 shaders one has the black outline and the other is vertex lit. I may update it later but it's not bad for now.

The data/methods update wraps almost all internal methods but not for new types like TFluid. The fields/data members are all pointers except for lists. There is a global function CopyList(list) or if the list is a Field you use obj.CopyList(list). You have to add CopyList before any EachIn loops. It is easy to convert Minib3d code to Openb3d now because the Fields are pointers and the compiler tells you where (then just add [0] after the var) - except if it's an array passed to a function as parameter in which case you don't have to change it anyway.

I converted the minib3d-Newton demo but there seems to be a bug where the boxes disappear when the camera is below -15m. Wierd.

I plan on adding at least Terrain and Shadow internals too.


angros47(Posted 2015) [#119]
About NewFilePath, I remind you that under Windows you need to use "\", under unix-based OSes (Linux and OSX) you need to use "/"; also, in a file path there could be more than one "\" or "/", like:

textures\building\roof.png


By using the solution by Cocopino, it would become:

textures\building/roof.png


and it would not work.

Meanwhile, I just built a particle emitter that can emit any kind of entity: it can emit sprites (if they are rendered as particles, in mode 3, they can also leave trails), but also other entities, like metaballs... or even other emitters (an "emitter of emitters" can be useful to produce fireworks effects). It will be in the new version.

I am also wondering... maybe, if I include a constraints system, libraries like Newton would become unnecessary... what do you think?


Cocopino(Posted 2015) [#120]
I tested the bones example again and tried to break it, e.g. use paths like "media\levelup/zombie.b3d" but it seems pretty sturdy, at least on Windows 7.

Toon shader is looking nice, am very interested in the particle emitter.
Good job both of you :)


feeble1(Posted 2015) [#121]
I would love to see that marching cubes code directed at a voxel terrain. I have been working at it, but have failed repeatedly.


angros47(Posted 2015) [#122]
You can create a voxel terrain with marching cubes: just store your terrain data in a 3d array, create a fluid object (that will be rendered using marching cubes), and use the command FluidArray to pass the pointer of your array and its dimensions to the fluid object: the fluid will render the array, interpolating automatically the values of the array to produce a smooth surface.

There is no command equivalent to LoadTerrain, because there are no terrain files to load (I never find an editor to create it, either); for classic terrains the concept of using an heightmap image is almost a standard, but there is no standard for marching cube terrains.


feeble1(Posted 2015) [#123]
I have a 3d array created by a simple diamond square, but have not been able to figure out how to extract iso surfaces the right way.


angros47(Posted 2015) [#124]
Create a fluid:

Fluid=CreateFluid()


Then, pass the array to it using FluidArray: you need to provide the fluid handle, the array pointer, and the dimensions of the array (this might be a bit tricky: some languages start an array index from 0, so they have one more element, also the order of dimensions might be different): try swapping the three values, and increasing/decreasing them by 1


feeble1(Posted 2015) [#125]
Would I create an array of blobs to pass to the FluidArray? Is there some way that I could use a basic cube for testing purposes. I think this is likely beyond my understanding (at this time).

I have been messing about with it for a few hours now.


angros47(Posted 2015) [#126]
Not an array of blobs, just an array of raw float values (single precision)


Hezkore(Posted 2015) [#127]
Do you think it would be hard to implement a bloom shader and a gray scale shader with varying intensity?
An example with that would be fantastic!


markcw(Posted 2015) [#128]
I agree about NewFilePath. Unix doesn't accept \ but I read that Windows has accepted either \ or / (in C) since early DOS days. I noticed that I made a mistake in NewFilePath (windows was using /) and have now added preprocessors to determine the platform.

Hezkore, there is a version of minib3d 0.40 around somewhere which has postfx shader code for bloom and blur along with terrains and physics and others. I'm not sure who made it but I plan on looking at that soon.


angros47(Posted 2015) [#129]
Are you talking about BlaBZ version?

http://www.blitzbasic.com/Community/posts.php?topic=102524

I guess you could try to use the same shaders on OpenB3D: just use CameraToTex to render the scene to a texture, and use the texture on a quad mesh that has the shader enabled; I haven't tried yet, but in theory it should work.


Cocopino(Posted 2015) [#130]
Are there any emitter/particle examples for me to look at?
Thanks!


Hezkore(Posted 2015) [#131]
I have never used shaders, so I think that might be a bit too advanced for me at the moment hehe.


angros47(Posted 2015) [#132]
@Cocopino
Since the emitter is a feature of the upcoming version of OpenB3D I am currently working on, there are no examples yet

@Hezkore
Shaders are an advanced features, and have their own programming languace (a dialect of C; you cannot code a shadere in BlitzMax, Basic, Pascal, C++ or any other language, only C). I included them because too many people wanted them, and because they allow some special effects, like fur-like surfaces (some other effects, like toon shading, or bumpmapping, can be achieved with fixed function, too, so shaders are not really indispensable); also, somebody says that in the future shaders will be the only way to render a surface (for now, that's true only in GLES2.0), so it's better being prepared.


Hezkore(Posted 2015) [#133]
Mmm yes, I know the basics but I haven't actually worked with them.
It would be awesome if you could include some more examples covering shaders.
The ones I want the most are bloom and grayscale shaders.
Other than that, some sort of simple motion blur would be fun to play around with.


Cocopino(Posted 2015) [#134]
I never coded shaders myself but all three of those sound like you want to apply them to the entire screen. So you probably first need to render the camera to a texture, and then apply the shader to an object having that texture. There's a render to texture example in the examples folder that does that.

Grayscale sounds like it should be pretty easy to write, it's probably something like setting all 3 colors to (red+green+blue)/3 or something similar.


angros47(Posted 2015) [#135]
@Hezkore

You don't need shaders to achieve motion blur; just using the accumulation buffer will do the trick. You need to set the flag to enable it when you set graphic mode, then, after each RenderWorld call, just add these three lines:

	glAccum(GL_ACCUM, 0.03)
	glAccum(GL_RETURN, 1.0)
	glAccum(GL_LOAD, 0.97)


It's well explained here:
http://www.gadgetweb.de/programming/accumulator-in-opengl.html


Cocopino(Posted 2015) [#136]
Hezkore, you might be in luck. I wanted to test what I wrote earlier while learning something new in the process so I wrote my first shader ever :)
It wasn't much to look at, so I added a little extra: when a red pixel meets a certain threshold, it won't be greyed out, for something like a "Sin City" effect. If you don't like that simply remove the "if (gl_FragColor.r>0.85)" line.

// greyscale.vert
varying vec2 texCoord0;

void main() {
	gl_Position = ftransform();
	texCoord0=gl_MultiTexCoord0.xy;
}


// greyscale.frag 
// with red threshold
uniform sampler2D texture0;

varying vec2 texCoord0;

void main() {

	gl_FragColor = texture2D(texture0,texCoord0);
	float avg = (gl_FragColor.r + gl_FragColor.g + gl_FragColor.b) / 3.0;

	float red = avg;
	float green = avg;
	float blue = avg;

	if (gl_FragColor.r>0.85) { red = gl_FragColor.r; green = 0.1; blue = 0.1; }
	
	gl_FragColor=vec4(red,green,blue,1.0);
}



Hezkore(Posted 2015) [#137]
Thanks everyone!
But how would I go about applying both bloom AND greyscale to the screen?
And is there any way I could adjust the greyscale intensity from ingame?
I only want about 50% greyscale, and sometimes less depending on the level.


Cocopino(Posted 2015) [#138]
I don't know if you can communicate directly with the shader from your game, but you could setup a shader named "postfilter". Then you do something like:

bloom.frag
#define BLOOM
include "postfilter.frag"


bloom-greyscale.frag
#define BLOOM
#define GREYSCALE
include "postfilter.frag"


postfilter.frag
#ifdef BLOOM
//bloom shader code
#endif

#ifdef GREYSCALE
//greyscale shader code
#endif



Hezkore(Posted 2015) [#139]
Ah okay... That makes sense.
Still, I have no idea how to get this ingame, or make a bloom shader hehe.
Thanks anyways. :)


Cocopino(Posted 2015) [#140]
"Still, I have no idea how to get this ingame"

I just tested my greyscale shader with the tex_render example from the examples folder. If you save these to the corresponding filenames in the shaders folder and then add:

Local shader:TShader = LoadShader("", "shaders/greyscale.vert", "shaders/greyscale.frag")
ShaderTexture(shader, texture, "tex", 0)
ShadeEntity(cube,shader)


just before the main game loop everything works as I would expect.

"or make a bloom shader hehe."

Well, a bloom shader is much more advanced than greyscale, at least if you want it to look good while not affect performance too much. However, it can and has been done before, so at least you know your game won't be stopped by that hurdle.


Hezkore(Posted 2015) [#141]
The engine posted above DOES come with a bloom shader, I don't know how to implement it, but it's there if you know how hehe.
Thanks for the code btw! I'll give it a go once I'm by the computer.


Cocopino(Posted 2015) [#142]
Which engine do you mean?
Can you point me to a download?


Hezkore(Posted 2015) [#143]
http://www.blitzbasic.com/Community/posts.php?topic=102524

Here's a direct link to the download:
http://infotread.com/downloads/blabz.mod.zip


Cocopino(Posted 2015) [#144]
I found a bloom.vert/bloom.frag but it does not produce the effect I would expect.
It looks more like blue static. So if it works correctly in that engine, it might use shaders differently.


Hezkore(Posted 2015) [#145]
Mmm well I have no idea mate.
I haven't used that engine.
But surely there must be hundreds of bloom shaders out there for free?


Hezkore(Posted 2015) [#146]
I'm trying to use OpenB3D combined with beanage's FBO module, but I'm getting some weird results...
After binding an FBO, all depth testing seems to be gone.
Entities are sorted by the order they were created in, not but depth.

The green cone is closer to the camera, but is still rendered below the red cone.

It's very likely that the issue is in beanage's module and not OpenB3D, but I'm still wondering if there's a way to fix this.
Infact I'm pretty sure it's the FBO module and not OpenB3D, as the problem seems to be somewhere in the bind() function.

I've created a little example of the problem, it also includes the FBO module.
The example can be found here.

Is there perhaps some simple gl function I can call to enable depth testing?
Or can we perhaps figure out a way to fix beanage's module?


angros47(Posted 2015) [#147]
At the moment I am using a phone, so I can't test, but in a FBO you need to set and enable a depth buffer if you want to use it (have a look at CameraToTex function); beanage module looks like something made for 2d graphics, so maybe depth buffer is not enabled (in 2d it would be seldom used); you'd have to add some instructions to the module.


Hezkore(Posted 2015) [#148]
Ah okay!
Any chance you could help me out with the code when you're by the computer?
I have no idea how to enable a depth buffer...
I'm trying to do my own fake bloom using it hehe.


angros47(Posted 2015) [#149]
You need to create a RenderBuffer (add a line after "glGenFramebuffersEXT 1, VarPtr _id", with something like "glGenRenderbuffersEXT(1 , VarPtr _id_rb") , otherwise there is no place to store depth buffer (in a texture there is no depth buffer, so no memory is allocated for it by default); then you need to use the renderbuffer to store depth data: after the line "glBindFramebufferEXT GL_FRAMEBUFFER_EXT, _id", you should add something like:

glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, VarPtr _id_rb);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , VarPtr _id_rb)


Maybe beanage has been made with 2d in mind, so the author didn't care about depth buffer at all.

P.S. Remember that I haven't BlitzMax, so I can't test these changes.


Hezkore(Posted 2015) [#150]
Yay, I managed to get it working.
Thanks a lot angros!

I also managed to get the greyscale shader in there with a varying intensity.
If you use SetFloat you can change a value in the shader.
So thank you Cocopino for that.


FBEpyon(Posted 2015) [#151]
Hello,

I have been looking at this for a while now, and was waiting for the bugs to be processed out, and seems to be moving along nicely.

I do have a question though if there was going to be any type of physics system added to this for an all in one module, or am I missing something?

Thanks,

FBEpyon


markcw(Posted 2015) [#152]
Hi FBEpyon,

Angros said somewhere that he isn't adding a physics engine since he thinks it's better kept separate - as some people don't want physics and others may want a different engine. I'll be trying to organize a compatible physics engine module for Openb3d when I get the time.

Are you talking about BlaBZ version?

I guess you could try to use the same shaders on OpenB3D: just use CameraToTex to render the scene to a texture, and use the texture on a quad mesh that has the shader enabled; I haven't tried yet, but in theory it should work.


@Angros, no it's an old version of Minib3d Extended - the zip was named Minib3dPFXNewton0.40.tar.gz and it's not available now since klepto2's site is gone. I couldn't get Minib3d Plus running on my pc as the updated opengl module it needs didn't work - I think it's because my opengl version (2.1) was too old.

Also, nice work getting the bloom shader going Hezkore!


angros47(Posted 2015) [#153]
As far as I know, the last version of the extended minib3d made by klepto is 0.41 beta. I downloaded it years ago, and ported some parts of it (the stencil shadow module, and the shader module) to c++. So, shaders in OpenB3D are managed almost in the same way.

About physics: most of the work of a physics engine is collision management (and OpenB3D has its own collision system: using an external one would be more accurate, maybe, but would not work with terrains... and a collision system that does not support terrains would be useless). Other features are constraints, and rigid body simulation. But if we had a way to support constraints in OpenB3D (like a command "CreateConstraint entity1, entity2, distance"), it would be possible to build a "grid" of pivots, and if some of them have collision detection enabled, the structure would act as a rigid body. If we bind a mesh to it (it would have to be bound to four pivots: one to set the position, and three to define rotation axis) that mesh could be used like a rigid body. With this solution, OpenB3D would have a small physic engine integrated, with no need for external libraries.

Could that be a solution?


markcw(Posted 2015) [#154]
I don't have version 0.41 beta, I have the 0.40 version (postfx+newton) which I got from klepto's website and the one still available HERE (0.51 it says) which doesn't have postfx shaders but some kind of postfx manager.

I like the sound of this constraints system idea, I find Newton too complex and would prefer a relatively simple system that is easy to understand and use (not sure if there is such a thing with physics). There is also an ODE module HERE but I haven't looked at it yet and I also bought JV-ODE for BMX which may help. ODE might be a good option as apparently it's fast and fairly simple.


feeble1(Posted 2015) [#155]
It is possible to convert Klepto's Newton from MiniB3dext, but you have to add in all of the vector stuff and mess around with the mesh's matrix.

Why not just try Itmbin's version?
It is way easier to get working with OpenB3D.

http://www.blitzbasic.com/Community/posts.php?topic=99417


angros47(Posted 2015) [#156]
As I've said, I'm not going to use Newton, ODE, TrueAxis, Tokamak or any other external library: I am going to add physics features in OpenB3D itself. No wrapper, and no external files will be needed.

A matrix, in OpenGl, is made by 16 elements, but actually only 12 are used: 3 to set the x, y, z coord, and 9 to set the 3 rotation vectors; so, a matrix could also be built from 4 pivots: the entity will be at the same coordinates of the pivot 0, will point toward the pivot 1 (this will set its pitch and yaw, and the distance from the pivot will be its depth), its top will point toward pivot 2 (so roll will be set, too, and the distance from that pivot will be the height), and its side will face toward pivot 3 (so, even width can be set): with that solution, scale, rotation and position of an entity could depend on a set of "points" that are controlled by a system of constraints similar to the one used in most physics engines: if these constrained points have their collision set, the entity should be able to move and rotate when it bounces on obstacles.

I got the idea from that:
http://www.blitzbasic.com/Community/posts.php?topic=24611
http://www.blitzbasic.com/Community/posts.php?topic=84714

@Munch
I'm going to integrate the DepthBufferToTex in the official version, but with a change: it will have a "camera" option, to be able to render directly on a texture (using frame buffers) instead of using back buffer.


feeble1(Posted 2015) [#157]
I would be fine with no physics system at all. The simple collisions work for my purposes. I just mentioned Itmbin's wrapper as an easy plugin for those who want Newton. :)

The transformation matrices in OpenB3D are already fairly exposed with GetMatElement. Good luck to you, physics get silly.


FBEpyon(Posted 2015) [#158]
Thanks for all the information I was just wondering if there was going to be any physics additions.

They have their own usages for collisions like adding a rigid body collision which works great for collision checks, but can cause other low end machines to suffer.

I wouldn't need any kinetics or anything, but would be nice for so things like adding wind and other slight movements to a game.

Keep up the good work I have been working with this for a few days now, and works wonders..


kiami(Posted 2015) [#159]
compiles but exe exits before showing anything. Any clue?


markcw(Posted 2015) [#160]
My first thought would be, is MinGW installed correctly?


kiami(Posted 2015) [#161]
If by "correctly" you mean no error when recompiling modules, I think it does, because I was able to compile the wrapper. I can see *.i and *.a files in all three directories and I didn't get any error. Also, I deleted old minib3d module files and compiled them again, the fog example there compiled and run. Let me try the whole thing in my laptop. I had problem with Blitz3D few weeks ago, maybe it is my graphic card. This is going to take a while, I got to go out now.


markcw(Posted 2015) [#162]
By correctly I mean using Brucey's guide here: http://www.blitzmax.com/Community/posts.php?topic=95220

You need to have copied the same versions of the installed MinGW files to the BlitzMax bin+lib folders.


angros47(Posted 2015) [#163]
Munch, maybe you'd like to start messing with the upcoming version:

http://sourceforge.net/projects/minib3d/files/version%201.1%20preview.tar.gz/download

So you could help me finding bugs.


Brucey(Posted 2015) [#164]
maybe you'd like to start messing with the upcoming version

angros, if you used a public source control (svn, git, etc), it would be easier to test/keep up-to-date and report bugs.

Example : https://github.com/bmx-ng/sdl.mod


kiami(Posted 2015) [#165]
@munch, Brucey's guide did the job, perfect. Thanks!


markcw(Posted 2015) [#166]
Oh good! Otherwise I would be stumped. ;)

@Angros, ok I'll have a look and see if I can test it out.


feeble1(Posted 2015) [#167]
@munch: Awesome wrapping, but why GetParentEntity instead of GetParent?


markcw(Posted 2015) [#168]
Thanks! I dunno, I got confused there, but that's what angros named it in functions.cpp:
Entity* GetParentEntity(Entity* ent){
	return ent->GetParent();
}

I guess since Minib3d uses GetParent it would be best to simply rename it in functions.bmx.

Edit: done.


feeble1(Posted 2015) [#169]
I was just curious. I thought there was some reason that I was simply not seeing. :)


angros47(Posted 2015) [#170]
About NewFilePath, StripFile and similar stuff; if, under windows, it's possible to use the slash in file path (and looks like most C++ compilers accept it), there is a simple solution: in files "texture.cpp", and "material.cpp", just replace all occurrences of:

filename=Strip(filename);


with:

std::replace(filename.begin(), filename.end(), '\\', '/');


There are two occurrences in texture.cpp, and one in material.cpp

Also, you need to add at the beginning of these files the line:
#include <algorithm>


After that, you can get rid of the "Strip" function. Please test it.


FBEpyon(Posted 2015) [#171]
@munch

Hey I had problems with using Framework for the mod. Your mod doesn't import the JPG Loader only the PNG or I'm missing something. I mean its simple to just to do the import myself I guess, but I figured most of the textures are JPG so I figured I would bring it up.

Thanks,

FBEpyon


markcw(Posted 2015) [#172]
MiniB3D uses official BMX modules like libjpeg to load textures but OpenB3D uses stb_image, so the wrapper doesn't import any image loaders. It was upgraded a while ago by Angros to support tga. Also another issue is it only supports standard jpg compression (not progressive). Look at LoadTexture.bmx example to see all formats supported by stb_image.


markcw(Posted 2015) [#173]
About using replace instead of Strip function in texture/material loaders.

I think there may be a problem this way, when used in model/3ds.cpp the filename is taken from the model and sometimes this is a full path (like for example the Zombie.jpg path in zombie.b3d) which will cause an error. NewFilePath makes sure this doesn't happen by using the filepath known to be correct and adding the result from strip(filename) to make the full path.


angros47(Posted 2015) [#174]
Are you sure? NewFilePath takes path info from filename: if it's wrong, the program cannot know; from your source, I see that your code split a string containing the full path in two strings, one with path, the other with the file name, and then joins them back; so, splitting the string might be unnecessary.

Have you encountered any issue with my solution?


markcw(Posted 2015) [#175]
Yes, I'm sure. I've just tested your solution out with bones.bmx example in Win7 and it won't load the texture for media/zombie.b3d.
The filename in LoadTexture is this "debug: C:/work/mymodels/zombie/Zombie.jpg" so you need to strip that absolute path off and use the filepath/url of the model for the texture to load.


angros47(Posted 2015) [#176]
What happens if you try to load that model with original MiniB3D? And if you try to load it from Blitz3D?

If Blitz3D does not accept it, it means that the fault is in the file, and even if it's actually possible to load it, this should not be encouraged.


markcw(Posted 2015) [#177]
The texture for the model loads in minib3d and in Blitz3d.

Looking at Minib3d there is a function FileFind in TTexture.bmx which seems to cut up the url one directory at a time and check the file exists. I can't see how that solves the problem though.


angros47(Posted 2015) [#178]
I looked at it: it first check if the file exist at the absolute path, otherwise it removes path info (like Strip does) and looks in current directory


markcw(Posted 2015) [#179]
Yes that's what FileAbs in TTexture.bmx does. It must be that CurrentDirectory returns the right folder - that is the same one as the model - rather than the exe folder.


angros47(Posted 2015) [#180]
Actually, the trick is in file TModel.bmx:

Local cd$=CurrentDir$()
...
If dir$<>"" Then ChangeDir(dir$)

.....
(actual loader)

ChangeDir(cd$)
Return TMesh(root_ent)



it changes current directory to mesh directory, then set it back when the mesh is loaded. It's a "dirty" solution, but it seems to work.


angros47(Posted 2015) [#181]
@Munch

After all, I think I will use your solution (it's "cleaner" than the one used in original MiniB3D), but there is no need to add new functions: in "file.cpp" there is the ResourceFilePath function that, at the moment, is useless, so the code that fix the path should go there.

in "file.cpp", you should put something like:

static string filepath_in_use;

string File::ResourceFilePath(string filename){

	std::replace(filename.begin(), filename.end(), '\\', '/');

	File* stream;

	stream=File::ReadFile(filename);

	if (stream!=0) {
		stream->CloseFile();
		return filename;
	}

	string::size_type idx=filename.rfind("/");

	if(idx!=string::npos){
		filename=filename.substr(idx+1);
	}
	if (filepath_in_use.length() != 0) {
		filename=filepath_in_use+"/"+filename;
	}

	stream=File::ReadFile(filename);

	if (stream!=0) {
		stream->CloseFile();
		return filename;
	}

	return "";

}

File* File::ReadResourceFile(string filename){

	std::replace(filename.begin(), filename.end(), '\\', '/');

	string::size_type idx=filename.rfind("/");

	if(idx!=string::npos){
		filepath_in_use=filename.substr(0,idx);
	}

	//string filename2=ResourceFilePath(filename);

	

	if(filename==""){
		cout << "Error: No Filename: " << filename << endl;
	}

	const char* c_filename=filename.c_str();

	FILE* pFile=fopen(c_filename,"rb");

	if(pFile==NULL){
		cout << "Error: Cannot Find Resource File: " << filename << endl;
		return NULL;
	}

	File* file=new File();
	file->pFile=pFile;

	return file;

}



in "texture.cpp", just use

		filename=File::ResourceFilePath(filename);


Basically, when you open a .b3d model the static variable "filepath_in_use" in module file.cpp is updated with the path (by default, it is empty). When you load a texture, OpenB3D should first try the absolute path, and if it does not work it strips it away, and looks in the current dir (if "filepath_in_use" is empty) or in the same dir pointed by filepath_in_use.

Since both windows and linux can accept slash separator, there is no need to keep two version: only slash is used, and if there is any backslashes they are replaced with slashed before starting.


feeble1(Posted 2015) [#182]
Hey munch, my compiler does not like your water shader example. I have traced it back to the cubemap flag in CreateTexture. Without the flag, everything is fine. I am on Windows and wonder if I am the only one experiencing this problem.


markcw(Posted 2015) [#183]
Strange, it's working fine in Win7. Have you tried changing the cubemap size or maybe just using 128 flag "cubetex:TTexture=CreateTexture(256,256,1+2+128)"? Can you run sl_cubemap.bmx example ok?

Angros, thanks for the improved texture loading functions! I have tested them in Linux and it works perfectly, it also reports the bad url which is great. I am now trying to wrap the new stuff in 1.1 and then I'll update my repo. Lots of new functions!


feeble1(Posted 2015) [#184]
Yes, it occurs in both sl_cubemap.bmx and sl_water.bmx.

It seems to be BackBufferToTex in TTexture.bmx. It only occurs when the cubemap flag (128) is used with CreateTexture. Perhaps it is the same thing that Hezkore has experienced.

Don't let this distract you from your current goals. I just wanted to report what I saw.


markcw(Posted 2015) [#185]
Ok, does calling "CameraToTex cubetex,cube_cam" [either in or] before the main loop help? That was Hezkore's fix.


Chapman7(Posted 2015) [#186]
much is your email up to date? I need help with something


feeble1(Posted 2015) [#187]
Adding CameraToTex outside of the main loop does fix the problem. I probably should have read this forum better. It does, however, cut the fps in half.

Thanks munch!


markcw(Posted 2015) [#188]
Hi Chapman, yes that email is still in use I just don't check it much. I'll have a look at it.

Edit: email sent.

Feeble1, glad to hear the CameraToTex fix worked! I'm going to try updating the sl_water.bmx example with stencil reflections for objects instead of cubemap reflections, which should look better.


kiami(Posted 2015) [#189]
munch, do we expect openB3D and the wrapper to behave like B3D? If we do, texturing plane seems not doing so.

This is Blitz3D code converted to BlitzMax. I cannot see the texture over the plane in BlitzMax, but in Blitz3D I do very well.

SuperStrict

Framework angros.b3dglgraphics

Graphics3D 800,600

Local camera:TCamera =CreateCamera()
PositionEntity (camera, 0, 1, 0)

Local light:TLight=CreateLight()
RotateEntity light,90,0,0

Local ground:TMesh=CreatePlane()
Local ground_tex:TTexture=LoadTexture( "ground.jpg" )
EntityTexture ground, ground_tex

While Not KeyDown( KEY_ESCAPE )
	If KeyDown( key_down )=True TurnEntity camera, 0, 0, -.25	
	If KeyDown( key_up )=True TurnEntity camera, 0, 0, .25
	If KeyDown( key_left )=True TurnEntity camera, 0, 1, 0	
	If KeyDown( key_right )=True TurnEntity camera, 0, -1, 0
	RenderWorld
	Flip
Wend
End 



Hezkore(Posted 2015) [#190]
After a clean install of BlitzMax and Mingw v5-1-3, I am no longer able to compile OpenB3D.
C:/Program Files (x86)/BlitzMax/mod/angros.mod/openb3dlib.mod/openb3d/src/3ds.cpp: In function `void load3ds::ReadTriMesh()':
C:/Program Files (x86)/BlitzMax/mod/angros.mod/openb3dlib.mod/openb3d/src/3ds.cpp: In function `Mesh* load3ds::Load3ds(std::string, Entity*)':
C:/Program Files (x86)/BlitzMax/mod/angros.mod/openb3dlib.mod/openb3d/src/3ds.cpp:384: error: no match for 'operator!=' in 'it != std::list<_Tp, _Alloc>::rend() [with _Tp = int, _Alloc = std::allocator<int>]()'
Build Error: failed to compile C:/Program Files (x86)/BlitzMax/mod/angros.mod/openb3dlib.mod/openb3d/src/3ds.cpp

If I comment out the "3ds.cpp" loader in "source.bmx" I get a similar error about about "x.cpp"

If I comment out "x.cpp" it will compile, but trying to run any of the examples gives me errors about the missing functions
C:/Program Files (x86)/BlitzMax/mod/angros.mod/openb3dlib.mod/openb3dlib.release.win32.x86.a(mesh.cpp.release.win32.x86.o):mesh.cpp:(.text+0x894): undefined reference to `load3ds::Load3ds(std::string, Entity*)'
C:/Program Files (x86)/BlitzMax/mod/angros.mod/openb3dlib.mod/openb3dlib.release.win32.x86.a(mesh.cpp.release.win32.x86.o):mesh.cpp:(.text+0x3ed6): undefined reference to `loadX::LoadX(std::string, Entity*)'


Any idea what's going on?

UPDATE: I managed to get it working with Brucey's MinGW installed ( http://www.blitzmax.com/Community/posts.php?topic=95220 )
But I'm now forced to include a bunch of libstdc++-6.dll files with game... I don't like that.


3DRCzy(Posted 2015) [#191]
^ I got the same issue aswell.


kiami(Posted 2015) [#192]
Hezkore and 3DRCzy,

I had your problem, after following the guide by Brucy, everything began to work. Latest version of BlitzMax is OK.


3DRCzy(Posted 2015) [#193]
Ah yes, thank you so much. This worked. :D


Hezkore(Posted 2015) [#194]
@kiami Yeah I've already done that (see end of my post).
But I said, I don't want to include any extra DLL files.


markcw(Posted 2015) [#195]
kiami, yes Openb3d is meant to behave as much like B3d as possible but sometimes doesn't. So yes, CreatePlane is not working right.

Hezkore, you should be able to delete those "dll.a" files in the BMX/lib folder and rebuild all modules, see HERE. I only have .o and .a files in my lib folder. If that still doesn't work then you may have to try a clean install of BMX 1.50.

I have just updated sl_alphamap.bmx and added alphamap.bmx if you want to look at those Chapman7 [since you may prefer to use the built-in way]. It seems texture blending with alpha maps doesn't work in Openb3d or Minib3d (or at least I couldn't get it working) so you have to use the shader alphamap2.frag.glsl used in sl_alphamap.bmx.


Hezkore(Posted 2015) [#196]
Thanks munch, that seems to have been the issue!

But I've got some trouble getting the stencil shadows working correctly.
I'm using static shadows and moving the light around in an attempt to try and get the shadows looking the same for every object.
But only a few of the objects actually gets shadows, the rest seems to be placed far underneath the world? (see picture)
It seems to be random which objects gets shadows and which don't, cause if I rebuild the shadows, the ones that didn't have shadows before might get it this time and some that had shadow might disappear this time.
And the shadows seem to be relative to the camera somehow too, cause if I rebuild after moving the camera, the shadows will look different.
Even though the sun/light is always placed above the object when the shadow is created.
However, if the shadows aren't static, I get shadows on every object, but still weird shadows far below the world (and a much lower FPS).




angros47(Posted 2015) [#197]
About the "random" static shadow, you might have exposed a bug: in file "shadow.cpp", function "ShadowObject* ShadowObject::Create(Mesh* Parent, char Static)", locate the line:

		S->ShadowVolume = S->ShadowMesh->CreateSurface();
		S->Parent = Parent;
		S->Static = Static;


and add, after them, the line:

		S->VCreated=0;


Theory: static shadow are calculated only once; the variable VCreated is used to tell that they have already been calculated; but I forgot to initialize it (in C++, a variable is not set to 0 by default, it might have any value, depending on how the allocated memory has been used before); hence the random result.
Please tell me if that fixes the bug, so I will include it in the official release.


markcw(Posted 2015) [#198]
Glad you got it working Hezkore! Did you just delete the ".dll.a" files in lib?

The main problem with stencil shadows in Openb3d is that there is a bug with static shadows (when flag is True) so you must always have that parameter in CreateShadow set to False. That will remove the wrong-placed or "detached" shadows.

Another issue is you can't use ScaleEntity commands on the casters, only ScaleMesh or FitMesh will work, otherwise you get one (or maybe a few) of these "detached" shadows.


Hezkore(Posted 2015) [#199]
Yep, just deleted those files and it seems to have fixed the issue.

I'm not scaling the entities or anything like that.
Just merging small meshes to a world mesh and doing CreateShadow right before the actual merge.

I guess I'll use "live" shadows instead of static ones for now.
But it pretty heavy and I'd love to see a fix for it.

Another question...
Is it possible to have multiple lights in different colours with the bumpmap shader somehow?
I've created several lights (4) all in different colours, but only one colour seems to be actually used.
Or even better would be parallax mapping with multiple lights in different colours.


angros47(Posted 2015) [#200]
@munch

Have you tried if my patch fixes the bug?


markcw(Posted 2015) [#201]
Hi angros, yes quickly. It didn't work. I remember I tried that trick myself before but it didn't work then so I gave up since I thought no-one really wants static stencil shadows [and I didn't know how to] anyway, but it seems they are wanted. I have been trying to improve the stencil_shadow.bmx example to make the dynamic shadows move but haven't quite figured that out yet.

Thanks Hezkore, good to know.

About bumpmaps, bumpmaps 2 and 3 support multiple lights and they should also support different colors. The first bumpmap only supports one but I'd like to fix that.


Hezkore(Posted 2015) [#202]
I've been experimenting with bumpmap2 all day, I just can't get multiple lights working with it.


angros47(Posted 2015) [#203]
Could you post me a code sample that exposes the static shadow bug?


markcw(Posted 2015) [#204]
Well the example stencil_shadows.bmx can show it.

Just edit line 23 to be "Local static%=1" then press the down arrow key and the detached shadows will come into view.


markcw(Posted 2015) [#205]
Hezkore, you must not have changed the number of lights constant in the shader "#define NUM_LIGHTS 1". I have updated sl_bumpmap.bmx to use 2 lights for bumpmaps 2 and 3. The maximum number is 8 but it is possible to have more if using shaders for lights (not that I plan to do this).

I also updated stencil_shadows.bmx to show dynamic shadows with a moving light and rotating shadow casters. The shadow routine uses global positions not rotations from the light, so for the directional light I positioned it and then pointed it at 0,0,0 which seems to work ok.


Hezkore(Posted 2015) [#206]
Oh I didn't know I had to specify that.
It worked the second I changed it.
Thanks munch!

I have however discovered that if you do
BeginMax2D()
EndMax2D()
right before Flip(), the bumpmap shader no longer works.
Especially not bumpmap2.


angros47(Posted 2015) [#207]
@munch

I tested your stencil shadow example. There is a simple work around to get static shadows work: before the line

Local wiretoggle%=-1,lightmove%=1,cylindermove%=1


add these lines:

PositionEntity light,EntityX(sphere,1),EntityY(sphere,1),EntityZ(sphere,1)
cameraclscolor camera,0,0,255
camerarange camera,1,300
renderworld
camerarange camera,1,1000


The algorithm used (z-fail stencil shadow) requires capped shadow volumes; the detached shadows occurs when the shadow volume mesh (that is automatically generated by OpenB3D) for some reason is not capped correctly. In your examples, one end of the shadow volume is so far that fall outside of camera range, so it's not rendered and hence the bug. OpenB3D usually reduces the length of the shadow volume to ensure that it does not fall outside the range (the variable VolumeLength in shadow.cpp is used for that: as you can see, it takes in account the camera distance); but this means rebuilding all the shadow volume every time camera is moved (in other words, it means having dynamic shadows). And using a smaller shadow volume by default would introduce another program: long shadows (like the ones you could see in the evening, when sun is low) would be "cut" abruptly.

The work around I proposed here is simple: the first time shadows have to be rendered (static shadows are calculated in that occasion, and never again), camera range is decreased, so shadow volumes are made shorter; after that, camera range id set again to the default. Anyway, that bug should only occur if the camera goes farther from the scene, not when it get closer: so, if you place the camera in the furthest place (i.e., on the border of the scene) and then move it closer to the subject, you'd have no issues


Hezkore(Posted 2015) [#208]
Feature request!
I want to disable shadow casting for a light.
Light.CastShadow(False)

I'd also like to be able to temporarily disable/hide a shadow.
Shadow.Hide()/Disable()
Shadow.Show()/Enable()


markcw(Posted 2015) [#209]
That's great! it works a charm, thanks Angros.

A few issues still though, I see shadows don't really work with multiple lights, once I add a second light the shadow casters should render two shadows in different places but they only render one (actually two from the first light source).

Also, I am wondering would it be possible to reset static shadows so that they can be re-rendered when needed? I find this one-render feature too limiting.


angros47(Posted 2015) [#210]
@Hezkore
To disable a shadow, you can use FreeShadow; you can create it again if you need it. A "HideShadow" command would not be much faster, because a dynamic shadow is rebuilt at each frame, so destroying it and rebuilding it from scratch would make not much difference.

About disabling shadow casting on a light, I just noticed a bug: HideEntity doesn't work for lights (the same bug affects iMiniB3D, don't know why). What do you need, exactly?

@Munch
To reset a static shadow you need to set its VCreated parameter to zero. The issue you described with multiple light sources occurs only in static shadows, or does it happens with dynamic shadows, too?


angros47(Posted 2015) [#211]
@Munch
Add this to functions.cpp

void ResetShadow(ShadowObject* shad){
	shad->VCreated=0;
}



Hezkore(Posted 2015) [#212]
I have 3 lights.

First light is what I call the sun, its purpose is to cast shadows on my shadow enabled entities.
It's far away and doesn't produce any real light, it's only there for the shadows.

The second light follows the player around, it lights up the area around the player.
I don't want this light to actually cast any shadows.

Third light is used when the player fires a bullet and is only seen for a very short time.
I'm not sure if I want this light to cast shadows too.

With the current version of the engine, I have 3 shadows from every entity since I can't disable shadow casting on lights.

Basically I just want to have a light that doesn't cast any shadows.


angros47(Posted 2015) [#213]
In the file "shadow.cpp", locate the lines:

	for(it=Light::light_list.begin();it!=Light::light_list.end();++it){
		Light* Light=*it;


and add the line
		if (Light->hide==true || Light->cast_shadow==false) continue;


You also need to add a property "char cast_shadow;" (or "int cast_shadow;") in the file light.h. By changing this property, the light will cast shadow or not.


angros47(Posted 2015) [#214]
Also, in Light::CreateLight (in file "light.cpp"), replace the line:

light->light_type=l_type;


with this code:
	if (l_type>0){
		light->light_type=l_type;
	}else{
		light->light_type=-l_type;
		light->cast_shadow=0;			//if type is negative, light won't cast shadows
	}


In this way, no new command will be required: to create a light that does not cast shadows, just use a negative light type parameter.


markcw(Posted 2015) [#215]
ResetShadow works great, thanks!

Multiple lights work fine with dynamic shadows but not with static shadows, even after using ResetShadow.

Nice solution for non-casting lights! Perhaps a new function called DisableLightShadows(light).


angros47(Posted 2015) [#216]
If you want a new function... in my opinion, there is no need to pollute the namespace if it can be avoided (even for dynamic collisions, instead of adding a "setDynamicType" command I preferred using EntityType with a negative value)

About multiple lights and shadows: to render two (or more) shadows, actually there is only one shadow volume, that is modified and rendered many times (once per light); a static shadow has a volume that cannot be modified, so it is rendered twice, but with no changes, so it refers always to the same light.

A simple fix could be to create two static shadows on the same entity: you create the first shadow, then enable one light, and perform a RenderWorld: shadow is built; then, you move the light (or hide it, and enable the other... with the new patch it should now work), and create a second static shadow on the same entity, then perform another RenderWorld. It should work


markcw(Posted 2015) [#217]
Ok yes, these commands can be added as ShadowObject methods and wrapping the data members without needing to add new functions.

I haven't tried the static shadow multiple lights fix yet but thanks for the help.

I've fixed the CreatePlane issue not texturing, also the divs parameter not functioning. It's called CreatePlane2 and it's adapted from my CreateFlatGrid function, it allows you to set divs to more than 16. There's also a CreatePlane3 function which is just to show how to texture the CreatePlane function in mesh.cpp but this doesn't have divs.




Hezkore(Posted 2015) [#218]
Thanks everyone for helping me out :)

Munch, could you have a look at the bumpmap bug I mentioned a few posts back.
The one about BeginMax2D messing it up.
It's really getting in the way of progress.


markcw(Posted 2015) [#219]
Hezkore, I was able to fix bumpmap 1 but not bumpmap 2 although I tried. I also made bumpmap 1 to use multiple lights. They're all about the same speed, a bit slow on my machine but bumpmap 1 looks bumpier than bumpmap 3.

Something happens with the states that disables bumpmaps with Max2d but I'm not sure what exactly. I did find that GL light and material values change but not sure if this is the problem. My fix was to simply edit the shader.

I also noticed that the alpha map examples didn't work with Max2d, so I fixed it by setting TGlobal.blend_mode[0]=1 in EndMax2d.

I have updated the wrapper to the 1.1 preview version, if anyone wants to mess with the new functions. Everything else seems to be working.

Next I'm going to wrap ShadowObject with the new fixes by Angros in this thread.


Hezkore(Posted 2015) [#220]
Ah thank you.
Shame about bumpmap 2 not working, it was neat playing around with EntityShininess and making surfaces look wet in the rain.


markcw(Posted 2015) [#221]
I decided to have another go at bumpmap 2 as I couldn't sleep. Actually, I had the idea of what was wrong while lying in bed. Turns out that was what was wrong!

So the problem is the GL light properties are not restored after EndMax2d and in the case of bumpmap 2 there are 3 values critical to it working properly. My fix uses glLightfv before RenderWorld to reset these values. Hopefully my hard-coded values will work everywhere, but if not then you can use glGetLightfv after a RenderWorld to get the initial values.

Also, it seems shader attributes get altered as well, so I just changed these to uniforms. These were for tangent values. That was the only thing wrong with bumpmap 1.

I also edited the sl_water example again and added my CreatePlane fix to TMesh.


Hezkore(Posted 2015) [#222]
Well done! But the shine... specular?... Isn't the same as it was before on bumpmap 2.
The old version looked much better.



Or am I doing something wrong here?

UPDATE: "tangent" was changed to a vec3 instead of a vec4, so I was passing the wrong data.
I'm not sure it looks quite the same though...
No, it seems specular is limited to the first light only after Max2D is enabled, and it does reflect a bit differently than last version.

Before and after BeginMax2D (no specular on red light)




Hey I was wondering about the speed of BufferToTex.
Is there any faster way to get the entire screen to a texture than BufferToTex?

And the whole DisableLightShadows(light) thing isn't in yet, is it?
Also, is there some way to change how visible/transparent the stencil shadows are?


markcw(Posted 2015) [#223]
Thanks for the screenies.

I decided the best thing to do is get all the glLight parameters, since we can't know what will be changed and how this will affect the scene. So I added 2 new functions to TLight, GetLightValues and SetLightValues. The get function uses glGetLightfv and needs to be called at init after a RenderWorld or the default light values will be used. The set function uses glLightfv and must be called after EndMax2d (or before RenderWorld) in the main loop. That's all you have to do. There is also a debug function DebugLightValues in the sl_bumpmap example which shows how easy it is to access light values now, for example you would want to set specular to the same color as light2 (I haven't done this). Edit: ok, I added this to init in sl_bumpmap.

I also changed tangent in bumpmap2.vert back to a vec4, it makes no difference though.

About BufferToTex, there is CameraToTex but I don't know which is faster. There may be a faster way with shaders but I don't know it.

About shadows, no I haven't done any of this yet. Yes, there is a function SetShadowColor not externed, which lets you change color and alpha of shadows.


angros47(Posted 2015) [#224]
Ok, version 1.1 is online:

Added:
-3d actions: ActMoveBy, ActTurnBy, ActMoveTo, ActTurnTo, and many more
-Physics features: CreateConstraints and CreateRigidBody; with the last one, it's possible to define position, scale and rotation of an entity by linking it to four other entities (usually pivots): if that entities are controlled by constraints, the main entity can be controlled in a physically realistic way
-Particle system: emitters can be made with CreateEmitter (even an "emitter of emitters" is possible)
-if a light is created with a negative light type, it won't cast shadows
-DepthBufferToTex: with no args it uses the back buffer, otherwise it can render the depth buffer from a camera (like in CameraToTex)

Fixed:
-Collisions crashed when an entity made with CopyEntity was erased, it doesn't crash any more
-Dynamic collisions didn't work for scaled entities, or child entities; now they work
-HideEntity now works on lights
-Finally, it's possible to load textures from different directories; path info in texture name is now used: if the file cannot be found, a warning is emitted and the file is searched in current directory (or in the directory where the 3d model using that texture is located).
-CreateGeosphere now build a model with correct texture mapping
-When updating a child entity, only its matrix is recalculated, not the entire tree (should be slightly faster)
-PaintEntity and TextureFilter now should work
-fixed a bug in static shadows


markcw(Posted 2015) [#225]
Cool. Thanks Angros! Looking forward to trying it out.

So what was the static shadows bug?


Hezkore(Posted 2015) [#226]
Sweet!
About lights... Is light type -1 the same as light type 1 just without shadows?
Same with type 2 and -2?


angros47(Posted 2015) [#227]
@munch
The bug was that I forgot yo set VCreated to 0

@Hezkore
Yes


Hezkore(Posted 2015) [#228]
Thanks angros!

When we can expect the BlitzMax module to be updated munch? :)


Cocopino(Posted 2015) [#229]
Those sound like great additions angros.
Do you have an example (FreeBasic or otherwise) of CreateParticleEmitter or an emitter property/method list?

Thanks!


angros47(Posted 2015) [#230]
Of course:

http://freebasic.net/forum/viewtopic.php?p=211401#p211401


Cocopino(Posted 2015) [#231]
Looking nice :)

Is it possible to rotate the particles?
Also, is it possible to add variety to the origin of the particles, so they do not start at the exact same spot every time? To simulate snow for example?


angros47(Posted 2015) [#232]
These features are not directly available. Anyway, it's possible to set a callback function: you can set it with "EmitterParticleFunction emitter, routine"

"routine" is a function that has two arguments: the handle of the particle, and its life; you can write this function as you like (the concept is similar to FluidFunction), if will be called once for every particle at every frame (so be sure to keep it simple and fast), and you can use it if you want some custom behavior (a particle can rotate, change its color, become bigger or smaller...); the "life" parameter will tell the function how long the particle will last (when it goes to zero, the particle is deleted: it can be used to set the alpha level, and the particle will fade away). If you set a particle life of, let's say, 1000, you can use the custom function to randomly displace a particle only when its life is 1000 (so, only when it has been just emitted); by displacing only on X and Z axis, all particles will fall from a square area, from the same height (perfect to simulate snow); the same custom function can also slightly move the falling particle randomly (to simulate the irregular path of falling snowflakes).

Most particle systems have a lot of extra commands to set rotation, color fading etc; unfortunately, they are never good enough to make satisfy every need (what if I want a particle that changes color twice, then becomes bigger, then fades away?); so, I only put commands for essential features (gravity, rate, life time, variance), and left the rest to the callback function.


Cocopino(Posted 2015) [#233]
I get it, thanks


markcw(Posted 2015) [#234]
I've updated the module repo now for the latest 1.1 source.

TShadowObject now has all data members and functions. The example stencil_shadows has had a big update to get static shadows working with multiple lights and animated models. I used Angros's workaround to render two shadows per mesh for two lights. It could be adapted for 3 lights fairly easily. I tried using cast_shadow but it was too tricky. So you can now have static shadows with 'dynamic' shadows, that are actually static but re-created. I actually prefer the static shadows now as they do not double up when they cross each other, which looks more natural.

Edit: one point I forgot to mention is you can't mix dynamic with static shadows because the static shadows need to hide all but one light to avoid doubling the render, so you can't mix them (just in case someone trys. Edit: unless you're only using one light). I checked the fps between dynamic and static and static was slower even when most shadows were static, this is from the animated model shadows which have two extra RenderWorlds per loop.

Edit2: just updated the stencil_shadows example again. Static shadows have been optimized, so there's every available option there now, press A to test different modes.

I changed my fix for fog with Max2d so rather than my cpp edit I added an UpdateFog method to TCamera and updated the fog example. This seems to only be needed on Linux but makes no difference on Win/Mac.

Edit: forgot to add project.h, not adding the glew include worked in Linux/Win but errored on Mac. I also had to move methods/data imports into source.bmx for it to build on Mac.


markcw(Posted 2015) [#235]
Angros, I meant to mention x.cpp, as I see you've updated it but haven't added Brucey's fix for Mac yet, see post #3 this thread. Are you going to add this? These are the changes:

ln 225...
void loadBrush(list<XLoader_TreeNode*> matlist, Brush* brushes[], vector<string> &brushnames){
ln 233...
		brushnames.push_back(material->name);
ln 333...
						vector<string> brushnames;
ln 532...
										vector<string> Lbrushnames;



angros47(Posted 2015) [#236]
Oh, sorry, since I don't have a mac, I forgot.

Anyway, the only change I made is replacing ReadFile with ReadResourceFile, to be able to use the new fix to read textures with path.


markcw(Posted 2015) [#237]
Ok fine. Also, remember that if you don't add the right headers to project.h it won't build on Mac. I've updated x.cpp with both changes and edited shadow.cpp to add a fix for ShadowAlpha always being 0.5. I also updated the stencil_shadows example again (just trying to make it clearer about using static shadows).


Hezkore(Posted 2015) [#238]
I'm having some issues with alpha textures always being rendered below the stencil shadows.
Any way to fix this?

Basically I have a few quads with textures on them, those textures have some transparent parts, so they're loaded with the alpha flag.
And the object sorting seems to go crazy when alpha is enabled.


angros47(Posted 2015) [#239]
When alpha is enabled, the mesh does not affect the depth buffer (in fact, to render it correctly a slower algorithm, called z sorting, is used); if depth buffer were updated, in fact, the surface might still behave as if it were opaque.

Unfortunately stencil shadows work using the depth buffer, and don't acknowledge transparent objects. If only part of the texture is transparent, try using mask flag instead of alpha flag (mas&#311;ed flag set the depth buffer, because transparency is "all or nothing")


markcw(Posted 2015) [#240]
I can't reproduce this on ubuntu or Win7. Could you provide code? See the stencil_shadows example for my test.

Edit: updated the example with some more alpha quads but it still works fine. Also added a proper fix for UpdateFog, it's in in EndMax2d now.


Hezkore(Posted 2015) [#241]
Make sure the quads have textures loaded with flag 2 I believe?
The quads also sorts a bit weirdly among themselves...

I'll try to get a sample working for you.


Hezkore(Posted 2015) [#242]
I've managed to get a decent example of the issue.
alpha_issue.zip (Win EXE and source)


markcw(Posted 2015) [#243]
Ok, I've tested and I can see the issue now (I think). Alpha mapped quads in front of stencil shadows don't obscure them.

So as Angros said, alpha and stencil shadows will be combined in the depth buffer rather than sorted as normal. So you can either use the mask flag in LoadTexture, which is 4, color is opaque which is 1 (there doesn't appear to be a setting for masked textures in EntityFX) - or you could just use meshes (which might look better). If you really need alpha quads then you would have to make your own shadow system with pre-calculated animated shadow quads.

Also note, there is an issue with alpha where you need more than one visible surface (ie. non-alpha and non-hidden) for alpha to work, otherwise everything is opaque.


Hezkore(Posted 2015) [#244]
There's no alpha shader that save me?


markcw(Posted 2015) [#245]
No, I don't think so. This is a limitation of stencil shadows, shaders and alpha meshes are both subject to the same depth buffer issue.


angros47(Posted 2015) [#246]
Unfortunately, since shaders have become available, some people started looking at them as if they were a magic solution for everything: "How can I do bumpmapping in OpenGL?" "Use shaders"; "How can I get shadows?" "Use shaders", "How can I achieve a better transparency?" "Use shaders", "How can I..." "Just use shaders".... Have a look at some programming forum, if you don't believe me. Shaders are just a way to run compiled code on GPU instead of CPU, nothing more; they cannot overcome rules of math and geometry. Even the concept of running a program written in a C-like language on GPU is nothing new, it was already possible in 1986 (with TMS34010 chip)

Running the same algorithm on GPU could sometimes make it faster, but cannot make it better. Other algorithms (like shadow mapping) don't have the issues of stencil shadows, but have other issues (i.e. they don't work when a point light cast shadows in all directions)


Hezkore(Posted 2015) [#247]
I haven't used any shaders before in my entire life, and I'm really no good with "normal" 3D either.
So I certainly don't intend to start relying on shaders as a solution for everything, and I don't think that they're magical in any way.
I was just curious if perhaps a shader could render the "alpha parts" of an image or something like that.
But if it doesn't work and there really is no way to use my alpha textures - then that's fine.
I'll find a way to work around it.


markcw(Posted 2015) [#248]
Well, you could use 2d alpha images positioned over a hidden mesh caster, but you can't render shadows from hidden meshes so you'd have to edit shadow.cpp or maybe use the methods in TShadow.


angros47(Posted 2015) [#249]
If an entity is not hidden, but have alpha set to zero, it should still be invisible, but it will cast shadow.

To render an alpha mesh (or quad) "over" the shadow, I forgot to mention the simplest solution: multipass rendering. Just hide the transparent mesh, perform a RenderWorld, then set CameraClsMode to 0,0 (so it won't erase the already rendered scene), hide everything (if all objects are childs ov an hypothetical "scene"pivot, you can do it with a single command) , show only the transparents objects and render them with another RenderWorld. It should work.


Hezkore(Posted 2015) [#250]
I'm back with more bug reports!

If you run OpenB3D inside a MaxGUI window, lights do not work nor does shadows.
I've made a simple example here showing the problem.
maxgui_shadows.zip
Set "UseMaxGUI" to "False" to see how things should look.
It looks like the shadows are instead covering the entire screen.
Setting shadow alpha to 255 and color to red makes the entire screen red!



And I'm not 100% sure, but I think shaders might also be bugged when using MaxGUI? (Not in example)
It might just be cause of the lights not working correctly though.


markcw(Posted 2015) [#251]
Angros, I tried that but couldn't get it working because I was trying to hide the light but following your method I got it working! Also I added a key to toggle multipass. The only problem is it won't go under the shadow but I think this will be fine for Hezkore.

Hezkore, you're great at finding bugs! Thanks, it's really making the wrapper much better. I'll look into this Maxgui bug soon.


angros47(Posted 2015) [#252]
Maybe MaxGUI does not set OpenGL context to use the stencil buffer . If there are no stencils, the shadow is drawn on the whole scene.


markcw(Posted 2015) [#253]
Ok, the solution for Maxgui is to use the flags parameter in SetGraphicsDriver like so.
Local flags%=GRAPHICS_BACKBUFFER|GRAPHICS_ALPHABUFFER|GRAPHICS_DEPTHBUFFER|GRAPHICS_STENCILBUFFER|GRAPHICS_ACCUMBUFFER
SetGraphicsDriver GLMax2DDriver(),flags

Edit: I have updated the maxgui example with this fix. Also GraphicsResize has been removed, so you use TGlobal width/height pointers instead. That just lets Openb3d know the graphics has been resized.


Hezkore(Posted 2015) [#254]
I still had some issues but I managed to figure out that SetGraphicsDriver(GLMax2DDriver(),flags) has to be called BEFORE the canvas is created.
I only called it before Graphics3D().

Is it just me, or does myShadow.SetShadowColor(R,G,B,A) set the color and alpha for ALL shadows?
It seems a bit odd that it's called as a method from a shadow object and not via just SetShadowColor(R,G,B,A) if it's a global setting.
Especially since the example for stencil shadows calls SetShadowColor multiple times for a lot of different objects, and in the end they're all the same color anyways.

Also, shadows doesn't seem to work if an entity has alpha -1.
In my demo posted above, set the cube's alpha to -1 with EntityAlpha(cube, -1) and shadows will no longer work.
And in my game, any entity with a different alpha value than 1 makes shadows disappear.


Ferret(Posted 2015) [#255]
Trying to update but the module fails to build.
Compile Error: Module does not match commandline module
[D:/BlitzMax/mod/angros.mod/b3dglgraphics.mod/b3dglgraphics.bmx;27;30]
Build Error: failed to compile D:/BlitzMax/mod/angros.mod/b3dglgraphics.mod/b3dglgraphics.bmx



Hezkore(Posted 2015) [#256]
@Ferret the name has changed from "angros.mod" to "openb3d.mod", so rename your folder!


Ferret(Posted 2015) [#257]
It works when i use the correct folder name :-)
Project builds fine too, thx again!


markcw(Posted 2015) [#258]
Yeah, sorry I decided to renamed the modscope to Openb3d because I thought it was more appropriate. I decided I would rather use a non-personal name for the modscope because it was more of a thing than an it, if that makes sense. Also, I have moved the minib3d/blitz3d examples to subfolders so it is more organized.

Re: shadow colors. It should certainly be possible to set each color individually, perhaps a value based on the distance from the light would work well. About alpha being -1, it should be a value from 0..255 anything else will produce unknown results.


Hezkore(Posted 2015) [#259]
Well in the current version of the engine, shadows color does not work correctly.
Setting the shadow color for one object changes it for all objects.


markcw(Posted 2015) [#260]
The problem with shadow color is that it is set by glMaterial which is a global function so you would have to perform multiple renders for each change in shadow color and this will really eat into the FPS. I think shadows are all the same color/shade anyway so I don't see why you need this.


Hezkore(Posted 2015) [#261]
That's why I think SetShadowColor should be a function on its own and not called as a method.

In my situation, I wanted stronger shadows in certain parts of the map, for example indoors.
There's no loading screens or anything like that, and both inside and outside of a "house" can be seen, so setting shadows based on where you are isn't really an option for me.
So I coded the editor to allow different shadow color and alpha per entity, only to find out that it sets the color for all of them.

But I just wanted to make sure I wasn't doing something wrong/stupid, not complaining heh.
If that's how shadows works, I'll work with what I have!


markcw(Posted 2015) [#262]
I managed to get multiple shadow colors working with dynamic shadows but not static, maybe I will try that one again but the FPS is better for dynamic shadows anyway so IMO there is little point in using static shadows unless they can be optimized. Edit: well if you're using all static shadows then that is the fastest but if you want dynamic AND static you should just use all dynamic.

I'm having a MAV issue with the latest version but the stencil_shadows example has been updated and you can see the method used for doing multiple shadow colors (well just two in this case). You use ShadowRenderWorldZFail instead of RenderWorld. Edit: the MAV issue (appcrash on any example) was due to a MinGW 4.8.1 lib conflict I couldn't resolve it so I just tried 4.7.1 and it's fine.