MAJOR UPDATE - Manual Mesh Creation
Screeny...
Using the SMesh() and the SMeshBuffer() classes I've managed to get fully working the manual creation of meshes. The current stage of the DarkIrrlicht project is attached to this post... (It's in 7z format as I won't use rar anymore, sorry)
I recently tried a very similar demo using just DBP and I was getting frame rates below 20, where-as with this version of it, with a more detailed plane layout I get much higher frame rates...
Here's the code snippet included in the download so you can see how easy it is:
` ------------------------------------------------------------------------------
` DarkIrrlicht SMesh & SMeshBuffer example
` I originally wrote this example on Linux using Irrlicht
` ------------------------------------------------------------------------------
` switch off DBP for now (only need to do the SYNC)
SYNC ON
` ------------------------------------------------------------------------------
` GLOBALS
` Delta timer to handle different frame rates smoothly
TYPE DELTA_TIMER
told AS FLOAT
tdel AS FLOAT
ENDTYPE
GLOBAL dtel AS DELTA_TIMER
` Images and textures
TYPE GFX_DATA
color AS DWORD
image AS DWORD
texture AS DWORD
ENDTYPE
GLOBAL DIM gfx(2) AS GFX_DATA
` Camera and light
TYPE CAM_AND_LIGHT
ang1 AS FLOAT
ang2 AS FLOAT
ang3 AS FLOAT
cam AS DWORD
light AS DWORD
ENDTYPE
GLOBAL cam AS CAM_AND_LIGHT
#CONSTANT cam_spd1 0.96
#CONSTANT cam_spd2 1.15
#CONSTANT cam_spd3 1.51
#CONSTANT cam_rad1 80.0
#CONSTANT cam_rad2 65.0
#CONSTANT cam_rad3 100.0
#CONSTANT cam_dst -105.0
` Cube node
GLOBAL cube_node AS DWORD
GLOBAL cube_ang AS INTEGER
` 3D plane objects
TYPE PLANE_OBJECT
ang AS FLOAT
spd AS FLOAT
pos AS FLOAT
node AS DWORD
ENDTYPE
GLOBAL pmesh_ptr AS DWORD
#CONSTANT MAX_OBJS 20
GLOBAL DIM objs(MAX_OBJS) AS PLANE_OBJECT
` default built in font <--- BUILT IN FONT NOT WORKING!!! ARGH!!!
`GLOBAL dfont AS DWORD
`dfont = IGUI GET DEFAULT FONT()
` ------------------------------------------------------------------------------
` Initialise the DarkIrrlicht window
IRR INIT 1,800,600
` ------------------------------------------------------------------------------
` Initialise all the demo stuff
init_graphics( 128, 12 )
init_objects(1500,15,100)
init_camera()
init_cube()
update_timer()
REPEAT
IVID BEGIN 1, 1, 0x00004080
IDEV TIMER TICK
run_camera()
run_cube()
update_timer()
ISCN DRAW ALL
`IFONT DRAW dfont, 0, 0, 0xffffffff, "FPS: " + STR$( IVID FPS() )
IDEV SET WINDOW CAPTION "FPS: " + STR$( IVID FPS() )
IVID END
UNTIL IRR KEYSTATE(32)
IRR DROP
END
` ------------------------------------------------------------------------------
` Delta timing
FUNCTION update_timer()
LOCAL c#
c# = IDEV GET TIME()
dtel.tdel = ( c# - dtel.told ) / 33.0
dtel.told = c#
ENDFUNCTION
` ------------------------------------------------------------------------------
`
FUNCTION init_graphics(size,gap)
` local vars
LOCAL c
LOCAL p1
LOCAL p2
LOCAL col
LOCAL raw
LOCAL tname$
` set the color array
gfx(0).color = 0xffff0000
gfx(1).color = 0xff00ff00
gfx(2).color = 0xff0000ff
FOR c=0 TO 2
` create the image
gfx(c).image = IIMG CREATE32( size, size )
` lock the image for faster drawing (not using the raw pointer)
raw = IIMG LOCK( gfx(c).image )
` clear the image (usually has junk)
IIMG FILL gfx(c).image, 0x00000000
` draw the cross texture
FOR p1=0 TO size
FOR p2=0 TO gap
col = RND(0x00ffffff) AND 0x007f7f7f
col = col OR gfx(c).color
IIMG SET PIXEL gfx(c).image, p1, p2, col, 0
IIMG SET PIXEL gfx(c).image, p2, p1, col, 0
NEXT p2
NEXT p1
` unlock now
IIMG UNLOCK gfx(c).image
` create the texture from the image
tname$ = "tx"+str$(c)
gfx(c).texture = IVID IMAGE TEXTURE( tname$, gfx(c).image )
NEXT c
ENDFUNCTION
` ------------------------------------------------------------------------------
` Manually create the plane meshes to handle the lighting better
FUNCTION init_objects(size,scale,space)
LOCAL buf AS DWORD
LOCAL x AS INTEGER
LOCAL y AS INTEGER
LOCAL v AS INTEGER
LOCAL xx#
LOCAL yy#
LOCAL v1 AS INTEGER
LOCAL v2 AS INTEGER
LOCAL v3 AS INTEGER
LOCAL v4 AS INTEGER
LOCAL i AS INTEGER
LOCAL smat AS DWORD
LOCAL c AS iNTEGER
LOCAL dummy AS DWORD
` grab a new SMesh and a new SMeshBuffer
pmesh_ptr = ISMESH NEW()
buf = ISMBUF NEW()
iSMESH ADD MESH bufFER pmesh_ptr, buf
` we can still use the buffer pointer even after dropping it
iSMBUF DROP buf
` setup the vertex and index sizes
ISMBUF SET USED VERTICES buf, (scale+1) * (scale+1)
ISMBUF SET USED INDICES buf, scale * scale * 6
FOR x=0 TO scale
FOR y=0 TO scale
` vertex position in array
v = ( y * ( scale + 1 ) ) + x
` calc the position
xx# = -( size / 2.0 ) + ( size / ( scale + 1.0 ) * x )
yy# = -( size / 2.0 ) + ( size / ( scale + 1.0 ) * y )
` set it up with normals, UV's, etc
iSMBUF vERTEX POSITION buf, v, xx#, yy#, 0.0
iSMBUF vERTEX NORMAL buf, v, 0.0, 0.0, -1.0
iSMBUF vERTEX TCOORD buf, v, x, y
ISMBUF VERTEX COLOR buf, v, 0xffffffff
` setup the index table for the faces
iF x<scale AND y<scale
v1 = x + y * ( scale + 1 )
v2 = v1 + scale + 1
v3 = v2 + 1
v4 = v1 + 1
i = ( x + y * scale ) * 6
ISMBUF INDEX buf, i + 0, v1 ` 1st face
ISMBUF INDEX buf, i + 1, v2
ISMBUF INDEX buf, i + 2, v3
ISMBUF INDEX buf, i + 3, v3 ` 2nd face
ISMBUF INDEX buf, i + 4, v4
ISMBUF INDEX buf, i + 5, v1
ENDIF
NEXT y
NEXT x
` recalc the bounding box (not really needed for this demo)
ISMBUF CALC BOUNDING BOX buf
` setup all the material parameters
smat = ISMBUF GET MATERIAL( buf )
IMAT SET AMBIENT smat, 0xffffffff
IMAT SET DIFFUSE smat, 0xffffffff
IMAT SET EMISSIVE smat, 0xffffffff
IMAT SET SPECULAR smat, 0xffffffff
IMAT SET SHININESS smat, 1.0 ` <-- DOUBLE CHECK FUNCTION C++
IMAT SET LIGHTING smat, 1
IMAT SET MATERIAL TYPE smat, 13 ` EMT_TRANSPARENT_ALPHA_CHANNEL
` This bit isn't needed anymore, just looks uglier
` although it still positions the mesh on the scene
FOR c=0 TO MAX_OBJS
objs(c).ang = 0.0
objs(c).spd = c * 0.25 + 1.0
objs(c).pos = c * space
objs(c).node = ISCN ADD MESH NODE( 0, pmesh_ptr )
INODE MATERIAL TEXTURE objs(c).node, 0, gfx(c MOD 3).texture
INODE POS objs(c).node, 0, 0, c * space
NEXT c
ENDFUNCTION
` ------------------------------------------------------------------------------
` Camera and Light handler
FUNCTION init_camera()
cam.ang1 = 0.0
cam.ang2 = 0.0
cam.ang3 = 0.0
cam.cam = ISCN ADD CAMERA NODE( 0 )
cam.light = ISCN ADD LIGHT NODE( 0 )
ILIGHT SET RADIUS cam.light, 250.0
ENDFUNCTION
FUNCTION run_camera()
LOCAL x#
LOCAL y#
LOCAL z#
LOCAL tx#
LOCAL ty#
LOCAL spd1#
LOCAL spd2#
LOCAL spd3#
x# = COS( cam.ang1 ) * cam_rad1
y# = SIN( cam.ang1 ) * cam_rad1
z# = COS( cam.ang3 ) * cam_rad3 + cam_dst
INODE POS cam.cam, x#, y#, z#
tx# = COS( cam.ang2 ) * cam_rad2
ty# = SIN( cam.ang2 ) * cam_rad2
ICAM TARGET cam.cam, tx#, ty#, 20.0
INODE POS cam.light, x#, y#, z#
spd1# = cam_spd1 * dtel.tdel
spd2# = cam_spd2 * dtel.tdel
spd3# = cam_spd3 * dtel.tdel
cam.ang1 = WRAPVALUE( cam.ang1 + spd1# )
cam.ang2 = WRAPVALUE( cam.ang2 + spd2# )
cam.ang3 = wrapvalue( cam.ang3 + spd3# )
ENDFUNCTION
` ------------------------------------------------------------------------------
` Cube node handler
FUNCTION init_cube()
LOCAL smat AS DWORD
cube_node = ISCN ADD CUBE NODE( 0, 40 )
cube_ang = 0.0
smat = INODE GET MATERIAL(cube_node,0)
IMAT SET LIGHTING smat, 1
ENDFUNCTION
FUNCTION run_cube()
INODE ROT cube_node, cube_ang, cube_ang, 0
cube_ang = WRAPVALUE( cube_ang + 1.0 )
ENDFUNCTION
` ------------------------------------------------------------------------------
`
Mental arithmetic? Me? (That's for computers) I can't subtract a fart from a plate of beans!
Warning! May contain Nuts!