private bool CalculateNormals() { // Create a temporary array to hold the un-normalized normal verctors. var normals = new Vector3[(TerrainHeight - 1) * (TerrainWidth - 1)]; // Go through all the faces in the mesh and calculate their normals. for (var j = 0; j < (TerrainHeight - 1); j++) { for (var i = 0; i < (TerrainWidth - 1); i++) { var index1 = (j * TerrainHeight) + i; var index2 = (j * TerrainHeight) + (i + 1); var index3 = ((j + 1) * TerrainHeight) + i; // Get three vertices from the face. var vertex1 = new[] { HeightMap[index1].x, HeightMap[index1].y, HeightMap[index1].z }; var vertex2 = new[] { HeightMap[index2].x, HeightMap[index2].y, HeightMap[index2].z }; var vertex3 = new[] { HeightMap[index3].x, HeightMap[index3].y, HeightMap[index3].z }; // Calculate the two vectors for this face. var vector1 = new[] { vertex1[0] - vertex3[0], vertex1[1] - vertex3[1], vertex1[2] - vertex3[2] }; var vector2 = new[] { vertex3[0] - vertex2[0], vertex3[1] - vertex2[1], vertex3[2] - vertex2[2] }; var index = (j * (TerrainHeight - 1)) + i; // Calculate the cross product of those two vectors to get the un-normalized value for this face normal. normals[index] = new Vector3() { X = (vector1[1] * vector2[2]) - (vector1[2] * vector2[1]), Y = (vector1[2] * vector2[0]) - (vector1[0] * vector2[2]), Z = (vector1[0] * vector2[1]) - (vector1[1] * vector2[0]) }; } } // Now go through all the vertices and take an average of each face normal // that the vertex touches to get the averaged normal fot that vertex. for (var j = 0; j < (TerrainHeight - 1); j++) { for (var i = 0; i < (TerrainWidth - 1); i++) { int index; // Initialize the sum var sum = new[] { 0f, 0f, 0f }; // Initialize the count var count = 0; // Bottom left face if (((i - 1) >= 0) && ((j - 1) >= 0)) { index = ((j - 1) * (TerrainHeight - 1)) + (i - 1); sum[0] += normals[index].X; sum[1] += normals[index].Y; sum[2] += normals[index].Z; count++; } // Bottom right face if ((i < (TerrainWidth - 1)) && ((j - 1) >= 0)) { index = ((j - 1) * (TerrainHeight - 1)) + i; sum[0] += normals[index].X; sum[1] += normals[index].Y; sum[2] += normals[index].Z; count++; } // Upper left face if (((i - 1) >= 0) && (j < (TerrainHeight - 1))) { index = (j * (TerrainHeight - 1)) + i; sum[0] += normals[index].X; sum[1] += normals[index].Y; sum[2] += normals[index].Z; count++; } // Upper right face if ((i < (TerrainWidth - 1)) && (j < (TerrainHeight - 1))) { index = (j * (TerrainHeight - 1)) + i; sum[0] += normals[index].X; sum[1] += normals[index].Y; sum[2] += normals[index].Z; count++; } // Take the average of the faces touching this vertex. sum[0] /= count; sum[1] /= count; sum[2] /= count; // Calculate the length of this normal. var length = (float)Math.Sqrt(sum[0] * sum[0] + sum[1] * sum[1] + sum[2] * sum[2]); // Get the index to the vertex location in the height map array. index = (j * TerrainHeight) + i; // Normalize the final share normal fot this vertex and store it in the height map array. var heightMap = HeightMap[index]; heightMap.nx = sum[0] / length; heightMap.ny = sum[1] / length; heightMap.nz = sum[2] / length; HeightMap[index] = heightMap; } } return true; }
private bool UpdateBuffers(DeviceContext deviceContext, int positionX, int positionY) { // If the position we rendering this bitmap to has not changed then don't update the vertex buffer since it. if (positionX == PreviousPosX && positionY == PreviousPosY) return true; // If it has changed then update the position it is being rendered to. PreviousPosX = positionX; PreviousPosY = positionY; // Calculate the screen coordinates of the left side of the bitmap. var left = (-(ScreenWidth >> 1)) + (float)positionX; // Calculate the screen coordinates of the right side of the bitmap. var right = left + BitmapWidth; // Calculate the screen coordinates of the top of the bitmap. var top = (ScreenHeight >> 1) - (float)positionY; // Calculate the screen coordinates of the bottom of the bitmap. var bottom = top - BitmapHeight; // Create and load the vertex array. var vertices = new[] { new TextureShader.Vertex() { position = new Vector3(left, top, 0), texture = new Vector2(0, 0) }, new TextureShader.Vertex() { position = new Vector3(right, bottom, 0), texture = new Vector2(1, 1) }, new TextureShader.Vertex() { position = new Vector3(left, bottom, 0), texture = new Vector2(0, 1) }, new TextureShader.Vertex() { position = new Vector3(left, top, 0), texture = new Vector2(0, 0) }, new TextureShader.Vertex() { position = new Vector3(right, top, 0), texture = new Vector2(1, 0) }, new TextureShader.Vertex() { position = new Vector3(right, bottom, 0), texture = new Vector2(1, 1) } }; DataStream mappedResource; #region Vertex Buffer // Lock the vertex buffer so it can be written to. deviceContext.MapSubresource(VertexBuffer, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out mappedResource); // Copy the data into the vertex buffer. mappedResource.WriteRange<TextureShader.Vertex>(vertices); // Unlock the vertex buffer. deviceContext.UnmapSubresource(VertexBuffer, 0); #endregion return true; }