public BillboardRenderComponent(Actor owner) : base(owner) { Effect = null; mDepthOnlyEffect = null; mTexture = null; mGeometry = null; mCurrentTime = 0.0f; }
public RawGeometryNode(MeshPart geometry, EffectApplication defaultMaterial) : base(defaultMaterial) { Geometry = geometry; }
public AlphaCutoutGeometryNode(MeshPart geometry, EffectApplication defaultOpaqueMaterial, EffectApplication defaultFringeMaterial) : base(geometry, defaultOpaqueMaterial) { mFringeMaterials = new Dictionary<TraversalContext.MaterialFlags, EffectApplication>(); mFringeMaterials.Add(TraversalContext.MaterialFlags.None, defaultFringeMaterial); }
public override void Initialize(ContentManager contentLoader, ComponentManifest manifest) { Effect genericEffect = contentLoader.Load <Effect>("shaders\\Billboard"); // If we have several of these objects, the content manager will return // a single shared effect instance to them all. But we want to preconfigure // the effect with parameters that are specific to this particular // object. By cloning the effect, we prevent one // from stomping over the parameter settings of another. Effect = genericEffect.Clone(); Effect.CurrentTechnique = Effect.Techniques["Billboard"]; EffectRegistry.Add(Effect, RenderOptions.BillboardParams); EffectParameterCollection parameters = Effect.Parameters; // Set the values of parameters that do not change. parameters["WindAmount"].SetValue(0.0f); parameters["BillboardWidth"].SetValue(2.0f); parameters["BillboardHeight"].SetValue(2.0f); mTexture = contentLoader.Load <Texture>((string)(manifest.Properties[ManifestKeys.TEXTURE])); parameters["Texture"].SetValue(mTexture); parameters["gBright"].SetValue(0.17f); parameters["gContrast"].SetValue(0.9f); mDepthOnlyEffect = Effect.Clone(); mDepthOnlyEffect.CurrentTechnique = mDepthOnlyEffect.Techniques["DepthOnlyBillboard"]; EffectRegistry.Add(mDepthOnlyEffect, RenderOptions.BillboardParams); mGeometry = new MeshPart(); BillboardVertex[] vertices = new BillboardVertex[4]; vertices[0].Position = Vector3.Zero; vertices[1].Position = Vector3.Zero; vertices[2].Position = Vector3.Zero; vertices[3].Position = Vector3.Zero; vertices[0].Normal = Vector3.Up; vertices[1].Normal = Vector3.Up; vertices[2].Normal = Vector3.Up; vertices[3].Normal = Vector3.Up; vertices[0].TexCoord = Vector2.Zero; vertices[1].TexCoord = Vector2.UnitX; vertices[2].TexCoord = Vector2.One; vertices[3].TexCoord = Vector2.UnitY; float randValue = 0.5f; if (manifest.Properties.ContainsKey(ManifestKeys.IS_RANDOMIZED) && (bool)(manifest.Properties[ManifestKeys.IS_RANDOMIZED])) { randValue = (float)(GameResources.ActorManager.Random.Next(-524288, 524288)) / (float)524288; } vertices[0].Random = randValue; vertices[1].Random = randValue; vertices[2].Random = randValue; vertices[3].Random = randValue; mGeometry.VertexBuffer = new VertexBuffer( SharedResources.Game.GraphicsDevice, BillboardVertex.VertexDeclaration, 4, BufferUsage.None); mGeometry.VertexBuffer.SetData(vertices); // Create and populate the index buffer. ushort[] indices = new ushort[] { 0, 1, 2, 0, 2, 3 }; mGeometry.IndexBuffer = new IndexBuffer( SharedResources.Game.GraphicsDevice, typeof(ushort), indices.Length, BufferUsage.None); mGeometry.IndexBuffer.SetData(indices); mGeometry.NumVertices = 4; mGeometry.PrimitiveCount = 2; mGeometry.StartIndex = 0; mGeometry.VertexOffset = 0; GameResources.ActorManager.PreAnimationUpdateStep += PreAnimationUpdateHandler; base.Initialize(contentLoader, manifest); }
public static void Initialize() { List<VertexPositionNormalTexture> shapesVertices = new List<VertexPositionNormalTexture>(); List<short> shapesIndices = new List<short>(); // Sphere. Sphere = new MeshPart(); Sphere.VertexOffset = shapesVertices.Count; Sphere.StartIndex = shapesIndices.Count; const int SPHERE_NUM_SEGMENTS = 32; const int SPHERE_NUM_RINGS = 18; // Poles: note that there will be texture coordinate distortion as there is // not a unique point on the texture map to assign to the pole when mapping // a rectangular texture onto a sphere. VertexPositionNormalTexture topVertex = new VertexPositionNormalTexture(Vector3.Up, Vector3.Up, Vector2.Zero); VertexPositionNormalTexture bottomVertex = new VertexPositionNormalTexture(Vector3.Down, Vector3.Down, Vector2.UnitY); shapesVertices.Add(topVertex); float phiStep = MathHelper.Pi / SPHERE_NUM_RINGS; float thetaStep = MathHelper.TwoPi / SPHERE_NUM_SEGMENTS; // Compute vertices for each ring (do not count the poles as rings). for (int i = 1; i < SPHERE_NUM_RINGS; ++i) { float phi = i * phiStep; // Vertices of ring. Note that we're adding an extra vertex on each ring so the uv coords will wrap correctly. for (int j = 0; j <= SPHERE_NUM_SEGMENTS; ++j) { float theta = j * thetaStep; VertexPositionNormalTexture v; // spherical to cartesian v.Position.X = (float)(Math.Sin(phi) * Math.Cos(theta)); v.Position.Y = (float)(Math.Cos(phi)); v.Position.Z = (float)(Math.Sin(phi) * Math.Sin(theta)); v.Normal = v.Position; v.TextureCoordinate.X = theta / MathHelper.TwoPi; v.TextureCoordinate.Y = phi / MathHelper.Pi; shapesVertices.Add(v); } } shapesVertices.Add(bottomVertex); // Compute indices for top ring. The top ring was written first to the vertex buffer // and connects the top pole to the first ring. for(short j = 1; j <= SPHERE_NUM_SEGMENTS; ++j) { shapesIndices.Add(0); shapesIndices.Add((short)(j + 1)); shapesIndices.Add(j); } // Compute indices for inner stacks (not connected to poles). // Offset the indices to the index of the first vertex in the first ring. // This is just skipping the top pole vertex. int baseIndex = 1; int verticesPerRing = SPHERE_NUM_SEGMENTS + 1; for (int i = 0; i < SPHERE_NUM_RINGS - 2; ++i) { for (int j = 0; j < SPHERE_NUM_SEGMENTS; ++j) { shapesIndices.Add((short)(baseIndex + i * verticesPerRing + j)); shapesIndices.Add((short)(baseIndex + i * verticesPerRing + j + 1)); shapesIndices.Add((short)(baseIndex + (i + 1) * verticesPerRing + j)); shapesIndices.Add((short)(baseIndex + i * verticesPerRing + j + 1)); shapesIndices.Add((short)(baseIndex + (i + 1) * verticesPerRing + j + 1)); shapesIndices.Add((short)(baseIndex + (i + 1) * verticesPerRing + j)); } } // Compute indices for bottom stack. The bottom stack was written last to the vertex buffer // and connects the bottom pole to the bottom ring. short southPoleIndex = (short)(1 + verticesPerRing * (SPHERE_NUM_RINGS - 1)); // Offset the indices to the index of the first vertex in the last ring. baseIndex = southPoleIndex - verticesPerRing; for (short j = 0; j < SPHERE_NUM_SEGMENTS; ++j) { shapesIndices.Add(southPoleIndex); shapesIndices.Add((short)(baseIndex + j)); shapesIndices.Add((short)(baseIndex + j + 1)); } Sphere.NumVertices = shapesVertices.Count - Sphere.VertexOffset; Sphere.PrimitiveCount = (shapesIndices.Count - Sphere.StartIndex) / 3; // Box. Box = new MeshPart(); Box.VertexOffset = shapesVertices.Count; Box.StartIndex = shapesIndices.Count; VertexPositionNormalTexture[] box = new VertexPositionNormalTexture[24]; Vector3[] orderOfFaces = { Vector3.Backward, Vector3.Forward, Vector3.Up, Vector3.Down, Vector3.Left, Vector3.Right }; Vector2[] orderOfTexCoords = { Vector2.UnitY, Vector2.One, Vector2.UnitX, Vector2.Zero }; for (int b = 0; b < 24; ++b) { box[b].Normal = orderOfFaces[b / 4]; box[b].TextureCoordinate = orderOfTexCoords[b % 4]; } // Back face (normal is backward vector (0, 0, -1,)) box[0].Position = new Vector3(-1.0f, -1.0f, 1.0f); box[1].Position = new Vector3(+1.0f, -1.0f, 1.0f); box[2].Position = new Vector3(+1.0f, +1.0f, 1.0f); box[3].Position = new Vector3(-1.0f, +1.0f, 1.0f); // Front face box[4].Position = new Vector3(+1.0f, -1.0f, -1.0f); box[5].Position = new Vector3(-1.0f, -1.0f, -1.0f); box[6].Position = new Vector3(-1.0f, +1.0f, -1.0f); box[7].Position = new Vector3(+1.0f, +1.0f, -1.0f); // Top face box[8].Position = new Vector3(-1.0f, 1.0f, +1.0f); box[9].Position = new Vector3(+1.0f, 1.0f, +1.0f); box[10].Position = new Vector3(+1.0f, 1.0f, -1.0f); box[11].Position = new Vector3(-1.0f, 1.0f, -1.0f); // Bottom face box[12].Position = new Vector3(-1.0f, -1.0f, -1.0f); box[13].Position = new Vector3(+1.0f, -1.0f, -1.0f); box[14].Position = new Vector3(+1.0f, -1.0f, +1.0f); box[15].Position = new Vector3(-1.0f, -1.0f, +1.0f); // Left face box[16].Position = new Vector3(-1.0f, -1.0f, -1.0f); box[17].Position = new Vector3(-1.0f, -1.0f, +1.0f); box[18].Position = new Vector3(-1.0f, +1.0f, +1.0f); box[19].Position = new Vector3(-1.0f, +1.0f, -1.0f); // Right face box[20].Position = new Vector3(1.0f, -1.0f, +1.0f); box[21].Position = new Vector3(1.0f, -1.0f, -1.0f); box[22].Position = new Vector3(1.0f, +1.0f, -1.0f); box[23].Position = new Vector3(1.0f, +1.0f, +1.0f); shapesVertices.AddRange(box); for (int b = 0; b < 21; b += 4) { shapesIndices.Add((short)b); shapesIndices.Add((short)(b + 2)); shapesIndices.Add((short)(b + 1)); shapesIndices.Add((short)(b)); shapesIndices.Add((short)(b + 3)); shapesIndices.Add((short)(b + 2)); } Box.NumVertices = shapesVertices.Count - Box.VertexOffset; Box.PrimitiveCount = (shapesIndices.Count - Box.StartIndex) / 3; VertexBuffer shapesVB = new VertexBuffer(SharedResources.Game.GraphicsDevice, VertexPositionNormalTexture.VertexDeclaration, shapesVertices.Count, BufferUsage.None); shapesVB.SetData(shapesVertices.ToArray()); IndexBuffer shapesIB = new IndexBuffer(SharedResources.Game.GraphicsDevice, IndexElementSize.SixteenBits, shapesIndices.Count, BufferUsage.None); shapesIB.SetData(shapesIndices.ToArray()); Sphere.IndexBuffer = shapesIB; Sphere.VertexBuffer = shapesVB; Box.IndexBuffer = shapesIB; Box.VertexBuffer = shapesVB; }
public override void Initialize(ContentManager contentLoader, ComponentManifest manifest) { Effect genericEffect = contentLoader.Load<Effect>("shaders\\Billboard"); // If we have several of these objects, the content manager will return // a single shared effect instance to them all. But we want to preconfigure // the effect with parameters that are specific to this particular // object. By cloning the effect, we prevent one // from stomping over the parameter settings of another. Effect = genericEffect.Clone(); Effect.CurrentTechnique = Effect.Techniques["Billboard"]; EffectRegistry.Add(Effect, RenderOptions.BillboardParams); EffectParameterCollection parameters = Effect.Parameters; // Set the values of parameters that do not change. parameters["WindAmount"].SetValue(0.0f); parameters["BillboardWidth"].SetValue(2.0f); parameters["BillboardHeight"].SetValue(2.0f); mTexture = contentLoader.Load<Texture>((string)(manifest.Properties[ManifestKeys.TEXTURE])); parameters["Texture"].SetValue(mTexture); parameters["gBright"].SetValue(0.17f); parameters["gContrast"].SetValue(0.9f); mDepthOnlyEffect = Effect.Clone(); mDepthOnlyEffect.CurrentTechnique = mDepthOnlyEffect.Techniques["DepthOnlyBillboard"]; EffectRegistry.Add(mDepthOnlyEffect, RenderOptions.BillboardParams); mGeometry = new MeshPart(); BillboardVertex[] vertices = new BillboardVertex[4]; vertices[0].Position = Vector3.Zero; vertices[1].Position = Vector3.Zero; vertices[2].Position = Vector3.Zero; vertices[3].Position = Vector3.Zero; vertices[0].Normal = Vector3.Up; vertices[1].Normal = Vector3.Up; vertices[2].Normal = Vector3.Up; vertices[3].Normal = Vector3.Up; vertices[0].TexCoord = Vector2.Zero; vertices[1].TexCoord = Vector2.UnitX; vertices[2].TexCoord = Vector2.One; vertices[3].TexCoord = Vector2.UnitY; float randValue = 0.5f; if (manifest.Properties.ContainsKey(ManifestKeys.IS_RANDOMIZED) && (bool)(manifest.Properties[ManifestKeys.IS_RANDOMIZED])) randValue = (float)(GameResources.ActorManager.Random.Next(-524288, 524288)) / (float)524288; vertices[0].Random = randValue; vertices[1].Random = randValue; vertices[2].Random = randValue; vertices[3].Random = randValue; mGeometry.VertexBuffer = new VertexBuffer( SharedResources.Game.GraphicsDevice, BillboardVertex.VertexDeclaration, 4, BufferUsage.None); mGeometry.VertexBuffer.SetData(vertices); // Create and populate the index buffer. ushort[] indices = new ushort[] { 0, 1, 2, 0, 2, 3 }; mGeometry.IndexBuffer = new IndexBuffer( SharedResources.Game.GraphicsDevice, typeof(ushort), indices.Length, BufferUsage.None); mGeometry.IndexBuffer.SetData(indices); mGeometry.NumVertices = 4; mGeometry.PrimitiveCount = 2; mGeometry.StartIndex = 0; mGeometry.VertexOffset = 0; GameResources.ActorManager.PreAnimationUpdateStep += PreAnimationUpdateHandler; base.Initialize(contentLoader, manifest); }
public static void Initialize() { List <VertexPositionNormalTexture> shapesVertices = new List <VertexPositionNormalTexture>(); List <short> shapesIndices = new List <short>(); // Sphere. Sphere = new MeshPart(); Sphere.VertexOffset = shapesVertices.Count; Sphere.StartIndex = shapesIndices.Count; const int SPHERE_NUM_SEGMENTS = 32; const int SPHERE_NUM_RINGS = 18; // Poles: note that there will be texture coordinate distortion as there is // not a unique point on the texture map to assign to the pole when mapping // a rectangular texture onto a sphere. VertexPositionNormalTexture topVertex = new VertexPositionNormalTexture(Vector3.Up, Vector3.Up, Vector2.Zero); VertexPositionNormalTexture bottomVertex = new VertexPositionNormalTexture(Vector3.Down, Vector3.Down, Vector2.UnitY); shapesVertices.Add(topVertex); float phiStep = MathHelper.Pi / SPHERE_NUM_RINGS; float thetaStep = MathHelper.TwoPi / SPHERE_NUM_SEGMENTS; // Compute vertices for each ring (do not count the poles as rings). for (int i = 1; i < SPHERE_NUM_RINGS; ++i) { float phi = i * phiStep; // Vertices of ring. Note that we're adding an extra vertex on each ring so the uv coords will wrap correctly. for (int j = 0; j <= SPHERE_NUM_SEGMENTS; ++j) { float theta = j * thetaStep; VertexPositionNormalTexture v; // spherical to cartesian v.Position.X = (float)(Math.Sin(phi) * Math.Cos(theta)); v.Position.Y = (float)(Math.Cos(phi)); v.Position.Z = (float)(Math.Sin(phi) * Math.Sin(theta)); v.Normal = v.Position; v.TextureCoordinate.X = theta / MathHelper.TwoPi; v.TextureCoordinate.Y = phi / MathHelper.Pi; shapesVertices.Add(v); } } shapesVertices.Add(bottomVertex); // Compute indices for top ring. The top ring was written first to the vertex buffer // and connects the top pole to the first ring. for (short j = 1; j <= SPHERE_NUM_SEGMENTS; ++j) { shapesIndices.Add(0); shapesIndices.Add((short)(j + 1)); shapesIndices.Add(j); } // Compute indices for inner stacks (not connected to poles). // Offset the indices to the index of the first vertex in the first ring. // This is just skipping the top pole vertex. int baseIndex = 1; int verticesPerRing = SPHERE_NUM_SEGMENTS + 1; for (int i = 0; i < SPHERE_NUM_RINGS - 2; ++i) { for (int j = 0; j < SPHERE_NUM_SEGMENTS; ++j) { shapesIndices.Add((short)(baseIndex + i * verticesPerRing + j)); shapesIndices.Add((short)(baseIndex + i * verticesPerRing + j + 1)); shapesIndices.Add((short)(baseIndex + (i + 1) * verticesPerRing + j)); shapesIndices.Add((short)(baseIndex + i * verticesPerRing + j + 1)); shapesIndices.Add((short)(baseIndex + (i + 1) * verticesPerRing + j + 1)); shapesIndices.Add((short)(baseIndex + (i + 1) * verticesPerRing + j)); } } // Compute indices for bottom stack. The bottom stack was written last to the vertex buffer // and connects the bottom pole to the bottom ring. short southPoleIndex = (short)(1 + verticesPerRing * (SPHERE_NUM_RINGS - 1)); // Offset the indices to the index of the first vertex in the last ring. baseIndex = southPoleIndex - verticesPerRing; for (short j = 0; j < SPHERE_NUM_SEGMENTS; ++j) { shapesIndices.Add(southPoleIndex); shapesIndices.Add((short)(baseIndex + j)); shapesIndices.Add((short)(baseIndex + j + 1)); } Sphere.NumVertices = shapesVertices.Count - Sphere.VertexOffset; Sphere.PrimitiveCount = (shapesIndices.Count - Sphere.StartIndex) / 3; // Box. Box = new MeshPart(); Box.VertexOffset = shapesVertices.Count; Box.StartIndex = shapesIndices.Count; VertexPositionNormalTexture[] box = new VertexPositionNormalTexture[24]; Vector3[] orderOfFaces = { Vector3.Backward, Vector3.Forward, Vector3.Up, Vector3.Down, Vector3.Left, Vector3.Right }; Vector2[] orderOfTexCoords = { Vector2.UnitY, Vector2.One, Vector2.UnitX, Vector2.Zero }; for (int b = 0; b < 24; ++b) { box[b].Normal = orderOfFaces[b / 4]; box[b].TextureCoordinate = orderOfTexCoords[b % 4]; } // Back face (normal is backward vector (0, 0, -1,)) box[0].Position = new Vector3(-1.0f, -1.0f, 1.0f); box[1].Position = new Vector3(+1.0f, -1.0f, 1.0f); box[2].Position = new Vector3(+1.0f, +1.0f, 1.0f); box[3].Position = new Vector3(-1.0f, +1.0f, 1.0f); // Front face box[4].Position = new Vector3(+1.0f, -1.0f, -1.0f); box[5].Position = new Vector3(-1.0f, -1.0f, -1.0f); box[6].Position = new Vector3(-1.0f, +1.0f, -1.0f); box[7].Position = new Vector3(+1.0f, +1.0f, -1.0f); // Top face box[8].Position = new Vector3(-1.0f, 1.0f, +1.0f); box[9].Position = new Vector3(+1.0f, 1.0f, +1.0f); box[10].Position = new Vector3(+1.0f, 1.0f, -1.0f); box[11].Position = new Vector3(-1.0f, 1.0f, -1.0f); // Bottom face box[12].Position = new Vector3(-1.0f, -1.0f, -1.0f); box[13].Position = new Vector3(+1.0f, -1.0f, -1.0f); box[14].Position = new Vector3(+1.0f, -1.0f, +1.0f); box[15].Position = new Vector3(-1.0f, -1.0f, +1.0f); // Left face box[16].Position = new Vector3(-1.0f, -1.0f, -1.0f); box[17].Position = new Vector3(-1.0f, -1.0f, +1.0f); box[18].Position = new Vector3(-1.0f, +1.0f, +1.0f); box[19].Position = new Vector3(-1.0f, +1.0f, -1.0f); // Right face box[20].Position = new Vector3(1.0f, -1.0f, +1.0f); box[21].Position = new Vector3(1.0f, -1.0f, -1.0f); box[22].Position = new Vector3(1.0f, +1.0f, -1.0f); box[23].Position = new Vector3(1.0f, +1.0f, +1.0f); shapesVertices.AddRange(box); for (int b = 0; b < 21; b += 4) { shapesIndices.Add((short)b); shapesIndices.Add((short)(b + 2)); shapesIndices.Add((short)(b + 1)); shapesIndices.Add((short)(b)); shapesIndices.Add((short)(b + 3)); shapesIndices.Add((short)(b + 2)); } Box.NumVertices = shapesVertices.Count - Box.VertexOffset; Box.PrimitiveCount = (shapesIndices.Count - Box.StartIndex) / 3; VertexBuffer shapesVB = new VertexBuffer(SharedResources.Game.GraphicsDevice, VertexPositionNormalTexture.VertexDeclaration, shapesVertices.Count, BufferUsage.None); shapesVB.SetData(shapesVertices.ToArray()); IndexBuffer shapesIB = new IndexBuffer(SharedResources.Game.GraphicsDevice, IndexElementSize.SixteenBits, shapesIndices.Count, BufferUsage.None); shapesIB.SetData(shapesIndices.ToArray()); Sphere.IndexBuffer = shapesIB; Sphere.VertexBuffer = shapesVB; Box.IndexBuffer = shapesIB; Box.VertexBuffer = shapesVB; }
public AlphaCutoutGeometryNode(MeshPart geometry, EffectApplication defaultOpaqueMaterial, EffectApplication defaultFringeMaterial) : base(geometry, defaultOpaqueMaterial) { mFringeMaterials = new Dictionary <TraversalContext.MaterialFlags, EffectApplication>(); mFringeMaterials.Add(TraversalContext.MaterialFlags.None, defaultFringeMaterial); }