aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorraysan5 <raysan5@gmail.com>2013-11-23 13:30:54 +0100
committerraysan5 <raysan5@gmail.com>2013-11-23 13:30:54 +0100
commitccf26080915d5487dfb2e5fdb79c2bc2893b7454 (patch)
treee7a4856dbea9eac3d356533260b37ce812d5f6e1 /src
parent7635e9c79ff2ed581942b61ca6cebac73712ecca (diff)
downloadraylib-ccf26080915d5487dfb2e5fdb79c2bc2893b7454.tar.gz
raylib-ccf26080915d5487dfb2e5fdb79c2bc2893b7454.zip
Replaced tab by 4 spaces and adjust text
Diffstat (limited to 'src')
-rw-r--r--src/audio.c404
-rw-r--r--src/core.c650
-rw-r--r--src/models.c1350
-rw-r--r--src/raylib.h406
-rw-r--r--src/shapes.c374
-rw-r--r--src/text.c770
-rw-r--r--src/textures.c354
-rw-r--r--src/vector3.c126
-rw-r--r--src/vector3.h52
9 files changed, 2244 insertions, 2242 deletions
diff --git a/src/audio.c b/src/audio.c
index 41ba6fed..a696950e 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -1,41 +1,41 @@
/*********************************************************************************************
*
-* raylib.audio
+* raylib.audio
*
-* Basic functions to manage Audio: InitAudioDevice, LoadAudioFiles, PlayAudioFiles
-*
-* Uses external lib:
-* OpenAL - Audio device management lib
-* TODO: stb_vorbis - Ogg audio files loading
+* Basic functions to manage Audio: InitAudioDevice, LoadAudioFiles, PlayAudioFiles
+*
+* Uses external lib:
+* OpenAL - Audio device management lib
+* TODO: stb_vorbis - Ogg audio files loading
*
-* Copyright (c) 2013 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.
+* Copyright (c) 2013 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.
*
-* Permission is granted to anyone to use this software for any purpose, including commercial
-* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
-* 1. The origin of this software must not be misrepresented; you must not claim that you
-* wrote the original software. If you use this software in a product, an acknowledgment
-* in the product documentation would be appreciated but is not required.
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
*
-* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
-* as being the original software.
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
*
-* 3. This notice may not be removed or altered from any source distribution.
+* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include "raylib.h"
-#include <AL/al.h> // OpenAL basic header
-#include <AL/alc.h> // OpenAL context header (like OpenGL, OpenAL requires a context to work)
+#include <AL/al.h> // OpenAL basic header
+#include <AL/alc.h> // OpenAL context header (like OpenGL, OpenAL requires a context to work)
-#include <stdlib.h> // To use exit() function
-#include <stdio.h> // Used for .WAV loading
+#include <stdlib.h> // To use exit() function
+#include <stdio.h> // Used for .WAV loading
-//#include "stb_vorbis.h" // TODO: OGG loading functions
+//#include "stb_vorbis.h" // TODO: OGG loading functions
//----------------------------------------------------------------------------------
// Defines and Macros
@@ -48,11 +48,11 @@
// Wave file data
typedef struct Wave {
- unsigned char *data; // Buffer data pointer
- unsigned int sampleRate;
- unsigned int dataSize;
- short channels;
- short format;
+ unsigned char *data; // Buffer data pointer
+ unsigned int sampleRate;
+ unsigned int dataSize;
+ short channels;
+ short format;
} Wave;
//----------------------------------------------------------------------------------
@@ -74,231 +74,231 @@ static void UnloadWAV(Wave wave);
// Initialize audio device and context
void InitAudioDevice()
{
- // Open and initialize a device with default settings
- ALCdevice *device = alcOpenDevice(NULL);
-
- if(!device)
- {
- fprintf(stderr, "Could not open a device!\n");
- exit(1);
- }
-
- ALCcontext *context = alcCreateContext(device, NULL);
-
- if(context == NULL || alcMakeContextCurrent(context) == ALC_FALSE)
- {
- if(context != NULL) alcDestroyContext(context);
-
- alcCloseDevice(device);
-
- fprintf(stderr, "Could not set a context!\n");
- exit(1);
- }
-
- printf("Opened \"%s\"\n", alcGetString(device, ALC_DEVICE_SPECIFIER));
-
- // Listener definition (just for 2D)
- alListener3f(AL_POSITION, 0, 0, 0);
- alListener3f(AL_VELOCITY, 0, 0, 0);
- alListener3f(AL_ORIENTATION, 0, 0, -1);
+ // Open and initialize a device with default settings
+ ALCdevice *device = alcOpenDevice(NULL);
+
+ if(!device)
+ {
+ fprintf(stderr, "Could not open a device!\n");
+ exit(1);
+ }
+
+ ALCcontext *context = alcCreateContext(device, NULL);
+
+ if(context == NULL || alcMakeContextCurrent(context) == ALC_FALSE)
+ {
+ if(context != NULL) alcDestroyContext(context);
+
+ alcCloseDevice(device);
+
+ fprintf(stderr, "Could not set a context!\n");
+ exit(1);
+ }
+
+ printf("Opened \"%s\"\n", alcGetString(device, ALC_DEVICE_SPECIFIER));
+
+ // Listener definition (just for 2D)
+ alListener3f(AL_POSITION, 0, 0, 0);
+ alListener3f(AL_VELOCITY, 0, 0, 0);
+ alListener3f(AL_ORIENTATION, 0, 0, -1);
}
// Close the audio device for the current context, and destroys the context
void CloseAudioDevice()
{
- ALCdevice *device;
- ALCcontext *context = alcGetCurrentContext();
-
- if (context == NULL) return;
+ ALCdevice *device;
+ ALCcontext *context = alcGetCurrentContext();
+
+ if (context == NULL) return;
- device = alcGetContextsDevice(context);
+ device = alcGetContextsDevice(context);
- alcMakeContextCurrent(NULL);
- alcDestroyContext(context);
- alcCloseDevice(device);
+ alcMakeContextCurrent(NULL);
+ alcDestroyContext(context);
+ alcCloseDevice(device);
}
// Load sound to memory
Sound LoadSound(char *fileName)
{
- Sound sound;
-
- // NOTE: The entire file is loaded to memory to play it all at once (no-streaming)
-
- // WAV file loading
- // NOTE: Buffer space is allocated inside LoadWAV, Wave must be freed
- Wave wave = LoadWAV(fileName);
-
- ALenum format;
- // The OpenAL format is worked out by looking at the number of channels and the bits per sample
- if (wave.channels == 1)
- {
- if (wave.sampleRate == 8 ) format = AL_FORMAT_MONO8;
- else if (wave.sampleRate == 16) format = AL_FORMAT_MONO16;
- }
- else if (wave.channels == 2)
- {
- if (wave.sampleRate == 8 ) format = AL_FORMAT_STEREO8;
- else if (wave.sampleRate == 16) format = AL_FORMAT_STEREO16;
- }
-
- // Create an audio source
- ALuint source;
- alGenSources(1, &source); // Generate pointer to audio source
-
- alSourcef(source, AL_PITCH, 1);
- alSourcef(source, AL_GAIN, 1);
- alSource3f(source, AL_POSITION, 0, 0, 0);
- alSource3f(source, AL_VELOCITY, 0, 0, 0);
- alSourcei(source, AL_LOOPING, AL_FALSE);
-
- // Convert loaded data to OpenAL buffer
- //----------------------------------------
- ALuint buffer;
- alGenBuffers(1, &buffer); // Generate pointer to buffer
-
- // Upload sound data to buffer
- alBufferData(buffer, format, wave.data, wave.dataSize, wave.sampleRate);
-
- // Attach sound buffer to source
- alSourcei(source, AL_BUFFER, buffer);
-
- // Unallocate WAV data
- UnloadWAV(wave);
-
- printf("Sample rate: %i\n", wave.sampleRate);
- printf("Channels: %i\n", wave.channels);
+ Sound sound;
+
+ // NOTE: The entire file is loaded to memory to play it all at once (no-streaming)
+
+ // WAV file loading
+ // NOTE: Buffer space is allocated inside LoadWAV, Wave must be freed
+ Wave wave = LoadWAV(fileName);
+
+ ALenum format;
+ // The OpenAL format is worked out by looking at the number of channels and the bits per sample
+ if (wave.channels == 1)
+ {
+ if (wave.sampleRate == 8 ) format = AL_FORMAT_MONO8;
+ else if (wave.sampleRate == 16) format = AL_FORMAT_MONO16;
+ }
+ else if (wave.channels == 2)
+ {
+ if (wave.sampleRate == 8 ) format = AL_FORMAT_STEREO8;
+ else if (wave.sampleRate == 16) format = AL_FORMAT_STEREO16;
+ }
+
+ // Create an audio source
+ ALuint source;
+ alGenSources(1, &source); // Generate pointer to audio source
+
+ alSourcef(source, AL_PITCH, 1);
+ alSourcef(source, AL_GAIN, 1);
+ alSource3f(source, AL_POSITION, 0, 0, 0);
+ alSource3f(source, AL_VELOCITY, 0, 0, 0);
+ alSourcei(source, AL_LOOPING, AL_FALSE);
+
+ // Convert loaded data to OpenAL buffer
+ //----------------------------------------
+ ALuint buffer;
+ alGenBuffers(1, &buffer); // Generate pointer to buffer
+
+ // Upload sound data to buffer
+ alBufferData(buffer, format, wave.data, wave.dataSize, wave.sampleRate);
+
+ // Attach sound buffer to source
+ alSourcei(source, AL_BUFFER, buffer);
+
+ // Unallocate WAV data
+ UnloadWAV(wave);
+
+ printf("Sample rate: %i\n", wave.sampleRate);
+ printf("Channels: %i\n", wave.channels);
printf("Format: %i\n", wave.format);
-
- printf("Audio file loaded...!\n");
-
- sound.source = source;
- sound.buffer = buffer;
-
- return sound;
+
+ printf("Audio file loaded...!\n");
+
+ sound.source = source;
+ sound.buffer = buffer;
+
+ return sound;
}
// Unload sound
void UnloadSound(Sound sound)
{
- alDeleteSources(1, &sound.source);
- alDeleteBuffers(1, &sound.buffer);
+ alDeleteSources(1, &sound.source);
+ alDeleteBuffers(1, &sound.buffer);
}
// Play a sound
void PlaySound(Sound sound)
{
- alSourcePlay(sound.source); // Play the sound
-
- printf("Playing sound!\n");
-
- // Find the current position of the sound being played
- // NOTE: Only work when the entire file is in a single buffer
- //int byteOffset;
- //alGetSourcei(sound.source, AL_BYTE_OFFSET, &byteOffset);
- //float seconds = (float)byteOffset / sampleRate; // Number of seconds since the beginning of the sound
+ alSourcePlay(sound.source); // Play the sound
+
+ printf("Playing sound!\n");
+
+ // Find the current position of the sound being played
+ // NOTE: Only work when the entire file is in a single buffer
+ //int byteOffset;
+ //alGetSourcei(sound.source, AL_BYTE_OFFSET, &byteOffset);
+ //float seconds = (float)byteOffset / sampleRate; // Number of seconds since the beginning of the sound
}
// Play a sound with extended options
void PlaySoundEx(Sound sound, float timePosition, bool loop)
{
- // TODO: Review
-
- // Change the current position (e.g. skip some part of the sound)
- // NOTE: Only work when the entire file is in a single buffer
- //alSourcei(sound.source, AL_BYTE_OFFSET, int(position * sampleRate));
-
- alSourcePlay(sound.source); // Play the sound
-
- if (loop) alSourcei(sound.source, AL_LOOPING, AL_TRUE);
- else alSourcei(sound.source, AL_LOOPING, AL_FALSE);
+ // TODO: Review
+
+ // Change the current position (e.g. skip some part of the sound)
+ // NOTE: Only work when the entire file is in a single buffer
+ //alSourcei(sound.source, AL_BYTE_OFFSET, int(position * sampleRate));
+
+ alSourcePlay(sound.source); // Play the sound
+
+ if (loop) alSourcei(sound.source, AL_LOOPING, AL_TRUE);
+ else alSourcei(sound.source, AL_LOOPING, AL_FALSE);
}
// Pause a sound
void PauseSound(Sound sound)
{
- alSourcePause(sound.source);
+ alSourcePause(sound.source);
}
// Stop reproducing a sound
void StopSound(Sound sound)
{
- alSourceStop(sound.source);
+ alSourceStop(sound.source);
}
// Load WAV file into Wave structure
static Wave LoadWAV(char *fileName)
{
- Wave wave;
+ Wave wave;
FILE *wavFile;
wavFile = fopen(fileName, "rb");
-
- if (!wavFile)
- {
- printf("Could not load WAV file.\n");
- exit(1);
- }
-
- unsigned char id[4]; // Four bytes to hold 'RIFF' and 'WAVE' (and other ids)
-
- unsigned int size = 0; // File size (useless)
-
- short format;
- short channels;
- short blockAlign;
- short bitsPerSample;
-
- unsigned int formatLength;
- unsigned int sampleRate;
- unsigned int avgBytesSec;
- unsigned int dataSize;
-
- fread(id, sizeof(unsigned char), 4, wavFile); // Read the first four bytes
-
- if ((id[0] != 'R') || (id[1] != 'I') || (id[2] != 'F') || (id[3] != 'F'))
- {
- printf("Invalid RIFF file.\n"); // If not "RIFF" id, exit
- exit(1);
- }
-
- fread(&size, sizeof(unsigned int), 1, wavFile); // Read file size
- fread(id, sizeof(unsigned char), 4, wavFile); // Read the next id
-
- if ((id[0] != 'W') || (id[1] != 'A') || (id[2] != 'V') || (id[3] != 'E'))
- {
- printf("Invalid WAVE file.\n"); // If not "WAVE" id, exit
- exit(1);
- }
-
- fread(id, sizeof(unsigned char), 4, wavFile); // Read 4 bytes id "fmt "
- fread(&formatLength, sizeof(unsigned int),1,wavFile); // Read format lenght
- fread(&format, sizeof(short), 1, wavFile); // Read format tag
- fread(&channels, sizeof(short), 1, wavFile); // Read num channels (1 mono, 2 stereo)
- fread(&sampleRate, sizeof(unsigned int), 1, wavFile); // Read sample rate (44100, 22050, etc...)
- fread(&avgBytesSec, sizeof(short), 1, wavFile); // Read average bytes per second (probably won't need this)
- fread(&blockAlign, sizeof(short), 1, wavFile); // Read block alignment (probably won't need this)
- fread(&bitsPerSample, sizeof(short), 1, wavFile); // Read bits per sample (8 bit or 16 bit)
-
- fread(id, sizeof(unsigned char), 4, wavFile); // Read 4 bytes id "data"
- fread(&dataSize, sizeof(unsigned int), 1, wavFile); // Read data size (in bytes)
-
- wave.sampleRate = sampleRate;
- wave.dataSize = dataSize;
- wave.channels = channels;
- wave.format = format;
-
- wave.data = (unsigned char *)malloc(sizeof(unsigned char) * dataSize); // Allocate the required bytes to store data
-
- fread(wave.data, sizeof(unsigned char), dataSize, wavFile); // Read the whole sound data chunk
-
- return wave;
+
+ if (!wavFile)
+ {
+ printf("Could not load WAV file.\n");
+ exit(1);
+ }
+
+ unsigned char id[4]; // Four bytes to hold 'RIFF' and 'WAVE' (and other ids)
+
+ unsigned int size = 0; // File size (useless)
+
+ short format;
+ short channels;
+ short blockAlign;
+ short bitsPerSample;
+
+ unsigned int formatLength;
+ unsigned int sampleRate;
+ unsigned int avgBytesSec;
+ unsigned int dataSize;
+
+ fread(id, sizeof(unsigned char), 4, wavFile); // Read the first four bytes
+
+ if ((id[0] != 'R') || (id[1] != 'I') || (id[2] != 'F') || (id[3] != 'F'))
+ {
+ printf("Invalid RIFF file.\n"); // If not "RIFF" id, exit
+ exit(1);
+ }
+
+ fread(&size, sizeof(unsigned int), 1, wavFile); // Read file size
+ fread(id, sizeof(unsigned char), 4, wavFile); // Read the next id
+
+ if ((id[0] != 'W') || (id[1] != 'A') || (id[2] != 'V') || (id[3] != 'E'))
+ {
+ printf("Invalid WAVE file.\n"); // If not "WAVE" id, exit
+ exit(1);
+ }
+
+ fread(id, sizeof(unsigned char), 4, wavFile); // Read 4 bytes id "fmt "
+ fread(&formatLength, sizeof(unsigned int),1,wavFile); // Read format lenght
+ fread(&format, sizeof(short), 1, wavFile); // Read format tag
+ fread(&channels, sizeof(short), 1, wavFile); // Read num channels (1 mono, 2 stereo)
+ fread(&sampleRate, sizeof(unsigned int), 1, wavFile); // Read sample rate (44100, 22050, etc...)
+ fread(&avgBytesSec, sizeof(short), 1, wavFile); // Read average bytes per second (probably won't need this)
+ fread(&blockAlign, sizeof(short), 1, wavFile); // Read block alignment (probably won't need this)
+ fread(&bitsPerSample, sizeof(short), 1, wavFile); // Read bits per sample (8 bit or 16 bit)
+
+ fread(id, sizeof(unsigned char), 4, wavFile); // Read 4 bytes id "data"
+ fread(&dataSize, sizeof(unsigned int), 1, wavFile); // Read data size (in bytes)
+
+ wave.sampleRate = sampleRate;
+ wave.dataSize = dataSize;
+ wave.channels = channels;
+ wave.format = format;
+
+ wave.data = (unsigned char *)malloc(sizeof(unsigned char) * dataSize); // Allocate the required bytes to store data
+
+ fread(wave.data, sizeof(unsigned char), dataSize, wavFile); // Read the whole sound data chunk
+
+ return wave;
}
// Unload WAV file data
static void UnloadWAV(Wave wave)
{
- free(wave.data);
+ free(wave.data);
}
// TODO: Ogg data loading
diff --git a/src/core.c b/src/core.c
index c835cb5b..a784f4bb 100644
--- a/src/core.c
+++ b/src/core.c
@@ -1,41 +1,41 @@
/*********************************************************************************************
*
-* raylib.core
+* raylib.core
*
-* Basic functions to manage Windows, OpenGL context and Input
-*
-* Uses external lib:
-* GLFW3 - Window, context and Input management (static lib version)
+* Basic functions to manage Windows, OpenGL context and Input
+*
+* Uses external lib:
+* GLFW3 - Window, context and Input management (static lib version)
*
-* Copyright (c) 2013 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.
+* Copyright (c) 2013 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.
*
-* Permission is granted to anyone to use this software for any purpose, including commercial
-* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
-* 1. The origin of this software must not be misrepresented; you must not claim that you
-* wrote the original software. If you use this software in a product, an acknowledgment
-* in the product documentation would be appreciated but is not required.
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
*
-* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
-* as being the original software.
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
*
-* 3. This notice may not be removed or altered from any source distribution.
+* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include "raylib.h"
-#include <GLFW/glfw3.h> // GLFW3 lib: Windows, OpenGL context and Input management
-//#include <GL/gl.h> // OpenGL functions (GLFW3 already includes gl.h)
-#include <stdio.h> // Standard input / output lib
-#include <stdlib.h> // Declares malloc() and free() for memory management
-#include <math.h> // Math related functions, tan() on SetPerspective
-#include "vector3.h" // Basic Vector3 functions
+#include <GLFW/glfw3.h> // GLFW3 lib: Windows, OpenGL context and Input management
+//#include <GL/gl.h> // OpenGL functions (GLFW3 already includes gl.h)
+#include <stdio.h> // Standard input / output lib
+#include <stdlib.h> // Declares malloc() and free() for memory management
+#include <math.h> // Math related functions, tan() on SetPerspective
+#include "vector3.h" // Basic Vector3 functions
-//#define GLFW_DLL // Using GLFW DLL on Windows -> No, we use static version!
+//#define GLFW_DLL // Using GLFW DLL on Windows -> No, we use static version!
//----------------------------------------------------------------------------------
// Defines and Macros
@@ -50,34 +50,34 @@ typedef Color pixel;
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
-static GLFWwindow* window; // Main window
-static bool fullscreen; // Fullscreen mode track
+static GLFWwindow* window; // Main window
+static bool fullscreen; // Fullscreen mode track
-static double currentTime, previousTime; // Used to track timmings
-static double updateTime, drawTime; // Time measures for update and draw
-static double frameTime; // Time measure for one frame
-static double targetTime = 0; // Desired time for one frame, if 0 not applied
+static double currentTime, previousTime; // Used to track timmings
+static double updateTime, drawTime; // Time measures for update and draw
+static double frameTime; // Time measure for one frame
+static double targetTime = 0; // Desired time for one frame, if 0 not applied
-static int windowWidth, windowHeight; // Required to switch between windowed/fullscren mode (F11)
-static char *windowTitle; // Required to switch between windowed/fullscren mode (F11)
+static int windowWidth, windowHeight; // Required to switch between windowed/fullscren mode (F11)
+static char *windowTitle; // Required to switch between windowed/fullscren mode (F11)
//----------------------------------------------------------------------------------
// Other Modules Functions Declaration (required by core)
//----------------------------------------------------------------------------------
-extern void LoadDefaultFont(); // [Module: text] Loads default font on InitWindow()
-extern void UnloadDefaultFont(); // [Module: text] Unloads default font from GPU memory
-extern void WriteBitmap(const char *fileName, const pixel *imgDataPixel, int width, int height); // [Module: textures] Writes a bitmap (BMP) file
+extern void LoadDefaultFont(); // [Module: text] Loads default font on InitWindow()
+extern void UnloadDefaultFont(); // [Module: text] Unloads default font from GPU memory
+extern void WriteBitmap(const char *fileName, const pixel *imgDataPixel, int width, int height); // [Module: textures] Writes a bitmap (BMP) file
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
-static void InitGraphicsDevice(); // Initialize Graphics Device (OpenGL stuff)
-static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
-static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed
-static void WindowSizeCallback(GLFWwindow* window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
-static void CameraLookAt(Vector3 position, Vector3 target, Vector3 up); // Setup camera view (updates MODELVIEW matrix)
-static void SetPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); // Setup view projection (updates PROJECTION matrix)
-static void TakeScreenshot(); // Takes a bitmap (BMP) screenshot and saves it in the same folder as executable
+static void InitGraphicsDevice(); // Initialize Graphics Device (OpenGL stuff)
+static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
+static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed
+static void WindowSizeCallback(GLFWwindow* window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
+static void CameraLookAt(Vector3 position, Vector3 target, Vector3 up); // Setup camera view (updates MODELVIEW matrix)
+static void SetPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); // Setup view projection (updates PROJECTION matrix)
+static void TakeScreenshot(); // Takes a bitmap (BMP) screenshot and saves it in the same folder as executable
//----------------------------------------------------------------------------------
// Module Functions Definition - Window and OpenGL Context Functions
@@ -87,202 +87,202 @@ static void TakeScreenshot(); // Takes a bitmap (BMP) screenshot
void InitWindow(int width, int height, char* title)
{
glfwSetErrorCallback(ErrorCallback);
-
+
if (!glfwInit()) exit(1);
-
- //glfwWindowHint(GLFW_SAMPLES, 4); // If called before windows creation, enables multisampling x4 (MSAA), default is 0
-
+
+ //glfwWindowHint(GLFW_SAMPLES, 4); // If called before windows creation, enables multisampling x4 (MSAA), default is 0
+
window = glfwCreateWindow(width, height, title, NULL, NULL);
-
- windowWidth = width;
- windowHeight = height;
- windowTitle = title;
-
+
+ windowWidth = width;
+ windowHeight = height;
+ windowTitle = title;
+
if (!window)
{
glfwTerminate();
exit(1);
}
-
- glfwSetWindowSizeCallback(window, WindowSizeCallback);
-
- glfwMakeContextCurrent(window);
- glfwSetKeyCallback(window, KeyCallback);
- glfwSwapInterval(0); // Disables GPU v-sync (if set), so frames are not limited to screen refresh rate (60Hz -> 60 FPS)
- // If not set, swap interval uses GPU v-sync configuration
- // Framerate can be setup using SetTargetFPS()
- InitGraphicsDevice();
-
- previousTime = glfwGetTime();
-
- LoadDefaultFont();
+
+ glfwSetWindowSizeCallback(window, WindowSizeCallback);
+
+ glfwMakeContextCurrent(window);
+ glfwSetKeyCallback(window, KeyCallback);
+ glfwSwapInterval(0); // Disables GPU v-sync (if set), so frames are not limited to screen refresh rate (60Hz -> 60 FPS)
+ // If not set, swap interval uses GPU v-sync configuration
+ // Framerate can be setup using SetTargetFPS()
+ InitGraphicsDevice();
+
+ previousTime = glfwGetTime();
+
+ LoadDefaultFont();
}
// Close Window and Terminate Context
void CloseWindow()
{
- UnloadDefaultFont();
+ UnloadDefaultFont();
glfwDestroyWindow(window);
- glfwTerminate();
+ glfwTerminate();
}
// Detect if KEY_ESCAPE pressed or Close icon pressed
bool WindowShouldClose()
{
- return (glfwWindowShouldClose(window));
+ return (glfwWindowShouldClose(window));
}
// Fullscreen toggle (by default F11)
void ToggleFullscreen()
{
- if (glfwGetKey(window, GLFW_KEY_F11))
- {
- fullscreen = !fullscreen; // Toggle fullscreen flag
-
- glfwDestroyWindow(window); // Destroy the current window (we will recreate it!)
-
- // NOTE: Window aspect ratio is always windowWidth / windowHeight
- if (fullscreen) window = glfwCreateWindow(windowWidth, windowHeight, windowTitle, glfwGetPrimaryMonitor(), NULL); // Fullscreen mode
- else window = glfwCreateWindow(windowWidth, windowHeight, windowTitle, NULL, NULL);
-
- if (!window)
- {
- glfwTerminate();
- exit(1);
- }
-
- glfwMakeContextCurrent(window);
- glfwSetKeyCallback(window, KeyCallback);
-
- InitGraphicsDevice();
- }
+ if (glfwGetKey(window, GLFW_KEY_F11))
+ {
+ fullscreen = !fullscreen; // Toggle fullscreen flag
+
+ glfwDestroyWindow(window); // Destroy the current window (we will recreate it!)
+
+ // NOTE: Window aspect ratio is always windowWidth / windowHeight
+ if (fullscreen) window = glfwCreateWindow(windowWidth, windowHeight, windowTitle, glfwGetPrimaryMonitor(), NULL); // Fullscreen mode
+ else window = glfwCreateWindow(windowWidth, windowHeight, windowTitle, NULL, NULL);
+
+ if (!window)
+ {
+ glfwTerminate();
+ exit(1);
+ }
+
+ glfwMakeContextCurrent(window);
+ glfwSetKeyCallback(window, KeyCallback);
+
+ InitGraphicsDevice();
+ }
}
// Sets Background Color
void ClearBackground(Color color)
{
- // Color values clamp to 0.0f(0) and 1.0f(255)
- float r = (float)color.r / 255;
- float g = (float)color.g / 255;
- float b = (float)color.b / 255;
- float a = (float)color.a / 255;
-
- glClearColor(r, g, b, a);
+ // Color values clamp to 0.0f(0) and 1.0f(255)
+ float r = (float)color.r / 255;
+ float g = (float)color.g / 255;
+ float b = (float)color.b / 255;
+ float a = (float)color.a / 255;
+
+ glClearColor(r, g, b, a);
}
// Setup drawing canvas to start drawing
void BeginDrawing()
{
- currentTime = glfwGetTime(); // glfwGetTime() returns a 'double' containing the number of elapsed seconds since glfwInit() was called
- updateTime = currentTime - previousTime;
- previousTime = currentTime;
+ currentTime = glfwGetTime(); // glfwGetTime() returns a 'double' containing the number of elapsed seconds since glfwInit() was called
+ updateTime = currentTime - previousTime;
+ previousTime = currentTime;
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers, Depth Buffer is used for 3D
-
- glLoadIdentity(); // Reset current matrix (MODELVIEW)
-
- glTranslatef(0.375, 0.375, 0); // HACK to have 2D pixel-perfect drawing on OpenGL
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers, Depth Buffer is used for 3D
+
+ glLoadIdentity(); // Reset current matrix (MODELVIEW)
+
+ glTranslatef(0.375, 0.375, 0); // HACK to have 2D pixel-perfect drawing on OpenGL
}
// End canvas drawing and Swap Buffers (Double Buffering)
void EndDrawing()
{
- glfwSwapBuffers(window); // Swap back and front buffers
- glfwPollEvents(); // Register keyboard/mouse events
-
- currentTime = glfwGetTime();
- drawTime = currentTime - previousTime;
- previousTime = currentTime;
-
- frameTime = updateTime + drawTime;
-
- double extraTime = 0;
-
- while (frameTime < targetTime)
- {
- // Implement a delay
- currentTime = glfwGetTime();
- extraTime = currentTime - previousTime;
- previousTime = currentTime;
- frameTime += extraTime;
- }
+ glfwSwapBuffers(window); // Swap back and front buffers
+ glfwPollEvents(); // Register keyboard/mouse events
+
+ currentTime = glfwGetTime();
+ drawTime = currentTime - previousTime;
+ previousTime = currentTime;
+
+ frameTime = updateTime + drawTime;
+
+ double extraTime = 0;
+
+ while (frameTime < targetTime)
+ {
+ // Implement a delay
+ currentTime = glfwGetTime();
+ extraTime = currentTime - previousTime;
+ previousTime = currentTime;
+ frameTime += extraTime;
+ }
}
// Initializes 3D mode for drawing (Camera setup)
void Begin3dMode(Camera camera)
{
- //glEnable(GL_LIGHTING); // TODO: Setup proper lighting system (raylib 1.x)
-
- glMatrixMode(GL_PROJECTION); // Switch to projection matrix
-
- glPushMatrix(); // Save previous matrix, which contains the settings for the 2d ortho projection
- glLoadIdentity(); // Reset current matrix (PROJECTION)
-
- SetPerspective(45.0f, (GLfloat)windowWidth/(GLfloat)windowHeight, 0.1f, 100.0f); // Setup perspective projection
-
- glMatrixMode(GL_MODELVIEW); // Switch back to modelview matrix
- glLoadIdentity(); // Reset current matrix (MODELVIEW)
-
- CameraLookAt(camera.position, camera.target, camera.up); // Setup Camera view
+ //glEnable(GL_LIGHTING); // TODO: Setup proper lighting system (raylib 1.x)
+
+ glMatrixMode(GL_PROJECTION); // Switch to projection matrix
+
+ glPushMatrix(); // Save previous matrix, which contains the settings for the 2d ortho projection
+ glLoadIdentity(); // Reset current matrix (PROJECTION)
+
+ SetPerspective(45.0f, (GLfloat)windowWidth/(GLfloat)windowHeight, 0.1f, 100.0f); // Setup perspective projection
+
+ glMatrixMode(GL_MODELVIEW); // Switch back to modelview matrix
+ glLoadIdentity(); // Reset current matrix (MODELVIEW)
+
+ CameraLookAt(camera.position, camera.target, camera.up); // Setup Camera view
}
// Ends 3D mode and returns to default 2D orthographic mode
void End3dMode()
{
- glMatrixMode(GL_PROJECTION); // Switch to projection matrix
- glPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack
-
- glMatrixMode(GL_MODELVIEW); // Get back to modelview matrix
- glLoadIdentity(); // Reset current matrix (MODELVIEW)
-
- glTranslatef(0.375, 0.375, 0); // HACK to ensure pixel-perfect drawing on OpenGL (after exiting 3D mode)
-
- //glDisable(GL_LIGHTING); // TODO: Setup proper lighting system (raylib 1.x)
+ glMatrixMode(GL_PROJECTION); // Switch to projection matrix
+ glPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack
+
+ glMatrixMode(GL_MODELVIEW); // Get back to modelview matrix
+ glLoadIdentity(); // Reset current matrix (MODELVIEW)
+
+ glTranslatef(0.375, 0.375, 0); // HACK to ensure pixel-perfect drawing on OpenGL (after exiting 3D mode)
+
+ //glDisable(GL_LIGHTING); // TODO: Setup proper lighting system (raylib 1.x)
}
// Set target FPS for the game
void SetTargetFPS(int fps)
{
- targetTime = 1 / (float)fps;
-
- printf("TargetTime per Frame: %f seconds\n", (float)targetTime);
+ targetTime = 1 / (float)fps;
+
+ printf("TargetTime per Frame: %f seconds\n", (float)targetTime);
}
// Returns current FPS
float GetFPS()
{
- return (1/(float)frameTime);
+ return (1/(float)frameTime);
}
// Returns time in seconds for one frame
float GetFrameTime()
{
- // As we are operating quite a lot with frameTime, it could be no stable
- // so we round it before before passing around to be used
- // NOTE: There are still problems with high framerates (>500fps)
- double roundedFrameTime = round(frameTime*10000) / 10000;
-
- return (float)roundedFrameTime; // Time in seconds to run a frame
+ // As we are operating quite a lot with frameTime, it could be no stable
+ // so we round it before before passing around to be used
+ // NOTE: There are still problems with high framerates (>500fps)
+ double roundedFrameTime = round(frameTime*10000) / 10000;
+
+ return (float)roundedFrameTime; // Time in seconds to run a frame
}
// Returns a Color struct from hexadecimal value
Color GetColor(int hexValue)
{
- Color color;
+ Color color;
- color.r = (unsigned char)(hexValue >> 24) & 0xFF;
- color.g = (unsigned char)(hexValue >> 16) & 0xFF;
- color.b = (unsigned char)(hexValue >> 8) & 0xFF;
- color.a = (unsigned char)hexValue & 0xFF;
-
- return color;
+ color.r = (unsigned char)(hexValue >> 24) & 0xFF;
+ color.g = (unsigned char)(hexValue >> 16) & 0xFF;
+ color.b = (unsigned char)(hexValue >> 8) & 0xFF;
+ color.a = (unsigned char)hexValue & 0xFF;
+
+ return color;
}
// Returns hexadecimal value for a Color
int GetHexValue(Color color)
{
- return ((color.a << 24) + (color.r << 16) + (color.g << 8) + color.b);
+ return ((color.a << 24) + (color.r << 16) + (color.g << 8) + color.b);
}
//----------------------------------------------------------------------------------
@@ -292,125 +292,125 @@ int GetHexValue(Color color)
// Detect if a key is being pressed (key held down)
bool IsKeyPressed(int key)
{
- if (glfwGetKey(window, key) == GLFW_PRESS) return true;
- else return false;
+ if (glfwGetKey(window, key) == GLFW_PRESS) return true;
+ else return false;
}
// Detect if a key is NOT being pressed (key not held down)
bool IsKeyReleased(int key)
{
- if (glfwGetKey(window, key) == GLFW_RELEASE) return true;
- else return false;
+ if (glfwGetKey(window, key) == GLFW_RELEASE) return true;
+ else return false;
}
// Detect if a mouse button is being pressed
bool IsMouseButtonPressed(int button)
{
- if (glfwGetMouseButton(window, button) == GLFW_PRESS) return true;
- else return false;
+ if (glfwGetMouseButton(window, button) == GLFW_PRESS) return true;
+ else return false;
}
// Detect if a mouse button is NOT being pressed
bool IsMouseButtonReleased(int button)
{
- if (glfwGetMouseButton(window, button) == GLFW_RELEASE) return true;
- else return false;
+ if (glfwGetMouseButton(window, button) == GLFW_RELEASE) return true;
+ else return false;
}
// Returns mouse position X
int GetMouseX()
{
- double mouseX;
- double mouseY;
-
- glfwGetCursorPos(window, &mouseX, &mouseY);
+ double mouseX;
+ double mouseY;
+
+ glfwGetCursorPos(window, &mouseX, &mouseY);
- return (int)mouseX;
+ return (int)mouseX;
}
// Returns mouse position Y
int GetMouseY()
{
- double mouseX;
- double mouseY;
-
- glfwGetCursorPos(window, &mouseX, &mouseY);
+ double mouseX;
+ double mouseY;
+
+ glfwGetCursorPos(window, &mouseX, &mouseY);
- return (int)mouseY;
+ return (int)mouseY;
}
// Returns mouse position XY
Vector2 GetMousePosition()
{
- double mouseX;
- double mouseY;
-
- glfwGetCursorPos(window, &mouseX, &mouseY);
-
- Vector2 position = { (float)mouseX, (float)mouseY };
+ double mouseX;
+ double mouseY;
+
+ glfwGetCursorPos(window, &mouseX, &mouseY);
+
+ Vector2 position = { (float)mouseX, (float)mouseY };
- return position;
+ return position;
}
// Detect if a gamepad is available
bool IsGamepadAvailable(int gamepad)
{
- int result = glfwJoystickPresent(gamepad);
-
- if (result == 1) return true;
- else return false;
+ int result = glfwJoystickPresent(gamepad);
+
+ if (result == 1) return true;
+ else return false;
}
// Return axis movement vector for a gamepad
Vector2 GetGamepadMovement(int gamepad)
{
- Vector2 vec = { 0, 0 };
-
- const float *axes;
+ Vector2 vec = { 0, 0 };
+
+ const float *axes;
int axisCount;
-
- axes = glfwGetJoystickAxes(gamepad, &axisCount);
-
- if (axisCount >= 2)
- {
- vec.x = axes[0]; // Left joystick X
- vec.y = axes[1]; // Left joystick Y
-
- //vec.x = axes[2]; // Right joystick X
- //vec.x = axes[3]; // Right joystick Y
- }
-
- return vec;
+
+ axes = glfwGetJoystickAxes(gamepad, &axisCount);
+
+ if (axisCount >= 2)
+ {
+ vec.x = axes[0]; // Left joystick X
+ vec.y = axes[1]; // Left joystick Y
+
+ //vec.x = axes[2]; // Right joystick X
+ //vec.x = axes[3]; // Right joystick Y
+ }
+
+ return vec;
}
// Detect if a gamepad button is being pressed
bool IsGamepadButtonPressed(int gamepad, int button)
{
- const unsigned char* buttons;
- int buttonsCount;
-
- buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
-
- if (buttons[button] == GLFW_PRESS)
- {
- return true;
- }
- else return false;
+ const unsigned char* buttons;
+ int buttonsCount;
+
+ buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
+
+ if (buttons[button] == GLFW_PRESS)
+ {
+ return true;
+ }
+ else return false;
}
// Detect if a gamepad button is NOT being pressed
bool IsGamepadButtonReleased(int gamepad, int button)
{
- const unsigned char* buttons;
- int buttonsCount;
-
- buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
-
- if (buttons[button] == GLFW_RELEASE)
- {
- return true;
- }
- else return false;
+ const unsigned char* buttons;
+ int buttonsCount;
+
+ buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
+
+ if (buttons[button] == GLFW_RELEASE)
+ {
+ return true;
+ }
+ else return false;
}
//----------------------------------------------------------------------------------
@@ -421,112 +421,112 @@ bool IsGamepadButtonReleased(int gamepad, int button)
static void ErrorCallback(int error, const char *description)
{
printf(description);
- //fprintf(stderr, description);
+ //fprintf(stderr, description);
}
// GLFW3 Keyboard Callback, runs on key pressed
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
- {
- glfwSetWindowShouldClose(window, GL_TRUE);
-
- // NOTE: Before closing window, while loop must be left!
- }
- else if (key == GLFW_KEY_F11 && action == GLFW_PRESS)
- {
- ToggleFullscreen();
- }
- else if (key == GLFW_KEY_F12 && action == GLFW_PRESS)
- {
- TakeScreenshot();
- }
+ {
+ glfwSetWindowShouldClose(window, GL_TRUE);
+
+ // NOTE: Before closing window, while loop must be left!
+ }
+ else if (key == GLFW_KEY_F11 && action == GLFW_PRESS)
+ {
+ ToggleFullscreen();
+ }
+ else if (key == GLFW_KEY_F12 && action == GLFW_PRESS)
+ {
+ TakeScreenshot();
+ }
}
// GLFW3 WindowSize Callback, runs when window is resized
static void WindowSizeCallback(GLFWwindow* window, int width, int height)
{
- InitGraphicsDevice(); // If window is resized, graphics device is re-initialized
- // NOTE: Aspect ratio does not change, so, image can be deformed
+ InitGraphicsDevice(); // If window is resized, graphics device is re-initialized
+ // NOTE: Aspect ratio does not change, so, image can be deformed
}
// Initialize Graphics Device (OpenGL stuff)
static void InitGraphicsDevice()
{
- int fbWidth, fbHeight;
-
- glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
-
- glViewport(0, 0, fbWidth, fbHeight); // Set viewport width and height
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers, depth buffer is used for 3D
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Set background color (black)
- glClearDepth(1.0f); // Clear depth buffer
-
- glEnable(GL_DEPTH_TEST); // Enables depth testing (required for 3D)
- glDepthFunc(GL_LEQUAL); // Type of depth testing to apply
-
- glEnable(GL_BLEND); // Enable color blending (required to work with transparencies)
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Color blending function (how colors are mixed)
-
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation (Deprecated in OGL 3.0)
- // Other options: GL_FASTEST, GL_DONT_CARE (default)
-
- glMatrixMode(GL_PROJECTION); // Switch to PROJECTION matrix
- glLoadIdentity(); // Reset current matrix (PROJECTION)
- glOrtho(0, fbWidth, fbHeight, 0, 0, 1); // Config orthographic mode: top-left corner --> (0,0)
- glMatrixMode(GL_MODELVIEW); // Switch back to MODELVIEW matrix
- glLoadIdentity(); // Reset current matrix (MODELVIEW)
-
- glDisable(GL_LIGHTING); // Lighting Disabled...
-
- // TODO: Create an efficient Lighting System with proper functions (raylib 1.x)
-/*
- glEnable(GL_COLOR_MATERIAL); // Enable materials, causes some glMaterial atributes to track the current color (glColor)...
- glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // Material types and where to apply them
- // NOTE: ONLY works with lighting; defines how light interacts with material
-
- glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmbient); // Define ambient light color property
- glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDiffuse); // Define diffuse light color property
- glLightfv(GL_LIGHT1, GL_POSITION, lightPosition); // Define light position
-
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT1); // Enable light one (8 lights available at the same time)
-*/
- // TODO: Review all shapes/models are drawn CCW and enable backface culling
-
- //glEnable(GL_CULL_FACE); // Enable backface culling (Disabled by default)
- //glCullFace(GL_BACK); // Cull the Back face (default)
- //glFrontFace(GL_CCW); // Front face are defined counter clockwise (default)
-
- glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation)
- // Possible options: GL_SMOOTH (Color interpolation) or GL_FLAT (no interpolation)
+ int fbWidth, fbHeight;
+
+ glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
+
+ glViewport(0, 0, fbWidth, fbHeight); // Set viewport width and height
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers, depth buffer is used for 3D
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Set background color (black)
+ glClearDepth(1.0f); // Clear depth buffer
+
+ glEnable(GL_DEPTH_TEST); // Enables depth testing (required for 3D)
+ glDepthFunc(GL_LEQUAL); // Type of depth testing to apply
+
+ glEnable(GL_BLEND); // Enable color blending (required to work with transparencies)
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Color blending function (how colors are mixed)
+
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation (Deprecated in OGL 3.0)
+ // Other options: GL_FASTEST, GL_DONT_CARE (default)
+
+ glMatrixMode(GL_PROJECTION); // Switch to PROJECTION matrix
+ glLoadIdentity(); // Reset current matrix (PROJECTION)
+ glOrtho(0, fbWidth, fbHeight, 0, 0, 1); // Config orthographic mode: top-left corner --> (0,0)
+ glMatrixMode(GL_MODELVIEW); // Switch back to MODELVIEW matrix
+ glLoadIdentity(); // Reset current matrix (MODELVIEW)
+
+ glDisable(GL_LIGHTING); // Lighting Disabled...
+
+ // TODO: Create an efficient Lighting System with proper functions (raylib 1.x)
+/*
+ glEnable(GL_COLOR_MATERIAL); // Enable materials, causes some glMaterial atributes to track the current color (glColor)...
+ glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // Material types and where to apply them
+ // NOTE: ONLY works with lighting; defines how light interacts with material
+
+ glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmbient); // Define ambient light color property
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDiffuse); // Define diffuse light color property
+ glLightfv(GL_LIGHT1, GL_POSITION, lightPosition); // Define light position
+
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT1); // Enable light one (8 lights available at the same time)
+*/
+ // TODO: Review all shapes/models are drawn CCW and enable backface culling
+
+ //glEnable(GL_CULL_FACE); // Enable backface culling (Disabled by default)
+ //glCullFace(GL_BACK); // Cull the Back face (default)
+ //glFrontFace(GL_CCW); // Front face are defined counter clockwise (default)
+
+ glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation)
+ // Possible options: GL_SMOOTH (Color interpolation) or GL_FLAT (no interpolation)
}
// Setup camera view (updates MODELVIEW matrix)
static void CameraLookAt(Vector3 position, Vector3 target, Vector3 up)
{
- float rotMatrix[16]; // Matrix to store camera rotation
+ float rotMatrix[16]; // Matrix to store camera rotation
- Vector3 rotX, rotY, rotZ; // Vectors to calculate camera rotations X, Y, Z (Euler)
+ Vector3 rotX, rotY, rotZ; // Vectors to calculate camera rotations X, Y, Z (Euler)
// Construct rotation matrix from vectors
- rotZ = VectorSubtract(position, target);
- VectorNormalize(&rotZ);
- rotY = up; // Y rotation vector
- rotX = VectorCrossProduct(rotY, rotZ); // X rotation vector = Y cross Z
- rotY = VectorCrossProduct(rotZ, rotX); // Recompute Y rotation = Z cross X
- VectorNormalize(&rotX); // X rotation vector normalization
- VectorNormalize(&rotY); // Y rotation vector normalization
+ rotZ = VectorSubtract(position, target);
+ VectorNormalize(&rotZ);
+ rotY = up; // Y rotation vector
+ rotX = VectorCrossProduct(rotY, rotZ); // X rotation vector = Y cross Z
+ rotY = VectorCrossProduct(rotZ, rotX); // Recompute Y rotation = Z cross X
+ VectorNormalize(&rotX); // X rotation vector normalization
+ VectorNormalize(&rotY); // Y rotation vector normalization
rotMatrix[0] = rotX.x;
- rotMatrix[1] = rotY.x;
- rotMatrix[2] = rotZ.x;
- rotMatrix[3] = 0.0f;
+ rotMatrix[1] = rotY.x;
+ rotMatrix[2] = rotZ.x;
+ rotMatrix[3] = 0.0f;
rotMatrix[4] = rotX.y;
- rotMatrix[5] = rotY.y;
+ rotMatrix[5] = rotY.y;
rotMatrix[6] = rotZ.y;
- rotMatrix[7] = 0.0f;
+ rotMatrix[7] = 0.0f;
rotMatrix[8] = rotX.z;
rotMatrix[9] = rotY.z;
rotMatrix[10] = rotZ.z;
@@ -536,9 +536,9 @@ static void CameraLookAt(Vector3 position, Vector3 target, Vector3 up)
rotMatrix[14] = 0.0f;
rotMatrix[15] = 1.0f;
- glMultMatrixf(rotMatrix); // Multiply MODELVIEW matrix by rotation matrix
+ glMultMatrixf(rotMatrix); // Multiply MODELVIEW matrix by rotation matrix
- glTranslatef(-position.x, -position.y, -position.z); // Translate eye to position
+ glTranslatef(-position.x, -position.y, -position.z); // Translate eye to position
}
// Setup view projection (updates PROJECTION matrix)
@@ -557,26 +557,26 @@ static void SetPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdou
// Takes a bitmap (BMP) screenshot and saves it in the same folder as executable
static void TakeScreenshot()
{
- static int shotNum = 0; // Screenshot number, increments every screenshot take during program execution
-
- char buffer[20]; // Buffer to store file name
- int fbWidth, fbHeight;
-
- Color *imgDataPixel; // Pixel image data array
+ static int shotNum = 0; // Screenshot number, increments every screenshot take during program execution
+
+ char buffer[20]; // Buffer to store file name
+ int fbWidth, fbHeight;
+
+ Color *imgDataPixel; // Pixel image data array
- glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
+ glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
- imgDataPixel = (Color *)malloc(fbWidth * fbHeight * sizeof(Color));
+ imgDataPixel = (Color *)malloc(fbWidth * fbHeight * sizeof(Color));
- // NOTE: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer
- glReadPixels(0, 0, fbWidth, fbHeight, GL_RGBA, GL_UNSIGNED_BYTE, imgDataPixel);
-
- sprintf(buffer, "screenshot%03i.bmp", shotNum);
+ // NOTE: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer
+ glReadPixels(0, 0, fbWidth, fbHeight, GL_RGBA, GL_UNSIGNED_BYTE, imgDataPixel);
+
+ sprintf(buffer, "screenshot%03i.bmp", shotNum);
- // NOTE: BMP directly stores data flipped vertically
- WriteBitmap(buffer, imgDataPixel, fbWidth, fbHeight); // Writes pixel data array into a bitmap (BMP) file
-
- free(imgDataPixel);
-
- shotNum++;
+ // NOTE: BMP directly stores data flipped vertically
+ WriteBitmap(buffer, imgDataPixel, fbWidth, fbHeight); // Writes pixel data array into a bitmap (BMP) file
+
+ free(imgDataPixel);
+
+ shotNum++;
} \ No newline at end of file
diff --git a/src/models.c b/src/models.c
index af5012eb..12db08ba 100644
--- a/src/models.c
+++ b/src/models.c
@@ -1,35 +1,35 @@
/*********************************************************************************************
*
-* raylib.models
+* raylib.models
*
-* Basic functions to draw 3d shapes and load/draw 3d models (.OBJ)
+* Basic functions to draw 3d shapes and load/draw 3d models (.OBJ)
*
-* Copyright (c) 2013 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.
+* Copyright (c) 2013 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.
*
-* Permission is granted to anyone to use this software for any purpose, including commercial
-* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
-* 1. The origin of this software must not be misrepresented; you must not claim that you
-* wrote the original software. If you use this software in a product, an acknowledgment
-* in the product documentation would be appreciated but is not required.
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
*
-* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
-* as being the original software.
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
*
-* 3. This notice may not be removed or altered from any source distribution.
+* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include "raylib.h"
-#include <GL/gl.h> // OpenGL functions
-#include <stdio.h> // Standard input/output functions, used to read model files data
-#include <stdlib.h> // Declares malloc() and free() for memory management
-#include <math.h> // Used for sin, cos, tan
-#include "vector3.h" // Basic Vector3 functions
+#include <GL/gl.h> // OpenGL functions
+#include <stdio.h> // Standard input/output functions, used to read model files data
+#include <stdlib.h> // Declares malloc() and free() for memory management
+#include <math.h> // Used for sin, cos, tan
+#include "vector3.h" // Basic Vector3 functions
//----------------------------------------------------------------------------------
// Defines and Macros
@@ -59,761 +59,761 @@
// NOTE: Cube position is de center position
void DrawCube(Vector3 position, float width, float height, float lenght, Color color)
{
- glPushMatrix();
- glTranslatef(position.x, position.y, position.z);
- //glRotatef(rotation, 0.0f, 1.0f, 0.0f);
- //glScalef(1.0f, 1.0f, 1.0f);
-
- glBegin(GL_QUADS);
- glColor4ub(color.r, color.g, color.b, color.a);
-
- // Front Face
- glNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
- glTexCoord2f(0.0f, 0.0f); glVertex3f(-width/2, -height/2, lenght/2); // Bottom Left Of The Texture and Quad
- glTexCoord2f(1.0f, 0.0f); glVertex3f( width/2, -height/2, lenght/2); // Bottom Right Of The Texture and Quad
- glTexCoord2f(1.0f, 1.0f); glVertex3f( width/2, height/2, lenght/2); // Top Right Of The Texture and Quad
- glTexCoord2f(0.0f, 1.0f); glVertex3f(-width/2, height/2, lenght/2); // Top Left Of The Texture and Quad
- // Back Face
- glNormal3f( 0.0f, 0.0f,-1.0f); // Normal Pointing Away From Viewer
- glTexCoord2f(1.0f, 0.0f); glVertex3f(-width/2, -height/2, -lenght/2); // Bottom Right Of The Texture and Quad
- glTexCoord2f(1.0f, 1.0f); glVertex3f(-width/2, height/2, -lenght/2); // Top Right Of The Texture and Quad
- glTexCoord2f(0.0f, 1.0f); glVertex3f( width/2, height/2, -lenght/2); // Top Left Of The Texture and Quad
- glTexCoord2f(0.0f, 0.0f); glVertex3f( width/2, -height/2, -lenght/2); // Bottom Left Of The Texture and Quad
- // Top Face
- glNormal3f( 0.0f, 1.0f, 0.0f); // Normal Pointing Up
- glTexCoord2f(0.0f, 1.0f); glVertex3f(-width/2, height/2, -lenght/2); // Top Left Of The Texture and Quad
- glTexCoord2f(0.0f, 0.0f); glVertex3f(-width/2, height/2, lenght/2); // Bottom Left Of The Texture and Quad
- glTexCoord2f(1.0f, 0.0f); glVertex3f( width/2, height/2, lenght/2); // Bottom Right Of The Texture and Quad
- glTexCoord2f(1.0f, 1.0f); glVertex3f( width/2, height/2, -lenght/2); // Top Right Of The Texture and Quad
- // Bottom Face
- glNormal3f( 0.0f,-1.0f, 0.0f); // Normal Pointing Down
- glTexCoord2f(1.0f, 1.0f); glVertex3f(-width/2, -height/2, -lenght/2); // Top Right Of The Texture and Quad
- glTexCoord2f(0.0f, 1.0f); glVertex3f( width/2, -height/2, -lenght/2); // Top Left Of The Texture and Quad
- glTexCoord2f(0.0f, 0.0f); glVertex3f( width/2, -height/2, lenght/2); // Bottom Left Of The Texture and Quad
- glTexCoord2f(1.0f, 0.0f); glVertex3f(-width/2, -height/2, lenght/2); // Bottom Right Of The Texture and Quad
- // Right face
- glNormal3f( 1.0f, 0.0f, 0.0f); // Normal Pointing Right
- glTexCoord2f(1.0f, 0.0f); glVertex3f( width/2, -height/2, -lenght/2); // Bottom Right Of The Texture and Quad
- glTexCoord2f(1.0f, 1.0f); glVertex3f( width/2, height/2, -lenght/2); // Top Right Of The Texture and Quad
- glTexCoord2f(0.0f, 1.0f); glVertex3f( width/2, height/2, lenght/2); // Top Left Of The Texture and Quad
- glTexCoord2f(0.0f, 0.0f); glVertex3f( width/2, -height/2, lenght/2); // Bottom Left Of The Texture and Quad
- // Left Face
- glNormal3f(-1.0f, 0.0f, 0.0f); // Normal Pointing Left
- glTexCoord2f(0.0f, 0.0f); glVertex3f(-width/2, -height/2, -lenght/2); // Bottom Left Of The Texture and Quad
- glTexCoord2f(1.0f, 0.0f); glVertex3f(-width/2, -height/2, lenght/2); // Bottom Right Of The Texture and Quad
- glTexCoord2f(1.0f, 1.0f); glVertex3f(-width/2, height/2, lenght/2); // Top Right Of The Texture and Quad
- glTexCoord2f(0.0f, 1.0f); glVertex3f(-width/2, height/2, -lenght/2); // Top Left Of The Texture and Quad
- glEnd();
- glPopMatrix();
+ glPushMatrix();
+ glTranslatef(position.x, position.y, position.z);
+ //glRotatef(rotation, 0.0f, 1.0f, 0.0f);
+ //glScalef(1.0f, 1.0f, 1.0f);
+
+ glBegin(GL_QUADS);
+ glColor4ub(color.r, color.g, color.b, color.a);
+
+ // Front Face
+ glNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
+ glTexCoord2f(0.0f, 0.0f); glVertex3f(-width/2, -height/2, lenght/2); // Bottom Left Of The Texture and Quad
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( width/2, -height/2, lenght/2); // Bottom Right Of The Texture and Quad
+ glTexCoord2f(1.0f, 1.0f); glVertex3f( width/2, height/2, lenght/2); // Top Right Of The Texture and Quad
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-width/2, height/2, lenght/2); // Top Left Of The Texture and Quad
+ // Back Face
+ glNormal3f( 0.0f, 0.0f,-1.0f); // Normal Pointing Away From Viewer
+ glTexCoord2f(1.0f, 0.0f); glVertex3f(-width/2, -height/2, -lenght/2); // Bottom Right Of The Texture and Quad
+ glTexCoord2f(1.0f, 1.0f); glVertex3f(-width/2, height/2, -lenght/2); // Top Right Of The Texture and Quad
+ glTexCoord2f(0.0f, 1.0f); glVertex3f( width/2, height/2, -lenght/2); // Top Left Of The Texture and Quad
+ glTexCoord2f(0.0f, 0.0f); glVertex3f( width/2, -height/2, -lenght/2); // Bottom Left Of The Texture and Quad
+ // Top Face
+ glNormal3f( 0.0f, 1.0f, 0.0f); // Normal Pointing Up
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-width/2, height/2, -lenght/2); // Top Left Of The Texture and Quad
+ glTexCoord2f(0.0f, 0.0f); glVertex3f(-width/2, height/2, lenght/2); // Bottom Left Of The Texture and Quad
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( width/2, height/2, lenght/2); // Bottom Right Of The Texture and Quad
+ glTexCoord2f(1.0f, 1.0f); glVertex3f( width/2, height/2, -lenght/2); // Top Right Of The Texture and Quad
+ // Bottom Face
+ glNormal3f( 0.0f,-1.0f, 0.0f); // Normal Pointing Down
+ glTexCoord2f(1.0f, 1.0f); glVertex3f(-width/2, -height/2, -lenght/2); // Top Right Of The Texture and Quad
+ glTexCoord2f(0.0f, 1.0f); glVertex3f( width/2, -height/2, -lenght/2); // Top Left Of The Texture and Quad
+ glTexCoord2f(0.0f, 0.0f); glVertex3f( width/2, -height/2, lenght/2); // Bottom Left Of The Texture and Quad
+ glTexCoord2f(1.0f, 0.0f); glVertex3f(-width/2, -height/2, lenght/2); // Bottom Right Of The Texture and Quad
+ // Right face
+ glNormal3f( 1.0f, 0.0f, 0.0f); // Normal Pointing Right
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( width/2, -height/2, -lenght/2); // Bottom Right Of The Texture and Quad
+ glTexCoord2f(1.0f, 1.0f); glVertex3f( width/2, height/2, -lenght/2); // Top Right Of The Texture and Quad
+ glTexCoord2f(0.0f, 1.0f); glVertex3f( width/2, height/2, lenght/2); // Top Left Of The Texture and Quad
+ glTexCoord2f(0.0f, 0.0f); glVertex3f( width/2, -height/2, lenght/2); // Bottom Left Of The Texture and Quad
+ // Left Face
+ glNormal3f(-1.0f, 0.0f, 0.0f); // Normal Pointing Left
+ glTexCoord2f(0.0f, 0.0f); glVertex3f(-width/2, -height/2, -lenght/2); // Bottom Left Of The Texture and Quad
+ glTexCoord2f(1.0f, 0.0f); glVertex3f(-width/2, -height/2, lenght/2); // Bottom Right Of The Texture and Quad
+ glTexCoord2f(1.0f, 1.0f); glVertex3f(-width/2, height/2, lenght/2); // Top Right Of The Texture and Quad
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-width/2, height/2, -lenght/2); // Top Left Of The Texture and Quad
+ glEnd();
+ glPopMatrix();
}
// Draw cube (Vector version)
void DrawCubeV(Vector3 position, Vector3 size, Color color)
{
- DrawCube(position, size.x, size.y, size.z, color);
+ DrawCube(position, size.x, size.y, size.z, color);
}
// Draw cube wires
void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color)
{
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- DrawCube(position, width, height, lenght, color);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ DrawCube(position, width, height, lenght, color);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
// Draw sphere
void DrawSphere(Vector3 centerPos, float radius, Color color)
{
- DrawSphereEx(centerPos, radius, 16, 16, color);
+ DrawSphereEx(centerPos, radius, 16, 16, color);
}
// Draw sphere with extended parameters
void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color)
{
- float lat0, z0, zr0;
- float lat1, z1, zr1;
- float lng, x, y;
-
- glPushMatrix();
- glTranslatef(centerPos.x, centerPos.y, centerPos.z);
- glRotatef(90, 1, 0, 0);
- glScalef(radius, radius, radius);
-
- glBegin(GL_QUAD_STRIP);
-
- glColor4ub(color.r, color.g, color.b, color.a);
-
- for(int i = 0; i <= rings; i++)
- {
- lat0 = PI * (-0.5 + (float)(i - 1) / rings);
- z0 = sin(lat0);
- zr0 = cos(lat0);
-
- lat1 = PI * (-0.5 + (float)i / rings);
- z1 = sin(lat1);
- zr1 = cos(lat1);
-
- for(int j = 0; j <= slices; j++)
- {
- lng = 2 * PI * (float)(j - 1) / slices;
- x = cos(lng);
- y = sin(lng);
-
- glNormal3f(x * zr0, y * zr0, z0);
- glVertex3f(x * zr0, y * zr0, z0);
-
- glNormal3f(x * zr1, y * zr1, z1);
- glVertex3f(x * zr1, y * zr1, z1);
- }
- }
- glEnd();
- glPopMatrix();
+ float lat0, z0, zr0;
+ float lat1, z1, zr1;
+ float lng, x, y;
+
+ glPushMatrix();
+ glTranslatef(centerPos.x, centerPos.y, centerPos.z);
+ glRotatef(90, 1, 0, 0);
+ glScalef(radius, radius, radius);
+
+ glBegin(GL_QUAD_STRIP);
+
+ glColor4ub(color.r, color.g, color.b, color.a);
+
+ for(int i = 0; i <= rings; i++)
+ {
+ lat0 = PI * (-0.5 + (float)(i - 1) / rings);
+ z0 = sin(lat0);
+ zr0 = cos(lat0);
+
+ lat1 = PI * (-0.5 + (float)i / rings);
+ z1 = sin(lat1);
+ zr1 = cos(lat1);
+
+ for(int j = 0; j <= slices; j++)
+ {
+ lng = 2 * PI * (float)(j - 1) / slices;
+ x = cos(lng);
+ y = sin(lng);
+
+ glNormal3f(x * zr0, y * zr0, z0);
+ glVertex3f(x * zr0, y * zr0, z0);
+
+ glNormal3f(x * zr1, y * zr1, z1);
+ glVertex3f(x * zr1, y * zr1, z1);
+ }
+ }
+ glEnd();
+ glPopMatrix();
}
// Draw sphere wires
void DrawSphereWires(Vector3 centerPos, float radius, Color color)
{
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- DrawSphere(centerPos, radius, color);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ DrawSphere(centerPos, radius, color);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
// Draw a cylinder/cone
-void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color) // Could be used for pyramid and cone!
+void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color) // Could be used for pyramid and cone!
{
- static int count = 0;
-
- Vector3 a = { position.x, position.y + height, position.z };
- Vector3 d = { 0.0f, 1.0f, 0.0f };
- Vector3 p;
- Vector3 c = { a.x + (-d.x * height), a.y + (-d.y * height), a.z + (-d.z * height) }; //= a + (-d * h);
- Vector3 e0 = VectorPerpendicular(d);
- Vector3 e1 = VectorCrossProduct(e0, d);
- float angInc = 360.0 / slices * DEG2RAD;
-
- if (radiusTop == 0) // Draw pyramid or cone
- {
- //void drawCone(const Vector3 &d, const Vector3 &a, const float h, const float rd, const int n)
- //d – axis defined as a normalized vector from base to apex
- //a – position of apex (top point)
- //h – height
- //rd – radius of directrix
- //n – number of radial "slices"
-
- glPushMatrix();
- //glTranslatef(centerPos.x, centerPos.y, centerPos.z);
- glRotatef(DEG2RAD*count, 0.0f, 1.0f, 0.0f);
- //glScalef(1.0f, 1.0f, 1.0f);
-
- // Draw cone top
- glBegin(GL_TRIANGLE_FAN);
- glColor4ub(color.r, color.g, color.b, color.a);
- glVertex3f(a.x, a.y, a.z);
- for (int i = 0; i <= slices; i++)
- {
- float rad = angInc * i;
- p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusBottom);
- p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusBottom);
- p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
- glVertex3f(p.x, p.y, p.z);
- }
- glEnd();
-
- // Draw cone bottom
- glBegin(GL_TRIANGLE_FAN);
- glColor4ub(color.r, color.g, color.b, color.a);
- glVertex3f(c.x, c.y, c.z);
- for (int i = slices; i >= 0; i--)
- {
- float rad = angInc * i;
- p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusBottom);
- p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusBottom);
- p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
- glVertex3f(p.x, p.y, p.z);
- }
- glEnd();
-
- glPopMatrix();
- }
- else // Draw cylinder
- {
- glPushMatrix();
- //glTranslatef(centerPos.x, centerPos.y, centerPos.z);
- glRotatef(DEG2RAD*count, 0.0f, 1.0f, 0.0f);
- //glScalef(1.0f, 1.0f, 1.0f);
-
- // Draw cylinder top (pointed cap)
- glBegin(GL_TRIANGLE_FAN);
- glColor4ub(color.r, color.g, color.b, color.a);
- glVertex3f(c.x, c.y + height, c.z);
- for (int i = slices; i >= 0; i--)
- {
- float rad = angInc * i;
- p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusTop);
- p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusTop) + height;
- p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusTop);
- glVertex3f(p.x, p.y, p.z);
- }
- glEnd();
-
- // Draw cylinder sides
- glBegin(GL_TRIANGLE_STRIP);
- glColor4ub(color.r, color.g, color.b, color.a);
- for (int i = slices; i >= 0; i--)
- {
- float rad = angInc * i;
- p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusTop);
- p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusTop) + height;
- p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusTop);
- glVertex3f(p.x, p.y, p.z);
-
- p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusBottom);
- p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusBottom);
- p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
- glVertex3f(p.x, p.y, p.z);
- }
- glEnd();
-
- // Draw cylinder bottom
- glBegin(GL_TRIANGLE_FAN);
- glColor4ub(color.r, color.g, color.b, color.a);
- glVertex3f(c.x, c.y, c.z);
- for (int i = slices; i >= 0; i--)
- {
- float rad = angInc * i;
- p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusBottom);
- p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusBottom);
- p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
- glVertex3f(p.x, p.y, p.z);
- }
- glEnd();
-
- glPopMatrix();
- }
-
- count += 1;
+ static int count = 0;
+
+ Vector3 a = { position.x, position.y + height, position.z };
+ Vector3 d = { 0.0f, 1.0f, 0.0f };
+ Vector3 p;
+ Vector3 c = { a.x + (-d.x * height), a.y + (-d.y * height), a.z + (-d.z * height) }; //= a + (-d * h);
+ Vector3 e0 = VectorPerpendicular(d);
+ Vector3 e1 = VectorCrossProduct(e0, d);
+ float angInc = 360.0 / slices * DEG2RAD;
+
+ if (radiusTop == 0) // Draw pyramid or cone
+ {
+ //void drawCone(const Vector3 &d, const Vector3 &a, const float h, const float rd, const int n)
+ //d – axis defined as a normalized vector from base to apex
+ //a – position of apex (top point)
+ //h – height
+ //rd – radius of directrix
+ //n – number of radial "slices"
+
+ glPushMatrix();
+ //glTranslatef(centerPos.x, centerPos.y, centerPos.z);
+ glRotatef(DEG2RAD*count, 0.0f, 1.0f, 0.0f);
+ //glScalef(1.0f, 1.0f, 1.0f);
+
+ // Draw cone top
+ glBegin(GL_TRIANGLE_FAN);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glVertex3f(a.x, a.y, a.z);
+ for (int i = 0; i <= slices; i++)
+ {
+ float rad = angInc * i;
+ p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusBottom);
+ p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusBottom);
+ p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
+ glVertex3f(p.x, p.y, p.z);
+ }
+ glEnd();
+
+ // Draw cone bottom
+ glBegin(GL_TRIANGLE_FAN);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glVertex3f(c.x, c.y, c.z);
+ for (int i = slices; i >= 0; i--)
+ {
+ float rad = angInc * i;
+ p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusBottom);
+ p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusBottom);
+ p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
+ glVertex3f(p.x, p.y, p.z);
+ }
+ glEnd();
+
+ glPopMatrix();
+ }
+ else // Draw cylinder
+ {
+ glPushMatrix();
+ //glTranslatef(centerPos.x, centerPos.y, centerPos.z);
+ glRotatef(DEG2RAD*count, 0.0f, 1.0f, 0.0f);
+ //glScalef(1.0f, 1.0f, 1.0f);
+
+ // Draw cylinder top (pointed cap)
+ glBegin(GL_TRIANGLE_FAN);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glVertex3f(c.x, c.y + height, c.z);
+ for (int i = slices; i >= 0; i--)
+ {
+ float rad = angInc * i;
+ p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusTop);
+ p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusTop) + height;
+ p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusTop);
+ glVertex3f(p.x, p.y, p.z);
+ }
+ glEnd();
+
+ // Draw cylinder sides
+ glBegin(GL_TRIANGLE_STRIP);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ for (int i = slices; i >= 0; i--)
+ {
+ float rad = angInc * i;
+ p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusTop);
+ p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusTop) + height;
+ p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusTop);
+ glVertex3f(p.x, p.y, p.z);
+
+ p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusBottom);
+ p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusBottom);
+ p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
+ glVertex3f(p.x, p.y, p.z);
+ }
+ glEnd();
+
+ // Draw cylinder bottom
+ glBegin(GL_TRIANGLE_FAN);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glVertex3f(c.x, c.y, c.z);
+ for (int i = slices; i >= 0; i--)
+ {
+ float rad = angInc * i;
+ p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusBottom);
+ p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusBottom);
+ p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
+ glVertex3f(p.x, p.y, p.z);
+ }
+ glEnd();
+
+ glPopMatrix();
+ }
+
+ count += 1;
}
// Draw a cylinder/cone wires
void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color)
{
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- DrawCylinder(position, radiusTop, radiusBottom, height, slices, color);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ DrawCylinder(position, radiusTop, radiusBottom, height, slices, color);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
// Draw a plane
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color)
{
- // NOTE: Plane is always created on XZ ground and then rotated
- glPushMatrix();
- glTranslatef(centerPos.x, centerPos.y, centerPos.z);
-
- // TODO: Review multiples rotations Gimbal-Lock... use matrix or quaternions...
- glRotatef(rotation.x, 1, 0, 0);
- glRotatef(rotation.y, 0, 1, 0);
- glRotatef(rotation.z, 0, 0, 1);
- glScalef(size.x, 1.0f, size.y);
-
- glBegin(GL_QUADS);
- glColor4ub(color.r, color.g, color.b, color.a);
- glNormal3f(0.0f, 1.0f, 0.0f);
- glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f, 0.0f, -0.5f);
- glTexCoord2f(1.0f, 0.0f); glVertex3f(0.5f, 0.0f, -0.5f);
- glTexCoord2f(1.0f, 1.0f); glVertex3f(0.5f, 0.0f, 0.5f);
- glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, 0.0f, 0.5f);
- glEnd();
-
- glPopMatrix();
+ // NOTE: Plane is always created on XZ ground and then rotated
+ glPushMatrix();
+ glTranslatef(centerPos.x, centerPos.y, centerPos.z);
+
+ // TODO: Review multiples rotations Gimbal-Lock... use matrix or quaternions...
+ glRotatef(rotation.x, 1, 0, 0);
+ glRotatef(rotation.y, 0, 1, 0);
+ glRotatef(rotation.z, 0, 0, 1);
+ glScalef(size.x, 1.0f, size.y);
+
+ glBegin(GL_QUADS);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glNormal3f(0.0f, 1.0f, 0.0f);
+ glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f, 0.0f, -0.5f);
+ glTexCoord2f(1.0f, 0.0f); glVertex3f(0.5f, 0.0f, -0.5f);
+ glTexCoord2f(1.0f, 1.0f); glVertex3f(0.5f, 0.0f, 0.5f);
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, 0.0f, 0.5f);
+ glEnd();
+
+ glPopMatrix();
}
// Draw a plane with divisions
void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color)
{
- float quadWidth = size.x / slicesX;
- float quadLenght = size.y / slicesZ;
-
- float texPieceW = 1 / size.x;
- float texPieceH = 1 / size.y;
-
- // NOTE: Plane is always created on XZ ground and then rotated
- glPushMatrix();
- glTranslatef(-size.x / 2, 0.0f, -size.y / 2);
- glTranslatef(centerPos.x, centerPos.y, centerPos.z);
-
- // TODO: Review multiples rotations Gimbal-Lock... use matrix or quaternions...
- glRotatef(rotation.x, 1, 0, 0);
- glRotatef(rotation.y, 0, 1, 0);
- glRotatef(rotation.z, 0, 0, 1);
-
- glBegin(GL_QUADS);
- glColor4ub(color.r, color.g, color.b, color.a);
- glNormal3f(0.0f, 1.0f, 0.0f);
-
- for (int z = 0; z < slicesZ; z++)
- {
- for (int x = 0; x < slicesX; x++)
- {
- // Draw the plane quad by quad (with textcoords)
- glTexCoord2f((float)x * texPieceW, (float)z * texPieceH);
- glVertex3f((float)x * quadWidth, 0.0f, (float)z * quadLenght);
-
- glTexCoord2f((float)x * texPieceW + texPieceW, (float)z * texPieceH);
- glVertex3f((float)x * quadWidth + quadWidth, 0.0f, (float)z * quadLenght);
-
- glTexCoord2f((float)x * texPieceW + texPieceW, (float)z * texPieceH + texPieceH);
- glVertex3f((float)x * quadWidth + quadWidth, 0.0f, (float)z * quadLenght + quadLenght);
-
- glTexCoord2f((float)x * texPieceW, (float)z * texPieceH + texPieceH);
- glVertex3f((float)x * quadWidth, 0.0f, (float)z * quadLenght + quadLenght);
- }
- }
- glEnd();
-
- glPopMatrix();
+ float quadWidth = size.x / slicesX;
+ float quadLenght = size.y / slicesZ;
+
+ float texPieceW = 1 / size.x;
+ float texPieceH = 1 / size.y;
+
+ // NOTE: Plane is always created on XZ ground and then rotated
+ glPushMatrix();
+ glTranslatef(-size.x / 2, 0.0f, -size.y / 2);
+ glTranslatef(centerPos.x, centerPos.y, centerPos.z);
+
+ // TODO: Review multiples rotations Gimbal-Lock... use matrix or quaternions...
+ glRotatef(rotation.x, 1, 0, 0);
+ glRotatef(rotation.y, 0, 1, 0);
+ glRotatef(rotation.z, 0, 0, 1);
+
+ glBegin(GL_QUADS);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glNormal3f(0.0f, 1.0f, 0.0f);
+
+ for (int z = 0; z < slicesZ; z++)
+ {
+ for (int x = 0; x < slicesX; x++)
+ {
+ // Draw the plane quad by quad (with textcoords)
+ glTexCoord2f((float)x * texPieceW, (float)z * texPieceH);
+ glVertex3f((float)x * quadWidth, 0.0f, (float)z * quadLenght);
+
+ glTexCoord2f((float)x * texPieceW + texPieceW, (float)z * texPieceH);
+ glVertex3f((float)x * quadWidth + quadWidth, 0.0f, (float)z * quadLenght);
+
+ glTexCoord2f((float)x * texPieceW + texPieceW, (float)z * texPieceH + texPieceH);
+ glVertex3f((float)x * quadWidth + quadWidth, 0.0f, (float)z * quadLenght + quadLenght);
+
+ glTexCoord2f((float)x * texPieceW, (float)z * texPieceH + texPieceH);
+ glVertex3f((float)x * quadWidth, 0.0f, (float)z * quadLenght + quadLenght);
+ }
+ }
+ glEnd();
+
+ glPopMatrix();
}
// Draw a grid centered at (0, 0, 0)
void DrawGrid(int slices, float spacing)
{
- int halfSlices = slices / 2;
-
- //glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
- //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
-
- glPushMatrix();
- glScalef(spacing, 1.0f, spacing);
-
- glBegin(GL_LINES);
- for(int i = -halfSlices; i <= halfSlices; i++)
- {
- if (i == 0) glColor3f(0.5f, 0.5f, 0.5f);
- else glColor3f(0.75f, 0.75f, 0.75f);
-
- glVertex3f((float)i, 0.0f, (float)-halfSlices);
- glVertex3f((float)i, 0.0f, (float)halfSlices);
-
- glVertex3f((float)-halfSlices, 0.0f, (float)i);
- glVertex3f((float)halfSlices, 0.0f, (float)i);
- }
- glEnd();
-
- glPopMatrix();
-
- //glDisable(GL_LINE_SMOOTH);
+ int halfSlices = slices / 2;
+
+ //glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
+ //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
+
+ glPushMatrix();
+ glScalef(spacing, 1.0f, spacing);
+
+ glBegin(GL_LINES);
+ for(int i = -halfSlices; i <= halfSlices; i++)
+ {
+ if (i == 0) glColor3f(0.5f, 0.5f, 0.5f);
+ else glColor3f(0.75f, 0.75f, 0.75f);
+
+ glVertex3f((float)i, 0.0f, (float)-halfSlices);
+ glVertex3f((float)i, 0.0f, (float)halfSlices);
+
+ glVertex3f((float)-halfSlices, 0.0f, (float)i);
+ glVertex3f((float)halfSlices, 0.0f, (float)i);
+ }
+ glEnd();
+
+ glPopMatrix();
+
+ //glDisable(GL_LINE_SMOOTH);
}
// Draw gizmo (with or without orbits)
void DrawGizmo(Vector3 position, bool orbits)
{
- // NOTE: RGB = XYZ
- float lenght = 1.0f;
- float radius = 1.0f;
-
- //glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
- //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
-
- glPushMatrix();
- glTranslatef(position.x, position.y, position.z);
- //glRotatef(rotation, 0, 1, 0);
- glScalef(lenght, lenght, lenght);
-
- glBegin(GL_LINES);
- glColor3f(1.0f, 0.0f, 0.0f);
- glVertex3f(0.0f, 0.0f, 0.0f);
- glVertex3f(1.0f, 0.0f, 0.0f);
-
- glColor3f(0.0f, 1.0f, 0.0f);
- glVertex3f(0.0f, 0.0f, 0.0f);
- glVertex3f(0.0f, 1.0f, 0.0f);
-
- glColor3f(0.0f, 0.0f, 1.0f);
- glVertex3f(0.0f, 0.0f, 0.0f);
- glVertex3f(0.0f, 0.0f, 1.0f);
- glEnd();
-
- if (orbits)
- {
- glBegin(GL_LINE_LOOP);
- glColor4f(1.0f, 0.0f, 0.0f, 0.4f);
- for (int i=0; i < 360; i++) glVertex3f(sin(DEG2RAD*i) * radius, 0, cos(DEG2RAD*i) * radius);
- glEnd();
-
- glBegin(GL_LINE_LOOP);
- glColor4f(0.0f, 1.0f, 0.0f, 0.4f);
- for (int i=0; i < 360; i++) glVertex3f(sin(DEG2RAD*i) * radius, cos(DEG2RAD*i) * radius, 0);
- glEnd();
-
- glBegin(GL_LINE_LOOP);
- glColor4f(0.0f, 0.0f, 1.0f, 0.4f);
- for (int i=0; i < 360; i++) glVertex3f(0, sin(DEG2RAD*i) * radius, cos(DEG2RAD*i) * radius);
- glEnd();
- }
-
- glPopMatrix();
-
- //glDisable(GL_LINE_SMOOTH);
+ // NOTE: RGB = XYZ
+ float lenght = 1.0f;
+ float radius = 1.0f;
+
+ //glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
+ //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
+
+ glPushMatrix();
+ glTranslatef(position.x, position.y, position.z);
+ //glRotatef(rotation, 0, 1, 0);
+ glScalef(lenght, lenght, lenght);
+
+ glBegin(GL_LINES);
+ glColor3f(1.0f, 0.0f, 0.0f);
+ glVertex3f(0.0f, 0.0f, 0.0f);
+ glVertex3f(1.0f, 0.0f, 0.0f);
+
+ glColor3f(0.0f, 1.0f, 0.0f);
+ glVertex3f(0.0f, 0.0f, 0.0f);
+ glVertex3f(0.0f, 1.0f, 0.0f);
+
+ glColor3f(0.0f, 0.0f, 1.0f);
+ glVertex3f(0.0f, 0.0f, 0.0f);
+ glVertex3f(0.0f, 0.0f, 1.0f);
+ glEnd();
+
+ if (orbits)
+ {
+ glBegin(GL_LINE_LOOP);
+ glColor4f(1.0f, 0.0f, 0.0f, 0.4f);
+ for (int i=0; i < 360; i++) glVertex3f(sin(DEG2RAD*i) * radius, 0, cos(DEG2RAD*i) * radius);
+ glEnd();
+
+ glBegin(GL_LINE_LOOP);
+ glColor4f(0.0f, 1.0f, 0.0f, 0.4f);
+ for (int i=0; i < 360; i++) glVertex3f(sin(DEG2RAD*i) * radius, cos(DEG2RAD*i) * radius, 0);
+ glEnd();
+
+ glBegin(GL_LINE_LOOP);
+ glColor4f(0.0f, 0.0f, 1.0f, 0.4f);
+ for (int i=0; i < 360; i++) glVertex3f(0, sin(DEG2RAD*i) * radius, cos(DEG2RAD*i) * radius);
+ glEnd();
+ }
+
+ glPopMatrix();
+
+ //glDisable(GL_LINE_SMOOTH);
}
// Load a 3d model (.OBJ)
// TODO: Add comments explaining this function process
Model LoadModel(const char *fileName)
{
- Model model;
-
- char dataType;
- char comments[200];
-
- int numVertex = 0;
- int numNormals = 0;
- int numTexCoords = 0;
- int numTriangles = 0;
-
- FILE* objfile;
+ Model model;
+
+ char dataType;
+ char comments[200];
+
+ int numVertex = 0;
+ int numNormals = 0;
+ int numTexCoords = 0;
+ int numTriangles = 0;
+
+ FILE* objfile;
objfile = fopen(fileName, "rt");
-
- while(!feof(objfile))
- {
- fscanf(objfile, "%c", &dataType);
-
- switch(dataType)
- {
- case '#': // It's a comment
- {
- fgets(comments, 200, objfile);
- } break;
- case 'v':
- {
- fscanf(objfile, "%c", &dataType);
-
- if (dataType == 't') // Read texCoord
- {
- fgets(comments, 200, objfile);
- fscanf(objfile, "%c", &dataType);
-
- while (dataType == 'v')
- {
- fgets(comments, 200, objfile);
- fscanf(objfile, "%c", &dataType);
- }
-
- if (dataType == '#')
- {
- fscanf(objfile, "%i", &numTexCoords);
- }
- else printf("Ouch! Something was wrong...");
-
- fgets(comments, 200, objfile);
- }
- else if (dataType == 'n') // Read normals
- {
- fgets(comments, 200, objfile);
- fscanf(objfile, "%c", &dataType);
-
- while (dataType == 'v')
- {
- fgets(comments, 200, objfile);
- fscanf(objfile, "%c", &dataType);
- }
-
- if (dataType == '#')
- {
- fscanf(objfile, "%i", &numNormals);
- }
- else printf("Ouch! Something was wrong...");
-
- fgets(comments, 200, objfile);
- }
- else // Read vertex
- {
- fgets(comments, 200, objfile);
- fscanf(objfile, "%c", &dataType);
-
- while (dataType == 'v')
- {
- fgets(comments, 200, objfile);
- fscanf(objfile, "%c", &dataType);
- }
-
- if (dataType == '#')
- {
- fscanf(objfile, "%i", &numVertex);
- }
- else printf("Ouch! Something was wrong...");
-
- fgets(comments, 200, objfile);
- }
- } break;
- case 'f':
- {
- fgets(comments, 200, objfile);
- fscanf(objfile, "%c", &dataType);
-
- while (dataType == 'f')
- {
- fgets(comments, 200, objfile);
- fscanf(objfile, "%c", &dataType);
- }
-
- if (dataType == '#')
- {
- fscanf(objfile, "%i", &numTriangles);
- }
- else printf("Ouch! Something was wrong...");
-
- fgets(comments, 200, objfile);
-
- } break;
- default: break;
- }
- }
-
- Vector3 midVertices[numVertex];
- Vector3 midNormals[numNormals];
- Vector2 midTexCoords[numTexCoords];
-
- model.numVertices = numTriangles*3;
-
- model.vertices = (Vector3 *)malloc(model.numVertices * sizeof(Vector3));
- model.normals = (Vector3 *)malloc(model.numVertices * sizeof(Vector3));
- model.texcoords = (Vector2 *)malloc(model.numVertices * sizeof(Vector2));
-
- int countVertex = 0;
- int countNormals = 0;
- int countTexCoords = 0;
-
- int countMaxVertex = 0;
-
- rewind(objfile);
-
- while(!feof(objfile))
- {
- fscanf(objfile, "%c", &dataType);
-
- switch(dataType)
- {
- case '#':
- {
- fgets(comments, 200, objfile);
- } break;
- case 'v':
- {
- fscanf(objfile, "%c", &dataType);
-
- if (dataType == 't') // Read texCoord
- {
- float useless = 0;
-
- fscanf(objfile, "%f %f %f", &midTexCoords[countTexCoords].x, &midTexCoords[countTexCoords].y, &useless);
- countTexCoords++;
-
- fscanf(objfile, "%c", &dataType);
- }
- else if (dataType == 'n') // Read normals
- {
- fscanf(objfile, "%f %f %f", &midNormals[countNormals].x, &midNormals[countNormals].y, &midNormals[countNormals].z );
- countNormals++;
-
- fscanf(objfile, "%c", &dataType);
- }
- else // Read vertex
- {
- fscanf(objfile, "%f %f %f", &midVertices[countVertex].x, &midVertices[countVertex].y, &midVertices[countVertex].z );
- countVertex++;
-
- fscanf(objfile, "%c", &dataType);
- }
- } break;
- case 'f':
- {
- int vNum, vtNum, vnNum;
- fscanf(objfile, "%c", &dataType);
- fscanf(objfile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
-
- model.vertices[countMaxVertex] = midVertices[vNum-1];
- model.normals[countMaxVertex] = midNormals[vnNum-1];
- model.texcoords[countMaxVertex].x = midTexCoords[vtNum-1].x;
- model.texcoords[countMaxVertex].y = -midTexCoords[vtNum-1].y;
- countMaxVertex++;
-
- fscanf(objfile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
-
- model.vertices[countMaxVertex] = midVertices[vNum-1];
- model.normals[countMaxVertex] = midNormals[vnNum-1];
- model.texcoords[countMaxVertex].x = midTexCoords[vtNum-1].x;
- model.texcoords[countMaxVertex].y = -midTexCoords[vtNum-1].y;
- countMaxVertex++;
-
- fscanf(objfile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
-
- model.vertices[countMaxVertex] = midVertices[vNum-1];
- model.normals[countMaxVertex] = midNormals[vnNum-1];
- model.texcoords[countMaxVertex].x = midTexCoords[vtNum-1].x;
- model.texcoords[countMaxVertex].y = -midTexCoords[vtNum-1].y;
- countMaxVertex++;
- } break;
- default: break;
- }
- }
-
- fclose(objfile);
-
- return model;
+
+ while(!feof(objfile))
+ {
+ fscanf(objfile, "%c", &dataType);
+
+ switch(dataType)
+ {
+ case '#': // It's a comment
+ {
+ fgets(comments, 200, objfile);
+ } break;
+ case 'v':
+ {
+ fscanf(objfile, "%c", &dataType);
+
+ if (dataType == 't') // Read texCoord
+ {
+ fgets(comments, 200, objfile);
+ fscanf(objfile, "%c", &dataType);
+
+ while (dataType == 'v')
+ {
+ fgets(comments, 200, objfile);
+ fscanf(objfile, "%c", &dataType);
+ }
+
+ if (dataType == '#')
+ {
+ fscanf(objfile, "%i", &numTexCoords);
+ }
+ else printf("Ouch! Something was wrong...");
+
+ fgets(comments, 200, objfile);
+ }
+ else if (dataType == 'n') // Read normals
+ {
+ fgets(comments, 200, objfile);
+ fscanf(objfile, "%c", &dataType);
+
+ while (dataType == 'v')
+ {
+ fgets(comments, 200, objfile);
+ fscanf(objfile, "%c", &dataType);
+ }
+
+ if (dataType == '#')
+ {
+ fscanf(objfile, "%i", &numNormals);
+ }
+ else printf("Ouch! Something was wrong...");
+
+ fgets(comments, 200, objfile);
+ }
+ else // Read vertex
+ {
+ fgets(comments, 200, objfile);
+ fscanf(objfile, "%c", &dataType);
+
+ while (dataType == 'v')
+ {
+ fgets(comments, 200, objfile);
+ fscanf(objfile, "%c", &dataType);
+ }
+
+ if (dataType == '#')
+ {
+ fscanf(objfile, "%i", &numVertex);
+ }
+ else printf("Ouch! Something was wrong...");
+
+ fgets(comments, 200, objfile);
+ }
+ } break;
+ case 'f':
+ {
+ fgets(comments, 200, objfile);
+ fscanf(objfile, "%c", &dataType);
+
+ while (dataType == 'f')
+ {
+ fgets(comments, 200, objfile);
+ fscanf(objfile, "%c", &dataType);
+ }
+
+ if (dataType == '#')
+ {
+ fscanf(objfile, "%i", &numTriangles);
+ }
+ else printf("Ouch! Something was wrong...");
+
+ fgets(comments, 200, objfile);
+
+ } break;
+ default: break;
+ }
+ }
+
+ Vector3 midVertices[numVertex];
+ Vector3 midNormals[numNormals];
+ Vector2 midTexCoords[numTexCoords];
+
+ model.numVertices = numTriangles*3;
+
+ model.vertices = (Vector3 *)malloc(model.numVertices * sizeof(Vector3));
+ model.normals = (Vector3 *)malloc(model.numVertices * sizeof(Vector3));
+ model.texcoords = (Vector2 *)malloc(model.numVertices * sizeof(Vector2));
+
+ int countVertex = 0;
+ int countNormals = 0;
+ int countTexCoords = 0;
+
+ int countMaxVertex = 0;
+
+ rewind(objfile);
+
+ while(!feof(objfile))
+ {
+ fscanf(objfile, "%c", &dataType);
+
+ switch(dataType)
+ {
+ case '#':
+ {
+ fgets(comments, 200, objfile);
+ } break;
+ case 'v':
+ {
+ fscanf(objfile, "%c", &dataType);
+
+ if (dataType == 't') // Read texCoord
+ {
+ float useless = 0;
+
+ fscanf(objfile, "%f %f %f", &midTexCoords[countTexCoords].x, &midTexCoords[countTexCoords].y, &useless);
+ countTexCoords++;
+
+ fscanf(objfile, "%c", &dataType);
+ }
+ else if (dataType == 'n') // Read normals
+ {
+ fscanf(objfile, "%f %f %f", &midNormals[countNormals].x, &midNormals[countNormals].y, &midNormals[countNormals].z );
+ countNormals++;
+
+ fscanf(objfile, "%c", &dataType);
+ }
+ else // Read vertex
+ {
+ fscanf(objfile, "%f %f %f", &midVertices[countVertex].x, &midVertices[countVertex].y, &midVertices[countVertex].z );
+ countVertex++;
+
+ fscanf(objfile, "%c", &dataType);
+ }
+ } break;
+ case 'f':
+ {
+ int vNum, vtNum, vnNum;
+ fscanf(objfile, "%c", &dataType);
+ fscanf(objfile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
+
+ model.vertices[countMaxVertex] = midVertices[vNum-1];
+ model.normals[countMaxVertex] = midNormals[vnNum-1];
+ model.texcoords[countMaxVertex].x = midTexCoords[vtNum-1].x;
+ model.texcoords[countMaxVertex].y = -midTexCoords[vtNum-1].y;
+ countMaxVertex++;
+
+ fscanf(objfile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
+
+ model.vertices[countMaxVertex] = midVertices[vNum-1];
+ model.normals[countMaxVertex] = midNormals[vnNum-1];
+ model.texcoords[countMaxVertex].x = midTexCoords[vtNum-1].x;
+ model.texcoords[countMaxVertex].y = -midTexCoords[vtNum-1].y;
+ countMaxVertex++;
+
+ fscanf(objfile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
+
+ model.vertices[countMaxVertex] = midVertices[vNum-1];
+ model.normals[countMaxVertex] = midNormals[vnNum-1];
+ model.texcoords[countMaxVertex].x = midTexCoords[vtNum-1].x;
+ model.texcoords[countMaxVertex].y = -midTexCoords[vtNum-1].y;
+ countMaxVertex++;
+ } break;
+ default: break;
+ }
+ }
+
+ fclose(objfile);
+
+ return model;
}
// Unload 3d model from memory
void UnloadModel(Model model)
{
- free(model.vertices);
- free(model.texcoords);
- free(model.normals);
+ free(model.vertices);
+ free(model.texcoords);
+ free(model.normals);
}
// Draw a model
void DrawModel(Model model, Vector3 position, float scale, Color color)
{
- // NOTE: For models we use Vertex Arrays (OpenGL 1.1)
- static float rotation = 0;
-
- glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex array
- glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Enable texture coords array
- glEnableClientState(GL_NORMAL_ARRAY); // Enable normals array
-
- glVertexPointer(3, GL_FLOAT, 0, model.vertices); // Pointer to vertex coords array
- glTexCoordPointer(2, GL_FLOAT, 0, model.texcoords); // Pointer to texture coords array
- glNormalPointer(GL_FLOAT, 0, model.normals); // Pointer to normals array
- //glColorPointer(4, GL_UNSIGNED_BYTE, 0, model.colors); // Pointer to colors array (NOT USED)
-
- glPushMatrix();
- glTranslatef(position.x, position.y, position.z);
- glRotatef(rotation * GetFrameTime(), 0, 1, 0);
- glScalef(scale, scale, scale);
-
- glColor4ub(color.r, color.g, color.b, color.a);
-
- glDrawArrays(GL_TRIANGLES, 0, model.numVertices);
- glPopMatrix();
-
- glDisableClientState(GL_VERTEX_ARRAY); // Disable vertex array
- glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Disable texture coords array
- glDisableClientState(GL_NORMAL_ARRAY); // Disable normals array
-
- rotation += 10;
+ // NOTE: For models we use Vertex Arrays (OpenGL 1.1)
+ static float rotation = 0;
+
+ glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex array
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Enable texture coords array
+ glEnableClientState(GL_NORMAL_ARRAY); // Enable normals array
+
+ glVertexPointer(3, GL_FLOAT, 0, model.vertices); // Pointer to vertex coords array
+ glTexCoordPointer(2, GL_FLOAT, 0, model.texcoords); // Pointer to texture coords array
+ glNormalPointer(GL_FLOAT, 0, model.normals); // Pointer to normals array
+ //glColorPointer(4, GL_UNSIGNED_BYTE, 0, model.colors); // Pointer to colors array (NOT USED)
+
+ glPushMatrix();
+ glTranslatef(position.x, position.y, position.z);
+ glRotatef(rotation * GetFrameTime(), 0, 1, 0);
+ glScalef(scale, scale, scale);
+
+ glColor4ub(color.r, color.g, color.b, color.a);
+
+ glDrawArrays(GL_TRIANGLES, 0, model.numVertices);
+ glPopMatrix();
+
+ glDisableClientState(GL_VERTEX_ARRAY); // Disable vertex array
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Disable texture coords array
+ glDisableClientState(GL_NORMAL_ARRAY); // Disable normals array
+
+ rotation += 10;
}
// Draw a textured model
void DrawModelEx(Model model, Texture2D texture, Vector3 position, float scale, Color tint)
{
- glEnable(GL_TEXTURE_2D);
-
- glBindTexture(GL_TEXTURE_2D, texture.glId);
-
- DrawModel(model, position, scale, tint);
-
- glDisable(GL_TEXTURE_2D);
+ glEnable(GL_TEXTURE_2D);
+
+ glBindTexture(GL_TEXTURE_2D, texture.glId);
+
+ DrawModel(model, position, scale, tint);
+
+ glDisable(GL_TEXTURE_2D);
}
// Draw a model wires
void DrawModelWires(Model model, Vector3 position, float scale, Color color)
{
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- DrawModel(model, position, scale, color);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ DrawModel(model, position, scale, color);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
// Draw a billboard
void DrawBillboard(Camera camera, Texture2D texture, Vector3 basePos, float size, Color tint)
{
- // NOTE: Billboard size will represent the width, height maintains aspect ratio
- Vector3 centerPos = { basePos.x, basePos.y + size * (float)texture.height/(float)texture.width/2, basePos.z };
- Vector2 sizeRatio = { size, size * (float)texture.height/texture.width };
- Vector3 rotation = { 90, 0, 0 };
-
- // TODO: Calculate Y rotation to face always camera (use matrix)
- // OPTION: Lock Y-axis
-
- glEnable(GL_TEXTURE_2D);
-
- glBindTexture(GL_TEXTURE_2D, texture.glId);
-
- DrawPlane(centerPos, sizeRatio, rotation, tint); // TODO: Review this function...
-
- glDisable(GL_TEXTURE_2D);
+ // NOTE: Billboard size will represent the width, height maintains aspect ratio
+ Vector3 centerPos = { basePos.x, basePos.y + size * (float)texture.height/(float)texture.width/2, basePos.z };
+ Vector2 sizeRatio = { size, size * (float)texture.height/texture.width };
+ Vector3 rotation = { 90, 0, 0 };
+
+ // TODO: Calculate Y rotation to face always camera (use matrix)
+ // OPTION: Lock Y-axis
+
+ glEnable(GL_TEXTURE_2D);
+
+ glBindTexture(GL_TEXTURE_2D, texture.glId);
+
+ DrawPlane(centerPos, sizeRatio, rotation, tint); // TODO: Review this function...
+
+ glDisable(GL_TEXTURE_2D);
}
// Draw a billboard (part of a texture defined by a rectangle)
void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 basePos, float size, Color tint)
{
- // NOTE: Billboard size will represent the width, height maintains aspect ratio
- Vector3 centerPos = { basePos.x, basePos.y + size * (float)texture.height/(float)texture.width/2, basePos.z };
- Vector2 sizeRatio = { size, size * (float)texture.height/texture.width };
- Vector3 rotation = { 90, 0, 0 };
-
- // TODO: Calculate Y rotation to face always camera (use matrix)
- // OPTION: Lock Y-axis
-
- glEnable(GL_TEXTURE_2D);
-
- glBindTexture(GL_TEXTURE_2D, texture.glId);
-
- // TODO: DrawPlane with correct textcoords for source rec.
-
- glDisable(GL_TEXTURE_2D);
+ // NOTE: Billboard size will represent the width, height maintains aspect ratio
+ Vector3 centerPos = { basePos.x, basePos.y + size * (float)texture.height/(float)texture.width/2, basePos.z };
+ Vector2 sizeRatio = { size, size * (float)texture.height/texture.width };
+ Vector3 rotation = { 90, 0, 0 };
+
+ // TODO: Calculate Y rotation to face always camera (use matrix)
+ // OPTION: Lock Y-axis
+
+ glEnable(GL_TEXTURE_2D);
+
+ glBindTexture(GL_TEXTURE_2D, texture.glId);
+
+ // TODO: DrawPlane with correct textcoords for source rec.
+
+ glDisable(GL_TEXTURE_2D);
}
// Draw a heightmap using a provided image data
void DrawHeightmap(Image heightmap, Vector3 centerPos, Vector3 scale, Color color)
{
- // NOTE: Pixel-data is interpreted as grey-scale (even being a color image)
- // NOTE: Heightmap resolution will depend on image size (one quad per pixel)
-
- // TODO: Review how this function works... probably we need:
- // Model LoadHeightmap(Image image, Vector3 resolution);
-
- // NOTE: We are allocating and de-allocating vertex data every frame! --> framerate drops 80%! CRAZY!
- Vector3 *terrainVertex = (Vector3 *)malloc(heightmap.width * heightmap.height * sizeof(Vector3));
-
- for (int z = 0; z < heightmap.height; z++)
- {
- for (int x = 0; x < heightmap.width; x++)
- {
- terrainVertex[z*heightmap.height + x].x = (float)(x*scale.x);
- terrainVertex[z*heightmap.height + x].y = ((float)heightmap.pixels[z*heightmap.height + x].r +
- (float)heightmap.pixels[z*heightmap.height + x].g +
- (float)heightmap.pixels[z*heightmap.height + x].b) / 3 * scale.y;
- terrainVertex[z*heightmap.height + x].z = (float)(-z*scale.z);
- }
- }
-
- // TODO: Texture coordinates and normals computing
-
- for (int z = 0; z < heightmap.height-1; z++)
- {
- glBegin(GL_TRIANGLE_STRIP);
- for (int x = 0; x < heightmap.width; x++)
- {
- glColor3f((float)heightmap.pixels[z*heightmap.height + x].r / 255.0f,
- (float)heightmap.pixels[z*heightmap.height + x].g / 255.0f,
- (float)heightmap.pixels[z*heightmap.height + x].b / 255.0f);
-
- glVertex3f(terrainVertex[z*heightmap.height + x].x, terrainVertex[z*heightmap.height + x].y, terrainVertex[z*heightmap.height + x].z);
- glVertex3f(terrainVertex[(z+1)*heightmap.height + x].x, terrainVertex[(z+1)*heightmap.height + x].y, terrainVertex[(z+1)*heightmap.height + x].z);
- }
- glEnd();
- }
-
- free(terrainVertex);
+ // NOTE: Pixel-data is interpreted as grey-scale (even being a color image)
+ // NOTE: Heightmap resolution will depend on image size (one quad per pixel)
+
+ // TODO: Review how this function works... probably we need:
+ // Model LoadHeightmap(Image image, Vector3 resolution);
+
+ // NOTE: We are allocating and de-allocating vertex data every frame! --> framerate drops 80%! CRAZY!
+ Vector3 *terrainVertex = (Vector3 *)malloc(heightmap.width * heightmap.height * sizeof(Vector3));
+
+ for (int z = 0; z < heightmap.height; z++)
+ {
+ for (int x = 0; x < heightmap.width; x++)
+ {
+ terrainVertex[z*heightmap.height + x].x = (float)(x*scale.x);
+ terrainVertex[z*heightmap.height + x].y = ((float)heightmap.pixels[z*heightmap.height + x].r +
+ (float)heightmap.pixels[z*heightmap.height + x].g +
+ (float)heightmap.pixels[z*heightmap.height + x].b) / 3 * scale.y;
+ terrainVertex[z*heightmap.height + x].z = (float)(-z*scale.z);
+ }
+ }
+
+ // TODO: Texture coordinates and normals computing
+
+ for (int z = 0; z < heightmap.height-1; z++)
+ {
+ glBegin(GL_TRIANGLE_STRIP);
+ for (int x = 0; x < heightmap.width; x++)
+ {
+ glColor3f((float)heightmap.pixels[z*heightmap.height + x].r / 255.0f,
+ (float)heightmap.pixels[z*heightmap.height + x].g / 255.0f,
+ (float)heightmap.pixels[z*heightmap.height + x].b / 255.0f);
+
+ glVertex3f(terrainVertex[z*heightmap.height + x].x, terrainVertex[z*heightmap.height + x].y, terrainVertex[z*heightmap.height + x].z);
+ glVertex3f(terrainVertex[(z+1)*heightmap.height + x].x, terrainVertex[(z+1)*heightmap.height + x].y, terrainVertex[(z+1)*heightmap.height + x].z);
+ }
+ glEnd();
+ }
+
+ free(terrainVertex);
}
void DrawHeightmapEx(Image heightmap, Texture2D texture, Vector3 centerPos, Vector3 scale, Color tint)
{
- glEnable(GL_TEXTURE_2D);
-
- glBindTexture(GL_TEXTURE_2D, texture.glId);
-
- // NOTE: No texture coordinates or normals defined at this moment...
- DrawHeightmap(heightmap, centerPos, scale, tint);
-
- glDisable(GL_TEXTURE_2D);
+ glEnable(GL_TEXTURE_2D);
+
+ glBindTexture(GL_TEXTURE_2D, texture.glId);
+
+ // NOTE: No texture coordinates or normals defined at this moment...
+ DrawHeightmap(heightmap, centerPos, scale, tint);
+
+ glDisable(GL_TEXTURE_2D);
} \ No newline at end of file
diff --git a/src/raylib.h b/src/raylib.h
index b004265f..c23834a0 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -1,56 +1,56 @@
/*********************************************************************************************
*
-* raylib 1.0.0 (www.raylib.com)
-*
-* A simple and easy-to-use library to learn C videogames programming
+* raylib 1.0.0 (www.raylib.com)
+*
+* A simple and easy-to-use library to learn C videogames programming
*
-* Features:
-* Library written in plain C code (C99)
-* Uses C# PascalCase/camelCase notation
-* Hardware accelerated with OpenGL 1.1
-* Powerful fonts module with SpriteFonts support
-* Basic 3d support for Shapes and Models
-* Audio loading and playing
-*
-* Used external libs:
-* GLFW3 (www.glfw.org) for window/context management and input
-* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
-* OpenAL Soft for audio device/context management
+* Features:
+* Library written in plain C code (C99)
+* Uses C# PascalCase/camelCase notation
+* Hardware accelerated with OpenGL 1.1
+* Powerful fonts module with SpriteFonts support
+* Basic 3d support for Shapes and Models
+* Audio loading and playing
+*
+* Used external libs:
+* GLFW3 (www.glfw.org) for window/context management and input
+* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
+* OpenAL Soft for audio device/context management
*
-* Some design decisions:
-* 32bit Colors - All defined color are always RGBA
-* 32bit Textures - All loaded images are converted automatically to RGBA textures
-* SpriteFonts - All loaded sprite-font images are converted to RGBA and POT textures
-* One custom default font is loaded automatically when InitWindow()
+* Some design decisions:
+* 32bit Colors - All defined color are always RGBA
+* 32bit Textures - All loaded images are converted automatically to RGBA textures
+* SpriteFonts - All loaded sprite-font images are converted to RGBA and POT textures
+* One custom default font is loaded automatically when InitWindow()
*
-* -- LICENSE (raylib v1.0, November 2013) --
+* -- LICENSE (raylib v1.0, November 2013) --
*
-* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
-* BSD-like license that allows static linking with closed source software:
-*
-* Copyright (c) 2013 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.
+* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software:
+*
+* Copyright (c) 2013 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.
*
-* Permission is granted to anyone to use this software for any purpose, including commercial
-* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
-* 1. The origin of this software must not be misrepresented; you must not claim that you
-* wrote the original software. If you use this software in a product, an acknowledgment
-* in the product documentation would be appreciated but is not required.
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
*
-* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
-* as being the original software.
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
*
-* 3. This notice may not be removed or altered from any source distribution.
+* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#ifndef RAYLIB_H
#define RAYLIB_H
-#define NO_AUDIO // Audio is still being tested, deactivated by default
+#define NO_AUDIO // Audio is still being tested, deactivated by default
//----------------------------------------------------------------------------------
// Some basic Defines
@@ -88,60 +88,60 @@
#define KEY_RIGHT_ALT 346
// Mouse Buttons
-#define MOUSE_LEFT_BUTTON 0
-#define MOUSE_RIGHT_BUTTON 1
-#define MOUSE_MIDDLE_BUTTON 2
+#define MOUSE_LEFT_BUTTON 0
+#define MOUSE_RIGHT_BUTTON 1
+#define MOUSE_MIDDLE_BUTTON 2
// Gamepad Number
-#define GAMEPAD_PLAYER1 0
-#define GAMEPAD_PLAYER2 1
-#define GAMEPAD_PLAYER3 2
-#define GAMEPAD_PLAYER4 3
+#define GAMEPAD_PLAYER1 0
+#define GAMEPAD_PLAYER2 1
+#define GAMEPAD_PLAYER3 2
+#define GAMEPAD_PLAYER4 3
// Gamepad Buttons
// NOTE: Adjusted for a PS3 USB Controller
-#define GAMEPAD_BUTTON_A 2
-#define GAMEPAD_BUTTON_B 1
-#define GAMEPAD_BUTTON_X 3
-#define GAMEPAD_BUTTON_Y 4
-#define GAMEPAD_BUTTON_R1 7
-#define GAMEPAD_BUTTON_R2 5
-#define GAMEPAD_BUTTON_L1 6
-#define GAMEPAD_BUTTON_L2 8
-#define GAMEPAD_BUTTON_SELECT 9
-#define GAMEPAD_BUTTON_START 10
+#define GAMEPAD_BUTTON_A 2
+#define GAMEPAD_BUTTON_B 1
+#define GAMEPAD_BUTTON_X 3
+#define GAMEPAD_BUTTON_Y 4
+#define GAMEPAD_BUTTON_R1 7
+#define GAMEPAD_BUTTON_R2 5
+#define GAMEPAD_BUTTON_L1 6
+#define GAMEPAD_BUTTON_L2 8
+#define GAMEPAD_BUTTON_SELECT 9
+#define GAMEPAD_BUTTON_START 10
// TODO: Review Xbox360 USB Controller Buttons
// Some Basic Colors
// NOTE: Custom raylib color palette for amazing visuals on WHITE background
-#define LIGHTGRAY (Color){ 200, 200, 200, 255 } // Light Gray
-#define GRAY (Color){ 130, 130, 130, 255 } // Gray
-#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
-#define YELLOW (Color){ 253, 249, 0, 255 } // Yellow
-#define GOLD (Color){ 255, 203, 0, 255 } // Gold
-#define ORANGE (Color){ 255, 161, 0, 255 } // Orange
-#define PINK (Color){ 255, 109, 194, 255 } // Pink
-#define RED (Color){ 230, 41, 55, 255 } // Red
-#define MAROON (Color){ 190, 33, 55, 255 } // Maroon
-#define GREEN (Color){ 0, 228, 48, 255 } // Green
-#define LIME (Color){ 0, 158, 47, 255 } // Lime
-#define DARKGREEN (Color){ 0, 117, 44, 255 } // Dark Green
-#define SKYBLUE (Color){ 102, 191, 255, 255 } // Sky Blue
-#define BLUE (Color){ 0, 121, 241, 255 } // Blue
-#define DARKBLUE (Color){ 0, 82, 172, 255 } // Dark Blue
-#define PURPLE (Color){ 200, 122, 255, 255 } // Purple
-#define VIOLET (Color){ 135, 60, 190, 255 } // Violet
-#define DARKPURPLE (Color){ 112, 31, 126, 255 } // Dark Purple
-#define BEIGE (Color){ 211, 176, 131, 255 } // Beige
-#define BROWN (Color){ 127, 106, 79, 255 } // Brown
-#define DARKBROWN (Color){ 76, 63, 47, 255 } // Dark Brown
-
-#define WHITE (Color){ 255, 255, 255, 255 } // White
-#define BLACK (Color){ 0, 0, 0, 255 } // Black
-#define BLANK (Color){ 0, 0, 0, 0 } // Blank (Transparent)
-#define MAGENTA (Color){ 255, 0, 255, 255 } // Magenta
-#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
+#define LIGHTGRAY (Color){ 200, 200, 200, 255 } // Light Gray
+#define GRAY (Color){ 130, 130, 130, 255 } // Gray
+#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
+#define YELLOW (Color){ 253, 249, 0, 255 } // Yellow
+#define GOLD (Color){ 255, 203, 0, 255 } // Gold
+#define ORANGE (Color){ 255, 161, 0, 255 } // Orange
+#define PINK (Color){ 255, 109, 194, 255 } // Pink
+#define RED (Color){ 230, 41, 55, 255 } // Red
+#define MAROON (Color){ 190, 33, 55, 255 } // Maroon
+#define GREEN (Color){ 0, 228, 48, 255 } // Green
+#define LIME (Color){ 0, 158, 47, 255 } // Lime
+#define DARKGREEN (Color){ 0, 117, 44, 255 } // Dark Green
+#define SKYBLUE (Color){ 102, 191, 255, 255 } // Sky Blue
+#define BLUE (Color){ 0, 121, 241, 255 } // Blue
+#define DARKBLUE (Color){ 0, 82, 172, 255 } // Dark Blue
+#define PURPLE (Color){ 200, 122, 255, 255 } // Purple
+#define VIOLET (Color){ 135, 60, 190, 255 } // Violet
+#define DARKPURPLE (Color){ 112, 31, 126, 255 } // Dark Purple
+#define BEIGE (Color){ 211, 176, 131, 255 } // Beige
+#define BROWN (Color){ 127, 106, 79, 255 } // Brown
+#define DARKBROWN (Color){ 76, 63, 47, 255 } // Dark Brown
+
+#define WHITE (Color){ 255, 255, 255, 255 } // White
+#define BLACK (Color){ 0, 0, 0, 255 } // Black
+#define BLANK (Color){ 0, 0, 0, 0 } // Blank (Transparent)
+#define MAGENTA (Color){ 255, 0, 255, 255 } // Magenta
+#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
//----------------------------------------------------------------------------------
// Types and Structures Definition
@@ -152,34 +152,34 @@ typedef enum { false, true } bool;
// Color type, RGBA (32bit)
typedef struct Color {
- unsigned char r;
- unsigned char g;
- unsigned char b;
- unsigned char a;
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+ unsigned char a;
} Color;
// Rectangle type
typedef struct Rectangle {
- int x;
- int y;
- int width;
- int height;
+ int x;
+ int y;
+ int width;
+ int height;
} Rectangle;
// Image type, bpp always RGBA (32bit)
// NOTE: Data stored in CPU memory (RAM)
typedef struct Image {
- Color *pixels;
- int width;
- int height;
+ Color *pixels;
+ int width;
+ int height;
} Image;
// Texture2D type, bpp always RGBA (32bit)
// NOTE: Data stored in GPU memory
typedef struct Texture2D {
- unsigned int glId;
- int width;
- int height;
+ unsigned int glId;
+ int width;
+ int height;
} Texture2D;
// SpriteFont one Character (Glyph) data, defined in text module
@@ -187,47 +187,47 @@ typedef struct Character Character;
// SpriteFont type, includes texture and charSet array data
typedef struct SpriteFont {
- Texture2D texture;
- int numChars;
- Character *charSet;
+ Texture2D texture;
+ int numChars;
+ Character *charSet;
} SpriteFont;
// Vector2 type
typedef struct Vector2 {
- float x;
- float y;
+ float x;
+ float y;
} Vector2;
// Vector3 type
typedef struct Vector3 {
- float x;
- float y;
- float z;
+ float x;
+ float y;
+ float z;
} Vector3;
// Camera type, defines a camera position/orientation in 3d space
typedef struct Camera {
- Vector3 position;
- Vector3 target;
- Vector3 up;
+ Vector3 position;
+ Vector3 target;
+ Vector3 up;
} Camera;
// Basic 3d Model type
typedef struct Model {
- int numVertices;
- Vector3 *vertices;
- Vector2 *texcoords;
- Vector3 *normals;
+ int numVertices;
+ Vector3 *vertices;
+ Vector2 *texcoords;
+ Vector3 *normals;
} Model;
// Basic Sound source and buffer
typedef struct Sound {
- unsigned int source;
- unsigned int buffer;
+ unsigned int source;
+ unsigned int buffer;
} Sound;
#ifdef __cplusplus
-extern "C" { // Prevents name mangling of functions
+extern "C" { // Prevents name mangling of functions
#endif
//------------------------------------------------------------------------------------
@@ -238,136 +238,136 @@ extern "C" { // Prevents name mangling of functions
//------------------------------------------------------------------------------------
// Window and Graphics Device Functions (Module: core)
//------------------------------------------------------------------------------------
-void InitWindow(int width, int height, char* title); // Initialize Window and Graphics Context (OpenGL)
-void CloseWindow(); // Close Window and Terminate Context
-bool WindowShouldClose(); // Detect if KEY_ESCAPE pressed or Close icon pressed
-void ToggleFullscreen(); // Fullscreen toggle (by default F11)
+void InitWindow(int width, int height, char* title); // Initialize Window and Graphics Context (OpenGL)
+void CloseWindow(); // Close Window and Terminate Context
+bool WindowShouldClose(); // Detect if KEY_ESCAPE pressed or Close icon pressed
+void ToggleFullscreen(); // Fullscreen toggle (by default F11)
-void ClearBackground(Color color); // Sets Background Color
-void BeginDrawing(); // Setup drawing canvas to start drawing
-void EndDrawing(); // End canvas drawing and Swap Buffers (Double Buffering)
+void ClearBackground(Color color); // Sets Background Color
+void BeginDrawing(); // Setup drawing canvas to start drawing
+void EndDrawing(); // End canvas drawing and Swap Buffers (Double Buffering)
-void Begin3dMode(Camera cam); // Initializes 3D mode for drawing (Camera setup)
-void End3dMode(); // Ends 3D mode and returns to default 2D orthographic mode
+void Begin3dMode(Camera cam); // Initializes 3D mode for drawing (Camera setup)
+void End3dMode(); // Ends 3D mode and returns to default 2D orthographic mode
-void SetTargetFPS(int fps); // Set target FPS (maximum)
-float GetFPS(); // Returns current FPS
-float GetFrameTime(); // Returns time in seconds for one frame
+void SetTargetFPS(int fps); // Set target FPS (maximum)
+float GetFPS(); // Returns current FPS
+float GetFrameTime(); // Returns time in seconds for one frame
-Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
-int GetHexValue(Color color); // Returns hexadecimal value for a Color
+Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
+int GetHexValue(Color color); // Returns hexadecimal value for a Color
//------------------------------------------------------------------------------------
// Input Handling Functions (Module: core)
//------------------------------------------------------------------------------------
-bool IsKeyPressed(int key); // Detect if a key is being pressed
-bool IsKeyReleased(int key); // Detect if a key is NOT being pressed
+bool IsKeyPressed(int key); // Detect if a key is being pressed
+bool IsKeyReleased(int key); // Detect if a key is NOT being pressed
-bool IsMouseButtonPressed(int button); // Detect if a mouse button is being pressed
-bool IsMouseButtonReleased(int button); // Detect if a mouse button is NOT being pressed
-int GetMouseX(); // Returns mouse position X
-int GetMouseY(); // Returns mouse position Y
-Vector2 GetMousePosition(); // Returns mouse position XY
+bool IsMouseButtonPressed(int button); // Detect if a mouse button is being pressed
+bool IsMouseButtonReleased(int button); // Detect if a mouse button is NOT being pressed
+int GetMouseX(); // Returns mouse position X
+int GetMouseY(); // Returns mouse position Y
+Vector2 GetMousePosition(); // Returns mouse position XY
-bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
-Vector2 GetGamepadMovement(int gamepad); // Return axis movement vector for a gamepad
-bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button is being pressed
-bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button is NOT being pressed
+bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
+Vector2 GetGamepadMovement(int gamepad); // Return axis movement vector for a gamepad
+bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button is being pressed
+bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button is NOT being pressed
//------------------------------------------------------------------------------------
// Basic Shapes Drawing Functions (Module: shapes)
//------------------------------------------------------------------------------------
-void DrawPixel(int posX, int posY, Color color); // Draw a pixel
-void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version)
-void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
-void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version)
-void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
-void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle
-void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
-void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
-void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
-void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
-void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2); // Draw a gradient-filled rectangle
-void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
-void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
-void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle
-void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline
-void DrawPoly(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points
-void DrawPolyLine(Vector2 *points, int numPoints, Color color); // Draw polygon lines
+void DrawPixel(int posX, int posY, Color color); // Draw a pixel
+void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version)
+void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
+void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version)
+void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
+void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle
+void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
+void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
+void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
+void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
+void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2); // Draw a gradient-filled rectangle
+void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
+void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
+void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle
+void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline
+void DrawPoly(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points
+void DrawPolyLine(Vector2 *points, int numPoints, Color color); // Draw polygon lines
//------------------------------------------------------------------------------------
// Texture Loading and Drawing Functions (Module: textures)
//------------------------------------------------------------------------------------
-Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
-void UnloadImage(Image image); // Unload image from CPU memory (RAM)
-Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
-//Texture2D LoadTextureEx(const char *fileName, bool createPOT, bool mipmaps); // Load an image as texture (and convert to POT with mipmaps) (raylib 1.x)
-void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
-void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
-void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
-void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, float scale, Color tint); // Draw a part of a texture defined by a rectangle
+Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
+void UnloadImage(Image image); // Unload image from CPU memory (RAM)
+Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
+//Texture2D LoadTextureEx(const char *fileName, bool createPOT, bool mipmaps); // Load an image as texture (and convert to POT with mipmaps) (raylib 1.x)
+void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
+void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
+void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
+void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, float scale, Color tint); // Draw a part of a texture defined by a rectangle
//------------------------------------------------------------------------------------
// Font Loading and Text Drawing Functions (Module: text)
//------------------------------------------------------------------------------------
-SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
-void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
-void DrawText(const char *text, int posX, int posY, int fontSize, int spacing, Color color); // Draw text (using default font)
-void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint); // Draw text using SpriteFont
-int MeasureText(const char *text, int fontSize, int spacing); // Measure string width for default font
-Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont
-int GetFontBaseSize(SpriteFont spriteFont); // Returns the base size for a SpriteFont (chars height)
-void DrawFps(int posX, int posY); // Shows current FPS on top-left corner
-const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
+SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
+void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
+void DrawText(const char *text, int posX, int posY, int fontSize, int spacing, Color color); // Draw text (using default font)
+void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint); // Draw text using SpriteFont
+int MeasureText(const char *text, int fontSize, int spacing); // Measure string width for default font
+Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont
+int GetFontBaseSize(SpriteFont spriteFont); // Returns the base size for a SpriteFont (chars height)
+void DrawFps(int posX, int posY); // Shows current FPS on top-left corner
+const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
//------------------------------------------------------------------------------------
// Basic 3d Shapes Drawing Functions (Module: models)
//------------------------------------------------------------------------------------
-void DrawCube(Vector3 position, float width, float height, float lenght, Color color); // Draw cube
-void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
-void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color); // Draw cube wires
-void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
-void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
-void DrawSphereWires(Vector3 centerPos, float radius, Color color); // Draw sphere wires
-void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
-void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
-void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color); // Draw a plane
-void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color); // Draw a plane with divisions
-void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
-void DrawGizmo(Vector3 position, bool orbits); // Draw gizmo (with or without orbits)
+void DrawCube(Vector3 position, float width, float height, float lenght, Color color); // Draw cube
+void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
+void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color); // Draw cube wires
+void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
+void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
+void DrawSphereWires(Vector3 centerPos, float radius, Color color); // Draw sphere wires
+void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
+void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
+void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color); // Draw a plane
+void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color); // Draw a plane with divisions
+void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
+void DrawGizmo(Vector3 position, bool orbits); // Draw gizmo (with or without orbits)
//DrawTorus(), DrawTeapot() are useless...
//------------------------------------------------------------------------------------
// Model 3d Loading and Drawing Functions (Module: models)
//------------------------------------------------------------------------------------
-Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
-void UnloadModel(Model model); // Unload 3d model from memory
-void DrawModel(Model model, Vector3 position, float scale, Color color); // Draw a model
-void DrawModelEx(Model model, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a textured model
-void DrawModelWires(Model model, Vector3 position, float scale, Color color); // Draw a model wires
+Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
+void UnloadModel(Model model); // Unload 3d model from memory
+void DrawModel(Model model, Vector3 position, float scale, Color color); // Draw a model
+void DrawModelEx(Model model, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a textured model
+void DrawModelWires(Model model, Vector3 position, float scale, Color color); // Draw a model wires
// NOTE: The following functions work but are incomplete or require some revision
// DrawHeightmap is extremely inefficient and can impact performance up to 60%
-void DrawBillboard(Camera camera, Texture2D texture, Vector3 basePos, float size, Color tint); // REVIEW: Draw a billboard (raylib 1.x)
-void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 basePos, float size, Color tint); // REVIEW: Draw a billboard (raylib 1.x)
-void DrawHeightmap(Image heightmap, Vector3 centerPos, Vector3 scale, Color color); // REVIEW: Draw heightmap using image map (raylib 1.x)
-void DrawHeightmapEx(Image heightmap, Texture2D texture, Vector3 centerPos, Vector3 scale, Color tint); // REVIEW: Draw textured heightmap (raylib 1.x)
+void DrawBillboard(Camera camera, Texture2D texture, Vector3 basePos, float size, Color tint); // REVIEW: Draw a billboard (raylib 1.x)
+void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 basePos, float size, Color tint); // REVIEW: Draw a billboard (raylib 1.x)
+void DrawHeightmap(Image heightmap, Vector3 centerPos, Vector3 scale, Color color); // REVIEW: Draw heightmap using image map (raylib 1.x)
+void DrawHeightmapEx(Image heightmap, Texture2D texture, Vector3 centerPos, Vector3 scale, Color tint); // REVIEW: Draw textured heightmap (raylib 1.x)
#ifndef NO_AUDIO
//------------------------------------------------------------------------------------
// Audio Loading and Playing Functions (Module: audio)
//------------------------------------------------------------------------------------
-void InitAudioDevice(); // Initialize audio device and context
-void CloseAudioDevice(); // Close the audio device and context
-Sound LoadSound(char *fileName); // Load sound to memory
-void UnloadSound(Sound sound); // Unload sound
-void PlaySound(Sound sound); // Play a sound
-void PlaySoundEx(Sound sound, float timePosition, bool loop); // Play a sound with extended parameters
-void PauseSound(Sound sound); // Pause a sound
-void StopSound(Sound sound); // Stop playing a sound
-
-#endif // NO_AUDIO
+void InitAudioDevice(); // Initialize audio device and context
+void CloseAudioDevice(); // Close the audio device and context
+Sound LoadSound(char *fileName); // Load sound to memory
+void UnloadSound(Sound sound); // Unload sound
+void PlaySound(Sound sound); // Play a sound
+void PlaySoundEx(Sound sound, float timePosition, bool loop); // Play a sound with extended parameters
+void PauseSound(Sound sound); // Pause a sound
+void StopSound(Sound sound); // Stop playing a sound
+
+#endif // NO_AUDIO
#ifdef __cplusplus
}
diff --git a/src/shapes.c b/src/shapes.c
index 705cd3ab..ea55f198 100644
--- a/src/shapes.c
+++ b/src/shapes.c
@@ -1,32 +1,32 @@
/*********************************************************************************************
*
-* raylib.shapes
+* raylib.shapes
*
-* Basic functions to draw 2d Shapes
-*
-* Copyright (c) 2013 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.
+* Basic functions to draw 2d Shapes
+*
+* Copyright (c) 2013 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.
*
-* Permission is granted to anyone to use this software for any purpose, including commercial
-* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
-* 1. The origin of this software must not be misrepresented; you must not claim that you
-* wrote the original software. If you use this software in a product, an acknowledgment
-* in the product documentation would be appreciated but is not required.
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
*
-* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
-* as being the original software.
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
*
-* 3. This notice may not be removed or altered from any source distribution.
+* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include "raylib.h"
-#include <GL/gl.h> // OpenGL functions
-#include <math.h> // Math related functions, sin() and cos() used on DrawCircle*
+#include <GL/gl.h> // OpenGL functions
+#include <math.h> // Math related functions, sin() and cos() used on DrawCircle*
//----------------------------------------------------------------------------------
// Defines and Macros
@@ -55,78 +55,78 @@
// Draw a pixel
void DrawPixel(int posX, int posY, Color color)
{
- glBegin(GL_POINTS);
- glColor4ub(color.r, color.g, color.b, color.a);
- glVertex2i(posX, posY);
- glEnd();
-
- // NOTE: Alternative method to draw a pixel (point)
+ glBegin(GL_POINTS);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glVertex2i(posX, posY);
+ glEnd();
+
+ // NOTE: Alternative method to draw a pixel (point)
/*
- glEnable(GL_POINT_SMOOTH);
- glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); // Deprecated on OGL 3.0
-
- glPointSize(1.0f);
- glPoint((float)posX, (float)posY, 0.0f);
+ glEnable(GL_POINT_SMOOTH);
+ glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); // Deprecated on OGL 3.0
+
+ glPointSize(1.0f);
+ glPoint((float)posX, (float)posY, 0.0f);
*/
}
// Draw a pixel (Vector version)
void DrawPixelV(Vector2 position, Color color)
{
- glBegin(GL_POINTS);
- glColor4ub(color.r, color.g, color.b, color.a);
- glVertex2f(position.x, position.y);
- glEnd();
+ glBegin(GL_POINTS);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glVertex2f(position.x, position.y);
+ glEnd();
}
// Draw a line
void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color)
{
- glBegin(GL_LINES);
- glColor4ub(color.r, color.g, color.b, color.a);
- glVertex2i(startPosX, startPosY);
- glVertex2i(endPosX, endPosY);
- glEnd();
+ glBegin(GL_LINES);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glVertex2i(startPosX, startPosY);
+ glVertex2i(endPosX, endPosY);
+ glEnd();
}
// Draw a line (Vector version)
void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
{
- glBegin(GL_LINES);
- glColor4ub(color.r, color.g, color.b, color.a);
- glVertex2f(startPos.x, startPos.y);
- glVertex2f(endPos.x, endPos.y);
- glEnd();
+ glBegin(GL_LINES);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glVertex2f(startPos.x, startPos.y);
+ glVertex2f(endPos.x, endPos.y);
+ glEnd();
}
// Draw a color-filled circle
void DrawCircle(int centerX, int centerY, float radius, Color color)
{
- glEnable(GL_POLYGON_SMOOTH);
- glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
-
- glBegin(GL_TRIANGLE_FAN);
- glColor4ub(color.r, color.g, color.b, color.a);
- glVertex2i(centerX, centerY);
+ glEnable(GL_POLYGON_SMOOTH);
+ glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
+
+ glBegin(GL_TRIANGLE_FAN);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glVertex2i(centerX, centerY);
- for (int i=0; i <= 360; i++) //i++ --> Step = 1.0 pixels
- {
- float degInRad = i*DEG2RAD;
- //glVertex2f(cos(degInRad)*radius,sin(degInRad)*radius);
+ for (int i=0; i <= 360; i++) //i++ --> Step = 1.0 pixels
+ {
+ float degInRad = i*DEG2RAD;
+ //glVertex2f(cos(degInRad)*radius,sin(degInRad)*radius);
- glVertex2f(centerX + sin(degInRad) * radius, centerY + cos(degInRad) * radius);
- }
- glEnd();
-
- glDisable(GL_POLYGON_SMOOTH);
-
- // NOTE: Alternative method to draw a circle (point)
+ glVertex2f(centerX + sin(degInRad) * radius, centerY + cos(degInRad) * radius);
+ }
+ glEnd();
+
+ glDisable(GL_POLYGON_SMOOTH);
+
+ // NOTE: Alternative method to draw a circle (point)
/*
- glEnable(GL_POINT_SMOOTH);
- glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); // Deprecated on OGL 3.0
-
- glPointSize(radius);
- glPoint((float)centerX, (float)centerY, 0.0f);
+ glEnable(GL_POINT_SMOOTH);
+ glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); // Deprecated on OGL 3.0
+
+ glPointSize(radius);
+ glPoint((float)centerX, (float)centerY, 0.0f);
*/
}
@@ -134,58 +134,58 @@ void DrawCircle(int centerX, int centerY, float radius, Color color)
// NOTE: Gradient goes from center (color1) to border (color2)
void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2)
{
- glBegin(GL_TRIANGLE_FAN);
- glColor4ub(color1.r, color1.g, color1.b, color1.a);
- glVertex2i(centerX, centerY);
- glColor4ub(color2.r, color2.g, color2.b, color2.a);
-
- for (int i=0; i <= 360; i++) //i++ --> Step = 1.0 pixels
- {
- glVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius);
- }
- glEnd();
+ glBegin(GL_TRIANGLE_FAN);
+ glColor4ub(color1.r, color1.g, color1.b, color1.a);
+ glVertex2i(centerX, centerY);
+ glColor4ub(color2.r, color2.g, color2.b, color2.a);
+
+ for (int i=0; i <= 360; i++) //i++ --> Step = 1.0 pixels
+ {
+ glVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius);
+ }
+ glEnd();
}
// Draw a color-filled circle (Vector version)
void DrawCircleV(Vector2 center, float radius, Color color)
{
- glEnable(GL_POLYGON_SMOOTH);
- glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
-
- glBegin(GL_TRIANGLE_FAN);
- glColor4ub(color.r, color.g, color.b, color.a);
- glVertex2f(center.x, center.y);
+ glEnable(GL_POLYGON_SMOOTH);
+ glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
+
+ glBegin(GL_TRIANGLE_FAN);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glVertex2f(center.x, center.y);
- for (int i=0; i <= 360; i++) //i++ --> Step = 1.0 pixels
- {
- glVertex2f(center.x + sin(DEG2RAD*i) * radius, center.y + cos(DEG2RAD*i) * radius);
- }
- glEnd();
-
- glDisable(GL_POLYGON_SMOOTH);
+ for (int i=0; i <= 360; i++) //i++ --> Step = 1.0 pixels
+ {
+ glVertex2f(center.x + sin(DEG2RAD*i) * radius, center.y + cos(DEG2RAD*i) * radius);
+ }
+ glEnd();
+
+ glDisable(GL_POLYGON_SMOOTH);
}
// Draw circle outline
void DrawCircleLines(int centerX, int centerY, float radius, Color color)
{
- glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
- glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
-
- glBegin(GL_LINE_LOOP);
- glColor4ub(color.r, color.g, color.b, color.a);
-
- // NOTE: Circle outline is drawn pixel by pixel every degree (0 to 360)
- for (int i=0; i < 360; i++)
- {
- glVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius);
- }
+ glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
+ glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
+
+ glBegin(GL_LINE_LOOP);
+ glColor4ub(color.r, color.g, color.b, color.a);
+
+ // NOTE: Circle outline is drawn pixel by pixel every degree (0 to 360)
+ for (int i=0; i < 360; i++)
+ {
+ glVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius);
+ }
glEnd();
// NOTE: Alternative method to draw circle outline
/*
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- DrawCircle(centerX, centerY, radius, color);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ DrawCircle(centerX, centerY, radius, color);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
*/
glDisable(GL_LINE_SMOOTH);
}
@@ -193,134 +193,134 @@ void DrawCircleLines(int centerX, int centerY, float radius, Color color)
// Draw a color-filled rectangle
void DrawRectangle(int posX, int posY, int width, int height, Color color)
{
- glBegin(GL_QUADS);
- glColor4ub(color.r, color.g, color.b, color.a);
- glVertex2i(posX, posY);
- glVertex2i(posX + width, posY);
- glVertex2i(posX + width, posY + height);
- glVertex2i(posX, posY + height);
- glEnd();
+ glBegin(GL_QUADS);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glVertex2i(posX, posY);
+ glVertex2i(posX + width, posY);
+ glVertex2i(posX + width, posY + height);
+ glVertex2i(posX, posY + height);
+ glEnd();
}
// Draw a color-filled rectangle
void DrawRectangleRec(Rectangle rec, Color color)
{
- DrawRectangle(rec.x, rec.y, rec.width, rec.height, color);
-}
+ DrawRectangle(rec.x, rec.y, rec.width, rec.height, color);
+}
// Draw a gradient-filled rectangle
// NOTE: Gradient goes from bottom (color1) to top (color2)
void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2)
{
- glBegin(GL_QUADS);
- glColor4ub(color1.r, color1.g, color1.b, color1.a);
- glVertex2i(posX, posY);
- glVertex2i(posX + width, posY);
- glColor4ub(color2.r, color2.g, color2.b, color2.a);
- glVertex2i(posX + width, posY + height);
- glVertex2i(posX, posY + height);
- glEnd();
+ glBegin(GL_QUADS);
+ glColor4ub(color1.r, color1.g, color1.b, color1.a);
+ glVertex2i(posX, posY);
+ glVertex2i(posX + width, posY);
+ glColor4ub(color2.r, color2.g, color2.b, color2.a);
+ glVertex2i(posX + width, posY + height);
+ glVertex2i(posX, posY + height);
+ glEnd();
}
// Draw a color-filled rectangle (Vector version)
void DrawRectangleV(Vector2 position, Vector2 size, Color color)
{
- glBegin(GL_QUADS);
- glColor4ub(color.r, color.g, color.b, color.a);
- glVertex2i(position.x, position.y);
- glVertex2i(position.x + size.x, position.y);
- glVertex2i(position.x + size.x, position.y + size.y);
- glVertex2i(position.x, position.y + size.y);
- glEnd();
+ glBegin(GL_QUADS);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glVertex2i(position.x, position.y);
+ glVertex2i(position.x + size.x, position.y);
+ glVertex2i(position.x + size.x, position.y + size.y);
+ glVertex2i(position.x, position.y + size.y);
+ glEnd();
}
// Draw rectangle outline
void DrawRectangleLines(int posX, int posY, int width, int height, Color color)
{
- //glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
- //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
-
- // NOTE: Lines are rasterized using the "Diamond Exit" rule so, it's nearly impossible to obtain a pixel-perfect engine
- // NOTE: Recommended trying to avoid using lines, at least >1.0f pixel lines with anti-aliasing (glLineWidth function)
+ //glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
+ //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
+
+ // NOTE: Lines are rasterized using the "Diamond Exit" rule so, it's nearly impossible to obtain a pixel-perfect engine
+ // NOTE: Recommended trying to avoid using lines, at least >1.0f pixel lines with anti-aliasing (glLineWidth function)
- glBegin(GL_LINE_LOOP);
- glColor4ub(color.r, color.g, color.b, color.a);
- glVertex2i(posX, posY);
- glVertex2i(posX + width - 1, posY);
- glVertex2i(posX + width - 1, posY + height - 1);
- glVertex2i(posX, posY + height - 1);
- glEnd();
+ glBegin(GL_LINE_LOOP);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glVertex2i(posX, posY);
+ glVertex2i(posX + width - 1, posY);
+ glVertex2i(posX + width - 1, posY + height - 1);
+ glVertex2i(posX, posY + height - 1);
+ glEnd();
// NOTE: Alternative method to draw rectangle outline
/*
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- DrawRectangle(posX, posY, width - 1, height - 1, color);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ DrawRectangle(posX, posY, width - 1, height - 1, color);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
*/
- //glDisable(GL_LINE_SMOOTH);
+ //glDisable(GL_LINE_SMOOTH);
}
// Draw a triangle
void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
{
- glBegin(GL_TRIANGLES);
- glColor4ub(color.r, color.g, color.b, color.a);
- glVertex2f(v1.x, v1.y);
- glVertex2f(v2.x, v2.y);
- glVertex2f(v3.x, v3.y);
- glEnd();
+ glBegin(GL_TRIANGLES);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glVertex2f(v1.x, v1.y);
+ glVertex2f(v2.x, v2.y);
+ glVertex2f(v3.x, v3.y);
+ glEnd();
}
void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
{
- glBegin(GL_LINE_LOOP);
- glColor4ub(color.r, color.g, color.b, color.a);
- glVertex2f(v1.x, v1.y);
- glVertex2f(v2.x, v2.y);
- glVertex2f(v3.x, v3.y);
- glEnd();
+ glBegin(GL_LINE_LOOP);
+ glColor4ub(color.r, color.g, color.b, color.a);
+ glVertex2f(v1.x, v1.y);
+ glVertex2f(v2.x, v2.y);
+ glVertex2f(v3.x, v3.y);
+ glEnd();
}
// Draw a closed polygon defined by points
// NOTE: Array num elements MUST be passed as parameter to function
void DrawPoly(Vector2 *points, int numPoints, Color color)
{
- if (numPoints >= 3)
- {
- glEnable(GL_POLYGON_SMOOTH);
- glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
-
- glBegin(GL_POLYGON);
- glColor4ub(color.r, color.g, color.b, color.a);
-
- for (int i = 0; i < numPoints; i++)
- {
- glVertex2f(points[i].x, points[i].y);
- }
- glEnd();
-
- glDisable(GL_POLYGON_SMOOTH);
- }
+ if (numPoints >= 3)
+ {
+ glEnable(GL_POLYGON_SMOOTH);
+ glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
+
+ glBegin(GL_POLYGON);
+ glColor4ub(color.r, color.g, color.b, color.a);
+
+ for (int i = 0; i < numPoints; i++)
+ {
+ glVertex2f(points[i].x, points[i].y);
+ }
+ glEnd();
+
+ glDisable(GL_POLYGON_SMOOTH);
+ }
}
// Draw polygon lines
-// NOTE: Array num elements MUST be passed as parameter to function
+// NOTE: Array num elements MUST be passed as parameter to function
void DrawPolyLine(Vector2 *points, int numPoints, Color color)
{
- if (numPoints >= 2)
- {
- //glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
- //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
-
- glBegin(GL_LINE_LOOP);
- glColor4ub(color.r, color.g, color.b, color.a);
-
- for (int i = 0; i < numPoints; i++)
- {
- glVertex2f(points[i].x, points[i].y);
- }
- glEnd();
-
- //glDisable(GL_LINE_SMOOTH);
- }
-}
+ if (numPoints >= 2)
+ {
+ //glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
+ //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
+
+ glBegin(GL_LINE_LOOP);
+ glColor4ub(color.r, color.g, color.b, color.a);
+
+ for (int i = 0; i < numPoints; i++)
+ {
+ glVertex2f(points[i].x, points[i].y);
+ }
+ glEnd();
+
+ //glDisable(GL_LINE_SMOOTH);
+ }
+}
diff --git a/src/text.c b/src/text.c
index e9a66d89..ac0dacfd 100644
--- a/src/text.c
+++ b/src/text.c
@@ -1,43 +1,43 @@
/*********************************************************************************************
*
-* raylib.text
+* raylib.text
*
-* Basic functions to load SpriteFonts and draw Text
-*
-* Uses external lib:
-* stb_image - Multiple formats image loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
+* Basic functions to load SpriteFonts and draw Text
+*
+* Uses external lib:
+* stb_image - Multiple formats image loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
*
-* Copyright (c) 2013 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.
+* Copyright (c) 2013 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.
*
-* Permission is granted to anyone to use this software for any purpose, including commercial
-* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
-* 1. The origin of this software must not be misrepresented; you must not claim that you
-* wrote the original software. If you use this software in a product, an acknowledgment
-* in the product documentation would be appreciated but is not required.
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
*
-* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
-* as being the original software.
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
*
-* 3. This notice may not be removed or altered from any source distribution.
+* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include "raylib.h"
-#include <GL/gl.h> // OpenGL functions
-#include <stdlib.h> // Declares malloc() and free() for memory management
-#include <string.h> // String management functions (just strlen() is used)
-#include <stdarg.h> // Used for functions with variable number of parameters (FormatText())
-#include "stb_image.h" // Used to read image data (multiple formats support)
+#include <GL/gl.h> // OpenGL functions
+#include <stdlib.h> // Declares malloc() and free() for memory management
+#include <string.h> // String management functions (just strlen() is used)
+#include <stdarg.h> // Used for functions with variable number of parameters (FormatText())
+#include "stb_image.h" // Used to read image data (multiple formats support)
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
-#define FIRST_CHAR 32
+#define FIRST_CHAR 32
#define MAX_FONTCHARS 128
#define BIT_CHECK(a,b) ((a) & (1<<(b)))
@@ -49,227 +49,227 @@ typedef unsigned char byte;
// SpriteFont one Character (Glyph) data
struct Character {
- int value; //char value = ' '; (int)value = 32;
- int x;
- int y;
- int w;
- int h;
+ int value; //char value = ' '; (int)value = 32;
+ int x;
+ int y;
+ int w;
+ int h;
};
//----------------------------------------------------------------------------------
// Global variables
//----------------------------------------------------------------------------------
-static SpriteFont defaultFont; // Default font provided by raylib
- // NOTE: defaultFont is loaded on InitWindow and disposed on CloseWindow [module: core]
+static SpriteFont defaultFont; // Default font provided by raylib
+// NOTE: defaultFont is loaded on InitWindow and disposed on CloseWindow [module: core]
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
-static bool PixelIsMagenta(Color p); // Check if a pixel is magenta
-static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Character **charSet); // Parse image pixel data to obtain character set measures
-static int GetNextPOT(int num); // Calculate next power-of-two value for a given value
+static bool PixelIsMagenta(Color p); // Check if a pixel is magenta
+static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Character **charSet); // Parse image pixel data to obtain character set measures
+static int GetNextPOT(int num); // Calculate next power-of-two value for a given value
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
extern void LoadDefaultFont()
{
- defaultFont.numChars = 96; // We know our default font has 94 chars
- defaultFont.texture.width = 128; // We know our default font texture is 128 pixels width
- defaultFont.texture.height = 64; // We know our default font texture is 64 pixels height
-
- // Default font is directly defined here (data generated from a sprite font image)
- // This way, we reconstruct SpriteFont without creating large global variables
- // This data is automatically allocated to Stack and automatically deallocated at the end of this function
- int defaultFontData[256] = {
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00200020, 0x0001b000, 0x00000000, 0x00000000, 0x8ef92520, 0x00020a00, 0x7dbe8000, 0x1f7df45f,
- 0x4a2bf2a0, 0x0852091e, 0x41224000, 0x10041450, 0x2e292020, 0x08220812, 0x41222000, 0x10041450, 0x10f92020, 0x3efa084c, 0x7d22103c, 0x107df7de,
- 0xe8a12020, 0x08220832, 0x05220800, 0x10450410, 0xa4a3f000, 0x08520832, 0x05220400, 0x10450410, 0xe2f92020, 0x0002085e, 0x7d3e0281, 0x107df41f,
- 0x00200000, 0x8001b000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xc0000fbe, 0xfbf7e00f, 0x5fbf7e7d, 0x0050bee8, 0x440808a2, 0x0a142fe8, 0x50810285, 0x0050a048,
- 0x49e428a2, 0x0a142828, 0x40810284, 0x0048a048, 0x10020fbe, 0x09f7ebaf, 0xd89f3e84, 0x0047a04f, 0x09e48822, 0x0a142aa1, 0x50810284, 0x0048a048,
- 0x04082822, 0x0a142fa0, 0x50810285, 0x0050a248, 0x00008fbe, 0xfbf42021, 0x5f817e7d, 0x07d09ce8, 0x00008000, 0x00000fe0, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000c0180,
- 0xdfbf4282, 0x0bfbf7ef, 0x42850505, 0x004804bf, 0x50a142c6, 0x08401428, 0x42852505, 0x00a808a0, 0x50a146aa, 0x08401428, 0x42852505, 0x00081090,
- 0x5fa14a92, 0x0843f7e8, 0x7e792505, 0x00082088, 0x40a15282, 0x08420128, 0x40852489, 0x00084084, 0x40a16282, 0x0842022a, 0x40852451, 0x00088082,
- 0xc0bf4282, 0xf843f42f, 0x7e85fc21, 0x3e0900bf, 0x00000000, 0x00000004, 0x00000000, 0x000c0180, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04000402, 0x41482000, 0x00000000, 0x00000800,
- 0x04000404, 0x4100203c, 0x00000000, 0x00000800, 0xf7df7df0, 0x514bef85, 0xbefbefbe, 0x04513bef, 0x14414500, 0x494a2885, 0xa28a28aa, 0x04510820,
- 0xf44145f0, 0x474a289d, 0xa28a28aa, 0x04510be0, 0x14414510, 0x494a2884, 0xa28a28aa, 0x02910a00, 0xf7df7df0, 0xd14a2f85, 0xbefbe8aa, 0x011f7be0,
- 0x00000000, 0x00400804, 0x20080000, 0x00000000, 0x00000000, 0x00600f84, 0x20080000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0xac000000, 0x00000f01, 0x00000000, 0x00000000, 0x24000000, 0x00000901, 0x00000000, 0x00000000, 0x24000000, 0x00000901, 0x00000000, 0x00000000,
- 0x24fa28a2, 0x00000901, 0x00000000, 0x00000000, 0x2242252a, 0x00000952, 0x00000000, 0x00000000, 0x2422222a, 0x00000929, 0x00000000, 0x00000000,
- 0x2412252a, 0x00000901, 0x00000000, 0x00000000, 0x24fbe8be, 0x00000901, 0x00000000, 0x00000000, 0xac020000, 0x00000f01, 0x00000000, 0x00000000,
- 0x0003e000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
-
- int charsHeight = 10;
- int charsDivisor = 1; // Every char is separated from the consecutive by a 1 pixel divisor, horizontally and vertically
-
- int charsWidth[96] = { 3, 1, 4, 6, 5, 7, 6, 2, 3, 3, 5, 5, 2, 4, 1, 7, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 3, 4, 3, 6,
- 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 5, 6, 5, 7, 6, 6, 6, 6, 6, 6, 7, 6, 7, 7, 6, 6, 6, 2, 7, 2, 3, 5,
- 2, 5, 5, 5, 5, 5, 4, 5, 5, 1, 2, 5, 2, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 3, 1, 3, 4, 4 };
-
-
- // Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, numChars
- //------------------------------------------------------------------------------
- defaultFont.charSet = (Character *)malloc(defaultFont.numChars * sizeof(Character)); // Allocate space for our character data
- // This memory should be freed at end! --> Done on CloseWindow()
- int currentLine = 0;
- int currentPosX = charsDivisor;
- int testPosX = charsDivisor;
-
- for (int i = 0; i < defaultFont.numChars; i++)
- {
- defaultFont.charSet[i].value = FIRST_CHAR + i;
- defaultFont.charSet[i].x = currentPosX;
- defaultFont.charSet[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor);
- defaultFont.charSet[i].w = charsWidth[i];
- defaultFont.charSet[i].h = charsHeight;
-
- testPosX += (defaultFont.charSet[i].w + charsDivisor);
-
- if (testPosX >= defaultFont.texture.width)
- {
- currentLine++;
- currentPosX = 2 * charsDivisor + charsWidth[i];
- testPosX = currentPosX;
-
- defaultFont.charSet[i].x = charsDivisor;
- defaultFont.charSet[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor);
- }
- else currentPosX = testPosX;
- }
-
- // Re-construct image from defaultFontData and generate OpenGL texture
- //----------------------------------------------------------------------
- Color *imgDataPixel = (Color *)malloc(defaultFont.texture.width * defaultFont.texture.height * sizeof(Color));
-
- for (int i = 0; i < defaultFont.texture.width * defaultFont.texture.height; i++) imgDataPixel[i] = BLANK; // Initialize array
-
- int counter = 0; // Font data elements counter
-
- // Fill imgData with defaultFontData (convert from bit to pixel!)
- for (int i = 0; i < defaultFont.texture.width * defaultFont.texture.height; i += 32)
- {
- for (int j = 31; j >= 0; j--)
- {
- if (BIT_CHECK(defaultFontData[counter], j)) imgDataPixel[i+j] = WHITE;
- }
-
- counter++;
-
- if (counter > 256) counter = 0; // Security check...
- }
-
- // Convert loaded data to OpenGL texture
- //----------------------------------------
- GLuint id;
- glGenTextures(1, &id); // Generate pointer to the texture
-
- glBindTexture(GL_TEXTURE_2D, id);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); // Set texture to clamp on x-axis
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); // Set texture to clamp on y-axis
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, defaultFont.texture.width, defaultFont.texture.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgDataPixel);
-
- // NOTE: Not using mipmappings (texture for 2D drawing)
- // At this point we have the image converted to texture and uploaded to GPU
-
- free(imgDataPixel); // Now we can free loaded data from RAM memory
-
- defaultFont.texture.glId = id;
+ defaultFont.numChars = 96; // We know our default font has 94 chars
+ defaultFont.texture.width = 128; // We know our default font texture is 128 pixels width
+ defaultFont.texture.height = 64; // We know our default font texture is 64 pixels height
+
+ // Default font is directly defined here (data generated from a sprite font image)
+ // This way, we reconstruct SpriteFont without creating large global variables
+ // This data is automatically allocated to Stack and automatically deallocated at the end of this function
+ int defaultFontData[256] = {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00200020, 0x0001b000, 0x00000000, 0x00000000, 0x8ef92520, 0x00020a00, 0x7dbe8000, 0x1f7df45f,
+ 0x4a2bf2a0, 0x0852091e, 0x41224000, 0x10041450, 0x2e292020, 0x08220812, 0x41222000, 0x10041450, 0x10f92020, 0x3efa084c, 0x7d22103c, 0x107df7de,
+ 0xe8a12020, 0x08220832, 0x05220800, 0x10450410, 0xa4a3f000, 0x08520832, 0x05220400, 0x10450410, 0xe2f92020, 0x0002085e, 0x7d3e0281, 0x107df41f,
+ 0x00200000, 0x8001b000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xc0000fbe, 0xfbf7e00f, 0x5fbf7e7d, 0x0050bee8, 0x440808a2, 0x0a142fe8, 0x50810285, 0x0050a048,
+ 0x49e428a2, 0x0a142828, 0x40810284, 0x0048a048, 0x10020fbe, 0x09f7ebaf, 0xd89f3e84, 0x0047a04f, 0x09e48822, 0x0a142aa1, 0x50810284, 0x0048a048,
+ 0x04082822, 0x0a142fa0, 0x50810285, 0x0050a248, 0x00008fbe, 0xfbf42021, 0x5f817e7d, 0x07d09ce8, 0x00008000, 0x00000fe0, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000c0180,
+ 0xdfbf4282, 0x0bfbf7ef, 0x42850505, 0x004804bf, 0x50a142c6, 0x08401428, 0x42852505, 0x00a808a0, 0x50a146aa, 0x08401428, 0x42852505, 0x00081090,
+ 0x5fa14a92, 0x0843f7e8, 0x7e792505, 0x00082088, 0x40a15282, 0x08420128, 0x40852489, 0x00084084, 0x40a16282, 0x0842022a, 0x40852451, 0x00088082,
+ 0xc0bf4282, 0xf843f42f, 0x7e85fc21, 0x3e0900bf, 0x00000000, 0x00000004, 0x00000000, 0x000c0180, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04000402, 0x41482000, 0x00000000, 0x00000800,
+ 0x04000404, 0x4100203c, 0x00000000, 0x00000800, 0xf7df7df0, 0x514bef85, 0xbefbefbe, 0x04513bef, 0x14414500, 0x494a2885, 0xa28a28aa, 0x04510820,
+ 0xf44145f0, 0x474a289d, 0xa28a28aa, 0x04510be0, 0x14414510, 0x494a2884, 0xa28a28aa, 0x02910a00, 0xf7df7df0, 0xd14a2f85, 0xbefbe8aa, 0x011f7be0,
+ 0x00000000, 0x00400804, 0x20080000, 0x00000000, 0x00000000, 0x00600f84, 0x20080000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xac000000, 0x00000f01, 0x00000000, 0x00000000, 0x24000000, 0x00000901, 0x00000000, 0x00000000, 0x24000000, 0x00000901, 0x00000000, 0x00000000,
+ 0x24fa28a2, 0x00000901, 0x00000000, 0x00000000, 0x2242252a, 0x00000952, 0x00000000, 0x00000000, 0x2422222a, 0x00000929, 0x00000000, 0x00000000,
+ 0x2412252a, 0x00000901, 0x00000000, 0x00000000, 0x24fbe8be, 0x00000901, 0x00000000, 0x00000000, 0xac020000, 0x00000f01, 0x00000000, 0x00000000,
+ 0x0003e000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+
+ int charsHeight = 10;
+ int charsDivisor = 1; // Every char is separated from the consecutive by a 1 pixel divisor, horizontally and vertically
+
+ int charsWidth[96] = { 3, 1, 4, 6, 5, 7, 6, 2, 3, 3, 5, 5, 2, 4, 1, 7, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 3, 4, 3, 6,
+ 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 5, 6, 5, 7, 6, 6, 6, 6, 6, 6, 7, 6, 7, 7, 6, 6, 6, 2, 7, 2, 3, 5,
+ 2, 5, 5, 5, 5, 5, 4, 5, 5, 1, 2, 5, 2, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 3, 1, 3, 4, 4 };
+
+
+ // Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, numChars
+ //------------------------------------------------------------------------------
+ defaultFont.charSet = (Character *)malloc(defaultFont.numChars * sizeof(Character)); // Allocate space for our character data
+ // This memory should be freed at end! --> Done on CloseWindow()
+ int currentLine = 0;
+ int currentPosX = charsDivisor;
+ int testPosX = charsDivisor;
+
+ for (int i = 0; i < defaultFont.numChars; i++)
+ {
+ defaultFont.charSet[i].value = FIRST_CHAR + i;
+ defaultFont.charSet[i].x = currentPosX;
+ defaultFont.charSet[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor);
+ defaultFont.charSet[i].w = charsWidth[i];
+ defaultFont.charSet[i].h = charsHeight;
+
+ testPosX += (defaultFont.charSet[i].w + charsDivisor);
+
+ if (testPosX >= defaultFont.texture.width)
+ {
+ currentLine++;
+ currentPosX = 2 * charsDivisor + charsWidth[i];
+ testPosX = currentPosX;
+
+ defaultFont.charSet[i].x = charsDivisor;
+ defaultFont.charSet[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor);
+ }
+ else currentPosX = testPosX;
+ }
+
+ // Re-construct image from defaultFontData and generate OpenGL texture
+ //----------------------------------------------------------------------
+ Color *imgDataPixel = (Color *)malloc(defaultFont.texture.width * defaultFont.texture.height * sizeof(Color));
+
+ for (int i = 0; i < defaultFont.texture.width * defaultFont.texture.height; i++) imgDataPixel[i] = BLANK; // Initialize array
+
+ int counter = 0; // Font data elements counter
+
+ // Fill imgData with defaultFontData (convert from bit to pixel!)
+ for (int i = 0; i < defaultFont.texture.width * defaultFont.texture.height; i += 32)
+ {
+ for (int j = 31; j >= 0; j--)
+ {
+ if (BIT_CHECK(defaultFontData[counter], j)) imgDataPixel[i+j] = WHITE;
+ }
+
+ counter++;
+
+ if (counter > 256) counter = 0; // Security check...
+ }
+
+ // Convert loaded data to OpenGL texture
+ //----------------------------------------
+ GLuint id;
+ glGenTextures(1, &id); // Generate pointer to the texture
+
+ glBindTexture(GL_TEXTURE_2D, id);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); // Set texture to clamp on x-axis
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); // Set texture to clamp on y-axis
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, defaultFont.texture.width, defaultFont.texture.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgDataPixel);
+
+ // NOTE: Not using mipmappings (texture for 2D drawing)
+ // At this point we have the image converted to texture and uploaded to GPU
+
+ free(imgDataPixel); // Now we can free loaded data from RAM memory
+
+ defaultFont.texture.glId = id;
}
extern void UnloadDefaultFont()
{
- glDeleteTextures(1, &defaultFont.texture.glId);
- free(defaultFont.charSet);
+ glDeleteTextures(1, &defaultFont.texture.glId);
+ free(defaultFont.charSet);
}
// Load a SpriteFont image into GPU memory
SpriteFont LoadSpriteFont(const char* fileName)
{
- SpriteFont spriteFont;
-
- // Use stb_image to load image data!
- int imgWidth;
- int imgHeight;
- int imgBpp;
-
- byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4); // Force loading to 4 components (RGBA)
-
- // Convert array to pixel array for working convenience
- Color *imgDataPixel = (Color *)malloc(imgWidth * imgHeight * sizeof(Color));
- Color *imgDataPixelPOT = NULL;
-
+ SpriteFont spriteFont;
+
+ // Use stb_image to load image data!
+ int imgWidth;
+ int imgHeight;
+ int imgBpp;
+
+ byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4); // Force loading to 4 components (RGBA)
+
+ // Convert array to pixel array for working convenience
+ Color *imgDataPixel = (Color *)malloc(imgWidth * imgHeight * sizeof(Color));
+ Color *imgDataPixelPOT = NULL;
+
int pix = 0;
-
- for (int i = 0; i < (imgWidth * imgHeight * 4); i += 4)
- {
- imgDataPixel[pix].r = imgData[i];
- imgDataPixel[pix].g = imgData[i+1];
- imgDataPixel[pix].b = imgData[i+2];
- imgDataPixel[pix].a = imgData[i+3];
- pix++;
- }
-
- stbi_image_free(imgData);
-
- // At this point we have a pixel array with all the data...
-
- // Process bitmap Font pixel data to get measures (Character array)
- // spriteFont.charSet data is filled inside the function and memory is allocated!
- int numChars = ParseImageData(imgDataPixel, imgWidth, imgHeight, &spriteFont.charSet);
-
- spriteFont.numChars = numChars;
-
- // Convert image font to POT image before conversion to texture
- // Just add the required amount of pixels at the right and bottom sides of image...
+
+ for (int i = 0; i < (imgWidth * imgHeight * 4); i += 4)
+ {
+ imgDataPixel[pix].r = imgData[i];
+ imgDataPixel[pix].g = imgData[i+1];
+ imgDataPixel[pix].b = imgData[i+2];
+ imgDataPixel[pix].a = imgData[i+3];
+ pix++;
+ }
+
+ stbi_image_free(imgData);
+
+ // At this point we have a pixel array with all the data...
+
+ // Process bitmap Font pixel data to get measures (Character array)
+ // spriteFont.charSet data is filled inside the function and memory is allocated!
+ int numChars = ParseImageData(imgDataPixel, imgWidth, imgHeight, &spriteFont.charSet);
+
+ spriteFont.numChars = numChars;
+
+ // Convert image font to POT image before conversion to texture
+ // Just add the required amount of pixels at the right and bottom sides of image...
int potWidth = GetNextPOT(imgWidth);
int potHeight = GetNextPOT(imgHeight);
-
- // Check if POT texture generation is required (if texture is not already POT)
- if ((potWidth != imgWidth) || (potHeight != imgWidth))
- {
- // Generate POT array from NPOT data
- imgDataPixelPOT = (Color *)malloc(potWidth * potHeight * sizeof(Color));
-
- for (int j = 0; j < potHeight; j++)
- {
- for (int i = 0; i < potWidth; i++)
- {
- if ((j < imgHeight) && (i < imgWidth)) imgDataPixelPOT[j*potWidth + i] = imgDataPixel[j*imgWidth + i];
- else imgDataPixelPOT[j*potWidth + i] = MAGENTA;
- }
- }
- }
-
- free(imgDataPixel);
-
- // Convert loaded data to OpenGL texture
- //----------------------------------------
- GLuint id;
- glGenTextures(1, &id); // Generate pointer to the texture
-
- glBindTexture(GL_TEXTURE_2D, id);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, potWidth, potHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgDataPixelPOT);
-
- // NOTE: Not using mipmappings (texture for 2D drawing)
- // At this point we have the image converted to texture and uploaded to GPU
-
- free(imgDataPixelPOT); // Now we can free loaded data from RAM memory
-
- spriteFont.texture.glId = id;
- spriteFont.texture.width = potWidth;
- spriteFont.texture.height = potHeight;
+
+ // Check if POT texture generation is required (if texture is not already POT)
+ if ((potWidth != imgWidth) || (potHeight != imgWidth))
+ {
+ // Generate POT array from NPOT data
+ imgDataPixelPOT = (Color *)malloc(potWidth * potHeight * sizeof(Color));
+
+ for (int j = 0; j < potHeight; j++)
+ {
+ for (int i = 0; i < potWidth; i++)
+ {
+ if ((j < imgHeight) && (i < imgWidth)) imgDataPixelPOT[j*potWidth + i] = imgDataPixel[j*imgWidth + i];
+ else imgDataPixelPOT[j*potWidth + i] = MAGENTA;
+ }
+ }
+ }
+
+ free(imgDataPixel);
+
+ // Convert loaded data to OpenGL texture
+ //----------------------------------------
+ GLuint id;
+ glGenTextures(1, &id); // Generate pointer to the texture
+
+ glBindTexture(GL_TEXTURE_2D, id);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, potWidth, potHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgDataPixelPOT);
+
+ // NOTE: Not using mipmappings (texture for 2D drawing)
+ // At this point we have the image converted to texture and uploaded to GPU
+
+ free(imgDataPixelPOT); // Now we can free loaded data from RAM memory
+
+ spriteFont.texture.glId = id;
+ spriteFont.texture.width = potWidth;
+ spriteFont.texture.height = potHeight;
return spriteFont;
}
@@ -277,145 +277,145 @@ SpriteFont LoadSpriteFont(const char* fileName)
// Unload SpriteFont from GPU memory
void UnloadSpriteFont(SpriteFont spriteFont)
{
- glDeleteTextures(1, &spriteFont.texture.glId);
- free(spriteFont.charSet);
+ glDeleteTextures(1, &spriteFont.texture.glId);
+ free(spriteFont.charSet);
}
// Draw text (using default font)
// NOTE: fontSize work like in any drawing program but if fontSize is lower than font-base-size, then font-base-size is used
void DrawText(const char* text, int posX, int posY, int fontSize, int spacing, Color color)
{
- Vector2 position = { (float)posX, (float)posY };
-
- DrawTextEx(defaultFont, text, position, fontSize, spacing, color);
+ Vector2 position = { (float)posX, (float)posY };
+
+ DrawTextEx(defaultFont, text, position, fontSize, spacing, color);
}
// Formatting of text with variables to 'embed'
const char *FormatText(const char *text, ...)
{
- int length = strlen(text);
- char *buffer = malloc(length + 20); // We add 20 extra characters, should be enough... :P
-
- va_list args;
- va_start(args, text);
- vsprintf(buffer, text, args); // NOTE: We use vsprintf() defined in <stdarg.h>
- va_end(args);
-
- //strcat(buffer, "\0"); // We add a end-of-string mark at the end (not needed)
-
- return buffer;
+ int length = strlen(text);
+ char *buffer = malloc(length + 20); // We add 20 extra characters, should be enough... :P
+
+ va_list args;
+ va_start(args, text);
+ vsprintf(buffer, text, args); // NOTE: We use vsprintf() defined in <stdarg.h>
+ va_end(args);
+
+ //strcat(buffer, "\0"); // We add a end-of-string mark at the end (not needed)
+
+ return buffer;
}
// Draw text using SpriteFont
// NOTE: If font size is lower than base size, base size is used
void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint)
{
- int length = strlen(text);
- int positionX = (int)position.x;
- float scaleFactor;
-
- Character c;
-
- if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
- else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
-
- glDisable(GL_LIGHTING); // When drawing text, disable LIGHTING
- glEnable(GL_TEXTURE_2D);
-
- glBindTexture(GL_TEXTURE_2D, spriteFont.texture.glId);
-
- glPushMatrix();
-
- // Optimized to use one draw call per string
- glBegin(GL_QUADS);
- for(int i = 0; i < length; i++)
- {
- c = spriteFont.charSet[(int)text[i] - FIRST_CHAR];
-
- glColor4ub(tint.r, tint.g, tint.b, tint.a);
- glNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
- glTexCoord2f((float)c.x / spriteFont.texture.width, (float)c.y / spriteFont.texture.height); glVertex2f(positionX, position.y);
- glTexCoord2f((float)c.x / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height); glVertex2f(positionX, position.y + (c.h) * scaleFactor);
- glTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height); glVertex2f(positionX + (c.w) * scaleFactor, position.y + (c.h) * scaleFactor);
- glTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)c.y / spriteFont.texture.height); glVertex2f(positionX + (c.w) * scaleFactor, position.y);
-
- positionX += (spriteFont.charSet[(int)text[i] - FIRST_CHAR].w + spacing) * scaleFactor;
- }
- glEnd();
-
- glPopMatrix();
-
- glDisable(GL_TEXTURE_2D);
+ int length = strlen(text);
+ int positionX = (int)position.x;
+ float scaleFactor;
+
+ Character c;
+
+ if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
+ else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
+
+ glDisable(GL_LIGHTING); // When drawing text, disable LIGHTING
+ glEnable(GL_TEXTURE_2D);
+
+ glBindTexture(GL_TEXTURE_2D, spriteFont.texture.glId);
+
+ glPushMatrix();
+
+ // Optimized to use one draw call per string
+ glBegin(GL_QUADS);
+ for(int i = 0; i < length; i++)
+ {
+ c = spriteFont.charSet[(int)text[i] - FIRST_CHAR];
+
+ glColor4ub(tint.r, tint.g, tint.b, tint.a);
+ glNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
+ glTexCoord2f((float)c.x / spriteFont.texture.width, (float)c.y / spriteFont.texture.height); glVertex2f(positionX, position.y);
+ glTexCoord2f((float)c.x / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height); glVertex2f(positionX, position.y + (c.h) * scaleFactor);
+ glTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height); glVertex2f(positionX + (c.w) * scaleFactor, position.y + (c.h) * scaleFactor);
+ glTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)c.y / spriteFont.texture.height); glVertex2f(positionX + (c.w) * scaleFactor, position.y);
+
+ positionX += (spriteFont.charSet[(int)text[i] - FIRST_CHAR].w + spacing) * scaleFactor;
+ }
+ glEnd();
+
+ glPopMatrix();
+
+ glDisable(GL_TEXTURE_2D);
}
// Measure string width for default font
int MeasureText(const char *text, int fontSize, int spacing)
{
- Vector2 vec;
+ Vector2 vec;
- vec = MeasureTextEx(defaultFont, text, fontSize, spacing);
+ vec = MeasureTextEx(defaultFont, text, fontSize, spacing);
- return (int)vec.x;
+ return (int)vec.x;
}
// Measure string size for SpriteFont
Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing)
{
- int len = strlen(text);
- int textWidth = 0;
- float scaleFactor;
-
- for (int i = 0; i < len; i++)
- {
- textWidth += spriteFont.charSet[(int)text[i] - FIRST_CHAR].w;
- }
-
- textWidth += (int)((len - 1) * spacing); // Adds chars spacing to measure
-
- if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
- else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
-
- Vector2 vec;
- vec.x = (float)textWidth * scaleFactor;
- vec.y = (float)spriteFont.charSet[0].h * scaleFactor;
-
- return vec;
+ int len = strlen(text);
+ int textWidth = 0;
+ float scaleFactor;
+
+ for (int i = 0; i < len; i++)
+ {
+ textWidth += spriteFont.charSet[(int)text[i] - FIRST_CHAR].w;
+ }
+
+ textWidth += (int)((len - 1) * spacing); // Adds chars spacing to measure
+
+ if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
+ else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
+
+ Vector2 vec;
+ vec.x = (float)textWidth * scaleFactor;
+ vec.y = (float)spriteFont.charSet[0].h * scaleFactor;
+
+ return vec;
}
// Returns the base size for a SpriteFont (chars height)
int GetFontBaseSize(SpriteFont spriteFont)
{
- return spriteFont.charSet[0].h;
+ return spriteFont.charSet[0].h;
}
// Shows current FPS on top-left corner
// NOTE: Uses default font
void DrawFps(int posX, int posY)
{
- // NOTE: We are rendering fps every second for better viewing on high framerates
- static float fps;
- static int counter = 0;
- static int refreshRate = 0;
-
- char buffer[20];
-
- if (counter < refreshRate)
- {
- sprintf(buffer, "%2.0f FPS", fps);
- DrawText(buffer, posX, posY, 20, 1, LIME);
-
- counter++;
- }
- else
- {
- fps = GetFPS();
- refreshRate = fps;
- sprintf(buffer, "%2.0f FPS", fps);
- DrawText(buffer, posX, posY, 20, 1, LIME);
-
- counter = 0;
- }
+ // NOTE: We are rendering fps every second for better viewing on high framerates
+ static float fps;
+ static int counter = 0;
+ static int refreshRate = 0;
+
+ char buffer[20];
+
+ if (counter < refreshRate)
+ {
+ sprintf(buffer, "%2.0f FPS", fps);
+ DrawText(buffer, posX, posY, 20, 1, LIME);
+
+ counter++;
+ }
+ else
+ {
+ fps = GetFPS();
+ refreshRate = fps;
+ sprintf(buffer, "%2.0f FPS", fps);
+ DrawText(buffer, posX, posY, 20, 1, LIME);
+
+ counter = 0;
+ }
}
//----------------------------------------------------------------------------------
@@ -425,76 +425,76 @@ void DrawFps(int posX, int posY)
// Check if a pixel is magenta
static bool PixelIsMagenta(Color p)
{
- return ((p.r == 255) && (p.g == 0) && (p.b == 255) && (p.a == 255));
+ return ((p.r == 255) && (p.g == 0) && (p.b == 255) && (p.a == 255));
}
// Parse image pixel data to obtain character set measures
static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Character **charSet)
{
- int charSpacing = 0;
- int lineSpacing = 0;
-
- int x = 0;
- int y = 0;
-
- Character tempCharSet[MAX_FONTCHARS]; // We allocate a temporal array for charData, once we get the actual charNumber we copy data to a sized array.
-
- for(y = 0; y < imgHeight; y++)
- {
- for(x = 0; x < imgWidth; x++)
- {
- if (!PixelIsMagenta(imgDataPixel[y*imgWidth + x])) break;
- }
- if (!PixelIsMagenta(imgDataPixel[y*imgWidth + x])) break;
- }
-
- charSpacing = x;
- lineSpacing = y;
-
- int charHeight = 0;
- int j = 0;
-
- while(!PixelIsMagenta(imgDataPixel[(lineSpacing + j)*imgWidth + charSpacing])) j++;
-
- charHeight = j;
-
- // Check array values to get characters: value, x, y, w, h
- int index = 0;
- int lineToRead = 0;
- int xPosToRead = charSpacing;
-
- while((lineSpacing + lineToRead * (charHeight + lineSpacing)) < imgHeight)
- {
- while((xPosToRead < imgWidth) &&
- !PixelIsMagenta((imgDataPixel[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*imgWidth + xPosToRead])))
- {
- tempCharSet[index].value = FIRST_CHAR + index;
- tempCharSet[index].x = xPosToRead;
- tempCharSet[index].y = lineSpacing + lineToRead * (charHeight + lineSpacing);
- tempCharSet[index].h = charHeight;
-
- int charWidth = 0;
-
- while(!PixelIsMagenta(imgDataPixel[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*imgWidth + xPosToRead + charWidth])) charWidth++;
-
- tempCharSet[index].w = charWidth;
-
- index++;
-
- xPosToRead += (charWidth + charSpacing);
- }
-
- lineToRead++;
- xPosToRead = charSpacing;
- }
-
- // We got tempCharSet populated with char data and the number of chars (index)
- // Now we move temp data to real charSet (passed as parameter to the function)
- (*charSet) = (Character *)malloc(index * sizeof(Character)); // BE CAREFUL! This memory should be freed!
-
- for (int i = 0; i < index; i++) (*charSet)[i] = tempCharSet[i];
-
- return index;
+ int charSpacing = 0;
+ int lineSpacing = 0;
+
+ int x = 0;
+ int y = 0;
+
+ Character tempCharSet[MAX_FONTCHARS]; // We allocate a temporal array for charData, once we get the actual charNumber we copy data to a sized array.
+
+ for(y = 0; y < imgHeight; y++)
+ {
+ for(x = 0; x < imgWidth; x++)
+ {
+ if (!PixelIsMagenta(imgDataPixel[y*imgWidth + x])) break;
+ }
+ if (!PixelIsMagenta(imgDataPixel[y*imgWidth + x])) break;
+ }
+
+ charSpacing = x;
+ lineSpacing = y;
+
+ int charHeight = 0;
+ int j = 0;
+
+ while(!PixelIsMagenta(imgDataPixel[(lineSpacing + j)*imgWidth + charSpacing])) j++;
+
+ charHeight = j;
+
+ // Check array values to get characters: value, x, y, w, h
+ int index = 0;
+ int lineToRead = 0;
+ int xPosToRead = charSpacing;
+
+ while((lineSpacing + lineToRead * (charHeight + lineSpacing)) < imgHeight)
+ {
+ while((xPosToRead < imgWidth) &&
+ !PixelIsMagenta((imgDataPixel[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*imgWidth + xPosToRead])))
+ {
+ tempCharSet[index].value = FIRST_CHAR + index;
+ tempCharSet[index].x = xPosToRead;
+ tempCharSet[index].y = lineSpacing + lineToRead * (charHeight + lineSpacing);
+ tempCharSet[index].h = charHeight;
+
+ int charWidth = 0;
+
+ while(!PixelIsMagenta(imgDataPixel[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*imgWidth + xPosToRead + charWidth])) charWidth++;
+
+ tempCharSet[index].w = charWidth;
+
+ index++;
+
+ xPosToRead += (charWidth + charSpacing);
+ }
+
+ lineToRead++;
+ xPosToRead = charSpacing;
+ }
+
+ // We got tempCharSet populated with char data and the number of chars (index)
+ // Now we move temp data to real charSet (passed as parameter to the function)
+ (*charSet) = (Character *)malloc(index * sizeof(Character)); // BE CAREFUL! This memory should be freed!
+
+ for (int i = 0; i < index; i++) (*charSet)[i] = tempCharSet[i];
+
+ return index;
}
// Calculate next power-of-two value for a given num
@@ -503,13 +503,13 @@ static int GetNextPOT(int num)
if (num != 0)
{
num--;
- num |= (num >> 1); // Or first 2 bits
- num |= (num >> 2); // Or next 2 bits
- num |= (num >> 4); // Or next 4 bits
- num |= (num >> 8); // Or next 8 bits
+ num |= (num >> 1); // Or first 2 bits
+ num |= (num >> 2); // Or next 2 bits
+ num |= (num >> 4); // Or next 4 bits
+ num |= (num >> 8); // Or next 8 bits
num |= (num >> 16); // Or next 16 bits
num++;
}
- return num;
+ return num;
} \ No newline at end of file
diff --git a/src/textures.c b/src/textures.c
index 1a7e23a7..fc342a80 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -1,36 +1,36 @@
/*********************************************************************************************
*
-* raylib.textures
+* raylib.textures
*
-* Basic functions to load and draw Textures (2d)
-*
-* Uses external lib:
-* stb_image - Multiple formats image loading (JPEG, PNG, BMP, TGA, PSD, GIF, PIC)
+* Basic functions to load and draw Textures (2d)
+*
+* Uses external lib:
+* stb_image - Multiple formats image loading (JPEG, PNG, BMP, TGA, PSD, GIF, PIC)
*
-* Copyright (c) 2013 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.
+* Copyright (c) 2013 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.
*
-* Permission is granted to anyone to use this software for any purpose, including commercial
-* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
-* 1. The origin of this software must not be misrepresented; you must not claim that you
-* wrote the original software. If you use this software in a product, an acknowledgment
-* in the product documentation would be appreciated but is not required.
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
*
-* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
-* as being the original software.
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
*
-* 3. This notice may not be removed or altered from any source distribution.
+* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include "raylib.h"
-#include <GL/gl.h> // OpenGL functions
-#include <stdlib.h> // Declares malloc() and free() for memory management
-#include "stb_image.h" // Used to read image data (multiple formats support)
+#include <GL/gl.h> // OpenGL functions
+#include <stdlib.h> // Declares malloc() and free() for memory management
+#include "stb_image.h" // Used to read image data (multiple formats support)
//----------------------------------------------------------------------------------
// Defines and Macros
@@ -59,208 +59,210 @@ typedef unsigned char byte;
// Load an image into CPU memory (RAM)
Image LoadImage(const char *fileName)
{
- Image image;
-
- int imgWidth;
- int imgHeight;
- int imgBpp;
-
- // NOTE: Using stb_image to load images (Supports: BMP, TGA, PNG, JPG, ...)
- byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4); // Force loading to 4 components (RGBA)
-
- // Convert array to pixel array for working convenience
- image.pixels = (Color *)malloc(imgWidth * imgHeight * sizeof(Color));
-
+ Image image;
+
+ int imgWidth;
+ int imgHeight;
+ int imgBpp;
+
+ // NOTE: Using stb_image to load images (Supports: BMP, TGA, PNG, JPG, ...)
+ // Force loading to 4 components (RGBA)
+ byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
+
+ // Convert array to pixel array for working convenience
+ image.pixels = (Color *)malloc(imgWidth * imgHeight * sizeof(Color));
+
int pix = 0;
-
- for (int i = 0; i < (imgWidth * imgHeight * 4); i += 4)
- {
- image.pixels[pix].r = imgData[i];
- image.pixels[pix].g = imgData[i+1];
- image.pixels[pix].b = imgData[i+2];
- image.pixels[pix].a = imgData[i+3];
- pix++;
- }
-
- stbi_image_free(imgData);
-
- image.width = imgWidth;
- image.height = imgHeight;
-
- // 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.
- //image.pixels = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
+
+ for (int i = 0; i < (imgWidth * imgHeight * 4); i += 4)
+ {
+ image.pixels[pix].r = imgData[i];
+ image.pixels[pix].g = imgData[i+1];
+ image.pixels[pix].b = imgData[i+2];
+ image.pixels[pix].a = imgData[i+3];
+ pix++;
+ }
+
+ stbi_image_free(imgData);
+
+ image.width = imgWidth;
+ image.height = imgHeight;
+
+ // 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.
+ //image.pixels = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
- return image;
+ return image;
}
// Unload image from CPU memory (RAM)
void UnloadImage(Image image)
{
- free(image.pixels);
+ free(image.pixels);
}
// Load an image as texture into GPU memory
Texture2D LoadTexture(const char *fileName)
{
- Texture2D texture;
+ Texture2D texture;
- int imgWidth;
- int imgHeight;
- int imgBpp;
-
- // NOTE: Using stb_image to load images (Supports: BMP, TGA, PNG, JPG, ...)
- byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4); // Force loading to 4 components (RGBA)
-
- // Convert loaded data to OpenGL texture
- //----------------------------------------
- GLuint id;
- glGenTextures(1, &id); // Generate Pointer to the Texture
-
- glBindTexture(GL_TEXTURE_2D, id);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repead on x-axis
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repead on y-axis
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imgWidth, imgHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgData);
-
- // NOTE: Not using mipmappings (texture for 2D drawing)
- // At this point we have the image converted to texture and uploaded to GPU
-
- stbi_image_free(imgData); // Now we can free loaded data from RAM memory
-
- texture.glId = id;
- texture.width = imgWidth;
- texture.height = imgHeight;
-
- return texture;
+ int imgWidth;
+ int imgHeight;
+ int imgBpp;
+
+ // NOTE: Using stb_image to load images (Supports: BMP, TGA, PNG, JPG, ...)
+ // Force loading to 4 components (RGBA)
+ byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
+
+ // Convert loaded data to OpenGL texture
+ //----------------------------------------
+ GLuint id;
+ glGenTextures(1, &id); // Generate Pointer to the Texture
+
+ glBindTexture(GL_TEXTURE_2D, id);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repead on x-axis
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repead on y-axis
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imgWidth, imgHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgData);
+
+ // NOTE: Not using mipmappings (texture for 2D drawing)
+ // At this point we have the image converted to texture and uploaded to GPU
+
+ stbi_image_free(imgData); // Now we can free loaded data from RAM memory
+
+ texture.glId = id;
+ texture.width = imgWidth;
+ texture.height = imgHeight;
+
+ return texture;
}
// Load an image as texture (and convert to POT with mipmaps)
Texture2D LoadTextureEx(const char *fileName, bool createPOT, bool mipmaps)
{
- Texture2D texture;
-
- // TODO: Load and image and convert to Power-Of-Two
- // NOTE: Conversion could be done just adding extra space to image or by scaling image
- // NOTE: If scaling image, be careful with scaling algorithm (aproximation, bilinear, bicubic...)
-
- // TODO: Generate all required mipmap levels from image and convert to testure (not that easy)
- // NOTE: If using OpenGL 1.1, the only option is doing mipmap generation on CPU side (i.e. gluBuild2DMipmaps)
- // NOTE: raylib tries to minimize external dependencies so, we are not using GLU
- // NOTE: Re-implement some function similar to gluBuild2DMipmaps (not that easy...)
-
- return texture;
+ Texture2D texture;
+
+ // TODO: Load and image and convert to Power-Of-Two
+ // NOTE: Conversion could be done just adding extra space to image or by scaling image
+ // NOTE: If scaling image, be careful with scaling algorithm (aproximation, bilinear, bicubic...)
+
+ // TODO: Generate all required mipmap levels from image and convert to testure (not that easy)
+ // NOTE: If using OpenGL 1.1, the only option is doing mipmap generation on CPU side (i.e. gluBuild2DMipmaps)
+ // NOTE: raylib tries to minimize external dependencies so, we are not using GLU
+ // NOTE: Re-implement some function similar to gluBuild2DMipmaps (not that easy...)
+
+ return texture;
}
// Unload texture from GPU memory
void UnloadTexture(Texture2D texture)
{
- glDeleteTextures(1, &texture.glId);
+ glDeleteTextures(1, &texture.glId);
}
// Draw a Texture2D
void DrawTexture(Texture2D texture, int posX, int posY, Color tint)
{
- DrawTextureEx(texture, (Vector2){ (float)posX, (float)posY}, 0, 1.0f, tint);
+ DrawTextureEx(texture, (Vector2){ (float)posX, (float)posY}, 0, 1.0f, tint);
}
// Draw a Texture2D with extended parameters
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint)
{
- glEnable(GL_TEXTURE_2D); // Enable textures usage
-
- glBindTexture(GL_TEXTURE_2D, texture.glId);
-
- glPushMatrix();
- // NOTE: Rotation is applied before translation and scaling, even being called in inverse order...
- // NOTE: Rotation point is upper-left corner
- glTranslatef(position.x, position.y, 0);
- glScalef(scale, scale, 1.0f);
- glRotatef(rotation, 0, 0, 1);
-
- glBegin(GL_QUADS);
- glColor4ub(tint.r, tint.g, tint.b, tint.a);
- glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
- glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); // Bottom-left corner for texture and quad
- glTexCoord2f(1.0f, 0.0f); glVertex2f(texture.width, 0.0f); // Bottom-right corner for texture and quad
- glTexCoord2f(1.0f, 1.0f); glVertex2f(texture.width, texture.height); // Top-right corner for texture and quad
- glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, texture.height); // Top-left corner for texture and quad
- glEnd();
- glPopMatrix();
-
- glDisable(GL_TEXTURE_2D); // Disable textures usage
+ glEnable(GL_TEXTURE_2D); // Enable textures usage
+
+ glBindTexture(GL_TEXTURE_2D, texture.glId);
+
+ glPushMatrix();
+ // NOTE: Rotation is applied before translation and scaling, even being called in inverse order...
+ // NOTE: Rotation point is upper-left corner
+ glTranslatef(position.x, position.y, 0);
+ glScalef(scale, scale, 1.0f);
+ glRotatef(rotation, 0, 0, 1);
+
+ glBegin(GL_QUADS);
+ glColor4ub(tint.r, tint.g, tint.b, tint.a);
+ glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
+ glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); // Bottom-left corner for texture and quad
+ glTexCoord2f(1.0f, 0.0f); glVertex2f(texture.width, 0.0f); // Bottom-right corner for texture and quad
+ glTexCoord2f(1.0f, 1.0f); glVertex2f(texture.width, texture.height); // Top-right corner for texture and quad
+ glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, texture.height); // Top-left corner for texture and quad
+ glEnd();
+ glPopMatrix();
+
+ glDisable(GL_TEXTURE_2D); // Disable textures usage
}
// Draw a part of a texture (defined by a rectangle)
void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, float scale, Color tint)
{
- glEnable(GL_TEXTURE_2D); // Enable textures usage
-
- glBindTexture(GL_TEXTURE_2D, texture.glId);
-
- glPushMatrix();
- glTranslatef(position.x, position.y, 0);
- glScalef(scale, scale, 1.0f);
- //glRotatef(rotation, 0, 0, 1);
-
- glBegin(GL_QUADS);
- glColor4ub(tint.r, tint.g, tint.b, tint.a);
- glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
-
- // Bottom-left corner for texture and quad
- glTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
- glVertex2f(0.0f, 0.0f);
-
- // Bottom-right corner for texture and quad
- glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
- glVertex2f(sourceRec.width, 0.0f);
-
- // Top-right corner for texture and quad
- glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
- glVertex2f(sourceRec.width, sourceRec.height);
-
- // Top-left corner for texture and quad
- glTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
- glVertex2f(0.0f, sourceRec.height);
- glEnd();
- glPopMatrix();
-
- glDisable(GL_TEXTURE_2D); // Disable textures usage
+ glEnable(GL_TEXTURE_2D); // Enable textures usage
+
+ glBindTexture(GL_TEXTURE_2D, texture.glId);
+
+ glPushMatrix();
+ glTranslatef(position.x, position.y, 0);
+ glScalef(scale, scale, 1.0f);
+ //glRotatef(rotation, 0, 0, 1);
+
+ glBegin(GL_QUADS);
+ glColor4ub(tint.r, tint.g, tint.b, tint.a);
+ glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
+
+ // Bottom-left corner for texture and quad
+ glTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
+ glVertex2f(0.0f, 0.0f);
+
+ // Bottom-right corner for texture and quad
+ glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
+ glVertex2f(sourceRec.width, 0.0f);
+
+ // Top-right corner for texture and quad
+ glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
+ glVertex2f(sourceRec.width, sourceRec.height);
+
+ // Top-left corner for texture and quad
+ glTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
+ glVertex2f(0.0f, sourceRec.height);
+ glEnd();
+ glPopMatrix();
+
+ glDisable(GL_TEXTURE_2D); // Disable textures usage
}
// Creates a bitmap (BMP) file from an array of pixel data
// NOTE: This function is only used by module [core], not explicitly available to raylib users
extern void WriteBitmap(const char *fileName, const Color *imgDataPixel, int width, int height)
{
- int filesize = 54 + 3*width*height;
-
- unsigned char bmpFileHeader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0}; // Standard BMP file header
- unsigned char bmpInfoHeader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0}; // Standard BMP info header
+ int filesize = 54 + 3*width*height;
+
+ unsigned char bmpFileHeader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0}; // Standard BMP file header
+ unsigned char bmpInfoHeader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0}; // Standard BMP info header
- bmpFileHeader[2] = (unsigned char)(filesize);
- bmpFileHeader[3] = (unsigned char)(filesize>>8);
- bmpFileHeader[4] = (unsigned char)(filesize>>16);
- bmpFileHeader[5] = (unsigned char)(filesize>>24);
+ bmpFileHeader[2] = (unsigned char)(filesize);
+ bmpFileHeader[3] = (unsigned char)(filesize>>8);
+ bmpFileHeader[4] = (unsigned char)(filesize>>16);
+ bmpFileHeader[5] = (unsigned char)(filesize>>24);
- bmpInfoHeader[4] = (unsigned char)(width);
- bmpInfoHeader[5] = (unsigned char)(width>>8);
- bmpInfoHeader[6] = (unsigned char)(width>>16);
- bmpInfoHeader[7] = (unsigned char)(width>>24);
- bmpInfoHeader[8] = (unsigned char)(height);
- bmpInfoHeader[9] = (unsigned char)(height>>8);
- bmpInfoHeader[10] = (unsigned char)(height>>16);
- bmpInfoHeader[11] = (unsigned char)(height>>24);
+ bmpInfoHeader[4] = (unsigned char)(width);
+ bmpInfoHeader[5] = (unsigned char)(width>>8);
+ bmpInfoHeader[6] = (unsigned char)(width>>16);
+ bmpInfoHeader[7] = (unsigned char)(width>>24);
+ bmpInfoHeader[8] = (unsigned char)(height);
+ bmpInfoHeader[9] = (unsigned char)(height>>8);
+ bmpInfoHeader[10] = (unsigned char)(height>>16);
+ bmpInfoHeader[11] = (unsigned char)(height>>24);
- FILE *bmpFile = fopen(fileName, "wb"); // Define a pointer to bitmap file and open it in write-binary mode
-
- // NOTE: fwrite parameters are: data pointer, size in bytes of each element to be written, number of elements, file-to-write pointer
- fwrite(bmpFileHeader, sizeof(unsigned char), 14, bmpFile); // Write BMP file header data
- fwrite(bmpInfoHeader, sizeof(unsigned char), 40, bmpFile); // Write BMP info header data
-
- // Write pixel data to file
+ FILE *bmpFile = fopen(fileName, "wb"); // Define a pointer to bitmap file and open it in write-binary mode
+
+ // NOTE: fwrite parameters are: data pointer, size in bytes of each element to be written, number of elements, file-to-write pointer
+ fwrite(bmpFileHeader, sizeof(unsigned char), 14, bmpFile); // Write BMP file header data
+ fwrite(bmpInfoHeader, sizeof(unsigned char), 40, bmpFile); // Write BMP info header data
+
+ // Write pixel data to file
for (int y = 0; y < height ; y++)
{
for (int x = 0; x < width; x++)
@@ -271,5 +273,5 @@ extern void WriteBitmap(const char *fileName, const Color *imgDataPixel, int wid
}
}
- fclose(bmpFile); // Close bitmap file
+ fclose(bmpFile); // Close bitmap file
} \ No newline at end of file
diff --git a/src/vector3.c b/src/vector3.c
index 8752f4d0..378ab877 100644
--- a/src/vector3.c
+++ b/src/vector3.c
@@ -1,25 +1,25 @@
/*********************************************************************************************
*
-* raylib.vector3
+* raylib.vector3
*
-* Vector3 Functions Definition
+* Vector3 Functions Definition
*
-* Copyright (c) 2013 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.
+* Copyright (c) 2013 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.
*
-* Permission is granted to anyone to use this software for any purpose, including commercial
-* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
-* 1. The origin of this software must not be misrepresented; you must not claim that you
-* wrote the original software. If you use this software in a product, an acknowledgment
-* in the product documentation would be appreciated but is not required.
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
*
-* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
-* as being the original software.
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
*
-* 3. This notice may not be removed or altered from any source distribution.
+* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
@@ -30,59 +30,59 @@
// Add two vectors
Vector3 VectorAdd(Vector3 v1, Vector3 v2)
{
- Vector3 out;
+ Vector3 out;
- out.x = v1.x + v2.x;
- out.y = v1.y + v2.y;
- out.z = v1.z + v2.z;
-
- return out;
+ out.x = v1.x + v2.x;
+ out.y = v1.y + v2.y;
+ out.z = v1.z + v2.z;
+
+ return out;
}
// Substract two vectors
Vector3 VectorSubtract(Vector3 v1, Vector3 v2)
{
- Vector3 out;
+ Vector3 out;
- out.x = v1.x - v2.x;
- out.y = v1.y - v2.y;
- out.z = v1.z - v2.z;
-
- return out;
+ out.x = v1.x - v2.x;
+ out.y = v1.y - v2.y;
+ out.z = v1.z - v2.z;
+
+ return out;
}
// Calculate two vectors cross product
Vector3 VectorCrossProduct(Vector3 v1, Vector3 v2)
{
- Vector3 cross;
+ Vector3 cross;
- cross.x = v1.y*v2.z - v1.z*v2.y;
- cross.y = v1.z*v2.x - v1.x*v2.z;
- cross.z = v1.x*v2.y - v1.y*v2.x;
-
- return cross;
+ cross.x = v1.y*v2.z - v1.z*v2.y;
+ cross.y = v1.z*v2.x - v1.x*v2.z;
+ cross.z = v1.x*v2.y - v1.y*v2.x;
+
+ return cross;
}
// Calculate one vector perpendicular vector
Vector3 VectorPerpendicular(Vector3 v)
{
- Vector3 out;
-
+ Vector3 out;
+
float min = fabs(v.x);
Vector3 cardinalAxis = {1.0, 0.0, 0.0};
if (fabs(v.y) < min)
- {
+ {
min = fabs(v.y);
cardinalAxis = (Vector3){0.0, 1.0, 0.0};
}
if(fabs(v.z) < min)
- {
+ {
cardinalAxis = (Vector3){0.0, 0.0, 1.0};
}
-
- out = VectorCrossProduct(v, cardinalAxis);
+
+ out = VectorCrossProduct(v, cardinalAxis);
return out;
}
@@ -90,51 +90,51 @@ Vector3 VectorPerpendicular(Vector3 v)
// Calculate two vectors dot product
float VectorDotProduct(Vector3 v1, Vector3 v2)
{
- float dot;
-
- dot = v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
-
- return dot;
+ float dot;
+
+ dot = v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
+
+ return dot;
}
// Calculate vector lenght
float VectorLength(const Vector3 v)
{
- float length;
-
- length = sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
-
- return length;
+ float length;
+
+ length = sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
+
+ return length;
}
// Scale provided vector
void VectorScale(Vector3 *v, float scale)
{
- v->x *= scale;
- v->y *= scale;
- v->z *= scale;
+ v->x *= scale;
+ v->y *= scale;
+ v->z *= scale;
}
// Invert provided vector (direction)
void VectorInverse(Vector3 *v)
{
- v->x = -v->x;
- v->y = -v->y;
- v->z = -v->z;
+ v->x = -v->x;
+ v->y = -v->y;
+ v->z = -v->z;
}
// Normalize provided vector
void VectorNormalize(Vector3 *v)
{
- float length, ilength;
+ float length, ilength;
- length = VectorLength(*v);
-
- if (length == 0) length = 1;
+ length = VectorLength(*v);
+
+ if (length == 0) length = 1;
- ilength = 1.0/length;
-
- v->x *= ilength;
- v->y *= ilength;
- v->z *= ilength;
+ ilength = 1.0/length;
+
+ v->x *= ilength;
+ v->y *= ilength;
+ v->z *= ilength;
}
diff --git a/src/vector3.h b/src/vector3.h
index 3973f479..a42b2678 100644
--- a/src/vector3.h
+++ b/src/vector3.h
@@ -1,35 +1,35 @@
/*********************************************************************************************
*
-* raylib.vector3
-*
-* Some useful functions to work with Vector3
+* raylib.vector3
+*
+* Some useful functions to work with Vector3
*
-* Copyright (c) 2013 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.
+* Copyright (c) 2013 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.
*
-* Permission is granted to anyone to use this software for any purpose, including commercial
-* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
-* 1. The origin of this software must not be misrepresented; you must not claim that you
-* wrote the original software. If you use this software in a product, an acknowledgment
-* in the product documentation would be appreciated but is not required.
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
*
-* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
-* as being the original software.
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
*
-* 3. This notice may not be removed or altered from any source distribution.
+* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#ifndef VECTOR3_H
#define VECTOR3_H
-#include "raylib.h" // Defines Vector3 structure
+#include "raylib.h" // Defines Vector3 structure
#ifdef __cplusplus
-extern "C" { // Prevents name mangling of functions
+extern "C" { // Prevents name mangling of functions
#endif
//------------------------------------------------------------------------------------
@@ -40,15 +40,15 @@ extern "C" { // Prevents name mangling of functions
//------------------------------------------------------------------------------------
// Functions Declaration to work with Vector3
//------------------------------------------------------------------------------------
-Vector3 VectorAdd(Vector3 v1, Vector3 v2); // Add two vectors
-Vector3 VectorSubtract(Vector3 v1, Vector3 v2); // Substract two vectors
-Vector3 VectorCrossProduct(Vector3 v1, Vector3 v2); // Calculate two vectors cross product
-Vector3 VectorPerpendicular(Vector3 v); // Calculate one vector perpendicular vector
-float VectorDotProduct(Vector3 v1, Vector3 v2); // Calculate two vectors dot product
-float VectorLength(const Vector3 v); // Calculate vector lenght
-void VectorScale(Vector3 *v, float scale); // Scale provided vector
-void VectorInverse(Vector3 *v); // Invert provided vector (direction)
-void VectorNormalize(Vector3 *v); // Normalize provided vector
+Vector3 VectorAdd(Vector3 v1, Vector3 v2); // Add two vectors
+Vector3 VectorSubtract(Vector3 v1, Vector3 v2); // Substract two vectors
+Vector3 VectorCrossProduct(Vector3 v1, Vector3 v2); // Calculate two vectors cross product
+Vector3 VectorPerpendicular(Vector3 v); // Calculate one vector perpendicular vector
+float VectorDotProduct(Vector3 v1, Vector3 v2); // Calculate two vectors dot product
+float VectorLength(const Vector3 v); // Calculate vector lenght
+void VectorScale(Vector3 *v, float scale); // Scale provided vector
+void VectorInverse(Vector3 *v); // Invert provided vector (direction)
+void VectorNormalize(Vector3 *v); // Normalize provided vector
#ifdef __cplusplus
}