动态模拟粒子溃堤效果
- 格式:doc
- 大小:94.50 KB
- 文档页数:9
动态模拟粒子溃堤效果动态模拟粒子溃堤效果收藏新一篇: 旧一篇: 新一篇 Arcglobe 中平行于 opengl 的方法 | 旧一篇 Arcglobe 中平行于 opengl 的方法using System; using System.Collections.Generic; using System.Text; using ESRI.ArcGIS.Geometry; using CsGL.Basecode; using CsGL.OpenGL; using System.Drawing.Imaging; using CsGL; using System.Drawing; using ESRI.ArcGIS.Analyst3D; namespace USTC { /// <summary> /// 使用如下: /// Particles pt = new Particles(); /// pt.initParticles(@"D:\rr.bmp",this.m_sceneViwer); /// pt.DrawParticles(pp.glX,pp.glY,pp.glZ); /// </summary>class Particles { #region Private Fields private const int MAX_PARTICLES = 300; articles To Create private static bool rainbow = true; private static bool sbp; private static bool rp; private static float slowdown = 2.0f; ticles private static float xspeed = 0.0f; low Keyboard Direction Of Tail) private static float yspeed = 0.0f; low Keyboard Direction Of Tail) private static float zoom = -40.0f; private static uint loop; private static uint col; private static uint delay; private static uint[] texture = new uint[1]; // Used To Zoom Out // Misc Loop Variable // Current Color Selection // Rainbow Effect Delay // Our Particle Texture // Base Y Speed (To Al // Base X Speed (To Al // Rainbow Mode? // Space Bar Pressed? // R Pressed? // Slow Down Par // Number Of Pprivate struct Particle { public bool active; public float life; public float fade; public float r; public float g; public float b; public float x; public float y; public float z; public float xi; public float yi; public float zi; public float xg; public float yg; public float zg; } // Create A Structure For Particle // Active True / False // Particle Life // Fade Speed // Red Value // Green Value // Blue Value // X Position // Y Position // Z Position // X Direction // Y Direction // Z Direction // X Gravity // Y Gravity // Z Gravityprivate static Particle[] particle = new Particle[MAX_PARTICLES]; article Array private static float[][] colors = new float[12][] { f Colors new float[] {1.0f, 0.5f, 0.5f}, new float[] {1.0f, 0.75f, 0.5f}, new float[] {1.0f, 1.0f, 0.5f}, new float[] {0.75f, 1.0f, 0.5f}, new float[] {0.5f, 1.0f, 0.5f}, new float[] {0.5f, 1.0f, 0.75f}, new float[] {0.5f, 1.0f, 1.0f}, new float[] {0.5f, 0.75f, 1.0f}, new float[] {0.5f, 0.5f, 1.0f}, new float[] {0.75f, 0.5f, 1.0f}, new float[] {1.0f, 0.5f, 1.0f}, new float[] {1.0f, 0.5f, 0.75f} }; private static Random rand = new Random(); ber Generator #endregion Private Fields private double[] m_modelViewMatrix = null; private double[] m_billboardMatrix = null; private ISceneViewer m_sceneViwer = null; #region 粒子系统计算 public void initParticles(string filename, ISceneViewer sceneViwer) { this.m_sceneViwer = sceneViwer; texture[0] = OpenGLTool.CreateTexture(filename); // Jump To Texture Loading Routine m_modelViewMatrix = new double[16]; m_billboardMatrix = new double[16]; for (loop = 0; loop < MAX_PARTICLES; loop++) { ctive particle[loop].life = 1.0f; ll Life particle[loop].fade = (rand.Next() % 100) / 1000.0f + 0.003f; ade Speed particle[loop].r = colors[loop * (12 / MAX_PARTICLES)][0]; // Initialize All The Particles particle[loop].active = true;// P// Rainbow O// Random Num// Make All The Particles A // Give All The Particles Fu // Random F // SelectRed Rainbow Color particle[loop].g = colors[loop * (12 / MAX_PARTICLES)][1]; Red Rainbow Color particle[loop].b = colors[loop * (12 / MAX_PARTICLES)][2]; Red Rainbow Color particle[loop].xi = ((rand.Next() % 50) - 26.0f) * 10.0f; d On X Axis particle[loop].yi = ((rand.Next() % 50) - 25.0f) * 10.0f; d On Y Axis particle[loop].zi = ((rand.Next() % 50) - 25.0f) * 10.0f; d On Z Axis particle[loop].xg = 0.0f; o particle[loop].yg = -0.8f; rd particle[loop].zg = 0.0f; ro } } #endregion public void DrawParticles(double dx,double dy,double dz) { GL.glGetDoublev(GL.GL_MODELVIEW_MATRIX, m_modelViewMatrix); //populate the billboard matrix m_billboardMatrix[0] = m_modelViewMatrix[0]; m_billboardMatrix[1] = m_modelViewMatrix[4]; m_billboardMatrix[2] = m_modelViewMatrix[8]; m_billboardMatrix[3] = 0; m_billboardMatrix[4] = m_modelViewMatrix[1]; m_billboardMatrix[5] = m_modelViewMatrix[5]; m_billboardMatrix[6] = m_modelViewMatrix[9]; m_billboardMatrix[7] = 0; m_billboardMatrix[8] = m_modelViewMatrix[2]; m_billboardMatrix[9] = m_modelViewMatrix[6]; m_billboardMatrix[10] = m_modelViewMatrix[10]; m_billboardMatrix[11] = 0; // Set Pull On Z Axis To Ze // Set Vertical Pull Downwa // Set Horizontal Pull To Zer // Random Spee // Random Spee // Random Spee // Select // Selectm_billboardMatrix[12] = 0; m_billboardMatrix[13] = 0; m_billboardMatrix[14] = 0; m_billboardMatrix[15] = 1; GL.glEnable(GL.GL_TEXTURE_2D); exture Mapping //glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //GL.glDisable(GL.GL_DEPTH_TEST); pth Testing //GL.glEnable(GL.GL_BLEND); g //GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPH A); T); Our Texture double dblObsX, dblObsY, dblObsZ, dMagnitude, scale; ICamera camera = m_sceneViwer.Camera; camera.Observer.QueryCoords(out dblObsX, out dblObsY); dblObsZ = camera.Observer.Z; for (loop = 0; loop < MAX_PARTICLES; loop++) { { Our Particle X Position float y = particle[loop].y / 1000 + (float)dy; Our Particle Y Position float z = (particle[loop].z) / 1000 + (float)dz; Pos + Zoom IVector3D m_vector3D = new Vector3DClass(); m_vector3D .SetComponents(dblObsX -dx, dblObsY - dy, dblObsZ - dz); dMagnitude = m_vector3D.Magnitude; scale = 0.01 * dMagnitude; GL.glDisable(GL.GL_LIGHTING); GL.glEnable(GL.GL_BLEND); GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); GL.glDepthFunc(GL.GL_LEQUAL); // GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BI // Particle Z // Grab // Loop Through All The Particles if (particle[loop].active) // If The Particle Is Active float x = particle[loop].x / 1000 + (float)dx; // Grab // Type Of Blending To Perform //GL.glHint(GL.GL_POINT_SMOOTH_HINT, GL.GL_NICES // Really Nice Point Smoothing GL.glBindTexture(GL.GL_TEXTURE_2D, texture[0]); // Select // Enable Blendin // Black Background // Disables De // Enable TT); Modelview Matrix// Clear Screen And Depth Buffer // GL.glLoadIdentity(); GL.glPushMatrix(); // GL.glAlphaFunc(GL.GL_GREATER, 0.5f); //translate to the items location GL.glTranslatef((float)x, (float)y, (float)z); //orient the icon so that it'll face the camera OrientBillboard(); //scale the item (original size is 1 ubit) GL.glScaled(scale, scale, 1.0); // Draw The Particle Using Our RGB Values, Fade The Particle Based // Reset The CurrentOn It's Life // GL.glColor4f(particle[loop].r, particle[loop].g, particle[loop].b, particle[loop].lif e); // GL.glBegin(GL.GL_TRIANGLE_STRIP); iangle Strip GL.glBegin(GL.GL_QUADS); GL.glTexCoord2d(1, 1); GL.glVertex3f(0.5f, 0.5f, 0); GL.glTexCoord2d(0, 1); GL.glVertex3f(-0.5f, 0.5f, 0); GL.glTexCoord2d(1, 0); GL.glVertex3f(0.5f, -0.5f, 0); GL.glTexCoord2d(0, 0); GL.glVertex3f(-0.5f, -0.5f, 0); GL.glEnd(); GL.glPopMatrix();// Done Building Triangle Strip // GL.glPolygonMode(GL.GL_FRONT, GL.GL_FILL); particle[loop].x += particle[loop].xi / (slowdown * 1000); he X Axis By X Speed particle[loop].y += particle[loop].yi / (slowdown * 1000); he Y Axis By Y Speed particle[loop].z += particle[loop].zi / (slowdown * 1000); he Z Axis By Z Speed particle[loop].xi += particle[loop].xg; s Into Account particle[loop].yi += particle[loop].yg; s Into Account particle[loop].zi += particle[loop].zg; Into Account particle[loop].life -= particle[loop].fade; By 'Fade' // Reduce Particles Life // Take Pull On Z Axis // Take Pull On Y Axi // Take Pull On X Axi // Move On T // Move On T // Move On T // Top Right // Top Left // Bottom Right // Bottom Left // Build Quad From A Trif (particle[loop].life < 0.0f) { // If Particle Is Burned Out particle[loop].life = 1.0f; ade Value particle[loop].x = 0.0f; particle[loop].y = 0.0f; particle[loop].z = 0.0f; ed And Direction particle[loop].yi = (yspeed + (rand.Next() % 60)) - 30.0f; ed And Direction particle[loop].zi = (rand.Next() % 60) - 30.0f; nd Direction particle[loop].r = colors[col][0]; Table particle[loop].g = colors[col][1]; or Table particle[loop].b = colors[col][2]; Table } } } delay++; // Increase Rainbow Mode Color Cycling Delay Counter if (rainbow && (delay > 25)) { delay = 0; ling Delay col++; if (col > 11) { col = 0; } } GL.glDisable(GL.GL_BLEND); } private void LoadTextures(string filename) { //string filename = @"D:\OpenGL 专题 3D\CsGLExamples\data\NeHeLesson19\Particl // If col Is Too High // Reset It // Change The Particle Color // If rainbow Is On And delay Is Too High // Reset The Rainbow Color Cyc // Select Blue From Color // Select Green From Col // Select Red From Color // Z Axis Speed A // Y Axis Spe // Center On X Axis // Center On Y Axis // Center On Z Axis // X Axis Spe // Give It New Life // Random F particle[loop].fade = (rand.Next() % 100) / 1000.0f + 0.003f;particle[loop].xi = (xspeed + (rand.Next() % 60)) - 32.0f;e.bmp"; ur Texture// The File To Load Bitmap bitmap = null; Rectangle rectangle; // The Bitmap Image For O // The Rectangle For Locking // The Bitmap's Pixel DThe Bitmap In Memory BitmapData bitmapData = null; ata // Load The Bitmap try { bitmap = new Bitmap(filename); Bitmap bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); map Along The Y-Axis rectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height); e Whole Bitmap // Get The Pixel Data From The Locked Bitmap bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, System.Draw ing.Imaging.PixelFormat.Format24bppRgb); GL.glGenTextures(1, texture); e // Create Linear Filtered Texture GL.glBindTexture(GL.GL_TEXTURE_2D, texture[0]); GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, G L.GL_LINEAR); GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, G L.GL_LINEAR); GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, (int)GL.GL_RGB8, bitmap.Width, bi tmap.Height, 0, GL.GL_BGR_EXT, GL.GL_UNSIGNED_BYTE, bitmapData.Scan0); } catch (Exception e) { // Handle Any Exceptions While Loading Textures, Exit App string errorMsg = "An Error Occurred While Loading Texture:\n\t" + filename + "\n" + "\n\nStack Trace:\n\t" + e.StackTrace + "\n"; //MessageBox.Show(errorMsg, "Error", MessageBoxButtons.OK, MessageBoxIcon.S top); } finally // Create 1 Textur // Select Th // Flip The Bit // Load The File As A{ if (bitmap != null) { bitmap.UnlockBits(bitmapData); a From Memory bitmap.Dispose(); } } } /// <summary> /// orient the icons so that it'll face the camera /// </summary> private void OrientBillboard() { GL.glMultMatrixd(m_billboardMatrix); } } } // Clean Up The Bitmap // Unlock The Pixel Dat。