Skip to content

Instantly share code, notes, and snippets.

@ciwolsey
Created March 3, 2018 23:32
Show Gist options
  • Save ciwolsey/24635ea523b4a6b758783688be53bf86 to your computer and use it in GitHub Desktop.
Save ciwolsey/24635ea523b4a6b758783688be53bf86 to your computer and use it in GitHub Desktop.
using UnityEngine;
using FreeImageAPI;
using System.Threading;
using System;
public class ThreadedTexture2D : MonoBehaviour
{
// The actual Texture
public Texture2D tex;
// Dimensions of image to be loaded (must match size on disk)
public int importHeight = 4096;
public int importWidth = 4096;
// Raw texture data
private byte[] texData;
// is thread done?
private bool isDone = false;
// Actual thread
private Thread thread;
// EVENTS:
// Loading has started but hasn't finished yet
public event Action OnLoading;
// The Texture2D is now ready to use
public event Action<Texture2D> OnLoaded;
private void Awake()
{
// Converted texture data, 32bpp BGRA32
texData = new byte[importHeight * importWidth * 4];
// Texture2D to load it into, also BGRA32
tex = new Texture2D(importWidth, importHeight, TextureFormat.BGRA32, false, false);
tex.filterMode = FilterMode.Point;
}
public void Load(string path)
{
// Trigger event to signify the texture is currently being loaded
OnLoading?.Invoke();
// Create thread
thread = new Thread(OnThread);
// Make sure it's a background thread so it's aborted
thread.IsBackground = true;
// Start thread to load png texture async
thread.Start(path);
}
private void OnThread(object path)
{
// Load png into FreeImage bitmap
FIBITMAP fiBitmap = FreeImage.Load(FREE_IMAGE_FORMAT.FIF_PNG, (string)path, FREE_IMAGE_LOAD_FLAGS.DEFAULT);
// Write it into texData as 32bppp BGRA32. Params 5, 6, 7 have no effect all on 32bpp formats
FreeImage.ConvertToRawBits(texData, fiBitmap, (int)FreeImage.GetPitch(fiBitmap), 32, FreeImage.FI16_555_BLUE_MASK, FreeImage.FI_RGBA_RED_MASK, FreeImage.FI_RGBA_BLUE_MASK, false);
// Can be verified with FreeImage.GetDIBSize(fiBitmap);
FreeImage.Unload(fiBitmap);
// Thread is done
isDone = true;
}
private void Update()
{
// When thread has finished begin creating textures
if (isDone) CreateTextures();
}
private void CreateTextures()
{
// Load texData into tex2D as raw
tex.LoadRawTextureData(texData);
// Send texture to GPU
tex.Apply(false, true);
// Reset isDone
isDone = false;
// Trigger event to signify texture is ready
OnLoaded?.Invoke(tex);
}
}
@jganser
Copy link

jganser commented Feb 8, 2019

Wow this is really neat!

I was trying to implement this myself, but got stuck at building my project.
Could you tell me which Library your FreeImageAPI is coming from?
Currently I'm trying to get a custom for mono build of the FreeImageNET project to run, but I struggle with IL2CPP builds :/

Thanks beforehand!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment