Merge pull request #5 from raysan5/master

merge
This commit is contained in:
Murray Campbell 2018-09-21 18:09:53 -05:00 committed by GitHub
commit c015529088
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 3791 additions and 606 deletions

View File

@ -7,7 +7,7 @@ Use your best judgement, and feel free to propose changes to this document in a
### raylib philosophy ### raylib philosophy
- raylib is a tool to LEARN videogames programming, every single function in raylib should be a tutorial on itself. - raylib is a tool to enjoy videogames programming, every single function in raylib should be a tutorial on itself.
- raylib is SIMPLE and EASY-TO-USE, I tried to keep it compact with a small set of functions, if a function is too complex or is not clearly useful, better not to include it. - raylib is SIMPLE and EASY-TO-USE, I tried to keep it compact with a small set of functions, if a function is too complex or is not clearly useful, better not to include it.
- raylib is open source and free; educators and institutions can use this tool to TEACH videogames programming completely by free. - raylib is open source and free; educators and institutions can use this tool to TEACH videogames programming completely by free.
- raylib is collaborative; contribution of tutorials / code-examples / bugs-solving / code-comments are highly appreciated. - raylib is collaborative; contribution of tutorials / code-examples / bugs-solving / code-comments are highly appreciated.

View File

@ -18,7 +18,7 @@ with a small [donation](http://www.raylib.com/helpme.html) or contributing with
raylib philosophy raylib philosophy
------------------ ------------------
* raylib is a tool to LEARN videogames programming, every single function in raylib should be a tutorial on itself. * raylib is a tool to enjoy videogames programming, every single function in raylib should be a tutorial on itself.
* raylib is SIMPLE and EASY-TO-USE, I tried to keep it compact with a small set of functions, if a function is too complex or has not a clear usefulness, better not to include it. * raylib is SIMPLE and EASY-TO-USE, I tried to keep it compact with a small set of functions, if a function is too complex or has not a clear usefulness, better not to include it.
* raylib is open source and free; educators and institutions can use this tool to TEACH videogames programming completely by free. * raylib is open source and free; educators and institutions can use this tool to TEACH videogames programming completely by free.
* raylib is collaborative; contribution of tutorials / code-examples / bugs-solving / code-comments are highly appreciated. * raylib is collaborative; contribution of tutorials / code-examples / bugs-solving / code-comments are highly appreciated.

View File

@ -1,12 +1,12 @@
<img align="left" src="https://github.com/raysan5/raylib/blob/master/logo/raylib_256x256.png" width=256> <img align="left" src="https://github.com/raysan5/raylib/blob/master/logo/raylib_256x256.png" width=256>
**raylib is a simple and easy-to-use library to learn videogames programming.** **raylib is a simple and easy-to-use library to enjoy videogames programming.**
raylib is highly inspired by Borland BGI graphics lib and by XNA framework. raylib is highly inspired by Borland BGI graphics lib and by XNA framework.
raylib could be useful for prototyping, tools development, graphic applications, embedded systems and education. raylib could be useful for prototyping, tools development, graphic applications, embedded systems and education.
NOTE for ADVENTURERS: raylib is a programming library to learn videogames programming; NOTE for ADVENTURERS: raylib is a programming library to enjoy videogames programming;
no fancy interface, no visual helpers, no auto-debugging... just coding in the most no fancy interface, no visual helpers, no auto-debugging... just coding in the most
pure spartan-programmers way. Are you ready to learn? Jump to [code examples!](http://www.raylib.com/examples.html) pure spartan-programmers way. Are you ready to learn? Jump to [code examples!](http://www.raylib.com/examples.html)

View File

@ -29,19 +29,18 @@ int main()
fontDefault.baseSize = 16; fontDefault.baseSize = 16;
fontDefault.charsCount = 95; fontDefault.charsCount = 95;
// Parameters > font size: 16, no chars array provided (0), chars count: 95 (autogenerate chars array) // Parameters > font size: 16, no chars array provided (0), chars count: 95 (autogenerate chars array)
fontDefault.chars = LoadFontData("resources/AnonymousPro-Bold.ttf", 16, 0, 95, false); fontDefault.chars = LoadFontData("resources/AnonymousPro-Bold.ttf", 16, 0, 95, FONT_DEFAULT);
// Parameters > chars count: 95, font size: 16, chars padding in image: 4 px, pack method: 0 (default) // Parameters > chars count: 95, font size: 16, chars padding in image: 4 px, pack method: 0 (default)
Image atlas = GenImageFontAtlas(fontDefault.chars, 95, 16, 4, 0); Image atlas = GenImageFontAtlas(fontDefault.chars, 95, 16, 4, 0);
fontDefault.texture = LoadTextureFromImage(atlas); fontDefault.texture = LoadTextureFromImage(atlas);
UnloadImage(atlas); UnloadImage(atlas);
// SDF font generation from TTF font // SDF font generation from TTF font
// NOTE: SDF chars data is generated with LoadFontData(), it's just a bool option
Font fontSDF = { 0 }; Font fontSDF = { 0 };
fontSDF.baseSize = 16; fontSDF.baseSize = 16;
fontSDF.charsCount = 95; fontSDF.charsCount = 95;
// Parameters > font size: 16, no chars array provided (0), chars count: 0 (defaults to 95) // Parameters > font size: 16, no chars array provided (0), chars count: 0 (defaults to 95)
fontSDF.chars = LoadFontData("resources/AnonymousPro-Bold.ttf", 16, 0, 0, true); fontSDF.chars = LoadFontData("resources/AnonymousPro-Bold.ttf", 16, 0, 0, FONT_SDF);
// Parameters > chars count: 95, font size: 16, chars padding in image: 0 px, pack method: 1 (Skyline algorythm) // Parameters > chars count: 95, font size: 16, chars padding in image: 0 px, pack method: 1 (Skyline algorythm)
atlas = GenImageFontAtlas(fontSDF.chars, 95, 16, 0, 1); atlas = GenImageFontAtlas(fontSDF.chars, 95, 16, 0, 1);
fontSDF.texture = LoadTextureFromImage(atlas); fontSDF.texture = LoadTextureFromImage(atlas);

View File

@ -26,7 +26,7 @@ int main()
Image parrots = LoadImage("resources/parrots.png"); // Load image in CPU memory (RAM) Image parrots = LoadImage("resources/parrots.png"); // Load image in CPU memory (RAM)
// Draw over image using custom font // Draw over image using custom font
ImageDrawTextEx(&parrots, (Vector2){ 20.0f, 20.0f }, font, "[Parrots font drawing]", (float)font.baseSize, 0.0f, WHITE); ImageDrawTextEx(&parrots, (Vector2){ 20.0f, 20.0f }, font, "[Parrots font drawing]", (float)font.baseSize, 0.0f, RED);
Texture2D texture = LoadTextureFromImage(parrots); // Image converted to texture, uploaded to GPU memory (VRAM) Texture2D texture = LoadTextureFromImage(parrots); // Image converted to texture, uploaded to GPU memory (VRAM)
UnloadImage(parrots); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM UnloadImage(parrots); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM

View File

@ -37,7 +37,7 @@ static int framesCounter;
static int finishScreen; static int finishScreen;
const char msgLogoA[64] = "A simple and easy-to-use library"; const char msgLogoA[64] = "A simple and easy-to-use library";
const char msgLogoB[64] = "to learn videogames programming"; const char msgLogoB[64] = "to enjoy videogames programming";
int logoPositionX; int logoPositionX;
int logoPositionY; int logoPositionY;

View File

@ -37,7 +37,7 @@ static int framesCounter;
static int finishScreen; static int finishScreen;
const char msgLogoA[64] = "A simple and easy-to-use library"; const char msgLogoA[64] = "A simple and easy-to-use library";
const char msgLogoB[64] = "to learn videogames programming"; const char msgLogoB[64] = "to enjoy videogames programming";
int logoPositionX; int logoPositionX;
int logoPositionY; int logoPositionY;

View File

@ -4,7 +4,7 @@ libdir=${exec_prefix}/lib
includedir=${prefix}/include includedir=${prefix}/include
Name: raylib Name: raylib
Description: Simple and easy-to-use library to learn videogames programming Description: Simple and easy-to-use library to enjoy videogames programming
URL: http://github.com/raysan5/raylib URL: http://github.com/raysan5/raylib
Version: @PROJECT_VERSION@ Version: @PROJECT_VERSION@
Libs: -L${libdir} -lraylib @PKG_CONFIG_LIBS_EXTRA@ Libs: -L${libdir} -lraylib @PKG_CONFIG_LIBS_EXTRA@

View File

@ -259,7 +259,7 @@ message(STATUS " GRAPHICS=" ${GRAPHICS})
# Packaging # Packaging
SET(CPACK_PACKAGE_NAME "raylib") SET(CPACK_PACKAGE_NAME "raylib")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simple and easy-to-use library to learn videogames programming") SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simple and easy-to-use library to enjoy videogames programming")
SET(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") SET(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
SET(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}") SET(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
SET(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}") SET(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")

View File

@ -45,6 +45,7 @@ option(SUPPORT_FONT_TEXTURE "Draw rectangle shapes using font texture white char
option(SUPPORT_QUADS_DRAW_MODE "Use QUADS instead of TRIANGLES for drawing when possible. Some lines-based shapes could still use lines" ON) option(SUPPORT_QUADS_DRAW_MODE "Use QUADS instead of TRIANGLES for drawing when possible. Some lines-based shapes could still use lines" ON)
# textures.c # textures.c
option(SUPPORT_IMAGE_EXPORT "Support image exporting to file" ON)
option(SUPPORT_IMAGE_GENERATION "Support procedural image generation functionality (gradient, spot, perlin-noise, cellular)" ON) option(SUPPORT_IMAGE_GENERATION "Support procedural image generation functionality (gradient, spot, perlin-noise, cellular)" ON)
option(SUPPORT_FILEFORMAT_PNG "Support loading PNG as textures" ON) option(SUPPORT_FILEFORMAT_PNG "Support loading PNG as textures" ON)
option(SUPPORT_FILEFORMAT_DDS "Support loading DDS as textures" ON) option(SUPPORT_FILEFORMAT_DDS "Support loading DDS as textures" ON)
@ -72,8 +73,6 @@ option(SUPPORT_FILEFORMAT_MOD "Support loading MOD for sound" ON)
option(SUPPORT_FILEFORMAT_FLAC "Support loading FLAC for sound" ${OFF}) option(SUPPORT_FILEFORMAT_FLAC "Support loading FLAC for sound" ${OFF})
# utils.c # utils.c
option(SUPPORT_SAVE_PNG "Support saving image data in PNG file format" ON)
option(SUPPORT_SAVE_BMP "Support saving image data in BMP file format" ${OFF})
option(SUPPORT_TRACELOG "Show TraceLog() output messages. NOTE: By default LOG_DEBUG traces not shown" ON) option(SUPPORT_TRACELOG "Show TraceLog() output messages. NOTE: By default LOG_DEBUG traces not shown" ON)
option(SUPPORT_FILEFORMAT_FNT "Support loading fonts in FNT format" ON) option(SUPPORT_FILEFORMAT_FNT "Support loading fonts in FNT format" ON)

View File

@ -221,6 +221,9 @@ static Wave LoadOGG(const char *fileName); // Load OGG file
#if defined(SUPPORT_FILEFORMAT_FLAC) #if defined(SUPPORT_FILEFORMAT_FLAC)
static Wave LoadFLAC(const char *fileName); // Load FLAC file static Wave LoadFLAC(const char *fileName); // Load FLAC file
#endif #endif
#if defined(SUPPORT_FILEFORMAT_MP3)
static Wave LoadMP3(const char *fileName); // Load MP3 file
#endif
#if defined(AUDIO_STANDALONE) #if defined(AUDIO_STANDALONE)
bool IsFileExtension(const char *fileName, const char *ext); // Check file extension bool IsFileExtension(const char *fileName, const char *ext); // Check file extension
@ -857,6 +860,9 @@ Wave LoadWave(const char *fileName)
#endif #endif
#if defined(SUPPORT_FILEFORMAT_FLAC) #if defined(SUPPORT_FILEFORMAT_FLAC)
else if (IsFileExtension(fileName, ".flac")) wave = LoadFLAC(fileName); else if (IsFileExtension(fileName, ".flac")) wave = LoadFLAC(fileName);
#endif
#if defined(SUPPORT_FILEFORMAT_MP3)
else if (IsFileExtension(fileName, ".mp3")) wave = LoadMP3(fileName);
#endif #endif
else TraceLog(LOG_WARNING, "[%s] Audio fileformat not supported, it can't be loaded", fileName); else TraceLog(LOG_WARNING, "[%s] Audio fileformat not supported, it can't be loaded", fileName);
@ -1049,6 +1055,89 @@ void UpdateSound(Sound sound, const void *data, int samplesCount)
#endif #endif
} }
// Export wave data to file
void ExportWave(Wave wave, const char *fileName)
{
bool success = false;
if (IsFileExtension(fileName, ".wav"))
{
// Basic WAV headers structs
typedef struct {
char chunkID[4];
int chunkSize;
char format[4];
} RiffHeader;
typedef struct {
char subChunkID[4];
int subChunkSize;
short audioFormat;
short numChannels;
int sampleRate;
int byteRate;
short blockAlign;
short bitsPerSample;
} WaveFormat;
typedef struct {
char subChunkID[4];
int subChunkSize;
} WaveData;
RiffHeader riffHeader;
WaveFormat waveFormat;
WaveData waveData;
// Fill structs with data
riffHeader.chunkID[0] = 'R';
riffHeader.chunkID[1] = 'I';
riffHeader.chunkID[2] = 'F';
riffHeader.chunkID[3] = 'F';
riffHeader.chunkSize = 44 - 4 + wave.sampleCount*wave.sampleSize/8;
riffHeader.format[0] = 'W';
riffHeader.format[1] = 'A';
riffHeader.format[2] = 'V';
riffHeader.format[3] = 'E';
waveFormat.subChunkID[0] = 'f';
waveFormat.subChunkID[1] = 'm';
waveFormat.subChunkID[2] = 't';
waveFormat.subChunkID[3] = ' ';
waveFormat.subChunkSize = 16;
waveFormat.audioFormat = 1;
waveFormat.numChannels = wave.channels;
waveFormat.sampleRate = wave.sampleRate;
waveFormat.byteRate = wave.sampleRate*wave.sampleSize/8;
waveFormat.blockAlign = wave.sampleSize/8;
waveFormat.bitsPerSample = wave.sampleSize;
waveData.subChunkID[0] = 'd';
waveData.subChunkID[1] = 'a';
waveData.subChunkID[2] = 't';
waveData.subChunkID[3] = 'a';
waveData.subChunkSize = wave.sampleCount*wave.channels*wave.sampleSize/8;
FILE *wavFile = fopen(fileName, "wb");
if (wavFile == NULL) return;
fwrite(&riffHeader, 1, sizeof(RiffHeader), wavFile);
fwrite(&waveFormat, 1, sizeof(WaveFormat), wavFile);
fwrite(&waveData, 1, sizeof(WaveData), wavFile);
fwrite(wave.data, 1, wave.sampleCount*wave.channels*wave.sampleSize/8, wavFile);
fclose(wavFile);
success = true;
}
else if (IsFileExtension(fileName, ".raw")) { } // TODO: Support additional file formats to export wave sample data
if (success) TraceLog(LOG_INFO, "Wave exported successfully: %s", fileName);
else TraceLog(LOG_WARNING, "Wave could not be exported.");
}
// Play a sound // Play a sound
void PlaySound(Sound sound) void PlaySound(Sound sound)
{ {
@ -1565,6 +1654,9 @@ void StopMusicStream(Music music)
#if defined(SUPPORT_FILEFORMAT_FLAC) #if defined(SUPPORT_FILEFORMAT_FLAC)
case MUSIC_AUDIO_FLAC: /* TODO: Restart FLAC context */ break; case MUSIC_AUDIO_FLAC: /* TODO: Restart FLAC context */ break;
#endif #endif
#if defined(SUPPORT_FILEFORMAT_MP3)
case MUSIC_AUDIO_MP3: /* TODO: Restart MP3 context */ break;
#endif
#if defined(SUPPORT_FILEFORMAT_XM) #if defined(SUPPORT_FILEFORMAT_XM)
case MUSIC_MODULE_XM: /* TODO: Restart XM context */ break; case MUSIC_MODULE_XM: /* TODO: Restart XM context */ break;
#endif #endif
@ -1705,6 +1797,13 @@ void UpdateMusicStream(Music music)
} break; } break;
#endif #endif
#if defined(SUPPORT_FILEFORMAT_MP3)
case MUSIC_AUDIO_MP3:
{
// NOTE: Returns the number of samples to process
unsigned int numSamplesMp3 = (unsigned int)drmp3_read_f32(&music->ctxMp3, samplesCount*music->stream.channels, (float *)pcm);
} break;
#endif
#if defined(SUPPORT_FILEFORMAT_XM) #if defined(SUPPORT_FILEFORMAT_XM)
case MUSIC_MODULE_XM: jar_xm_generate_samples_16bit(music->ctxXm, pcm, samplesCount); break; case MUSIC_MODULE_XM: jar_xm_generate_samples_16bit(music->ctxXm, pcm, samplesCount); break;
#endif #endif
@ -2294,6 +2393,33 @@ static Wave LoadFLAC(const char *fileName)
} }
#endif #endif
#if defined(SUPPORT_FILEFORMAT_MP3)
// Load MP3 file into Wave structure
// NOTE: Using dr_mp3 library
static Wave LoadMP3(const char *fileName)
{
Wave wave;
// Decode an entire MP3 file in one go
uint64_t totalSampleCount;
drmp3_config *config;
wave.data = drmp3_open_and_decode_file_f32(fileName, config, &totalSampleCount);
wave.channels = config->outputChannels;
wave.sampleRate = config->outputSampleRate;
wave.sampleCount = (int)totalSampleCount/wave.channels;
wave.sampleSize = 16;
// NOTE: Only support up to 2 channels (mono, stereo)
if (wave.channels > 2) TraceLog(LOG_WARNING, "[%s] MP3 channels number (%i) not supported", fileName, wave.channels);
if (wave.data == NULL) TraceLog(LOG_WARNING, "[%s] MP3 data could not be loaded", fileName);
else TraceLog(LOG_INFO, "[%s] MP3 file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo");
return wave;
}
#endif
// Some required functions for audio standalone module version // Some required functions for audio standalone module version
#if defined(AUDIO_STANDALONE) #if defined(AUDIO_STANDALONE)
// Check file extension // Check file extension

View File

@ -86,6 +86,8 @@
//#define SUPPORT_FILEFORMAT_PKM 1 //#define SUPPORT_FILEFORMAT_PKM 1
//#define SUPPORT_FILEFORMAT_PVR 1 //#define SUPPORT_FILEFORMAT_PVR 1
// Support image export functionality (.png, .bmp, .tga, .jpg)
#define SUPPORT_IMAGE_EXPORT 1
// Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... // 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() // If not defined only three image editing functions supported: ImageFormat(), ImageAlphaMask(), ImageToPOT()
#define SUPPORT_IMAGE_MANIPULATION 1 #define SUPPORT_IMAGE_MANIPULATION 1
@ -133,10 +135,6 @@
// Show TraceLog() output messages // Show TraceLog() output messages
// NOTE: By default LOG_DEBUG traces not shown // NOTE: By default LOG_DEBUG traces not shown
#define SUPPORT_TRACELOG 1 #define SUPPORT_TRACELOG 1
// Support saving image data fileformats
// NOTE: Requires stb_image_write library
#define SUPPORT_SAVE_PNG 1
//#define SUPPORT_SAVE_BMP 1
#endif //defined(RAYLIB_CMAKE) #endif //defined(RAYLIB_CMAKE)

View File

@ -41,6 +41,9 @@
#cmakedefine SUPPORT_FILEFORMAT_PKM 1 #cmakedefine SUPPORT_FILEFORMAT_PKM 1
#cmakedefine SUPPORT_FILEFORMAT_PVR 1 #cmakedefine SUPPORT_FILEFORMAT_PVR 1
// Support image export functionality (.png, .bmp, .tga, .jpg)
#define SUPPORT_IMAGE_EXPORT 1
/* 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() */ /* 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() */
#cmakedefine SUPPORT_IMAGE_MANIPULATION 1 #cmakedefine SUPPORT_IMAGE_MANIPULATION 1

View File

@ -1297,7 +1297,9 @@ void TakeScreenshot(const char *fileName)
{ {
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
unsigned char *imgData = rlReadScreenPixels(renderWidth, renderHeight); unsigned char *imgData = rlReadScreenPixels(renderWidth, renderHeight);
SavePNG(fileName, imgData, renderWidth, renderHeight, 4); // Save image as PNG
Image image = { imgData, renderWidth, renderHeight, 1, UNCOMPRESSED_R8G8B8A8 };
ExportImage(image, fileName);
free(imgData); free(imgData);
TraceLog(LOG_INFO, "Screenshot taken: %s", fileName); TraceLog(LOG_INFO, "Screenshot taken: %s", fileName);

2023
src/external/cgltf.h vendored Normal file

File diff suppressed because it is too large Load Diff

1753
src/external/mini_al.h vendored

File diff suppressed because it is too large Load Diff

View File

@ -5,10 +5,10 @@
* CONFIGURATION: * CONFIGURATION:
* *
* #define SUPPORT_FILEFORMAT_OBJ * #define SUPPORT_FILEFORMAT_OBJ
* Selected desired fileformats to be supported for loading.
*
* #define SUPPORT_FILEFORMAT_MTL * #define SUPPORT_FILEFORMAT_MTL
* Selected desired fileformats to be supported for loading. * #define SUPPORT_FILEFORMAT_IQM
* #define SUPPORT_FILEFORMAT_GLTF
* Selected desired fileformats to be supported for model data loading.
* *
* #define SUPPORT_MESH_GENERATION * #define SUPPORT_MESH_GENERATION
* Support procedural mesh generation functions, uses external par_shapes.h library * Support procedural mesh generation functions, uses external par_shapes.h library
@ -48,8 +48,20 @@
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2 #include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2
#if defined(SUPPORT_FILEFORMAT_IQM)
#define RIQM_IMPLEMENTATION
#include "external/riqm.h" // IQM file format loading
#endif
#if defined(SUPPORT_FILEFORMAT_GLTF)
#define CGLTF_IMPLEMENTATION
#include "external/cgltf.h" // glTF file format loading
#endif
#if defined(SUPPORT_MESH_GENERATION)
#define PAR_SHAPES_IMPLEMENTATION #define PAR_SHAPES_IMPLEMENTATION
#include "external/par_shapes.h" // Shapes 3d parametric generation #include "external/par_shapes.h" // Shapes 3d parametric generation
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
@ -75,6 +87,12 @@ static Mesh LoadOBJ(const char *fileName); // Load OBJ mesh data
#if defined(SUPPORT_FILEFORMAT_MTL) #if defined(SUPPORT_FILEFORMAT_MTL)
static Material LoadMTL(const char *fileName); // Load MTL material data static Material LoadMTL(const char *fileName); // Load MTL material data
#endif #endif
#if defined(SUPPORT_FILEFORMAT_GLTF)
static Mesh LoadIQM(const char *fileName); // Load IQM mesh data
#endif
#if defined(SUPPORT_FILEFORMAT_GLTF)
static Mesh LoadGLTF(const char *fileName); // Load GLTF mesh data
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Definition // Module Functions Definition
@ -646,8 +664,12 @@ void UnloadMesh(Mesh *mesh)
rlUnloadMesh(mesh); rlUnloadMesh(mesh);
} }
// Export mesh as an OBJ file // Export mesh data to file
void ExportMesh(const char *fileName, Mesh mesh) void ExportMesh(Mesh mesh, const char *fileName)
{
bool success = false;
if (IsFileExtension(fileName, ".obj"))
{ {
FILE *objFile = fopen(fileName, "wt"); FILE *objFile = fopen(fileName, "wt");
@ -684,7 +706,12 @@ void ExportMesh(const char *fileName, Mesh mesh)
fclose(objFile); fclose(objFile);
TraceLog(LOG_INFO, "Mesh saved: %s", fileName); success = true;
}
else if (IsFileExtension(fileName, ".raw")) { } // TODO: Support additional file formats to export mesh vertex data
if (success) TraceLog(LOG_INFO, "Mesh exported successfully: %s", fileName);
else TraceLog(LOG_WARNING, "Mesh could not be exported.");
} }
#if defined(SUPPORT_MESH_GENERATION) #if defined(SUPPORT_MESH_GENERATION)
@ -699,7 +726,7 @@ Mesh GenMeshPlane(float width, float length, int resX, int resZ)
resZ++; resZ++;
// Vertices definition // Vertices definition
int vertexCount = resX*resZ*6; // 6 vertex by quad int vertexCount = resX*resZ; // vertices get reused for the faces
Vector3 *vertices = (Vector3 *)malloc(vertexCount*sizeof(Vector3)); Vector3 *vertices = (Vector3 *)malloc(vertexCount*sizeof(Vector3));
for (int z = 0; z < resZ; z++) for (int z = 0; z < resZ; z++)
@ -2206,7 +2233,6 @@ void MeshBinormals(Mesh *mesh)
Vector3 tangent = { mesh->tangents[i*4 + 0], mesh->tangents[i*4 + 1], mesh->tangents[i*4 + 2] }; Vector3 tangent = { mesh->tangents[i*4 + 0], mesh->tangents[i*4 + 1], mesh->tangents[i*4 + 2] };
float tangentW = mesh->tangents[i*4 + 3]; float tangentW = mesh->tangents[i*4 + 3];
// TODO: Register computed binormal in mesh->binormal ? // TODO: Register computed binormal in mesh->binormal ?
// Vector3 binormal = Vector3Multiply(Vector3CrossProduct(normal, tangent), tangentW); // Vector3 binormal = Vector3Multiply(Vector3CrossProduct(normal, tangent), tangentW);
} }
@ -2222,7 +2248,7 @@ static Mesh LoadOBJ(const char *fileName)
{ {
Mesh mesh = { 0 }; Mesh mesh = { 0 };
char dataType; char dataType = 0;
char comments[200]; char comments[200];
int vertexCount = 0; int vertexCount = 0;
@ -2245,7 +2271,7 @@ static Mesh LoadOBJ(const char *fileName)
// NOTE: faces MUST be defined as TRIANGLES (3 vertex per face) // NOTE: faces MUST be defined as TRIANGLES (3 vertex per face)
while (!feof(objFile)) while (!feof(objFile))
{ {
dataType = '\0'; dataType = 0;
fscanf(objFile, "%c", &dataType); fscanf(objFile, "%c", &dataType);
switch (dataType) switch (dataType)
@ -2631,3 +2657,59 @@ static Material LoadMTL(const char *fileName)
return material; return material;
} }
#endif #endif
#if defined(SUPPORT_FILEFORMAT_GLTF)
// Load IQM mesh data
static Mesh LoadIQM(const char *fileName)
{
Mesh mesh = { 0 };
// TODO: Load IQM file
return mesh;
}
#endif
#if defined(SUPPORT_FILEFORMAT_GLTF)
// Load GLTF mesh data
static Mesh LoadGLTF(const char *fileName)
{
Mesh mesh = { 0 };
// GLTF file loading
FILE *gltfFile = fopen(fileName, "rb");
if (gltfFile == NULL)
{
TraceLog(LOG_WARNING, "[%s] GLTF file could not be opened", fileName);
return mesh;
}
fseek(gltfFile, 0, SEEK_END);
int size = ftell(gltfFile);
fseek(gltfFile, 0, SEEK_SET);
void *buffer = malloc(size);
fread(buffer, size, 1, gltfFile);
fclose(gltfFile);
// GLTF data loading
cgltf_options options = {0};
cgltf_data data;
cgltf_result result = cgltf_parse(&options, buffer, size, &data);
if (result == cgltf_result_success)
{
printf("Type: %u\n", data.file_type);
printf("Version: %d\n", data.version);
printf("Meshes: %lu\n", data.meshes_count);
}
else TraceLog(LOG_WARNING, "[%s] GLTF data could not be loaded", fileName);
free(buffer);
cgltf_free(&data);
return mesh;
}
#endif

View File

@ -1,6 +1,6 @@
/********************************************************************************************** /**********************************************************************************************
* *
* raylib - A simple and easy-to-use library to learn videogames programming (www.raylib.com) * raylib - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
* *
* FEATURES: * FEATURES:
* - NO external dependencies, all required libraries included with raylib * - NO external dependencies, all required libraries included with raylib
@ -442,6 +442,7 @@ typedef struct RenderTexture2D {
// RenderTexture type, same as RenderTexture2D // RenderTexture type, same as RenderTexture2D
typedef RenderTexture2D RenderTexture; typedef RenderTexture2D RenderTexture;
// N-Patch layout info
typedef struct NPatchInfo { typedef struct NPatchInfo {
Rectangle sourceRec; // Region in the texture Rectangle sourceRec; // Region in the texture
int left; // left border offset int left; // left border offset
@ -720,6 +721,13 @@ typedef enum {
WRAP_MIRROR WRAP_MIRROR
} TextureWrapMode; } TextureWrapMode;
// Font type, defines generation method
typedef enum {
FONT_DEFAULT = 0, // Default font generation, anti-aliased
FONT_BITMAP, // Bitmap font generation, no anti-aliasing
FONT_SDF // SDF font generation, requires external shader
} FontType;
// Color blending modes (pre-defined) // Color blending modes (pre-defined)
typedef enum { typedef enum {
BLEND_ALPHA = 0, BLEND_ALPHA = 0,
@ -980,7 +988,7 @@ RLAPI Image LoadImage(const char *fileName);
RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image from Color array data (RGBA - 32bit) RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image from Color array data (RGBA - 32bit)
RLAPI Image LoadImagePro(void *data, int width, int height, int format); // Load image from raw data with parameters RLAPI Image LoadImagePro(void *data, int width, int height, int format); // Load image from raw data with parameters
RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data
RLAPI void ExportImage(const char *fileName, Image image); // Export image as a PNG file RLAPI void ExportImage(Image image, const char *fileName); // Export image data to file
RLAPI Texture2D LoadTexture(const char *fileName); // Load texture from file into GPU memory (VRAM) RLAPI Texture2D LoadTexture(const char *fileName); // Load texture from file into GPU memory (VRAM)
RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data
RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer) RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer)
@ -1055,7 +1063,7 @@ RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle
RLAPI Font GetFontDefault(void); // Get the default Font RLAPI Font GetFontDefault(void); // Get the default Font
RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM) RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM)
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load font from file with extended parameters RLAPI Font LoadFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load font from file with extended parameters
RLAPI CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int charsCount, bool sdf); // Load font data for further use RLAPI CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int charsCount, int type); // Load font data for further use
RLAPI Image GenImageFontAtlas(CharInfo *chars, int fontSize, int charsCount, int padding, int packMethod); // Generate image font atlas using chars info RLAPI Image GenImageFontAtlas(CharInfo *chars, int fontSize, int charsCount, int padding, int packMethod); // Generate image font atlas using chars info
RLAPI void UnloadFont(Font font); // Unload Font from GPU memory (VRAM) RLAPI void UnloadFont(Font font); // Unload Font from GPU memory (VRAM)
@ -1105,7 +1113,7 @@ RLAPI void UnloadModel(Model model);
// Mesh loading/unloading functions // Mesh loading/unloading functions
RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file
RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM) RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM)
RLAPI void ExportMesh(const char *fileName, Mesh mesh); // Export mesh as an OBJ file RLAPI void ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file
// Mesh manipulation functions // Mesh manipulation functions
RLAPI BoundingBox MeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits RLAPI BoundingBox MeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
@ -1213,6 +1221,7 @@ RLAPI Sound LoadSoundFromWave(Wave wave); // Load so
RLAPI void UpdateSound(Sound sound, const void *data, int samplesCount);// Update sound buffer with new data RLAPI void UpdateSound(Sound sound, const void *data, int samplesCount);// Update sound buffer with new data
RLAPI void UnloadWave(Wave wave); // Unload wave data RLAPI void UnloadWave(Wave wave); // Unload wave data
RLAPI void UnloadSound(Sound sound); // Unload sound RLAPI void UnloadSound(Sound sound); // Unload sound
RLAPI void ExportWave(Wave wave, const char *fileName); // Export wave data to file
// Wave/Sound management functions // Wave/Sound management functions
RLAPI void PlaySound(Sound sound); // Play a sound RLAPI void PlaySound(Sound sound); // Play a sound

View File

@ -229,6 +229,13 @@ RMDEF Vector2 Vector2Scale(Vector2 v, float scale)
return result; return result;
} }
// Multiply vector by vector
RMDEF Vector2 Vector2MultiplyV(Vector2 v1, Vector2 v2)
{
Vector2 result = { v1.x*v2.x, v1.y*v2.y };
return result;
}
// Negate vector // Negate vector
RMDEF Vector2 Vector2Negate(Vector2 v) RMDEF Vector2 Vector2Negate(Vector2 v)
{ {
@ -243,6 +250,13 @@ RMDEF Vector2 Vector2Divide(Vector2 v, float div)
return result; return result;
} }
// Divide vector by vector
RMDEF Vector2 Vector2DivideV(Vector2 v1, Vector2 v2)
{
Vector2 result = { v1.x/v2.x, v1.y/v2.y };
return result;
}
// Normalize provided vector // Normalize provided vector
RMDEF Vector2 Vector2Normalize(Vector2 v) RMDEF Vector2 Vector2Normalize(Vector2 v)
{ {
@ -378,6 +392,20 @@ RMDEF Vector3 Vector3Negate(Vector3 v)
return result; return result;
} }
// Divide vector by a float value
RMDEF Vector3 Vector3Divide(Vector3 v, float div)
{
Vector3 result = { v.x / div, v.y / div, v.z / div };
return result;
}
// Divide vector by vector
RMDEF Vector3 Vector3DivideV(Vector3 v1, Vector3 v2)
{
Vector3 result = { v1.x/v2.x, v1.y/v2.y, v1.z/v2.z };
return result;
}
// Normalize provided vector // Normalize provided vector
RMDEF Vector3 Vector3Normalize(Vector3 v) RMDEF Vector3 Vector3Normalize(Vector3 v)
{ {

View File

@ -86,9 +86,6 @@ static Font LoadImageFont(Image image, Color key, int firstChar); // Load a Imag
#if defined(SUPPORT_FILEFORMAT_FNT) #if defined(SUPPORT_FILEFORMAT_FNT)
static Font LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file) static Font LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file)
#endif #endif
#if defined(SUPPORT_FILEFORMAT_TTF)
//static Font LoadTTF(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load spritefont from TTF data
#endif
#if defined(SUPPORT_DEFAULT_FONT) #if defined(SUPPORT_DEFAULT_FONT)
extern void LoadDefaultFont(void); extern void LoadDefaultFont(void);
@ -221,7 +218,7 @@ extern void LoadDefaultFont(void)
defaultFont.chars[i].value = 32 + i; // First char is 32 defaultFont.chars[i].value = 32 + i; // First char is 32
defaultFont.chars[i].rec.x = (float)currentPosX; defaultFont.chars[i].rec.x = (float)currentPosX;
defaultFont.chars[i].rec.y = (float)charsDivisor + currentLine*(charsHeight + charsDivisor); defaultFont.chars[i].rec.y = (float)(charsDivisor + currentLine*(charsHeight + charsDivisor));
defaultFont.chars[i].rec.width = (float)charsWidth[i]; defaultFont.chars[i].rec.width = (float)charsWidth[i];
defaultFont.chars[i].rec.height = (float)charsHeight; defaultFont.chars[i].rec.height = (float)charsHeight;
@ -234,7 +231,7 @@ extern void LoadDefaultFont(void)
testPosX = currentPosX; testPosX = currentPosX;
defaultFont.chars[i].rec.x = (float)charsDivisor; defaultFont.chars[i].rec.x = (float)charsDivisor;
defaultFont.chars[i].rec.y = (float)charsDivisor + currentLine*(charsHeight + charsDivisor); defaultFont.chars[i].rec.y = (float)(charsDivisor + currentLine*(charsHeight + charsDivisor));
} }
else currentPosX = testPosX; else currentPosX = testPosX;
@ -283,7 +280,7 @@ Font LoadFont(const char *fileName)
{ {
font.baseSize = DEFAULT_TTF_FONTSIZE; font.baseSize = DEFAULT_TTF_FONTSIZE;
font.charsCount = DEFAULT_TTF_NUMCHARS; font.charsCount = DEFAULT_TTF_NUMCHARS;
font.chars = LoadFontData(fileName, font.baseSize, NULL, font.charsCount, false); font.chars = LoadFontData(fileName, font.baseSize, NULL, font.charsCount, FONT_DEFAULT);
Image atlas = GenImageFontAtlas(font.chars, font.charsCount, font.baseSize, 4, 0); Image atlas = GenImageFontAtlas(font.chars, font.charsCount, font.baseSize, 4, 0);
font.texture = LoadTextureFromImage(atlas); font.texture = LoadTextureFromImage(atlas);
UnloadImage(atlas); UnloadImage(atlas);
@ -319,8 +316,8 @@ Font LoadFontEx(const char *fileName, int fontSize, int charsCount, int *fontCha
font.baseSize = fontSize; font.baseSize = fontSize;
font.charsCount = (charsCount > 0) ? charsCount : 95; font.charsCount = (charsCount > 0) ? charsCount : 95;
font.chars = LoadFontData(fileName, font.baseSize, fontChars, font.charsCount, false); font.chars = LoadFontData(fileName, font.baseSize, fontChars, font.charsCount, FONT_DEFAULT);
Image atlas = GenImageFontAtlas(font.chars, font.charsCount, font.baseSize, 0, 0); Image atlas = GenImageFontAtlas(font.chars, font.charsCount, font.baseSize, 2, 0);
font.texture = LoadTextureFromImage(atlas); font.texture = LoadTextureFromImage(atlas);
UnloadImage(atlas); UnloadImage(atlas);
@ -329,7 +326,7 @@ Font LoadFontEx(const char *fileName, int fontSize, int charsCount, int *fontCha
// Load font data for further use // Load font data for further use
// NOTE: Requires TTF font and can generate SDF data // NOTE: Requires TTF font and can generate SDF data
CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int charsCount, bool sdf) CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int charsCount, int type)
{ {
// NOTE: Using some SDF generation default values, // NOTE: Using some SDF generation default values,
// trades off precision with ability to handle *smaller* sizes // trades off precision with ability to handle *smaller* sizes
@ -337,6 +334,8 @@ CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int c
#define SDF_ON_EDGE_VALUE 128 #define SDF_ON_EDGE_VALUE 128
#define SDF_PIXEL_DIST_SCALE 64.0f #define SDF_PIXEL_DIST_SCALE 64.0f
#define BITMAP_ALPHA_THRESHOLD 80
// In case no chars count provided, default to 95 // In case no chars count provided, default to 95
charsCount = (charsCount > 0) ? charsCount : 95; charsCount = (charsCount > 0) ? charsCount : 95;
@ -367,8 +366,6 @@ CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int c
// NOTE: ascent is equivalent to font baseline // NOTE: ascent is equivalent to font baseline
int ascent, descent, lineGap; int ascent, descent, lineGap;
stbtt_GetFontVMetrics(&fontInfo, &ascent, &descent, &lineGap); stbtt_GetFontVMetrics(&fontInfo, &ascent, &descent, &lineGap);
ascent *= (int) scaleFactor;
descent *= (int) scaleFactor;
// Fill fontChars in case not provided externally // Fill fontChars in case not provided externally
// NOTE: By default we fill charsCount consecutevely, starting at 32 (Space) // NOTE: By default we fill charsCount consecutevely, starting at 32 (Space)
@ -392,22 +389,33 @@ CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int c
// stbtt_GetCodepointBitmapBox() -- how big the bitmap must be // stbtt_GetCodepointBitmapBox() -- how big the bitmap must be
// stbtt_MakeCodepointBitmap() -- renders into bitmap you provide // stbtt_MakeCodepointBitmap() -- renders into bitmap you provide
if (!sdf) chars[i].data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, ch, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY); if (type != FONT_SDF) chars[i].data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, ch, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
else if (ch != 32) chars[i].data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, ch, SDF_CHAR_PADDING, SDF_ON_EDGE_VALUE, SDF_PIXEL_DIST_SCALE, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY); else if (ch != 32) chars[i].data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, ch, SDF_CHAR_PADDING, SDF_ON_EDGE_VALUE, SDF_PIXEL_DIST_SCALE, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
if (type == FONT_BITMAP)
{
// Aliased bitmap (black & white) font generation, avoiding anti-aliasing
// NOTE: For optimum results, bitmap font should be generated at base pixel size
for (int p = 0; p < chw*chh; p++)
{
if (chars[i].data[p] < BITMAP_ALPHA_THRESHOLD) chars[i].data[p] = 0;
else chars[i].data[p] = 255;
}
}
chars[i].rec.width = (float)chw; chars[i].rec.width = (float)chw;
chars[i].rec.height = (float)chh; chars[i].rec.height = (float)chh;
chars[i].offsetY += ascent; chars[i].offsetY += (int)((float)ascent*scaleFactor);
// Get bounding box for character (may be offset to account for chars that dip above or below the line) // Get bounding box for character (may be offset to account for chars that dip above or below the line)
int chX1, chY1, chX2, chY2; int chX1, chY1, chX2, chY2;
stbtt_GetCodepointBitmapBox(&fontInfo, ch, scaleFactor, scaleFactor, &chX1, &chY1, &chX2, &chY2); stbtt_GetCodepointBitmapBox(&fontInfo, ch, scaleFactor, scaleFactor, &chX1, &chY1, &chX2, &chY2);
TraceLog(LOG_DEBUG, "Character box measures: %i, %i, %i, %i", chX1, chY1, chX2 - chX1, chY2 - chY1); TraceLog(LOG_DEBUG, "Character box measures: %i, %i, %i, %i", chX1, chY1, chX2 - chX1, chY2 - chY1);
TraceLog(LOG_DEBUG, "Character offsetY: %i", ascent + chY1); TraceLog(LOG_DEBUG, "Character offsetY: %i", (int)((float)ascent*scaleFactor) + chY1);
stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL); stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL);
chars[i].advanceX *= (int) scaleFactor; chars[i].advanceX *= scaleFactor;
} }
free(fontBuffer); free(fontBuffer);

View File

@ -19,6 +19,9 @@
* Selecte desired fileformats to be supported for image data 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 * supported by default, to remove support, just comment unrequired #define in this module
* *
* #define SUPPORT_IMAGE_EXPORT
* Support image export in multiple file formats
*
* #define SUPPORT_IMAGE_MANIPULATION * #define SUPPORT_IMAGE_MANIPULATION
* Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... * 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() * If not defined only three image editing functions supported: ImageFormat(), ImageAlphaMask(), ImageToPOT()
@ -103,6 +106,11 @@
// NOTE: Used to read image data (multiple formats support) // NOTE: Used to read image data (multiple formats support)
#endif #endif
#if defined(SUPPORT_IMAGE_EXPORT)
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "external/stb_image_write.h" // Required for: stbi_write_*()
#endif
#if defined(SUPPORT_IMAGE_MANIPULATION) #if defined(SUPPORT_IMAGE_MANIPULATION)
#define STB_IMAGE_RESIZE_IMPLEMENTATION #define STB_IMAGE_RESIZE_IMPLEMENTATION
#include "external/stb_image_resize.h" // Required for: stbir_resize_uint8() #include "external/stb_image_resize.h" // Required for: stbir_resize_uint8()
@ -706,14 +714,31 @@ void UpdateTexture(Texture2D texture, const void *pixels)
rlUpdateTexture(texture.id, texture.width, texture.height, texture.format, pixels); rlUpdateTexture(texture.id, texture.width, texture.height, texture.format, pixels);
} }
// Export image as a PNG file // Export image data to file
void ExportImage(const char *fileName, Image image) // NOTE: File format depends on fileName extension
void ExportImage(Image image, const char *fileName)
{ {
int success = 0;
// NOTE: Getting Color array as RGBA unsigned char values // NOTE: Getting Color array as RGBA unsigned char values
unsigned char *imgData = (unsigned char *)GetImageData(image); unsigned char *imgData = (unsigned char *)GetImageData(image);
// NOTE: SavePNG() not supported by some platforms: PLATFORM_WEB, PLATFORM_ANDROID if (IsFileExtension(fileName, ".png")) success = stbi_write_png(fileName, image.width, image.height, 4, imgData, image.width*4);
SavePNG(fileName, imgData, image.width, image.height, 4); else if (IsFileExtension(fileName, ".bmp")) success = stbi_write_bmp(fileName, image.width, image.height, 4, imgData);
else if (IsFileExtension(fileName, ".tga")) success = stbi_write_tga(fileName, image.width, image.height, 4, imgData);
else if (IsFileExtension(fileName, ".jpg")) success = stbi_write_jpg(fileName, image.width, image.height, 4, imgData, 80); // Between 1 and 100
else if (IsFileExtension(fileName, ".raw"))
{
// Export raw pixel data
// NOTE: It's up to the user to track image parameters
FILE *rawFile = fopen(fileName, "wb");
fwrite(image.data, GetPixelDataSize(image.width, image.height, image.format), 1, rawFile);
fclose(rawFile);
}
else if (IsFileExtension(fileName, ".h")) { } // TODO: Export pixel data as an array of bytes
if (success != 0) TraceLog(LOG_INFO, "Image exported successfully: %s", fileName);
else TraceLog(LOG_WARNING, "Image could not be exported.");
free(imgData); free(imgData);
} }
@ -1555,6 +1580,8 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
// Define ImageFont struct? or include Image spritefont in Font struct? // Define ImageFont struct? or include Image spritefont in Font struct?
Image imFont = GetTextureData(font.texture); Image imFont = GetTextureData(font.texture);
ImageFormat(&imFont, UNCOMPRESSED_R8G8B8A8); // Make sure image format could be properly colored!
ImageColorTint(&imFont, tint); // Apply color tint to font ImageColorTint(&imFont, tint); // Apply color tint to font
// Create image to store text // Create image to store text
@ -2827,7 +2854,11 @@ static Image LoadKTX(const char *fileName)
// GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 // GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
// KTX file Header (64 bytes) // KTX file Header (64 bytes)
// https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/ // v1.1 - https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
// v2.0 - http://github.khronos.org/KTX-Specification/
// TODO: Support KTX 2.2 specs!
typedef struct { typedef struct {
char id[12]; // Identifier: "«KTX 11»\r\n\x1A\n" char id[12]; // Identifier: "«KTX 11»\r\n\x1A\n"
unsigned int endianness; // Little endian: 0x01 0x02 0x03 0x04 unsigned int endianness; // Little endian: 0x01 0x02 0x03 0x04

View File

@ -4,21 +4,10 @@
* *
* CONFIGURATION: * CONFIGURATION:
* *
* #define SUPPORT_SAVE_PNG (defined by default)
* Support saving image data as PNG fileformat
* NOTE: Requires stb_image_write library
*
* #define SUPPORT_SAVE_BMP
* Support saving image data as BMP fileformat
* NOTE: Requires stb_image_write library
*
* #define SUPPORT_TRACELOG * #define SUPPORT_TRACELOG
* Show TraceLog() output messages * Show TraceLog() output messages
* NOTE: By default LOG_DEBUG traces not shown * NOTE: By default LOG_DEBUG traces not shown
* *
* DEPENDENCIES:
* stb_image_write - BMP/PNG writting functions
*
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
@ -62,12 +51,6 @@ FILE *funopen(const void *cookie, int (*readfn)(void *, char *, int),
int (*writefn)(void *, const char *, int), int (*writefn)(void *, const char *, int),
fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *)); fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *));
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "external/stb_image_write.h" // Required for: stbi_write_bmp(), stbi_write_png()
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Global Variables Definition // Global Variables Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -160,24 +143,6 @@ void TraceLog(int msgType, const char *text, ...)
#endif // SUPPORT_TRACELOG #endif // SUPPORT_TRACELOG
} }
// Creates a BMP image file from an array of pixel data
void SaveBMP(const char *fileName, unsigned char *imgData, int width, int height, int compSize)
{
#if defined(SUPPORT_SAVE_BMP) && (defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI))
stbi_write_bmp(fileName, width, height, compSize, imgData);
TraceLog(LOG_INFO, "BMP Image saved: %s", fileName);
#endif
}
// Creates a PNG image file from an array of pixel data
void SavePNG(const char *fileName, unsigned char *imgData, int width, int height, int compSize)
{
#if defined(SUPPORT_SAVE_PNG) && (defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI))
stbi_write_png(fileName, width, height, compSize, imgData, width*compSize);
TraceLog(LOG_INFO, "PNG Image saved: %s", fileName);
#endif
}
// Keep track of memory allocated // Keep track of memory allocated
// NOTE: mallocType defines the type of data allocated // NOTE: mallocType defines the type of data allocated
/* /*

View File

@ -32,10 +32,6 @@
#include <android/asset_manager.h> // Required for: AAssetManager #include <android/asset_manager.h> // Required for: AAssetManager
#endif #endif
#ifndef SUPPORT_SAVE_PNG
#define SUPPORT_SAVE_PNG 1
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Some basic Defines // Some basic Defines
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -58,13 +54,6 @@ extern "C" { // Prevents name mangling of functions
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Declaration // Module Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#if defined(SUPPORT_SAVE_BMP)
void SaveBMP(const char *fileName, unsigned char *imgData, int width, int height, int compSize);
#endif
#if defined(SUPPORT_SAVE_PNG)
void SavePNG(const char *fileName, unsigned char *imgData, int width, int height, int compSize);
#endif
#if defined(PLATFORM_ANDROID) #if defined(PLATFORM_ANDROID)
void InitAssetManager(AAssetManager *manager); // Initialize asset manager from android app void InitAssetManager(AAssetManager *manager); // Initialize asset manager from android app
FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen() FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen()