public static ShapeDescriptor DrawRectangularOutline(Vector2 position, Size size, int borderSize, Color borderColor, BorderStyle style, Border borders) { switch (style) { case BorderStyle.Raised: return(DrawRectangularOutline(position, size, Color.FromArgb(255, ColorOperator.Scale(borderColor, lightShadeFactor)), Color.FromArgb(255, ColorOperator.Scale(borderColor, darkShadeFactor)), borderSize, borders)); case BorderStyle.Sunken: return(DrawRectangularOutline(position, size, Color.FromArgb(255, ColorOperator.Scale(borderColor, darkShadeFactor)), Color.FromArgb(255, ColorOperator.Scale(borderColor, lightShadeFactor)), borderSize, borders)); case BorderStyle.Flat: default: return(DrawRectangularOutline(position, size, borderColor, borderColor, borderSize, borders)); } }
/// <summary> /// Update the particles location /// </summary> /// <param name="i">the index of the particle to update</param> /// <returns>Null</returns> private void UpdateLoc(int i) { float percent = (float)particles[i].Age / (float)particles[i].Life; particles[i].LocX = particles[i].LocX + (int)nudVelX.Value + ColorOperator.Lerp(0, (int)nudGravityY.Value, percent); particles[i].LocY = particles[i].LocY + (int)nudVelY.Value + ColorOperator.Lerp(0, (int)nudGravityX.Value, percent); }
/// <summary> /// Update the particles color /// </summary> /// <param name="i">the index of the particle to update</param> /// <returns>Null</returns> private void UpdateColor(int i) { float percent = (float)particles[i].Age / (float)particles[i].Life; particles[i].CurrentAlpha = ColorOperator.Lerp((int)particles[i].StartAlpha, (int)particles[i].EndAlpha, percent); particles[i].CurrentRed = ColorOperator.Lerp((int)particles[i].StartRed, (int)particles[i].EndRed, percent); particles[i].CurrentGreen = ColorOperator.Lerp((int)particles[i].StartGreen, (int)particles[i].EndGreen, percent); particles[i].CurrentBlue = ColorOperator.Lerp((int)particles[i].StartBlue, (int)particles[i].EndBlue, percent); }
/// <summary> /// Shades a rectangle right to left using the specified color. /// </summary> /// <param name="color">The color.</param> /// <returns>An array of ints containing the color of each vertex (0: top left 1: top right 2: bottomLeft 3: bottom right</returns> public static int[] ShadeRightToLeft(Color color) { int colorTopLeft = Color.FromArgb(color.A, ColorOperator.Scale(color, darkShadeFactor)).ToArgb(); int colorTopRight = color.ToArgb(); int colorBottomLeft = colorTopLeft; int colorBottomRight = colorTopRight; return(new int[] { colorTopLeft, colorTopRight, colorBottomLeft, colorBottomRight }); }
/// <summary> /// Draws a right trapezoidal outline. /// </summary> /// <param name="position">The position.</param> /// <param name="size">The size.</param> /// <param name="triangleWidth">Width of the triangle.</param> /// <param name="isTriangleUpside">Ff set to <c>true</c> the triangle will be upside.</param> /// <param name="color">The color.</param> /// <param name="borderSize">Size of the border.</param> /// <param name="borderColor">Color of the border.</param> /// <param name="style">The style.</param> /// <param name="rectangleBorders">The rectangle borders.</param> /// <param name="triangleBorders">The triangle borders.</param> /// <returns>A right trapezoidal outline ShapeDescriptor object.</returns> public static ShapeDescriptor DrawRightTrapezoidalOutline(Vector2 position, Size size, int triangleWidth, bool isTriangleUpside, Color color, int borderSize, Color borderColor, BorderStyle style, Border rectangleBorders, Border triangleBorders) { Vector2 topLeft = position; Size innerSize = new Size(size.Width - borderSize, size.Height - borderSize); ShapeDescriptor sTriangleSide = ShapeDescriptor.Empty; ShapeDescriptor sTriangleBase = ShapeDescriptor.Empty; ShapeDescriptor sRectangleOutline = DrawRectangularOutline(topLeft, size, borderSize, borderColor, style, rectangleBorders); if (isTriangleUpside) { if ((triangleBorders & Border.Right) == Border.Right) { sTriangleSide = DrawLine(borderSize, Color.FromArgb(255, ColorOperator.Scale(borderColor, lightShadeFactor)), new Vector2(topLeft.X + size.Width, position.Y + (borderSize / 2)), new Vector2(topLeft.X + size.Width + triangleWidth, topLeft.Y + size.Height - (borderSize / 2))); } if ((triangleBorders & Border.Bottom) == Border.Bottom) { sTriangleBase = DrawRectangle(new Vector2(topLeft.X + size.Width, topLeft.Y + size.Height - borderSize), new Size(triangleWidth, borderSize), Color.FromArgb(255, ColorOperator.Scale(borderColor, darkShadeFactor))); } } else { if ((triangleBorders & Border.Left) == Border.Left) { sTriangleSide = DrawLine(borderSize, Color.FromArgb(255, ColorOperator.Scale(borderColor, darkShadeFactor)), new Vector2(topLeft.X + innerSize.Width, position.Y + size.Height - (borderSize / 2)), new Vector2(topLeft.X + innerSize.Width + triangleWidth, position.Y + (borderSize / 2))); } if ((triangleBorders & Border.Top) == Border.Top) { sTriangleBase = DrawRectangle(new Vector2(topLeft.X + innerSize.Width - borderSize, topLeft.Y), new Size(triangleWidth, borderSize), Color.FromArgb(255, ColorOperator.Scale(borderColor, lightShadeFactor))); } } return(ShapeDescriptor.Join(sRectangleOutline, sTriangleSide, sTriangleBase)); }
/// <summary> /// This callback function will be called at the end of every frame to perform all the /// rendering calls for the scene, and it will also be called if the window needs to be /// repainted. After this function has returned, the sample framework will call /// Device.Present to display the contents of the next buffer in the swap chain /// </summary> public void OnFrameRender(Device device, double appTime, float elapsedTime) { bool beginSceneCalled = false; // Clear the render target and the zbuffer device.Clear(ClearFlags.ZBuffer | ClearFlags.Target, unchecked ((int)0x8C003F3F), 1.0f, 0); try { device.BeginScene(); beginSceneCalled = true; // Render the arrows so the user can visually see the light direction ColorValue arrowColor = LightColor; lightControl.OnRender(arrowColor, camera.ViewMatrix, camera.ProjectionMatrix, camera.EyeLocation); if (nif != null) { // Update the effects now Vector3 ldir = lightControl.LightDirection; Vector3 edir = -camera.EyeVector; Vector3 hdir = ldir + edir; hdir.Normalize(); float[] dir = new float[] { ldir.X, ldir.Y, ldir.Z }; effect.SetValue(ehLightDir, dir); effect.SetValue(ehLightCol, ColorOperator.Scale(LightColor, lightScale)); effect.SetValue(egAmbCol, ColorOperator.Scale(AmbientLightColor, ambLightScale)); effect.SetValue(ehViewProj, camera.ViewMatrix * camera.ProjectionMatrix); dir = new float[] { camera.EyeLocation.X, camera.EyeLocation.Y, camera.EyeLocation.Z }; effect.SetValue(ehEyePos, dir); dir = new float[] { edir.X, edir.Y, edir.Z }; effect.SetValue(ehEyeVec, dir); dir = new float[] { hdir.X, hdir.Y, hdir.Z }; effect.SetValue(ehHalfVec, dir); // Apply the technique contained in the effect if (currentSubset == -1) { nif.Render(); } else { nif.RenderSubset(currentSubset); } } // Show frame rate and help, etc RenderText(appTime); // Show UI hud.OnRender(elapsedTime); sampleUi.OnRender(elapsedTime); } finally { if (beginSceneCalled) { device.EndScene(); } } }
/// <summary>Blend the colors together</summary> public void Blend(ControlState state, float elapsedTime, float rate) { if ((States == null) || (States.Length == 0)) { return; // Nothing to do } ColorValue destColor = States[(int)state]; Current = ColorOperator.Lerp(Current, destColor, 1.0f - (float)Math.Pow(rate, 30 * elapsedTime)); }
public override void CreateShape() { base.CreateShape(); buttonDescriptor = ShapeDescriptor.ComputeShape(this, Shape.Rectangle); triangleDescriptor = Shapes.DrawEquilateralTriangle(triangleLeftVertexAbsolutePosition, DefaultTriangleSideLength, ColorOperator.Scale(Color.Black, 0.5f), false, false); buttonDescriptor.Depth = depth; triangleDescriptor.Depth = Depth.AsChildOf(depth); shapeDescriptors[0] = buttonDescriptor; shapeDescriptors[1] = triangleDescriptor; }
public static ShapeDescriptor DrawEquilateralTriangle(Vector2 leftVertex, float sideLength, Color color, bool isShaded, bool isTriangleUpside) { CustomVertex.TransformedColored[] vertices = new CustomVertex.TransformedColored[3]; Color shaded; float heightOffset = (float)(sideLength / 2 * Math.Sqrt(3)); int col1 = color.ToArgb(); int col2; if (isShaded) { shaded = Color.FromArgb(color.A, ColorOperator.Scale(color, darkShadeFactor)); col2 = shaded.ToArgb(); } else { col2 = col1; } vertices[0] = new CustomVertex.TransformedColored(leftVertex.X, leftVertex.Y, 0, 1, col2); vertices[1] = new CustomVertex.TransformedColored(leftVertex.X + sideLength, leftVertex.Y, 0, 1, col2); int[] indices = new int[3]; if (isTriangleUpside) { heightOffset *= -1; indices[0] = 0; indices[1] = 1; indices[2] = 2; } else { indices[0] = 2; indices[1] = 0; indices[2] = 1; } vertices[2] = new CustomVertex.TransformedColored(leftVertex.X + sideLength / 2, leftVertex.Y + heightOffset, 0, 1, col1); return(new ShapeDescriptor(1, vertices, indices)); }
/// <summary> /// Renders the scene /// </summary> public void Render() { // Set the render states for using point sprites device.RenderState.ZBufferWriteEnable = false; device.RenderState.AlphaBlendEnable = true; device.RenderState.SourceBlend = Blend.One; device.RenderState.DestinationBlend = Blend.One; bool lightEnabled = device.RenderState.Lighting; device.RenderState.Lighting = false; device.SetTexture(0, particleTexture); device.Transform.World = Matrix.Identity; device.RenderState.PointSpriteEnable = true; device.RenderState.PointScaleEnable = true; device.RenderState.PointSize = 1.0f; device.RenderState.PointScaleA = 0f; device.RenderState.PointScaleB = 1.0f; device.RenderState.PointScaleC = 1.0f; // Set up the vertex buffer to be rendered device.SetStreamSource(0, vertexBuffer, 0); device.VertexFormat = PointVertex.Format; PointVertex[] vertices = null; int numParticlesToRender = 0; // Lock the vertex buffer. We fill the vertex buffer in small // chunks, using LockFlags.NoOverWrite. When we are done filling // each chunk, we call DrawPrim, and lock the next chunk. When // we run out of space in the vertex buffer, we start over at // the beginning, using LockFlags.Discard. baseParticle += flush; if (baseParticle >= discard) { baseParticle = 0; } int count = 0; vertices = (PointVertex[])vertexBuffer.Lock(baseParticle * DXHelp.GetTypeSize(typeof(PointVertex)), typeof(PointVertex), (baseParticle != 0) ? LockFlags.NoOverwrite : LockFlags.Discard, flush); foreach (Particle p in particlesList) { Vector3 vPos = p.positionVector; Vector3 vVel = p.velocityVector; float fLengthSq = vVel.LengthSq(); uint steps; if (fLengthSq < 1.0f) { steps = 2; } else if (fLengthSq < 4.00f) { steps = 3; } else if (fLengthSq < 9.00f) { steps = 4; } else if (fLengthSq < 12.25f) { steps = 5; } else if (fLengthSq < 16.00f) { steps = 6; } else if (fLengthSq < 20.25f) { steps = 7; } else { steps = 8; } vVel *= -0.01f / (float)steps; System.Drawing.Color diffuse = ColorOperator.Lerp(p.fadeColor, p.diffuseColor, p.fadeProgression); // Render each particle a bunch of times to get a blurring effect for (int i = 0; i < steps; i++) { vertices[count].v = vPos; vertices[count].color = diffuse.ToArgb(); count++; if (++numParticlesToRender == flush) { // Done filling this chunk of the vertex buffer. Lets unlock and // draw this portion so we can begin filling the next chunk. vertexBuffer.Unlock(); device.DrawPrimitives(PrimitiveType.PointList, baseParticle, numParticlesToRender); // Lock the next chunk of the vertex buffer. If we are at the // end of the vertex buffer, LockFlags.Discard the vertex buffer and start // at the beginning. Otherwise, specify LockFlags.NoOverWrite, so we can // continue filling the VB while the previous chunk is drawing. baseParticle += flush; if (baseParticle >= discard) { baseParticle = 0; } vertices = (PointVertex[])vertexBuffer.Lock(baseParticle * DXHelp.GetTypeSize(typeof(PointVertex)), typeof(PointVertex), (baseParticle != 0) ? LockFlags.NoOverwrite : LockFlags.Discard, flush); count = 0; numParticlesToRender = 0; } vPos += vVel; } } // Unlock the vertex buffer vertexBuffer.Unlock(); // Render any remaining particles if (numParticlesToRender > 0) { device.DrawPrimitives(PrimitiveType.PointList, baseParticle, numParticlesToRender); } // Reset render states device.RenderState.PointSpriteEnable = false; device.RenderState.PointScaleEnable = false; device.RenderState.Lighting = lightEnabled; device.RenderState.ZBufferWriteEnable = true; device.RenderState.AlphaBlendEnable = false; }
/// <summary> /// This callback function will be called at the end of every frame to perform all the /// rendering calls for the scene, and it will also be called if the window needs to be /// repainted. After this function has returned, the sample framework will call /// Device.Present to display the contents of the next buffer in the swap chain /// </summary> public unsafe void OnFrameRender(Device device, double appTime, float elapsedTime) { bool beginSceneCalled = false; // Clear the render target and the zbuffer device.Clear(ClearFlags.ZBuffer | ClearFlags.Target, unchecked ((int)0x8C003F3F), 1.0f, 0); try { device.BeginScene(); beginSceneCalled = true; Vector3 * pLightDir = stackalloc Vector3[MaxNumberLights]; ColorValue *pLightDiffuse = stackalloc ColorValue[MaxNumberLights]; // Render the arrows so the user can visually see the light direction for (int i = 0; i < numberActiveLights; i++) { ColorValue arrowColor = (i == activeLight) ? YellowColor : WhiteColor; lightControl[i].OnRender(arrowColor, camera.ViewMatrix, camera.ProjectionMatrix, camera.EyeLocation); // Get the light direction and color pLightDir[i] = lightControl[i].LightDirection; pLightDiffuse[i] = ColorOperator.Scale(WhiteColor, lightScale); } Matrix worldMatrix = worldFix * camera.WorldMatrix; // Update the effects now effect.SetValue("g_LightDir", pLightDir, sizeof(Vector3) * MaxNumberLights); effect.SetValue("g_LightDiffuse", pLightDiffuse, sizeof(ColorValue) * MaxNumberLights); // Update the effect's variables. Instead of using strings, it would // be more efficient to cache a handle to the parameter by calling // Effect.GetParameter effect.SetValue("worldViewProjection", worldMatrix * camera.ViewMatrix * camera.ProjectionMatrix); effect.SetValue("worldMatrix", worldMatrix); effect.SetValue("appTime", (float)appTime); effect.SetValue("g_MaterialDiffuseColor", WhiteColor); effect.SetValue("g_nNumLights", numberActiveLights); // Render the scene with this technique as defined in the .fx file switch (numberActiveLights) { case 1: effect.Technique = "RenderSceneWithTexture1Light"; break; case 2: effect.Technique = "RenderSceneWithTexture2Light"; break; case 3: effect.Technique = "RenderSceneWithTexture3Light"; break; } // Apply the technique contained in the effect int passes = effect.Begin(0); for (int pass = 0; pass < passes; pass++) { effect.BeginPass(pass); // The effect interface queues up the changes and performs them // with the CommitChanges call. You do not need to call CommitChanges if // you are not setting any parameters between the BeginPass and EndPass. // effect.CommitChanges() ); // Render the mesh with the applied technique mesh.DrawSubset(0); effect.EndPass(); } effect.End(); // Show frame rate and help, etc RenderText(appTime); // Show UI hud.OnRender(elapsedTime); sampleUi.OnRender(elapsedTime); } finally { if (beginSceneCalled) { device.EndScene(); } } }
/// <summary> /// Updates the scene /// </summary> public void Update(float fSecsPerFrame, int NumParticlesToEmit, System.Drawing.Color clrEmitColor, System.Drawing.Color clrFadeColor, float fEmitVel, Vector3 vPosition) { time += fSecsPerFrame; for (int ii = particlesList.Count - 1; ii >= 0; ii--) { Particle p = (Particle)particlesList[ii]; // Calculate new position float fT = time - p.creationTime; float fGravity; if (p.isSpark) { fGravity = -5.0f; p.fadeProgression -= (fSecsPerFrame * 2.25f); } else { fGravity = -9.8f; p.fadeProgression -= fSecsPerFrame * 0.25f; } p.positionVector = p.initialVelocity * fT + p.initialPosition; p.positionVector.Y += (0.5f * fGravity) * (fT * fT); p.velocityVector.Y = p.initialVelocity.Y + fGravity * fT; if (p.fadeProgression < 0.0f) { p.fadeProgression = 0.0f; } // Kill old particles if (p.positionVector.Y < radius || p.isSpark && p.fadeProgression <= 0.0f) { // Emit sparks if (!p.isSpark) { for (int i = 0; i < 4; i++) { Particle spark; if (freeParticles.Count > 0) { spark = (Particle)freeParticles[0]; freeParticles.RemoveAt(0); } else { spark = new Particle(); } spark.isSpark = true; spark.initialVelocity = new Vector3(); spark.initialPosition = p.positionVector; spark.initialPosition.Y = radius; float fRand1 = ((float)rand.Next(int.MaxValue) / (float)int.MaxValue) * (float)Math.PI * 2.00f; float fRand2 = ((float)rand.Next(int.MaxValue) / (float)int.MaxValue) * (float)Math.PI * 0.25f; spark.initialVelocity.X = p.velocityVector.X * 0.25f + (float)Math.Cos(fRand1) * (float)Math.Sin(fRand2); spark.initialVelocity.Z = p.velocityVector.Z * 0.25f + (float)Math.Sin(fRand1) * (float)Math.Sin(fRand2); spark.initialVelocity.Y = (float)Math.Cos(fRand2); spark.initialVelocity.Y *= ((float)rand.Next(int.MaxValue) / (float)int.MaxValue) * 1.5f; spark.positionVector = spark.initialPosition; spark.velocityVector = spark.initialVelocity; spark.diffuseColor = ColorOperator.Lerp(p.fadeColor, p.diffuseColor, p.fadeProgression); spark.fadeColor = System.Drawing.Color.Black; spark.fadeProgression = 1.0f; spark.creationTime = time; particlesList.Add(spark); } } // Kill particle freeParticles.Add(p); particlesList.RemoveAt(ii); if (!p.isSpark) { particles--; } } else { particlesList[ii] = p; } } // Emit new particles int particlesEmit = particles + NumParticlesToEmit; while (particles < particlesLimit && particles < particlesEmit) { Particle particle; if (freeParticles.Count > 0) { particle = (Particle)freeParticles[0]; freeParticles.RemoveAt(0); } else { particle = new Particle(); } // Emit new particle float fRand1 = ((float)rand.Next(int.MaxValue) / (float)int.MaxValue) * (float)Math.PI * 2.0f; float fRand2 = ((float)rand.Next(int.MaxValue) / (float)int.MaxValue) * (float)Math.PI * 0.25f; particle.isSpark = false; particle.initialPosition = vPosition + new Vector3(0.0f, radius, 0.0f); particle.initialVelocity.X = (float)Math.Cos(fRand1) * (float)Math.Sin(fRand2) * 2.5f; particle.initialVelocity.Z = (float)Math.Sin(fRand1) * (float)Math.Sin(fRand2) * 2.5f; particle.initialVelocity.Y = (float)Math.Cos(fRand2); particle.initialVelocity.Y *= ((float)rand.Next(int.MaxValue) / (float)int.MaxValue) * fEmitVel; particle.positionVector = particle.initialPosition; particle.velocityVector = particle.initialVelocity; particle.diffuseColor = clrEmitColor; particle.fadeColor = clrFadeColor; particle.fadeProgression = 1.0f; particle.creationTime = time; particlesList.Add(particle); particles++; } }