public static List <BuiltIn> GetUniformBuiltIns() { if (_uniformBuiltins == null) { _startTime = DateTime.Now; Register("_worldToClip", (location, display) => { float[] w2c = display.GetOpenGLWorldToClip(true); OpenGL.glUniformMatrix4fv(location, 1, false, w2c); }); Register("_viewportSize", (location, display) => { var viewportSize = display.Viewport.Size; OpenGL.glUniform2f(location, (float)viewportSize.Width, (float)viewportSize.Height); }); Register("_worldToCamera", (location, display) => { float[] w2c = display.GetOpenGLWorldToCamera(true); OpenGL.glUniformMatrix4fv(location, 1, false, w2c); }); Register("_worldToCameraNormal", (location, display) => { var xf = display.Viewport.GetTransform(Rhino.DocObjects.CoordinateSystem.World, Rhino.DocObjects.CoordinateSystem.Camera); xf = xf.Transpose(); Rhino.Geometry.Transform m; xf.TryGetInverse(out m); m = m.Transpose(); float[] w2cn = new float[] { (float)m.M00, (float)m.M01, (float)m.M02, (float)m.M10, (float)m.M11, (float)m.M12, (float)m.M20, (float)m.M21, (float)m.M22 }; OpenGL.glUniformMatrix3fv(location, 1, false, w2cn); }); Register("_worldToScreen", (location, display) => { var xf = display.Viewport.GetTransform(Rhino.DocObjects.CoordinateSystem.World, Rhino.DocObjects.CoordinateSystem.Screen); xf = xf.Transpose(); Rhino.Geometry.Transform m; xf.TryGetInverse(out m); m = m.Transpose(); float[] w2cn = new float[] { (float)m.M00, (float)m.M01, (float)m.M02, (float)m.M03, (float)m.M10, (float)m.M11, (float)m.M12, (float)m.M13, (float)m.M20, (float)m.M21, (float)m.M22, (float)m.M23 }; OpenGL.glUniformMatrix4fv(location, 1, false, w2cn); }); Register("_cameraToClip", (location, display) => { float[] c2c = display.GetOpenGLCameraToClip(); OpenGL.glUniformMatrix4fv(location, 1, false, c2c); }); Register("_time", (location, display) => { var span = DateTime.Now - _startTime; double seconds = span.TotalSeconds; OpenGL.glUniform1f(location, (float)seconds); }); Register("_cameraLocation", (location, display) => { var camLoc = display.Viewport.CameraLocation; OpenGL.glUniform3f(location, (float)camLoc.X, (float)camLoc.Y, (float)camLoc.Z); }); const int maxlights = 4; Register("_lightCount", (location, display) => { // Use reflection until 6.3 goes to release candidate. GetLights is not available until 6.3 //var lights = display.GetLights(); var lights = GetLightsHelper(display); int count = lights.Length < maxlights ? lights.Length : 4; OpenGL.glUniform1i(location, count); }); Register($"_lightPosition[{maxlights}]", (location, display) => { // Use reflection until 6.3 goes to release candidate. GetLights is not available until 6.3 //var lights = display.GetLights(); var lights = GetLightsHelper(display); float[] v = new float[3 * maxlights]; for (int i = 0; i < lights.Length; i++) { if (i >= maxlights) { break; } var loc = lights[i].Location; v[i * 3] = (float)loc.X; v[i * 3 + 1] = (float)loc.Y; v[i * 3 + 2] = (float)loc.Z; } OpenGL.glUniform3fv(location, maxlights, v); }); Register($"_lightDirection[{maxlights}]", (location, display) => { // Use reflection until 6.3 goes to release candidate. GetLights is not available until 6.3 //var lights = display.GetLights(); var lights = GetLightsHelper(display); float[] v = new float[3 * maxlights]; for (int i = 0; i < lights.Length; i++) { if (i >= maxlights) { break; } var direction = lights[i].Direction; v[i * 3] = (float)direction.X; v[i * 3 + 1] = (float)direction.Y; v[i * 3 + 2] = (float)direction.Z; } OpenGL.glUniform3fv(location, maxlights, v); }); Register($"_lightInCameraSpace[{maxlights}]", (location, display) => { // Use reflection until 6.3 goes to release candidate. GetLights is not available until 6.3 //var lights = display.GetLights(); var lights = GetLightsHelper(display); int[] v = new int[maxlights]; for (int i = 0; i < lights.Length; i++) { if (i >= maxlights) { break; } bool isCameraLight = lights[i].CoordinateSystem == Rhino.DocObjects.CoordinateSystem.Camera; v[i] = isCameraLight ? 1 : 0; } OpenGL.glUniform1iv(location, maxlights, v); }); _uniformBuiltins.Sort((a, b) => (a.Name.CompareTo(b.Name))); } return(_uniformBuiltins); }