Happy programming at 1200PM :)
Uh oh, im still bugged, is it possible to Render all Faces by parsing Leaffaces?
Because I got 2 faces not rendered, a bit closer to success, than before i used fld and fstp on pure DWORD not fild and fistp ;)
Uh oh, im still bugged, is it possible to Render all Faces by parsing Leaffaces?
Because I got 2 faces not rendered, a bit closer to success, than before i used fld and fstp on pure DWORD not fild and fistp ;)
Yes thats possible.
In fact you are meant to draw all faces that are inside a leaf.
Here's a little pseudocode which shows the correct method of rendering a BSP for back-to-front order. Considering that a bsp is a tree constructed of nodes, it's important to understand how to "walk" these nodes, which is not simple to understand unless you have experience with linked lists etc. This is one of the reasons I chose not to use a parsive loading approach, although you can still accomodate. I suggest you have a look at some of the descriptive articles on google aimed at programmers to understand how a BSP is meant to be rendered. I'll throw a couple of quick links down below. Hope I have been helpful.
function render(node)
{
if this node is a leaf
{
draw this node to the screen
}
else
{
determine which side of the dividing line the viewpoint is
if it is on the left side
{
render(right subnode)
render(left subnode)
}
else
{
render(left subnode)
render(right subnode)
}
}
}
btw happy birthday if that is accurate :)
http://shaderlab.com/q3map2/manual/dictionary/spogtrms.htm
http://www.ecs.soton.ac.uk/%7Esdh300/stuffage/uni/bsp/
In fact you are meant to draw all faces that are inside a leaf.
Here's a little pseudocode which shows the correct method of rendering a BSP for back-to-front order. Considering that a bsp is a tree constructed of nodes, it's important to understand how to "walk" these nodes, which is not simple to understand unless you have experience with linked lists etc. This is one of the reasons I chose not to use a parsive loading approach, although you can still accomodate. I suggest you have a look at some of the descriptive articles on google aimed at programmers to understand how a BSP is meant to be rendered. I'll throw a couple of quick links down below. Hope I have been helpful.
function render(node)
{
if this node is a leaf
{
draw this node to the screen
}
else
{
determine which side of the dividing line the viewpoint is
if it is on the left side
{
render(right subnode)
render(left subnode)
}
else
{
render(left subnode)
render(right subnode)
}
}
}
btw happy birthday if that is accurate :)
http://shaderlab.com/q3map2/manual/dictionary/spogtrms.htm
http://www.ecs.soton.ac.uk/%7Esdh300/stuffage/uni/bsp/
BSP_ReadLeaves was completed and is calculating the BoundingBoxes for all Leaves. I have just checked and it seems every dependant procedure of BSP_LOAD is now complete.
I think I have completed the bsp Loader :)
Yayyyyyy :D
Therefore I will post again already :)
I think I have completed the bsp Loader :)
Yayyyyyy :D
Therefore I will post again already :)
Next mission: theres one line I had commented out of BSP_LOAD which calls BSP_SetupPrimitives ... this in turn requires some functionality from the CPrimitive class which I'd been kinda neglecting. I'll have to translate at least some of the CPrimitive class next, but I'll do it only as dependant functions are encountered, and only where it seems warranted :)
This is gonna be a bit of a brainfart - don't expect any more postings for a while :)
I have implemente Quaternions! It works fine, and is it better than a glRotate3f ?
and how to do glTranslatef ?
About RenderLeaf
I found whats wrong, the ECX which contained LEAF.num_of_faces was reseted to zero after RenderFace, I istalled softice but not everything is fine, because when i use FindLeaf and IsClusterVisible i got not rendered some faces one of them has an bug, i even dissasembled the HELL (C++ code) compared almost no difference
except that C++ s0x (just h8 it:notsure:)
Here they are!
The original source is at www.GameTutorials.com the bsp loader 3
the PVS tutorial
and how to do glTranslatef ?
About RenderLeaf
I found whats wrong, the ECX which contained LEAF.num_of_faces was reseted to zero after RenderFace, I istalled softice but not everything is fine, because when i use FindLeaf and IsClusterVisible i got not rendered some faces one of them has an bug, i even dissasembled the HELL (C++ code) compared almost no difference
except that C++ s0x (just h8 it:notsure:)
Here they are!
FindLeaf proc x:REAL4,y:REAL4,z:REAL4
xor ecx,ecx
.while !SIGN?
mov esi,sizeof BSP_NODE
imul esi,ecx
add esi,[addrNodes]
mov edi,sizeof BSP_PLANE
imul edi,[esi.BSP_NODE.plane]
add edi,[addrPlanes]
fld [edi.BSP_PLANE.vNormal_x]
fmul x
fld [edi.BSP_PLANE.vNormal_y]
fmul y
faddp st(1),st(0)
fld [edi.BSP_PLANE.vNormal_z]
fmul z
faddp st(1),st(0)
fadd [edi.BSP_PLANE.d] ; with sub i always get negative cluster :(
fistp tempik3
cmp tempik3,0
.if SIGN?
mov ecx,[esi.BSP_NODE.front]
.else
mov ecx,[esi.BSP_NODE.back]
.endif
cmp ecx,0
.endw
not ecx
ret
FindLeaf endp
IsClusterVisible proc current:DWORD,testcluster:DWORD
push edi
push ecx
mov eax,1
cmp nVisdata,0
.if ZERO?
ret
.endif
cmp current,0
.if SIGN?
ret
.endif
mov edi,addrVisdata
;byte visSet = m_clusters.pBitsets[(current*m_clusters.bytesPerCluster) + (test / 8)];
mov ecx,current
imul ecx,[edi.BSP_VISDATA.bytesPerCluster]
fild testcluster
fdiv r4_8_0 ; some times testcluster is negative
fistp tempik
add ecx,tempik
mov al,byte ptr [ecx + edi.BSP_VISDATA.pBitsets]
and eax,0000000FFh
;int result = visSet & (1 << ((test) & 7));
mov ecx, testcluster
and ecx, 7 ; 0111b
xor edx, edx
inc edx
shl edx, cl
and eax, edx ; copyed from c++
pop ecx
pop edi
ret
IsClusterVisible endp
The original source is at www.GameTutorials.com the bsp loader 3
the PVS tutorial
You are not walking the Nodes correctly.
If we look at the struct for BSPNode we see:
BSPNode struct
planeID dd ?
frontChildID dd ?
backChildID dd ?
min D3DXVECTOR3 <?> ;Unsure if we'll be forced to write to IVECTOR3 Class or not
max D3DXVECTOR3 <?>
BSPNode ends
The frontChildID and backChildID fields hold the index of the next Node in the left and right branches of the BSP Tree. We then call iteratively to follow branches of the tree. Thats how I understand it anyway. You're still ahead of me, I had to write the CPrimitive class up for 1 to 8 stage texture blending support, which is getting close to being complete.
If we look at the struct for BSPNode we see:
BSPNode struct
planeID dd ?
frontChildID dd ?
backChildID dd ?
min D3DXVECTOR3 <?> ;Unsure if we'll be forced to write to IVECTOR3 Class or not
max D3DXVECTOR3 <?>
BSPNode ends
The frontChildID and backChildID fields hold the index of the next Node in the left and right branches of the BSP Tree. We then call iteratively to follow branches of the tree. Thats how I understand it anyway. You're still ahead of me, I had to write the CPrimitive class up for 1 to 8 stage texture blending support, which is getting close to being complete.
Yeah, I almost understand the stuff, but where did I do mistake?
I check planes... assign to counter (ecx) frontID or backID then check it for sign
I check planes... assign to counter (ecx) frontID or backID then check it for sign
Why do you NOT the return index value at the end of FindLeaf?
I've implemented CPrimitive and CVertexManipulator.
When we create a CPrimitive Object, we create two CVertexManipulators, storing their ptrs in the CPrimitive object. When we call CPrimitive_SetNumberOfTextureStage it sets up the FVF/vertex size in the CVertexManipulator according to #Textures in CPrimitive.
CPrimitive functions use CVertexManip to modify vertex calculation factors.
This way we can alter the #stages in realtime and call common code with our dynamic FVF. Problem now is to identify a small stack corruption occuring some time during BSP_SetupPrimitives or its dependants. When I return to the original caller of BSP_LOAD (proc called init , in Demo_Init.inc) the stack is bad. App dies.
Still, I figured out how to implement this "FVF Manager" which is good news.
I've implemented CPrimitive and CVertexManipulator.
When we create a CPrimitive Object, we create two CVertexManipulators, storing their ptrs in the CPrimitive object. When we call CPrimitive_SetNumberOfTextureStage it sets up the FVF/vertex size in the CVertexManipulator according to #Textures in CPrimitive.
CPrimitive functions use CVertexManip to modify vertex calculation factors.
This way we can alter the #stages in realtime and call common code with our dynamic FVF. Problem now is to identify a small stack corruption occuring some time during BSP_SetupPrimitives or its dependants. When I return to the original caller of BSP_LOAD (proc called init , in Demo_Init.inc) the stack is bad. App dies.
Still, I figured out how to implement this "FVF Manager" which is good news.
The implementation of two CVManips may be unwarranted, should be able to use just one :)
Debugging to catch stack corruption revealed there was none - but after loading the bsp, when we try to create particlesystems, malloc is crashing when we try to allocate fewer than 16 bytes for a Name string. changed this to use globalalloc, no problem, until next time we try :( seems theres a memory issue !! Perhaps the CreateHeap call is wrong in the Class include, and should not specify a max size so the Heap can be allowed to grow infinitely?
Debugging to catch stack corruption revealed there was none - but after loading the bsp, when we try to create particlesystems, malloc is crashing when we try to allocate fewer than 16 bytes for a Name string. changed this to use globalalloc, no problem, until next time we try :( seems theres a memory issue !! Perhaps the CreateHeap call is wrong in the Class include, and should not specify a max size so the Heap can be allowed to grow infinitely?
:confused: :confused: :confused:
First time you told me that i walking nodes not correctly then u tell that i not return index? index of what? index of leaf node? in FindLeaf here it is at end
then i do next after FindLeaf:
if NODE's child index is negative then its leafnode
so, stop make me more confused im alredy almost harakiri here :notsure:
First time you told me that i walking nodes not correctly then u tell that i not return index? index of what? index of leaf node? in FindLeaf here it is at end
not ecx
ret ; result in ECX
then i do next after FindLeaf:
[COLOR=orangered]mov[/COLOR] edi,sizeof BSP_LEAF [COLOR=green]; size of LEAF structure[/COLOR]
[COLOR=orangered]imul[/COLOR] edi,ecx [COLOR=green]; <- ECX[/COLOR]
[COLOR=orangered]add[/COLOR] edi,dword ptr [addrLeafs] [COLOR=green]; <- addrLeaf has Pure Address in memory of LEAFS[/COLOR]
[COLOR=orangered]m2m[/COLOR] clustar,[edi.BSP_LEAF.cluster] [COLOR=green]; clustar - local var[/COLOR]
[COLOR=orangered]m2m[/COLOR] VisVert,clustar [COLOR=green]; <=- VisVert the public that i will see on screen always -1[/COLOR]
if NODE's child index is negative then its leafnode
so, stop make me more confused im alredy almost harakiri here :notsure:
Don't panic, my Loader is complete and work has begun on the Render code, I'll post what I have done soon :)
I apologise if I threw you with the comment about NOT opcode :tongue:
I apologise if I threw you with the comment about NOT opcode :tongue:
Ok, Thanks anyway
Just to let you all know I've been working on other projects but its time to pick up this one again now. I've translated most of the Render code and implemented it, now its time to translate the CViewPort class which provides support for calculating view frustrum related stuff.
Well well well ... hehehe ... seems MOST of CViewPort is devoted to useless stuff like Fog settings, and FOV/perspective. What a waste of time that would have been. I'll disregard it and write plain helper procs where applicable.
That being said, I'm going to spend the rest of the day drinking beer in the sun :)
That being said, I'm going to spend the rest of the day drinking beer in the sun :)
Ummm... I decided to implement CViewPort anyway.
Here's the current codebase, its buggy but more complete.
Here's the current codebase, its buggy but more complete.
Time to start debugging the current codebase...
One of the most important fields of the BSP class is called p_BSPPrimitive.
It's a pointer to a CPrimitive class object instance.
One of the last things that we do in BSP_LOAD is create an instance of the CPrimitive class and store the object instance pointer in this field.
In the process of creating an instance of CPrimitive, its constructor is called.
This procedure is named CPrimitive_CPrimitive. Within this constructor we set up the default values for the CPrimitive class and fill in its fields as appropriate.
One of the fields of CPrimitive that is of interest is called p_CTexture.
The name is a little misleading. It's an array of 8 pointers to instances of the CTexture class, but the CPrimitive constructor simply sets them all to NULL.
This brings me to the first proven bug that I have found.
Later on during Rendering, we call a function called CPrimitive_SetupRendering.
Among other things, it examines some of the p_CTexture array pointers, and acts on them if they are not NULL. Of course by rights they should be NULL. We set them to NULL, did we not? Well, by the time we get to CPrimitive_SetupRendering they have got something in them which isn't a pointer to a CTexture instance.
Something is very, very wrong.
Is anyone interested in helping to debug this codebase?
If anyone is, I will post the ENTIRE project source.
One of the most important fields of the BSP class is called p_BSPPrimitive.
It's a pointer to a CPrimitive class object instance.
One of the last things that we do in BSP_LOAD is create an instance of the CPrimitive class and store the object instance pointer in this field.
In the process of creating an instance of CPrimitive, its constructor is called.
This procedure is named CPrimitive_CPrimitive. Within this constructor we set up the default values for the CPrimitive class and fill in its fields as appropriate.
One of the fields of CPrimitive that is of interest is called p_CTexture.
The name is a little misleading. It's an array of 8 pointers to instances of the CTexture class, but the CPrimitive constructor simply sets them all to NULL.
This brings me to the first proven bug that I have found.
Later on during Rendering, we call a function called CPrimitive_SetupRendering.
Among other things, it examines some of the p_CTexture array pointers, and acts on them if they are not NULL. Of course by rights they should be NULL. We set them to NULL, did we not? Well, by the time we get to CPrimitive_SetupRendering they have got something in them which isn't a pointer to a CTexture instance.
Something is very, very wrong.
Is anyone interested in helping to debug this codebase?
If anyone is, I will post the ENTIRE project source.
i can try
Just to let you all know that today I'm feeling less depressed than usual, so I've done a little debugging of this codebase, and can tell you that problems in CPrimitive_SetupRendering were resolved, one left in BSP_Render3D (minor stack corruption, should be fixed today) and then we move forwards to the last remaining Render function debugging. That means that the implementation of CPrimitive appears to have been successful, which is important because it means this codebase operates with a naive FVF.
Just as a matter of interest, most of the issues related to DX functions corrupting my object pointer register (ecx), but not all of them do, so it was a matter of trial and error trying not always to refresh ecx after mcalls, ie, identifying which mcalls corrupt ecx and which don't.
Just as a matter of interest, most of the issues related to DX functions corrupting my object pointer register (ecx), but not all of them do, so it was a matter of trial and error trying not always to refresh ecx after mcalls, ie, identifying which mcalls corrupt ecx and which don't.
OK the minor stack corruption was verified and corrected.
Problem was near the end of BSP_Render3D, I was trying to pass a vec3 as a param to BSP_InLeaf. I've altered it to pass a ptr to the vec3 instead and now the stack is happy again :) It seems silly to me to pass whole structs as params anyway, much nicer to pass a ptr to struct instead.
Pressing onwards...
Problem was near the end of BSP_Render3D, I was trying to pass a vec3 as a param to BSP_InLeaf. I've altered it to pass a ptr to the vec3 instead and now the stack is happy again :) It seems silly to me to pass whole structs as params anyway, much nicer to pass a ptr to struct instead.
Pressing onwards...