No I Don't but - SOMEWHERE in these forums - someone made a Pseudo "Code Snippet" that was LESS about the commands and more about how you go about it. This started me down the road of understanding - but note - it took awhile to get ... well... never mastered .. I'm still learning but it took awhile to get decent with it but I WAS VERY HAPPY I took the time to understand it!
(borrowed from another thread - not my creation)
My knowledge of how to do this is a bit limited, but I'll share with you what I know. This is how you make an FVF 338 memblock mesh. I'm sorry if this is a bit pedestrian, but I don't want to make any assumptions about what anyone who reads this knows.
1. Decide how many tiles you want your mesh to be. When I tried making a mesh larger than 100 x 100, I got some sort of memory error message. I don't know if my system doesn't have enough memory or if there is some limitation, or what. I just use multiple meshes if I need more than 100 x 100 tiles.
2. Determine the number of tiles by multiplying the number of tiles in the X dimension by the number of tiles in the Z dimension.
3. Determine the number of polys by multiplying the number of tiles by 2.
4. Determine the number of vertices by multiplying the number of polys by 3.
5. Determine the memblock size by multiplying the number of vertices by 36 and then adding 12 for header information.
6. Make a memblock of the size determined in step 5.
7. Write the header info as shown:
write memblock dword MemBlockNumber, 0, 338
write memblock dword MemBlockNumber, 4, 36
write memblock dword MemBlockNumber, 8, Number of Vertices
338 is the Flexible Vertex Format of the mesh we're making. 36 is the number of bytes per vertex (more on that later). Number of vertices was determined in step 4.
8. Establish a memory variable for the current memblock byte (MemoryPosition) and initialize the value to 12 - the first byte after the header info.
9. Do a FOR/NEXT loop which will write the following information for each vertex:
write memblock float MemBlockNumber, MemoryPosition, X Position
write memblock float MemBlockNumber, MemoryPosition, Y Position
write memblock float MemBlockNumber, MemoryPosition, Z Position
write memblock float MemBlockNumber, MemoryPosition, X Normal
write memblock float MemBlockNumber, MemoryPosition, Y Normal
write memblock float MemBlockNumber, MemoryPosition, Z Normal
write memblock dword MemBlockNumber, MemoryPosition, Grid Color
write memblock float MemBlockNumber, MemoryPosition, U Coordinate
write memblock float MemBlockNumber, MemoryPosition, V Coordinate
IMPORTANT NOTE: Increment the MemoryPosition variable by 4 after each value is written to the memblock.
The number of iterations of the loop is from 1 to the number of vertices.
The number 36 that has been used before comes from the 9 pieces of information listed times the 4 bytes that each float or dword needs.
10. Make a mesh from the memblock
MAKE MESH FROM MEMBLOCK MeshNumber, MemBlockNumber
11. Make an object from the mesh
MAKE OBJECT FROM MESH MeshNumber, ObjectNumber
Now, like you, I don't know the data layouts for the various FVF formats. But there have been times when I needed FVF 530 meshes which hold two sets of UV data. This is what I do for that:
1. Make an FVF 338 mesh as described above.
2. Convert the mesh to FVF 530:
CONVERT OBJECT FVF ObjectNumber, 530
3. Lock the vertex data.
4. Do a FOR/NEXT loop with the following command:
SET VERTEXDATA UV VertexNumber, TextureStage, U, V
The number of iterations is, once again, the number of vertices.
5. Unlock the vertex data.
Now, getting a second set of UV coordinates may not be what you need. My point is that I got that second set of UV coordinates without knowing the structure of the data for an FVF 530 mesh.
I hope this helps you out.
Another Snippet I took for reference
The following reply was posted by Lost in Thought into Dark GDK to a thread you are watching:
Didn't have time to read all of this so sorry if it has been resolved, but ADR posted the normal calcing code I use on the forums.
[code] null = make vector3(1)
null = make vector3(2)
null = make vector3(3)
` -- calculate the two directional vectors for the adj and opp edges...
`where p1 is vert1, p2 is vert2 and p3 is vert3 of the poly
set vector3 1, P1X#, P1Y#, P1Z#
set vector3 2, P2X#, P2Y#, P2Z#
set vector3 3, P3X#, P3Y#, P3Z#
subtract vector3 2, 2, 1
subtract vector3 3, 3, 1 ` -- vector 3 and 1 are now directional vectors
normalize vector3 2,2 ` -- normalize em
normalize vector3 3,3
cross product vector3 1, 2,3 ` -- use the origin vector (1) to store the face normal
normalize vector3 1,1
`save normals (all 3 verts have same normals)
N1X# = x vector3(1)
N1Y# = y vector3(1)
N1Z# = z vector3(1)
N2X# = N1X#
N2Y# = N1Y#
N2Z# = N1Z#
N3X# = N1X#
N3Y# = N1Y#
N3Z# = N1Z#
null = delete vector3(1)
null = delete vector3(2)
null = delete vector3(3)
And then you can use set object smoothing if you want the normals to be more even. Of course you would not create and delete the 3 vectors for each poly. For some reason creating and deleting vectors is quite slow. I just create all the ones I will be needing at the top of my code and delete them at the very end.
Also about the Frustum port ... alot of that was added due to DBP being wicked slow at alot of stuff. You may be able to do away with alot of it fo the DGDK without much notice in speed.
[/code]
FVF - Evolved
null = make vector3(1)
null = make vector3(2)
null = make vector3(3)
` -- calculate the two directional vectors for the adj and opp edges...
`where p1 is vert1, p2 is vert2 and p3 is vert3 of the poly
set vector3 1, P1X#, P1Y#, P1Z#
set vector3 2, P2X#, P2Y#, P2Z#
set vector3 3, P3X#, P3Y#, P3Z#
subtract vector3 2, 2, 1
subtract vector3 3, 3, 1 ` -- vector 3 and 1 are now directional vectors
normalize vector3 2,2 ` -- normalize em
normalize vector3 3,3
cross product vector3 1, 2,3 ` -- use the origin vector (1) to store the face normal
normalize vector3 1,1
`save normals (all 3 verts have same normals)
N1X# = x vector3(1)
N1Y# = y vector3(1)
N1Z# = z vector3(1)
N2X# = N1X#
N2Y# = N1Y#
N2Z# = N1Z#
N3X# = N1X#
N3Y# = N1Y#
N3Z# = N1Z#
null = delete vector3(1)
null = delete vector3(2)
null = delete vector3(3)[/code]
And then you can use set object smoothing if you want the normals to be more even. Of course you would not create and delete the 3 vectors for each poly. For some reason creating and deleting vectors is quite slow. I just create all the ones I will be needing at the top of my code and delete them at the very end.
Also about the Frustum port ... alot of that was added due to DBP being wicked slow at alot of stuff. You may be able to do away with alot of it fo the DGDK without much notice in speed.
Welding Verts - Visigoth
remstart
> fist take a look at DX fvf list <
Flexible vertex format list:
FVF_xyz 0x002 : SIZE ( <x>4 + <y>4 + <z>4 ) = 12
FVF_NORMAL 0x010 : SIZE ( <x>4 + <y>4 + <z>4 ) = 12
FVF_DIFFUSE 0x040 : SIZE ( <r>4 + <g>4 + <b>4 + <a>4 ) = 16
FVF_SPECULAR 0x080 : SIZE ( <r>4 + <g>4 + <b>4 + <a>4 ) = 16
FVF_tex0 0x000 : SIZE ( <u>4 + <v>4 ) = 8
FVF_tex1 0x100 : SIZE ( <u>4 + <v>4 ) = 8
FVF_tex2 0x200 : SIZE ( <u>4 + <v>4 ) = 8
FVF_tex3 0x300 : SIZE ( <u>4 + <v>4 ) = 8
FVF_tex4 0x400 : SIZE ( <u>4 + <v>4 ) = 8
FVF_tex5 0x500 : SIZE ( <u>4 + <v>4 ) = 8
FVF_tex6 0x600 : SIZE ( <u>4 + <v>4 ) = 8
FVF_tex7 0x700 : SIZE ( <u>4 + <v>4 ) = 8
FVF_tex8 0x800 : SIZE ( <u>4 + <v>4 ) = 8
as you can see evey index in the formats are 4 bytes large,
so UV has 2 positions so that totals out 4+4=8 and vertex
xyz position is 4+4+4 = 12.
>default FVF DBP memblock of a box<
<vertex format used>
FVF_xyz
FVF_NORMAL
FVF_tex0
<FVF byte size>
FVF=( FVF_xyz || FVF_NORMAL || FVF_tex0 )
This FVF byte is = 274
<vertex size>
Vertex_Size = 12 + 12 + 8
( 12[xyz] + 12[Nxyz] + 8[uv] )=32 which is the defalt vertex byte size
<Vertex count>
Vertexes=36
usual vertex count of a box is 36 ( 12[polys] * 3[vertex per poly] )
<Memblock size>
Memblock_size=(Vertexes*Vertex_Size) + 12
( head size is usualy always 12 bytes (4[FVF byte] + 4[Vertex Size] 4[Vertex count] )
<Makeing mesh Memblock>
Make Memblock 1,Memblock_size
Write Memblock Dword 1,0,FVF ` vertex format
Write Memblock Dword 1,4,Vertex_Size ` Vertex Size
Write Memblock Dword 1,8,Vertexes ` Vertex count
<looping through vertexes>
for v=0 to Vertexes-1
<memblock position data>
(memblock num,
<start off from head size[12]> ( (
<Vertex Size[32]> * (
<vertex num> - 1 ) ) +
<move position> ))
<Vertex position>
Position=12
(head size[12])
vx#=memblock float(1, Position + ( Vertex_Size* v ) +0 )
vy#=memblock float(1, Position + ( Vertex_Size* v ) +4 )
vz#=memblock float(1, Position + ( Vertex_Size* v ) +8 )
<Normals>
Position=12+12
(head size[12] + vertex xyz size[12])
vx#=memblock float(1, Position + ( Vertex_Size* v ) +0 )
vy#=memblock float(1, Position + ( Vertex_Size* v ) +4 )
vz#=memblock float(1, Position + ( Vertex_Size* v ) +8 )
<UV>
Position=12+12+12
(head size[12] + vertex xyz size[12] + normal xyz size[12])
vx#=memblock float(1, Position + ( Vertex_Size* v ) +0 )
vy#=memblock float(1, Position + ( Vertex_Size* v ) +4 )
next v
>Custom FVF DBP memblock of a box<
were just going to add 2 texcoords (texture stage 0 and 1 ) to the memblock.
this is usefull for the blend mapping commands as you can set the uv data of
the texture stages for lightmapping and stuff !! .
<Flexible vertex format used>
FVF_xyz
FVF_NORMAL
FVF_tex2
<FVF byte size>
FVF=( FVF_xyz || FVF_NORMAL || FVF_tex2 )
<vertex size>
Vertex_Size = 12 + 12 + 8 + 8
( 12[xyz] + 12[Nxyz] + 8[uv0] + 8[uv1] ) = 40
<Vertex count>
Vertexes=36
<Memblock size>
Memblock_size=(Vertexes*Vertex_Size) + 12
<Makeing mesh Memblock>
Make Memblock 1,Memblock_size
Write Memblock Dword 1,0,FVF
Write Memblock Dword 1,4,Vertex_Size
Write Memblock Dword 1,8,Vertexes
<looping through vertexes>
for v=0 to Vertexes-1
<Vertex position>
Position=12
(head size[12])
vx#=memblock float(1, Position + ( Vertex_Size* v ) +0 )
vy#=memblock float(1, Position + ( Vertex_Size* v ) +4 )
vz#=memblock float(1, Position + ( Vertex_Size* v ) +8 )
<Normals>
Position=12+12
(head size[12] + vertex xyz size[12])
vx#=memblock float(1, Position + ( Vertex_Size* v ) +0 )
vy#=memblock float(1, Position + ( Vertex_Size* v ) +4 )
vz#=memblock float(1, Position + ( Vertex_Size* v ) +8 )
<UV stage 1>
Position=12+12+12
(head size[12] + vertex xyz size[12] + normal xyz size[12])
vx#=memblock float(1, Position + ( Vertex_Size* v ) +0 )
vy#=memblock float(1, Position + ( Vertex_Size* v ) +4 )
<UV stage 2>
Position=12+12+12+8
(head size[12] + vertex xyz size[12] + normal xyz size[12] + UV stage 1[8] )
vx#=memblock float(1, Position + ( Vertex_Size* v ) +0 )
vy#=memblock float(1, Position + ( Vertex_Size* v ) +4 )
next v
remend
````````````````````````````````````````````````````````
` DEMO
````````````````````````````````````````````````````````
`set up
sync on
sync rate 60
`make object box + mesh and defalt memblock
make object box 1,100,100,100
make mesh from object 1,1
make memblock from mesh 1,1
delete mesh 1
delete object 1
`memblock mesh data
#Constant FVF_xyz 0x002
#Constant FVF_NORMAL 0x010
#Constant FVF_tex2 0x200
FVF=( FVF_xyz || FVF_NORMAL || FVF_tex2)
Vertex_Size = 12+12+8+8
Vertexes = Memblock Dword(1,8)
Memblock_size = (Vertexes*Vertex_Size) + 12
`make new memblock
Make Memblock 2,Memblock_size
Write Memblock Dword 2,0,FVF
Write Memblock Dword 2,4,Vertex_Size
Write Memblock Dword 2,8,Vertexes
`loop through vertexes
for v=0 to Vertexes-1
`Vertex position in defalt memblock
Position=12
vx#=memblock float(1, Position + ( 32 * v ) + 0 )
vy#=memblock float(1, Position + ( 32 * v ) + 4 )
vz#=memblock float(1, Position + ( 32 * v ) + 8 )
`add vertex position to new memblock
Position=12
write memblock float 2, Position + (Vertex_Size * v ) +0 ,vx#
write memblock float 2, Position + (Vertex_Size * v ) +4 ,vy#
write memblock float 2, Position + (Vertex_Size * v ) +8 ,vz#
`Vertex normals in defalt memblock
Position=12+12
nx#=memblock float(1, Position + ( 32 * v ) + 0 )
ny#=memblock float(1, Position + ( 32 * v ) + 4 )
nz#=memblock float(1, Position + ( 32 * v ) + 8 )
`add vertex normals to new memblock
Position=12+12
write memblock float 2, Position + (Vertex_Size * v ) +0 ,nx#
write memblock float 2, Position + (Vertex_Size * v ) +4 ,ny#
write memblock float 2, Position + (Vertex_Size * v ) +8 ,nz#
`Vertex uv data in defalt memblock
Position=12+12+12
u#=memblock float(1, Position + ( 32 * v ) + 0 )
v#=memblock float(1, Position + ( 32 * v ) + 4 )
`add vertex uv data[0] to new memblock
Position=12+12+12
write memblock float 2, Position + (Vertex_Size * v ) +0 ,u#
write memblock float 2, Position + (Vertex_Size * v ) +4 ,v#
`add vertex uv data[1] to new memblock dobble the uv scale
Position=12+12+12+8
write memblock float 2, Position + (Vertex_Size * v ) +0 ,u# * 2
write memblock float 2, Position + (Vertex_Size * v ) +4 ,v# * 2
`next vertex
next v
`re-make object with new fvf data
make mesh from memblock 1,2
make object 1,1,0
delete mesh 1
`delet memblocks
delete memblock 1
delete memblock 2
`apply belnd mapping to show uv tex changes
load image "t1.bmp", 1
load image "t2.bmp", 2
texture object 1,1
SET BLEND MAPPING ON 1 , 1 , 2 , 0 , 5
`position camera
position camera 0,0,-150
point camera 0,0,0
`start loop
do
`rotate object
rotate object 1,object angle x(1)+0.5,object angle y(1)+0.5,object angle z(1)+0.5
`end loop
sync
loop
(Welding verts I only understand why its beneficial - and the concept - I never dug into the code enough to understand the "process" of making them out of an uwelded mesh.
Hope this is helpful
Jason
` This code was downloaded from The Game Creators
` It is reproduced here with full permission
` http://www.thegamecreators.com
REM Created by Mike Shihrer aka Visigoth
REM free to use,modify,etc have fun
function weld_vertices(id as integer,texturemode as integer)
remstart
rem put this at the top of your code
type vdata
x1 as float
y1 as float
z1 as float
u as integer
v as integer
index as integer
index2 as integer
x2 as float
y2 as float
z2 as float
match as boolean
endtype
Global Dim copyv(1) as vdata
remend
rem a_time# = timer()
undim copyv()
numVerts = 0
vc = 0
rem create a mesh from an object
make mesh from object 1,id
rem save it to an .x file, so you can see the differences. This is not necessary, and can be deleted.
save mesh "beforeweld_obj"+str$(id)+".x",1
delete object id
lock vertexdata for mesh 1
rem get the total number of indexes (polys) and total number of vertexs
vi = get vertexdata index count()
vc = get vertexdata vertex count()
rem create our type array
Global Dim copyv(vi) as vdata
rem copy vertex data into type array
for i = 1 to vi
copyv(i).index = get indexdata(i -1)
copyv(i).x1 = get vertexdata position x(copyv(i).index)
copyv(i).y1 = get vertexdata position y(copyv(i).index)
copyv(i).z1 = get vertexdata position z(copyv(i).index)
copyv(i).index2 = 0
copyv(i).x2 = 0
copyv(i).y2 = 0
copyv(i).z2 = 0
next vi
rem look for duplicate vertices, and flag them this took 4.4 seconds on 3200 polys this is the slow part
for i = 1 to vi
if copyv(i).match = 0 rem this fixed the slowness a bunch, only check the list if not already marked a match
for j = i + 1 to vi
if copyv(i).x1 = copyv(j).x1 and copyv(i).y1 = copyv(j).y1 and copyv(i).z1 = copyv(j).z1
copyv(j).match = 1
endif
next j
endif
next i
rem get the total count of unique vertices, copy them into type array
for i = 1 to vi
If copyv(i).match = 0
copyv(numVerts + 1).x2 = copyv(i).x1
copyv(numVerts + 1).y2 = copyv(i).y1
copyv(numVerts + 1).z2 = copyv(i).z1
copyv(numVerts + 1).index2 = numVerts rem remove this?
inc numVerts,1
endif
next i
rem compare the unique verts to the original verts, and write the index data to the type array
rem I changed this to preload the x,y.z values into a variable so the code doesn't have to look backwards into the type everytime it compares.
rem this saved about a half second
for i = 1 to numVerts
x2# = copyv(i).x2
y2# = copyv(i).y2
z2# = copyv(i).z2
i2 = copyv(i).index2
for j = i to vi
if copyv(j).x1 = x2# and copyv(j).y1 = y2# and copyv(j).z1 = z2#
copyv(j).index = i2
endif
next j
next i
rem resize the vertexdata to allow for only unique vertices
delete mesh from vertexdata numVerts,vc,0,0
rem write the vertices to the vertexdata
for i = 1 to numverts
set vertexdata position (i - 1),copyv(i).x2,copyv(i).y2,copyv(i).z2
next i
rem and finally, update the indexdata so faces draw the same
for i = 1 to vi
set indexdata (i - 1),copyv(i).index
next i
rem set uv coordinates to stretch across object
rem should probably break this down into its own function for different kinds of objects, like mode 0 for my grid, 1 for DBPro cubes, 2 for DBPro box, etc
unlock vertexdata
make object id,1,0
save mesh "afterweld_obj"+str$(id)+".x",1
delete mesh 1
If texturemode = 1
u# = object size x(id)
v# = object size z(id)
make mesh from object 1,id
delete object id
lock vertexdata for mesh 1
rem loop throught the texture coordinates and determine what percent of total width, height the vertex is at
for i = 0 to numverts - 1
set vertexdata uv i, get vertexdata position x(i) / u#, v# - (get vertexdata position z(i) / v#)
next i
unlock vertexdata
make object id,1,0
save mesh "afterweld_obj"+str$(id)+".x",1
delete mesh 1
endif
rem create normals data for vertices
set object normals id
undim copyv()
rem b_time# = timer()
rem tw_time# = (b_time# - a_time#) * .001
endfunction