aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRay <raysan5@gmail.com>2018-01-18 00:23:28 +0100
committerRay <raysan5@gmail.com>2018-01-18 00:23:45 +0100
commitce9f191f1b0dee3bc9607e58232a166c10cef9c7 (patch)
tree8e994413ce979b7feb21a7bd0f597d4d3955eada /src
parentbdb61306aca39f8c92e6b5406af348f34171cdd0 (diff)
downloadraylib-ce9f191f1b0dee3bc9607e58232a166c10cef9c7.tar.gz
raylib-ce9f191f1b0dee3bc9607e58232a166c10cef9c7.zip
Added function: ImageMipmaps()
Diffstat (limited to 'src')
-rw-r--r--src/raylib.h1
-rw-r--r--src/textures.c75
2 files changed, 76 insertions, 0 deletions
diff --git a/src/raylib.h b/src/raylib.h
index 2bb04f77..85c035c3 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -886,6 +886,7 @@ RLAPI void ImageAlphaPremultiply(Image *image);
RLAPI void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle
RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize and image (bilinear filtering)
RLAPI void ImageResizeNN(Image *image,int newWidth,int newHeight); // Resize and image (Nearest-Neighbor scaling algorithm)
+RLAPI void ImageMipmaps(Image *image); // Generate all mipmap levels for a provided image
RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font)
RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font)
diff --git a/src/textures.c b/src/textures.c
index e228b356..f53adb73 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -1071,6 +1071,81 @@ void ImageResizeNN(Image *image,int newWidth,int newHeight)
free(pixels);
}
+// Generate all mipmap levels for a provided image
+// NOTE 1: Supports POT and NPOT images
+// NOTE 2: image.data is scaled to include mipmap levels
+// NOTE 3: Mipmaps format is the same as base image
+void ImageMipmaps(Image *image)
+{
+ int mipCount = 1; // Required mipmap levels count (including base level)
+ int mipWidth = image->width; // Base image width
+ int mipHeight = image->height; // Base image height
+ int mipSize = GetPixelDataSize(mipWidth, mipHeight, image->format); // Image data size (in bytes)
+
+ // Count mipmap levels required
+ while ((mipWidth != 1) || (mipHeight != 1))
+ {
+ if (mipWidth != 1) mipWidth /= 2;
+ if (mipHeight != 1) mipHeight /= 2;
+
+ // Security check for NPOT textures
+ if (mipWidth < 1) mipWidth = 1;
+ if (mipHeight < 1) mipHeight = 1;
+
+ TraceLog(LOG_DEBUG, "Next mipmap level: %i x %i - current size %i", mipWidth, mipHeight, mipSize);
+
+ mipCount++;
+ mipSize += GetPixelDataSize(mipWidth, mipHeight, image->format); // Add mipmap size (in bytes)
+ }
+
+ TraceLog(LOG_DEBUG, "Total mipmaps required: %i", mipCount);
+ TraceLog(LOG_DEBUG, "Total size of data required: %i", mipSize);
+ TraceLog(LOG_DEBUG, "Image data original memory point: %i", image->data);
+
+ if (image->mipmaps < mipCount)
+ {
+ void *temp = realloc(image->data, mipSize);
+
+ if (temp != NULL)
+ {
+ image->data = temp; // Assign new pointer (new size) to store mipmaps data
+ TraceLog(LOG_DEBUG, "Image data memory point reallocated: %i", temp);
+ }
+ else TraceLog(LOG_WARNING, "Mipmaps required memory could not be allocated");
+
+ // Pointer to allocated memory point where store next mipmap level data
+ unsigned char *nextmip = image->data + GetPixelDataSize(image->width, image->height, image->format);
+
+ mipWidth = image->width/2;
+ mipHeight = image->height/2;
+ mipSize = GetPixelDataSize(mipWidth, mipHeight, image->format);
+ Image imCopy = ImageCopy(*image);
+
+ for (int i = 1; i < mipCount; i++)
+ {
+ TraceLog(LOG_DEBUG, "Next mipmap level %i (%i x %i) - size %i - mem pos: %i", i, mipWidth, mipHeight, mipSize, nextmip);
+
+ ImageResize(&imCopy, mipWidth, mipHeight); // Uses internally Mitchell cubic downscale filter
+
+ memcpy(nextmip, imCopy.data, mipSize);
+ nextmip += mipSize;
+ image->mipmaps++;
+
+ mipWidth /= 2;
+ mipHeight /= 2;
+
+ // Security check for NPOT textures
+ if (mipWidth < 1) mipWidth = 1;
+ if (mipHeight < 1) mipHeight = 1;
+
+ mipSize = GetPixelDataSize(mipWidth, mipHeight, image->format);
+ }
+
+ UnloadImage(imCopy);
+ }
+ else TraceLog(LOG_WARNING, "Image mipmaps already available");
+}
+
// Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
// NOTE: In case selected bpp do not represent an known 16bit format,
// dithered data is stored in the LSB part of the unsigned short