aboutsummaryrefslogtreecommitdiff
path: root/src/textures.c
diff options
context:
space:
mode:
authorRay <raysan5@gmail.com>2019-02-15 17:58:00 +0100
committerGitHub <noreply@github.com>2019-02-15 17:58:00 +0100
commit8a21830b77eaa76ffe0c31df5f96aecd6bd2eecc (patch)
tree2d6f216f70e43ed477c14cf5a1d6a224ed7df379 /src/textures.c
parentbc86b0f78b3f901ddc688f55915d260359f0da15 (diff)
parenteed69d41271a597c9753605da77281f93231d4f8 (diff)
downloadraylib-8a21830b77eaa76ffe0c31df5f96aecd6bd2eecc.tar.gz
raylib-8a21830b77eaa76ffe0c31df5f96aecd6bd2eecc.zip
Merge pull request #755 from neonmoe/fix-config-flags
Fix config.h flags
Diffstat (limited to 'src/textures.c')
-rw-r--r--src/textures.c258
1 files changed, 139 insertions, 119 deletions
diff --git a/src/textures.c b/src/textures.c
index bd47fc81..5edd7201 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -182,7 +182,11 @@ Image LoadImage(const char *fileName)
{
Image image = { 0 };
+#if defined(SUPPORT_FILEFORMAT_PNG)
if ((IsFileExtension(fileName, ".png"))
+#else
+ if ((false)
+#endif
#if defined(SUPPORT_FILEFORMAT_BMP)
|| (IsFileExtension(fileName, ".bmp"))
#endif
@@ -398,90 +402,6 @@ Texture2D LoadTextureFromImage(Image image)
return texture;
}
-// Load cubemap from image, multiple image cubemap layouts supported
-TextureCubemap LoadTextureCubemap(Image image, int layoutType)
-{
- TextureCubemap cubemap = { 0 };
-
- if (layoutType == CUBEMAP_AUTO_DETECT) // Try to automatically guess layout type
- {
- // Check image width/height to determine the type of cubemap provided
- if (image.width > image.height)
- {
- if ((image.width/6) == image.height) { layoutType = CUBEMAP_LINE_HORIZONTAL; cubemap.width = image.width/6; }
- else if ((image.width/4) == (image.height/3)) { layoutType = CUBEMAP_CROSS_FOUR_BY_THREE; cubemap.width = image.width/4; }
- else if (image.width >= (int)((float)image.height*1.85f)) { layoutType = CUBEMAP_PANORAMA; cubemap.width = image.width/4; }
- }
- else if (image.height > image.width)
- {
- if ((image.height/6) == image.width) { layoutType = CUBEMAP_LINE_VERTICAL; cubemap.width = image.height/6; }
- else if ((image.width/3) == (image.height/4)) { layoutType = CUBEMAP_CROSS_THREE_BY_FOUR; cubemap.width = image.width/3; }
- }
-
- cubemap.height = cubemap.width;
- }
-
- int size = cubemap.width;
-
- if (layoutType != CUBEMAP_AUTO_DETECT)
- {
- //unsigned int dataSize = GetPixelDataSize(size, size, format);
- //void *facesData = malloc(size*size*dataSize*6); // Get memory for 6 faces in a column
-
- Image faces = { 0 }; // Vertical column image
- Rectangle faceRecs[6] = { 0 }; // Face source rectangles
- for (int i = 0; i < 6; i++) faceRecs[i] = (Rectangle){ 0, 0, size, size };
-
- if (layoutType == CUBEMAP_LINE_VERTICAL)
- {
- faces = image;
- for (int i = 0; i < 6; i++) faceRecs[i].y = size*i;
- }
- else if (layoutType == CUBEMAP_PANORAMA)
- {
- // TODO: Convert panorama image to square faces...
- }
- else
- {
- if (layoutType == CUBEMAP_LINE_HORIZONTAL) for (int i = 0; i < 6; i++) faceRecs[i].x = size*i;
- else if (layoutType == CUBEMAP_CROSS_THREE_BY_FOUR)
- {
- faceRecs[0].x = size; faceRecs[0].y = size;
- faceRecs[1].x = size; faceRecs[1].y = 3*size;
- faceRecs[2].x = size; faceRecs[2].y = 0;
- faceRecs[3].x = size; faceRecs[3].y = 2*size;
- faceRecs[4].x = 0; faceRecs[4].y = size;
- faceRecs[5].x = 2*size; faceRecs[5].y = size;
- }
- else if (layoutType == CUBEMAP_CROSS_FOUR_BY_THREE)
- {
- faceRecs[0].x = 2*size; faceRecs[0].y = size;
- faceRecs[1].x = 0; faceRecs[1].y = size;
- faceRecs[2].x = size; faceRecs[2].y = 0;
- faceRecs[3].x = size; faceRecs[3].y = 2*size;
- faceRecs[4].x = size; faceRecs[4].y = size;
- faceRecs[5].x = 3*size; faceRecs[5].y = size;
- }
-
- // Convert image data to 6 faces in a vertical column, that's the optimum layout for loading
- faces = GenImageColor(size, size*6, MAGENTA);
- ImageFormat(&faces, image.format);
-
- // TODO: Image formating does not work with compressed textures!
- }
-
- for (int i = 0; i < 6; i++) ImageDraw(&faces, image, faceRecs[i], (Rectangle){ 0, size*i, size, size });
-
- cubemap.id = rlLoadTextureCubemap(faces.data, size, faces.format);
- if (cubemap.id == 0) TraceLog(LOG_WARNING, "Cubemap image could not be loaded.");
-
- UnloadImage(faces);
- }
- else TraceLog(LOG_WARNING, "Cubemap image layout can not be detected.");
-
- return cubemap;
-}
-
// Load texture for rendering (framebuffer)
// NOTE: Render texture is loaded by default with RGBA color attachment and depth RenderBuffer
RenderTexture2D LoadRenderTexture(int width, int height)
@@ -825,14 +745,27 @@ void ExportImage(Image image, const char *fileName)
{
int success = 0;
+#if defined(SUPPORT_IMAGE_EXPORT)
// NOTE: Getting Color array as RGBA unsigned char values
unsigned char *imgData = (unsigned char *)GetImageData(image);
+#if defined(SUPPORT_FILEFORMAT_PNG)
if (IsFileExtension(fileName, ".png")) success = stbi_write_png(fileName, image.width, image.height, 4, imgData, image.width*4);
+#else
+ if (false) {}
+#endif
+#if defined(SUPPORT_FILEFORMAT_BMP)
else if (IsFileExtension(fileName, ".bmp")) success = stbi_write_bmp(fileName, image.width, image.height, 4, imgData);
+#endif
+#if defined(SUPPORT_FILEFORMAT_TGA)
else if (IsFileExtension(fileName, ".tga")) success = stbi_write_tga(fileName, image.width, image.height, 4, imgData);
+#endif
+#if defined(SUPPORT_FILEFORMAT_JPG)
else if (IsFileExtension(fileName, ".jpg")) success = stbi_write_jpg(fileName, image.width, image.height, 4, imgData, 80); // JPG quality: between 1 and 100
+#endif
+#if defined(SUPPORT_FILEFORMAT_KTX)
else if (IsFileExtension(fileName, ".ktx")) success = SaveKTX(image, fileName);
+#endif
else if (IsFileExtension(fileName, ".raw"))
{
// Export raw pixel data (without header)
@@ -842,10 +775,11 @@ void ExportImage(Image image, const char *fileName)
fclose(rawFile);
}
+ free(imgData);
+#endif
+
if (success != 0) TraceLog(LOG_INFO, "Image exported successfully: %s", fileName);
else TraceLog(LOG_WARNING, "Image could not be exported.");
-
- free(imgData);
}
// Export image as code file (.h) defining an array of bytes
@@ -1133,7 +1067,9 @@ void ImageFormat(Image *image, int newFormat)
if (image->mipmaps > 1)
{
image->mipmaps = 1;
+ #if defined(SUPPORT_IMAGE_MANIPULATION)
if (image->data != NULL) ImageMipmaps(image);
+ #endif
}
}
else TraceLog(LOG_WARNING, "Image data format is compressed, can not be converted");
@@ -1202,38 +1138,6 @@ void ImageAlphaClear(Image *image, Color color, float threshold)
ImageFormat(image, prevFormat);
}
-// Crop image depending on alpha value
-void ImageAlphaCrop(Image *image, float threshold)
-{
- Color *pixels = GetImageData(*image);
-
- int xMin = 65536; // Define a big enough number
- int xMax = 0;
- int yMin = 65536;
- int yMax = 0;
-
- for (int y = 0; y < image->height; y++)
- {
- for (int x = 0; x < image->width; x++)
- {
- if (pixels[y*image->width + x].a > (unsigned char)(threshold*255.0f))
- {
- if (x < xMin) xMin = x;
- if (x > xMax) xMax = x;
- if (y < yMin) yMin = y;
- if (y > yMax) yMax = y;
- }
- }
- }
-
- Rectangle crop = { xMin, yMin, (xMax + 1) - xMin, (yMax + 1) - yMin };
-
- free(pixels);
-
- // Check for not empty image brefore cropping
- if (!((xMax < xMin) || (yMax < yMin))) ImageCrop(image, crop);
-}
-
// Premultiply alpha channel
void ImageAlphaPremultiply(Image *image)
{
@@ -1259,6 +1163,90 @@ void ImageAlphaPremultiply(Image *image)
#if defined(SUPPORT_IMAGE_MANIPULATION)
+// Load cubemap from image, multiple image cubemap layouts supported
+TextureCubemap LoadTextureCubemap(Image image, int layoutType)
+{
+ TextureCubemap cubemap = { 0 };
+
+ if (layoutType == CUBEMAP_AUTO_DETECT) // Try to automatically guess layout type
+ {
+ // Check image width/height to determine the type of cubemap provided
+ if (image.width > image.height)
+ {
+ if ((image.width/6) == image.height) { layoutType = CUBEMAP_LINE_HORIZONTAL; cubemap.width = image.width/6; }
+ else if ((image.width/4) == (image.height/3)) { layoutType = CUBEMAP_CROSS_FOUR_BY_THREE; cubemap.width = image.width/4; }
+ else if (image.width >= (int)((float)image.height*1.85f)) { layoutType = CUBEMAP_PANORAMA; cubemap.width = image.width/4; }
+ }
+ else if (image.height > image.width)
+ {
+ if ((image.height/6) == image.width) { layoutType = CUBEMAP_LINE_VERTICAL; cubemap.width = image.height/6; }
+ else if ((image.width/3) == (image.height/4)) { layoutType = CUBEMAP_CROSS_THREE_BY_FOUR; cubemap.width = image.width/3; }
+ }
+
+ cubemap.height = cubemap.width;
+ }
+
+ int size = cubemap.width;
+
+ if (layoutType != CUBEMAP_AUTO_DETECT)
+ {
+ //unsigned int dataSize = GetPixelDataSize(size, size, format);
+ //void *facesData = malloc(size*size*dataSize*6); // Get memory for 6 faces in a column
+
+ Image faces = { 0 }; // Vertical column image
+ Rectangle faceRecs[6] = { 0 }; // Face source rectangles
+ for (int i = 0; i < 6; i++) faceRecs[i] = (Rectangle){ 0, 0, size, size };
+
+ if (layoutType == CUBEMAP_LINE_VERTICAL)
+ {
+ faces = image;
+ for (int i = 0; i < 6; i++) faceRecs[i].y = size*i;
+ }
+ else if (layoutType == CUBEMAP_PANORAMA)
+ {
+ // TODO: Convert panorama image to square faces...
+ }
+ else
+ {
+ if (layoutType == CUBEMAP_LINE_HORIZONTAL) for (int i = 0; i < 6; i++) faceRecs[i].x = size*i;
+ else if (layoutType == CUBEMAP_CROSS_THREE_BY_FOUR)
+ {
+ faceRecs[0].x = size; faceRecs[0].y = size;
+ faceRecs[1].x = size; faceRecs[1].y = 3*size;
+ faceRecs[2].x = size; faceRecs[2].y = 0;
+ faceRecs[3].x = size; faceRecs[3].y = 2*size;
+ faceRecs[4].x = 0; faceRecs[4].y = size;
+ faceRecs[5].x = 2*size; faceRecs[5].y = size;
+ }
+ else if (layoutType == CUBEMAP_CROSS_FOUR_BY_THREE)
+ {
+ faceRecs[0].x = 2*size; faceRecs[0].y = size;
+ faceRecs[1].x = 0; faceRecs[1].y = size;
+ faceRecs[2].x = size; faceRecs[2].y = 0;
+ faceRecs[3].x = size; faceRecs[3].y = 2*size;
+ faceRecs[4].x = size; faceRecs[4].y = size;
+ faceRecs[5].x = 3*size; faceRecs[5].y = size;
+ }
+
+ // Convert image data to 6 faces in a vertical column, that's the optimum layout for loading
+ faces = GenImageColor(size, size*6, MAGENTA);
+ ImageFormat(&faces, image.format);
+
+ // TODO: Image formating does not work with compressed textures!
+ }
+
+ for (int i = 0; i < 6; i++) ImageDraw(&faces, image, faceRecs[i], (Rectangle){ 0, size*i, size, size });
+
+ cubemap.id = rlLoadTextureCubemap(faces.data, size, faces.format);
+ if (cubemap.id == 0) TraceLog(LOG_WARNING, "Cubemap image could not be loaded.");
+
+ UnloadImage(faces);
+ }
+ else TraceLog(LOG_WARNING, "Cubemap image layout can not be detected.");
+
+ return cubemap;
+}
+
// Crop an image to area defined by a rectangle
// NOTE: Security checks are performed in case rectangle goes out of bounds
void ImageCrop(Image *image, Rectangle crop)
@@ -1309,6 +1297,38 @@ void ImageCrop(Image *image, Rectangle crop)
}
}
+// Crop image depending on alpha value
+void ImageAlphaCrop(Image *image, float threshold)
+{
+ Color *pixels = GetImageData(*image);
+
+ int xMin = 65536; // Define a big enough number
+ int xMax = 0;
+ int yMin = 65536;
+ int yMax = 0;
+
+ for (int y = 0; y < image->height; y++)
+ {
+ for (int x = 0; x < image->width; x++)
+ {
+ if (pixels[y*image->width + x].a > (unsigned char)(threshold*255.0f))
+ {
+ if (x < xMin) xMin = x;
+ if (x > xMax) xMax = x;
+ if (y < yMin) yMin = y;
+ if (y > yMax) yMax = y;
+ }
+ }
+ }
+
+ Rectangle crop = { xMin, yMin, (xMax + 1) - xMin, (yMax + 1) - yMin };
+
+ free(pixels);
+
+ // Check for not empty image brefore cropping
+ if (!((xMax < xMin) || (yMax < yMin))) ImageCrop(image, crop);
+}
+
// Resize and image to new size
// NOTE: Uses stb default scaling filters (both bicubic):
// STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_CATMULLROM
@@ -2146,7 +2166,6 @@ void ImageColorReplace(Image *image, Color color, Color replace)
}
#endif // SUPPORT_IMAGE_MANIPULATION
-#if defined(SUPPORT_IMAGE_GENERATION)
// Generate image: plain color
Image GenImageColor(int width, int height, Color color)
{
@@ -2161,6 +2180,7 @@ Image GenImageColor(int width, int height, Color color)
return image;
}
+#if defined(SUPPORT_IMAGE_GENERATION)
// Generate image: vertical gradient
Image GenImageGradientV(int width, int height, Color top, Color bottom)
{