Horde3D Module

BlitzMax Forums/BlitzMax Programming/Horde3D Module

seyhajin(Posted 2009) [#1]
Hi all,

i have written Horde3D module for BlitzMax (1.30), you can get it here : Horde3D Module based on last Horde3d version (1.00 beta 3).
I used fake namespace 'H3D' for main library and 'H3DU' for utils functions.
All functions are documented in IDE, but if you want more informations, please visit official website http://www.horde3d.org.
A forum and wiki are best to start programming with Horde.
Horde have beautifull Scene Editor too.
the module is free for all usage.

official screenshots:




that's all. Enjoy !


DreamLoader(Posted 2009) [#2]
cool job,keep the nice work!


byo(Posted 2009) [#3]
Wow, nice. Thanks a lot.


plash(Posted 2009) [#4]
Is there a .lib for Horde3D? You can map the functions way easier than loading the DLL at runtime, and using so many global function pointers.


Filax(Posted 2009) [#5]
hi seyhajin

Good job man :)


sigi(Posted 2009) [#6]
Great, Thank You. :)


Panno(Posted 2009) [#7]
wow ! its free ! double wow !!

thx


FantomKite(Posted 2009) [#8]
Awesome! Maybe you can show some game coding examples? I mean a simple game. Thanks a lot!


Panno(Posted 2009) [#9]
any news ??


puki(Posted 2009) [#10]
Hey, in that top picture - the one with the guy in a hat, with the black coat. Is that model freely available? If so, post a link to it.


seyhajin(Posted 2009) [#11]
@puki: you can find man model in wrapper folder: "horde3d.mode/horde3d.mod/samples/models/man"

Simple sample with 3 pipelines renderers ( HDR, Forward, Deferred ), freelook, Max2D

strict

framework horde3d.horde3d
import horde3d.horde3dutils
'Max2D
import brl.max2d
import brl.glmax2d
import pub.glew

'// Load Horde3D Library (copy horde3d.dll and horde3dutils.dll into sample root )
H3D.OpenLibrary()
H3DU.OpenLibrary()

AppTitle = "Horde3D"

'// Open OpenGL context
const AppWidth% = 800
const AppHeight% = 600

SetGraphicsDriver GLMax2DDriver()
Graphics AppWidth, AppHeight
glewInit()

'// Initialize Horde3D, if false write errors into log file.
if not H3D.Init()
	H3DU.DumpMessages()
	end
endif

'// Set Horde options
H3D.SetOption( EngineOptions.LoadTextures, 1 )
H3D.SetOption( EngineOptions.TexCompression, 0 )
H3D.SetOption( EngineOptions.MaxAnisotropy, 4 )
H3D.SetOption( EngineOptions.ShadowMapSize, 1024 )


'// Add external resources
local forwardRes% = H3D.AddResource( ResourceTypes.Pipeline, "pipelines/forward.pipeline.xml", 0 )
local hdrRes% = H3D.AddResource( ResourceTypes.Pipeline, "pipelines/hdr.pipeline.xml", 0 )
local deferredRes% = H3D.AddResource( ResourceTypes.Pipeline, "pipelines/deferred.pipeline.xml", 0 )
local skyboxRes% = H3D.AddResource( ResourceTypes.SceneGraph, "models/skybox/skybox.scene.xml", 0 )
local lightRes% = H3D.AddResource( ResourceTypes.Material, "materials/light.material.xml", 0 )
local fontRes% = H3D.AddResource( ResourceTypes.Material, "overlays/font.material.xml", 0 )
local meshRes% = H3D.AddResource( ResourceTypes.SceneGraph, "models/knight/kinight.scene.xml", 0 )

'// you can copy content (from samples wrapper) into his sample root otherwise set your 'content' path,
'// Horde3d need external files ( pipelines, shaders,...) for working properly
H3DU.LoadResourcesFromDisk( "content" )

'// Add objects in SceneGraph
local camera% = H3D.AddCameraNode( RootNode, "Camera", hdrRes )
H3D.SetupViewport( 0, 0, AppWidth, AppHeight, true )
H3D.SetupCameraView( camera, 60.0, float(AppWidth)/float(AppHeight), 0.1, 5000.0 )

local skybox% = H3D.AddNodes( RootNode, skyboxRes )
H3D.SetNodeTransform( skybox, 0,0,0, 0,0,0, 500,500,500 )  

local light% = H3D.AddLightNode( RootNode, "Light", lightRes, "LIGHTING", "SHADOWMAP" )
H3D.SetNodeTransform( light, 0,50,500, 0,0,0, 1,1,1 )
H3D.setNodeParamf( light, LightNodeParams.Radius, 1000 )
H3D.setNodeParamf( light, LightNodeParams.FOV, 180 )
H3D.setNodeParami( light, LightNodeParams.ShadowMapCount, 3 )
H3D.setNodeParamf( light, LightNodeParams.ShadowSplitLambda, 0.9 )
H3D.setNodeParamf( light, LightNodeParams.ShadowMapBias, 0.001 )
H3D.setNodeParamf( light, LightNodeParams.Col_R, 1 )
H3D.setNodeParamf( light, LightNodeParams.Col_G, 1 )
H3D.setNodeParamf( light, LightNodeParams.Col_B, 1 )

local mesh% = H3D.AddNodes( RootNode, meshRes )


'// HDR post-process
local hdrMat% = H3D.FindResource( ResourceTypes.Material, "pipelines/postHDR.material.xml" )
rem
	a - Exposure (higher values make scene brighter)
	b - Brightpass threshold (intensity where blooming begins)
	c - BrightPass offset (smaller values produce stronger blooming) 
endrem

local exposure# = 2.0
local brightThreshold# = 0.3
local brightOffset# = 0.4
local blur# = 0.0

local turn# = 0.0
local pipeline% = 0
local debug% = false
While not keyhit( KEY_ESCAPE )

        '// update Nodes
	turn:+0.1
	H3D.SetNodeTransform( mesh,0,0,0,0,turn,0, 0.5,0.5,0.5 )

	'freelook
	Freelook( camera )
	
	'// debug mode
	if keyhit( KEY_F1 ) debug = not debug
	if ( debug )
		H3D.SetOption( EngineOptions.DebugViewMode, 1 )
	else
		H3D.SetOption( EngineOptions.DebugViewMode, 0 )
	endif
	
	'// switch between pipeline
	if keyhit( KEY_SPACE )
		pipeline = ( pipeline + 1 ) mod 3

		select ( pipeline )
			case 0
				H3D.SetNodeParamI( camera, CameraNodeParams.PipelineRes, hdrRes )
			case 1
				H3D.SetNodeParamI( camera, CameraNodeParams.PipelineRes, forwardRes )
			case 2
				H3D.SetNodeParamI( camera, CameraNodeParams.PipelineRes, deferredRes )
		endselect		
	endif
	
	if pipeline = 0 'HDR
		if keydown( KEY_A ) exposure:+0.01 elseif keydown( KEY_Q ) exposure:-0.01
		if keydown( KEY_Z ) brightThreshold:+0.01 elseif keydown( KEY_S ) brightThreshold:-0.01
		if keydown( KEY_E ) brightOffset:+0.001 elseif keydown( KEY_D ) brightOffset:-0.001
		if keydown( KEY_R ) blur:+0.01 elseif keydown( KEY_F ) blur:-0.01
		
		exposure = Clamp( exposure, 0.0, 5.0 )
		brightThreshold = Clamp( brightThreshold )
		brightOffset = Clamp( brightOffset, 0.0, 0.5 )
		blur = Clamp( blur, 0.0, 5.0 )
		

		H3D.SetMaterialUniform( hdrMat, "hdrParams", exposure, brightThreshold, brightOffset, 0.0 )
		H3D.SetMaterialUniform( hdrMat, "blurParams", blur, 0, 0 , 0 )
	endif
	
	'// overlay
	H3DU.ShowText( GetFPS() + " FPS | " + int( H3D.GetStat( EngineStats.TriCount, 1 )) + " Tris", 0, 0, 0.02, 1,0.5,0, fontRes, 5 )
	select ( pipeline )
		case 0
			H3DU.ShowText( "Pipeline (SPACE): HDR", 0.7, 0, 0.02, 1,1,1, fontRes, 5 )
			H3DU.ShowText( "exposure    (A/Q): " + exposure, 0, 0.02, 0.02, 1, 1 , 1, fontRes, 5 )
			H3DU.ShowText( "b.threshold (Z/S): " + brightThreshold, 0, 0.04, 0.02, 1, 1 , 1, fontRes, 5 )
			H3DU.ShowText( "b.offset    (E/D): " + brightOffset, 0, 0.06, 0.02, 1, 1 , 1, fontRes, 5 )
			H3DU.ShowText( "blur        (R/F): " + blur, 0, 0.08, 0.02, 1, 1 , 1, fontRes, 5 )
		case 1
			H3DU.ShowText( "Pipeline (SPACE): Forward", 0.7, 0, 0.02, 1,1,1, fontRes, 5 )
		case 2
			H3DU.ShowText( "Pipeline (SPACE): Deferred", 0.7, 0, 0.02, 1,1,1, fontRes, 5 )
	endselect

	'// Camera scene rendering
	H3D.Render(camera)
		
	'// Test MAX 2D
'	Switch2D()
'	SetColor 255,0,0
'	SetBlend ALPHABLEND
'	SetAlpha 0.5
'	GLDrawRect 100,100,200,300
'	SetAlpha 1.0
'	Switch3D()
	
	'// Finalize frame rendering
	H3D.FinalizeFrame()
	
	'// clear overlays
	H3D.ClearOverlays()
	
	'// write logging messages
	H3DU.DumpMessages() 	

	flip
wend

'// Release Horde3D & co
H3D.Release_()

end

function GetFPS()
	global fps% , lastms% , renders%
	renders:+1
	if (( milliSecs() - lastms ) >= 1000 )
		lastms = milliSecs()
		fps = renders
		renders = 0
	endif
	return fps
endfunction

function Freelook( camera% )
	global mxs% = mousex() , mys% = mousex() , lastmx% = mousex() , lastmy% = mousey()
	global cam_p# , cam_y# , cam_ud# , cam_lr# , cam_velx# , cam_velz#, cam_px#, cam_py#, cam_pz#
	global gw% = GraphicsWidth() / 2, gh% = GraphicsHeight() / 2
		
	if mousedown( 2 ) 
		mxs = ( mousex() - lastmx ) / 1.5
		mys = ( mousey() - lastmy ) / 1.5
		
		cam_p:+ mys
		cam_y:+ mxs
		
		cam_ud:+ (( cam_p - cam_ud ) / 10.0 ) 
		cam_lr:+ (( cam_y - cam_lr ) / 10.0 )
				
		movemouse gw, gh
		
		RotateEntity( camera, -cam_ud, -cam_lr, 0 )
	endif
	lastmx = mousex() 
	lastmy = mousey()
	
	if keydown( KEY_UP ) 
		cam_velz:- 0.05
	elseif keydown( KEY_DOWN ) 
		cam_velz:+ 0.05
	endif
		
	if keydown( KEY_LEFT ) 
		cam_velx:- 0.05
	elseif keydown( KEY_RIGHT ) 
		cam_velx:+ 0.05
	endif
	
	cam_velx:/ 1.1
	cam_velz:/ 1.1

	MoveEntity( camera, cam_velx, 0, cam_velz )
endfunction

'// Math Routines
function Clamp#( value# , min_# = 0.0 , max_# = 1.0 )	
	return min( max( value , min_ ) , max_ ) 
endfunction

function MatrixMultiplyVector#[]( m# ptr, v# ptr )
	return[	m[00] * v[0] + m[04] * v[1] + m[08] * v[2] , ..	
			m[01] * v[0] + m[05] * v[1] + m[09] * v[2] , ..
			m[02] * v[0] + m[06] * v[1] + m[10] * v[2] ]
endfunction

'// Blitz Entity System (Local Only)
function PositionEntity( entity%, x#, y#, z# )
	local tx#, ty#, tz#, rx#, ry#, rz#, sx#, sy#, sz#
	H3D.GetNodeTransform( entity, tx, ty, tz, rx, ry, rz, sx, sy, sz )
	H3D.SetNodeTransform( entity,  x,  y,  z, rx, ry, rz, sx, sy, sz )
endfunction

function RotateEntity( entity%, p#, y#, r# )
	local tx#, ty#, tz#, rx#, ry#, rz#, sx#, sy#, sz#
	H3D.GetNodeTransform( entity, tx, ty, tz, rx, ry, rz, sx, sy, sz )
	H3D.SetNodeTransform( entity, tx, ty, tz,  p,  y,  r, sx, sy, sz )
endfunction

function ScaleEntity( entity%, x#, y#, z# )
	local tx#, ty#, tz#, rx#, ry#, rz#, sx#, sy#, sz#
	H3D.GetNodeTransform( entity, tx, ty, tz, rx, ry, rz, sx, sy, sz )
	H3D.SetNodeTransform( entity, tx, ty, tz, rx, ry, rz,  x,  y,  z )
endfunction

function ScaleEntityUniform( entity%, scale# )
	ScaleEntity( entity, scale, scale, scale )
endfunction

function TranslateEntity( entity%, x#, y#, z# )
	local tx#, ty#, tz#, rx#, ry#, rz#, sx#, sy#, sz#
	H3D.GetNodeTransform( entity, tx, ty, tz, rx, ry, rz, sx, sy, sz )
	H3D.SetNodeTransform( entity, tx + x, ty + y, tz + z, rx, ry, rz, sx, sy, sz )
endfunction

function TurnEntity( entity%, p#, y#, r# )
	local tx#, ty#, tz#, rx#, ry#, rz#, sx#, sy#, sz#, turn#[4]
	H3D.GetNodeTransform( entity, tx, ty, tz, rx, ry, rz, sx, sy, sz )
	if ( p ) rx:+ p
	if ( y ) ry:+ y
	if ( r ) rz:+ r
	H3D.SetNodeTransform( entity, tx, ty, tz, rx, ry, rz, sx, sy, sz )
endfunction

function MoveEntity( entity%, x#, y#, z# )
	local tx#, ty#, tz#, rx#, ry#, rz#, sx#, sy#, sz#, localmatrix# ptr, move#[]
	H3D.GetNodeTransform( entity, tx, ty, tz, rx, ry, rz, sx, sy, sz )
	H3D.GetNodeTransformMatrices( entity, varptr localmatrix, null )
	move = MatrixMultiplyVector( localmatrix, [ x, y, z ] )
	tx:+ move[0]
	ty:+ move[1]
	tz:+ move[2]
	H3D.SetNodeTransform( entity, tx, ty, tz, rx, ry, rz, sx, sy, sz )
endfunction


'// Misc (thanks klepto2)
Function Switch2D()
        Global viewport:Int[4]
        glPushMatrix ()
        glLoadIdentity ()
        glMatrixMode(GL_PROJECTION)
        glPushMatrix ()
        glLoadIdentity() 

        glUseProgramObjectARB(0)

        glGetIntegerv (GL_VIEWPORT , viewport)
        gluOrtho2d (0,viewport[2], viewport[3], 0)

        glEnable(GL_DEPTH_TEST)
        glDepthFunc(GL_ALWAYS)
        SetBlend MASKBLEND
End Function

Function Switch3D()
        glDepthFunc (GL_LESS)
        glPopMatrix ()
        glMatrixMode(GL_MODELVIEW)
        glPopMatrix ()
        SetBlend(-1)
End Function 




Robb(Posted 2009) [#12]
Hey, thanks for this awesome wrapper.

Unfortunately I haven't been able to compile the source from your last post. Firstly I get errors as H3DU doesnt exist (works when I change it to H3DUtils as per the chicago example) but then I get another error on this line:

H3D.GetNodeTransformMatrices( entity, Varptr localmatrix, Null )
"Var must be a variable"


DreamLoader(Posted 2009) [#13]
does this mean we can use native max2d in h3d?


seyhajin(Posted 2009) [#14]
@Robb: download a last version of wrapper from same url : Horde3D Module, i have fixed minors bugs and i changed 'namespace'.

@DreamLoader: everything is possible with BlitzMax :)


DreamLoader(Posted 2009) [#15]
@seyhajin
sorry if this is not reasonalbe,just wonder if you can put a simple
max2d mixing example/code,i tried but failed,thanks for the share


Robb(Posted 2009) [#16]
@seyhajin: Thanks! I managed to get it working now. I loaded a completed scene file that I converted to horde and the frame rate is a constant 60fps with HDR. Truly amazing.

A quick question though, which could be more related to Horde itself, but how do I get alpha channels on my textures to work?
Do I need to set the blendmode in the code itself or will I need to edit the horde shaders?

I also noticed that the shaders included with your examples are not the same XXXXX.shader.xml files that come with the Horde3D download. Do they need to be edited to work with the wrapper?


seyhajin(Posted 2009) [#17]
@DreamLoader: i tried that quickly, it's work only with GLxxx commands, not Max2D, i look that and post code if it work correctly with Max2D.

@Robb: all shaders files in Horde3d package works without change anything. Can you post any screens :) ?

thanks for comments.