/// <summary> /// Constructor lets the caller specify whether to include the standard /// "A=ok, B=cancel" usage text prompt. /// </summary> public MessageBoxScreen(string message, bool includeUsageText = false, bool includeCancelOption = false) { _IncludeCancelOption = includeCancelOption; _Gradient_Id = TextureManager.AddTexture(new CutlassTexture("Content/Textures/gradient")); string usageText = String.Empty; switch (CutlassEngine.CurrentPlatform) { case PlatformID.MacOSX: goto case PlatformID.Win32Windows; case PlatformID.Unix: goto case PlatformID.Win32Windows; case PlatformID.Win32NT: goto case PlatformID.Win32Windows; case PlatformID.Win32S: goto case PlatformID.Win32Windows; case PlatformID.Win32Windows: usageText = "\nSpace, Enter = OK"; if (_IncludeCancelOption) { usageText += "\nEsc = Cancel"; } break; case PlatformID.WinCE: goto case PlatformID.Win32Windows; case PlatformID.Xbox: usageText = "\nSA = OK"; if (_IncludeCancelOption) { usageText += "\nB = Cancel"; } break; default: break; } if (includeUsageText) { this._Message = message + usageText; } else { this._Message = message; } IsPopup = true; TransitionOnTime = TimeSpan.FromSeconds(0.2); TransitionOffTime = TimeSpan.FromSeconds(0.2); }
/// <summary> /// Get a Texture2D /// </summary> /// <param name="textureName"></param> /// <returns></returns> public static Texture2D GetTexture2D(TexId textureId) { ICutlassTexture texture = GetTexture(textureId); if (texture != null) { return(texture.BaseTexture); } else { return(null); } }
static void AddBatch(int counter, int offset, TexId prevTexture, MyTransparentMaterial prevMaterial) { MyBillboardRendererBatch batch = new MyBillboardRendererBatch(); batch.Offset = offset; batch.Num = counter - offset; batch.Texture = prevTexture; batch.Lit = prevMaterial.CanBeAffectedByOtherLights; batch.AlphaCutout = prevMaterial.AlphaCutout; m_batches.Add(batch); }
/// <summary> /// Load graphics content. /// </summary> protected override void LoadContent() { //_SpriteBatch = new SpriteBatch(GraphicsDevice); _Blank_Id = TextureManager.AddTexture(new CutlassTexture("Content/Textures/blank")); _Cursor_Id = TextureManager.AddTexture(new CutlassTexture("Content/Textures/cursor")); // Tell each of the screens to load their content. foreach (GameScreen screen in _Screens) { screen.LoadContent(); } }
internal static MyTextureArray FromStringArray(string[] mergeList, MyTextureEnum type, string debugName) { if (mergeList == null) { return(null); } TexId[] ids = new TexId[mergeList.Length]; for (int i = 0; i < ids.Length; i++) { ids[i] = MyTextures.GetTexture(mergeList[i], type, true); } return(new MyTextureArray(ids, debugName)); }
/// <summary> /// Remove a texture from the dictionary. /// </summary> /// <param name="textureName"></param> public static void RemoveTexture(TexId textureId) { ICutlassTexture textureToRemove; _Textures.TryGetValue(textureId, out textureToRemove); if (textureToRemove != null) { if (_Initialized) { textureToRemove.UnloadContent(); } _Textures.Remove(textureId); } }
/// <summary> /// Load Content /// </summary> public override void LoadContent() { base.LoadContent(); _TitleScrollMiddle_Id = TextureManager.AddTexture(new CutlassTexture("Content/Textures/titleScrollMiddle")); _TitleScrollEdge_Id = TextureManager.AddTexture(new CutlassTexture("Content/Textures/titleScrollEdge")); _MenuBackgroundCorner_Id = TextureManager.AddTexture(new CutlassTexture("Content/Textures/backgroundMenuCorner")); _MenuBackgroundVerticalEdge_Id = TextureManager.AddTexture(new CutlassTexture("Content/Textures/backgroundMenuVerticalEdge")); _MenuBackgroundHorizontalEdge_Id = TextureManager.AddTexture(new CutlassTexture("Content/Textures/backgroundMenuHorizontalEdge")); _TitleFont_Id = FontManager.AddFont(new CutlassFont("Content/Fonts/bilboSwashCaps")); SetMenuEntryFont(FontManager.AddFont(new CutlassFont("Content/Fonts/frederickaTheGreat"))); SetMenuEntryTextColor(Palette.CharcoalGrey); SetMenuEntrySelectedTextColor(Palette.LightBlue); }
public Scenery(Vector2 position, bool isVisible = true, ICutlassTexture texture = null, bool animated = false, CollisionSide side = CollisionSide.All) { _Position = position; _IsVisible = isVisible; _Active = true; if (isVisible && texture != null) { _SceneryObject_Id = TextureManager.AddTexture(texture); _Animated = animated; _Side = side; } else { _Side = CollisionSide.All; } }
public Player(GameplayScreen parentScreen, Vector2 position) { _Player_TexId_Standing_R = TextureManager.AddTexture(new CutlassTexture("Content/Sprites/pirate-standing-48-120-R")); _Player_TexId_Standing_L = TextureManager.AddTexture(new CutlassTexture("Content/Sprites/pirate-standing-48-120-L")); _Player_TexId_Jumping_R = TextureManager.AddTexture(new CutlassTexture("Content/Sprites/pirate-jumping-64-120-R")); _Player_TexId_Jumping_L = TextureManager.AddTexture(new CutlassTexture("Content/Sprites/pirate-jumping-64-120-L")); _Player_TexId_Walking_R = TextureManager.AddTexture(new CutlassAnimatedTexture("Content/Sprites/pirate-walking-560-120-R", 10, 5)); _Player_TexId_Walking_L = TextureManager.AddTexture(new CutlassAnimatedTexture("Content/Sprites/pirate-walking-560-120-L", 10, 5)); _Player_TexId_Walking_Reverse_R = TextureManager.AddTexture(new CutlassAnimatedTexture("Content/Sprites/pirate-walking-reverse-560-120-R", 10, 5)); _Player_TexId_Walking_Reverse_L = TextureManager.AddTexture(new CutlassAnimatedTexture("Content/Sprites/pirate-walking-reverse-560-120-L", 10, 5)); _CurrentTexture = _Player_TexId_Walking_R; _ParentScreen = parentScreen; _Active = true; _Position = position; _IsVisible = true; }
internal static void UpdateSpotlight(LightId light, bool enabled, Vector3 direction, float range, float apertureCos, Vector3 up, Vector3 color, float falloff, TexId reflectorTexture) { var info = Spotlights[light.Index]; var gid = light.ParentGID; if (gid != -1 && MyIDTracker <MyActor> .FindByID((uint)gid) != null) { var matrix = MyIDTracker <MyActor> .FindByID((uint)gid).WorldMatrix; Vector3.TransformNormal(ref direction, ref matrix, out direction); Vector3.TransformNormal(ref up, ref matrix, out up); } bool aabbChanged = info.Direction != direction || info.Range != range || info.ApertureCos != apertureCos || info.Up != up; Spotlights[light.Index].Enabled = enabled; Spotlights[light.Index].Direction = direction; Spotlights[light.Index].Range = range; Spotlights[light.Index].ApertureCos = apertureCos; Spotlights[light.Index].Up = up; Spotlights[light.Index].Falloff = falloff; Spotlights[light.Index].Color = color; Spotlights[light.Index].ReflectorTexture = reflectorTexture; var proxy = Spotlights[light.Index].BvhProxyId; var positionDifference = Vector3D.RectangularDistance(ref Spotlights[light.Index].LastBvhUpdatePosition, ref Lights.Data[light.Index].PositionWithOffset); bool dirty = (enabled && ((proxy == -1) || (positionDifference > MOVE_TOLERANCE || aabbChanged))) || (!enabled && proxy != -1); if (dirty) { DirtySpotlights.Add(light); } else { DirtySpotlights.Remove(light); } }
static void Gather() { // counting sorted billboards m_batches.Clear(); m_sortedNum = 0; PreGatherList(MyRenderProxy.BillboardsRead); PreGatherList(m_billboardsOnce); m_sortedBillboardsNum = m_sortedNum; m_unsorted = 0; m_sorted = 0; GatherList(MyRenderProxy.BillboardsRead); GatherList(m_billboardsOnce); Array.Sort(m_sortBuffer, 0, m_sortedNum); //Array.Reverse(m_sortBuffer, 0, m_sortedNum); //Array.Sort(m_sortBuffer, m_sortedNum, m_unsorted); var N = m_sorted + m_unsorted; var batch = new MyBillboardBatch(); //MyAssetTexture prevTexture = null; var prevTexId = TexId.NULL; int currentOffset = 0; if (N > 0) { var material = MyTransparentMaterials.GetMaterial(m_sortBuffer[0].Material); if (material.UseAtlas) { var item = m_atlasedTextures[material.Texture]; prevTexId = item.TextureId; } else { PreloadTexture(material.Texture); //prevTexture = MyTextureManager.GetTextureFast(material.Texture); prevTexId = MyTextures.GetTexture(material.Texture, MyTextureEnum.GUI, true); } } TexId batchTexId = TexId.NULL; MyTransparentMaterial prevMaterial = null; for (int i = 0; i < N; i++) { var billboard = m_sortBuffer[i]; var material = MyTransparentMaterials.GetMaterial(billboard.Material); var billboardData = new MyBillboardData(); billboardData.CustomProjectionID = billboard.CustomViewProjection; billboardData.Color = billboard.Color; if (material.UseAtlas) { var atlasItem = m_atlasedTextures[material.Texture]; //billboardData.UvModifiers = new HalfVector4(atlasItem.UvOffsetScale); batchTexId = atlasItem.TextureId; } else { batchTexId = MyTextures.GetTexture(material.Texture, MyTextureEnum.GUI, true); } billboardData.Reflective = billboard.Reflectivity; Vector3D pos0 = billboard.Position0; Vector3D pos1 = billboard.Position1; Vector3D pos2 = billboard.Position2; Vector3D pos3 = billboard.Position3; if (billboard.ParentID != -1) { if (MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID) != null) { var matrix = MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID).WorldMatrix; Vector3D.Transform(ref pos0, ref matrix, out pos0); Vector3D.Transform(ref pos1, ref matrix, out pos1); Vector3D.Transform(ref pos2, ref matrix, out pos2); Vector3D.Transform(ref pos3, ref matrix, out pos3); } } if (billboard.CustomViewProjection != -1) { var billboardViewProjection = MyRenderProxy.BillboardsViewProjectionRead[billboard.CustomViewProjection]; //pos0 -= MyEnvironment.CameraPosition; //pos1 -= MyEnvironment.CameraPosition; //pos2 -= MyEnvironment.CameraPosition; //pos3 -= MyEnvironment.CameraPosition; } else { pos0 -= MyEnvironment.CameraPosition; pos1 -= MyEnvironment.CameraPosition; pos2 -= MyEnvironment.CameraPosition; pos3 -= MyEnvironment.CameraPosition; } var normal = Vector3.Cross(pos1 - pos0, pos2 - pos0); normal.Normalize(); billboardData.Normal = normal; m_vertexData[i * 4 + 0].Position = pos0; m_vertexData[i * 4 + 1].Position = pos1; m_vertexData[i * 4 + 2].Position = pos2; m_vertexData[i * 4 + 3].Position = pos3; var uv0 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y); var uv1 = new Vector2(material.UVOffset.X + material.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y); var uv2 = new Vector2(material.UVOffset.X + material.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + material.UVSize.Y + billboard.UVOffset.Y); var uv3 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + material.UVSize.Y + billboard.UVOffset.Y); if (material.UseAtlas) { var atlasItem = m_atlasedTextures[material.Texture]; uv0 = uv0 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv1 = uv1 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv2 = uv2 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv3 = uv3 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); } m_vertexData[i * 4 + 0].Texcoord = new HalfVector2(uv0); m_vertexData[i * 4 + 1].Texcoord = new HalfVector2(uv1); m_vertexData[i * 4 + 2].Texcoord = new HalfVector2(uv2); m_vertexData[i * 4 + 3].Texcoord = new HalfVector2(uv3); pos0.AssertIsValid(); pos1.AssertIsValid(); pos2.AssertIsValid(); pos3.AssertIsValid(); MyTriangleBillboard triBillboard = billboard as MyTriangleBillboard; if (triBillboard != null) { m_vertexData[i * 4 + 3].Position = pos2; // second triangle will die in rasterizer m_vertexData[i * 4 + 0].Texcoord = new HalfVector2(triBillboard.UV0); m_vertexData[i * 4 + 1].Texcoord = new HalfVector2(triBillboard.UV1); m_vertexData[i * 4 + 2].Texcoord = new HalfVector2(triBillboard.UV2); billboardData.Normal = triBillboard.Normal0; // pew pew pew :O } m_billboardData[i] = billboardData; bool closeBatch = (batchTexId != prevTexId) || ((i == m_sortedNum) && (i > 0)); if (closeBatch) { batch = new MyBillboardBatch(); batch.Offset = currentOffset; batch.Num = i - currentOffset; batch.Texture = prevTexId != TexId.NULL ? MyTextures.Views[prevTexId.Index] : null; batch.Lit = prevMaterial.CanBeAffectedByOtherLights; m_batches.Add(batch); currentOffset = i; } prevTexId = batchTexId; prevMaterial = material; } if (N > 0) { batch = new MyBillboardBatch(); batch.Offset = currentOffset; batch.Num = N - currentOffset; batch.Texture = prevTexId != TexId.NULL ? MyTextures.GetView(prevTexId) : null; batch.Lit = prevMaterial.CanBeAffectedByOtherLights; m_batches.Add(batch); } }
/// <summary> /// Load Content. /// </summary> protected override void LoadContent() { base.LoadContent(); _Blank_Id = TextureManager.AddTexture(new CutlassTexture("Content/Textures/blank")); }
internal static void RenderColoredTextures(List <renderColoredTextureProperties> texturesToRender) { if (texturesToRender.Count == 0) { return; } if (!m_initialized) { Init(); } const int RENDER_TEXTURE_RESOLUTION = 512; RC.DeviceContext.OutputMerger.BlendState = null; RC.SetIL(null); RC.SetPS(m_ps); RC.SetCB(0, MyCommon.FrameConstants); RC.SetCB(1, m_cb); Dictionary <Vector2I, MyRenderTarget> createdRenderTextureTargets = new Dictionary <Vector2I, MyRenderTarget>(); foreach (var texture in texturesToRender) { TexId texId = MyTextures.GetTexture(texture.TextureName, MyTextureEnum.COLOR_METAL, true); if (texId == TexId.NULL) { continue; } Vector2 texSize = MyTextures.GetSize(texId); Vector2I renderTargetResolution = new Vector2I(RENDER_TEXTURE_RESOLUTION, RENDER_TEXTURE_RESOLUTION); if (texSize.Y > 0) { if (texSize.Y < RENDER_TEXTURE_RESOLUTION) { renderTargetResolution.X = (int)texSize.X; renderTargetResolution.Y = (int)texSize.Y; } else { renderTargetResolution.X *= (int)(texSize.X / texSize.Y); } } MyViewport viewport = new MyViewport(renderTargetResolution.X, renderTargetResolution.Y); MyRenderTarget renderTexture = null; if (!createdRenderTextureTargets.TryGetValue(renderTargetResolution, out renderTexture)) { renderTexture = new MyRenderTarget(renderTargetResolution.X, renderTargetResolution.Y, SharpDX.DXGI.Format.R8G8B8A8_UNorm_SRgb, 1, 0); createdRenderTextureTargets[renderTargetResolution] = renderTexture; } RC.BindDepthRT(null, DepthStencilAccess.ReadWrite, renderTexture); // Set color var mapping = MyMapping.MapDiscard(m_cb); Vector4 color = new Vector4(texture.ColorMaskHSV, 1); mapping.WriteAndPosition(ref color); mapping.Unmap(); // Set texture RC.DeviceContext.PixelShader.SetShaderResource(0, MyTextures.GetView(texId)); // Draw MyScreenPass.DrawFullscreenQuad(viewport); // Save to file MyTextureData.ToFile(renderTexture.GetHWResource(), texture.PathToSave, ImageFileFormat.Png); } texturesToRender.Clear(); foreach (var texture in createdRenderTextureTargets) { texture.Value.Release(); } createdRenderTextureTargets.Clear(); RC.BindDepthRT(null, DepthStencilAccess.ReadWrite, null); RC.BindGBufferForRead(0, MyGBuffer.Main); }
/// <summary> /// Loads graphics content for this screen. The background texture is quite /// big, so we use our own local ContentManager to load it. This allows us /// to unload before going from the menus into the game itself, wheras if we /// used the shared ContentManager provided by the Game class, the content /// would remain loaded forever. /// </summary> public override void LoadContent() { base.LoadContent(); _OceanClouds_Id = TextureManager.AddTexture(new CutlassTexture("Content/Textures/oceanClouds")); }
public void HandleInput(GameTime gameTime, Cutlass.GameComponents.Input input, Vector2 playerScreenPosition) { KeyboardState keyboardState = input.CurrentKeyboardState; MouseState mouseState = input.CurrentMouseState; GamePadState gamePadState = input.CurrentGamePadState; //Keyboard Input _IsJumpingDown = false; _WalkDirection = 0; if (keyboardState.IsKeyDown(GameSettingsManager.Default.LeftKey)) { _WalkDirection = _WalkDirection - 1; _Velocity.X = Math.Max(_Velocity.X - (0.1f * (float)gameTime.ElapsedGameTime.TotalMilliseconds), -MAX_PLAYER_HORIZONTAL_SPEED); } if (keyboardState.IsKeyDown(GameSettingsManager.Default.RightKey)) { _WalkDirection = _WalkDirection + 1; _Velocity.X = Math.Min(_Velocity.X + (0.1f * (float)gameTime.ElapsedGameTime.TotalMilliseconds), MAX_PLAYER_HORIZONTAL_SPEED); } if (keyboardState.IsKeyDown(GameSettingsManager.Default.JumpKey) && _IsOnGround) { _IsOnGround = false; if (keyboardState.IsKeyDown(GameSettingsManager.Default.DownKey)) { _IsJumpingDown = true; _Velocity.Y += 1.0f; } else { _Velocity.Y = _Velocity.Y - (6.0f); } } //Mouse Input Vector2 mousePosition = new Vector2(mouseState.X, mouseState.Y); _LookDirection = mousePosition - (playerScreenPosition);// + new Vector2(Width / 2, Height / 2)); _LookDirection.Normalize(); //Looking Right if (_LookDirection.X >= 0) { //On the ground if (_WasOnGround) { //Walking forward if (_WalkDirection > 0) { _CurrentTexture = _Player_TexId_Walking_R; } //Walking backward else if (_WalkDirection < 0) { _CurrentTexture = _Player_TexId_Walking_Reverse_R; } //Standing else { _CurrentTexture = _Player_TexId_Standing_R; } } //Jumping else { _CurrentTexture = _Player_TexId_Jumping_R; } } //Looking Left else { //On the ground if (_WasOnGround) { //Walking forward if (_WalkDirection < 0) { _CurrentTexture = _Player_TexId_Walking_L; } //Walking backward else if (_WalkDirection > 0) { _CurrentTexture = _Player_TexId_Walking_Reverse_L; } //Standing else { _CurrentTexture = _Player_TexId_Standing_L; } } //Jumping else { _CurrentTexture = _Player_TexId_Jumping_L; } } }
/// <summary> /// Get a texture /// </summary> /// <param name="textureId"></param> /// <returns></returns> public static ICutlassTexture GetTexture(TexId textureId) { return(_Textures.ElementAtOrDefault(textureId).Value); }
internal static void AddSingleSprite(TexId texId, Color color, Vector2 origin, Vector2 tangent, Rectangle?sourceRect, RectangleF destinationRect) { AddSingleSprite(MyTextures.Views[texId.Index], MyTextures.GetSize(texId), color, origin, tangent, sourceRect, destinationRect); }
static void Gather() { m_batches.Clear(); // counting sorted billboards m_sortedCount = 0; m_unsortedCount = 0; m_windowCount = 0; PreGatherList(MyRenderProxy.BillboardsRead); PreGatherList(m_billboardsOnce); if (BillboardCount == 0) { return; } ResizeStorage(); int sortedIndex = 0; int unsortedIndex = 0; GatherList(MyRenderProxy.BillboardsRead, ref sortedIndex, ref unsortedIndex); GatherList(m_billboardsOnce, ref sortedIndex, ref unsortedIndex); Array.Sort(m_sortedBuffer, 0, m_sortedCount); int i = 0; int windowidx = 0; var N = BillboardCountSafe; int currentOffset = 0; TexId prevTexId = TexId.NULL; TexId batchTexId = TexId.NULL; MyTransparentMaterial prevMaterial = null; while (true) { if (i == N) { AddBatch(N, currentOffset, prevTexId, prevMaterial); break; } MyBillboard billboard = m_sortedBuffer[i]; MyTransparentMaterial material = MyTransparentMaterials.GetMaterial(billboard.Material); if (material.UseAtlas) { var atlasItem = m_atlas.FindElement(material.Texture); batchTexId = atlasItem.TextureId; } else { batchTexId = MyTextures.GetTexture(material.Texture, MyTextureEnum.GUI, true); } bool closeBatch = i > 0 && (batchTexId != prevTexId || i == m_sortedCount); if (closeBatch) { AddBatch(i, currentOffset, prevTexId, prevMaterial); currentOffset = i; } var billboardData = new MyBillboardData(); var billboardVertices = new MyBillboardVertexData(); billboardData.CustomProjectionID = billboard.CustomViewProjection; billboardData.Color = billboard.Color; billboardData.Color.X *= billboard.ColorIntensity; billboardData.Color.Y *= billboard.ColorIntensity; billboardData.Color.Z *= billboard.ColorIntensity; billboardData.AlphaCutout = billboard.AlphaCutout; billboardData.AlphaSaturation = material.AlphaSaturation; billboardData.SoftParticleDistanceScale = billboard.SoftParticleDistanceScale * material.SoftParticleDistanceScale; billboardData.Reflective = billboard.Reflectivity; Vector3D pos0 = billboard.Position0; Vector3D pos1 = billboard.Position1; Vector3D pos2 = billboard.Position2; Vector3D pos3 = billboard.Position3; if (billboard.ParentID != -1) { if (MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID) != null) { var matrix = MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID).WorldMatrix; Vector3D.Transform(ref pos0, ref matrix, out pos0); Vector3D.Transform(ref pos1, ref matrix, out pos1); Vector3D.Transform(ref pos2, ref matrix, out pos2); Vector3D.Transform(ref pos3, ref matrix, out pos3); } } MyEnvironmentMatrices envMatrices = MyRender11.Environment; if (MyStereoRender.Enable) { if (MyStereoRender.RenderRegion == MyStereoRegion.LEFT) { envMatrices = MyStereoRender.EnvMatricesLeftEye; } else if (MyStereoRender.RenderRegion == MyStereoRegion.RIGHT) { envMatrices = MyStereoRender.EnvMatricesRightEye; } } if (billboard.CustomViewProjection != -1) { var billboardViewProjection = MyRenderProxy.BillboardsViewProjectionRead[billboard.CustomViewProjection]; //pos0 -= envMatrices.CameraPosition; //pos1 -= envMatrices.CameraPosition; //pos2 -= envMatrices.CameraPosition; //pos3 -= envMatrices.CameraPosition; } else { pos0 -= envMatrices.CameraPosition; pos1 -= envMatrices.CameraPosition; pos2 -= envMatrices.CameraPosition; pos3 -= envMatrices.CameraPosition; } var normal = Vector3.Cross(pos1 - pos0, pos2 - pos0); normal.Normalize(); billboardData.Normal = normal; billboardVertices.V0.Position = pos0; billboardVertices.V1.Position = pos1; billboardVertices.V2.Position = pos2; billboardVertices.V3.Position = pos3; var uv0 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y); var uv1 = new Vector2(material.UVOffset.X + material.UVSize.X * billboard.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y); var uv2 = new Vector2(material.UVOffset.X + material.UVSize.X * billboard.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y + material.UVSize.Y * billboard.UVSize.Y); var uv3 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y + material.UVSize.Y * billboard.UVSize.Y); if (material.UseAtlas) { var atlasItem = m_atlas.FindElement(material.Texture); uv0 = uv0 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv1 = uv1 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv2 = uv2 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv3 = uv3 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); } billboardVertices.V0.Texcoord = new HalfVector2(uv0); billboardVertices.V1.Texcoord = new HalfVector2(uv1); billboardVertices.V2.Texcoord = new HalfVector2(uv2); billboardVertices.V3.Texcoord = new HalfVector2(uv3); pos0.AssertIsValid(); pos1.AssertIsValid(); pos2.AssertIsValid(); pos3.AssertIsValid(); MyTriangleBillboard triBillboard = billboard as MyTriangleBillboard; if (triBillboard != null) { billboardVertices.V3.Position = pos2; // second triangle will die in rasterizer billboardVertices.V0.Texcoord = new HalfVector2(triBillboard.UV0); billboardVertices.V1.Texcoord = new HalfVector2(triBillboard.UV1); billboardVertices.V2.Texcoord = new HalfVector2(triBillboard.UV2); billboardData.Normal = triBillboard.Normal0; } m_arrayDataBillboards.Data[i] = billboardData; m_arrayDataBillboards.Vertex[i] = billboardVertices; if (billboard.Window && MyScreenDecals.HasEntityDecals((uint)billboard.ParentID)) { m_arrayDataWindows.Data[windowidx] = billboardData; m_arrayDataWindows.Vertex[windowidx] = billboardVertices; windowidx++; } prevTexId = batchTexId; prevMaterial = material; i++; } }