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 RegularTetrahedron3D : PdnBaseForm { private GroupBox groupBox1; //以下是所有接口变量 public static int[] m_aiSquareRGB = new int[3] { 255, 0, 0 };//正方面颜色 public static int[] m_aiTriangleRGB = new int[3] { 255, 0, 50 };//三角面颜色 public static int[] m_aiEdgeRGB = new int[3] { 0, 0, 0 };//棱的颜色 //public static double m_dEdgeLength = 100.0;//正十四面体的棱长 public static double m_dScale = 1.0;//实际显示时的放大比例 /*需要最大棱长的原因是:要建立一个不变的视场,保证每次显示时观察点远近方向都一样, 这样才能体现不同棱长十四面体的区别,也可设置为一个比较大的经验值。*/ public static double m_dMaxLength = 200.0;//可能存在的最大棱长 //以下是内部参数 private static double m_dHalfCubeLength = 100.0; private static float[] m_afRealSRGB = new float[3] { 1.0f, 0, 0 }; private static float[] m_afRealTRGB = new float[3] { 1.0f, 0, 0.5f }; private static float[] m_afRealERGB = new float[3] { 0, 0, 0 }; // --- Fields --- private static IntPtr hDC; // Private GDI Device Context private static IntPtr hRC; // Permanent Rendering Context private static RegularTetrahedron3D form; // Our Current Windows Form private static bool done = false; // Bool Variable To Exit Main Loop int m_iMusMod = 0;// 1;//0; public System.Windows.Forms.PictureBox pictureBox1; int m_iMusDown = 1;//##0; int m_iLastmouseX, m_iLastmouseY; int m_iLastMusDown = 0; float[] m_fR_xyz = new float[3] { 10.0F, 0.0F, 0.0F }; float[] m_fT_xyz = new float[3] { 0.0F, 0.0F, 0.0F }; public static double m1_dEdgeLength = 100.0;//正十四面体的棱长 //private AppWorkspace appWorkspace; /// /// 三维数据 /// private Base.SettingModel.ThreeDataDemoModel threeDataDemo; ////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; 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; internal RegularTetrahedron3D(double m0_dEdgeLength) { m1_dEdgeLength = m0_dEdgeLength; InitializeComponent(); InitializeLanguageText(); m_dHalfCubeLength = m1_dEdgeLength * m_dScale * 0.7071/*sqrt(1/2)*/; m_afRealSRGB[0] = (float)(Math.Min(Math.Max(m_aiSquareRGB[0] / 255.0, 0.0), 1.0)); m_afRealSRGB[1] = (float)(Math.Min(Math.Max(m_aiSquareRGB[1] / 255.0, 0.0), 1.0)); m_afRealSRGB[2] = (float)(Math.Min(Math.Max(m_aiSquareRGB[2] / 255.0, 0.0), 1.0)); m_afRealTRGB[0] = (float)(Math.Min(Math.Max(m_aiTriangleRGB[0] / 255.0, 0.0), 1.0)); m_afRealTRGB[1] = (float)(Math.Min(Math.Max(m_aiTriangleRGB[1] / 255.0, 0.0), 1.0)); m_afRealTRGB[2] = (float)(Math.Min(Math.Max(m_aiTriangleRGB[2] / 255.0, 0.0), 1.0)); m_afRealERGB[0] = (float)(Math.Min(Math.Max(m_aiEdgeRGB[0] / 255.0, 0.0), 1.0)); m_afRealERGB[1] = (float)(Math.Min(Math.Max(m_aiEdgeRGB[1] / 255.0, 0.0), 1.0)); m_afRealERGB[2] = (float)(Math.Min(Math.Max(m_aiEdgeRGB[2] / 255.0, 0.0), 1.0)); 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; // // RegularTetrahedron3D // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(632, 465); 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 = "RegularTetrahedron3D"; this.Text = "RegularTetrahedron3D"; this.Load += new System.EventHandler(this.RegularTetrahedron3D_Load); this.Controls.SetChildIndex(this.groupBox1, 0); this.ResumeLayout(false); } 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 int GetStatus() { 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 return 1; } return -1; } /// /// 更新正十四面体的棱长 /// /// internal static void UpdateRun(double m0_dEdgeLength) { m1_dEdgeLength = m0_dEdgeLength; m_dHalfCubeLength = m1_dEdgeLength * m_dScale * 0.7071/*sqrt(1/2)*/; //m_afRealSRGB[0] = (float)(Math.Min(Math.Max(m_aiSquareRGB[0] / 255.0, 0.0), 1.0)); //m_afRealSRGB[1] = (float)(Math.Min(Math.Max(m_aiSquareRGB[1] / 255.0, 0.0), 1.0)); //m_afRealSRGB[2] = (float)(Math.Min(Math.Max(m_aiSquareRGB[2] / 255.0, 0.0), 1.0)); //m_afRealTRGB[0] = (float)(Math.Min(Math.Max(m_aiTriangleRGB[0] / 255.0, 0.0), 1.0)); //m_afRealTRGB[1] = (float)(Math.Min(Math.Max(m_aiTriangleRGB[1] / 255.0, 0.0), 1.0)); //m_afRealTRGB[2] = (float)(Math.Min(Math.Max(m_aiTriangleRGB[2] / 255.0, 0.0), 1.0)); //m_afRealERGB[0] = (float)(Math.Min(Math.Max(m_aiEdgeRGB[0] / 255.0, 0.0), 1.0)); //m_afRealERGB[1] = (float)(Math.Min(Math.Max(m_aiEdgeRGB[1] / 255.0, 0.0), 1.0)); //m_afRealERGB[2] = (float)(Math.Min(Math.Max(m_aiEdgeRGB[2] / 255.0, 0.0), 1.0)); } internal static void Run(double m0_dEdgeLength) { done = false; // Create Our OpenGL Window //# 640, 480, 16 if (!CreateGLWindow(m0_dEdgeLength, "3D效果"/*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(double m0_dEdgeLength, 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 RegularTetrahedron3D(m0_dEdgeLength); // 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(); // 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.glBegin(Gl.GL_QUADS); Gl.glColor3f(m_afRealSRGB[0], m_afRealSRGB[1], m_afRealSRGB[2]); Gl.glVertex3d(m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(0, m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(0, -m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glVertex3d(0, m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glVertex3d(0, -m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glVertex3d(-m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(-m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glVertex3d(0, m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(0, m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(0, -m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glVertex3d(0, -m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glEnd(); Gl.glBegin(Gl.GL_TRIANGLES); Gl.glColor3f(m_afRealTRGB[0], m_afRealTRGB[1], m_afRealTRGB[2]); Gl.glVertex3d(m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(0, m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glVertex3d(0, -m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(0, m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(-m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(0, -m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glVertex3d(m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glVertex3d(0, -m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(0, m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(0, -m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glVertex3d(m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(0, m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(-m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glEnd(); Gl.glLineWidth(2); Gl.glColor3f(m_afRealERGB[0], m_afRealERGB[1], m_afRealERGB[2]); Gl.glBegin(Gl.GL_LINE_STRIP); Gl.glVertex3d(m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(0, m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(0, -m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glEnd(); Gl.glBegin(Gl.GL_LINE_STRIP); Gl.glVertex3d(m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glVertex3d(0, m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glVertex3d(0, -m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glEnd(); Gl.glBegin(Gl.GL_LINE_STRIP); Gl.glVertex3d(m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glVertex3d(m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glEnd(); Gl.glBegin(Gl.GL_LINE_STRIP); Gl.glVertex3d(-m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(-m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glVertex3d(-m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glEnd(); Gl.glBegin(Gl.GL_LINE_STRIP); Gl.glVertex3d(0, m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(0, m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(0, m_dHalfCubeLength, m_dHalfCubeLength); Gl.glEnd(); Gl.glBegin(Gl.GL_LINE_STRIP); Gl.glVertex3d(0, -m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glVertex3d(0, -m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glVertex3d(0, -m_dHalfCubeLength, m_dHalfCubeLength); Gl.glEnd(); Gl.glBegin(Gl.GL_LINE_STRIP); Gl.glVertex3d(m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(0, m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glEnd(); Gl.glBegin(Gl.GL_LINE_STRIP); Gl.glVertex3d(-m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glVertex3d(0, -m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glEnd(); Gl.glBegin(Gl.GL_LINE_STRIP); Gl.glVertex3d(0, m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(-m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(0, m_dHalfCubeLength, m_dHalfCubeLength); Gl.glEnd(); Gl.glBegin(Gl.GL_LINE_STRIP); Gl.glVertex3d(0, -m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glVertex3d(m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glVertex3d(0, -m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glEnd(); Gl.glBegin(Gl.GL_LINE_STRIP); Gl.glVertex3d(-m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glVertex3d(0, -m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glEnd(); Gl.glBegin(Gl.GL_LINE_STRIP); Gl.glVertex3d(m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(0, m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glEnd(); Gl.glBegin(Gl.GL_LINE_STRIP); Gl.glVertex3d(0, -m_dHalfCubeLength, m_dHalfCubeLength); Gl.glVertex3d(m_dHalfCubeLength, -m_dHalfCubeLength, 0); Gl.glVertex3d(m_dHalfCubeLength, 0, m_dHalfCubeLength); Gl.glVertex3d(0, -m_dHalfCubeLength, m_dHalfCubeLength); Gl.glEnd(); Gl.glBegin(Gl.GL_LINE_STRIP); Gl.glVertex3d(0, m_dHalfCubeLength, -m_dHalfCubeLength); Gl.glVertex3d(-m_dHalfCubeLength, m_dHalfCubeLength, 0); Gl.glVertex3d(-m_dHalfCubeLength, 0, -m_dHalfCubeLength); Gl.glVertex3d(0, m_dHalfCubeLength, -m_dHalfCubeLength); 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]); } } 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); //21.01.25 启动深度测试 Gl.glEnable(Gl.GL_DEPTH_TEST); // 设置投影模式 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; // 重置黑色背景 Gl.glClearColor(0, 0, 0, 0); //21.01.25 启动深度测试 Gl.glClear(Gl.GL_COLOR_BUFFER_BIT); Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_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.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); //### form.m_fT_xyz[2] = (float)(m_dMaxLength * 1.225/*sqrt(3/2)*/ * m_dScale); 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_Closing(object sender, CancelEventArgs e) { done = true; // Send A Quit Message } //zzz public int m_iYVCount = 10; public double m_dYVMax = 51; public double m_dYVMin = -51; public int m_iYPixelMax = 350; public int m_iYPixelMin = 40; public int m_iXPixelMax = 1100; public int m_iXPixelMin = 60; /* 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 >= 3/* //# 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;//21.01.25 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; } 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 RegularTetrahedron3D_Load(object sender, EventArgs e) { m_iMusMod = 1; ReSizeGLScene(form.Width, form.Height); // Resize The OpenGL Window } private void pictureBox1_MouseLeave(object sender, EventArgs e) { m_iMusDown = 0; } } }