public void DrawSprite(TextureResource texture, Coord position, double angle, double scaleX, double scaleY, int textureIndex) { SDL_Rect dst = new SDL_Rect(); dst.x = position.X; dst.y = position.Y; dst.w = Convert.ToInt32(Math.Floor(texture.SpriteSize.W * scaleX)); dst.h = Convert.ToInt32(Math.Floor(texture.SpriteSize.H * scaleY)); //Console.WriteLine("[Graphics.DrawSprite] Drawing texture '{0}'[{1}] onto ({2}, {3}) with size {4}x{5}.", texture.ResourceName, textureIndex, position.X, position.Y, texture.SpriteSize.W, texture.SpriteSize.H); //SetRenderDrawColor(new ColorRGBA(255, 255, 255, 255)); int res = SDL_RenderCopyEx(Renderer, texture.Textures[textureIndex], IntPtr.Zero, ref dst, angle, IntPtr.Zero, SDL_RendererFlip.SDL_FLIP_NONE); if (res != 0) { //error throw new EngineException("Error rendering texture '" + texture.ResourceName + "'.", "GraphicsEngine.DrawSprite()"); } if (DrawBorders) { int rdc = SDL_GetRenderDrawColor(Renderer, out byte r, out byte g, out byte b, out byte a); if (rdc != 0) { //error throw new EngineException("Error getting current render color.", "GraphicsEngine.DrawSprite()"); } int srdc1 = SDL_SetRenderDrawColor(Renderer, BorderColor.Red, BorderColor.Green, BorderColor.Blue, BorderColor.Alpha); if (srdc1 != 0) { //error throw new EngineException("Error setting render draw color to debug border color.", "GraphicsEngine.DrawSprite()"); } int bres = SDL_RenderDrawRect(Renderer, ref dst); if (bres != 0) { //error throw new EngineException("Error drawing sprite border for '" + texture.ResourceName + "'.", "GraphicsEngine.DrawSprite()"); } int srdc2 = SDL_SetRenderDrawColor(Renderer, r, g, b, a); if (srdc2 != 0) { //error throw new EngineException("Error restoring render draw color.", "GraphicsEngine.DrawSprite()"); } } }
public void LoadAsTexture(string fileLocation, string resourceName) { if (_SDL_Renderer == IntPtr.Zero) { Debug.Log("ResourceManager.LoadAsTexture()", "SDL Renderer not yet initialized, waiting for init."); Debug.Log("ResourceManager.LoadAsTexture()", "Warning! Call 'GameEngine.Start()' first before loading game resources."); Debug.Log("ResourceManager.LoadAsTexture()", "Otherwise, this will be an endless loop."); while (_SDL_Renderer == IntPtr.Zero) { SDL_Delay(100); } Debug.Log("ResourceManager.LoadAsTexture()", "SDL Renderer initialized."); //throw new ResourceException($"SDL Renderer not yet initialized, try calling GameEngine.InitGraphics() first", fileLocation); } if (_Textures.Contains(resourceName)) { throw new ResourceException($"A resource with the same name '{resourceName}' already exists.", fileLocation); } if (!File.Exists(fileLocation)) { throw new ResourceException($"Error loading resource '{resourceName}'. File not found.", fileLocation); } ZipArchive archive; try { archive = ZipFile.OpenRead(fileLocation); } catch { throw new ResourceException($"Error loading resource '{resourceName}'.", fileLocation); } bool loadedMetadata = false; List <string> files = new List <string>(); Size spriteSize = new Size(), sheetSize = new Size(); bool isSheet = false; foreach (ZipArchiveEntry entry in archive.Entries) { if (entry.Name == "metadata") { loadedMetadata = true; using (Stream ms = entry.Open()) { try { StreamReader reader = new StreamReader(ms); string json = reader.ReadToEnd(); reader.Close(); JsonDocument doc = JsonDocument.Parse(json); var meta = doc.RootElement; isSheet = meta.GetProperty("IsSheet").GetBoolean(); spriteSize.W = meta.GetProperty("SpriteSize.W").GetInt32(); spriteSize.H = meta.GetProperty("SpriteSize.H").GetInt32(); sheetSize.W = meta.GetProperty("SheetSize.W").GetInt32(); sheetSize.H = meta.GetProperty("SheetSize.H").GetInt32(); doc.Dispose(); } catch { throw new ResourceException($"Error parsing metadata for '{resourceName}'.", fileLocation); } } } else { files.Add(entry.Name); } } if (!loadedMetadata && !FLAG_ALLOW_MISSING_METADATA) { archive.Dispose(); throw new ResourceException($"Error loading resource '{resourceName}'. Metadata not found.", fileLocation); } List <IntPtr> surfaces = new List <IntPtr>(); List <IntPtr> textures = new List <IntPtr>(); /* Load resource here */ SDL_GetError(); foreach (string file in files) { try { ZipArchiveEntry data = archive.GetEntry(file); Stream s = data.Open(); byte[] buffer = new byte[data.Length]; //GCHandle handle = GCHandle.Alloc(byteData, GCHandleType.Pinned); IntPtr ptrArray = Marshal.AllocHGlobal(buffer.Length); s.Read(buffer, 0, buffer.Length); Marshal.Copy(buffer, 0, ptrArray, buffer.Length); Debug.Log("ResourceManager.LoadAsTexture()", $"Read texture data from {file}#{resourceName} @ {buffer.Length} byte(s)."); IntPtr rwops = SDL_RWFromMem(ptrArray, buffer.Length); IntPtr surface; surface = IMG_Load_RW(rwops, 0); string sE1 = SDL_GetError(); if (surface == IntPtr.Zero || rwops == IntPtr.Zero) { Debug.Log("ResourceManager.LoadAsTexture()", $"Error reading texture data {file}#{resourceName}. {sE1}"); continue; } Debug.Log("ResourceManager.LoadAsTexture()", $"Loaded texture data as surface from {file}#{resourceName}."); IntPtr texture; while (_SDL_Renderer == IntPtr.Zero) { SDL_Delay(100); } try { if (!FLAG_USE_ALTERNATE_TEXTURE_STRAT) { //SDL_Renderc texture = SDL_CreateTextureFromSurface(_SDL_Renderer, surface); //texture = CreateTexture(_SDL_Renderer, surface); } else { #pragma warning disable CS0162 // Unreachable code detected texture = IMG_LoadTexture_RW(_SDL_Renderer, rwops, 0); #pragma warning restore CS0162 // Unreachable code detected } } catch (Exception e) { Debug.Log("ResourceManager.LoadAsTexture()", $"Error creating texture data {file}#{resourceName}. {e.Message}"); continue; } string sE2 = SDL_GetError(); if (texture == IntPtr.Zero) { Debug.Log("ResourceManager.LoadAsTexture()", $"Error creating texture data {file}#{resourceName}. {sE2}"); continue; } surfaces.Add(surface); textures.Add(texture); Debug.Log("ResourceManager.LoadAsTexture()", $"Created texture from surface {file}#{resourceName}."); //SDL_FreeSurface(surface); Marshal.FreeHGlobal(ptrArray); SDL_RWclose(rwops); } catch { Debug.Log("ResourceManager.LoadAsTexture()", $"Error loading texture {file}#{resourceName}. Skipped file."); } } archive.Dispose(); TextureResource res = new TextureResource() { IsSpriteSheet = isSheet, SheetSize = sheetSize, SpriteSize = spriteSize, DataPtr = surfaces.ToArray(), Textures = textures.ToArray(), ResourceName = resourceName }; _Textures.Add(res); Debug.Log("ResourceManager.LoadAsTexture()", $"Successfully added texture {resourceName} to resources."); }