public void SetData(TriangleBuffer triangles, BufferUsageHint usageHint) { _indexCount = triangles.IndexCount; if (_indexCount % 3 != 0) { throw new IndexOutOfRangeException("Number of index entries must be divisible by 3."); } if (_indexCount == 0) { Dispose(); return; } if (_vertexArray == 0) { _vertexArray = GL.GenVertexArray(); _elementArrayBuffer = GL.GenBuffer(); _arrayBuffer = GL.GenBuffer(); GL.BindVertexArray(_vertexArray); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _elementArrayBuffer); GL.BindBuffer(BufferTarget.ArrayBuffer, _arrayBuffer); _specification.Bind(); } else { GL.BindBuffer(BufferTarget.ElementArrayBuffer, _elementArrayBuffer); GL.BindBuffer(BufferTarget.ArrayBuffer, _arrayBuffer); } triangles.UploadData(usageHint); }
public void SetData(TriangleBuffer triangles, BufferUsageHint usageHint) { _indexCount = triangles.IndexCount; if (_indexCount % 3 != 0) throw new IndexOutOfRangeException("Number of index entries must be divisible by 3."); if (_indexCount == 0) { Dispose(); return; } if (_vertexArray == 0) { _vertexArray = GL.GenVertexArray(); _elementArrayBuffer = GL.GenBuffer(); _arrayBuffer = GL.GenBuffer(); GL.BindVertexArray(_vertexArray); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _elementArrayBuffer); GL.BindBuffer(BufferTarget.ArrayBuffer, _arrayBuffer); _specification.Bind(); } else { GL.BindBuffer(BufferTarget.ElementArrayBuffer, _elementArrayBuffer); GL.BindBuffer(BufferTarget.ArrayBuffer, _arrayBuffer); } triangles.UploadData(usageHint); }
private void DrawBlockBottom(TriangleBuffer buffer, WorldTextureAtlas.TextureEntry textureEntry, float x, float y, float z, float highlight) { buffer.Triangle(0, 1, 3); buffer.Triangle(3, 1, 2); buffer.VertexFloat(x - 0.5f, y - 0.5f, z + 0.5f); buffer.VertexUInt16(textureEntry.X0, textureEntry.Y0); buffer.VertexColorBytes(0.33f, 0.33f, 0.33f, highlight); buffer.EndVertex(); buffer.VertexFloat(x - 0.5f, y - 0.5f, z - 0.5f); buffer.VertexUInt16(textureEntry.X0, textureEntry.Y1); buffer.VertexColorBytes(0.33f, 0.33f, 0.33f, highlight); buffer.EndVertex(); buffer.VertexFloat(x + 0.5f, y - 0.5f, z - 0.5f); buffer.VertexUInt16(textureEntry.X1, textureEntry.Y1); buffer.VertexColorBytes(0.33f, 0.33f, 0.33f, highlight); buffer.EndVertex(); buffer.VertexFloat(x + 0.5f, y - 0.5f, z + 0.5f); buffer.VertexUInt16(textureEntry.X1, textureEntry.Y0); buffer.VertexColorBytes(0.33f, 0.33f, 0.33f, highlight); buffer.EndVertex(); }
private void DrawEntity(TriangleBuffer buffer, float x, float y, float z, float xRadius, float height) { var textureEntry = _textureAtlas.GetTextureEntry(0); buffer.Triangle(0, 1, 3); buffer.Triangle(3, 1, 2); buffer.VertexFloat(x - xRadius, y, z + xRadius); buffer.VertexUInt16(textureEntry.X0, textureEntry.Y0); buffer.VertexByte(217, 217, 217, 0); buffer.EndVertex(); buffer.VertexFloat(x + xRadius, y, z + xRadius); buffer.VertexUInt16(textureEntry.X1, textureEntry.Y0); buffer.VertexByte(217, 217, 217, 0); buffer.EndVertex(); buffer.VertexFloat(x + xRadius, y + height, z + xRadius); buffer.VertexUInt16(textureEntry.X1, textureEntry.Y1); buffer.VertexByte(217, 217, 217, 0); buffer.EndVertex(); buffer.VertexFloat(x - xRadius, y + height, z + xRadius); buffer.VertexUInt16(textureEntry.X0, textureEntry.Y1); buffer.VertexByte(217, 217, 217, 0); buffer.EndVertex(); buffer.Triangle(0, 1, 3); buffer.Triangle(3, 1, 2); buffer.VertexFloat(x + xRadius, y, z + xRadius); buffer.VertexUInt16(textureEntry.X0, textureEntry.Y0); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.VertexFloat(x + xRadius, y, z - xRadius); buffer.VertexUInt16(textureEntry.X1, textureEntry.Y0); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.VertexFloat(x + xRadius, y + height, z - xRadius); buffer.VertexUInt16(textureEntry.X1, textureEntry.Y1); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.VertexFloat(x + xRadius, y + height, z + xRadius); buffer.VertexUInt16(textureEntry.X0, textureEntry.Y1); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.Triangle(0, 1, 3); buffer.Triangle(3, 1, 2); buffer.VertexFloat(x + xRadius, y, z - xRadius); buffer.VertexUInt16(textureEntry.X0, textureEntry.Y0); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.VertexFloat(x - xRadius, y, z - xRadius); buffer.VertexUInt16(textureEntry.X1, textureEntry.Y0); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.VertexFloat(x - xRadius, y + height, z - xRadius); buffer.VertexUInt16(textureEntry.X1, textureEntry.Y1); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.VertexFloat(x + xRadius, y + height, z - xRadius); buffer.VertexUInt16(textureEntry.X0, textureEntry.Y1); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.Triangle(0, 1, 3); buffer.Triangle(3, 1, 2); buffer.VertexFloat(x - xRadius, y, z - xRadius); buffer.VertexUInt16(textureEntry.X0, textureEntry.Y0); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.VertexFloat(x - xRadius, y, z + xRadius); buffer.VertexUInt16(textureEntry.X1, textureEntry.Y0); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.VertexFloat(x - xRadius, y + height, z + xRadius); buffer.VertexUInt16(textureEntry.X1, textureEntry.Y1); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.VertexFloat(x - xRadius, y + height, z - xRadius); buffer.VertexUInt16(textureEntry.X0, textureEntry.Y1); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.Triangle(0, 1, 3); buffer.Triangle(3, 1, 2); buffer.VertexFloat(x - xRadius, y, z + xRadius); buffer.VertexUInt16(textureEntry.X0, textureEntry.Y0); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.VertexFloat(x - xRadius, y, z - xRadius); buffer.VertexUInt16(textureEntry.X1, textureEntry.Y0); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.VertexFloat(x + xRadius, y, z - xRadius); buffer.VertexUInt16(textureEntry.X1, textureEntry.Y1); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.VertexFloat(x + xRadius, y, z + xRadius); buffer.VertexUInt16(textureEntry.X0, textureEntry.Y1); buffer.VertexByte(178, 204, 230, 0); buffer.EndVertex(); buffer.Triangle(0, 1, 3); buffer.Triangle(3, 1, 2); buffer.VertexFloat(x - xRadius, y + height, z + xRadius); buffer.VertexUInt16(textureEntry.X0, textureEntry.Y0); buffer.VertexByte(255, 255, 255, 0); buffer.EndVertex(); buffer.VertexFloat(x + xRadius, y + height, z + xRadius); buffer.VertexUInt16(textureEntry.X1, textureEntry.Y0); buffer.VertexByte(255, 255, 255, 0); buffer.EndVertex(); buffer.VertexFloat(x + xRadius, y + height, z - xRadius); buffer.VertexUInt16(textureEntry.X1, textureEntry.Y1); buffer.VertexByte(255, 255, 255, 0); buffer.EndVertex(); buffer.VertexFloat(x - xRadius, y + height, z - xRadius); buffer.VertexUInt16(textureEntry.X0, textureEntry.Y1); buffer.VertexByte(255, 255, 255, 0); buffer.EndVertex(); }
private void RenderChunk(TriangleBuffer buffer, Chunk chunk) { var offset = chunk.Pos - new BlockPos(0, 0, 0); float xOffset = offset.X + 0.5f; float yOffset = offset.Y + 0.5f; float zOffset = offset.Z + 0.5f; for (int y = GeometryConstants.ChunkSize - 1; y >= 0; --y) { for (int x = 0; x < GeometryConstants.ChunkSize; ++x) { for (int z = 0; z < GeometryConstants.ChunkSize; ++z) { ushort material = chunk[x, y, z]; if (material != 0) { var textureEntry = _textureAtlas.GetTextureEntry(material); float x1 = x + xOffset, y1 = y + yOffset, z1 = z + zOffset; if (x == 0 || chunk[x - 1, y, z] == 0) DrawBlockLeft(buffer, textureEntry, x1, y1, z1, 0); if (x == GeometryConstants.ChunkSize - 1 || chunk[x + 1, y, z] == 0) DrawBlockRight(buffer, textureEntry, x1, y1, z1, 0); if (y == 0 || chunk[x, y - 1, z] == 0) DrawBlockBottom(buffer, textureEntry, x1, y1, z1, 0); if (y == GeometryConstants.ChunkSize - 1 || chunk[x, y + 1, z] == 0) DrawBlockTop(buffer, textureEntry, x1, y1, z1, 0); if (z == 0 || chunk[x, y, z - 1] == 0) DrawBlockBack(buffer, textureEntry, x1, y1, z1, 0); if (z == GeometryConstants.ChunkSize - 1 || chunk[x, y, z + 1] == 0) DrawBlockFront(buffer, textureEntry, x1, y1, z1, 0); } } } } }
private void RenderBlocks(GameClient gameClient) { GL.UseProgram(_cubeShader.Value.Id); GL.UniformMatrix4(0, false, ref _projectionMatrix); GL.UniformMatrix4(4, false, ref _modelViewMatrix); var cameraChunkPos = (ChunkPos)gameClient.PositionData.Placement.Pos; var offset = (gameClient.PositionData.Placement.Pos - EntityPos.Origin) + new EntityOffset(0, gameClient.PhysicsValues.PlayerEyeHeight, 0); int chunkUpdates = 0; ChunkPos.IterateOutwards( cameraChunkPos, ChunkViewRadiusXZ, ChunkViewRadiusY, chunkPos => { ChunkBufferEntry entry; _chunkBuffers.TryGetValue(chunkPos, out entry); /* Don't let nearby entries expire. */ if (entry != null) entry.LastAccess = _currentFrameTime; if (!IsInViewingFrustum(gameClient, offset, chunkPos)) return; var chunk = gameClient.World.PeekChunk(chunkPos); if (chunk != null && chunk.HasData) { if (entry == null) { entry = new ChunkBufferEntry { LastAccess = _currentFrameTime }; _chunkBuffers[chunkPos] = entry; } if (entry.ContentHash != chunk.ContentHash) { if (chunkUpdates < 5 && entry.TriangleTask != null && entry.TriangleTask.IsCompleted) { var triangles = entry.TriangleTask.Result; if (entry.TriangleTaskContentHash == chunk.ContentHash) { ++chunkUpdates; if (entry.VertexArray == null) entry.VertexArray = new VertexArray(_cubeVertexSpecification); entry.VertexArray.SetData(triangles, BufferUsageHint.StaticDraw); entry.ContentHash = chunk.ContentHash; } triangles.Dispose(); entry.TriangleTask = null; entry.TriangleTaskContentHash = 0; } if (entry.ContentHash != chunk.ContentHash && entry.TriangleTask == null) { var triangleBuffer = new TriangleBuffer(_cubeVertexSpecification); var localChunk = chunk; entry.TriangleTask = Task.Run(() => { RenderChunk(triangleBuffer, localChunk); return triangleBuffer; }); entry.TriangleTaskContentHash = chunk.ContentHash; } } entry.VertexArray?.Draw(); } }); GL.UseProgram(0); RemoveExpiredChunks(); }