using System; using System.ComponentModel; using System.Windows.Forms; using System.Diagnostics; using System.Runtime.InteropServices; using Tao.OpenGl; using Tao.Platform.Windows; using OpenCvSharp; using System.Collections.Generic; using System.Drawing; namespace PaintDotNet.Instrument { public partial class SurfacePlotWindow : PdnBaseForm { private GroupBox groupBox1; // --- Fields --- private static IntPtr hDC; // Private GDI Device Context private static IntPtr hRC; // Permanent Rendering Context public static SurfacePlotWindow form; // Our Current Windows Form private static bool active = true; // Window Active Flag, Set To True By Default private static bool done = false; // Bool Variable To Exit Main Loop private AppWorkspace appWorkspace; /// /// 三维数据 /// private Base.SettingModel.ThreeDataDemoModel threeDataDemo; //for XML int m_iWidth; int m_iHeight; int m_iDLevel; double[] m_adDZ; double[,] m_adDC; double[,] m_adZV; double[,] m_adOverTurnZV; double m_dMaxZV; double m_dMinZV; float[, ,] m_afNewClr; //bmp float[, ,] m_afOrgClr; //new platform private System.Windows.Forms.PictureBox pictureBox1; int m_iMusDown = 0; //zzz public static/* const*/ int LINE_PNTS = 100; //Glfw.GLFWkeyfun m_funKeyCallBak; //Glfw.GLFWmousebuttonfun m_funMsBtnCallBak; //Glfw.GLFWmouseposfun m_funMsPosCallBak; int m_iMusMod = 1;//0; int m_iLastmouseX, m_iLastmouseY; int m_iLastMusDown = 0; float[] m_fR_xyz = new float[3] { 0.0F, 0.0F, 0.0F }; float[] m_fT_xyz = new float[3] { 0.0F, 0.0F, 0.0F }; bool m_bOverTurn = false; bool m_bRulerColor = true; float[] m_afPonitA = new float[2] { 1.0F, 1.0F }; float[] m_afPonitB = new float[2] { 1.0F, 1.0F }; float[] m_afLineStep = new float[2] { 0.0F, 0.0F }; float[,] m_afLineXY = new float[/*LINE_PNTS - 2*/98, 2]; double[] m_adLineZV = new double[/*LINE_PNTS*/100]; double[] m_adLineOverTurnZV = new double[/*LINE_PNTS*/100]; //SRLinesForm m_fmLine; float[, ,] m_afThisClr; double[,] m_adThisZV; double[] m_adThisLineZV; internal SurfacePlotWindow(AppWorkspace appWorkspace) { this.appWorkspace = appWorkspace; InitializeComponent(); InitializeLanguageText(); this.CreateParams.ClassStyle = this.CreateParams.ClassStyle | // Redraw On Size, And Own DC For Window. User.CS_HREDRAW | User.CS_VREDRAW | User.CS_OWNDC; this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); // No Need To Erase Form Background this.SetStyle(ControlStyles.DoubleBuffer, true); // Buffer Control //zzz this.SetStyle(ControlStyles.Opaque, true); // No Need To Draw Form Background this.SetStyle(ControlStyles.ResizeRedraw, true); // Redraw On Resize this.SetStyle(ControlStyles.UserPaint, true); // We'll Handle Painting Ourselves this.Activated += new EventHandler(this.Form_Activated); // On Activate Event Call Form_Activated this.Closing += new CancelEventHandler(this.Form_Closing); // On Closing Event Call Form_Closing this.Deactivate += new EventHandler(this.Form_Deactivate); // On Deactivate Event Call Form_Deactivate //this.KeyUp += new KeyEventHandler(this.Form_KeyUp); // On KeyUp Event Call Form_KeyUp this.Resize += new EventHandler(this.Form_Resize); //this.Close(); ReadPar(); } private void InitializeLanguageText() { this.groupBox1.Text = "";// "三维图像"; this.Text = PdnResources.GetString("Menu.Tools.SurfacePlot.Text"); } /// /// 初始化基础控件 /// public void InitializeComponent() { this.groupBox1 = new System.Windows.Forms.GroupBox(); this.SuspendLayout(); // // groupBox1 // this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); this.groupBox1.Location = new System.Drawing.Point(20, 20); this.groupBox1.Margin = new System.Windows.Forms.Padding(4); this.groupBox1.Name = "groupBox1"; this.groupBox1.Padding = new System.Windows.Forms.Padding(4); this.groupBox1.Size = new System.Drawing.Size(588, 424); this.groupBox1.TabIndex = 1; this.groupBox1.TabStop = false; // // SurfacePlotWindow // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(612, 425); this.Controls.Add(this.groupBox1); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.Margin = new System.Windows.Forms.Padding(4); this.MaximizeBox = false; this.MaximumSize = new System.Drawing.Size(648, 504); this.MinimizeBox = false; this.MinimumSize = new System.Drawing.Size(648, 504); this.Name = "SurfacePlotWindow"; this.Text = "SurfacePlotWindow"; this.Controls.SetChildIndex(this.groupBox1, 0); this.ResumeLayout(false); } //private Mat ImMer; public Base.SettingModel.ThreeDataDemoModel CreateThreeDataDemoModel() { Mat origMat = this.appWorkspace.ActiveDocumentWorkspace.CompositionSurface.CreatedAliasedMat(); string mode = "H"; int maxSize = 640; if (origMat.Width > origMat.Height) mode = "W"; Mat oriMat; if (maxSize >= origMat.Height && maxSize >= origMat.Width) oriMat = origMat;// PaintDotNet.Camera.Tools.ToMat(origin); else oriMat = Surface.MakeThumbnailMat(origMat, maxSize, maxSize, mode);//待测试 ////string fileName = System.Windows.Forms.Application.StartupPath + "\\ThreeDataDemo_temp.xml"; //this.ImMer = new Mat(oriMat.Size(), MatType.CV_8UC1/*4/*, oriMat.Type()*/);//Scalar.All(255)) Mat matGray = oriMat.CvtColor(ColorConversionCodes.BGR2GRAY); int dstWidth = oriMat.Width; int matHeight = oriMat.Height; //dataValueList = new List(); //threedDataList = new List>(); threeDataDemo = new Base.SettingModel.ThreeDataDemoModel();// Base.CommTool.XmlSerializeHelper.DESerializer(Base.CommTool.FileOperationHelper.ReadStringFromFile(System.Windows.Forms.Application.StartupPath + "\\Config\\" + "Default"/*SettingPrefix*/ + "\\ThreeDataDemo.xml", System.IO.FileMode.Open)); threeDataDemo.size = new Base.SettingModel.ThreeDataDemoModel.Size();//.Height = coll[0].Height; threeDataDemo.size.Height = matHeight; threeDataDemo.size.Width = dstWidth; threeDataDemo.Z_value = new List(); for (int threeD = 0; threeD < dstWidth; threeD++) { List threedData = new List(); for (int indexY = 0; indexY < matHeight; indexY++) threedData.Add(matGray.At(indexY, threeD)); //threedDataList.Add(threedData); threeDataDemo.Z_value.Add(string.Join(",", threedData.ToArray())); } //coll[0].ForEachAsDouble(DefineProfileForEachAsVec4bForHeight); //if (this.ImMer != null) //{ // Mat matGray = this.ImMer.CvtColor(ColorConversionCodes.BGR2GRAY); // for (int index_x = 0; index_x < threedDataList.Count; index_x++) // { // List threedData = threedDataList[index_x]; // for (int index_y = 0; index_y < matHeight; index_y++) // {//高度与颜色相乘 // byte vec = matGray.At(index_y, index_x); // threedData[index_y] = vec;// threedData[index_y] * vec / 255.0; // } // threeDataDemo.Z_value.Add(string.Join(",", threedData.ToArray())); // } //} threeDataDemo.Z_level = "16.000000,0.000000"; if (threeDataDemo.Dyeing == null || threeDataDemo.Dyeing.Count == 0) threeDataDemo.Dyeing = new List(); //threeDataDemo.Dyeing.Add("100.00,0.00,100.00"); threeDataDemo.Dyeing.Add("255.00,0.00,0.00"); threeDataDemo.Dyeing.Add("0.00,255.00,0.00"); return threeDataDemo; } public void ReadPar() { threeDataDemo = CreateThreeDataDemoModel();// Base.CommTool.XmlSerializeHelper.DESerializer(Base.CommTool.FileOperationHelper.ReadStringFromFile(fileName, System.IO.FileMode.Open)); //XmlDocument xd = new XmlDocument(); //string fileName = @"C:\Users\win10SSD\Desktop\工作目录\ThreeDDemo\ThreeDDemo20201029\ThreeDataDemo_00.xml"; ////string fileName = @"C:\Users\win10SSD\Desktop\工作目录\ThreeDDemo\ThreeDSR20201108\ThreeDSR\ThreeDData.xml"; //xd.Load(fileName); string str; string[] strarr; if (threeDataDemo.size.Width < 1) //if (xmlNoteList.Count < 1) { MessageBox.Show("XML文件错"); return; } str = threeDataDemo.size.Width.ToString(); m_iWidth = int.Parse(str); str = threeDataDemo.size.Height.ToString(); m_iHeight = int.Parse(str); if (threeDataDemo.Z_level == null) //if (xmlNoteList.Count < 1) { MessageBox.Show("XML文件错"); //return; } else { str = threeDataDemo.Z_level.ToString(); strarr = str.Split(','); m_iDLevel = strarr.Length; m_adDZ = new double[m_iDLevel]; m_adDC = new double[m_iDLevel, 3]; for (int i = 0; i < m_iDLevel; i++) { m_adDZ[i] = double.Parse(strarr[i]); } } //xmlNoteList = xd.GetElementsByTagName("colour"); if (threeDataDemo.Dyeing.Count < m_iDLevel) //if (xmlNoteList.Count < m_iDLevel) { MessageBox.Show("XML文件错"); return; } int iX = 0; for (int dyeingIndex = 0; dyeingIndex < threeDataDemo.Dyeing.Count; dyeingIndex++) //foreach (XmlElement item in xmlNoteList) { str = threeDataDemo.Dyeing[dyeingIndex].ToString(); //str = item.InnerXml; strarr = str.Split(','); if (strarr.Length < 3) { MessageBox.Show("XML文件错"); return; } m_adDC[iX, 0] = double.Parse(strarr[0]); m_adDC[iX, 1] = double.Parse(strarr[1]); m_adDC[iX, 2] = double.Parse(strarr[2]); iX++; } //xmlNoteList = xd.GetElementsByTagName("Column"); if (threeDataDemo.Z_value.Count < m_iWidth) //if (xmlNoteList.Count < m_iWidth) { MessageBox.Show("XML文件错"); return; } m_adZV = new double[m_iWidth, m_iHeight]; bool bFirst = true; iX = 0; for (int Z_valueIndex = 0; Z_valueIndex < threeDataDemo.Z_value.Count; Z_valueIndex++) //foreach (XmlElement item in xmlNoteList) { str = threeDataDemo.Z_value[Z_valueIndex].ToString(); //str = item.InnerXml; strarr = str.Split(','); if (strarr.Length < m_iHeight) { MessageBox.Show("XML文件错"); return; } for (int iY = 0; iY < m_iHeight; iY++) { m_adZV[iX, m_iHeight - 1 - iY] = double.Parse(strarr[iY]); if ((bFirst) || (m_adZV[iX, m_iHeight - 1 - iY] > m_dMaxZV)) { m_dMaxZV = m_adZV[iX, m_iHeight - 1 - iY]; } if ((bFirst) || (m_adZV[iX, m_iHeight - 1 - iY] < m_dMinZV)) { m_dMinZV = m_adZV[iX, m_iHeight - 1 - iY]; bFirst = false; } } iX++; } //处理剖面线参数 m_afPonitB[0] = m_iWidth - 1; m_afPonitB[1] = m_iHeight - 1; CalculationIne(); //处理颜色和翻转参数 m_afNewClr = new float[m_iWidth, m_iHeight, 3]; m_adOverTurnZV = new double[m_iWidth, m_iHeight]; //for (iX = 0; iX < m_iWidth; iX++) //{ // for (int iY = 0; iY < m_iHeight; iY++) // { // float[] fColor = CalculationColorf(m_adZV[iX, iY]); // m_afNewClr[iX, iY, 0] = fColor[0]; // m_afNewClr[iX, iY, 1] = fColor[1]; // m_afNewClr[iX, iY, 2] = fColor[2]; // m_adOverTurnZV[iX, iY] = m_dMinZV + (m_dMaxZV - m_adZV[iX, iY]); // } //} //fileName = System.Windows.Forms.Application.StartupPath/* + "\\Config\\" + "Default"*//*SettingPrefix*/ + "\\ThreeDataDemo_temp.bmp"; ////fileName = @"C:\Users\win10SSD\Desktop\工作目录\ThreeDDemo\ThreeDDemo20201029\d2.bmp"; ////fileName = @"C:\Users\win10SSD\Desktop\工作目录\ThreeDDemo\ThreeDSR20201108\ThreeDSR\d1.bmp"; Mat origMat = this.appWorkspace.ActiveDocumentWorkspace.CompositionSurface.CreatedAliasedMat(); string mode = "H"; int maxSize = 640; if (origMat.Width > origMat.Height) mode = "W"; Mat OrgImg; if (maxSize >= origMat.Height && maxSize >= origMat.Width) OrgImg = origMat;// PaintDotNet.Camera.Tools.ToMat(origin); else OrgImg = Surface.MakeThumbnailMat(origMat, maxSize, maxSize, mode);//待测试 if ((m_iWidth != OrgImg.Cols) || (m_iHeight != OrgImg.Rows))//行数Rows是Y,列数是X { MessageBox.Show("图像尺寸和XML文件矛盾"); return; } m_afOrgClr = new float[m_iWidth, m_iHeight, 3]; int[] point = new int[2]; Vec3b OrgClr; for (point[0] = 0; point[0] < m_iHeight; point[0]++) { for (point[1] = 0; point[1] < m_iWidth; point[1]++) { OrgClr = OrgImg.At(point[0], point[1]); m_afOrgClr[point[1], m_iHeight - 1 - point[0], 0] = OrgClr.Item2 / 255.0F; m_afOrgClr[point[1], m_iHeight - 1 - point[0], 1] = OrgClr.Item1 / 255.0F; m_afOrgClr[point[1], m_iHeight - 1 - point[0], 2] = OrgClr.Item0 / 255.0F; } } m_bRulerColor = false; m_afThisClr = m_afOrgClr; m_bOverTurn = false; m_adThisZV = m_adZV; m_adThisLineZV = m_adLineZV; ChangeColor(); } public float[] CalculationColorf(double dZ) { float[] fColor = new float[3]; if (dZ < m_adDZ[m_iDLevel - 1]) { fColor[0] = (float)m_adDC[m_iDLevel - 1, 0]; fColor[1] = (float)m_adDC[m_iDLevel - 1, 1]; fColor[2] = (float)m_adDC[m_iDLevel - 1, 2]; return fColor; } if (dZ > m_adDZ[0]) { fColor[0] = (float)m_adDC[0, 0]; fColor[1] = (float)m_adDC[0, 1]; fColor[2] = (float)m_adDC[0, 2]; return fColor; } int i, j; for (j = 1; j < m_iDLevel; j++) { if (dZ > m_adDZ[j]) { break; } } i = j - 1; double dIJ = Math.Abs(m_adDZ[i] - m_adDZ[j]); double dWI = Math.Abs(dZ - m_adDZ[j]) / dIJ; double dWJ = Math.Abs(m_adDZ[i] - dZ) / dIJ; fColor[0] = (float)((m_adDC[i, 0] * dWI + m_adDC[j, 0] * dWJ) / 255.0); fColor[1] = (float)((m_adDC[i, 1] * dWI + m_adDC[j, 1] * dWJ) / 255.0); fColor[2] = (float)((m_adDC[i, 2] * dWI + m_adDC[j, 2] * dWJ) / 255.0); return fColor; } private void CalculationIne() { LINE_PNTS = (int)Math.Sqrt((m_afPonitB[0] - m_afPonitA[0]) * (m_afPonitB[0] - m_afPonitA[0]) + (m_afPonitB[1] - m_afPonitA[1]) * (m_afPonitB[1] - m_afPonitA[1])); if (LINE_PNTS < 3) LINE_PNTS = 3; m_afLineStep[0] = (m_afPonitB[0] - m_afPonitA[0]) / (LINE_PNTS - 1); m_afLineStep[1] = (m_afPonitB[1] - m_afPonitA[1]) / (LINE_PNTS - 1); m_afLineXY = new float[LINE_PNTS - 2, 2]; m_adLineZV = new double[LINE_PNTS]; m_adLineOverTurnZV = new double[LINE_PNTS]; if (!m_bOverTurn) m_adThisLineZV = m_adLineZV; else m_adThisLineZV = m_adLineOverTurnZV; m_adLineZV[0] = CalculationInterpolation(m_afPonitA[0], m_afPonitA[1]); m_adLineOverTurnZV[0] = m_dMinZV + (m_dMaxZV - m_adLineZV[0]); for (int i = 0; i < (LINE_PNTS - 2); i++) { m_afLineXY[i, 0] = m_afPonitA[0] + (i + 1) * m_afLineStep[0]; m_afLineXY[i, 1] = m_afPonitA[1] + (i + 1) * m_afLineStep[1]; m_adLineZV[i + 1] = CalculationInterpolation(m_afLineXY[i, 0], m_afLineXY[i, 1]); m_adLineOverTurnZV[i + 1] = m_dMinZV + (m_dMaxZV - m_adLineZV[i + 1]); } m_adLineZV[LINE_PNTS - 1] = CalculationInterpolation(m_afPonitB[0], m_afPonitB[1]); m_adLineOverTurnZV[LINE_PNTS - 1] = m_dMinZV + (m_dMaxZV - m_adLineZV[LINE_PNTS - 1]); } private double CalculationInterpolation(float fX, float fY) { int iXS = Math.Min(Math.Max((int)(fX), 0), m_iWidth - 1); int iYS = Math.Min(Math.Max((int)(fY), 0), m_iHeight - 1); int iXB = Math.Min(Math.Max((int)(fX + 1.0), 0), m_iWidth - 1); int iYB = Math.Min(Math.Max((int)(fY + 1.0), 0), m_iHeight - 1); double dWXB = Math.Min(Math.Max((fX - (double)iXS), 0.0), 1.0); double dWXS = 1.0 - dWXB; double dWYB = Math.Min(Math.Max((fY - (double)iYS), 0.0), 1.0); double dWYS = 1.0 - dWYB; double dTempA = m_adZV[iXS, iYS]; double dTempB = m_adZV[iXS, iYB]; double dTempC = m_adZV[iXB, iYS]; double dTempD = m_adZV[iXB, iYB]; double dTempAB = dTempA * dWYS + dTempB * dWYB; double dTempCD = dTempC * dWYS + dTempD * dWYB; double dRtn = dTempAB * dWXS + dTempCD * dWXB; return dRtn;// dTempA;// } private static void PictureBox1_Paint(object sender, PaintEventArgs e) { //Application.DoEvents(); // Process Events //// Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene() //if ((active && (form != null) && !DrawGLScene()) /*|| keys[(int) Keys.Escape]*/) //{ // Active? Was There A Quit Received? // done = true; // ESC Or DrawGLScene Signalled A Quit //} //else //{ // Not Time To Quit, Update Screen // Gdi.SwapBuffers(hDC); // Swap Buffers (Double Buffering) //} } internal static void Run(AppWorkspace appWorkspace) { if (!done && (form != null)) { form.ReadPar(); form.Focus(); return; } done = false; // Create Our OpenGL Window if (!CreateGLWindow(appWorkspace, PdnResources.GetString("Menu.Tools.SurfacePlot.Text"), 990, 690, 16)) { return; // Quit If Window Was Not Created } while (!done) { // Loop That Runs While done = false Application.DoEvents(); // Process Events // Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene() if ((active && (form != null) && !DrawGLScene()) /*|| keys[(int) Keys.Escape]*/) { // Active? Was There A Quit Received? done = true; // ESC Or DrawGLScene Signalled A Quit } else { // Not Time To Quit, Update Screen Gdi.SwapBuffers(hDC); // Swap Buffers (Double Buffering) } /* if(keys[(int) Keys.F1]) { // Is F1 Being Pressed? keys[(int) Keys.F1] = false; // If So Make Key false KillGLWindow(); // Kill Our Current Window // Recreate Our OpenGL Window if(!CreateGLWindow("三维面绘制", 640, 480, 16)) { return; // Quit If Window Was Not Created } done = false; // We're Not Done Yet } */ } // Shutdown KillGLWindow(); // Kill The Window return; // Exit The Program } private static bool CreateGLWindow(AppWorkspace appWorkspace, string title, int width, int height, int bits) { int pixelFormat; // Holds The Results After Searching For A Match form = null; // Null The Form GC.Collect(); // Request A Collection // This Forces A Swap Kernel.SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1); form = new SurfacePlotWindow(appWorkspace); // Create The Window form.FormBorderStyle = FormBorderStyle.Sizable; // Sizable Cursor.Show(); // Show Mouse Pointer form.Width = width; // Set Window Width form.Height = height; // Set Window Height form.Text = title; // Set Window Title Gdi.PIXELFORMATDESCRIPTOR pfd = new Gdi.PIXELFORMATDESCRIPTOR(); // pfd Tells Windows How We Want Things To Be pfd.nSize = (short) Marshal.SizeOf(pfd); // Size Of This Pixel Format Descriptor pfd.nVersion = 1; // Version Number pfd.dwFlags = Gdi.PFD_DRAW_TO_WINDOW | // Format Must Support Window Gdi.PFD_SUPPORT_OPENGL | // Format Must Support OpenGL Gdi.PFD_DOUBLEBUFFER; // Format Must Support Double Buffering pfd.iPixelType = (byte) Gdi.PFD_TYPE_RGBA; // Request An RGBA Format pfd.cColorBits = (byte) bits; // Select Our Color Depth pfd.cRedBits = 0; // Color Bits Ignored pfd.cRedShift = 0; pfd.cGreenBits = 0; pfd.cGreenShift = 0; pfd.cBlueBits = 0; pfd.cBlueShift = 0; pfd.cAlphaBits = 0; // No Alpha Buffer pfd.cAlphaShift = 0; // Shift Bit Ignored pfd.cAccumBits = 0; // No Accumulation Buffer pfd.cAccumRedBits = 0; // Accumulation Bits Ignored pfd.cAccumGreenBits = 0; pfd.cAccumBlueBits = 0; pfd.cAccumAlphaBits = 0; pfd.cDepthBits = 16; // 16Bit Z-Buffer (Depth Buffer) pfd.cStencilBits = 0; // No Stencil Buffer pfd.cAuxBuffers = 0; // No Auxiliary Buffer pfd.iLayerType = (byte) Gdi.PFD_MAIN_PLANE; // Main Drawing Layer pfd.bReserved = 0; // Reserved pfd.dwLayerMask = 0; // Layer Masks Ignored pfd.dwVisibleMask = 0; pfd.dwDamageMask = 0; //hDC = User.GetDC(form.Handle); // Attempt To Get A Device Context form.pictureBox1 = new PictureBox(); ((System.ComponentModel.ISupportInitialize)(form.pictureBox1)).BeginInit(); //form.pictureBox1.Location = new System.Drawing.Point(22, 40); //form.pictureBox1.Location = new System.Drawing.Point(20, 180); form.pictureBox1.Location = new System.Drawing.Point(15, 18); form.pictureBox1.Name = "pictureBox1"; form.pictureBox1.Size = new System.Drawing.Size(560, 400); //form.pictureBox1.Size = new System.Drawing.Size(1272, 651); form.pictureBox1.TabIndex = 0; form.pictureBox1.TabStop = false; /*form*/form.groupBox1.Controls.Add(form.pictureBox1); ((System.ComponentModel.ISupportInitialize)(form.pictureBox1)).EndInit(); form.pictureBox1.Paint += PictureBox1_Paint; form.pictureBox1.MouseMove += new MouseEventHandler(form.pictureBox1_MouseMove); form.pictureBox1.MouseDown += new MouseEventHandler(form.pictureBox1_MouseDown); form.pictureBox1.MouseUp += new MouseEventHandler(form.pictureBox1_MouseUp); form.pictureBox1.MouseLeave += new EventHandler(form.pictureBox1_MouseLeave); hDC = User.GetDC(form.pictureBox1.Handle); if(hDC == IntPtr.Zero) { // Did We Get A Device Context? KillGLWindow(); // Reset The Display MessageBox.Show("Can't Create A GL Device Context.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } pixelFormat = Gdi.ChoosePixelFormat(hDC, ref pfd); // Attempt To Find An Appropriate Pixel Format if(pixelFormat == 0) { // Did Windows Find A Matching Pixel Format? KillGLWindow(); // Reset The Display MessageBox.Show("Can't Find A Suitable PixelFormat.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } if(!Gdi.SetPixelFormat(hDC, pixelFormat, ref pfd)) { // Are We Able To Set The Pixel Format? KillGLWindow(); // Reset The Display MessageBox.Show("Can't Set The PixelFormat.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } hRC = Wgl.wglCreateContext(hDC); // Attempt To Get The Rendering Context if(hRC == IntPtr.Zero) { // Are We Able To Get A Rendering Context? KillGLWindow(); // Reset The Display MessageBox.Show("Can't Create A GL Rendering Context.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } if(!Wgl.wglMakeCurrent(hDC, hRC)) { // Try To Activate The Rendering Context KillGLWindow(); // Reset The Display MessageBox.Show("Can't Activate The GL Rendering Context.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } form.Show(appWorkspace); // Show The Window //zzz form.TopMost = true; // Topmost Window form.Focus(); // Focus The Window //form.BackColor = Color.Gray; ////form.WindowState = FormWindowState.Maximized; //ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen if (!InitGL()) { // Initialize Our Newly Created GL Window KillGLWindow(); // Reset The Display MessageBox.Show("Initialization Failed.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } return true; // Success } private static bool DrawGLScene() { //new platform iniView(); Gl.glTranslatef(0, 0, 0); myRotate(); //错了 Gl.glTranslatef(m_fT_xyz[0],m_fT_xyz[1],0); for (int i = 0; i < form.m_iWidth - 1; i++) { Gl.glBegin(Gl.GL_TRIANGLE_STRIP); for (int j = 0; j < form.m_iHeight; j++) { DrowOnePnt(i, j); DrowOnePnt(i + 1, j); } Gl.glEnd(); } //if ((form.m_iMusMod >= 5) && (form.m_iMusMod <= 7) || true) //{ // Gl.glBegin(Gl.GL_QUADS); // Gl.glColor3f(1.0F, 1.0F, 0.0F); // Gl.glVertex3d(form.m_afPonitA[0] - 10 - form.m_iWidth / 2.0, form.m_afPonitA[1] - 10 - form.m_iHeight / 2.0, 1.0 + form.m_adThisLineZV[0] - (form.m_dMaxZV + form.m_dMinZV) / 2.0); // Gl.glVertex3d(form.m_afPonitA[0] + 10 - form.m_iWidth / 2.0, form.m_afPonitA[1] - 10 - form.m_iHeight / 2.0, 1.0 + form.m_adThisLineZV[0] - (form.m_dMaxZV + form.m_dMinZV) / 2.0); // Gl.glVertex3d(form.m_afPonitA[0] + 10 - form.m_iWidth / 2.0, form.m_afPonitA[1] + 10 - form.m_iHeight / 2.0, 1.0 + form.m_adThisLineZV[0] - (form.m_dMaxZV + form.m_dMinZV) / 2.0); // Gl.glVertex3d(form.m_afPonitA[0] - 10 - form.m_iWidth / 2.0, form.m_afPonitA[1] + 10 - form.m_iHeight / 2.0, 1.0 + form.m_adThisLineZV[0] - (form.m_dMaxZV + form.m_dMinZV) / 2.0); // Gl.glEnd(); // Gl.glBegin(Gl.GL_LINE_STRIP); // Gl.glColor3f(0.0F, 1.0F, 0.0F); // Gl.glVertex3d(form.m_afPonitA[0] - form.m_iWidth / 2.0, form.m_afPonitA[1] - form.m_iHeight / 2.0, 1.0 + form.m_adThisLineZV[0] - (form.m_dMaxZV + form.m_dMinZV) / 2.0); // for (int i = 0; i < (LINE_PNTS - 2); i++) // { // Gl.glVertex3d(form.m_afLineXY[i, 0] - form.m_iWidth / 2.0, form.m_afLineXY[i, 1] - form.m_iHeight / 2.0, 1.0 + /*form.m_adThisZV[(int)form.m_afLineXY[i, 0], (int)form.m_afLineXY[i, 1]]*/form.m_adThisLineZV[i + 1] - (form.m_dMaxZV + form.m_dMinZV) / 2.0); // } // Gl.glVertex3d(form.m_afPonitB[0] - form.m_iWidth / 2.0, form.m_afPonitB[1] - form.m_iHeight / 2.0, 1.0 + form.m_adThisLineZV[LINE_PNTS - 1] - (form.m_dMaxZV + form.m_dMinZV) / 2.0); // Gl.glEnd(); // Gl.glBegin(Gl.GL_QUADS); // Gl.glColor3f(0.0F, 1.0F, 01.0F); // Gl.glVertex3d(form.m_afPonitB[0] - 10 - form.m_iWidth / 2.0, form.m_afPonitB[1] - 10 - form.m_iHeight / 2.0, 1.0 + form.m_adThisLineZV[LINE_PNTS - 1] - (form.m_dMaxZV + form.m_dMinZV) / 2.0); // Gl.glVertex3d(form.m_afPonitB[0] + 10 - form.m_iWidth / 2.0, form.m_afPonitB[1] - 10 - form.m_iHeight / 2.0, 1.0 + form.m_adThisLineZV[LINE_PNTS - 1] - (form.m_dMaxZV + form.m_dMinZV) / 2.0); // Gl.glVertex3d(form.m_afPonitB[0] + 10 - form.m_iWidth / 2.0, form.m_afPonitB[1] + 10 - form.m_iHeight / 2.0, 1.0 + form.m_adThisLineZV[LINE_PNTS - 1] - (form.m_dMaxZV + form.m_dMinZV) / 2.0); // Gl.glVertex3d(form.m_afPonitB[0] - 10 - form.m_iWidth / 2.0, form.m_afPonitB[1] + 10 - form.m_iHeight / 2.0, 1.0 + form.m_adThisLineZV[LINE_PNTS - 1] - (form.m_dMaxZV + form.m_dMinZV) / 2.0); // Gl.glEnd(); //} Gl.glLoadIdentity(); return true; } private static void myRotate() { int[,] vec = new int[3, 3] { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }; for (int i = 0; i <= 2; i++) { Gl.glRotatef(form.m_fR_xyz[i], vec[i, 0], vec[i, 1], vec[i, 2]); } } public static void DrowOnePnt(int i, int j) { Gl.glColor3f(form.m_afThisClr[i, j, 0], form.m_afThisClr[i, j, 1], form.m_afThisClr[i, j, 2]); Gl.glVertex3d(i - form.m_iWidth / 2.0, j - form.m_iHeight / 2.0, form.m_adThisZV[i, j] - (form.m_dMaxZV + form.m_dMinZV) / 2.0); } private static bool InitGL() { //Gl.glShadeModel(Gl.GL_SMOOTH); // Enable Smooth Shading //Gl.glClearColor(0, 0, 0, 0.5f); // Black Background //Gl.glClearDepth(1); // Depth Buffer Setup Gl.glEnable(Gl.GL_DEPTH_TEST); // Enables Depth Testing //Gl.glDepthFunc(Gl.GL_LEQUAL); // The Type Of Depth Testing To Do //Gl.glHint(Gl.GL_PERSPECTIVE_CORRECTION_HINT, Gl.GL_NICEST); // Really Nice Perspective Calculations // 设置视口 viewport Gl.glViewport(0, 0, form.pictureBox1.Width, form.pictureBox1.Height); //启用阴影平滑 Gl.glShadeModel(Gl.GL_SMOOTH); //启用反走样 Gl.glHint(Gl.GL_PERSPECTIVE_CORRECTION_HINT, Gl.GL_NICEST); // 设置投影模式 projection matrix Gl.glMatrixMode(Gl.GL_PROJECTION); Gl.glLoadIdentity(); iniView(); return true; } public static void iniView(bool clearColor = true) { // 重置黑色背景 if (clearColor) { Gl.glClearColor((float)(0 / 255.0), (float)(0 / 255.0), (float)(0 / 255.0), (float)(255 / 255.0)); Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); } else return; form.m_fT_xyz[2] = (float)Math.Max(form.m_dMaxZV, Math.Abs(form.m_dMinZV)); form.m_fT_xyz[2] = (float)(-1.0 * Math.Max(Math.Max(form.m_iWidth * 0.98, form.m_iHeight * 0.98), form.m_fT_xyz[2])); ////form.m_fT_xyz[2] = (float)(1.2 * form.m_fT_xyz[2]); ////Glu.gluPerspective(85, form.pictureBox1.Width / (double)form.pictureBox1.Height, 1, -4.0/*-2.0*/ * form.m_fT_xyz[2]);//距离裁减 //Gl.glOrtho(0, form.pictureBox1.Width, form.pictureBox1.Height, 0, 1, -4.0/*-2.0*/ * form.m_fT_xyz[2]); double size1 = form.m_iHeight / 1.0; Gl.glOrtho(-size1 * form.pictureBox1.Width / (double)form.pictureBox1.Height, size1 * form.pictureBox1.Width / (double)form.pictureBox1.Height, -size1, size1, 2.4 * form.m_fT_xyz[2], -2.4 * form.m_fT_xyz[2]); // 选择模型观察矩阵 modelview matrix Gl.glMatrixMode(Gl.GL_MODELVIEW); //重置模型观察矩阵 Gl.glLoadIdentity(); Glu.gluLookAt(-1.0 * form.m_fT_xyz[0], -1.0 * form.m_fT_xyz[1], -1.0/*-1.0*/ * form.m_fT_xyz[2], // 眼睛位置 -1.0 * form.m_fT_xyz[0], -1.0 * form.m_fT_xyz[1], 0, // 观察点 0, 1, 0); } private static void KillGLWindow() { if(hRC != IntPtr.Zero) { // Do We Have A Rendering Context? if(!Wgl.wglMakeCurrent(IntPtr.Zero, IntPtr.Zero)) { // Are We Able To Release The DC and RC Contexts? MessageBox.Show("Release Of DC And RC Failed.", "SHUTDOWN ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); } if(!Wgl.wglDeleteContext(hRC)) { // Are We Able To Delete The RC? MessageBox.Show("Release Rendering Context Failed.", "SHUTDOWN ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); } hRC = IntPtr.Zero; // Set RC To Null } if(hDC != IntPtr.Zero) { // Do We Have A Device Context? if(form != null && !form.IsDisposed) { // Do We Have A Window? if(form.Handle != IntPtr.Zero) { // Do We Have A Window Handle? if(!User.ReleaseDC(form.Handle, hDC)) { // Are We Able To Release The DC? MessageBox.Show("Release Device Context Failed.", "SHUTDOWN ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } hDC = IntPtr.Zero; // Set DC To Null } if(form != null) { // Do We Have A Windows Form? form.Hide(); // Hide The Window form.Close(); // Close The Form form = null; // Set form To Null } } private static void ReSizeGLScene(int width, int height) { if(height == 0) { // Prevent A Divide By Zero... height = 1; // By Making Height Equal To One } Gl.glViewport(0, 0, width, height); // Reset The Current Viewport Gl.glMatrixMode(Gl.GL_PROJECTION); // Select The Projection Matrix Gl.glLoadIdentity(); // Reset The Projection Matrix Glu.gluPerspective(45, width / (double) height, 0.1, 100); // Calculate The Aspect Ratio Of The Window Gl.glMatrixMode(Gl.GL_MODELVIEW); // Select The Modelview Matrix Gl.glLoadIdentity(); // Reset The Modelview Matrix } private void Form_Activated(object sender, EventArgs e) { active = true; // Program Is Active } private void Form_Closing(object sender, CancelEventArgs e) { done = true; // Send A Quit Message } private void Form_Deactivate(object sender, EventArgs e) { active = false; // Program Is No Longer Active } //zzz public int m_iYVCount = 10; public double m_dYVMax = 51; public double m_dYVMin = -51; /// /// Z轴高度集合,从A到B按照均匀取到了100个点 /// private double[] m_adValue = new double[LINE_PNTS]; public int m_iYPixelMax = 350; public int m_iYPixelMin = 40; public int m_iXPixelMax = 1100; public int m_iXPixelMin = 60; private void ChangeColor() { if (m_bRulerColor) m_bRulerColor = false; else m_bRulerColor = true; if (m_bRulerColor) RefreshColorAction(); else m_afThisClr = m_afOrgClr; } private void RefreshColorAction() { if (m_bRulerColor) { style1Color1 = Color.Green; style1Color2 = Color.Red; double adZVRange = m_dMaxZV - m_dMinZV; //处理颜色和翻转参数 m_afNewClr = new float[m_iWidth, m_iHeight, 3]; //m_adOverTurnZV = new double[m_iWidth, m_iHeight]; for (int iX = 0; iX < m_iWidth; iX++) { for (int iY = 0; iY < m_iHeight; iY++) { Color fColor = /*Color.FromArgb(*/CalculationColorfRange(((m_bOverTurn ? m_adOverTurnZV[iX, iY] : m_adZV[iX, iY]) - m_dMinZV) / adZVRange)/*)*/; m_afNewClr[iX, iY, 0] = (float)(fColor.R / 255.0); m_afNewClr[iX, iY, 1] = (float)(fColor.G / 255.0); m_afNewClr[iX, iY, 2] = (float)(fColor.B / 255.0); //m_adOverTurnZV[iX, iY] = m_dMinZV + (m_dMaxZV - m_adZV[iX, iY]); } } m_afThisClr = m_afNewClr; } } private Color style1Color1; private Color style1Color2; /// /// 根据设置计算彩虹色的变化 /// /// /// public Color CalculationColorfRange(double dZ) { if (dZ < 0) dZ = 0; if (dZ > 1) dZ = 1; return Color.FromArgb(255, (int)(style1Color1.R + (style1Color2.R - style1Color1.R) * dZ), (int)(style1Color1.G + (style1Color2.G - style1Color1.G) * dZ), (int)(style1Color1.B + (style1Color2.B - style1Color1.B) * dZ));// (int)(style1Color1 + (style1Color2 - style1Color1) * dZ); } /* private void Form_KeyUp(object sender, KeyEventArgs e) { keys[e.KeyValue] = false; // Key Has Been Released, Mark It As false } */ private void Form_Resize(object sender, EventArgs e) { //ReSizeGLScene(form.Width, form.Height); // Resize The OpenGL Window } private void pictureBox1_MouseMove(object sender, MouseEventArgs e) { if ((m_iMusMod <= 0) || (m_iMusMod >= 7)) { return; } //int iBtnDwn = Glfw.glfwGetMouseButton(Glfw.GLFW_MOUSE_BUTTON_LEFT); if (0 == m_iMusDown) { m_iLastMusDown = 0; return; } else if (0 == m_iLastMusDown) { m_iLastMusDown = 1; m_iLastmouseX = e.X; m_iLastmouseY = e.Y; return; } float fXChange = e.X - m_iLastmouseX; float fYChange = e.Y - m_iLastmouseY; m_fR_xyz[0] = AngleNormalization(m_fR_xyz[0]); m_fR_xyz[1] = AngleNormalization(m_fR_xyz[1]); if (1 == m_iMusMod) { if ((m_fR_xyz[0] > 90.0) && (m_fR_xyz[0] < 270.0))//先绕X轴转完了 { fXChange *= -1.0F; } m_fR_xyz[0] += fYChange; m_fR_xyz[1] += fXChange; //m_fR_xyz[2] = 0.0F; } else if (2 == m_iMusMod) { m_fT_xyz[0] += fXChange * 0.91F; m_fT_xyz[1] += fYChange * -0.91F; } else if (5 == m_iMusMod) { if ((m_fR_xyz[0] > 90.0) && (m_fR_xyz[0] < 270.0))//先绕X轴转完了 { fYChange *= -1.0F; } if ((m_fR_xyz[1] > 90.0) && (m_fR_xyz[1] < 270.0))//先绕X轴转完了 { fXChange *= -1.0F; } m_afPonitA[0] += fXChange * 0.95F; m_afPonitA[0] = (float)Math.Min(Math.Max(m_afPonitA[0], 1.0), m_iWidth - 1); m_afPonitA[1] += fYChange * -0.95F; m_afPonitA[1] = (float)Math.Min(Math.Max(m_afPonitA[1], 1.0), m_iHeight - 1); CalculationIne(); } else if (6 == m_iMusMod) { if ((m_fR_xyz[0] > 90.0) && (m_fR_xyz[0] < 270.0))//先绕X轴转完了 { fYChange *= -1.0F; } if ((m_fR_xyz[1] > 90.0) && (m_fR_xyz[1] < 270.0))//先绕X轴转完了 { fXChange *= -1.0F; } m_afPonitB[0] += fXChange * 0.95F; m_afPonitB[0] = (float)Math.Min(Math.Max(m_afPonitB[0], 1.0), m_iWidth - 1); m_afPonitB[1] += fYChange * -0.95F; m_afPonitB[1] = (float)Math.Min(Math.Max(m_afPonitB[1], 1.0), m_iHeight - 1); CalculationIne(); } m_iLastmouseX = e.X; m_iLastmouseY = e.Y; } private float AngleNormalization(float fOldAngle) { float fNewAngle = fOldAngle % 360.0F; if (fNewAngle < 0) { fNewAngle += 360.0F; } return fNewAngle; } private void pictureBox1_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { m_iMusDown = 1; } } private void pictureBox1_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { m_iMusDown = 0; } } private void pictureBox1_MouseLeave(object sender, EventArgs e) { m_iMusDown = 0; } } }