;October 22- Decided to recode object manager functions (again) this time implementing Heap-based memory
; - Support Macros were added for creating, growing and destroying HEAPS.
; - SkinMesh Heap is being created and destroyed in Main procedure,
; created before the window is created, and destroyed when we return from the MessagePump loop.
; - We also create/destroy a heap for storing all Strings in Main procedure.
; - LinkedList functions "SetName", "KillName" and "SafeRelease_LL" were modified for Heap memory
;October 23- LinkedList functions "LinkedLists_Append", "AppendSibling", "FindEntryByName" were modified for Heap memory
; - also "SafeRelease_PlayerObject" , "Object_LoadMeshFromXFile" , "SafeRelease_TexObject"
; - also "SafeRelease_ObjectLL"
; - also "AnimationNode_Load , _Destroy , _FindBone , _SetTime" and lots more (I'm tired!)
;October 26- Have now modified most every function in the project bar one or two. Compiles!!
; - Unfortunately, I had a hdd issue today, and had to overinstall my os, so I don't have dx8 installed atm and cannot test it lol
; - Support Macros were added for creating, growing and destroying HEAPS.
; - SkinMesh Heap is being created and destroyed in Main procedure,
; created before the window is created, and destroyed when we return from the MessagePump loop.
; - We also create/destroy a heap for storing all Strings in Main procedure.
; - LinkedList functions "SetName", "KillName" and "SafeRelease_LL" were modified for Heap memory
;October 23- LinkedList functions "LinkedLists_Append", "AppendSibling", "FindEntryByName" were modified for Heap memory
; - also "SafeRelease_PlayerObject" , "Object_LoadMeshFromXFile" , "SafeRelease_TexObject"
; - also "SafeRelease_ObjectLL"
; - also "AnimationNode_Load , _Destroy , _FindBone , _SetTime" and lots more (I'm tired!)
;October 26- Have now modified most every function in the project bar one or two. Compiles!!
; - Unfortunately, I had a hdd issue today, and had to overinstall my os, so I don't have dx8 installed atm and cannot test it lol
I have completed implementing Heap-based memory and am ready to share the project source complete as it stands. We are back were we were before. The source still requires some debugging in the final moments but is looking good.
Here we go :)
(multiple zips)
Here we go :)
(multiple zips)
Debug module
file contents of Include folder (doesnt include subfolders)
*note* this aint the masm Include folder, its the Project's own..
*note* this aint the masm Include folder, its the Project's own..
Object Management module
SkinMesh Module
Terrain Module (not implemented but nonetheless...)
Macros Module
AudioEngine Module (not implemented but anyways..)
Camera Module
Let me know if I forgot anything or if you find you have missing dependancies etc :)
Changes made to a couple of functions (AppendSibling and FindEntryByName I think were the only ones), and all is well.
Basically the Animations Loader is also 100% completed, I get a bugfree and complete load. The application crashes on exit, due to I haven't cleanup up the lower object destructors yet, but I'll do that shortly.
In the meantime, I'll try to implement a static SkinMesh_Render function and then I'll post a complete update.
Basically the Animations Loader is also 100% completed, I get a bugfree and complete load. The application crashes on exit, due to I haven't cleanup up the lower object destructors yet, but I'll do that shortly.
In the meantime, I'll try to implement a static SkinMesh_Render function and then I'll post a complete update.
In case you are wondering what all the non skinmesh-related implemented code is about, we are querying the display modes of the hardware and listing them, we have a cheap multi-tiered menu system, we have a "Loading" screen consisting of a colorkeyed textured quad being rotated around Z (I use an image of a cd with the background colorkeyed, all you see is the spinning cd), and Scronty's Fighter.x flying about, theres other stuff but its currently disabled to aid debugging.
Implemented the Update and Render functions for SkinMesh module...
As far as I can see atm Update is performing admirably - which is less than I can say for the Render function :tongue: My next move will be to add some single-instance debug code to Render so I can figure out what it's beef is...
As far as I can see atm Update is performing admirably - which is less than I can say for the Render function :tongue: My next move will be to add some single-instance debug code to Render so I can figure out what it's beef is...
Here is the CPP version of the MeshNode_Render function, and following it is my MASM version of the same, which is not behaving !!
Please find a moment to examine it for obvious errors - I've been staring at this source for far too long and am probably overlooking something simple.
void CMeshNode::Render( LPDIRECT3DDEVICE8 pd3ddevice )
{
UINT ipattr;
// check if we have a skin mesh or a normal mesh
if (pD3DXSkinMesh)
{
// draw the skin mesh
// draw using non indexed blending
// assuming that the hardware can support the number of matrices
// get the bone combinations
LPD3DXBONECOMBINATION abonecombination;
abonecombination = (LPD3DXBONECOMBINATION)pBoneCombinationBuf->GetBufferPointer();
// enable vertex blending
pd3ddevice->SetRenderState( D3DRS_VERTEXBLEND, dwMaxFaceInfl - 1 );
for( ipattr = 0; ipattr < dwAttrCount; ipattr++ )
{
// set the matrices for this attribute range
for( DWORD i = 0; i < dwMaxFaceInfl; ++i )
{
DWORD matid = abonecombination.BoneId;
if( matid != UINT_MAX && (ipattr == 0 || matid != abonecombination.BoneId))
{
pd3ddevice->SetTransform( D3DTS_WORLDMATRIX(i), apBoneMatrix );
pd3ddevice->MultiplyTransform( D3DTS_WORLDMATRIX(i), &aBoneOffsetMatrix);
}
}
// check if the material is different than that of the previous attribute
if( ipattr == 0 || (abonecombination.AttribId != abonecombination.AttribId))
{
// set the new material
pd3ddevice->SetMaterial( &(aMaterial.AttribId]) );
pd3ddevice->SetTexture( 0, apD3DTexture.AttribId] );
}
// render
pD3DXBlendedMesh->DrawSubset( ipattr );
}
// rendering is finished, set the vertex blending back to disabled mode
pd3ddevice->SetRenderState( D3DRS_VERTEXBLEND, 0 );
}
else // pD3DSkinMesh
{
// we don't have a skin mesh, so draw the normal mesh
for( ipattr = 0; ipattr < dwAttrCount; ipattr++ )
{
pd3ddevice->SetMaterial( &(aMaterial) );
pd3ddevice->SetTexture( 0, apD3DTexture );
pD3DXBlendedMesh->DrawSubset( ipattr );
}
}
}
and my version...
;=================================================================================
MeshNode_Render PROC pThis:LPMESHNODE
;=================================================================================
local NumAttributes:DWORD
local ipattr:DWORD ;Counter for "current Attribute"
local attrid:DWORD ;Holds "Attribute ID" for current Attribute
local matid:DWORD ;Holds "Matrix ID" for current Attribute
local abonecombination:DWORD ;Holds pointer to an array of BoneCombination structs
local pMaterials:DWORD ;Holds pointer to array of Materials (we allocated when we loaded the mesh)
local pTextures:DWORD ;Holds pointer to array of pTextures (we allocatde when we loaded the mesh)
local ErrBuf[256]:BYTE ;Not being used
;=================================================================================
assume esi:nothing
.if pThis==NULL
mov OkToRender,FALSE
Errr CTXT("MORON tried to Render NULL MeshNode")
.endif
push esi
mov esi,pThis
assume esi:LPMESHNODE
;=================================================================================
;Check if we have a skin mesh or a normal mesh, based on whether we Generated the mesh
;=================================================================================
.if .pD3DXBlendedMesh!=0 && .pBoneCombinationBuf!=0
m2m NumAttributes,.dwAttrCount ;Fetch some values into Locals
m2m pMaterials, .pMeshMaterials
m2m pTextures, .pMeshTextures
mov abonecombination , $mcall (.pBoneCombinationBuf,ID3DXBuffer_GetBufferPointer)
; // enable vertex blending
mov eax,.dwMaxFaceInfluence
dec eax
mcall ,IDirect3DDevice8_SetRenderState, D3DRS_VERTEXBLEND, eax
; LOOP FOR ALL SUBSETS IN THE SKIN MESH
xor ecx,ecx
mov ipattr,ecx
.while ecx<NumAttributes ; for ipattr = 0; ipattr < dwAttrCount; ipattr++
; Set the matrices for this attribute range
; LOOP FOR ALL INFLUENCES
xor ecx,ecx
.while ecx<.dwMaxFaceInfluence ;for i = 0; i < dwMaxFaceInfl; ++i
push ecx
assume ebx:nothing
mov ebx,abonecombination
mov eax,ipattr
imul eax,sizeof D3DXBONECOMBINATION
add ebx,eax ;pointing to BONECOMBINATION
assume ebx:ptr D3DXBONECOMBINATION
mov ebx,.BoneId ;BoneId is a pointer to a dword array
assume ebx:nothing
shl ecx,2 ;BoneID's are in an array of dwords
add ebx,ecx ;which dword? THAT one :)
m2m matid , dword ptr ;copy it
mov ebx,abonecombination
mov eax,ipattr
dec eax
.if eax==-1
mov eax,3
.endif
shl eax,2
add ebx,eax ;pointing to BONECOMBINATION
mov ebx,.D3DXBONECOMBINATION.BoneId ;BoneId is a pointer to a dword array
add ebx,ecx ;which dword? THAT one :)
mov eax,matid
.if eax != 65535 && (ipattr == 0 || eax != dword ptr )
mov ecx,matid
imul ecx,sizeof D3DMATRIX
add ecx,.pBoneMatrix
add ebx,256 ; D3DTS_WORLDMATRIX = transform index + 256
mcall ,IDirect3DDevice8_SetTransform,ebx, ecx
mov ecx,matid
imul ecx,sizeof D3DMATRIX
mcall ,IDirect3DDevice8_MultiplyTransform,ebx, addr .pBoneOffsetMatrix
.endif
pop ecx
inc ecx
.endw
; // check if the material is different than that of the previous attribute
; AKA HAS THE MATERIAL CHANGED ???
.if ipattr==0
jmp @F
.endif
assume ecx:nothing
mov ecx,ipattr ;ecx=current attribute (counter)
imul ecx,sizeof D3DXBONECOMBINATION ;skip to correct BoneCombination struct
add ecx,abonecombination ;ecx =ptr to current BoneCombination
m2m attrid, .D3DXBONECOMBINATION.AttribId ;fetch Attribute ID of current attribute
mov ebx,ecx
sub ebx,sizeof D3DXBONECOMBINATION ;ebx=ptr to LAST attribute
mov edx,.D3DXBONECOMBINATION.AttribId
.if ( ipattr == 0) || (EAX !=EDX) ;If this is the first attribute, or if attribute has changed...
@@: push esi
mov ebx, pMaterials
mov ecx,attrid
imul ecx,sizeof D3DMATERIAL8
add ebx,ecx
mcall ,IDirect3DDevice8_SetMaterial, ebx ;SET MATERIAL !!!
mov ebx, pTextures
mov ecx,attrid
shl ecx,2
add ebx,ecx ;ebx=ptr to nth pTexture
mcall ,IDirect3DDevice8_SetTexture, 0, dword ptr
pop esi
.endif
mcall .pD3DXBlendedMesh,ID3DXBaseMesh_DrawSubset ,ipattr ;render
inc ipattr
mov ecx,ipattr
.endw
; // rendering is finished, set the vertex blending back to disabled mode
mcall ,IDirect3DDevice8_SetRenderState, D3DRS_VERTEXBLEND, 0
;=================================================================================
.else ;CASE 2 of 2 - DRAWING A NORMAL UNSKINNED MESH
xor ecx,ecx
.while ecx<.dwAttrCount
; push ecx
; mov ebx,pMaterials
; imul ecx,sizeof D3DMATERIAL8
; add ebx,ecx
; mcall ,IDirect3DDevice8_SetMaterial, ebx
; pop ecx
; push ecx
; mov ebx,pTextures
; shl ecx,2
; add ebx,ecx
; mcall ,IDirect3DDevice8_SetTexture, 0, dword ptr
; pop ecx
; push ecx
; mcall .pD3DXBlendedMesh,ID3DXBaseMesh_DrawSubset, ecx
; pop ecx
; inc
.endw
.endif
pop esi
return S_OK
MeshNode_Render ENDP
;=================================================================================
(please ignore the fact that I have disabled the non skinmesh Render code in that.)
Please find a moment to examine it for obvious errors - I've been staring at this source for far too long and am probably overlooking something simple.
void CMeshNode::Render( LPDIRECT3DDEVICE8 pd3ddevice )
{
UINT ipattr;
// check if we have a skin mesh or a normal mesh
if (pD3DXSkinMesh)
{
// draw the skin mesh
// draw using non indexed blending
// assuming that the hardware can support the number of matrices
// get the bone combinations
LPD3DXBONECOMBINATION abonecombination;
abonecombination = (LPD3DXBONECOMBINATION)pBoneCombinationBuf->GetBufferPointer();
// enable vertex blending
pd3ddevice->SetRenderState( D3DRS_VERTEXBLEND, dwMaxFaceInfl - 1 );
for( ipattr = 0; ipattr < dwAttrCount; ipattr++ )
{
// set the matrices for this attribute range
for( DWORD i = 0; i < dwMaxFaceInfl; ++i )
{
DWORD matid = abonecombination.BoneId;
if( matid != UINT_MAX && (ipattr == 0 || matid != abonecombination.BoneId))
{
pd3ddevice->SetTransform( D3DTS_WORLDMATRIX(i), apBoneMatrix );
pd3ddevice->MultiplyTransform( D3DTS_WORLDMATRIX(i), &aBoneOffsetMatrix);
}
}
// check if the material is different than that of the previous attribute
if( ipattr == 0 || (abonecombination.AttribId != abonecombination.AttribId))
{
// set the new material
pd3ddevice->SetMaterial( &(aMaterial.AttribId]) );
pd3ddevice->SetTexture( 0, apD3DTexture.AttribId] );
}
// render
pD3DXBlendedMesh->DrawSubset( ipattr );
}
// rendering is finished, set the vertex blending back to disabled mode
pd3ddevice->SetRenderState( D3DRS_VERTEXBLEND, 0 );
}
else // pD3DSkinMesh
{
// we don't have a skin mesh, so draw the normal mesh
for( ipattr = 0; ipattr < dwAttrCount; ipattr++ )
{
pd3ddevice->SetMaterial( &(aMaterial) );
pd3ddevice->SetTexture( 0, apD3DTexture );
pD3DXBlendedMesh->DrawSubset( ipattr );
}
}
}
and my version...
;=================================================================================
MeshNode_Render PROC pThis:LPMESHNODE
;=================================================================================
local NumAttributes:DWORD
local ipattr:DWORD ;Counter for "current Attribute"
local attrid:DWORD ;Holds "Attribute ID" for current Attribute
local matid:DWORD ;Holds "Matrix ID" for current Attribute
local abonecombination:DWORD ;Holds pointer to an array of BoneCombination structs
local pMaterials:DWORD ;Holds pointer to array of Materials (we allocated when we loaded the mesh)
local pTextures:DWORD ;Holds pointer to array of pTextures (we allocatde when we loaded the mesh)
local ErrBuf[256]:BYTE ;Not being used
;=================================================================================
assume esi:nothing
.if pThis==NULL
mov OkToRender,FALSE
Errr CTXT("MORON tried to Render NULL MeshNode")
.endif
push esi
mov esi,pThis
assume esi:LPMESHNODE
;=================================================================================
;Check if we have a skin mesh or a normal mesh, based on whether we Generated the mesh
;=================================================================================
.if .pD3DXBlendedMesh!=0 && .pBoneCombinationBuf!=0
m2m NumAttributes,.dwAttrCount ;Fetch some values into Locals
m2m pMaterials, .pMeshMaterials
m2m pTextures, .pMeshTextures
mov abonecombination , $mcall (.pBoneCombinationBuf,ID3DXBuffer_GetBufferPointer)
; // enable vertex blending
mov eax,.dwMaxFaceInfluence
dec eax
mcall ,IDirect3DDevice8_SetRenderState, D3DRS_VERTEXBLEND, eax
; LOOP FOR ALL SUBSETS IN THE SKIN MESH
xor ecx,ecx
mov ipattr,ecx
.while ecx<NumAttributes ; for ipattr = 0; ipattr < dwAttrCount; ipattr++
; Set the matrices for this attribute range
; LOOP FOR ALL INFLUENCES
xor ecx,ecx
.while ecx<.dwMaxFaceInfluence ;for i = 0; i < dwMaxFaceInfl; ++i
push ecx
assume ebx:nothing
mov ebx,abonecombination
mov eax,ipattr
imul eax,sizeof D3DXBONECOMBINATION
add ebx,eax ;pointing to BONECOMBINATION
assume ebx:ptr D3DXBONECOMBINATION
mov ebx,.BoneId ;BoneId is a pointer to a dword array
assume ebx:nothing
shl ecx,2 ;BoneID's are in an array of dwords
add ebx,ecx ;which dword? THAT one :)
m2m matid , dword ptr ;copy it
mov ebx,abonecombination
mov eax,ipattr
dec eax
.if eax==-1
mov eax,3
.endif
shl eax,2
add ebx,eax ;pointing to BONECOMBINATION
mov ebx,.D3DXBONECOMBINATION.BoneId ;BoneId is a pointer to a dword array
add ebx,ecx ;which dword? THAT one :)
mov eax,matid
.if eax != 65535 && (ipattr == 0 || eax != dword ptr )
mov ecx,matid
imul ecx,sizeof D3DMATRIX
add ecx,.pBoneMatrix
add ebx,256 ; D3DTS_WORLDMATRIX = transform index + 256
mcall ,IDirect3DDevice8_SetTransform,ebx, ecx
mov ecx,matid
imul ecx,sizeof D3DMATRIX
mcall ,IDirect3DDevice8_MultiplyTransform,ebx, addr .pBoneOffsetMatrix
.endif
pop ecx
inc ecx
.endw
; // check if the material is different than that of the previous attribute
; AKA HAS THE MATERIAL CHANGED ???
.if ipattr==0
jmp @F
.endif
assume ecx:nothing
mov ecx,ipattr ;ecx=current attribute (counter)
imul ecx,sizeof D3DXBONECOMBINATION ;skip to correct BoneCombination struct
add ecx,abonecombination ;ecx =ptr to current BoneCombination
m2m attrid, .D3DXBONECOMBINATION.AttribId ;fetch Attribute ID of current attribute
mov ebx,ecx
sub ebx,sizeof D3DXBONECOMBINATION ;ebx=ptr to LAST attribute
mov edx,.D3DXBONECOMBINATION.AttribId
.if ( ipattr == 0) || (EAX !=EDX) ;If this is the first attribute, or if attribute has changed...
@@: push esi
mov ebx, pMaterials
mov ecx,attrid
imul ecx,sizeof D3DMATERIAL8
add ebx,ecx
mcall ,IDirect3DDevice8_SetMaterial, ebx ;SET MATERIAL !!!
mov ebx, pTextures
mov ecx,attrid
shl ecx,2
add ebx,ecx ;ebx=ptr to nth pTexture
mcall ,IDirect3DDevice8_SetTexture, 0, dword ptr
pop esi
.endif
mcall .pD3DXBlendedMesh,ID3DXBaseMesh_DrawSubset ,ipattr ;render
inc ipattr
mov ecx,ipattr
.endw
; // rendering is finished, set the vertex blending back to disabled mode
mcall ,IDirect3DDevice8_SetRenderState, D3DRS_VERTEXBLEND, 0
;=================================================================================
.else ;CASE 2 of 2 - DRAWING A NORMAL UNSKINNED MESH
xor ecx,ecx
.while ecx<.dwAttrCount
; push ecx
; mov ebx,pMaterials
; imul ecx,sizeof D3DMATERIAL8
; add ebx,ecx
; mcall ,IDirect3DDevice8_SetMaterial, ebx
; pop ecx
; push ecx
; mov ebx,pTextures
; shl ecx,2
; add ebx,ecx
; mcall ,IDirect3DDevice8_SetTexture, 0, dword ptr
; pop ecx
; push ecx
; mcall .pD3DXBlendedMesh,ID3DXBaseMesh_DrawSubset, ecx
; pop ecx
; inc
.endw
.endif
pop esi
return S_OK
MeshNode_Render ENDP
;=================================================================================
(please ignore the fact that I have disabled the non skinmesh Render code in that.)
Some minor discrepancies found in the MeshNode module, here's an update of the MeshNode module..
Debug module was modified (below) and so was the ObjectManager module (attachment provided)
.data
LogFileHandle dd 0
.code
Debug_CreateLogFile PROC pName:DWORD
mov LogFileHandle,$invoke (CreateFile,pName,GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,0,0)
ret
Debug_CreateLogFile ENDP
Debug_CloseLogFile PROC
invoke CloseHandle,LogFileHandle
ret
Debug_CloseLogFile ENDP
Debug_WriteLogFile PROC pOut:DWORD
local cbWritten:DWORD
push esi
mov ebx,$invoke (lstrlen, pOut)
invoke WriteFile, LogFileHandle, pOut, ebx, addr cbWritten, NULL
pop esi
ret
Debug_WriteLogFile ENDP
Debug MACRO pOut:REQ
invoke Debug_WriteLogFile, pOut
ENDM
DebugValue MACRO pOut:REQ,pIn:REQ,xVal:REQ
push xVal
push esi
invoke wsprintf,pOut,pIn,xVal
invoke Debug_WriteLogFile,pOut
pop esi
pop xVal
ENDM
.data
LogFileHandle dd 0
.code
Debug_CreateLogFile PROC pName:DWORD
mov LogFileHandle,$invoke (CreateFile,pName,GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,0,0)
ret
Debug_CreateLogFile ENDP
Debug_CloseLogFile PROC
invoke CloseHandle,LogFileHandle
ret
Debug_CloseLogFile ENDP
Debug_WriteLogFile PROC pOut:DWORD
local cbWritten:DWORD
push esi
mov ebx,$invoke (lstrlen, pOut)
invoke WriteFile, LogFileHandle, pOut, ebx, addr cbWritten, NULL
pop esi
ret
Debug_WriteLogFile ENDP
Debug MACRO pOut:REQ
invoke Debug_WriteLogFile, pOut
ENDM
DebugValue MACRO pOut:REQ,pIn:REQ,xVal:REQ
push xVal
push esi
invoke wsprintf,pOut,pIn,xVal
invoke Debug_WriteLogFile,pOut
pop esi
pop xVal
ENDM
MeshNode's functions were modified to take into account that the misnamed field "pBoneMatrix" is NOT pointing to a Matrix, OR to an array of Matrices, it's pointing to an array of LPMATRIX (array of dword pointers to matrices)
So we really only needed a dword array of size = (#bones) for that...
Explanation of naming convention:
The field has been renamed "apBoneMatrices" ... the "a" signifies that this is an array pointer, and the pBoneMatrices indicates that the array contains LPMATRIX pointers.
So we really only needed a dword array of size = (#bones) for that...
Explanation of naming convention:
The field has been renamed "apBoneMatrices" ... the "a" signifies that this is an array pointer, and the pBoneMatrices indicates that the array contains LPMATRIX pointers.
Oh MY !! I got it to Render something !!
It's not exactly right, but it's a darn good start !!
I'm a bit tired - I'll post later.
It's not exactly right, but it's a darn good start !!
I'm a bit tired - I'll post later.
Congrats, it's always good to see something on screen, correct or not!
Sorry I haven't been more active but I've got a project of my own that's being uncooperative!
Once I get this project out of the way I should be able to help more.
Maelstrom
Sorry I haven't been more active but I've got a project of my own that's being uncooperative!
Once I get this project out of the way I should be able to help more.
Maelstrom