public void OnWindowRender(double delta) { var size = _game.Window.Size; GFX.Viewport(size); GFX.Clear(Color.Indigo); _program.Use(); Aspect <ICameraAspect> .ForEach(_game, camera => { // Get the camera's transform matrix and invert it. Matrix4x4.Invert(camera.Transform, out var cameraTransform); // Create the camera's projection matrix, either ortho or perspective. var cameraProjection = camera.Camera.IsOrthographic ? Matrix4x4.CreateOrthographic(size.Width, -size.Height, camera.Camera.NearPlane, camera.Camera.FarPlane) : Matrix4x4.CreatePerspectiveFieldOfView( camera.Camera.FieldOfView *MathF.PI / 180, // Degrees => Radians (float)size.Width / size.Height, // Aspect Ratio camera.Camera.NearPlane, camera.Camera.FarPlane); // Set the uniform to the combined transform and projection. _cameraMatrixUniform.Set(cameraTransform *cameraProjection); Aspect <IRenderableAspect> .ForEach(_game, renderable => { _modelMatrixUniform.Set(renderable.Transform); // If entity has Texture, bind it now. if (renderable.Texture != null) { renderable.Texture.Value.Bind(); } // If entity has SpriteIndex, only render two // triangles out of the mesh specified by that index. if (renderable.SpriteIndex != null) { renderable.Mesh.Draw(renderable.SpriteIndex.Value * 6, 6); } // Otherwise just render the entire mesh like usual. renderable.Mesh.Draw(); // If entity has Texture, unbind it after it has been rendered. if (renderable.Texture != null) { renderable.Texture.Value.Unbind(); } }); }); VertexArray.Unbind(); }