Ejemplo n.º 1
0
	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();
		}
	}
Ejemplo n.º 2
0
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();
		}
	}
}