mirror of
https://github.com/raysan5/raylib.git
synced 2025-12-25 10:22:33 -05:00
raylib 1.2
This is a huge update. Check CHANGELOG for details
This commit is contained in:
145
src/textures.c
145
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;
|
||||
}
|
||||
Reference in New Issue
Block a user