public void DrawQuad(IGameViewport viewport, ReadOnlySpan <ShapeVertex3d> corners, PackedLinearColorA color, ITexture texture) { _discVertexBuffer.Resource.Update(corners); _discBufferBinding.Resource.Bind(); BindQuadMaterial(viewport, color, texture); _device.SetIndexBuffer(_discIndexBuffer); _device.DrawIndexed(PrimitiveType.TriangleList, 4, 2 * 3); }
public void Render(RenderingDevice device) { if (VertexCount > 0 && IndexCount > 0) { BufferBinding.Resource.Bind(); device.SetIndexBuffer(IndexBuffer); device.DrawIndexed(PrimitiveType.TriangleList, VertexCount, IndexCount); } }
public void DrawRectangleWithMaterial(Span <Vertex2d> corners, IMdfRenderMaterial material) { MdfRenderOverrides overrides = new MdfRenderOverrides(); overrides.ignoreLighting = true; overrides.uiProjection = true; material?.Bind((WorldCamera)null, _device, Array.Empty <Light3d>(), overrides); _device.SetDepthStencilState(noDepthState); foreach (ref var vertex in corners) { vertex.normal = new Vector4(0, 0, -1, 0); } // Copy the vertices _device.UpdateBuffer <Vertex2d>(vertexBuffer, corners); mdfBufferBinding.Bind(); _device.SetIndexBuffer(indexBuffer); _device.DrawIndexed(PrimitiveType.TriangleList, 4, 6); }
public void Render(IGameViewport viewport, IAnimatedModel model, AnimatedModelParams animParams, IList <Light3d> lights, MdfRenderOverrides materialOverrides = null) { var renderData = GetOrCreateState(model); var materialIds = model.GetSubmeshes(); for (var i = 0; i < materialIds.Length; ++i) { var material = materialIds[i]; var submesh = animParams.rotation3d ? model.GetSubmeshForParticles(animParams, i) : model.GetSubmesh(animParams, i); // Usually this should not happen, since it means there's // an unbound replacement material if (material == null) { continue; } material.Bind(viewport, mDevice, lights, materialOverrides); // Do we have to recalculate the normals? if (material.GetSpec().recalculateNormals) { RecalcNormals( submesh.VertexCount, submesh.Positions, submesh.Normals, submesh.PrimitiveCount, submesh.Indices ); } var submeshData = GetSubmeshData(renderData, i, submesh); submeshData.binding.Resource.Bind(); mDevice.SetIndexBuffer(submeshData.idxBuffer); mDevice.DrawIndexed(PrimitiveType.TriangleList, submesh.VertexCount, submesh.PrimitiveCount * 3); } }
private void RenderParticles(PartSysEmitter emitter) { var it = emitter.NewIterator(); var totalCount = emitter.GetActiveCount(); if (totalCount == 0) { return; } // Lazily initialize render state if (!emitter.HasRenderState()) { emitter.SetRenderState( new QuadEmitterRenderState(_device, emitter)); } var renderState = (QuadEmitterRenderState)emitter.GetRenderState(); using var spriteMemory = MemoryPool.Rent(4 * totalCount); var sUpdateBuffer = spriteMemory.Memory.Span.Slice(0, 4 * totalCount); var i = 0; while (it.HasNext()) { var particleIdx = it.Next(); FillVertex(emitter, particleIdx, sUpdateBuffer, i); i += 4; } renderState.vertexBuffer.Resource.Update <SpriteVertex>(sUpdateBuffer); _device.SetMaterial(renderState.material); renderState.bufferBinding.Resource.Bind(); // Draw the batch _device.DrawIndexed(PrimitiveType.TriangleList, 4 * totalCount, 6 * totalCount); }
public void Render(IGameViewport viewport, LocAndOffsets loc, LocAndOffsets tgtLoc, float degreesTarget, IMdfRenderMaterial materialInside, IMdfRenderMaterial materialOutside) { Span <IntgameVertex> vertices = stackalloc IntgameVertex[38]; var elevation = MathF.Sin(-0.77539754f) * -1.5f; var outerConeAngle = Angles.ToRadians(degreesTarget); var originPos = loc.ToInches3D(); var targetPos = tgtLoc.ToInches3D(); var d = targetPos - originPos; var coneRadius = d.Length(); // The normal pointing in the direction of the target straight down the middle of the cone var coneNormal = d / coneRadius; // A portion of the full cone will be rendered as a "rim" on the outside, which // will have this radius: var ringRadius = MathF.Min(24.0f, coneRadius / 7.0f); var innerConeRadius = coneRadius - ringRadius; // Set the origin point vertices[0].pos = new Vector4(originPos.X, elevation, originPos.Z, 1); vertices[0].normal = Vector4.UnitY; vertices[0].uv = new Vector2(0, 0); vertices[0].diffuse = PackedLinearColorA.White; var innerConeAngle = (1.0f - (ringRadius + ringRadius) / (outerConeAngle * coneRadius)) * outerConeAngle; var innerConeAngleHalf = innerConeAngle * 0.5f; float angleStepInner = innerConeAngle / 18; // This is the point at the center of the cone, but on the inner rim var coneNearX = innerConeRadius * coneNormal.X; var coneNearY = innerConeRadius * coneNormal.Z; for (var i = 1; i < 20; i++) { // angle=0 is straight down the center of the cone, so it is shifted to the left by coneAngle/2 var angle = (i - 1) * angleStepInner - innerConeAngleHalf; vertices[i].pos = new Vector4( originPos.X + MathF.Cos(angle) * coneNearX - MathF.Sin(angle) * coneNearY, elevation, originPos.Z + MathF.Sin(angle) * coneNearX + MathF.Cos(angle) * coneNearY, 1 ); vertices[i].normal = Vector4.UnitY; vertices[i].diffuse = PackedLinearColorA.White; vertices[i].uv = new Vector2( (i + 1) % 2, 1.0f ); } _fanVertexBuffer.Resource.Update <IntgameVertex>(vertices.Slice(0, 20)); _fanBufferBinding.Resource.Bind(); _device.SetIndexBuffer(_fanIndexBuffer); materialInside.Bind(viewport, _device, new List <Light3d>()); _device.DrawIndexed(PrimitiveType.TriangleList, 20, FanIndices.Length); var slice = 0.0f; // Far center point of the cone, on the outside rim var coneFarX = coneRadius * coneNormal.X; var coneFarY = coneRadius * coneNormal.Z; for (var i = 0; i < 38; i += 2) { var angle = slice * angleStepInner - innerConeAngleHalf; vertices[i].pos = new Vector4( originPos.X + MathF.Cos(angle) * coneNearX - MathF.Sin(angle) * coneNearY, elevation, originPos.Z + MathF.Sin(angle) * coneNearX + MathF.Cos(angle) * coneNearY, 1 ); vertices[i].normal = Vector4.UnitY; vertices[i].uv = new Vector2(slice, 0); vertices[i].diffuse = PackedLinearColorA.White; vertices[i + 1].pos = new Vector4( originPos.X + MathF.Cos(angle) * coneFarX - MathF.Sin(angle) * coneFarY, elevation, originPos.Z + MathF.Cos(angle) * coneFarY + MathF.Sin(angle) * coneFarX, 1 ); vertices[i + 1].normal = Vector4.UnitY; vertices[i + 1].uv = new Vector2(slice, 1); vertices[i + 1].diffuse = PackedLinearColorA.White; slice += 1; } _ringVertexBuffer.Resource.Update <IntgameVertex>(vertices.Slice(0, 38)); _ringBufferBinding.Resource.Bind(); _device.SetIndexBuffer(_ringIndexBuffer); materialOutside.Bind(viewport, _device, new List <Light3d>()); _device.DrawIndexed(PrimitiveType.TriangleList, 38, RingIndices.Length); // Render the left and right side of the cone using the same texture as the outside ring var innerConeAngleHalfInv = -innerConeAngleHalf; var outerConeAngleHalf = outerConeAngle * 0.5f; var outerConeAngleHalfInv = -outerConeAngleHalf; var v71 = innerConeRadius / ringRadius; // Right flank of the cone vertices[0] = new IntgameVertex { pos = new Vector4( originPos.X + MathF.Cos(innerConeAngleHalfInv) * coneFarX - MathF.Sin(innerConeAngleHalfInv) * coneFarY, elevation, originPos.Z + MathF.Sin(innerConeAngleHalfInv) * coneFarX + MathF.Cos(innerConeAngleHalfInv) * coneFarY, 1 ), normal = Vector4.UnitY, uv = new Vector2(0, 1), diffuse = PackedLinearColorA.White }; vertices[1] = new IntgameVertex { pos = new Vector4( originPos.X + MathF.Cos(outerConeAngleHalfInv) * coneFarX - MathF.Sin(outerConeAngleHalfInv) * coneFarY, elevation, originPos.Z + MathF.Sin(outerConeAngleHalfInv) * coneFarX + MathF.Cos(outerConeAngleHalfInv) * coneFarY, 1 ), normal = Vector4.UnitY, uv = new Vector2(0, 1), diffuse = PackedLinearColorA.White }; vertices[2] = new IntgameVertex { pos = new Vector4( originPos.X + MathF.Cos(innerConeAngleHalfInv) * coneNearX - MathF.Sin(innerConeAngleHalfInv) * coneNearY, elevation, originPos.Z + MathF.Sin(innerConeAngleHalfInv) * coneNearX + MathF.Cos(innerConeAngleHalfInv) * coneNearY, 1 ), normal = Vector4.UnitY, uv = new Vector2(0, 0), diffuse = PackedLinearColorA.White }; vertices[3] = new IntgameVertex { pos = new Vector4( originPos.X + MathF.Cos(outerConeAngleHalfInv) * coneNearX - MathF.Sin(outerConeAngleHalfInv) * coneNearY, elevation, originPos.Z + MathF.Sin(outerConeAngleHalfInv) * coneNearX + MathF.Cos(outerConeAngleHalfInv) * coneNearY, 1 ), normal = Vector4.UnitY, uv = new Vector2(0, 1), diffuse = PackedLinearColorA.White }; vertices[4] = new IntgameVertex { pos = new Vector4( originPos.X, elevation, originPos.Z, 1 ), normal = Vector4.UnitY, uv = new Vector2(-v71, 0.5f), diffuse = PackedLinearColorA.White }; // Left flank of the cone vertices[5] = new IntgameVertex { pos = new Vector4( originPos.X + MathF.Cos(innerConeAngleHalf) * coneFarX - MathF.Sin(innerConeAngleHalf) * coneFarY, elevation, originPos.Z + MathF.Sin(innerConeAngleHalf) * coneFarX + MathF.Cos(innerConeAngleHalf) * coneFarY, 1 ), normal = Vector4.UnitY, uv = new Vector2(0, 1), diffuse = PackedLinearColorA.White }; vertices[6] = new IntgameVertex { pos = new Vector4( originPos.X + MathF.Cos(outerConeAngleHalf) * coneFarX - MathF.Sin(outerConeAngleHalf) * coneFarY, elevation, originPos.Z + MathF.Sin(outerConeAngleHalf) * coneFarX + MathF.Cos(outerConeAngleHalf) * coneFarY, 1 ), normal = Vector4.UnitY, uv = new Vector2(0, 1), diffuse = PackedLinearColorA.White }; vertices[7] = new IntgameVertex { pos = new Vector4( originPos.X + MathF.Cos(innerConeAngleHalf) * coneNearX - MathF.Sin(innerConeAngleHalf) * coneNearY, elevation, originPos.Z + MathF.Sin(innerConeAngleHalf) * coneNearX + MathF.Cos(innerConeAngleHalf) * coneNearY, 1 ), normal = Vector4.UnitY, uv = new Vector2(0, 0), diffuse = PackedLinearColorA.White }; vertices[8] = new IntgameVertex { pos = new Vector4( originPos.X + MathF.Cos(outerConeAngleHalf) * coneNearX - MathF.Sin(outerConeAngleHalf) * coneNearY, elevation, originPos.Z + MathF.Sin(outerConeAngleHalf) * coneNearX + MathF.Cos(outerConeAngleHalf) * coneNearY, 1 ), normal = Vector4.UnitY, uv = new Vector2(0, 1), diffuse = PackedLinearColorA.White }; // This could reuse vertices[4], but was here in vanilla also vertices[9] = new IntgameVertex { pos = new Vector4( originPos.X, elevation, originPos.Z, 1 ), normal = Vector4.UnitY, uv = new Vector2(v71, 0.5f), diffuse = PackedLinearColorA.White }; _flankVertexBuffer.Resource.Update <IntgameVertex>(vertices.Slice(0, 10)); _flankBufferBinding.Resource.Bind(); _device.SetIndexBuffer(_flankIndexBuffer); materialOutside.Bind(viewport, _device, new List <Light3d>()); _device.DrawIndexed(PrimitiveType.TriangleList, 10, FlankIndices.Length); }
public void Render(IGameViewport viewport, Vector3 srcPos, Vector3 tgtPos, float rayThickness, float minRange, float maxRange, IMdfRenderMaterial materialInside, IMdfRenderMaterial materialOutside) { float v11; float v69; float v70; float v71; Span <IntgameVertex> vertices = stackalloc IntgameVertex[52]; var elevation = MathF.Sin(-0.77539754f) * -1.5f; var srcAbsX = srcPos.X; var srcAbsY = srcPos.Z; var tgtAbsX = tgtPos.X; var tgtAbsY = tgtPos.Z; var deltaX = tgtAbsX - srcAbsX; var dettaY = tgtAbsY - srcAbsY; float dist = MathF.Sqrt(dettaY * dettaY + deltaX * deltaX); float normalizer = 1.0f / dist; var xHat = normalizer * deltaX; var yHat = normalizer * dettaY; var v62 = -xHat; if (dist < minRange) { dist = minRange; tgtAbsX = xHat * minRange + srcAbsX; v11 = yHat * minRange; tgtAbsY = v11 + srcAbsY; } else if (dist > maxRange) { dist = maxRange; tgtAbsX = xHat * maxRange + srcAbsX; v11 = yHat * maxRange; tgtAbsY = v11 + srcAbsY; } var v12 = dist / 7.0f; var v59 = v12; if (v12 > 24.0f) { v12 = 24.0f; } float v56 = rayThickness * 0.25f; if (v12 > v56) { v12 = v56; } var v16 = rayThickness - v12; var v57 = v16; if (dist - v12 * 3.0 < v57) { v57 = v59; } var v61 = v16; var v72 = rayThickness / v61; for (var i = 0; i < 22; i += 2) { float v21 = MathF.Cos((float)(i / 2) * 0.31415927f); var v22 = v21 * v61; v70 = yHat * v22; var v23 = v22; var v24 = MathF.Sqrt(v72 * v72 - v21 * v21) * v57; v71 = v24; v69 = v23 * v62; float v25 = v21 * rayThickness / locXY.INCH_PER_FEET; vertices[i] = new IntgameVertex { pos = new Vector4( srcAbsX + v70 + v24 * xHat, elevation, srcAbsY + v69 + v71 * yHat, 1 ), normal = Vector4.UnitY, uv = new Vector2(v25, 0), diffuse = PackedLinearColorA.White }; vertices[i + 1] = new IntgameVertex { pos = new Vector4( tgtAbsX + v70 - xHat * v12, elevation, tgtAbsY + v69 - v12 * yHat, 1 ), normal = Vector4.UnitY, uv = new Vector2(v25, 1.0f), diffuse = PackedLinearColorA.White }; } _innerVertexBuffer.Resource.Update <IntgameVertex>(vertices.Slice(0, 22)); _innerBufferBinding.Resource.Bind(); _device.SetIndexBuffer(_innerIndexBuffer); materialInside.Bind(viewport, _device, new List <Light3d>()); _device.DrawIndexed(PrimitiveType.TriangleList, 22, InnerIndices.Length); // Note: Unlike Vanilla, we'll pack the entire rest into a single VB and draw that for (var i = 0; i < 22; i += 2) { float v28 = MathF.Cos((float)(i / 2) * 0.31415927f); var v29 = v28 * v61; var v30 = v29; var v31 = MathF.Sqrt(1.0f - v28 * v28) * v57; var v32 = v30 * v62; var v33 = v28 * rayThickness * 0.083333336f; var v34 = MathF.Sqrt(v72 * v72 - v28 * v28) * v57; vertices[i] = new IntgameVertex { pos = new Vector4( v31 * xHat + yHat * v29 + srcAbsX, elevation, v31 * yHat + v32 + srcAbsY, 1 ), normal = Vector4.UnitY, uv = new Vector2(v33, 0), diffuse = PackedLinearColorA.White }; vertices[i + 1] = new IntgameVertex { pos = new Vector4( xHat * v34 + yHat * v29 + srcAbsX, elevation, v34 * yHat + v32 + srcAbsY, 1 ), normal = Vector4.UnitY, uv = new Vector2(v33, 1.0f), diffuse = PackedLinearColorA.White }; } for (var i = 0; i < 22; i += 2) { float v39 = MathF.Cos(i / 2 * 0.31415927f); var v40 = v61 * v39; var v41 = yHat * v40; var v42 = v41; var v43 = v40 * v62; v72 = v43; float v44 = v39 * rayThickness * 0.083333336f; vertices[22 + i] = new IntgameVertex { pos = new Vector4( v41 - xHat * v12 + tgtAbsX, elevation, v43 - v12 * yHat + tgtAbsY, 1 ), normal = Vector4.UnitY, uv = new Vector2(v44, 0), diffuse = PackedLinearColorA.White }; vertices[22 + i + 1] = new IntgameVertex { pos = new Vector4( v42 + tgtAbsX, elevation, v72 + tgtAbsY, 1 ), normal = Vector4.UnitY, uv = new Vector2(v44, 1.0f), diffuse = PackedLinearColorA.White }; } var vertexIdx = 44; var v45 = v61 * yHat; var v46 = v45; var v47 = v61 * v62; var v48 = v47; float v49 = dist * 0.041666668f; var v50 = v49; var v51 = yHat * rayThickness; var v52 = v51; var v53 = v62 * rayThickness; var v54 = v53; vertices[vertexIdx++] = new IntgameVertex { pos = new Vector4( v45 + srcAbsX, elevation, v47 + srcAbsY, 1 ), normal = Vector4.UnitY, uv = new Vector2(0, 0), diffuse = PackedLinearColorA.White }; vertices[vertexIdx++] = new IntgameVertex { pos = new Vector4( v46 + tgtAbsX, elevation, v48 + tgtAbsY, 1 ), normal = Vector4.UnitY, uv = new Vector2(v49, 0), diffuse = PackedLinearColorA.White }; vertices[vertexIdx++] = new IntgameVertex { pos = new Vector4( v51 + srcAbsX, elevation, v53 + srcAbsY, 1 ), normal = Vector4.UnitY, uv = new Vector2(0, 1), diffuse = PackedLinearColorA.White }; vertices[vertexIdx++] = new IntgameVertex { pos = new Vector4( v52 + tgtAbsX, elevation, v54 + tgtAbsY, 1 ), normal = Vector4.UnitY, uv = new Vector2(v49, 1), diffuse = PackedLinearColorA.White }; vertices[vertexIdx++] = new IntgameVertex { pos = new Vector4( srcAbsX - v46, elevation, srcAbsY - v48, 1 ), normal = Vector4.UnitY, uv = new Vector2(0, 0), diffuse = PackedLinearColorA.White }; vertices[vertexIdx++] = new IntgameVertex { pos = new Vector4( tgtAbsX - v46, elevation, tgtAbsY - v48, 1 ), normal = Vector4.UnitY, uv = new Vector2(v50, 0), diffuse = PackedLinearColorA.White }; vertices[vertexIdx++] = new IntgameVertex { pos = new Vector4( srcAbsX - v52, elevation, srcAbsY - v54, 1 ), normal = Vector4.UnitY, uv = new Vector2(0, 1), diffuse = PackedLinearColorA.White }; vertices[vertexIdx++] = new IntgameVertex { pos = new Vector4( tgtAbsX - v52, elevation, tgtAbsY - v54, 1 ), normal = Vector4.UnitY, uv = new Vector2(v50, 1), diffuse = PackedLinearColorA.White }; _outerVertexBuffer.Resource.Update <IntgameVertex>(vertices.Slice(0, vertexIdx)); _outerBufferBinding.Resource.Bind(); _device.SetIndexBuffer(_outerIndexBuffer); materialOutside.Bind(viewport, _device, new List <Light3d>()); _device.DrawIndexed(PrimitiveType.TriangleList, vertexIdx, OuterIndices.Length); }
public void Render(IGameViewport viewport, Vector3 aoeCenter, Vector3 casterPos, float aoeRadius) { Span <IntgameVertex> vertices = stackalloc IntgameVertex[4]; var elevation = MathF.Sin(-0.77539754f) * -1.5f; var v3 = aoeRadius * 0.56560004f; float v14 = v3; if (v3 <= 135.744) { if (v14 < 11.312) { v14 = 11.312f; } } else { v14 = 135.744f; } var dirVector = Vector3.Normalize(casterPos - aoeCenter); float v10 = aoeRadius - v14; vertices[0] = new IntgameVertex { pos = new Vector4( aoeCenter.X + v10 * dirVector.X, elevation, aoeCenter.Z + v10 * dirVector.Z, 1 ), normal = Vector4.UnitY, uv = new Vector2(0, 1), diffuse = PackedLinearColorA.White }; vertices[1] = new IntgameVertex { pos = new Vector4( aoeCenter.X + aoeRadius * dirVector.X + v14 * dirVector.Z, elevation, aoeCenter.Z + aoeRadius * dirVector.Z - v14 * dirVector.X, 1 ), normal = Vector4.UnitY, uv = new Vector2(0, 0), diffuse = PackedLinearColorA.White }; vertices[2] = new IntgameVertex { pos = new Vector4( aoeCenter.X + aoeRadius * dirVector.X - v14 * dirVector.Z, elevation, aoeCenter.Z + v14 * dirVector.X + aoeRadius * dirVector.Z, 1 ), normal = Vector4.UnitY, uv = new Vector2(1, 1), diffuse = PackedLinearColorA.White }; vertices[3] = new IntgameVertex { pos = new Vector4( aoeCenter.X + (v14 + aoeRadius) * dirVector.X, elevation, aoeCenter.Z + (v14 + aoeRadius) * dirVector.Z, 1 ), normal = Vector4.UnitY, uv = new Vector2(1, 0), diffuse = PackedLinearColorA.White }; _vertexBuffer.Resource.Update <IntgameVertex>(vertices); _bufferBinding.Resource.Bind(); _device.SetIndexBuffer(_indexBuffer); _material.Resource.Bind(viewport, _device, new List <Light3d>()); _device.DrawIndexed( PrimitiveType.TriangleList, vertices.Length, Indices.Length); }