\input default.mac \keya{}\leftline{void\symbol{}\ \normal{}NV_PureKdTreeRenderAction\symbol{}::\normal{}TraverseNode\symbol{}(\normal{}KdTreeNode\symbol{}\ *\normal{}pCurrNode\symbol{}) } \leftline{ 1:\ \ \ $\{$ } \leftline{ 2:\ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (\normal{}pCurrNode\symbol{}->\normal{}m_bLeaf\symbol{}) } \leftline{ 3:\ \ \ \ \ \ \ \ \ \ $\{$ } \leftline{ 4:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//\ this\ has\ a\ frame\ counter\ to\ prevent\ double\ rendering } \symbol{}\leftline{ 5:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}->\normal{}RenderGeometry\symbol{}(); } \leftline{ 6:\ \ \ \ \ \ \ \ \ \ $\}$ } \leftline{ 7:\ \ \ \ \ \ \ \ \ \ \keya{}else\symbol{} } \leftline{ 8:\ \ \ \ \ \ \ \ \ \ $\{$ } \leftline{ 9:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}Point3f\symbol{}\ \ \ \ \ \ \normal{}ptViewpoint\symbol{}\ \ =\ \normal{}GetState\symbol{}()->\normal{}GetCamera\symbol{}()->\normal{}GetPosition\symbol{}(); } \leftline{10:\ \ \ } \leftline{11:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//----\ insert\ the\ children\ in\ the\ reverse\ order\ as\ they\ shall\ be\ dealt\ with } \symbol{}\leftline{12:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (\normal{}ptViewpoint\symbol{}[\normal{}pCurrNode\symbol{}->\normal{}m_iSplitAxis\symbol{}]\ >\ \normal{}pCurrNode\symbol{}->\normal{}m_fSplitValue\symbol{}) } \leftline{13:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ } \leftline{14:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}m_TraverseStack.Push\symbol{}(\normal{}pCurrNode\symbol{}->\normal{}m_pLeftChild\symbol{}); } \leftline{15:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}m_TraverseStack.Push\symbol{}(\normal{}pCurrNode\symbol{}->\normal{}m_pRightChild\symbol{}); } \leftline{16:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$ } \leftline{17:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}else\symbol{} } \leftline{18:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ } \leftline{19:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}m_TraverseStack.Push\symbol{}(\normal{}pCurrNode\symbol{}->\normal{}m_pRightChild\symbol{}); } \leftline{20:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}m_TraverseStack.Push\symbol{}(\normal{}pCurrNode\symbol{}->\normal{}m_pLeftChild\symbol{}); } \leftline{21:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$ } \leftline{22:\ \ \ \ \ \ \ \ \ \ $\}$\ \comment{}//\ no\ leaf } \symbol{}\leftline{23:\ \ \ $\}$ } \leftline{24:\ \ \ } \leftline{25:\ \ \ } \comment{}\leftline{26:\ \ \ //----\ the\ actual\ render\ algorithm } \keya{}\leftline{27:\ \ \ void\symbol{}\ \ \ \normal{}NV_PureKdTreeRenderAction\symbol{}::\normal{}RenderSorted\symbol{}() } \leftline{28:\ \ \ $\{$ } \leftline{29:\ \ \ \ \ \ \ \ \ \ \normal{}KdTreeNode\symbol{}\ \ \ \ *\ \normal{}pCurrNode\symbol{}; } \leftline{30:\ \ \ \ \ \ \ \ \ \ \keya{}int\symbol{}\ \ \ \ \ \ \normal{}iTestCounter\symbol{}\ \ \ \ =\ \normal{}0\symbol{}; } \leftline{31:\ \ \ } \leftline{32:\ \ \ \ \ \ \ \ \ \ \comment{}//----\ clear\ the\ two\ needed\ datastructures } \symbol{}\leftline{33:\ \ \ \ \ \ \ \ \ \ \normal{}m_TraverseStack.Clear\symbol{}(); } \leftline{34:\ \ \ \ \ \ \ \ \ \ \normal{}m_NVTestQueue.Clear\symbol{}(); } \leftline{35:\ \ \ } \leftline{36:\ \ \ \ \ \ \ \ \ \ \comment{}//----\ generate\ the\ occlusion\ queries } \symbol{}\leftline{37:\ \ \ \ \ \ \ \ \ \ \normal{}glGenOcclusionQueriesNV\symbol{}(\normal{}m_nNumNodes\symbol{},\ \normal{}m_pOcclusionQueries\symbol{}); } \leftline{38:\ \ \ } \leftline{39:\ \ \ \ \ \ \ \ \ \ \comment{}//----\ take\ the\ root\ as\ a\ start } \symbol{}\leftline{40:\ \ \ \ \ \ \ \ \ \ \normal{}m_pKdTree\symbol{}->\normal{}m_iPlaneMask\symbol{}\ \ \ \ \ \ \ =\ \normal{}0x3f\symbol{};\ \ \ \ \ \ \ \comment{}//\ =\ 0011\ 1111\ which\ means\ that\ at\ the\ beginning,\ all\ six\ planes\ have\ to\ frustum\ culled } \symbol{}\leftline{41:\ \ \ \ \ \ \ \ \ \ \normal{}m_TraverseStack.Push\symbol{}(\normal{}m_pKdTree\symbol{}); } \leftline{42:\ \ \ } \leftline{43:\ \ \ \ \ \ \ \ \ \ \comment{}//----\ the\ loop } \symbol{}\leftline{44:\ \ \ \ \ \ \ \ \ \ \keya{}while\symbol{}\ ((!\normal{}m_TraverseStack.Empty\symbol{}())\ ||\ (!\normal{}m_NVTestQueue.Empty\symbol{}())) } \leftline{45:\ \ \ \ \ \ \ \ \ \ $\{$ } \leftline{46:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}bool\symbol{}\ \normal{}result_available\symbol{}; } \leftline{47:\ \ \ } \leftline{48:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}while\symbol{}\ (!\normal{}m_NVTestQueue.Empty\symbol{}()\ \&\&\ } \leftline{49:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (\normal{}m_TraverseStack.Empty\symbol{}()\ || } \leftline{50:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (\normal{}result_available\symbol{}\ =\ \normal{}ResultAvailable\symbol{}(\normal{}m_NVTestQueue.GetFirst\symbol{}()->\normal{}m_nTest\symbol{})) } \leftline{51:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ) } \leftline{52:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ) } \leftline{53:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ } \leftline{54:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}\ =\ \normal{}m_NVTestQueue.GetFirst\symbol{}();\ \normal{}m_NVTestQueue.RemoveFirst\symbol{}(); } \leftline{55:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ } \leftline{56:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//\ the\ next\ line\ is\ only\ interesting\ if\ we\ want\ to\ avoid\ double\ rendering\ already\ here: } \symbol{}\leftline{57:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//bool\ was_visible\ =\ pCurrNode->m_bVisible\ \&\&\ (m_nLastVisitedId\ ==\ (GetCurrentFrame()\ -\ 1)); } \symbol{}\leftline{58:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ } \leftline{59:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//\ update\ visibility\ classification\ (this\ is\ the\ wait\ variety!) } \symbol{}\leftline{60:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}->\normal{}m_bVisible\symbol{}\ =\ \normal{}GetVisiblePixels\symbol{}(\normal{}pCurrNode\symbol{}->\normal{}m_nTest\symbol{})\ >\ \normal{}Settings\symbol{}::\normal{}Global\symbol{}()->\normal{}get_nvocc_pixel_treshold\symbol{}(); } \leftline{61:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}->\normal{}m_nLastVisitedId\symbol{}\ =\ \normal{}GetCurrentFrame\symbol{}(); } \leftline{62:\ \ \ } \leftline{63:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (\normal{}pCurrNode\symbol{}->\normal{}m_bVisible\symbol{})\ \comment{}//\ \&\&\ !was_visible)\ \ \ \ \ \ //\ note:\ could\ prevent\ double\ rendering\ already\ here! } \symbol{}\leftline{64:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ } \leftline{65:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}->\normal{}MakeParentsVisible\symbol{}(); } \leftline{66:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}TraverseNode\symbol{}(\normal{}pCurrNode\symbol{}); } \leftline{67:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$\ \comment{}//\ visible } \symbol{}\leftline{68:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$ } \leftline{69:\ \ \ } \leftline{70:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//----\ the\ second\ part\ manages\ the\ distance\ heap } \symbol{}\leftline{71:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (!\normal{}m_TraverseStack.Empty\symbol{}()) } \leftline{72:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ } \leftline{73:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//----\ get\ the\ element\ with\ the\ lowest\ distance } \symbol{}\leftline{74:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}\ \ \ =\ \normal{}m_TraverseStack.Pop\symbol{}();\ \ \ \ \ \ \ \ \ \ \ } \leftline{75:\ \ \ } \leftline{76:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//\ question:\ what\ is\ the\ difference\ if\ we\ do\ frustum\ culling\ only\ after\ setting\ visibility? } \symbol{}\leftline{77:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (\normal{}pCurrNode\symbol{}->\normal{}IsWithinViewFrustum\symbol{}()) } \leftline{78:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ } \leftline{79:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}bool\symbol{}\ \normal{}was_visible\symbol{}\ =\ \normal{}pCurrNode\symbol{}->\normal{}m_bVisible\symbol{}\ \&\&\ (\normal{}pCurrNode\symbol{}->\normal{}m_nLastVisitedId\symbol{}\ ==\ (\normal{}GetCurrentFrame\symbol{}()\ -\ \normal{}1\symbol{})); } \leftline{80:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ } \leftline{81:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//\ note:\ this\ is\ actually\ only\ done\ for\ internal\ nodes\ and\ could\ be\ skipped\ for\ leaf\ nodes } \symbol{}\leftline{82:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//\ in\ which\ case\ leaf\ node\ double\ rendering\ could\ be\ prevented\ here\ (see\ above) } \symbol{}\leftline{83:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}->\normal{}m_bVisible\symbol{}\ =\ \normal{}FALSE\symbol{}; } \leftline{84:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}->\normal{}m_nLastVisitedId\symbol{}\ =\ \normal{}GetCurrentFrame\symbol{}(); } \leftline{85:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ } \leftline{86:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (\normal{}pCurrNode\symbol{}->\normal{}m_bLeaf\symbol{}\ ||\ !\normal{}was_visible\symbol{}) } \leftline{87:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ } \leftline{88:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (\normal{}pCurrNode\symbol{}->\normal{}m_pSuccessor\symbol{}->\normal{}IssueNVTest\symbol{}(\normal{}m_pOcclusionQueries\symbol{}[\normal{}iTestCounter\symbol{}]))\ ++\normal{}iTestCounter\symbol{}; } \leftline{89:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}m_NVTestQueue.Append\symbol{}(\normal{}pCurrNode\symbol{}); } \leftline{90:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$ } \leftline{91:\ \ \ } \leftline{92:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (\normal{}was_visible\symbol{}) } \leftline{93:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ } \leftline{94:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}TraverseNode\symbol{}(\normal{}pCurrNode\symbol{}); } \leftline{95:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$ } \leftline{96:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$ } \leftline{97:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$ } \leftline{98:\ \ \ \ \ \ \ \ \ \ $\}$ } \leftline{99:\ \ \ } \leftline{100:\ \ \ \ \ \ \ \ \ \ \comment{}//----\ tell\ the\ driver\ that\ the\ occlusion\ queries\ won't\ be\ needed\ any\ more } \symbol{}\leftline{101:\ \ \ \ \ \ \ \ \ \ \normal{}glDeleteOcclusionQueriesNV\symbol{}(\normal{}m_nNumNodes\symbol{},\ \normal{}m_pOcclusionQueries\symbol{}); } \leftline{102:\ \ \ } \leftline{103:\ \ \ $\}$