Jump to content
  • Advertisement
Sign in to follow this  
RaPhiuS

Frustum culling

This topic is 5392 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I have recently implemented terrain rendering using a quad tree and now i am willing to do frustum culling to reduce the polygons number.. I have read the Mark Morley's tutorial about frustum culling. I used his code to extract the viewing frustum and his functions PointInFrustum, SphereInFrustum and CubeInFrustum. Now my problem is this. Each frame, i extract the frustum and then make a call to my Refine() method which is responsible to build the mesh before drawing it to the screen. In that method i'm doing a CubeInFrustum test by giving the x,y,z coordinates of the center of the quad node and it's size. If it is not in the frustum i simply disable this node. It "seems" to work and i get a "good" frame rate... but I can see holes, big nodes drawn and all the imperfections... (does that make sense ? :)) making everything to look somewhat "ugly". Have someone an idea of what is happening ? :/ Here is my Refine() method : void QuadTreeTerrain::Refine(int x, int z, int width) { float distance = 0.0f; // distance from center of node to camera position float f = 0.0f; // subdivision criterion (f in Röttger's whitepaper) int newWidth = 0; // edgelength of the "possible" childrens to subdivide // if we are at the smallest edgelength then stop recursion ! if (width<=2) { return; } newWidth = width / 2; int index = x + newWidth + (z+newWidth)*tData.size; if (!Frustum::CubeInFrustum(frustum,(x+newWidth)*tScale.x,GetHeight(x+newWidth,z+newWidth)*tScale.y,(z+newWidth)*tScale.z,width*tScale.x)) //if (!Frustum::CubeInFrustum(frustum,x*tScale.x,GetHeight(x,z)*tScale.y,z*tScale.z,width*tScale.x)) { // it is not needed to draw it, we don't see it ! quadTree[index]=0; return; } // Calculate the distance using the L1-Norm // d = |x2 - x1| + |y2 - y1| + |z2 - z1| distance = fabs(cameraPos.x-(x*tScale.x)) + fabs(cameraPos.y-(GetHeight(x,z)*tScale.y)) + fabs(cameraPos.z-(z*tScale.z)); // calculate the subdivision criterion f // f = d / (edgelength * C * MAX(c*d2,1)) f = distance / (width * minResolution * MAX(desiredResolution * errorTree[index],1)); quadTree[index] = 1; if (f<1.0f) { Refine(x,z,newWidth); Refine(x+newWidth,z,newWidth); Refine(x,z+newWidth,newWidth); Refine(x+newWidth,z+newWidth,newWidth); } } Here is my RenderNode() method : void QuadTreeTerrain::RenderNode(int x, int z, int width) { int halfWidth = width/2; int quarterWidth = width/4; int index = x + halfWidth + (z + halfWidth)*tData.size; int nIndex = index - width*tData.size; int sIndex = index + width*tData.size; int eIndex = index + width; int wIndex = index - width; int mapSize = SQUARE(tData.size); // checking map limits if (nIndex >= mapSize || nIndex < 0) { nIndex = 0; } if (sIndex >= mapSize || sIndex < 0) { sIndex = 0; } if (eIndex >= mapSize || eIndex < 0) { eIndex = 0; } if (wIndex >= mapSize || wIndex < 0) { wIndex = 0; } // get the top left, top right, bottom left and bottom right child index in the quad tree int tlChild = (index - quarterWidth) - (quarterWidth*tData.size); int trChild = (index + quarterWidth) - (quarterWidth*tData.size); int blChild = (index - quarterWidth) + (quarterWidth*tData.size); int brChild = (index + quarterWidth) + (quarterWidth*tData.size); // do not render the node if it's disabled ! if (quadTree[index]==0) { return; } // if any of our chilren are active then recurse and draw them! // (this simplification disallows partial triangle fans) else if (quadTree[tlChild]!=0 || quadTree[trChild]!=0 || quadTree[blChild]!=0 || quadTree[brChild]!=0) { RenderNode(x,z,halfWidth); RenderNode(x+halfWidth,z,halfWidth); RenderNode(x,z+halfWidth,halfWidth); RenderNode(x+halfWidth,z+halfWidth,halfWidth); } // else it's a leaf node and we draw a triangle fan ! else { // render a triangle fan and omit vertices if needed glBegin(GL_TRIANGLE_FAN); // center vertex RenderVertex(x+halfWidth,z+halfWidth); // top left vertex RenderVertex(x,z); if (quadTree[wIndex]!=0) { RenderVertex(x,z+halfWidth); } // bottom left vertex RenderVertex(x,z+width); // bottom vertex if (quadTree[sIndex]!=0) { RenderVertex(x+halfWidth,z+width); } // bottom right vertex RenderVertex(x+width,z+width); // right vertex if (quadTree[eIndex]!=0) { RenderVertex(x+width,z+halfWidth); } // top right vertex RenderVertex(x+width,z); // top vertex if (quadTree[nIndex]!=0) { RenderVertex(x+halfWidth,z); } // top left vertex once again RenderVertex(x,z); glEnd(); } } Help would be appreciated ;) Thx

Share this post


Link to post
Share on other sites
Advertisement
[ source] CODE_GOES_HERE [ /source]
use that to save the page from becomming massively long. I'm just going to read through what you have put know ;-)

Share this post


Link to post
Share on other sites
you could still edit your post and add the source tags :/
i dont think i could help you then but it would sure help others to help you.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!