Example #1
0
void Terrain::RenewNodes(const vec3& viewpoint, const QuadTree<TerrainNode>::Iterator& node)
{
	//Check if this node must be enabled using morph-factor
	float sz = static_cast<float>(node.LayerSize());
	float l = node.Offset().x / sz, r = (node.Offset().x + 1) / sz;
	float u = node.Offset().y / sz, d = (node.Offset().y + 1) / sz;
	vec3 rel_pos = vec3(inverse(GetModelMatrix()) * vec4(viewpoint, 1.0f));
	rel_pos.x = ClosestSegmentPoint(rel_pos.x, l, r);
	rel_pos.y = ClosestSegmentPoint(rel_pos.y, node->heights.x, node->heights.y);
	rel_pos.z = ClosestSegmentPoint(rel_pos.z, u, d);
	if (length(rel_pos)*length(rel_pos) / 
		(1.0f + node->heights.y - node->heights.x) / 
		(r - l) / (d - u) > 5.0f || 
		node.Level() == maxLOD)
	{
		//This node is probably enabled
	}
	else
	{
		//This node is not enabled
		//continue checking its children
		DisableNodes(node);
		RenewNodes(viewpoint, node.Child(1));
		RenewNodes(viewpoint, node.Child(0));
		RenewNodes(viewpoint, node.Child(3));
		RenewNodes(viewpoint, node.Child(2));
	}
}
Example #2
0
vec2 Terrain::LoadVertices(
	const QuadTree<TerrainNode>::Iterator& node, 
	const Image& hmap
	)
{
	//Setup vertex data
	vec2 res = vec2(1.0f, 0.0f);
	int verticesCount = (lodResolution + 1) * (lodResolution + 1);
	vector<vec3> vertices(verticesCount), colors(verticesCount);
	float deltaX = 1.0f / node.LayerSize() / lodResolution;
	float deltaY = 1.0f / node.LayerSize() / lodResolution;
	float x = node.OffsetFloat().x;
	for (int i = 0; i <= lodResolution; i++, x += deltaX)
	{
		float y = node.OffsetFloat().y;
		for (int j = 0; j <= lodResolution; j++, y += deltaY)
		{
			float h = hmap[vec2(x, y)].x;
			res = UniteSegments(res, vec2(h));

			vertices[i*lodResolution + i + j] = vec3(x, h, y);
			colors[i*lodResolution + i + j] = vec3(0.2f, 0.2f + h, 0.4f - h);
		}
	}

	// VAO allocation
	glGenVertexArrays(1, &node->vaoID);
	// VAO setup
	glBindVertexArray(node->vaoID);
	// VBOs allocation
	glGenBuffers(2, node->vboID);
	// VBOs setup
	// vertices buffer
	glBindBuffer(GL_ARRAY_BUFFER, node->vboID[0]);
	glBufferData(GL_ARRAY_BUFFER, vertices.size() * 3 * sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
	glEnableVertexAttribArray(0);
	// colors buffer
	glBindBuffer(GL_ARRAY_BUFFER, node->vboID[1]);
	glBufferData(GL_ARRAY_BUFFER, colors.size() * 3 * sizeof(GLfloat), colors.data(), GL_STATIC_DRAW);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
	glEnableVertexAttribArray(1);
	// indices buffer
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, GetIndicesBufferID());

	OPENGL_CHECK_FOR_ERRORS();
	// release vertex data
	vertices.clear();
	colors.clear();

	if (node.Level() < maxLOD)
	{
        for (int i : {0, 1, 2, 3})
            res = UniteSegments(res, LoadVertices(node.Add(i), hmap));
	}
	node->heights = res;

	return res;
}