diff --git a/src/raylib.h b/src/raylib.h index a2f286611..c44653e8d 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -341,7 +341,7 @@ typedef struct Image { int width; // Image base width int height; // Image base height int mipmaps; // Mipmap levels, 1 by default - int format; // Data format (TextureFormat type) + int format; // Data format (PixelFormat type) } Image; // Texture2D type @@ -351,7 +351,7 @@ typedef struct Texture2D { int width; // Texture base width int height; // Texture base height int mipmaps; // Mipmap levels, 1 by default - int format; // Data format (TextureFormat type) + int format; // Data format (PixelFormat type) } Texture2D; // RenderTexture2D type, for texture rendering @@ -571,18 +571,19 @@ typedef enum { #define MAP_DIFFUSE MAP_ALBEDO #define MAP_SPECULAR MAP_METALNESS -// Texture formats +// Pixel formats // NOTE: Support depends on OpenGL version and platform typedef enum { UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) - UNCOMPRESSED_GRAY_ALPHA, // 16 bpp (2 channels) + UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels) UNCOMPRESSED_R5G6B5, // 16 bpp UNCOMPRESSED_R8G8B8, // 24 bpp UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha) UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha) UNCOMPRESSED_R8G8B8A8, // 32 bpp - UNCOMPRESSED_R32G32B32, // 32 bit per channel (float) - HDR - UNCOMPRESSED_R32G32B32A32, // 32 bit per channel (float) - HDR + UNCOMPRESSED_R32, // 32 bpp (1 channel - float) + UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float) + UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float) COMPRESSED_DXT1_RGB, // 4 bpp (no alpha) COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha) COMPRESSED_DXT3_RGBA, // 8 bpp @@ -594,7 +595,7 @@ typedef enum { COMPRESSED_PVRT_RGBA, // 4 bpp COMPRESSED_ASTC_4x4_RGBA, // 8 bpp COMPRESSED_ASTC_8x8_RGBA // 2 bpp -} TextureFormat; +} PixelFormat; // Texture parameters: filter mode // NOTE 1: Filtering considers mipmaps if available in the texture diff --git a/src/rlgl.c b/src/rlgl.c index 4bbebf030..e7ab7cd73 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -1420,6 +1420,7 @@ unsigned int rlLoadTexture(void *data, int width, int height, int format, int mi case COMPRESSED_DXT5_RGBA: if (texCompDXTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, mipmapCount); break; #endif #if defined(GRAPHICS_API_OPENGL_ES2) + case UNCOMPRESSED_R32: if (texFloatSupported) glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_RGB, GL_FLOAT, (float *)data); break; // NOTE: Requires extension OES_texture_float case UNCOMPRESSED_R32G32B32: if (texFloatSupported) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_FLOAT, (float *)data); break; // NOTE: Requires extension OES_texture_float case UNCOMPRESSED_R32G32B32A32: if (texFloatSupported) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_FLOAT, (float *)data); break; // NOTE: Requires extension OES_texture_float case COMPRESSED_DXT1_RGB: if (texCompDXTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, mipmapCount); break; @@ -1475,6 +1476,7 @@ unsigned int rlLoadTexture(void *data, int width, int height, int format, int mi case UNCOMPRESSED_R5G5B5A1: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, (unsigned short *)data); break; case UNCOMPRESSED_R4G4B4A4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, (unsigned short *)data); break; case UNCOMPRESSED_R8G8B8A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data); break; + case UNCOMPRESSED_R32: if (texFloatSupported) glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RGB, GL_FLOAT, (float *)data); break; case UNCOMPRESSED_R32G32B32: if (texFloatSupported) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_FLOAT, (float *)data); break; case UNCOMPRESSED_R32G32B32A32: if (texFloatSupported) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGB, GL_FLOAT, (float *)data); break; case COMPRESSED_DXT1_RGB: if (texCompDXTSupported) LoadTextureCompressed((unsigned char *)data, width, height, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, mipmapCount); break; diff --git a/src/rlgl.h b/src/rlgl.h index 0e4a5d74d..68d8d4eb6 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -169,7 +169,7 @@ typedef unsigned char byte; int width; // Texture base width int height; // Texture base height int mipmaps; // Mipmap levels, 1 by default - int format; // Data format (TextureFormat) + int format; // Data format (PixelFormat) } Texture2D; // RenderTexture2D type, for texture rendering @@ -259,8 +259,9 @@ typedef unsigned char byte; UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha) UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha) UNCOMPRESSED_R8G8B8A8, // 32 bpp - UNCOMPRESSED_R32G32B32, // 32 bit per channel (float) - HDR - UNCOMPRESSED_R32G32B32A32, // 32 bit per channel (float) - HDR + UNCOMPRESSED_R32, // 32 bpp (1 channel - float) + UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float) + UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float) COMPRESSED_DXT1_RGB, // 4 bpp (no alpha) COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha) COMPRESSED_DXT3_RGBA, // 8 bpp @@ -272,7 +273,7 @@ typedef unsigned char byte; COMPRESSED_PVRT_RGBA, // 4 bpp COMPRESSED_ASTC_4x4_RGBA, // 8 bpp COMPRESSED_ASTC_8x8_RGBA // 2 bpp - } TextureFormat; + } PixelFormat; // Texture parameters: filter mode // NOTE 1: Filtering considers mipmaps if available in the texture diff --git a/src/textures.c b/src/textures.c index 9abee62bc..7ea54c2c9 100644 --- a/src/textures.c +++ b/src/textures.c @@ -226,11 +226,11 @@ Image LoadImage(const char *fileName) image.mipmaps = 1; - if (imgBpp == 3) image.format = UNCOMPRESSED_R32G32B32; + if (imgBpp == 1) image.format = UNCOMPRESSED_R32; + else if (imgBpp == 3) image.format = UNCOMPRESSED_R32G32B32; else if (imgBpp == 4) image.format = UNCOMPRESSED_R32G32B32A32; else { - // TODO: Support different number of channels at 32 bit float TraceLog(LOG_WARNING, "[%s] Image fileformat not supported", fileName); UnloadImage(image); } @@ -318,21 +318,9 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int { if (headerSize > 0) fseek(rawFile, headerSize, SEEK_SET); - unsigned int size = width*height; - - switch (format) - { - case UNCOMPRESSED_GRAYSCALE: image.data = (unsigned char *)malloc(size); break; // 8 bit per pixel (no alpha) - case UNCOMPRESSED_GRAY_ALPHA: image.data = (unsigned char *)malloc(size*2); size *= 2; break; // 16 bpp (2 channels) - case UNCOMPRESSED_R5G6B5: image.data = (unsigned short *)malloc(size); break; // 16 bpp - case UNCOMPRESSED_R8G8B8: image.data = (unsigned char *)malloc(size*3); size *= 3; break; // 24 bpp - case UNCOMPRESSED_R5G5B5A1: image.data = (unsigned short *)malloc(size); break; // 16 bpp (1 bit alpha) - case UNCOMPRESSED_R4G4B4A4: image.data = (unsigned short *)malloc(size); break; // 16 bpp (4 bit alpha) - case UNCOMPRESSED_R8G8B8A8: image.data = (unsigned char *)malloc(size*4); size *= 4; break; // 32 bpp - case UNCOMPRESSED_R32G32B32: image.data = (float *)malloc(size*12); size *= 12; break; // 4 byte per channel (12 byte) - case UNCOMPRESSED_R32G32B32A32: image.data = (float *)malloc(size*16); size *= 16; break; // 4 byte per channel (16 byte) - default: TraceLog(LOG_WARNING, "Image format not suported"); break; - } + unsigned int size = GetPixelDataSize(width, height, format); + + image.data = malloc(size); // Allocate required memory in bytes // NOTE: fread() returns num read elements instead of bytes, // to get bytes we need to read (1 byte size, elements) instead of (x byte size, 1 element) @@ -531,6 +519,7 @@ int GetPixelDataSize(int width, int height, int format) case UNCOMPRESSED_R4G4B4A4: bpp = 16; break; case UNCOMPRESSED_R8G8B8A8: bpp = 32; break; case UNCOMPRESSED_R8G8B8: bpp = 24; break; + case UNCOMPRESSED_R32: bpp = 32; break; case UNCOMPRESSED_R32G32B32: bpp = 32*3; break; case UNCOMPRESSED_R32G32B32A32: bpp = 32*4; break; case COMPRESSED_DXT1_RGB: @@ -727,6 +716,15 @@ void ImageFormat(Image *image, int newFormat) k++; } } break; + case UNCOMPRESSED_R32: + { + image->data = (float *)malloc(image->width*image->height*sizeof(float)); + + for (int i = 0; i < image->width*image->height; i++) + { + ((float *)image->data)[i] = (float)((float)pixels[i].r*0.299f/255.0f + (float)pixels[i].g*0.587f/255.0f + (float)pixels[i].b*0.114f/255.0f); + } + } break; case UNCOMPRESSED_R32G32B32: { image->data = (float *)malloc(image->width*image->height*3*sizeof(float)); @@ -858,39 +856,14 @@ Image ImageCopy(Image image) { Image newImage = { 0 }; - int byteSize = image.width*image.height; - - switch (image.format) - { - case UNCOMPRESSED_GRAYSCALE: break; // 8 bpp (1 byte) - case UNCOMPRESSED_GRAY_ALPHA: // 16 bpp - case UNCOMPRESSED_R5G6B5: // 16 bpp - case UNCOMPRESSED_R5G5B5A1: // 16 bpp - case UNCOMPRESSED_R4G4B4A4: byteSize *= 2; break; // 16 bpp (2 bytes) - case UNCOMPRESSED_R8G8B8: byteSize *= 3; break; // 24 bpp (3 bytes) - case UNCOMPRESSED_R8G8B8A8: byteSize *= 4; break; // 32 bpp (4 bytes) - case UNCOMPRESSED_R32G32B32: byteSize *= 12; break; // 4 byte per channel (12 bytes) - case UNCOMPRESSED_R32G32B32A32: byteSize *= 16; break; // 4 byte per channel (16 bytes) - case COMPRESSED_DXT3_RGBA: - case COMPRESSED_DXT5_RGBA: - case COMPRESSED_ETC2_EAC_RGBA: - case COMPRESSED_ASTC_4x4_RGBA: break; // 8 bpp (1 byte) - case COMPRESSED_DXT1_RGB: - case COMPRESSED_DXT1_RGBA: - case COMPRESSED_ETC1_RGB: - case COMPRESSED_ETC2_RGB: - case COMPRESSED_PVRT_RGB: - case COMPRESSED_PVRT_RGBA: byteSize /= 2; break; // 4 bpp - case COMPRESSED_ASTC_8x8_RGBA: byteSize /= 4; break;// 2 bpp - default: TraceLog(LOG_WARNING, "Image format not recognized"); break; - } + int size = GetPixelDataSize(image.width, image.height, image.format); - newImage.data = malloc(byteSize); + newImage.data = malloc(size); if (newImage.data != NULL) { // NOTE: Size must be provided in bytes - memcpy(newImage.data, image.data, byteSize); + memcpy(newImage.data, image.data, size); newImage.width = image.width; newImage.height = image.height;