/// <summary> /// Called once per frame, the call is the entry point for 3d rendering. This /// function sets up render states, clears the viewport, and renders the scene. /// </summary> protected override void Render() { // Clear the viewport device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, 0x000000ff, 1.0f, 0); device.BeginScene(); device.VertexDeclaration = ourDeclaration; device.VertexShader = ourShader; device.SetStreamSource(0, vertexBuffer, 0, DXHelp.GetTypeSize(typeof(Vector2))); device.Indices = indexBuffer; device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, numberVertices, 0, numberIndices / 3); // Output statistics drawingFont.DrawText(2, 1, System.Drawing.Color.Yellow, frameStats); drawingFont.DrawText(2, 20, System.Drawing.Color.Yellow, deviceStats); if (doShowHelp) { drawingFontSmall.DrawText(2, 40, System.Drawing.Color.White, "Keyboard controls:"); drawingFontSmall.DrawText(20, 60, System.Drawing.Color.White, "Move\nTurn\nPitch\nSlide\nHelp\nChange device\nExit"); drawingFontSmall.DrawText(210, 60, System.Drawing.Color.White, "W,S\nE,Q\nA,Z\nArrow keys\nF1\nF2\nEsc"); } else { drawingFontSmall.DrawText(2, 40, System.Drawing.Color.White, "Press F1 for help"); } device.EndScene(); }
public void FindMyFriends(string username, Server serverObject) { System.Collections.ArrayList friendList = new System.Collections.ArrayList(); foreach (XmlNode n in xmlDom.SelectNodes(gSchemaRootName + "/" + gFriendRootName + "/" + gRowName + "/" + gClientName)) { if (n.FirstChild.Value.ToLower() == username.ToLower()) { FriendType f = new FriendType(); f.friendName = n.NextSibling.FirstChild.Value; XmlNode friendNode = GetUserNode(f.friendName); f.friend = bool.Parse(n.NextSibling.NextSibling.FirstChild.Value); f.friendId = int.Parse(friendNode.NextSibling.NextSibling.NextSibling.FirstChild.Value); friendList.Add(f); } } if (friendList.Count > 0) { byte[] buffer = null; int offset = 0; // Well, we obviously have some friends, tell me all about them int sendId = GetCurrentPlayerId(username); DXHelp.AddDataToBuffer(ref buffer, MessageType.SendClientFriends, ref offset); // How many friends are we sending? DXHelp.AddDataToBuffer(ref buffer, friendList.Count, ref offset); foreach (FriendType f in friendList) { // Add whether they are a friend or blocked as well as the name DXHelp.AddDataToBuffer(ref buffer, f.friend, ref offset); DXHelp.AddDataToBuffer(ref buffer, f.friendName, ref offset); } serverObject.SendTo(sendId, buffer, 0, 0); // Now that's done, for every friend that's online, notify me again foreach (FriendType f in friendList) { if (f.friendId != 0) { buffer = null; offset = 0; DXHelp.AddDataToBuffer(ref buffer, MessageType.FriendLogon, ref offset); DXHelp.AddDataToBuffer(ref buffer, f.friendName, ref offset); serverObject.SendTo(sendId, buffer, 0, 0); } } } }
/// <summary> /// Called once per frame, the call is the entry point for 3d rendering. This /// function sets up render states, clears the viewport, and renders the scene. /// </summary> protected override void Render() { // Clear the viewport device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.Blue, 1.0f, 0); device.BeginScene(); if (useShader) { device.VertexFormat = BlendVertex.Format; device.VertexShader = shader; device.SetStreamSource(0, vertexBuffer, 0, DXHelp.GetTypeSize(typeof(BlendVertex))); device.Indices = indexBuffer; device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, numVertices, 0, numFaces); } else { device.VertexShader = null; // Enable vertex blending using API device.Transform.World = upperArm; device.Transform.World1 = lowerArm; renderState.VertexBlend = VertexBlend.OneWeights; // Display the object blendObject.Render(device); } // Output statistics drawingFont.DrawText(2, 1, System.Drawing.Color.Yellow, frameStats); drawingFont.DrawText(2, 20, System.Drawing.Color.Yellow, deviceStats); if (useShader) { drawingFont.DrawText(2, 40, System.Drawing.Color.White, "Using vertex shader"); } else { drawingFont.DrawText(2, 40, System.Drawing.Color.White, "Using RenderState.VertexBlend"); } device.EndScene(); }
public void NotifyFriends(string username, MessageType msg, Server serverObject) { int offset = 0; byte[] buffer = null; // We need to check to see if the user logging in is anyones friend. foreach (XmlNode n in xmlDom.SelectNodes(gSchemaRootName + "/" + gFriendRootName + "/" + gRowName + "/" + gFriendName)) { if (n.FirstChild.Value.ToLower() == username.ToLower()) // Yup, I got some friends! { // Are they logged on? XmlNode friend = GetUserNode(n.PreviousSibling.FirstChild.Value); int playerId = int.Parse(friend.NextSibling.NextSibling.NextSibling.FirstChild.Value); if (playerId != 0) // Yup, they got a dplay ID { DXHelp.AddDataToBuffer(ref buffer, msg, ref offset); DXHelp.AddDataToBuffer(ref buffer, username, ref offset); serverObject.SendTo(playerId, buffer, 0, 0); } break; } } }
public override void Render(Camera cam) { try { if (m_ActiveParticles.Count > 0) { // Set the render states for using point sprites CGameEngine.Device3D.RenderState.ZBufferWriteEnable = false; CGameEngine.Device3D.RenderState.AlphaBlendEnable = true; CGameEngine.Device3D.RenderState.SourceBlend = Blend.One; CGameEngine.Device3D.RenderState.DestinationBlend = Blend.One; CGameEngine.Device3D.SetTexture(0, m_Texture); CGameEngine.Device3D.RenderState.PointSpriteEnable = true; CGameEngine.Device3D.RenderState.PointScaleEnable = true; CGameEngine.Device3D.RenderState.PointSize = m_PointSize; CGameEngine.Device3D.RenderState.PointSizeMin = m_PointSizeMin; CGameEngine.Device3D.RenderState.PointScaleA = m_PointScaleA; CGameEngine.Device3D.RenderState.PointScaleB = m_PointScaleB; CGameEngine.Device3D.RenderState.PointScaleC = m_PointScaleC; CGameEngine.Device3D.VertexFormat = CustomVertex.PositionColoredTextured.Format; // Set up the vertex buffer to be rendered CGameEngine.Device3D.SetStreamSource(0, m_VB, 0); CustomVertex.PositionColoredTextured[] 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. m_BaseParticle += m_Flush; if (m_BaseParticle >= m_Discard) { m_BaseParticle = 0; } int count = 0; vertices = (CustomVertex.PositionColoredTextured[])m_VB.Lock(m_BaseParticle * DXHelp.GetTypeSize(typeof(CustomVertex.PositionColoredTextured)), typeof(CustomVertex.PositionColoredTextured), (m_BaseParticle != 0) ? LockFlags.NoOverwrite : LockFlags.Discard, m_Flush); foreach (Particle p in m_ActiveParticles) { vertices[count].X = p.m_Position.X; vertices[count].Y = p.m_Position.Y; vertices[count].Z = p.m_Position.Z; vertices[count].Color = p.m_Color.ToArgb(); count++; if (++numParticlesToRender == m_Flush) { // Done filling this chunk of the vertex buffer. Lets unlock and // draw this portion so we can begin filling the next chunk. m_VB.Unlock(); CGameEngine.Device3D.DrawPrimitives(PrimitiveType.PointList, m_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. m_BaseParticle += m_Flush; if (m_BaseParticle >= m_Discard) { m_BaseParticle = 0; } vertices = (CustomVertex.PositionColoredTextured[])m_VB.Lock(m_BaseParticle * DXHelp.GetTypeSize(typeof(CustomVertex.PositionColoredTextured)), typeof(CustomVertex.PositionColoredTextured), (m_BaseParticle != 0) ? LockFlags.NoOverwrite : LockFlags.Discard, m_Flush); count = 0; numParticlesToRender = 0; } } // Unlock the vertex buffer m_VB.Unlock(); // Render any remaining particles if (numParticlesToRender > 0) { CGameEngine.Device3D.DrawPrimitives(PrimitiveType.PointList, m_BaseParticle, numParticlesToRender); } // Reset render states CGameEngine.Device3D.RenderState.PointSpriteEnable = false; CGameEngine.Device3D.RenderState.PointScaleEnable = false; CGameEngine.Device3D.RenderState.ZBufferWriteEnable = true; CGameEngine.Device3D.RenderState.AlphaBlendEnable = false; } } catch (DirectXException d3de) { Console.AddLine("Unable to Render Particles for " + Name); Console.AddLine(d3de.ErrorString); } catch (Exception e) { Console.AddLine("Unable to Render Particles for " + Name); Console.AddLine(e.Message); } }
/// <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; }
public void Render(Device Device3D, DeviceInfo deviceInfo) { Update(); try { if (m_ActiveParticles.Count > 0) { Device3D.Transform.World = this.World; // il faut désactiver la lumière sinon les couleurs ne sont pas utilisées Device3D.RenderState.Lighting = false; // Set the render states for using point sprites Device3D.RenderState.ZBufferWriteEnable = false; Device3D.RenderState.AlphaBlendEnable = true; Device3D.RenderState.SourceBlend = Blend.SourceAlpha; Device3D.RenderState.DestinationBlend = Blend.One; Device3D.TextureState[0].ColorOperation = TextureOperation.Modulate; Device3D.TextureState[0].ColorArgument1 = TextureArgument.TextureColor; Device3D.TextureState[0].ColorArgument2 = TextureArgument.Diffuse; Device3D.TextureState[0].AlphaOperation = TextureOperation.Modulate; Device3D.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor; Device3D.TextureState[0].AlphaArgument2 = TextureArgument.Diffuse; Device3D.SetTexture(0, m_Texture.GetTexture()); Device3D.RenderState.PointSpriteEnable = true; Device3D.RenderState.PointScaleEnable = true; Device3D.RenderState.PointSize = m_PointSize; Device3D.RenderState.PointSizeMin = m_PointSizeMin; Device3D.RenderState.PointScaleA = m_PointScaleA; Device3D.RenderState.PointScaleB = m_PointScaleB; Device3D.RenderState.PointScaleC = m_PointScaleC; Device3D.VertexFormat = CustomVertex.PositionColoredTextured.Format; // Set up the vertex buffer to be rendered Device3D.SetStreamSource(0, m_VB, 0); CustomVertex.PositionColoredTextured[] 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. m_BaseParticle += m_Flush; if (m_BaseParticle >= m_Discard) { m_BaseParticle = 0; } int count = 0; vertices = (CustomVertex.PositionColoredTextured[])m_VB.Lock(m_BaseParticle * DXHelp.GetTypeSize(typeof(CustomVertex.PositionColoredTextured)), typeof(CustomVertex.PositionColoredTextured), (m_BaseParticle != 0) ? LockFlags.NoOverwrite : LockFlags.Discard, m_Flush); foreach (Particle p in m_ActiveParticles) { vertices[count].X = p.Position.X; vertices[count].Y = p.Position.Y; vertices[count].Z = p.Position.Z; vertices[count].Color = unchecked ((int)p.Color.ToArgb()); count++; if (++numParticlesToRender == m_Flush) { // Done filling this chunk of the vertex buffer. Lets unlock and // draw this portion so we can begin filling the next chunk. m_VB.Unlock(); Device3D.DrawPrimitives(PrimitiveType.PointList, m_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. m_BaseParticle += m_Flush; if (m_BaseParticle >= m_Discard) { m_BaseParticle = 0; } vertices = (CustomVertex.PositionColoredTextured[])m_VB.Lock(m_BaseParticle * DXHelp.GetTypeSize(typeof(CustomVertex.PositionColoredTextured)), typeof(CustomVertex.PositionColoredTextured), (m_BaseParticle != 0) ? LockFlags.NoOverwrite : LockFlags.Discard, m_Flush); count = 0; numParticlesToRender = 0; } } // Unlock the vertex buffer m_VB.Unlock(); // Render any remaining particles if (numParticlesToRender > 0) { Device3D.DrawPrimitives(PrimitiveType.PointList, m_BaseParticle, numParticlesToRender); } // Reset render states Device3D.RenderState.PointSpriteEnable = false; Device3D.RenderState.PointScaleEnable = false; Device3D.RenderState.ZBufferWriteEnable = true; Device3D.RenderState.AlphaBlendEnable = false; //Console.AddLine(m_ActiveParticles[0].Position.ToString() + "Alpha:" + m_ActiveParticles[0].Color.A); } } catch (DirectXException d3de) { Console.AddLine("Unable to Render Particles"); Console.AddLine(d3de.ErrorString); } catch (Exception e) { Console.AddLine("Unable to Render Particles"); Console.AddLine(e.Message); } }
/// <summary> /// Called once per frame, the call is the entry point for 3d /// rendering. This function sets up render states, clears the /// viewport, and renders the scene. /// </summary> protected override void Render() { // Begin the scene device.BeginScene(); // Render the Skybox { Matrix world = Matrix.Scaling(10.0f, 10.0f, 10.0f); Matrix view = matView; view.M41 = view.M42 = view.M43 = 0.0f; device.Transform.World = world; device.Transform.View = view; device.Transform.Projection = matProject; device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor; device.TextureState[0].ColorOperation = TextureOperation.SelectArg1; device.SamplerState[0].MinFilter = TextureFilter.Linear; device.SamplerState[0].MagFilter = TextureFilter.Linear; device.SamplerState[0].AddressU = TextureAddress.Wrap; device.SamplerState[0].AddressV = TextureAddress.Wrap; // Always pass Z-test, so we can avoid clearing color and depth buffers device.RenderState.ZBufferFunction = Compare.Always; skyBox.Render(device); device.RenderState.ZBufferFunction = Compare.LessEqual; } // Render the environment-mapped ShinyTeapot { // Set transform state Matrix viewProject = Matrix.Multiply(matView, matProject); Matrix matViewInv = Matrix.Invert(matView); Vector4 vecPosition = new Vector4(matViewInv.M41, matViewInv.M42, matViewInv.M43, 1.0f); effect.SetValue("matWorld", matWorld); effect.SetValue("matViewProject", viewProject); effect.SetValue("vecPosition", vecPosition); // Draw teapot VertexBuffer vb = shinyTeapot.LocalVertexBuffer; IndexBuffer ib = shinyTeapot.LocalIndexBuffer; device.VertexFormat = shinyTeapot.LocalMesh.VertexFormat; device.SetStreamSource(0, vb, 0, DXHelp.GetTypeSize(typeof(EnvMappedVertex))); device.Indices = ib; int passes = effect.Begin(0); for (int iPass = 0; iPass < passes; iPass++) { effect.Pass(iPass); device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, shinyTeapot.LocalMesh.NumberVertices, 0, shinyTeapot.LocalMesh.NumberFaces); } effect.End(); } // Output statistics font.DrawText(2, 1, System.Drawing.Color.Yellow, frameStats); font.DrawText(2, 21, System.Drawing.Color.Yellow, deviceStats); // End the scene. device.EndScene(); }
/// <summary> /// Renders all visual elements in the scene. This is called by the main /// Render() function, and also by the RenderIntoCubeMap() function. /// </summary> private void RenderScene(Matrix View, Matrix Project, bool canRenderTeapot) { // Render the Skybox { Matrix matWorld = Matrix.Scaling(10.0f, 10.0f, 10.0f); Matrix matView = View; matView.M41 = matView.M42 = matView.M43 = 0.0f; device.Transform.World = matWorld; device.Transform.View = matView; device.Transform.Projection = Project; device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor; device.TextureState[0].ColorOperation = TextureOperation.SelectArg1; device.SamplerState[0].MinFilter = TextureFilter.Linear; device.SamplerState[0].MagFilter = TextureFilter.Linear; device.SamplerState[0].AddressU = TextureAddress.Mirror; device.SamplerState[0].AddressV = TextureAddress.Mirror; // Always pass Z-test, so we can avoid clearing color and depth buffers device.RenderState.ZBufferFunction = Compare.Always; skyBoxMesh.Render(device); device.RenderState.ZBufferFunction = Compare.LessEqual; } // Render the Airplane { device.Transform.World = airplaneMatrix; device.Transform.View = View; device.Transform.Projection = Project; device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor; device.TextureState[0].ColorOperation = TextureOperation.SelectArg1; device.SamplerState[0].MinFilter = TextureFilter.Linear; device.SamplerState[0].MagFilter = TextureFilter.Linear; device.SamplerState[0].AddressU = TextureAddress.Wrap; device.SamplerState[0].AddressV = TextureAddress.Wrap; airplaneMesh.Render(device, true, false); device.Transform.World = worldMatrix; } // Render the environment-mapped ShinyTeapot if (canRenderTeapot) { // Set transform state if (cubeMap != null) { effect.SetValue(worldMatrixHandle, worldMatrix); effect.SetValue(viewMatrixHandle, View); } else { Matrix matWorldView = Matrix.Multiply(worldMatrix, View); effect.SetValue(worldViewMatrixHandle, matWorldView); } effect.SetValue(projectionMatrixHandle, Project); // Draw teapot VertexBuffer tempVertexBuffer = shinyTeapotMesh.LocalVertexBuffer; IndexBuffer tempIndexBuffer = shinyTeapotMesh.LocalIndexBuffer; int numVert = shinyTeapotMesh.LocalMesh.NumberVertices; int numFace = shinyTeapotMesh.LocalMesh.NumberFaces; device.SetStreamSource(0, tempVertexBuffer, 0, DXHelp.GetTypeSize(typeof(EnvMappedVertex))); device.VertexFormat = EnvMappedVertex.Format; device.Indices = tempIndexBuffer; int Passes = effect.Begin(0); for (int iPass = 0; iPass < Passes; iPass++) { effect.Pass(iPass); device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, numVert, 0, numFace); } effect.End(); } }
/// <summary> /// The device has been created. Resources that are not lost on /// Reset() can be created here -- resources in Pool.Managed, /// Pool.Scratch, or Pool.SystemMemory. Image surfaces created via /// CreateImageSurface are never lost and can be created here. Vertex /// shaders and pixel shaders can also be created here as they are not /// lost on Reset(). /// </summary> protected override void InitializeDeviceObjects() { VertexBuffer pMeshSourceVB = null; IndexBuffer pMeshSourceIB = null; Vertex[] src = null; GraphicsStream dst = null; GraphicsMesh DolphinMesh01 = new GraphicsMesh(); GraphicsMesh DolphinMesh02 = new GraphicsMesh(); GraphicsMesh DolphinMesh03 = new GraphicsMesh(); GraphicsMesh SeaFloorMesh = new GraphicsMesh(); // Initialize the font's internal textures drawingFont.InitializeDeviceObjects(device); try { // Create texture for the dolphin dolphinTexture = GraphicsUtility.CreateTexture(device, "Dolphin.bmp"); // Create textures for the seafloor seaFloorTexture = GraphicsUtility.CreateTexture(device, "SeaFloor.bmp"); // Create textures for the water caustics for (int t = 0; t < 32; t++) { string name = string.Format("Caust{0:D2}.tga", t); causticTextures[t] = GraphicsUtility.CreateTexture(device, name); } // Load the file-based mesh objects DolphinMesh01.Create(device, "dolphin1.x"); DolphinMesh02.Create(device, "dolphin2.x"); DolphinMesh03.Create(device, "dolphin3.x"); SeaFloorMesh.Create(device, "SeaFloor.x"); } catch { SampleException e = new MediaNotFoundException(); HandleSampleException(e, ApplicationMessage.ApplicationMustExit); throw e; } // Set the FVF type to match the vertex format we want DolphinMesh01.SetVertexFormat(device, Vertex.Format); DolphinMesh02.SetVertexFormat(device, Vertex.Format); DolphinMesh03.SetVertexFormat(device, Vertex.Format); SeaFloorMesh.SetVertexFormat(device, Vertex.Format); // Get the number of vertices and faces for the meshes numDolphinVertices = DolphinMesh01.SystemMesh.NumberVertices; numDolphinFaces = DolphinMesh01.SystemMesh.NumberFaces; numSeaFloorVertices = SeaFloorMesh.SystemMesh.NumberVertices; numSeaFloorFaces = SeaFloorMesh.SystemMesh.NumberFaces; // Create the dolphin and seafloor vertex and index buffers dolphinVertexBuffer1 = new VertexBuffer(typeof(Vertex), numDolphinVertices, device, Usage.WriteOnly, 0, Pool.Managed); dolphinVertexBuffer2 = new VertexBuffer(typeof(Vertex), numDolphinVertices, device, Usage.WriteOnly, 0, Pool.Managed); dolphinVertexBuffer3 = new VertexBuffer(typeof(Vertex), numDolphinVertices, device, Usage.WriteOnly, 0, Pool.Managed); seaFloorVertexBuffer = new VertexBuffer(typeof(Vertex), numSeaFloorVertices, device, Usage.WriteOnly, 0, Pool.Managed); dolphinIndexBuffer = new IndexBuffer(typeof(short), numDolphinFaces * 3, device, Usage.WriteOnly, Pool.Managed); seaFloorIndexBuffer = new IndexBuffer(typeof(short), numSeaFloorFaces * 3, device, Usage.WriteOnly, Pool.Managed); // Copy vertices for mesh 01 pMeshSourceVB = DolphinMesh01.SystemMesh.VertexBuffer; dst = dolphinVertexBuffer1.Lock(0, DXHelp.GetTypeSize(typeof(Vertex)) * numDolphinVertices, 0); src = (Vertex[])pMeshSourceVB.Lock(0, typeof(Vertex), 0, numDolphinVertices); dst.Write(src); dolphinVertexBuffer1.Unlock(); pMeshSourceVB.Unlock(); pMeshSourceVB.Dispose(); // Copy vertices for mesh 2 pMeshSourceVB = DolphinMesh02.SystemMesh.VertexBuffer; dst = dolphinVertexBuffer2.Lock(0, DXHelp.GetTypeSize(typeof(Vertex)) * numDolphinVertices, 0); src = (Vertex[])pMeshSourceVB.Lock(0, typeof(Vertex), 0, numDolphinVertices); dst.Write(src); dolphinVertexBuffer2.Unlock(); pMeshSourceVB.Unlock(); pMeshSourceVB.Dispose(); // Copy vertices for mesh 3 pMeshSourceVB = DolphinMesh03.SystemMesh.VertexBuffer; dst = dolphinVertexBuffer3.Lock(0, DXHelp.GetTypeSize(typeof(Vertex)) * numDolphinVertices, 0); src = (Vertex[])pMeshSourceVB.Lock(0, typeof(Vertex), 0, numDolphinVertices); dst.Write(src); dolphinVertexBuffer3.Unlock(); pMeshSourceVB.Unlock(); pMeshSourceVB.Dispose(); // Copy vertices for the seafloor mesh, and add some bumpiness pMeshSourceVB = SeaFloorMesh.SystemMesh.VertexBuffer; dst = seaFloorVertexBuffer.Lock(0, DXHelp.GetTypeSize(typeof(Vertex)) * numSeaFloorVertices, 0); src = (Vertex[])pMeshSourceVB.Lock(0, typeof(Vertex), 0, numSeaFloorVertices); System.Random r = new System.Random(); for (int i = 0; i < numSeaFloorVertices; i++) { src[i].p.Y += (r.Next() / (float)int.MaxValue); src[i].p.Y += (r.Next() / (float)int.MaxValue); src[i].p.Y += (r.Next() / (float)int.MaxValue); src[i].tu *= 10; src[i].tv *= 10; } dst.Write(src); seaFloorVertexBuffer.Unlock(); pMeshSourceVB.Unlock(); pMeshSourceVB.Dispose(); GraphicsStream dstib = null; short[] srcib = null; // Copy indices for the dolphin mesh pMeshSourceIB = DolphinMesh01.SystemMesh.IndexBuffer; dstib = dolphinIndexBuffer.Lock(0, DXHelp.GetTypeSize(typeof(short)) * numDolphinFaces * 3, 0); srcib = (short[])pMeshSourceIB.Lock(0, typeof(short), 0, numDolphinFaces * 3); dstib.Write(srcib); dolphinIndexBuffer.Unlock(); pMeshSourceIB.Unlock(); pMeshSourceIB.Dispose(); // Copy indices for the seafloor mesh pMeshSourceIB = SeaFloorMesh.SystemMesh.IndexBuffer; dstib = seaFloorIndexBuffer.Lock(0, DXHelp.GetTypeSize(typeof(short)) * numSeaFloorFaces * 3, 0); srcib = (short[])pMeshSourceIB.Lock(0, typeof(short), 0, numSeaFloorFaces * 3); dstib.Write(srcib); seaFloorIndexBuffer.Unlock(); pMeshSourceIB.Unlock(); pMeshSourceIB.Dispose(); }
/// <summary> /// Called once per frame, the call is the entry point for 3d rendering. This /// function sets up render states, clears the viewport, and renders the scene. /// </summary> protected override void Render() { // Clear the viewport device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, WaterColor, 1.0f, 0); device.BeginScene(); float[] fAmbientLight = { 0.25f, 0.25f, 0.25f, 0.25f }; device.SetVertexShaderConstant(22, fAmbientLight); // Render the seafloor device.SetTexture(0, seaFloorTexture); device.VertexDeclaration = seaFloorVertexDeclaration; device.VertexShader = seaFloorVertexShader; device.SetStreamSource(0, seaFloorVertexBuffer, 0, DXHelp.GetTypeSize(typeof(Vertex))); device.Indices = seaFloorIndexBuffer; device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, numSeaFloorVertices, 0, numSeaFloorFaces); // Render the dolphin device.SetTexture(0, dolphinTexture); device.VertexDeclaration = dolphinVertexDeclaration; device.VertexShader = dolphinVertexShader; device.SetStreamSource(0, dolphinVertexBuffer1, 0, DXHelp.GetTypeSize(typeof(Vertex))); device.SetStreamSource(1, dolphinVertexBuffer2, 0, DXHelp.GetTypeSize(typeof(Vertex))); device.SetStreamSource(2, dolphinVertexBuffer3, 0, DXHelp.GetTypeSize(typeof(Vertex))); device.Indices = dolphinIndexBuffer; device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, numDolphinVertices, 0, numDolphinFaces); // Now, we are going to do a 2nd pass, to alpha-blend in the caustics. // The caustics use a 2nd set of texture coords that are generated // by the vertex shaders. Lighting from the light above is used, but // ambient is turned off to avoid lighting objects from below (for // instance, we don't want caustics appearing on the dolphin's // underbelly). Finally, fog color is set to black, so that caustics // fade in distance. // Turn on alpha blending device.RenderState.AlphaBlendEnable = true; device.RenderState.SourceBlend = Blend.One; device.RenderState.DestinationBlend = Blend.One; // Setup the caustic texture device.SetTexture(0, currentCausticTexture); // Set ambient and fog colors to black float[] fAmbientDark = { 0.0f, 0.0f, 0.0f, 0.0f }; device.SetVertexShaderConstant(22, fAmbientDark); device.RenderState.FogColor = System.Drawing.Color.Black; // Render the caustic effects for the seafloor device.VertexDeclaration = seaFloorVertexDeclaration; device.VertexShader = seaFloorVertexShader2; device.SetStreamSource(0, seaFloorVertexBuffer, 0, DXHelp.GetTypeSize(typeof(Vertex))); device.Indices = seaFloorIndexBuffer; device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, numSeaFloorVertices, 0, numSeaFloorFaces); // Finally, render the caustic effects for the dolphin device.VertexDeclaration = dolphinVertexDeclaration; device.VertexShader = dolphinVertexShader2; device.SetStreamSource(0, dolphinVertexBuffer1, 0, DXHelp.GetTypeSize(typeof(Vertex))); device.SetStreamSource(1, dolphinVertexBuffer2, 0, DXHelp.GetTypeSize(typeof(Vertex))); device.SetStreamSource(2, dolphinVertexBuffer3, 0, DXHelp.GetTypeSize(typeof(Vertex))); device.Indices = dolphinIndexBuffer; device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, numDolphinVertices, 0, numDolphinFaces); // Restore modified render states device.RenderState.AlphaBlendEnable = false; device.RenderState.FogColor = WaterColor; // Output statistics drawingFont.DrawText(2, 1, System.Drawing.Color.Yellow, frameStats); drawingFont.DrawText(2, 20, System.Drawing.Color.Yellow, deviceStats); device.EndScene(); }