quake2xp weird bug
Moderator: InsideQC Admins
40 posts
• Page 3 of 3 • 1, 2, 3
so R_RecursiveWorldNode is used as a refresh ? makes sense
i remember there was a cullcheck in R_RecursiveWorldNode in your earlier code (backend for my realm engine)
ah aye it was a bit further down the code
just before the final refresh and after checking for other types.
i wonder how much impact it would have unless theres a lot of state changes going through though ?.
btw i like the new glsl renderer but i noticed it fades to gray on mapload and not black like the old one, i seem to remember in Q1
you needed to clear the color buffer on mapload i wonder if the change to glsl needs something different.
im also looking into moving the radarmap a bit since it overlaps with the hud models.
and if possible scale the huge ammo counters down a bit.
btw the GL_MsgGLError("R_RenderFrame: "); in R_RenderFrame sometimes throws an invalid GL_INVALID_OPERATION on some mods
im still investigating.
i remember there was a cullcheck in R_RecursiveWorldNode in your earlier code (backend for my realm engine)
ah aye it was a bit further down the code
- Code: Select all
// because we now have a mins and maxs for each surf we can do this!
// this avoids some VERY substantial surface overdraw - never less than
// 30 or so, and sometimes up to 200 or more surfs can be skipped.
// this is more of my "saving the GPU for the really fancy stuff" thing.
if (R_CullBox (surf->mins, surf->maxs)) continue;
just before the final refresh and after checking for other types.
i wonder how much impact it would have unless theres a lot of state changes going through though ?.
btw i like the new glsl renderer but i noticed it fades to gray on mapload and not black like the old one, i seem to remember in Q1
you needed to clear the color buffer on mapload i wonder if the change to glsl needs something different.
im also looking into moving the radarmap a bit since it overlaps with the hud models.
and if possible scale the huge ammo counters down a bit.
btw the GL_MsgGLError("R_RenderFrame: "); in R_RenderFrame sometimes throws an invalid GL_INVALID_OPERATION on some mods
im still investigating.
-

revelator - Posts: 2567
- Joined: Thu Jan 24, 2008 12:04 pm
- Location: inside tha debugger
The clipflags thing is straight outta software Quake by the way, and is substantially more optimal than the original R_CullBox as it accounts for all the automatic accept or reject of child nodes that I mentioned before, and also does so on a per-plane basis.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
i did notice you were starting to use a similar idea in some later engines of yours
so i figured it had some bearing.
im not totally sure how the clipflag thing works, is the flag value allways 15 ? and where is that value derived from.
maybe an idea to incorporate it in the R_CullBox function directly ? if possible that is.
im not totally sure how the clipflag thing works, is the flag value allways 15 ? and where is that value derived from.
maybe an idea to incorporate it in the R_CullBox function directly ? if possible that is.
-

revelator - Posts: 2567
- Joined: Thu Jan 24, 2008 12:04 pm
- Location: inside tha debugger
It's a bitwise mask, 1 | 2 | 4 | 8. Each bit represents a frustum plane, if the bit is 0 the node is inside the plane, if it's 1 the node is in a (potentially) unknown state. The headnode for the world gets 15 because we don't know it yet and need to test all 4 planes. (In practice it will intersect all 4 frustum planes and it's children will therefore inherit the 15).
BOX_ON_PLANE_SIDE returns 0, 1 or 2. 0 means that the node intersects the plane, 1 means that it's inside the plane, 2 means that it's outside the plane.
The neat thing here is that if a node is inside the plane on one side then all of it's child nodes (and their children recursively) are also inside the plane on that side so there's no need to test that side for children. That's what this code is for:
A node that's outside any one frustum plane is offscreen and doesn't get drawn (all of it's children are also rejected by the return):
A node that's inside the frustum on any one side gets the bit for that side removed from the clipflags so that it's children don't get tested (they're guaranteed to pass):
A node that's inside the frustum on all 4 planes therefore gets clipflags 0 and - as all of it's children recursively are guaranteed to be also inside the frustum on all 4 sides - child nodes don't need to be tested at all.
There's nothing to gain and everything to lose for incorporating it into R_CullBox; the implementation relies on the function using it being recursive. If you modify clipflags in R_CullBox then R_RecursiveWorldNode won't get the modified value when R_CullBox returns, meaning that when it calls itself it won't be able to make use of the parent node information for skipping tests for child nodes.
It's also only of use for a tree structure with parents and children, meaning that you'll need special handling for R_CullBox calls on entities.
Yeah, I'd been moving towards something similar myself but I'd totally missed this implementation which is a lot more elegant and robust than what I had been doing.
BOX_ON_PLANE_SIDE returns 0, 1 or 2. 0 means that the node intersects the plane, 1 means that it's inside the plane, 2 means that it's outside the plane.
The neat thing here is that if a node is inside the plane on one side then all of it's child nodes (and their children recursively) are also inside the plane on that side so there's no need to test that side for children. That's what this code is for:
- Code: Select all
if (!(clipflags & (1 << c))) continue;
A node that's outside any one frustum plane is offscreen and doesn't get drawn (all of it's children are also rejected by the return):
- Code: Select all
if ((clipped = BOX_ON_PLANE_SIDE (node->minmaxs, node->minmaxs + 3, plane)) == 2) return;
A node that's inside the frustum on any one side gets the bit for that side removed from the clipflags so that it's children don't get tested (they're guaranteed to pass):
- Code: Select all
if (clipped == 1) clipflags &= ~(1 << c);
A node that's inside the frustum on all 4 planes therefore gets clipflags 0 and - as all of it's children recursively are guaranteed to be also inside the frustum on all 4 sides - child nodes don't need to be tested at all.
There's nothing to gain and everything to lose for incorporating it into R_CullBox; the implementation relies on the function using it being recursive. If you modify clipflags in R_CullBox then R_RecursiveWorldNode won't get the modified value when R_CullBox returns, meaning that when it calls itself it won't be able to make use of the parent node information for skipping tests for child nodes.
It's also only of use for a tree structure with parents and children, meaning that you'll need special handling for R_CullBox calls on entities.
Yeah, I'd been moving towards something similar myself but I'd totally missed this implementation which is a lot more elegant and robust than what I had been doing.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
thanks for the very nice explanation
and dont be so hard on yourself sometimes im staring myself blind on something i want to optimize making a godawfull mess instead
but even blind monkeys (me) sometimes finds a banana
.
a lot of your work is pretty brilliant even if this one slipped past you
and dont be so hard on yourself sometimes im staring myself blind on something i want to optimize making a godawfull mess instead
but even blind monkeys (me) sometimes finds a banana
a lot of your work is pretty brilliant even if this one slipped past you
-

revelator - Posts: 2567
- Joined: Thu Jan 24, 2008 12:04 pm
- Location: inside tha debugger
hm not sure if its an oversight but i noticed quake2xp is using the textureanimation check for normalmaps but check this ->
fx is not readded to the refresh so i did this
i renamed fx to match addtexture and the normalmap one is a newer addtion.
isnt this more correct ?
- Code: Select all
// the polygon is visible, so add it to the texture
// sorted chain
image = R_TextureAnimation(surf->texinfo);
fx = R_TextureAnimationfx(surf->texinfo);
surf->texturechain = image->texturechain;
image->texturechain = surf;
fx is not readded to the refresh so i did this
- Code: Select all
// the polygon is visible, so add it to the texture
// sorted chain
image = R_TextureAnimation(surf->texinfo);
surf->texturechain = image->texturechain;
image->texturechain = surf;
normal = R_NormalTextureAnimation(surf->texinfo);
surf->texturechain = normal->texturechain;
normal->texturechain = surf;
add = R_AddTextureAnimation(surf->texinfo);
surf->texturechain = add->texturechain;
add->texturechain = surf;
i renamed fx to match addtexture and the normalmap one is a newer addtion.
isnt this more correct ?
-

revelator - Posts: 2567
- Joined: Thu Jan 24, 2008 12:04 pm
- Location: inside tha debugger
40 posts
• Page 3 of 3 • 1, 2, 3
Who is online
Users browsing this forum: No registered users and 1 guest



