Advertisement

Frustum culling

Started by October 11, 2004 08:40 AM
3 comments, last by BiGF00T 20 years, 1 month ago
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
Best Regards, RaPhiuS / PaRaSiTe
[ 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 ;-)
____________________________________________________________Programmers Resource Central
Advertisement
Sorry and thank you for the info ;-)

An idea about what is wrong in there :/ :-)
Best Regards, RaPhiuS / PaRaSiTe
Sorry and thank you for the info ;-)

An idea about what is wrong in there :/ :-)
Best Regards, RaPhiuS / PaRaSiTe
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.
Now get down on your hands and knees and start repeating "Open Source Good, M$ Evil", smacking your head against the pavement after each repetition. Once you have completed your training you may change your first name to GNU/, to show that you are free from the slavery of the closed source world. -Michalson

This topic is closed to new replies.

Advertisement