From 5387b4543175bee9d195b24e250a0ef863a63555 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 25 Mar 2017 12:01:01 +0100 Subject: [PATCH] Working on configuration flags --- src/core.c | 6 +- src/raylib.h | 2 +- src/rlgl.c | 21 ++- src/textures.c | 345 +++++++++++++++++++++++++++++-------------------- src/utils.c | 2 +- 5 files changed, 228 insertions(+), 148 deletions(-) diff --git a/src/core.c b/src/core.c index 1a0e5a66..5a1ab77f 100644 --- a/src/core.c +++ b/src/core.c @@ -70,13 +70,13 @@ * **********************************************************************************************/ -// Default supported features -//------------------------------------- +// Default configuration flags (supported features) +//------------------------------------------------- #define SUPPORT_DEFAULT_FONT #define SUPPORT_MOUSE_GESTURES #define SUPPORT_CAMERA_SYSTEM #define SUPPORT_GESTURES_SYSTEM -//------------------------------------- +//------------------------------------------------- #include "raylib.h" diff --git a/src/raylib.h b/src/raylib.h index cdefceb2..24d6e1fd 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -13,7 +13,7 @@ * - Multiple textures support, including compressed formats and mipmaps generation * - Basic 3d support for Shapes, Models, Billboards, Heightmaps and Cubicmaps * - Powerful math module for Vector, Matrix and Quaternion operations: [raymath] -* - Audio loading and playing with streaming support and mixing channels [audio] +* - Audio loading and playing with streaming support and mixing channels: [audio] * - VR stereo rendering support with configurable HMD device parameters * - Multiple platforms support: Windows, Linux, Mac, Android, Raspberry Pi, HTML5 and Oculus Rift CV1 * - Custom color palette for fancy visuals on raywhite background diff --git a/src/rlgl.c b/src/rlgl.c index a937bdec..546fbe6e 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -25,7 +25,7 @@ * #define SUPPORT_VR_SIMULATION / SUPPORT_STEREO_RENDERING * Support VR simulation functionality (stereo rendering) * -* #define SUPPORT_SHADER_DISTORTION +* #define SUPPORT_DISTORTION_SHADER * Include stereo rendering distortion shader (shader_distortion.h) * * DEPENDENCIES: @@ -54,6 +54,11 @@ * **********************************************************************************************/ +// Default configuration flags (supported features) +//------------------------------------------------- +#define SUPPORT_VR_SIMULATION +//------------------------------------------------- + #include "rlgl.h" #include // Required for: fopen(), fclose(), fread()... [Used only on LoadText()] @@ -100,7 +105,7 @@ #include // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()] #endif -#if !defined(GRAPHICS_API_OPENGL_11) && !defined(RLGL_NO_DISTORTION_SHADER) +#if !defined(GRAPHICS_API_OPENGL_11) && defined(SUPPORT_DISTORTION_SHADER) #include "shader_distortion.h" // Distortion shader to be embedded #endif @@ -2591,10 +2596,12 @@ void InitVrSimulator(int vrDevice) // Initialize framebuffer and textures for stereo rendering // NOTE: screen size should match HMD aspect ratio vrConfig.stereoFbo = rlglLoadRenderTexture(screenWidth, screenHeight); - + +#if defined(SUPPORT_DISTORTION_SHADER) // Load distortion shader (initialized by default with Oculus Rift CV1 parameters) vrConfig.distortionShader.id = LoadShaderProgram(vDistortionShaderStr, fDistortionShaderStr); if (vrConfig.distortionShader.id != 0) LoadDefaultShaderLocations(&vrConfig.distortionShader); +#endif SetStereoConfig(hmd); @@ -2613,7 +2620,9 @@ void CloseVrSimulator(void) if (vrSimulatorReady) { rlDeleteRenderTextures(vrConfig.stereoFbo); // Unload stereo framebuffer and texture + #if defined(SUPPORT_DISTORTION_SHADER) UnloadShader(vrConfig.distortionShader); // Unload distortion shader + #endif } #endif } @@ -2700,8 +2709,12 @@ void EndVrDrawing(void) rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix rlLoadIdentity(); // Reset internal modelview matrix +#if defined(SUPPORT_DISTORTION_SHADER) // Draw RenderTexture (stereoFbo) using distortion shader currentShader = vrConfig.distortionShader; +#else + currentShader = GetDefaultShader(); +#endif rlEnableTexture(vrConfig.stereoFbo.texture.id); @@ -3536,6 +3549,7 @@ static void SetStereoConfig(VrDeviceInfo hmd) TraceLog(DEBUG, "VR: Distortion Shader: Scale = { %f, %f }", scale[0], scale[1]); TraceLog(DEBUG, "VR: Distortion Shader: ScaleIn = { %f, %f }", scaleIn[0], scaleIn[1]); +#if defined(SUPPORT_DISTORTION_SHADER) // Update distortion shader with lens and distortion-scale parameters SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "leftLensCenter"), leftLensCenter, 2); SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "rightLensCenter"), rightLensCenter, 2); @@ -3546,6 +3560,7 @@ static void SetStereoConfig(VrDeviceInfo hmd) SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "scaleIn"), scaleIn, 2); SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "hmdWarpParam"), hmd.distortionK, 4); SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "chromaAbParam"), hmd.chromaAbCorrection, 4); +#endif // Fovy is normally computed with: 2*atan2(hmd.vScreenSize, 2*hmd.eyeToScreenDistance)*RAD2DEG // ...but with lens distortion it is increased (see Oculus SDK Documentation) diff --git a/src/textures.c b/src/textures.c index f323f352..6fff8e75 100644 --- a/src/textures.c +++ b/src/textures.c @@ -4,24 +4,24 @@ * * CONFIGURATION: * -* #define SUPPORT_STB_IMAGE / INCLUDE_STB_IMAGE -* -* #define SUPPORT_FILEFORMAT_BMP / SUPPORT_LOAD_BMP -* #define SUPPORT_FILEFORMAT_PNG / SUPPORT_LOAD_PNG +* #define SUPPORT_FILEFORMAT_BMP +* #define SUPPORT_FILEFORMAT_PNG * #define SUPPORT_FILEFORMAT_TGA -* #define SUPPORT_FILEFORMAT_JPG / ENABLE_LOAD_JPG +* #define SUPPORT_FILEFORMAT_JPG * #define SUPPORT_FILEFORMAT_GIF +* #define SUPPORT_FILEFORMAT_PSD * #define SUPPORT_FILEFORMAT_HDR -* #define SUPPORT_FILEFORMAT_DDS / ENABLE_LOAD_DDS +* #define SUPPORT_FILEFORMAT_DDS * #define SUPPORT_FILEFORMAT_PKM * #define SUPPORT_FILEFORMAT_KTX * #define SUPPORT_FILEFORMAT_PVR * #define SUPPORT_FILEFORMAT_ASTC -* Selected desired fileformats to be supported for loading. Some of those formats are +* Selecte desired fileformats to be supported for image data loading. Some of those formats are * supported by default, to remove support, just comment unrequired #define in this module * -* #define SUPPORT_IMAGE_RESIZE / INCLUDE_STB_IMAGE_RESIZE * #define SUPPORT_IMAGE_MANIPULATION +* Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... +* If not defined only three image editing functions supported: ImageFormat(), ImageAlphaMask(), ImageToPOT() * * DEPENDENCIES: * stb_image - Multiple image formats loading (JPEG, PNG, BMP, TGA, PSD, GIF, PIC) @@ -50,6 +50,12 @@ * **********************************************************************************************/ +// Default configuration flags (supported features) +//------------------------------------------------- +#define SUPPORT_FILEFORMAT_PNG +#define SUPPORT_IMAGE_MANIPULATION +//------------------------------------------------- + #include "raylib.h" #include // Required for: malloc(), free() @@ -61,23 +67,46 @@ #include "utils.h" // Required for: fopen() Android mapping, TraceLog() -// Support only desired texture formats, by default: JPEG, PNG, BMP, TGA -//#define STBI_NO_JPEG // Image format .jpg and .jpeg -//#define STBI_NO_PNG -//#define STBI_NO_BMP -//#define STBI_NO_TGA -#define STBI_NO_PSD -#define STBI_NO_GIF -#define STBI_NO_HDR +// Support only desired texture formats on stb_image +#if !defined(SUPPORT_FILEFORMAT_BMP) + #define STBI_NO_BMP +#endif +#if !defined(SUPPORT_FILEFORMAT_PNG) + #define STBI_NO_PNG +#endif +#if !defined(SUPPORT_FILEFORMAT_TGA) + #define STBI_NO_TGA +#endif +#if !defined(SUPPORT_FILEFORMAT_JPG) + #define STBI_NO_JPEG // Image format .jpg and .jpeg +#endif +#if !defined(SUPPORT_FILEFORMAT_PSD) + #define STBI_NO_PSD +#endif +#if !defined(SUPPORT_FILEFORMAT_GIF) + #define STBI_NO_GIF +#endif +#if !defined(SUPPORT_FILEFORMAT_HDR) + #define STBI_NO_HDR +#endif + +// Image fileformats not supported by default #define STBI_NO_PIC #define STBI_NO_PNM // Image format .ppm and .pgm -#define STB_IMAGE_IMPLEMENTATION -#include "external/stb_image.h" // Required for: stbi_load() - // NOTE: Used to read image data (multiple formats support) -#define STB_IMAGE_RESIZE_IMPLEMENTATION -#include "external/stb_image_resize.h" // Required for: stbir_resize_uint8() - // NOTE: Used for image scaling on ImageResize() +#if (defined(SUPPORT_FILEFORMAT_BMP) || defined(SUPPORT_FILEFORMAT_PNG) || defined(SUPPORT_FILEFORMAT_TGA) || \ + defined(SUPPORT_FILEFORMAT_JPG) || defined(SUPPORT_FILEFORMAT_PSD) || defined(SUPPORT_FILEFORMAT_GIF) || \ + defined(SUPPORT_FILEFORMAT_HDR)) + #define STB_IMAGE_IMPLEMENTATION + #include "external/stb_image.h" // Required for: stbi_load() + // NOTE: Used to read image data (multiple formats support) +#endif + +#if defined(SUPPORT_IMAGE_MANIPULATION) + #define STB_IMAGE_RESIZE_IMPLEMENTATION + #include "external/stb_image_resize.h" // Required for: stbir_resize_uint8() + // NOTE: Used for image scaling on ImageResize() +#endif //---------------------------------------------------------------------------------- // Defines and Macros @@ -102,11 +131,21 @@ //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- +#if defined(SUPPORT_FILEFORMAT_DDS) static Image LoadDDS(const char *fileName); // Load DDS file +#endif +#if defined(SUPPORT_FILEFORMAT_PKM) static Image LoadPKM(const char *fileName); // Load PKM file +#endif +#if defined(SUPPORT_FILEFORMAT_KTX) static Image LoadKTX(const char *fileName); // Load KTX file +#endif +#if defined(SUPPORT_FILEFORMAT_PVR) static Image LoadPVR(const char *fileName); // Load PVR file +#endif +#if defined(SUPPORT_FILEFORMAT_ASTC) static Image LoadASTC(const char *fileName); // Load ASTC file +#endif //---------------------------------------------------------------------------------- // Module Functions Definition @@ -124,18 +163,21 @@ Image LoadImage(const char *fileName) image.mipmaps = 0; image.format = 0; - if ((strcmp(GetExtension(fileName),"png") == 0) || - (strcmp(GetExtension(fileName),"bmp") == 0) || - (strcmp(GetExtension(fileName),"tga") == 0) || - (strcmp(GetExtension(fileName),"jpg") == 0) -#ifndef STBI_NO_GIF + if ((strcmp(GetExtension(fileName),"png") == 0) +#if defined(SUPPORT_FILEFORMAT_BMP) + || (strcmp(GetExtension(fileName),"bmp") == 0) +#endif +#if defined(SUPPORT_FILEFORMAT_TGA) + || (strcmp(GetExtension(fileName),"tga") == 0) +#endif +#if defined(SUPPORT_FILEFORMAT_JPG) + || (strcmp(GetExtension(fileName),"jpg") == 0) +#endif +#if defined(SUPPORT_FILEFORMAT_DDS) || (strcmp(GetExtension(fileName),"gif") == 0) #endif -#ifndef STBI_NO_PSD +#if defined(SUPPORT_FILEFORMAT_PSD) || (strcmp(GetExtension(fileName),"psd") == 0) -#endif -#ifndef STBI_NO_PIC - || (strcmp(GetExtension(fileName),"pic") == 0) #endif ) { @@ -155,11 +197,21 @@ Image LoadImage(const char *fileName) else if (imgBpp == 3) image.format = UNCOMPRESSED_R8G8B8; else if (imgBpp == 4) image.format = UNCOMPRESSED_R8G8B8A8; } +#if defined(SUPPORT_FILEFORMAT_DDS) else if (strcmp(GetExtension(fileName),"dds") == 0) image = LoadDDS(fileName); +#endif +#if defined(SUPPORT_FILEFORMAT_PKM) else if (strcmp(GetExtension(fileName),"pkm") == 0) image = LoadPKM(fileName); +#endif +#if defined(SUPPORT_FILEFORMAT_KTX) else if (strcmp(GetExtension(fileName),"ktx") == 0) image = LoadKTX(fileName); +#endif +#if defined(SUPPORT_FILEFORMAT_PVR) else if (strcmp(GetExtension(fileName),"pvr") == 0) image = LoadPVR(fileName); +#endif +#if defined(SUPPORT_FILEFORMAT_ASTC) else if (strcmp(GetExtension(fileName),"astc") == 0) image = LoadASTC(fileName); +#endif else if (strcmp(GetExtension(fileName),"rres") == 0) { RRES rres = LoadResource(fileName, 0); @@ -171,6 +223,7 @@ Image LoadImage(const char *fileName) UnloadResource(rres); } + else TraceLog("[%s] Image fileformat not supported", fileName); if (image.data != NULL) TraceLog(INFO, "[%s] Image loaded successfully (%ix%i)", fileName, image.width, image.height); else TraceLog(WARNING, "[%s] Image could not be loaded", fileName); @@ -664,115 +717,6 @@ void ImageAlphaMask(Image *image, Image alphaMask) } } -// 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 -void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp) -{ - if (image->format >= COMPRESSED_DXT1_RGB) - { - TraceLog(WARNING, "Compressed data formats can not be dithered"); - return; - } - - if ((rBpp+gBpp+bBpp+aBpp) > 16) - { - TraceLog(WARNING, "Unsupported dithering bpps (%ibpp), only 16bpp or lower modes supported", (rBpp+gBpp+bBpp+aBpp)); - } - else - { - Color *pixels = GetImageData(*image); - - free(image->data); // free old image data - - if ((image->format != UNCOMPRESSED_R8G8B8) && (image->format != UNCOMPRESSED_R8G8B8A8)) - { - TraceLog(WARNING, "Image format is already 16bpp or lower, dithering could have no effect"); - } - - // Define new image format, check if desired bpp match internal known format - if ((rBpp == 5) && (gBpp == 6) && (bBpp == 5) && (aBpp == 0)) image->format = UNCOMPRESSED_R5G6B5; - else if ((rBpp == 5) && (gBpp == 5) && (bBpp == 5) && (aBpp == 1)) image->format = UNCOMPRESSED_R5G5B5A1; - else if ((rBpp == 4) && (gBpp == 4) && (bBpp == 4) && (aBpp == 4)) image->format = UNCOMPRESSED_R4G4B4A4; - else - { - image->format = 0; - TraceLog(WARNING, "Unsupported dithered OpenGL internal format: %ibpp (R%iG%iB%iA%i)", (rBpp+gBpp+bBpp+aBpp), rBpp, gBpp, bBpp, aBpp); - } - - // NOTE: We will store the dithered data as unsigned short (16bpp) - image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short)); - - Color oldPixel = WHITE; - Color newPixel = WHITE; - - int rError, gError, bError; - unsigned short rPixel, gPixel, bPixel, aPixel; // Used for 16bit pixel composition - - #define MIN(a,b) (((a)<(b))?(a):(b)) - - for (int y = 0; y < image->height; y++) - { - for (int x = 0; x < image->width; x++) - { - oldPixel = pixels[y*image->width + x]; - - // NOTE: New pixel obtained by bits truncate, it would be better to round values (check ImageFormat()) - newPixel.r = oldPixel.r >> (8 - rBpp); // R bits - newPixel.g = oldPixel.g >> (8 - gBpp); // G bits - newPixel.b = oldPixel.b >> (8 - bBpp); // B bits - newPixel.a = oldPixel.a >> (8 - aBpp); // A bits (not used on dithering) - - // NOTE: Error must be computed between new and old pixel but using same number of bits! - // We want to know how much color precision we have lost... - rError = (int)oldPixel.r - (int)(newPixel.r << (8 - rBpp)); - gError = (int)oldPixel.g - (int)(newPixel.g << (8 - gBpp)); - bError = (int)oldPixel.b - (int)(newPixel.b << (8 - bBpp)); - - pixels[y*image->width + x] = newPixel; - - // NOTE: Some cases are out of the array and should be ignored - if (x < (image->width - 1)) - { - pixels[y*image->width + x+1].r = MIN((int)pixels[y*image->width + x+1].r + (int)((float)rError*7.0f/16), 0xff); - pixels[y*image->width + x+1].g = MIN((int)pixels[y*image->width + x+1].g + (int)((float)gError*7.0f/16), 0xff); - pixels[y*image->width + x+1].b = MIN((int)pixels[y*image->width + x+1].b + (int)((float)bError*7.0f/16), 0xff); - } - - if ((x > 0) && (y < (image->height - 1))) - { - pixels[(y+1)*image->width + x-1].r = MIN((int)pixels[(y+1)*image->width + x-1].r + (int)((float)rError*3.0f/16), 0xff); - pixels[(y+1)*image->width + x-1].g = MIN((int)pixels[(y+1)*image->width + x-1].g + (int)((float)gError*3.0f/16), 0xff); - pixels[(y+1)*image->width + x-1].b = MIN((int)pixels[(y+1)*image->width + x-1].b + (int)((float)bError*3.0f/16), 0xff); - } - - if (y < (image->height - 1)) - { - pixels[(y+1)*image->width + x].r = MIN((int)pixels[(y+1)*image->width + x].r + (int)((float)rError*5.0f/16), 0xff); - pixels[(y+1)*image->width + x].g = MIN((int)pixels[(y+1)*image->width + x].g + (int)((float)gError*5.0f/16), 0xff); - pixels[(y+1)*image->width + x].b = MIN((int)pixels[(y+1)*image->width + x].b + (int)((float)bError*5.0f/16), 0xff); - } - - if ((x < (image->width - 1)) && (y < (image->height - 1))) - { - pixels[(y+1)*image->width + x+1].r = MIN((int)pixels[(y+1)*image->width + x+1].r + (int)((float)rError*1.0f/16), 0xff); - pixels[(y+1)*image->width + x+1].g = MIN((int)pixels[(y+1)*image->width + x+1].g + (int)((float)gError*1.0f/16), 0xff); - pixels[(y+1)*image->width + x+1].b = MIN((int)pixels[(y+1)*image->width + x+1].b + (int)((float)bError*1.0f/16), 0xff); - } - - rPixel = (unsigned short)newPixel.r; - gPixel = (unsigned short)newPixel.g; - bPixel = (unsigned short)newPixel.b; - aPixel = (unsigned short)newPixel.a; - - ((unsigned short *)image->data)[y*image->width + x] = (rPixel << (gBpp + bBpp + aBpp)) | (gPixel << (bBpp + aBpp)) | (bPixel << aBpp) | aPixel; - } - } - - free(pixels); - } -} - // Convert image to POT (power-of-two) // NOTE: It could be useful on OpenGL ES 2.0 (RPI, HTML5) void ImageToPOT(Image *image, Color fillColor) @@ -818,6 +762,7 @@ void ImageToPOT(Image *image, Color fillColor) } } +#if defined(SUPPORT_IMAGE_MANIPULATION) // Copy an image to a new image Image ImageCopy(Image image) { @@ -1203,6 +1148,115 @@ void ImageFlipHorizontal(Image *image) image->data = processed.data; } +// 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 +void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp) +{ + if (image->format >= COMPRESSED_DXT1_RGB) + { + TraceLog(WARNING, "Compressed data formats can not be dithered"); + return; + } + + if ((rBpp+gBpp+bBpp+aBpp) > 16) + { + TraceLog(WARNING, "Unsupported dithering bpps (%ibpp), only 16bpp or lower modes supported", (rBpp+gBpp+bBpp+aBpp)); + } + else + { + Color *pixels = GetImageData(*image); + + free(image->data); // free old image data + + if ((image->format != UNCOMPRESSED_R8G8B8) && (image->format != UNCOMPRESSED_R8G8B8A8)) + { + TraceLog(WARNING, "Image format is already 16bpp or lower, dithering could have no effect"); + } + + // Define new image format, check if desired bpp match internal known format + if ((rBpp == 5) && (gBpp == 6) && (bBpp == 5) && (aBpp == 0)) image->format = UNCOMPRESSED_R5G6B5; + else if ((rBpp == 5) && (gBpp == 5) && (bBpp == 5) && (aBpp == 1)) image->format = UNCOMPRESSED_R5G5B5A1; + else if ((rBpp == 4) && (gBpp == 4) && (bBpp == 4) && (aBpp == 4)) image->format = UNCOMPRESSED_R4G4B4A4; + else + { + image->format = 0; + TraceLog(WARNING, "Unsupported dithered OpenGL internal format: %ibpp (R%iG%iB%iA%i)", (rBpp+gBpp+bBpp+aBpp), rBpp, gBpp, bBpp, aBpp); + } + + // NOTE: We will store the dithered data as unsigned short (16bpp) + image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short)); + + Color oldPixel = WHITE; + Color newPixel = WHITE; + + int rError, gError, bError; + unsigned short rPixel, gPixel, bPixel, aPixel; // Used for 16bit pixel composition + + #define MIN(a,b) (((a)<(b))?(a):(b)) + + for (int y = 0; y < image->height; y++) + { + for (int x = 0; x < image->width; x++) + { + oldPixel = pixels[y*image->width + x]; + + // NOTE: New pixel obtained by bits truncate, it would be better to round values (check ImageFormat()) + newPixel.r = oldPixel.r >> (8 - rBpp); // R bits + newPixel.g = oldPixel.g >> (8 - gBpp); // G bits + newPixel.b = oldPixel.b >> (8 - bBpp); // B bits + newPixel.a = oldPixel.a >> (8 - aBpp); // A bits (not used on dithering) + + // NOTE: Error must be computed between new and old pixel but using same number of bits! + // We want to know how much color precision we have lost... + rError = (int)oldPixel.r - (int)(newPixel.r << (8 - rBpp)); + gError = (int)oldPixel.g - (int)(newPixel.g << (8 - gBpp)); + bError = (int)oldPixel.b - (int)(newPixel.b << (8 - bBpp)); + + pixels[y*image->width + x] = newPixel; + + // NOTE: Some cases are out of the array and should be ignored + if (x < (image->width - 1)) + { + pixels[y*image->width + x+1].r = MIN((int)pixels[y*image->width + x+1].r + (int)((float)rError*7.0f/16), 0xff); + pixels[y*image->width + x+1].g = MIN((int)pixels[y*image->width + x+1].g + (int)((float)gError*7.0f/16), 0xff); + pixels[y*image->width + x+1].b = MIN((int)pixels[y*image->width + x+1].b + (int)((float)bError*7.0f/16), 0xff); + } + + if ((x > 0) && (y < (image->height - 1))) + { + pixels[(y+1)*image->width + x-1].r = MIN((int)pixels[(y+1)*image->width + x-1].r + (int)((float)rError*3.0f/16), 0xff); + pixels[(y+1)*image->width + x-1].g = MIN((int)pixels[(y+1)*image->width + x-1].g + (int)((float)gError*3.0f/16), 0xff); + pixels[(y+1)*image->width + x-1].b = MIN((int)pixels[(y+1)*image->width + x-1].b + (int)((float)bError*3.0f/16), 0xff); + } + + if (y < (image->height - 1)) + { + pixels[(y+1)*image->width + x].r = MIN((int)pixels[(y+1)*image->width + x].r + (int)((float)rError*5.0f/16), 0xff); + pixels[(y+1)*image->width + x].g = MIN((int)pixels[(y+1)*image->width + x].g + (int)((float)gError*5.0f/16), 0xff); + pixels[(y+1)*image->width + x].b = MIN((int)pixels[(y+1)*image->width + x].b + (int)((float)bError*5.0f/16), 0xff); + } + + if ((x < (image->width - 1)) && (y < (image->height - 1))) + { + pixels[(y+1)*image->width + x+1].r = MIN((int)pixels[(y+1)*image->width + x+1].r + (int)((float)rError*1.0f/16), 0xff); + pixels[(y+1)*image->width + x+1].g = MIN((int)pixels[(y+1)*image->width + x+1].g + (int)((float)gError*1.0f/16), 0xff); + pixels[(y+1)*image->width + x+1].b = MIN((int)pixels[(y+1)*image->width + x+1].b + (int)((float)bError*1.0f/16), 0xff); + } + + rPixel = (unsigned short)newPixel.r; + gPixel = (unsigned short)newPixel.g; + bPixel = (unsigned short)newPixel.b; + aPixel = (unsigned short)newPixel.a; + + ((unsigned short *)image->data)[y*image->width + x] = (rPixel << (gBpp + bBpp + aBpp)) | (gPixel << (bBpp + aBpp)) | (bPixel << aBpp) | aPixel; + } + } + + free(pixels); + } +} + // Modify image color: tint void ImageColorTint(Image *image, Color color) { @@ -1359,6 +1413,7 @@ void ImageColorBrightness(Image *image, int brightness) image->data = processed.data; } +#endif // SUPPORT_IMAGE_MANIPULATION // Generate GPU mipmaps for a texture void GenTextureMipmaps(Texture2D *texture) @@ -1547,6 +1602,7 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V // Module specific Functions Definition //---------------------------------------------------------------------------------- +#if defined(SUPPORT_FILEFORMAT_DDS) // Loading DDS image data (compressed or uncompressed) static Image LoadDDS(const char *fileName) { @@ -1744,7 +1800,9 @@ static Image LoadDDS(const char *fileName) return image; } +#endif +#if defined(SUPPORT_FILEFORMAT_PKM) // Loading PKM image data (ETC1/ETC2 compression) // NOTE: KTX is the standard Khronos Group compression format (ETC1/ETC2, mipmaps) // PKM is a much simpler file format used mainly to contain a single ETC1/ETC2 compressed image (no mipmaps) @@ -1836,7 +1894,9 @@ static Image LoadPKM(const char *fileName) return image; } +#endif +#if defined(SUPPORT_FILEFORMAT_KTX) // Load KTX compressed image data (ETC1/ETC2 compression) static Image LoadKTX(const char *fileName) { @@ -1929,7 +1989,9 @@ static Image LoadKTX(const char *fileName) return image; } +#endif +#if defined(SUPPORT_FILEFORMAT_PVR) // Loading PVR image data (uncompressed or PVRT compression) // NOTE: PVR v2 not supported, use PVR v3 instead static Image LoadPVR(const char *fileName) @@ -2087,7 +2149,9 @@ static Image LoadPVR(const char *fileName) return image; } +#endif +#if defined(SUPPORT_FILEFORMAT_ASTC) // Load ASTC compressed image data (ASTC compression) static Image LoadASTC(const char *fileName) { @@ -2170,3 +2234,4 @@ static Image LoadASTC(const char *fileName) return image; } +#endif \ No newline at end of file diff --git a/src/utils.c b/src/utils.c index 4d30cbc7..b6b309cc 100644 --- a/src/utils.c +++ b/src/utils.c @@ -20,7 +20,7 @@ * Show TraceLog() DEBUG messages * * DEPENDENCIES: -* stb_image_write - PNG writting functions +* stb_image_write - BMP/PNG writting functions * * * LICENSE: zlib/libpng