void Init() { PROFILE_SCOPED() frac = 1.0 / double(edgeLen-1); // also want vtx indices for tris not touching edge of patch indices.reset(new unsigned short[IDX_VBO_COUNT_ALL_IDX()]); unsigned short *idx = indices.get(); for (int x=0; x<edgeLen-1; x++) { for (int y=0; y<edgeLen-1; y++) { idx[0] = x + edgeLen*y; idx[1] = x+1 + edgeLen*y; idx[2] = x + edgeLen*(y+1); idx+=3; idx[0] = x+1 + edgeLen*y; idx[1] = x+1 + edgeLen*(y+1); idx[2] = x + edgeLen*(y+1); idx+=3; } } // these will hold the optimised indices std::vector<unsigned short> pl_short; // populate the N indices lists from the arrays built during InitTerrainIndices() // iterate over each index list and optimize it unsigned int tri_count = GetIndices(pl_short); VertexCacheOptimizerUShort vco; VertexCacheOptimizerUShort::Result res = vco.Optimize(&pl_short[0], tri_count); assert(0 == res); //create buffer & copy indexBuffer.Reset(Pi::renderer->CreateIndexBuffer(pl_short.size(), Graphics::BUFFER_USAGE_STATIC)); Uint16* idxPtr = indexBuffer->Map(Graphics::BUFFER_MAP_WRITE); for (Uint32 j = 0; j < pl_short.size(); j++) { idxPtr[j] = pl_short[j]; } indexBuffer->Unmap(); if (indices) { indices.reset(); } }
void GeoPatchContext::Init() { frac = 1.0 / double(edgeLen-1); vbotemp = new VBOVertex[NUMVERTICES()]; unsigned short *idx; midIndices.reset(new unsigned short[VBO_COUNT_MID_IDX()]); for (int i=0; i<4; i++) { loEdgeIndices[i].reset(new unsigned short[VBO_COUNT_LO_EDGE()]); hiEdgeIndices[i].reset(new unsigned short[VBO_COUNT_HI_EDGE()]); } /* also want vtx indices for tris not touching edge of patch */ idx = midIndices.get(); for (int x=1; x<edgeLen-2; x++) { for (int y=1; y<edgeLen-2; y++) { idx[0] = x + edgeLen*y; idx[1] = x+1 + edgeLen*y; idx[2] = x + edgeLen*(y+1); idx+=3; idx[0] = x+1 + edgeLen*y; idx[1] = x+1 + edgeLen*(y+1); idx[2] = x + edgeLen*(y+1); idx+=3; } } { for (int x=1; x<edgeLen-3; x+=2) { // razor teeth near edge 0 idx[0] = x + edgeLen; idx[1] = x+1; idx[2] = x+1 + edgeLen; idx+=3; idx[0] = x+1; idx[1] = x+2 + edgeLen; idx[2] = x+1 + edgeLen; idx+=3; } for (int x=1; x<edgeLen-3; x+=2) { // near edge 2 idx[0] = x + edgeLen*(edgeLen-2); idx[1] = x+1 + edgeLen*(edgeLen-2); idx[2] = x+1 + edgeLen*(edgeLen-1); idx+=3; idx[0] = x+1 + edgeLen*(edgeLen-2); idx[1] = x+2 + edgeLen*(edgeLen-2); idx[2] = x+1 + edgeLen*(edgeLen-1); idx+=3; } for (int y=1; y<edgeLen-3; y+=2) { // near edge 1 idx[0] = edgeLen-2 + y*edgeLen; idx[1] = edgeLen-1 + (y+1)*edgeLen; idx[2] = edgeLen-2 + (y+1)*edgeLen; idx+=3; idx[0] = edgeLen-2 + (y+1)*edgeLen; idx[1] = edgeLen-1 + (y+1)*edgeLen; idx[2] = edgeLen-2 + (y+2)*edgeLen; idx+=3; } for (int y=1; y<edgeLen-3; y+=2) { // near edge 3 idx[0] = 1 + y*edgeLen; idx[1] = 1 + (y+1)*edgeLen; idx[2] = (y+1)*edgeLen; idx+=3; idx[0] = 1 + (y+1)*edgeLen; idx[1] = 1 + (y+2)*edgeLen; idx[2] = (y+1)*edgeLen; idx+=3; } } // full detail edge triangles { idx = hiEdgeIndices[0].get(); for (int x=0; x<edgeLen-1; x+=2) { idx[0] = x; idx[1] = x+1; idx[2] = x+1 + edgeLen; idx+=3; idx[0] = x+1; idx[1] = x+2; idx[2] = x+1 + edgeLen; idx+=3; } idx = hiEdgeIndices[1].get(); for (int y=0; y<edgeLen-1; y+=2) { idx[0] = edgeLen-1 + y*edgeLen; idx[1] = edgeLen-1 + (y+1)*edgeLen; idx[2] = edgeLen-2 + (y+1)*edgeLen; idx+=3; idx[0] = edgeLen-1 + (y+1)*edgeLen; idx[1] = edgeLen-1 + (y+2)*edgeLen; idx[2] = edgeLen-2 + (y+1)*edgeLen; idx+=3; } idx = hiEdgeIndices[2].get(); for (int x=0; x<edgeLen-1; x+=2) { idx[0] = x + (edgeLen-1)*edgeLen; idx[1] = x+1 + (edgeLen-2)*edgeLen; idx[2] = x+1 + (edgeLen-1)*edgeLen; idx+=3; idx[0] = x+1 + (edgeLen-2)*edgeLen; idx[1] = x+2 + (edgeLen-1)*edgeLen; idx[2] = x+1 + (edgeLen-1)*edgeLen; idx+=3; } idx = hiEdgeIndices[3].get(); for (int y=0; y<edgeLen-1; y+=2) { idx[0] = y*edgeLen; idx[1] = 1 + (y+1)*edgeLen; idx[2] = (y+1)*edgeLen; idx+=3; idx[0] = (y+1)*edgeLen; idx[1] = 1 + (y+1)*edgeLen; idx[2] = (y+2)*edgeLen; idx+=3; } } // these edge indices are for patches with no // neighbour of equal or greater detail -- they reduce // their edge complexity by 1 division { idx = loEdgeIndices[0].get(); for (int x=0; x<edgeLen-2; x+=2) { idx[0] = x; idx[1] = x+2; idx[2] = x+1+edgeLen; idx += 3; } idx = loEdgeIndices[1].get(); for (int y=0; y<edgeLen-2; y+=2) { idx[0] = (edgeLen-1) + y*edgeLen; idx[1] = (edgeLen-1) + (y+2)*edgeLen; idx[2] = (edgeLen-2) + (y+1)*edgeLen; idx += 3; } idx = loEdgeIndices[2].get(); for (int x=0; x<edgeLen-2; x+=2) { idx[0] = x+edgeLen*(edgeLen-1); idx[2] = x+2+edgeLen*(edgeLen-1); idx[1] = x+1+edgeLen*(edgeLen-2); idx += 3; } idx = loEdgeIndices[3].get(); for (int y=0; y<edgeLen-2; y+=2) { idx[0] = y*edgeLen; idx[2] = (y+2)*edgeLen; idx[1] = 1 + (y+1)*edgeLen; idx += 3; } } // these will hold the optimised indices std::vector<unsigned short> pl_short[NUM_INDEX_LISTS]; // populate the N indices lists from the arrays built during InitTerrainIndices() for( int i=0; i<NUM_INDEX_LISTS; ++i ) { const unsigned int edge_hi_flags = i; indices_tri_counts[i] = getIndices(pl_short[i], edge_hi_flags); } // iterate over each index list and optimize it for( int i=0; i<NUM_INDEX_LISTS; ++i ) { int tri_count = indices_tri_counts[i]; VertexCacheOptimizerUShort vco; VertexCacheOptimizerUShort::Result res = vco.Optimize(&pl_short[i][0], tri_count); assert(0 == res); } // everything should be hunky-dory for setting up as OpenGL index buffers now. for( int i=0; i<NUM_INDEX_LISTS; ++i ) { glGenBuffersARB(1, &indices_list[i]); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, indices_list[i]); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*indices_tri_counts[i]*3, &(pl_short[i][0]), GL_STATIC_DRAW); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0); } // default it to the last entry which uses the hi-res borders indices_vbo = indices_list[NUM_INDEX_LISTS-1]; indices_tri_count = indices_tri_counts[NUM_INDEX_LISTS-1]; if (midIndices) { midIndices.reset(); for (int i=0; i<4; i++) { loEdgeIndices[i].reset(); hiEdgeIndices[i].reset(); } } }