aboutsummaryrefslogtreecommitdiff
path: root/src/textures.c
diff options
context:
space:
mode:
authorraysan5 <raysan5@gmail.com>2014-09-16 22:51:31 +0200
committerraysan5 <raysan5@gmail.com>2014-09-16 22:51:31 +0200
commitfc6081fe70ab7c3b037c0ab9f38478904d3cdde2 (patch)
tree6635fd800fa673ef3fb568c6f47ebc76a2b8ad6e /src/textures.c
parent01651af08a494b1ac08c897695891ad7cf44ad47 (diff)
downloadraylib-fc6081fe70ab7c3b037c0ab9f38478904d3cdde2.tar.gz
raylib-fc6081fe70ab7c3b037c0ab9f38478904d3cdde2.zip
raylib 1.2
This is a huge update. Check CHANGELOG for details
Diffstat (limited to 'src/textures.c')
-rw-r--r--src/textures.c145
1 files changed, 121 insertions, 24 deletions
diff --git a/src/textures.c b/src/textures.c
index 39947d12..e342e21b 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -1,4 +1,4 @@
-/*********************************************************************************************
+/**********************************************************************************************
*
* raylib.textures
*
@@ -6,8 +6,9 @@
*
* Uses external lib:
* stb_image - Multiple formats image loading (JPEG, PNG, BMP, TGA, PSD, GIF, PIC)
+* NOTE: stb_image has been slightly modified, original library: https://github.com/nothings/stb
*
-* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
+* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -30,15 +31,12 @@
#include <stdlib.h> // Declares malloc() and free() for memory management
#include <string.h> // Required for strcmp(), strrchr(), strncmp()
-#include "stb_image.h" // Used to read image data (multiple formats support)
-#include "utils.h" // rRES data decompression utility function
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
+#include "utils.h" // rRES data decompression utility function
+ // NOTE: Includes Android fopen function map
-// Security check in case no USE_OPENGL_* defined
-#if !defined(USE_OPENGL_11) && !defined(USE_OPENGL_33) && !defined(USE_OPENGL_ES2)
- #define USE_OPENGL_11
-#endif
+#include "stb_image.h" // Used to read image data (multiple formats support)
//----------------------------------------------------------------------------------
// Defines and Macros
@@ -73,7 +71,8 @@ typedef struct {
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
-static ImageEx LoadDDS(const char *fileName);
+static ImageEx LoadDDS(const char *fileName); // Load DDS file
+static ImageEx LoadPKM(const char *fileName); // Load PKM file
//----------------------------------------------------------------------------------
// Module Functions Definition
@@ -155,14 +154,18 @@ Image LoadImage(const char *fileName)
free(imageDDS.data);
- TraceLog(INFO, "[%s] Image loaded successfully", fileName);
+ TraceLog(INFO, "[%s] DDS Image loaded successfully (uncompressed, no mipmaps)", fileName);
}
- else TraceLog(WARNING, "[%s] Compressed image data could not be loaded", fileName);
+ else TraceLog(WARNING, "[%s] DDS Compressed image data could not be loaded", fileName);
+ }
+ else if (strcmp(GetExtension(fileName),"pkm") == 0)
+ {
+ TraceLog(INFO, "[%s] PKM Compressed image data could not be loaded", fileName);
}
else TraceLog(WARNING, "[%s] Image extension not recognized, it can't be loaded", fileName);
// ALTERNATIVE: We can load pixel data directly into Color struct pixels array,
- // to do that struct data alignment should be the right one (4 byte); it is.
+ // to do that, struct data alignment should be the right one (4 byte); it is.
//image.pixels = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
return image;
@@ -302,9 +305,7 @@ Texture2D LoadTexture(const char *fileName)
}
else
{
-#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
texture.id = rlglLoadCompressedTexture(image.data, image.width, image.height, image.mipmaps, image.compFormat);
-#endif
}
texture.width = image.width;
@@ -315,6 +316,20 @@ Texture2D LoadTexture(const char *fileName)
free(image.data);
}
+ else if (strcmp(GetExtension(fileName),"pkm") == 0)
+ {
+ ImageEx image = LoadPKM(fileName);
+
+ texture.id = rlglLoadCompressedTexture(image.data, image.width, image.height, image.mipmaps, image.compFormat);
+
+ texture.width = image.width;
+ texture.height = image.height;
+
+ if (texture.id == 0) TraceLog(WARNING, "[%s] PKM texture could not be loaded", fileName);
+ else TraceLog(INFO, "[%s] PKM texture loaded successfully", fileName);
+
+ free(image.data);
+ }
else
{
Image image = LoadImage(fileName);
@@ -453,8 +468,6 @@ Texture2D CreateTexture(Image image, bool genMipmaps)
texture.width = image.width;
texture.height = image.height;
- TraceLog(INFO, "[ID %i] Texture created successfully", texture.id);
-
free(imgData);
}
else TraceLog(WARNING, "Texture could not be created, image data is not valid");
@@ -471,15 +484,15 @@ ImageEx LoadDDS(const char *fileName)
#define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII
#ifndef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
- #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+ #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
#endif
#ifndef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
- #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
+ #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
#endif
#ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
- #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
+ #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
#endif
// DDS Pixel Format
@@ -582,11 +595,9 @@ ImageEx LoadDDS(const char *fileName)
}
else if ((header.ddspf.flags == 0x04) && (header.ddspf.fourCC > 0))
{
-#ifdef USE_OPENGL_11
- TraceLog(WARNING, "[%s] DDS image uses compression, not supported by current OpenGL version", fileName);
+ TraceLog(WARNING, "[%s] DDS image uses compression, not supported on OpenGL 1.1", fileName);
TraceLog(WARNING, "[%s] DDS compressed files require OpenGL 3.2+ or ES 2.0", fileName);
- fclose(ddsFile);
-#else
+
int bufsize;
// Calculate data size, including all mipmaps
@@ -614,10 +625,96 @@ ImageEx LoadDDS(const char *fileName)
// NOTE: Image num color components not required... for now...
//if (fourCC == FOURCC_DXT1) image.components = 3;
//else image.components = 4;
-#endif
}
}
}
return image;
+}
+
+// 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)
+ImageEx LoadPKM(const char *fileName)
+{
+ // If OpenGL ES 2.0. the following format could be supported (ETC1):
+ //GL_ETC1_RGB8_OES
+
+ #ifndef GL_ETC1_RGB8_OES
+ #define GL_ETC1_RGB8_OES 0x8D64
+ #endif
+
+ // If OpenGL ES 3.0, the following formats are supported (ETC2/EAC):
+ //GL_COMPRESSED_RGB8_ETC2
+ //GL_COMPRESSED_RGBA8_ETC2
+ //GL_COMPRESSED_RG11_EAC
+ //...
+
+ // PKM file (ETC1) Header (16 bytes)
+ typedef struct {
+ char id[4]; // "PKM "
+ char version[2]; // "10"
+ unsigned short format; // Format = number of mipmaps = 0 (ETC1_RGB_NO_MIPMAPS)
+ unsigned short extWidth; // Texture width (big-endian)
+ unsigned short extHeight; // Texture height (big-endian)
+ unsigned short origWidth; // Original width (big-endian)
+ unsigned short origHeight; // Original height (big-endian)
+ } pkmHeader;
+
+ // NOTE: The extended width and height are the widths rounded up to a multiple of 4.
+ // NOTE: ETC is always 4bit per pixel (64 bits for each 4x4 block of pixels)
+
+ // Bytes Swap (little-endian <-> big-endian)
+ //unsigned short data;
+ //unsigned short swap = ((data & 0x00FF) << 8) | ((data & 0xFF00) >> 8);
+
+ ImageEx image;
+
+ unsigned short width;
+ unsigned short height;
+ unsigned short useless;
+
+ FILE *pkmFile = fopen(fileName, "rb");
+
+ if (pkmFile == NULL)
+ {
+ TraceLog(WARNING, "[%s] PKM File could not be opened", fileName);
+ }
+ else
+ {
+ // Verify the type of file
+ char filecode[4];
+
+ fread(filecode, 1, 4, pkmFile);
+
+ if (strncmp(filecode, "PKM ", 4) != 0)
+ {
+ TraceLog(WARNING, "[%s] PKM File does not seem to be valid", fileName);
+ fclose(pkmFile);
+ }
+ else
+ {
+ // Get the surface descriptor
+ fread(&useless, sizeof(unsigned short), 1, pkmFile); // Discard version
+ fread(&useless, sizeof(unsigned short), 1, pkmFile); // Discard format
+
+ fread(&width, sizeof(unsigned short), 1, pkmFile); // Read extended width
+ fread(&height, sizeof(unsigned short), 1, pkmFile); // Read extended height
+
+ int size = (width/4)*(height/4)*8; // Total data size in bytes
+
+ image.data = (unsigned char*)malloc(size * sizeof(unsigned char));
+
+ fread(image.data, 1, size, pkmFile);
+
+ fclose(pkmFile); // Close file pointer
+
+ image.width = width;
+ image.height = height;
+ image.mipmaps = 1;
+ image.compFormat = GL_ETC1_RGB8_OES;
+ }
+ }
+
+ return image;
} \ No newline at end of file