load and unload images dynamically

This commit is contained in:
Colin McMillen 2023-07-25 21:24:20 -04:00
parent fb26de5fa1
commit 27a4a64ccb

View File

@ -177,7 +177,7 @@ public class Photo {
TryParseRating(info.Metadata.XmpProfile, out Rating); TryParseRating(info.Metadata.XmpProfile, out Rating);
} }
public async void Load() { public async void LoadAsync() {
// We don't assign to this.image until Load() is done, because we might // We don't assign to this.image until Load() is done, because we might
// edit the image due to rotation (etc) and don't want to try generating // edit the image due to rotation (etc) and don't want to try generating
// a texture for it until that's already happened. // a texture for it until that's already happened.
@ -186,6 +186,13 @@ public class Photo {
image = tmp; image = tmp;
} }
public void Unload() {
if (texture != placeholder) {
texture.Dispose();
texture = placeholder;
}
}
private bool TryParseRating(XmpProfile? xmp, out int rating) { private bool TryParseRating(XmpProfile? xmp, out int rating) {
rating = 0; rating = 0;
if (xmp == null) { if (xmp == null) {
@ -320,10 +327,6 @@ public class Photo {
Console.WriteLine($"*** WARNING: unexpected DateTimeOriginal value: {dateTimeOriginal.Value}"); Console.WriteLine($"*** WARNING: unexpected DateTimeOriginal value: {dateTimeOriginal.Value}");
} }
} }
// foreach (IExifValue exif in exifs.Values) {
// Console.WriteLine(exif.Tag.ToString() + " " + exif.GetValue().ToString());
// }
} }
public Texture Texture() { public Texture Texture() {
@ -512,6 +515,7 @@ public class Game : GameWindow {
int ElementBufferObject; int ElementBufferObject;
int VertexArrayObject; int VertexArrayObject;
List<Photo> photos = new(); List<Photo> photos = new();
HashSet<int> loadedImages = new();
int photoIndex = 0; int photoIndex = 0;
int ribbonIndex = 0; int ribbonIndex = 0;
Shader shader = new(); Shader shader = new();
@ -606,7 +610,7 @@ public class Game : GameWindow {
} }
} }
protected override async void OnLoad() { protected override void OnLoad() {
base.OnLoad(); base.OnLoad();
GL.ClearColor(0f, 0f, 0f, 1f); GL.ClearColor(0f, 0f, 0f, 1f);
@ -642,12 +646,12 @@ public class Game : GameWindow {
GL.EnableVertexAttribArray(texCoordLocation); GL.EnableVertexAttribArray(texCoordLocation);
GL.VertexAttribPointer(texCoordLocation, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float)); GL.VertexAttribPointer(texCoordLocation, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float));
// Load textures from JPEGs. // Load photos from a directory.
// string[] files = Directory.GetFiles(@"c:\users\colin\desktop\photos-test\"); // string[] files = Directory.GetFiles(@"c:\users\colin\desktop\photos-test\");
// string[] files = Directory.GetFiles(@"c:\users\colin\pictures\photos\2023\07\14\"); // string[] files = Directory.GetFiles(@"c:\users\colin\pictures\photos\2023\07\14\");
string[] files = Directory.GetFiles(@"G:\DCIM\100EOSR6\"); // string[] files = Directory.GetFiles(@"G:\DCIM\100EOSR6\");
// string[] files = Directory.GetFiles(@"C:\Users\colin\Pictures\photos\2018\06\23"); // string[] files = Directory.GetFiles(@"C:\Users\colin\Pictures\photos\2018\06\23");
// string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\Germany all\104D7000"); string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\Germany all\104D7000");
// string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\many-birds\"); // string[] files = Directory.GetFiles(@"C:\Users\colin\Desktop\many-birds\");
for (int i = 0; i < files.Count(); i++) { for (int i = 0; i < files.Count(); i++) {
@ -659,10 +663,6 @@ public class Game : GameWindow {
} }
photos.Sort(ComparePhotosByDate); photos.Sort(ComparePhotosByDate);
for (int i = 0; i < 40 && i < photos.Count; i++) {
await Task.Run( () => { photos[i].Load(); });
}
} }
private static int ComparePhotosByDate(Photo x, Photo y) { private static int ComparePhotosByDate(Photo x, Photo y) {
@ -679,11 +679,36 @@ public class Game : GameWindow {
base.OnUnload(); base.OnUnload();
} }
private async void LoadAndUnloadImagesAsync() {
int minUnloadedImage = Math.Max(0, photoIndex - 40);
int maxUnloadedImage = Math.Min(photoIndex + 40, photos.Count - 1);
int minLoadedImage = Math.Max(0, photoIndex - 20);
int maxLoadedImage = Math.Min(photoIndex + 20, photos.Count - 1);
// First, unload images that are far outside our window.
foreach (int i in loadedImages) {
if (i < minUnloadedImage || i > maxUnloadedImage) {
loadedImages.Remove(i);
photos[i].Unload();
Console.WriteLine("unloading " + i);
}
}
// Then, start loading any images that aren't in our window.
for (int i = minLoadedImage; i <= maxLoadedImage; i++) {
if (!loadedImages.Contains(i)) {
Console.WriteLine("loading " + i);
loadedImages.Add(i);
await Task.Run( () => { photos[i].LoadAsync(); });
}
}
}
protected override void OnRenderFrame(FrameEventArgs e) { protected override void OnRenderFrame(FrameEventArgs e) {
base.OnRenderFrame(e); base.OnRenderFrame(e);
LoadAndUnloadImagesAsync();
GL.Clear(ClearBufferMask.ColorBufferBit); GL.Clear(ClearBufferMask.ColorBufferBit);
GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferObject); GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferObject); HashSet<int> loadedImages = new();
GL.ActiveTexture(TextureUnit.Texture0); GL.ActiveTexture(TextureUnit.Texture0);
Photo activePhoto = photos[photoIndex]; Photo activePhoto = photos[photoIndex];
@ -829,4 +854,3 @@ static class Program {
} }
} }
} }