Thanks man! I might actually try using that for my game.
BTW, I thought I posted my 3D object loader code before in the snippets section, but I guess not.
Here it is, and attached are the media files needed:
SET DISPLAY MODE 640, 480, 32
SYNC ON : SYNC RATE 30
// `Set up verts & vectors to get normal data for our mesh
// r=MAKE VECTOR3(1) `Vertex 1
// r=MAKE VECTOR3(2) `Vertex 2
// r=MAKE VECTOR3(3) `Vertex 3
// r=MAKE VECTOR3(4) `CP Vector 1
// r=MAKE VECTOR3(5) `CP Vector 2
// r=MAKE VECTOR3(6) `Normal Vector
// r=MAKE VECTOR3(7) `Normalized Normal Vector
//
// SET VECTOR3 1, -100, 0, 0
// SET VECTOR3 2, 100, 0, 0
// SET VECTOR3 3, 0, 100, 0
// SUBTRACT VECTOR3 4, 1, 2
// SUBTRACT VECTOR3 5, 1, 3
// CROSS PRODUCT VECTOR3 6, 4, 5
// NORMALIZE VECTOR3 7, 6
//
// `Make Memblock Structure for our triangle mesh
// tri_memblock = 1
// bcounter = 0
//
// MAKE MEMBLOCK tri_memblock, 120 `size of data in bytes
//
// `Fill in header for mesh
//
// WRITE MEMBLOCK DWORD tri_memblock, bcounter, 338 : bcounter = bcounter + 4 `FVF Type
// WRITE MEMBLOCK DWORD tri_memblock, bcounter, 36 : bcounter = bcounter + 4 `FVF Size
// WRITE MEMBLOCK DWORD tri_memblock, bcounter, 3 : bcounter = bcounter + 4 `Number of verts
//
// `Vertex data for triangle, each group of three verts describes 1 poly.
//
// `vert1
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, X VECTOR3(1) : bcounter = bcounter + 4 `X
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, Y VECTOR3(1) : bcounter = bcounter + 4 `Y
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, Z VECTOR3(1) : bcounter = bcounter + 4 `Z
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, X VECTOR3(7) : bcounter = bcounter + 4 `x_normal
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, Y VECTOR3(7) : bcounter = bcounter + 4 `y_normal
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, Z VECTOR3(7) : bcounter = bcounter + 4 `z_normal
// WRITE MEMBLOCK DWORD tri_memblock, bcounter, 0 : bcounter = bcounter + 4 `diffuse_color
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, 0 : bcounter = bcounter + 4 `u
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, 0 : bcounter = bcounter + 4 `v
//
// `vert2
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, X VECTOR3(2) : bcounter = bcounter + 4
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, Y VECTOR3(2) : bcounter = bcounter + 4
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, Z VECTOR3(2) : bcounter = bcounter + 4
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, X VECTOR3(7) : bcounter = bcounter + 4
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, Y VECTOR3(7) : bcounter = bcounter + 4
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, Z VECTOR3(7) : bcounter = bcounter + 4
// WRITE MEMBLOCK DWORD tri_memblock, bcounter, 0 : bcounter = bcounter + 4
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, 1 : bcounter = bcounter + 4
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, 0 : bcounter = bcounter + 4
//
// `vert3
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, X VECTOR3(3) : bcounter = bcounter + 4
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, Y VECTOR3(3) : bcounter = bcounter + 4
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, Z VECTOR3(3) : bcounter = bcounter + 4
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, X VECTOR3(7) : bcounter = bcounter + 4
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, Y VECTOR3(7) : bcounter = bcounter + 4
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, Z VECTOR3(7) : bcounter = bcounter + 4
// WRITE MEMBLOCK DWORD tri_memblock, bcounter, 0 : bcounter = bcounter + 4
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, 1 : bcounter = bcounter + 4
// WRITE MEMBLOCK FLOAT tri_memblock, bcounter, 1 : bcounter = bcounter + 4
//
//
// `Make our mesh from the memblock
// MAKE MESH FROM MEMBLOCK 1, 1
//
// `Load image for texture
// LOAD IMAGE "D:\test.jpg", 1
//
// `Create object from mesh
// MAKE OBJECT 1, 1, 1
//
// POSITION OBJECT 1, 0, 0, 0
//
// POSITION CAMERA 0, 0, -200
// POINT CAMERA 0, 0, 0
//
// DO
// YROTATE OBJECT 1,OBJECT ANGLE Y(1)+0.1
// LOOP
`HOW TO UTILIZE THIS IN A 3D OBJECT LOADER: (In FIVE easy steps!!!)
` 1. Load object file.
` 2. Extract object data from file (number of verts, number of faces, vertices, faces, uv coords, colors, normals, etc.)
` a. For each line in the file (provided the file is a .OBJ), get what the prefix is and add to a list of verts, faces, tex coords, or normals accordingly.
`
` 3. Set up memblock, including mesh header (vertex type, vertex size, number of vertices).
` 4. For each polygon given, set up vertex information. (Including creating normals if necessary.)
` 5. Make mesh from memblock, then make object from mesh.
// Global data initialization
objfile = 1
TYPE VERT3
x AS FLOAT
y AS FLOAT
z AS FLOAT
ENDTYPE
TYPE FACE3
p1 AS DWORD
p2 AS DWORD
p3 AS DWORD
vn1 AS DWORD
vn2 AS DWORD
vn3 AS DWORD
vt1 AS DWORD
vt2 AS DWORD
vt3 AS DWORD
ENDTYPE
TYPE TEX2
u AS FLOAT
v AS FLOAT
ENDTYPE
DIM v() AS VERT3
DIM vn() AS VERT3
DIM vt() AS TEX2
DIM f() As FACE3
EMPTY ARRAY v(0)
EMPTY ARRAY vn(0)
EMPTY ARRAY vt(0)
EMPTY ARRAY f(0)
// How to load file
OPEN TO READ objfile, "D:\cube.obj"
IF FILE OPEN(objfile) = 1
WHILE FILE END(objfile) = 0
// Get line from file for parsing
READ STRING objfile, linestr$
// Get what the command is
cmd$ = FIRST TOKEN$(linestr$, " ")
// If command is vertex data, increase vertex list and store data there
IF (COMPARE CASE$(cmd$, "v") = 1)
ARRAY INSERT AT BOTTOM v(0)
v(ARRAY COUNT(v(0))).x = VAL(NEXT TOKEN$(" "))
v(ARRAY COUNT(v(0))).y = VAL(NEXT TOKEN$(" "))
v(ARRAY COUNT(v(0))).z = VAL(NEXT TOKEN$(" "))
ENDIF
// If command is vertex normal data, increase vertex normal list and store data there (like with vertex list)
IF (COMPARE CASE$(cmd$, "vn") = 1)
ARRAY INSERT AT BOTTOM vn(0)
vn(ARRAY COUNT(vn(0))).x = VAL(NEXT TOKEN$(" "))
vn(ARRAY COUNT(vn(0))).y = VAL(NEXT TOKEN$(" "))
vn(ARRAY COUNT(vn(0))).z = VAL(NEXT TOKEN$(" "))
ENDIF
// If command is texture coordinate data, increase texture coordinate list and store data there.
IF (COMPARE CASE$(cmd$, "vt") = 1)
ARRAY INSERT AT BOTTOM vt(0)
vt(ARRAY COUNT(vt(0))).u = VAL(NEXT TOKEN$(" "))
vt(ARRAY COUNT(vt(0))).v = VAL(NEXT TOKEN$(" "))
ENDIF
// If command is face data...
IF (COMPARE CASE$(cmd$, "f") = 1)
ARRAY INSERT AT BOTTOM f(0)
arg1$ = NEXT TOKEN$(" ")
arg2$ = NEXT TOKEN$(" ")
arg3$ = NEXT TOKEN$(" ")
// ...Split up face from normal/texture info (eg. layout: face/texcoord/vertnormal)
f(ARRAY COUNT(f(0))).p1 = INT(VAL(FIRST TOKEN$(arg1$, "/")))
f(ARRAY COUNT(f(0))).vt1 = INT(VAL(NEXT TOKEN$("/")))
f(ARRAY COUNT(f(0))).vn1 = INT(VAL(NEXT TOKEN$("/")))
f(ARRAY COUNT(f(0))).p2 = INT(VAL(FIRST TOKEN$(arg2$, "/")))
f(ARRAY COUNT(f(0))).vt2 = INT(VAL(NEXT TOKEN$("/")))
f(ARRAY COUNT(f(0))).vn2 = INT(VAL(NEXT TOKEN$("/")))
f(ARRAY COUNT(f(0))).p3 = INT(VAL(FIRST TOKEN$(arg3$, "/")))
f(ARRAY COUNT(f(0))).vt3 = INT(VAL(NEXT TOKEN$("/")))
f(ARRAY COUNT(f(0))).vn3 = INT(VAL(NEXT TOKEN$("/")))
ENDIF
ENDWHILE
ENDIF
CLOSE FILE objfile
// Create memblock to use to make mesh. Size is Number of Polys * 3 * 36 + 12.
objmb = 1
mbc = 0
MAKE MEMBLOCK objmb, (ARRAY COUNT(f(0)) + 1) * 3 * 36 + 12 // PolyNum * VertsPerPoly * SizeOf Internal Vertex + SizeOf Header
// Set up header for mesh data
WRITE MEMBLOCK DWORD objmb, mbc, 338 : mbc = mbc + 4
WRITE MEMBLOCK DWORD objmb, mbc, 36 : mbc = mbc + 4
WRITE MEMBLOCK DWORD objmb, mbc, (ARRAY COUNT(f(0)) + 1) * 3 : mbc = mbc + 4
// For each polygon, set up three vertices worth of data in memblock
For i = 0 To ARRAY COUNT(f(0))
// Vertex 1
WRITE MEMBLOCK FLOAT objmb, mbc, v(f(i).p1 - 1).x : mbc = mbc + 4 ` X
WRITE MEMBLOCK FLOAT objmb, mbc, v(f(i).p1 - 1).y : mbc = mbc + 4 ` Y
WRITE MEMBLOCK FLOAT objmb, mbc, v(f(i).p1 - 1).z : mbc = mbc + 4 ` Z
WRITE MEMBLOCK FLOAT objmb, mbc, vn(f(i).vn1 - 1).y : mbc = mbc + 4 ` VN X
WRITE MEMBLOCK FLOAT objmb, mbc, vn(f(i).vn1 - 1).y : mbc = mbc + 4 ` VN Y
WRITE MEMBLOCK FLOAT objmb, mbc, vn(f(i).vn1 - 1).y : mbc = mbc + 4 ` VN Z
WRITE MEMBLOCK DWORD objmb, mbc, 0 : mbc = mbc + 4 ` Diffuse Color
WRITE MEMBLOCK FLOAT objmb, mbc, vt(f(i).vt1 - 1).u : mbc = mbc + 4 // TODO: PUT U COORDINATE HERE
WRITE MEMBLOCK FLOAT objmb, mbc, vt(f(i).vt1 - 1).v : mbc = mbc + 4 // TODO: PUT V COORDINATE HERE
// Vertex 2
WRITE MEMBLOCK FLOAT objmb, mbc, v(f(i).p2 - 1).x : mbc = mbc + 4 ` X
WRITE MEMBLOCK FLOAT objmb, mbc, v(f(i).p2 - 1).y : mbc = mbc + 4 ` Y
WRITE MEMBLOCK FLOAT objmb, mbc, v(f(i).p2 - 1).z : mbc = mbc + 4 ` Z
WRITE MEMBLOCK FLOAT objmb, mbc, vn(f(i).vn2 - 1).y : mbc = mbc + 4 ` VN X
WRITE MEMBLOCK FLOAT objmb, mbc, vn(f(i).vn2 - 1).y : mbc = mbc + 4 ` VN Y
WRITE MEMBLOCK FLOAT objmb, mbc, vn(f(i).vn2 - 1).y : mbc = mbc + 4 ` VN Z
WRITE MEMBLOCK DWORD objmb, mbc, 0 : mbc = mbc + 4 ` Diffuse Color
WRITE MEMBLOCK FLOAT objmb, mbc, vt(f(i).vt2 - 1).u : mbc = mbc + 4 // TODO: PUT U COORDINATE HERE
WRITE MEMBLOCK FLOAT objmb, mbc, vt(f(i).vt2 - 1).v : mbc = mbc + 4 // TODO: PUT V COORDINATE HERE
// Vertex 3
WRITE MEMBLOCK FLOAT objmb, mbc, v(f(i).p3 - 1).x : mbc = mbc + 4 ` X
WRITE MEMBLOCK FLOAT objmb, mbc, v(f(i).p3 - 1).y : mbc = mbc + 4 ` Y
WRITE MEMBLOCK FLOAT objmb, mbc, v(f(i).p3 - 1).z : mbc = mbc + 4 ` Z
WRITE MEMBLOCK FLOAT objmb, mbc, vn(f(i).vn3 - 1).y : mbc = mbc + 4 ` VN X
WRITE MEMBLOCK FLOAT objmb, mbc, vn(f(i).vn3 - 1).y : mbc = mbc + 4 ` VN Y
WRITE MEMBLOCK FLOAT objmb, mbc, vn(f(i).vn3 - 1).y : mbc = mbc + 4 ` VN Z
WRITE MEMBLOCK DWORD objmb, mbc, 0 : mbc = mbc + 4 ` Diffuse Color
WRITE MEMBLOCK FLOAT objmb, mbc, vt(f(i).vt3 - 1).u : mbc = mbc + 4 // TODO: PUT U COORDINATE HERE
WRITE MEMBLOCK FLOAT objmb, mbc, vt(f(i).vt3 - 1).v : mbc = mbc + 4 // TODO: PUT V COORDINATE HERE
NEXT i
// Make mesh and then object
mesh = 1
MAKE MESH FROM MEMBLOCK mesh, objmb
LOAD IMAGE "D:\goldtile.bmp", 1
objx = 0.0
objy = 0.0
objz = 0.0
SET AMBIENT LIGHT 100
MAKE OBJECT 1, mesh, 1
count = TIMER()
DO
POSITION OBJECT 1, objx, objy, objz
IF UPKEY()
IF (TIMER() - count >= 100)
objz = objz + 1
count = TIMER()
ENDIF
ENDIF
IF DOWNKEY()
IF (TIMER() - count >= 100)
objz = objz - 1
count = TIMER()
ENDIF
ENDIF
SYNC
LOOP
I still have to wrap my head around how to work the animations. I looked at that documentation file for .DBOs that comes with the DBPro help, and it's a bit confusing on how the files are set up among other things.
And regarding the WIP... xD Shouldn't mods remove that since you already released it?