MiniB3d for FreeBasic

Headers, Bindings, Libraries for use with FreeBASIC, Please include example of use to help ensure they are tested and usable.
Post Reply
Gunslinger
Posts: 77
Joined: Mar 08, 2016 19:10
Location: The Netherlands

Re: MiniB3d for FreeBasic

Post by Gunslinger »

angros47 wrote: Oct 24, 2023 17:34 You might need to disable GL_TEXTURE_2D or GL_LIGHTING before glBegin
Thank you for the quick replay.
Disable GL_LIGHTING works.

after some research i found out a other solution.

Code: Select all

	glEnable( gl_Color_Material )
	glEnable(GL_BLEND)
	
	glLineWidth(100)
	glBegin(GL_LINES)
		glColor4f .5,-1,1,1 ' not working
		glVertex3f(0,-100,0)
		glVertex3f(0,0,0)
	glEnd()
	
	glDisable( GL_COLOR_MATERIAL )		   
here the color and alpha blend works also keeping lightning.
To bad i had to learn some OpenGL stuff...
Gunslinger
Posts: 77
Joined: Mar 08, 2016 19:10
Location: The Netherlands

Re: MiniB3d for FreeBasic

Post by Gunslinger »

Oke here i'm again trying to translate a BlitzBasic/BlitxMax openb3d code at https://www.blitzcoder.org/forum/topic.php?id=544
i have a problem getting terrainsize in openb3d for freebasic.
My idea to use MESHWIDTH or MESHDEPTH to get the terrain size becouse terrainsize in not in freebasic translation
But i do get strange results.

Exaple code:

Code: Select all

#include once "openb3d.bi" '64bit windows version
screenres 1024,768,32,1, &h10002
Graphics3D 1024,768,32,1

var mesh = Createterrain(10)
var obj = Createcube(mesh)
dim as long MESH_WIDTH = MESHWIDTH(mesh)
dim as long MESH_WIDTHo = MESHWIDTH(obj)

screen 0 'for console print
print str(MESH_WIDTH)
print str(MESH_WIDTHo)
end
outputs:
0
2

Conversion with shadow not working (wip):

Code: Select all

'---https://www.blitzcoder.org/forum/topic.php?id=544
#include once "openb3d.bi" 'https://www.freebasic.net/forum/viewtopic.php?t=15409&hilit=openb3d
#include "fbgfx.bi"
#if __FB_LANG__ = "fb"
Using FB '' Scan code constants are stored in the FB namespace in lang FB
#endif
screenres 1024,768,32,2 , &h10002
Graphics3D 1024,768,32,2
'var SetBuffer = BackBuffer()
'var WBuffer = 1


' ----- main camera and player pivot -----
dim shared as any ptr camera: camera=CreateCamera()
CameraRange camera,0.01,2000
CameraClsColor camera,100,150,200
dim shared as any ptr player
player=CreatePivot()
TranslateEntity camera,0,5,0
EntityParent camera,player
MoveEntity player,0,100,0
EntityRadius player,5
EntityType player,2


' -----shadow camema -----
dim shared as any ptr ShadowCam: ShadowCam=CreateCamera()
CameraProjMode ShadowCam,2
HideEntity Shadowcam


' ----- a lit terrain -----
dim shared as any ptr terrain: terrain=LoadTerrain("myhmap1.png")
dim shared as long towel_scale_Y=10
ScaleEntity terrain,10, towel_scale_Y, 10
'PositionEntity terrain,-TerrainSize(terrain)*5,0,-TerrainSize(terrain)*5
PositionEntity terrain,-256*5, 0, 256*5
var terrtex=LoadTexture("rock1.jpg")
EntityTexture terrain,terrtex
ScaleTexture terrtex,10,10
EntityType terrain,1
var light=CreateLight()
RotateEntity light,-45,45,0
'TerrainShading terrain,1
'TerrainDetail terrain,1000



' ----- init shadow texture -----
dim shared as long ShadowTexSize=512 ' defines the resolution of the shadow texture
dim shared as any ptr ShadowTex: ShadowTex=CreateTexture(ShadowTexSize,ShadowTexSize,8+1)
dim shared as long shadow_Towel_Yoffset=0.7 ' used to prevent "blinking" towel
' NOTE to make sure the offset is not so obvious, you should use characters with dark shoes 
' or trees with a darkish trunk etc.



' ----- create Shadow Towel -----
dim shared as long towel_size=32 ' defines the number of segments
dim shared as any ptr cam_towel
cam_towel=CreateTerrain(towel_size)
EntityFX cam_towel,1
var cam_towel_piv=CreatePivot()
dim shared as long towel_scale_XZ=12 ' defines the XZ scale factor
ScaleEntity cam_towel,towel_scale_XZ,towel_scale_Y,towel_scale_XZ
PositionEntity cam_towel,(-towel_size*towel_scale_XZ)/2.0,0,(-towel_size*towel_scale_XZ)/2.0,1
EntityParent cam_towel,cam_towel_piv
EntityTexture cam_towel,ShadowTex
TextureBlend shadowtex,2
EntityBlend cam_towel,2
ScaleTexture shadowtex,-towel_size,-towel_size
'TerrainDetail cam_towel,1000


' ----- create some dummy scene objects -----
var testtex=LoadTexture("colors.jpg")
dim shared as long num_o=50
Dim shared as any ptr c(num_o),c_brush(num_o)
For i as long=0 To num_o
 c(i)=CreateCube()
 ScaleEntity c(i),2,20,2
 PositionEntity c(i),(Rnd-.5)*2560,0,(Rnd-.5)*2560
 var y=TerrainY(terrain,EntityX(c(i)),0,EntityZ(c(i)) )*10 'crash line
 PositionEntity c(i),EntityX(c(i)),y+5+Rnd,EntityZ(c(i))
 EntityTexture c(i),testtex
 RotateEntity c(i),Rnd(360),Rnd(360),Rnd(360)
 EntityColor c(i),100,100,100
 c_brush(i)=GetEntityBrush(c(i))
Next
' NOTE: all meshes and their brushes etc. (but the terrain) need to be indexed in this arrays to make 
' them cast shadows!

var bol = createsphere()
ScaleEntity bol,10,10,10

' --------- several brushes used to paint background and shadow casters during shadow map rendering
'var whitebrush=CreateBrush(255,255,255)
dim shared as any ptr whitebrush
whitebrush=CreateBrush(255,0,255) ' use this to make the towel visible (for debugging)
BrushFX whitebrush,1
dim shared as any ptr shadowbrush
shadowbrush=CreateBrush(140,140,140) ' defines the darkness of the shadows
BrushFX shadowbrush,1
dim shared as any ptr terrainbrush: terrainbrush=GetEntityBrush(terrain)


Collisions 2,1,2,2
Dim As Longint x, y, buttons, res, oldx, oldy
dim as double t = timer()
' Set video mode and enter loop

declare sub UpdateShadowmap()
Declare sub UpdateShadows(ground as any ptr,towel as any ptr,piv as any ptr)



While MultiKey(SC_ESCAPE)=0 'KeyDown(1)=0
	For i as long =0 To num_o
		TurnEntity c(i),1,2,3 ' show that it's dynamic 
	Next

	If MultiKey(SC_W) then MoveEntity player,0,0,1
	If MultiKey(SC_S) then MoveEntity player,0,0,-1
	If MultiKey(SC_D) then MoveEntity player,1,0,0
	If MultiKey(SC_A) then MoveEntity player,-1,0,0

	
	res = GetMouse (x, y, , buttons)
	var msx=0.25 * ((1024/2)-x)
	var msy=0.25 * ((768/2)-y)
	SetMouse 1024/2, 768/2
	TurnEntity player,0,msx,0
	TurnEntity camera,msy,0,0
	If MultiKey(SC_SPACE)=0 then
		TranslateEntity player,0,-.5,0' gravity
	Else
		TranslateEntity player,0,.5,0' allow to fly with space key
	EndIf
	'/

	UpdateShadows(terrain, cam_towel, cam_towel_piv)
	UpdateWorld()
	RenderWorld()
	var old_t=t
	var t=timer()
	'locate 1,1
	windowtitle (1000.0/(t-old_t)) & " fps"
	'print "Tris rendered: "'; 'TrisRendered()
	sleep 1
	Flip
	
Wend
End



sub UpdateShadows(ground as any ptr, towel as any ptr, piv as any ptr)
	dim as long x=EntityX(player, 1)
	dim as long z=EntityZ(player, 1)
	PositionEntity piv, x, shadow_Towel_Yoffset, z, 1
	RotateEntity piv,0,180,0,1
	'align the shadow towel to the underlying terrain
	For i as long = 0 To towel_size-1 ' terrainsize
		var xx=EntityX(towel,1)-(i*towel_scale_XZ)
		For j as long =0 To towel_size-1
			var zz=EntityZ(towel,1)-(j*towel_scale_XZ)
			var tyl=TerrainY(ground,xx,0,zz)
			var ty=((TerrainY(ground,xx,0,zz))/towel_scale_Y)
			ModifyTerrain towel,i,j,ty
		Next
	Next

	' hide borders
	For i as long = 0 To towel_size
		ModifyTerrain towel,i,towel_size,0
	Next
	For j as long = 0 To towel_size
		ModifyTerrain towel,towel_size,j,0
	Next
	UpdateShadowmap()
End sub






sub UpdateShadowmap()
	' hide the towel, make the terrain white and all meshes grey
	For i as long =0 To num_o
		PaintEntity c(i), shadowbrush
		EntityFX c(i),1
	Next
	HideEntity cam_towel
	PaintEntity terrain, whitebrush
	' toggle shadow camera (orthographic)
	HideEntity camera
	CameraClsColor shadowcam,255,255,255
	CameraZoom shadowcam,(.031 /towel_scale_XZ)/(towel_size/64.0) ' .028
	ShowEntity ShadowCam
	CameraProjMode ShadowCam,2
	' take a render from above
	PositionEntity shadowcam, EntityX(player,1),1000,EntityZ(player,1)
	RotateEntity shadowcam,90,0,0
	CameraViewport shadowcam,0,0,ShadowTexSize,ShadowTexSize
	RenderWorld()
	' copy that render to the shadow texture buffer
	BACKBUFFERTOTEX ShadowTex
	'CopyRect 0,0,ShadowTexSize,ShadowTexSize,0,0,BackBuffer(),TextureBuffer(ShadowTex)
	'restore camera
	ShowEntity camera
	'HideEntity ShadowCam
	ShowEntity cam_towel
	' restore object materials
	PaintEntity terrain, terrainbrush
	for i as long=0 To num_o
		PaintEntity c(i),c_brush(i)
		EntityFX c(i),0
	Next
End sub
angros47
Posts: 2277
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

MeshWidth and MeshDepth do no apply to a terrain, because a terrain is not a mesh.
TerrainSize is not implemented in OpenB3D; it could be implemented by reading the member "size" of the class "Terrain", if would likely be something like:

Code: Select all

float TerrainSize (Terrain* terr){
	return terr->size;
}
By the way, the example you are trying to port is not written in BlitzMax OpenB3D (not even the BlitzMax version supports TerrainSize): it is written in Blitz3D, that is not based on OpenB3D. Also, you actually don't need to use that trick: in fact, original Blitz3D has no default way to implement shadows, so tricks like the one you linked were required, while OpenB3D already provides shadows, and they can be rendered on terrains with no need of that trick.
Gunslinger
Posts: 77
Joined: Mar 08, 2016 19:10
Location: The Netherlands

Re: MiniB3d for FreeBasic

Post by Gunslinger »

Thanks for the information. I already had the impression it was almost the same as shadow in openB3D.
I really do like to have a shader for shadow rendering, something like this:
https://github.com/markcwm/openb3d.docs ... .vert.glsl
I cant find any good examples for shaders that are a bit more complex with openB3D.

For start how to read the depth buffer texture and pase to frag shared.
I use to have some good examples but lost them.
angros47
Posts: 2277
Joined: Jun 21, 2005 19:04

Re: MiniB3d for FreeBasic

Post by angros47 »

Some examples of shader for OpenB3D can be found in the package OB3DPlus. There is a PBR shader, a bump mapping one, an interior mapping one, a glass one, a shadow mapping one, and several post processing ones (including SSAO , Depth of Field, and more), and even an experimental (barely working) example of deferred lighting.

The shadow mapping shader does more or less what you want.

Using a shader, for shadow rendering, has some issues: in fact, all the receiving entities (terrains, or meshes) where the shadow is cast on must be rendered with that specific shader, and that prevents using a different one: so, what if someone wants to use a fur shader to simulate the grass on a terrain, and at the same time wants to cast shadow on the same terrains? It can surely be achieved (by compiling a shader that includes both features, for example, or by using two terrains rendered in the same place, one with the grass, one with the shadow), but it is not always so immediate.

Also

The solution implemented by default by OpenB3D is stencil shadows: those shadows have some limits (the main one is that they cannot take in account a mask texture), but they are pretty fast, work everywhere, even on the old fixed pipeline, and can be cast on any surface, regardless of the shader used. Of course, shadow mapping can still be used if for any reason you don't like stencil shadows.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: MiniB3d for FreeBasic

Post by D.J.Peters »

I played a litle bit with Open3DJS here are a template for a resizable window/cannvas.

Joshy

Code: Select all

<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <title>OpenB3BJS template of resizable  window.</title>
    <script src="OpenB3D.js"></script>
    <script src="OpenB3DJS.js"></script>
  </head>

  <body>
    <script>
'use strict'; // <- Always better than trouble with undeclared variable. ;-) 

Module.onRuntimeInitialized = _ => {
  // create a canvas
  var canvas = document.createElement("canvas");
  
  // resize it to the client region of the web page
  canvas.width  = window.innerWidth;
  canvas.height = window.innerHeight; 
  
  // add it to the DOM of the web page
  document.body.appendChild(canvas);
  
  // store the WebGL context in the global var 'GLctx'
  GLctx = canvas.getContext("webgl");
  
  // use the dimension of the canvas to init the engine
  Graphics3D(canvas.width, canvas.height,0,0,0);
  
  // build the scene
  let cam   = CreateCamera(0);
  let cube  = CreateCube(0);
  let light = CreateLight(1,0);
  
  TurnEntity(light,45,45,0);
  MoveEntity(cube,0,0,5);

  function doFrame(){
    TurnEntity(cube,1,1,1);
    UpdateWorld();
    RenderWorld();
    setTimeout(doFrame,1000/30);
  }
  
  function onResize() {
    // resize the canvas
    canvas.width  = window.innerWidth;
    canvas.height = window.innerHeight;
    // tell the active camera the new size
    CameraViewport(cam,0,0,canvas.width, canvas.height)
  }
  // watch for browser/canvas resize
  window.onresize = onResize;
  // start the show ;-)
  doFrame();
};
    </script>
  </body>
</html>
Post Reply