https://github.com/ViveIsAwesome/OpenVROverlayTest/blob/master/OpenVROverlayTest/Program.cs
https://gist.github.com/naveedmurtuza/6600103
dependency:
https://github.com/ValveSoftware/openvr/blob/master/headers/openvr_api.cs
https://github.com/ValveSoftware/openvr/tree/master/bin/win64
Here is the code to create an OpenVR overlay by C# and display text in the overlay
//Program.cs using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Drawing.Text; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using Valve.VR; namespace CSOpenVROverlayTest { class Program { public static CVRSystem hmd { get; private set; } public static CVRCompositor compositor { get; private set; } public static CVROverlay overlay { get; private set; } private static int stringIndex = 0; //ref: https://github.com/ViveIsAwesome/OpenVROverlayTest/blob/master/OpenVROverlayTest/Program.cs static void Main(string[] args) { string ResourcePath = new FileInfo(Assembly.GetEntryAssembly().Location).Directory.FullName + "/Resources/"; // init var error = EVRInitError.None; OpenVR.Init(ref error, EVRApplicationType.VRApplication_Overlay); if (error != EVRInitError.None) throw new Exception(); OpenVR.GetGenericInterface(OpenVR.IVRCompositor_Version, ref error); if (error != EVRInitError.None) throw new Exception(); OpenVR.GetGenericInterface(OpenVR.IVROverlay_Version, ref error); if (error != EVRInitError.None) throw new Exception(); hmd = OpenVR.System; compositor = OpenVR.Compositor; //compositor.FadeToColor(0.5f, 0, 0, 0, 1, true); //compositor.FadeToColor(0.5f, 0, 0, 0, 1, false); overlay = OpenVR.Overlay; ulong overlayHandle = 0; EVROverlayError eVROverlayError; eVROverlayError = overlay.CreateOverlay("overlayTestKey", "overlayTest", ref overlayHandle); overlay.ShowOverlay(overlayHandle); Font font = new Font(FontFamily.GenericSansSerif, 12.0F, FontStyle.Bold); Bitmap textImage = null; IntPtr? unmanagedPointer = null; DrawTextToOverlay(overlayHandle, displayText, font, Color.Red, 1000, ref textImage, ref unmanagedPointer); overlay.SetOverlayWidthInMeters(overlayHandle, 2.5f); int count = 0; while (true) { Console.Clear(); TrackedDevicePose_t[] trackedDevicePose_T = new TrackedDevicePose_t[1]; hmd.GetDeviceToAbsoluteTrackingPose(ETrackingUniverseOrigin.TrackingUniverseStanding, 0.0f, trackedDevicePose_T); HmdMatrix34_t hmdMatrix34_T = trackedDevicePose_T[0].mDeviceToAbsoluteTracking; PrintMatrix("hmdMatrix34_T", hmdMatrix34_T); Console.WriteLine(""); HmdVector3_t hmdPos = new HmdVector3_t(); OpenVRMathHelper.Set(ref hmdPos, hmdMatrix34_T.Element(0, 3), hmdMatrix34_T.Element(1, 3), hmdMatrix34_T.Element(2, 3)); HmdVector3_t yVec = new HmdVector3_t(); //make overlay tranform's up vector as (0, 1, 0) OpenVRMathHelper.Set(ref yVec, 0.0f, 1.0f, 0.0f); //overlay tranform's forward vector (only retain the x and z components to make the overlay upright) HmdVector3_t zVec = new HmdVector3_t(); OpenVRMathHelper.Set(ref zVec, hmdMatrix34_T.Element(0, 2), 0.0f, hmdMatrix34_T.Element(2, 2)); OpenVRMathHelper.Normalize(ref zVec); //calculate overlay transform's right vector HmdVector3_t xVec = OpenVRMathHelper.crossHmdVector3t(yVec, zVec); OpenVRMathHelper.Normalize(ref xVec); HmdVector3_t pos = new HmdVector3_t(); OpenVRMathHelper.Set(ref pos, ref hmdPos); HmdVector3_t forward = new HmdVector3_t(); OpenVRMathHelper.Set(ref forward, ref zVec); OpenVRMathHelper.Scale(ref forward, -5.0f); //move overlay along hmd's forward vector from hmd OpenVRMathHelper.Add(ref pos, ref forward); //PrintVec("hmdPos", hmdPos); //PrintVec("xVec", xVec); //PrintVec("yVec", yVec); //PrintVec("zVec", zVec); //PrintVec("forward", forward); //PrintVec("pos", pos); //Console.WriteLine(""); HmdMatrix34_t overlayTransform = new HmdMatrix34_t(); OpenVRMathHelper.Set(ref overlayTransform, ref xVec, ref yVec, ref zVec, ref pos); PrintMatrix("overlayTransform", overlayTransform); //hmdMatrix34_T.m11 -= 5.0f; Console.WriteLine(""); //overlay.SetOverlayTransformAbsolute(overlayHandle, ETrackingUniverseOrigin.TrackingUniverseStanding, ref hmdMatrix34_T); overlay.SetOverlayTransformAbsolute(overlayHandle, ETrackingUniverseOrigin.TrackingUniverseStanding, ref overlayTransform); //Console.Write(hmdMatrix34_T.m0 + ", " + hmdMatrix34_T.m1 + ", " + hmdMatrix34_T.m2 + ", " + hmdMatrix34_T.m3);Console.WriteLine(); //Console.Write(hmdMatrix34_T.m4 + ", " + hmdMatrix34_T.m5 + ", " + hmdMatrix34_T.m6 + ", " + hmdMatrix34_T.m7);Console.WriteLine(); //Console.Write(hmdMatrix34_T.m8 + ", " + hmdMatrix34_T.m9 + ", " + hmdMatrix34_T.m10 + ", " + hmdMatrix34_T.m11);Console.WriteLine(); //Console.WriteLine(); Thread.Sleep(10); count += 10; if(count == 1000)//after 1 sec { count = 0; DrawTextToOverlay(overlayHandle, displayText, font, Color.Red, 1000, ref textImage, ref unmanagedPointer); } } } public static void PrintMatrix(string name, HmdMatrix34_t matrix) { Console.WriteLine("matrix: " + name); for(int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { Console.Write(matrix.Element(i, j) + ", "); } Console.WriteLine(""); } } public static void PrintVec(string name, HmdVector3_t vec) { Console.WriteLine(name + ": " + vec.v0 + ", " + vec.v1 + ", " + vec.v2); } public static string displayText { get { string result = ""; switch(stringIndex) { case 0: result = "Hi "; break; case 1: result = "HiHi "; break; case 2: result = "HiHiHi "; break; case 3: result = "HiHiHiHi "; break; case 4: result = "HiHiHiHiHi"; break; } stringIndex = (stringIndex + 1) % 5; return result; } } public static void DrawTextToOverlay(ulong overlayHandle, string text, Font font, Color color, int maxWidth, ref Bitmap bitmap, ref IntPtr? intPtr) { GC.Collect(); if (bitmap != null) { bitmap.Dispose(); } int w, h; DrawTextToImage(ref bitmap, text, font, color, maxWidth, out w, out h); IntPtr? prevPtr = intPtr; byte[] imgBytes = null; bitmapToByteArray(bitmap, ref imgBytes); intPtr = Marshal.AllocHGlobal(imgBytes.Length); Marshal.Copy(imgBytes, 0, intPtr.Value, imgBytes.Length); overlay.SetOverlayRaw(overlayHandle, intPtr.Value, (uint)w, (uint)h, 4); if (prevPtr.HasValue) { Marshal.FreeHGlobal(prevPtr.Value); } } //ref: https://gist.github.com/naveedmurtuza/6600103 public static Bitmap DrawTextToImage(ref Bitmap img, String text, Font font, Color textColor, int maxWidth, out int width, out int height) { //first, create a dummy bitmap just to get a graphics object img = new Bitmap(1, 1); Graphics drawing = Graphics.FromImage(img); //measure the string to see how big the image needs to be string textToMeasure = text.Replace(" ", "_"); SizeF textSize = drawing.MeasureString(textToMeasure, font, maxWidth); //set the stringformat flags to rtl StringFormat sf = new StringFormat(); //uncomment the next line for right to left languages //sf.FormatFlags = StringFormatFlags.DirectionRightToLeft; sf.Trimming = StringTrimming.Word; //free up the dummy image and old graphics object img.Dispose(); drawing.Dispose(); //create a new image of the right size img = new Bitmap((int)textSize.Width, (int)textSize.Height); width = (int)textSize.Width; height = (int)textSize.Height; drawing = Graphics.FromImage(img); //Adjust for high quality drawing.CompositingQuality = CompositingQuality.HighQuality; drawing.InterpolationMode = InterpolationMode.HighQualityBilinear; drawing.PixelOffsetMode = PixelOffsetMode.HighQuality; drawing.SmoothingMode = SmoothingMode.HighQuality; drawing.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; //paint the background drawing.Clear(Color.Transparent); //create a brush for the text Brush textBrush = new SolidBrush(textColor); drawing.DrawString(text, font, textBrush, new RectangleF(0, 0, textSize.Width, textSize.Height), sf); drawing.Save(); textBrush.Dispose(); drawing.Dispose(); return img; } public static byte[] bitmapToByteArray(Bitmap bitmap, ref byte[] byteArray) { byteArray = new byte[bitmap.Width * bitmap.Height * 4]; int width = bitmap.Width; int height = bitmap.Height; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { Color c = bitmap.GetPixel(j, i); //byteArray[(i * width + j) * 4] = c.A; //byteArray[(i * width + j) * 4 + 1] = c.R; //byteArray[(i * width + j) * 4 + 2] = c.G; //byteArray[(i * width + j) * 4 + 3] = c.B; byteArray[(i * width + j) * 4] = c.R; byteArray[(i * width + j) * 4 + 1] = c.G; byteArray[(i * width + j) * 4 + 2] = c.B; byteArray[(i * width + j) * 4 + 3] = c.A; //Console.WriteLine(c.A); //Console.WriteLine(c.R); //Console.WriteLine(c.G); //Console.WriteLine(c.B); //Console.WriteLine("--"); } } return byteArray; } } } //OpenVRMathHelper.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Valve.VR; public static class OpenVRMathHelper { public static float calcHmdVector3tLength(ref HmdVector3_t v) { return (float)Math.Sqrt(v.v0 * v.v0 + v.v1 * v.v1 + v.v2 * v.v2); } public static void Set(ref HmdVector3_t vec, float x, float y, float z) { vec.v0 = x; vec.v1 = y; vec.v2 = z; } public static void Normalize(ref HmdVector3_t vec) { float length = calcHmdVector3tLength(ref vec); vec.v0 = vec.v0 / length; vec.v1 = vec.v1 / length; vec.v2 = vec.v2 / length; } public static void Scale(ref HmdVector3_t vec, float scale) { vec.v0 = vec.v0 * scale; vec.v1 = vec.v1 * scale; vec.v2 = vec.v2 * scale; } public static void Add(ref HmdVector3_t vec, ref HmdVector3_t vec2) { vec.v0 = vec.v0 + vec2.v0; vec.v1 = vec.v1 + vec2.v1; vec.v2 = vec.v2 + vec2.v2; } public static void Set(ref HmdMatrix34_t matrix, ref HmdVector3_t col0, ref HmdVector3_t col1, ref HmdVector3_t col2, ref HmdVector3_t col3) { SetElement(ref matrix, 0, 0, col0.v0); SetElement(ref matrix, 1, 0, col0.v1); SetElement(ref matrix, 2, 0, col0.v2); SetElement(ref matrix, 0, 1, col1.v0); SetElement(ref matrix, 1, 1, col1.v1); SetElement(ref matrix, 2, 1, col1.v2); SetElement(ref matrix, 0, 2, col2.v0); SetElement(ref matrix, 1, 2, col2.v1); SetElement(ref matrix, 2, 2, col2.v2); SetElement(ref matrix, 0, 3, col3.v0); SetElement(ref matrix, 1, 3, col3.v1); SetElement(ref matrix, 2, 3, col3.v2); } public static void SetElement(ref HmdMatrix34_t matrix, int r, int c, float value) { switch (r) { case 0: switch (c) { case 0: matrix.m0 = value; return; case 1: matrix.m1 = value; return; case 2: matrix.m2 = value; return; case 3: matrix.m3 = value; return; } break; case 1: switch (c) { case 0: matrix.m4 = value; return; case 1: matrix.m5 = value; return; case 2: matrix.m6 = value; return; case 3: matrix.m7 = value; return; } break; case 2: switch (c) { case 0: matrix.m8 = value; return; case 1: matrix.m9 = value; return; case 2: matrix.m10 = value; return; case 3: matrix.m11 = value; return; } break; } } }
Are you selling viagra?
回覆刪除