Hey, I spent a while trying to port the matrix in a memblock code from the codebase to c++ for darksdk because it seemed that after writing a few extra functions for it it would be perfect.
I ported it over and it compiles grand and none of the functions cause an error, but trying to make a mesh from the resulting memblock blew up darksdk quite well.
I took a deeper look at his creation function (rather than the staring into space i've-been-doing-this-for-hours look i was using when porting the code) and I realised that it was no mesh format that I knew, didnt even write an FVF in the header. I figured that was why it was blowing up so i started working on a function to convert his memblock data to a standard FVF 338 format and make a mesh from it.
I've had several different versions of that function now and they all blow up when i try and make a mesh from it - unhandled exception, access violation. The line of the stack it halts on is: 0043DAD7 rep movs dword ptr [edi],dword ptr [esi]
which is just under: ?MakeLocalMeshFromPureMeshData@@YA_NPAUsMesh@@KKPAMKK@Z:
Anyway, i'll post my converting function and also my port of his function to make the original memblock so you can see the format he uses and how im trying to convert it. If anyone can find the error that makes it blow when converting to a mesh i would be very appreiciative
If its still there when whoever looks at this you can see both functions in syntax highlighted glory here:
http://pastebin.com/380163 but i dunno how long before it times out and disapears.
If its gone, my function:
///////////////////////////////////////////////////////
// Function to create a legitimate memblock compatiable
// with dbp's/darksdk's dbMakeMeshFromMemblock command.
// Original didnt write the FVF or comform to any
// format i know.
// -Dave
///////////////////////////////////////////////////////
void CreateCompatiableMesh(int memNum, int MeshID) {
if (!dbMemblockExist(memNum))
return;
//Nessiary offsets for dealing with his weird format...
int TilesX = dbMemblockDWORD(255, memNum * 16);
int TilesZ = dbMemblockDWORD(255, (memNum * 16) + 4);
int vertNum = TilesX * TilesZ * 4;
int faceNum = (TilesX * TilesZ) * 2;
int vertOffset = 32;
int normNum = vertNum;
int normOffset = 32 + (vertNum * 12);
int UVOffset = 32 + (vertNum * 12) + (normNum * 12) + (faceNum * 28);
//New header for the new mesh we will make. Standard FVF 338 format.
int FVF = 338;
int FVFSize = 36;
int NumVerts = dbMemblockDWORD(memNum, 0);
//Memblock we will build our mesh in
dbMakeMemblock(253, 4 + 4 + 4 + (NumVerts * FVFSize));
//Write the mesh header
dbWriteMemblockDWORD(253, 0, FVF);
dbWriteMemblockDWORD(253, 4, FVFSize);
dbWriteMemblockDWORD(253, 8, NumVerts);
//now mesh data
for (int n = 0; n < NumVerts; n++) {
//Vertex Position
dbWriteMemblockFloat(253, 12 + (n * FVFSize), dbMemblockFloat(memNum, vertOffset + (n * 12)));
dbWriteMemblockFloat(253, 12 + (n * FVFSize) + 4, dbMemblockFloat(memNum, vertOffset + (n * 12) + 4));
dbWriteMemblockFloat(253, 12 + (n * FVFSize) + 8, dbMemblockFloat(memNum, vertOffset + (n * 12) + 8));
//Normals
dbWriteMemblockFloat(253, 12 + (n * FVFSize) + 12, dbMemblockFloat(memNum, normOffset + (n * 12)));
dbWriteMemblockFloat(253, 12 + (n * FVFSize) + 16, dbMemblockFloat(memNum, normOffset + (n * 12) + 4));
dbWriteMemblockFloat(253, 12 + (n * FVFSize) + 20, dbMemblockFloat(memNum, normOffset + (n * 12) + 8));
//Diffuse for the mesh, not stored by Kelebrindae's memblock so just set a colour of any type
dbWriteMemblockDWORD(253, 12 + (n * FVFSize) + 24, dbRgb(255, 0, 0));
//U/V Coordinates
dbWriteMemblockFloat(253, 12 + (n * FVFSize) + 28, dbMemblockFloat(memNum, UVOffset + (n * 8)));
dbWriteMemblockFloat(253, 12 + (n * FVFSize) + 32, dbMemblockFloat(memNum, UVOffset + (n * 8) + 4));
}
//make a mesh from the memblock (CRASH!)
dbMakeMeshFromMemblock(MeshID, memNum);
}
and his (ported):
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Build a memblock containing the mesh of a "matrix-like" object.
// This mesh will be [width#] by [depth#], divided in a grid of [TilesX] by [TilesZ] squares.
// Each square has 4 vertices, so the mesh will contain [TilesX] * [TilesZ] * 4 vertices, numeroted from 0 to [Nb verteces - 1].
// This means that a 2x2 grid will have 16 verteces, like shown here:
// 09--10 13--14
// | | |
// 08__11 12__15
// 01 02 05 06
// | | |
// 00--03 04--07
// The mesh's pivot (0,0,0 coordinates) is located on vertex n°0 (in the "lower-left" corner).
// The UV coords 0,0 are located on the "upper left" corner of the matrix (in the 3x3 matrix, on vertex n°12).
// It is so because the Y axis in images is "inverted" (pixel 0,0 is in the upper left corner of the bitmap).
// So, to avoid a "vertical mirror" effect on the texture, I had to invert the V axis of UVmapping...
// Matrix number of tiles and dimensions are stored in memblock 255 for fast and easy access.
// Parameters:
// Memblock number, matrix width (pixels), matrix depth (pixels)
/////////////////////////////////////////////////////////////////////////////////////////////////////
void makeMemMatrix(int memNum, float width, float depth, int TilesX, int TilesZ) {
if (dbMemblockExist(memNum) == 1)
return;
// If memblock n°255 doesn't exist yet, create it.
if (dbMemblockExist(255) == 0) {
dbMakeMemblock(255, (memNum+1) * 16);
} else {
// If it exists but is too small, copy its content, delete and re-create it, then copy its datas back
int size = dbGetMemblockSize(255);
if (size < (memNum + 1) * 16) {
dbMakeMemblock(254, size);
dbCopyMemblock(255, 254, 0, 0, size);
dbDeleteMemblock(255);
dbMakeMemblock(255, (memNum+1)*16);
dbCopyMemblock(254, 255, 0, 0, size);
}
}
// Compute offsets and datas sizes
int vertNum = TilesX * TilesZ * 4;
int faceNum = (TilesX * TilesZ) * 2;
int vertOffset = 32;
int normNum = vertNum;
int normOffset = 32 + (vertNum * 12);
int faceOffset = 32 + (vertNum * 12) + (normNum * 12);
int faceSize = 7 * faceNum; //: // this size is in "Dwords", not in "Bytes"! (1 Dword = 4 bytes)
int UVOffset = 32 + (vertNum * 12) + (normNum * 12) + (faceNum * 28);
// Create memblock
int memSize = 32 + (12*vertNum) + (12*normNum) + (28*faceNum) + (8*vertNum);
dbMakeMemblock(memNum, memSize);
// Write mesh header
dbWriteMemblockDWORD(memNum, 0, vertNum);
dbWriteMemblockDWORD(memNum, 4, vertOffset);
dbWriteMemblockDWORD(memNum, 8, normNum);
dbWriteMemblockDWORD(memNum, 12, normOffset);
dbWriteMemblockDWORD(memNum, 16, faceNum);
dbWriteMemblockDWORD(memNum, 20, faceOffset);
dbWriteMemblockDWORD(memNum, 24, faceSize);
dbWriteMemblockDWORD(memNum, 28, UVOffset);
// Size of matrix tile, Size of UV tile
float tileWidth = width / (TilesX * 1.0f);
float tileDepth = depth / (TilesZ * 1.0f);
float UVtileWidth = 1.00f / (TilesX * 1.0f);
float UVtileDepth = 1.00f / (TilesZ * 1.0f);
// Store number of tiles and tiles size in memblock 255
dbWriteMemblockDWORD(255, memNum * 16, TilesX);
dbWriteMemblockDWORD(255, (memNum * 16) + 4, TilesZ);
dbWriteMemblockFloat(255, (memNum * 16) + 8, tileWidth);
dbWriteMemblockFloat(255, (memNum * 16) + 12, tileDepth);
// Create 4 vertex and 2 faces by tile
int vertCtr = 0;
int faceCtr = 0;
for (int cz = 0; cz <= TilesZ-1; cz++) {
for (int cx = 0; cx <= TilesX-1; cx++) {
// Vertex 0 coords
dbWriteMemblockFloat(memNum, vertOffset + (vertCtr * 12), cx * tileWidth);
dbWriteMemblockFloat(memNum, vertOffset + (vertCtr * 12) + 4, 0.00f);
dbWriteMemblockFloat(memNum, vertOffset + (vertCtr * 12) + 8, cz * tileDepth);
// Normals infos
dbWriteMemblockFloat(memNum, normOffset + (vertCtr * 12), 0.0f);
dbWriteMemblockFloat(memNum, normOffset + (vertCtr * 12) + 4, 1.00f);
dbWriteMemblockFloat(memNum, normOffset + (vertCtr * 12) + 8, 0.0f);
// UV coords
dbWriteMemblockFloat(memNum, UVOffset + (vertCtr * 8), cx * UVtileWidth);
dbWriteMemblockFloat(memNum, UVOffset + (vertCtr * 8) + 4, 1.00f - (cz * UVtileDepth));
// Store vertex number and go on
int v0 = vertCtr;
vertCtr++;
// Vertex 1 coords
dbWriteMemblockFloat(memNum, vertOffset + (vertCtr * 12), cx * tileWidth);
dbWriteMemblockFloat(memNum, vertOffset + (vertCtr * 12) + 4, 0.00f);
dbWriteMemblockFloat(memNum, vertOffset + (vertCtr * 12) + 8, (cz + 1) * tileDepth);
// Normals infos
dbWriteMemblockFloat(memNum, normOffset + (vertCtr * 12), 0.0f);
dbWriteMemblockFloat(memNum, normOffset + (vertCtr * 12) + 4, 1.00f);
dbWriteMemblockFloat(memNum, normOffset + (vertCtr * 12) + 8, 0.0f);
// UV coords
dbWriteMemblockFloat(memNum, UVOffset + (vertCtr * 8), cx * UVtileWidth);
dbWriteMemblockFloat(memNum, UVOffset + (vertCtr * 8) + 4, 1.00f - ((cz + 1) * UVtileDepth));
// Store vertex number and go on
int v1 = vertCtr;
vertCtr++;
// Vertex 2 coords
dbWriteMemblockFloat(memNum, vertOffset + (vertCtr * 12), (cx + 1) * tileWidth);
dbWriteMemblockFloat(memNum, vertOffset + (vertCtr * 12) + 4, 0.00f);
dbWriteMemblockFloat(memNum, vertOffset + (vertCtr * 12) + 8, (cz + 1) * tileDepth);
// Normals infos
dbWriteMemblockFloat(memNum, normOffset + (vertCtr * 12), 0.0f);
dbWriteMemblockFloat(memNum, normOffset + (vertCtr * 12) + 4, 1.00f);
dbWriteMemblockFloat(memNum, normOffset + (vertCtr * 12) + 8, 0.0f);
// UV coords
dbWriteMemblockFloat(memNum, UVOffset + (vertCtr * 8), (cx + 1) * UVtileWidth);
dbWriteMemblockFloat(memNum, UVOffset + (vertCtr * 8) + 4, 1.00f - ((cz + 1) * UVtileDepth));
// Store vertex number and go on
int v2 = vertCtr;
vertCtr++;
// Vertex 3 coords
dbWriteMemblockFloat(memNum, vertOffset + (vertCtr * 12), (cx + 1) * tileWidth);
dbWriteMemblockFloat(memNum, vertOffset + (vertCtr * 12) + 4, 0.00f);
dbWriteMemblockFloat(memNum, vertOffset + (vertCtr * 12) + 8, cz * tileDepth);
// Normals infos
dbWriteMemblockFloat(memNum, normOffset + (vertCtr * 12), 0.0f);
dbWriteMemblockFloat(memNum, normOffset + (vertCtr * 12) + 4, 1.00f);
dbWriteMemblockFloat(memNum, normOffset + (vertCtr * 12) + 8, 0.0f);
// UV coords
dbWriteMemblockFloat(memNum, UVOffset + (vertCtr * 8), (cx + 1) * UVtileWidth);
dbWriteMemblockFloat(memNum, UVOffset + (vertCtr * 8) + 4, 1.00f - (cz * UVtileDepth));
// Store vertex number and go on
int v3 = vertCtr;
vertCtr++;
// First triangle of tile
dbWriteMemblockDWORD(memNum, faceOffset + (faceCtr * 28), 3);
dbWriteMemblockDWORD(memNum, faceOffset + (faceCtr * 28) + 4, v1);
dbWriteMemblockDWORD(memNum, faceOffset + (faceCtr * 28) + 8, v1);
dbWriteMemblockDWORD(memNum, faceOffset + (faceCtr * 28) + 12, v2);
dbWriteMemblockDWORD(memNum, faceOffset + (faceCtr * 28) + 16, v2);
dbWriteMemblockDWORD(memNum, faceOffset + (faceCtr * 28) + 20, v0);
dbWriteMemblockDWORD(memNum, faceOffset + (faceCtr * 28) + 24, v0);
faceCtr++;
// Second triangle
dbWriteMemblockDWORD(memNum, faceOffset + (faceCtr * 28), 3);
dbWriteMemblockDWORD(memNum, faceOffset + (faceCtr * 28) + 4, v3);
dbWriteMemblockDWORD(memNum, faceOffset + (faceCtr * 28) + 8, v3);
dbWriteMemblockDWORD(memNum, faceOffset + (faceCtr * 28) + 12, v0);
dbWriteMemblockDWORD(memNum, faceOffset + (faceCtr * 28) + 16, v0);
dbWriteMemblockDWORD(memNum, faceOffset + (faceCtr * 28) + 20, v2);
dbWriteMemblockDWORD(memNum, faceOffset + (faceCtr * 28) + 24, v2);
faceCtr++;
}
}
}
im stumped, and annoyed :/