using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Diagnostics; using System.Runtime.InteropServices; using Tao.OpenGl; using Tao.Platform.Windows; using OpenCvSharp; using System.Xml; namespace ThreeDSR { public partial class SRWindow : Form { // --- Fields --- private static IntPtr hDC; // Private GDI Device Context private static IntPtr hRC; // Permanent Rendering Context private static SRWindow form; // Our Current Windows Form //private static bool[] keys = new bool[256]; // Array Used For The Keyboard Routine private static bool active = true; // Window Active Flag, Set To True By Default private static bool done = false; // Bool Variable To Exit Main Loop //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 const int LINE_PNTS = 100; //Glfw.GLFWkeyfun m_funKeyCallBak; //Glfw.GLFWmousebuttonfun m_funMsBtnCallBak; //Glfw.GLFWmouseposfun m_funMsPosCallBak; int m_iMusMod = 0; int m_iLastmouseX, m_iLastmouseY; int m_iLastMusDown = 0; float[] m_fR_xyz = new float[3] { 30.0F, 30.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_afLineXY = new float[LINE_PNTS - 2, 2]; float[] m_afLineStep = new float[2] { 0.0F, 0.0F }; double[] m_adLineZV = new double[LINE_PNTS]; double[] m_adLineOverTurnZV = new double[LINE_PNTS]; Form1 m_fmLine; float[, ,] m_afThisClr; double[,] m_adThisZV; double[] m_adThisLineZV; public SRWindow() { 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.KeyDown += new KeyEventHandler(this.Form_KeyDown); // On KeyDown Event Call Form_KeyDown //this.KeyUp += new KeyEventHandler(this.Form_KeyUp); // On KeyUp Event Call Form_KeyUp this.Resize += new EventHandler(this.Form_Resize); ReadPar(); } public void ReadPar() { XmlDocument xd = new XmlDocument(); string fileName = @"D:\ThreeDData.xml"; xd.Load(fileName); string str; string[] strarr; //XmlElement oneitem = (XmlElement)(xd.SelectSingleNode("Size")); //str = oneitem.GetAttribute("width"); //m_iWidth = int.Parse(str); //str = oneitem.GetAttribute("height"); //m_iHeight = int.Parse(str); XmlNodeList xmlNoteList = xd.GetElementsByTagName("Size"); if (xmlNoteList.Count < 1) { MessageBox.Show("XML文件错"); return; } foreach (XmlElement item in xmlNoteList) { str = item.GetAttribute("width"); m_iWidth = int.Parse(str); str = item.GetAttribute("height"); m_iHeight = int.Parse(str); break; } /* XmlNode onenode = xd.SelectSingleNode("Z_level"); str = onenode.InnerXml; string[] 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("Z_level"); if (xmlNoteList.Count < 1) { MessageBox.Show("XML文件错"); return; } foreach (XmlElement item in xmlNoteList) { str = item.InnerXml; 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]); } break; } xmlNoteList = xd.GetElementsByTagName("colour"); if (xmlNoteList.Count < m_iDLevel) { MessageBox.Show("XML文件错"); return; } int iX = 0; foreach (XmlElement item in xmlNoteList) { 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 (xmlNoteList.Count < m_iWidth) { MessageBox.Show("XML文件错"); return; } m_adZV = new double[m_iWidth, m_iHeight]; bool bFirst = true; iX = 0; foreach (XmlElement item in xmlNoteList) { 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, iY] = double.Parse(strarr[iY]); if ((bFirst) || (m_adZV[iX, iY] > m_dMaxZV)) { m_dMaxZV = m_adZV[iX, iY]; } if ((bFirst) || (m_adZV[iX, iY] < m_dMinZV)) { m_dMinZV = m_adZV[iX, 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 = @"D:\d1.bmp"; Mat OrgImg = OpenCvSharp.Cv2.ImRead(fileName); 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], point[0], 0] = OrgClr.Item2 / 255.0F; m_afOrgClr[point[1], point[0], 1] = OrgClr.Item1 / 255.0F; m_afOrgClr[point[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; } 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() { m_adLineZV[0] = CalculationInterpolation(m_afPonitA[0], m_afPonitA[1]); m_adLineOverTurnZV[0] = m_dMinZV + (m_dMaxZV - m_adLineZV[0]); m_afLineStep[0] = (m_afPonitB[0] - m_afPonitA[0]) / (LINE_PNTS - 1); m_afLineStep[1] = (m_afPonitB[1] - m_afPonitA[1]) / (LINE_PNTS - 1); 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; } public static void Run() { // Create Our OpenGL Window if(!CreateGLWindow("三维面绘制", 640, 480, 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(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 SRWindow(); // 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.Name = "pictureBox1"; form.pictureBox1.Size = new System.Drawing.Size(1272, 651); form.pictureBox1.TabIndex = 0; form.pictureBox1.TabStop = false; form.Controls.Add(form.pictureBox1); ((System.ComponentModel.ISupportInitialize)(form.pictureBox1)).EndInit(); 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(); // 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)) { 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, 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, 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, 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, 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, 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, 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, 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, form.m_adThisLineZV[0] - (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, form.m_adThisLineZV[0] - (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, form.m_adThisLineZV[0] - (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, form.m_adThisLineZV[0] - (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() { // 重置黑色背景 Gl.glClearColor(0, 0, 0, 0); Gl.glClear(Gl.GL_COLOR_BUFFER_BIT); 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.8, form.m_iHeight * 0.8), form.m_fT_xyz[2])); Glu.gluPerspective(65, form.pictureBox1.Width / (double)form.pictureBox1.Height, 1, -2.0 * 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 * 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 } private void Form_KeyDown(object sender, KeyEventArgs e) { //keys[e.KeyValue] = true; // Key Has Been Pressed, Mark It As true switch (e.KeyValue) { case (int) Keys.Escape://退出 done = true; break; case 49://'1' m_iMusMod = 1;//旋转图像 break; case 50://'2' m_iMusMod = 2;//平移图像 break; case 53://'5' m_iMusMod = 5;//操作点A break; case 54://'6' m_iMusMod = 6;//操作点B break; case 55://'7' m_iMusMod = 7;//看剖面线 ShowSectionLine(); break; case 56://'8' overturn(); break; case 57://'9' ChangeColor(); break; default: m_iMusMod = 0;//no meaning break; } } private void ShowSectionLine() { m_fmLine = new Form1(); m_fmLine.m_dYVMax = m_dMaxZV + 1.0; m_fmLine.m_dYVMin = m_dMinZV - 1.0; for (int i = 0; i < LINE_PNTS; i++) { m_fmLine.m_adValue[i] = m_adLineZV[i]; } m_fmLine.Show(); } private void overturn() { if (m_bOverTurn) { m_bOverTurn = false; m_adThisZV = m_adZV; m_adThisLineZV = m_adLineZV; } else { m_bOverTurn = true; m_adThisZV = m_adOverTurnZV; m_adThisLineZV = m_adLineOverTurnZV; } } private void ChangeColor() { if (m_bRulerColor) { m_bRulerColor = false; m_afThisClr = m_afOrgClr; } else { m_bRulerColor = true; m_afThisClr = m_afNewClr; } } /* 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.1F; m_fT_xyz[1] += fYChange * -0.1F; } 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.5F; m_afPonitA[0] = (float)Math.Min(Math.Max(m_afPonitA[0], 1.0), m_iWidth - 1); m_afPonitA[1] += fYChange * -0.5F; 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.5F; m_afPonitB[0] = (float)Math.Min(Math.Max(m_afPonitB[0], 1.0), m_iWidth - 1); m_afPonitB[1] += fYChange * -0.5F; 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; } } }