Update to version 1.0.3

View CHANGELOG for full list of changes
This commit is contained in:
raysan5 2013-12-19 12:08:06 +01:00
parent 134dcd4a6a
commit 5bf9675d38
40 changed files with 472 additions and 149 deletions

View file

@ -1,11 +1,26 @@
changelog
---------
Current Release: raylib 1.0.2 (December 2013)
Current Release: raylib 1.0.3 (December 2013)
NOTE: Only versions marked as 'Release' are available on release folder, updates are only available as source.
NOTE: Current Release includes all previous updates.
-----------------------------------------------
Release: raylib 1.0.3 (19 December 2013)
-----------------------------------------------
[fonts] Added 8 rBMF free fonts to be used on projects!
[text] LoadSpriteFont() - Now supports rBMF file loading (raylib Bitmap Font)
[examples] ex05a_sprite_fonts completed
[examples] ex05b_rbmf_fonts completed
[core] InitWindowEx() - InitWindow with extended parameters, resizing option and custom cursor!
[core] GetRandomValue() - Added, returns a random value within a range (int)
[core] SetExitKey() - Added, sets a key to exit program (default is ESC)
[core] Custom cursor not drawn when mouse out of screen
[shapes] CheckCollisionPointRec() - Added, check collision between point and rectangle
[shapes] CheckCollisionPointCircle() - Added, check collision between point and circle
[shapes] CheckCollisionPointTriangle() - Added, check collision between point and triangle
[shapes] DrawPoly() - Added, draw regular polygons of n sides, rotation can be defined!
-----------------------------------------------
Release: raylib 1.0.2 (1 December 2013)

View file

@ -27,4 +27,13 @@ applications, and to alter it and redistribute it freely, subject to the followi
fonts
------
...soon...
All rBMF fonts provided with raylib are free to use (freeware) and have been designed by the following people:
Alpha Beta - Brian Kent (AEnigma)
Setback - Brian Kent (AEnigma)
Jupiter Crash - Brian Kent (AEnigma)
Alagard - Hewett Tsoi
Romulus - Hewett Tsoi
Mecha - Captain Falcon
PixelPlay - Aleksander Shevchuk
PixAntiqua - Gerhard Großmann

View file

@ -18,10 +18,28 @@ int main()
int screenWidth = 800;
int screenHeight = 450;
const char msg1[50] = "THIS IS A custom SPRITE FONT...";
const char msg2[50] = "...and this is ANOTHER CUSTOM font...";
const char msg3[50] = "...and a THIRD one! GREAT! :D";
InitWindow(screenWidth, screenHeight, "raylib example 05a - sprite fonts");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
SpriteFont font = LoadSpriteFont("resources/custom_font.png"); // SpriteFont loading
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
SpriteFont font1 = LoadSpriteFont("resources/fonts/custom_mecha.png"); // SpriteFont loading
SpriteFont font2 = LoadSpriteFont("resources/fonts/custom_alagard.png"); // SpriteFont loading
SpriteFont font3 = LoadSpriteFont("resources/fonts/custom_jupiter_crash.png"); // SpriteFont loading
Vector2 fontPosition1, fontPosition2, fontPosition3;
fontPosition1.x = screenWidth/2 - MeasureTextEx(font1, msg1, GetFontBaseSize(font1), -3).x/2;
fontPosition1.y = screenHeight/2 - GetFontBaseSize(font1)/2 - 80;
fontPosition2.x = screenWidth/2 - MeasureTextEx(font2, msg2, GetFontBaseSize(font2), -2).x/2;
fontPosition2.y = screenHeight/2 - GetFontBaseSize(font2)/2 - 10;
fontPosition3.x = screenWidth/2 - MeasureTextEx(font3, msg3, GetFontBaseSize(font3), 2).x/2;
fontPosition3.y = screenHeight/2 - GetFontBaseSize(font3)/2 + 50;
//--------------------------------------------------------------------------------------
// Main game loop
@ -29,7 +47,7 @@ int main()
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
// TODO: Update variables here...
//----------------------------------------------------------------------------------
// Draw
@ -38,18 +56,19 @@ int main()
ClearBackground(RAYWHITE);
// TODO: Comming soon...
// TIP: Use DrawTextEx() function
/*
void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint);
*/
DrawTextEx(font1, msg1, fontPosition1, GetFontBaseSize(font1), -3, WHITE);
DrawTextEx(font2, msg2, fontPosition2, GetFontBaseSize(font2), -2, WHITE);
DrawTextEx(font3, msg3, fontPosition3, GetFontBaseSize(font3), 2, WHITE);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadSpriteFont(font); // SpriteFont unloading
UnloadSpriteFont(font1); // SpriteFont unloading
UnloadSpriteFont(font2); // SpriteFont unloading
UnloadSpriteFont(font3); // SpriteFont unloading
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Before After
Before After

View file

@ -9,19 +9,26 @@
*
********************************************************************************************/
#include "raylib.h"
#include "../raylib.h"
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
int screenWidth = 560;
int screenHeight = 800;
InitWindow(screenWidth, screenHeight, "raylib example 04b - texture rectangle");
InitWindow(screenWidth, screenHeight, "raylib example 05b - rBMF fonts");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
SpriteFont font = LoadSpriteFont("resources/custom_font.rbmf"); // SpriteFont loading
SpriteFont font1 = LoadSpriteFont("resources/fonts/alagard.rbmf"); // SpriteFont loading
SpriteFont font2 = LoadSpriteFont("resources/fonts/pixelplay.rbmf"); // SpriteFont loading
SpriteFont font3 = LoadSpriteFont("resources/fonts/mecha.rbmf"); // SpriteFont loading
SpriteFont font4 = LoadSpriteFont("resources/fonts/setback.rbmf"); // SpriteFont loading
SpriteFont font5 = LoadSpriteFont("resources/fonts/romulus.rbmf"); // SpriteFont loading
SpriteFont font6 = LoadSpriteFont("resources/fonts/pixantiqua.rbmf"); // SpriteFont loading
SpriteFont font7 = LoadSpriteFont("resources/fonts/alpha_beta.rbmf"); // SpriteFont loading
SpriteFont font8 = LoadSpriteFont("resources/fonts/jupiter_crash.rbmf"); // SpriteFont loading
//--------------------------------------------------------------------------------------
// Main game loop
@ -38,20 +45,31 @@ int main()
ClearBackground(RAYWHITE);
// TODO: Comming soon...
// TIP: Use DrawTextEx() function
/*
void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint);
*/
DrawTextEx(font1, "TESTING ALAGARD FONT", (Vector2){ 100, 100 }, GetFontBaseSize(font1)*2, 2, MAROON);
DrawTextEx(font2, "TESTING PIXELPLAY FONT", (Vector2){ 100, 180 }, GetFontBaseSize(font2)*2, 4, ORANGE);
DrawTextEx(font3, "TESTING MECHA FONT", (Vector2){ 100, 260 }, GetFontBaseSize(font3)*2, 8, DARKGREEN);
DrawTextEx(font4, "TESTING SETBACK FONT", (Vector2){ 100, 350 }, GetFontBaseSize(font4)*2, 4, DARKBLUE);
DrawTextEx(font5, "TESTING ROMULUS FONT", (Vector2){ 100, 430 }, GetFontBaseSize(font5)*2, 3, DARKPURPLE);
DrawTextEx(font6, "TESTING PIXANTIQUA FONT", (Vector2){ 100, 510 }, GetFontBaseSize(font6)*2, 4, LIME);
DrawTextEx(font7, "TESTING ALPHA_BETA FONT", (Vector2){ 100, 590 }, GetFontBaseSize(font7)*2, 4, GOLD);
DrawTextEx(font8, "TESTING JUPITER_CRASH FONT", (Vector2){ 100, 660 }, GetFontBaseSize(font8)*2, 1, RED);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadSpriteFont(font); // SpriteFont unloading
UnloadSpriteFont(font1); // SpriteFont unloading
UnloadSpriteFont(font2); // SpriteFont unloading
UnloadSpriteFont(font3); // SpriteFont unloading
UnloadSpriteFont(font4); // SpriteFont unloading
UnloadSpriteFont(font5); // SpriteFont unloading
UnloadSpriteFont(font6); // SpriteFont unloading
UnloadSpriteFont(font7); // SpriteFont unloading
UnloadSpriteFont(font8); // SpriteFont unloading
CloseWindow(); // Close window and OpenGL context
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -24,7 +24,7 @@ int main()
InitAudioDevice(); // Initialize audio device
Sound fx = LoadSound("resources/weird.wav"); // Load WAV audio file
Sound fx = LoadSound("resources/audio/weird.wav"); // Load WAV audio file
//--------------------------------------------------------------------------------------
// Main game loop

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
fonts/alagard.rbmf Normal file

Binary file not shown.

BIN
fonts/alpha_beta.rbmf Normal file

Binary file not shown.

View file

BIN
fonts/jupiter_crash.rbmf Normal file

Binary file not shown.

BIN
fonts/mecha.rbmf Normal file

Binary file not shown.

BIN
fonts/pixantiqua.rbmf Normal file

Binary file not shown.

BIN
fonts/pixelplay.rbmf Normal file

Binary file not shown.

BIN
fonts/romulus.rbmf Normal file

Binary file not shown.

BIN
fonts/setback.rbmf Normal file

Binary file not shown.

View file

@ -1,6 +1,6 @@
/*********************************************************************************************
*
* raylib 1.0.2 (www.raylib.com)
* raylib 1.0.3 (www.raylib.com)
*
* A simple and easy-to-use library to learn C videogames programming
*
@ -236,10 +236,13 @@ 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 InitWindow(int width, int height, const char *title); // Initialize Window and Graphics Context (OpenGL)
void InitWindowEx(int width, int height, const char* title, bool resizable, const char *cursorImage);
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 SetCustomCursor(const char *cursorImage); // Set a custom cursor icon/image
void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
void ClearBackground(Color color); // Sets Background Color
void BeginDrawing(); // Setup drawing canvas to start drawing
@ -255,6 +258,8 @@ float GetFrameTime(); // Returns time in secon
Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
int GetHexValue(Color color); // Returns hexadecimal value for a Color
int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
//------------------------------------------------------------------------------------
// Input Handling Functions (Module: core)
//------------------------------------------------------------------------------------
@ -296,8 +301,9 @@ void DrawRectangleV(Vector2 position, Vector2 size, Color color);
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 DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points
void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines
bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
@ -323,6 +329,7 @@ Texture2D CreateTexture2D(Image image);
//------------------------------------------------------------------------------------
SpriteFont GetDefaultFont(); // Get the default SpriteFont
SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
SpriteFont LoadFontRBMF(const char *fileName);
void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
void DrawText(const char *text, int posX, int posY, int fontSize, 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

Binary file not shown.

View file

@ -31,7 +31,8 @@
#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 <stdlib.h> // Declares malloc() and free() for memory management, rand()
#include <time.h> // Useful to initialize random seed
#include <math.h> // Math related functions, tan() on SetPerspective
#include "vector3.h" // Basic Vector3 functions
@ -59,7 +60,12 @@ 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 const char *windowTitle; // Required to switch between windowed/fullscren mode (F11)
static int exitKey = GLFW_KEY_ESCAPE;
static bool customCursor = false; // Tracks if custom cursor has been set
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
static Texture2D cursor; // Cursor texture
static char previousKeyState[512] = { 0 }; // Required to check if key pressed/released once
static char currentKeyState[512] = { 0 }; // Required to check if key pressed/released once
@ -83,6 +89,7 @@ extern void WriteBitmap(const char *fileName, const pixel *imgDataPixel, int wid
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 CursorEnterCallback(GLFWwindow* window, int enter); // GLFW3 Cursor Enter Callback, cursor enters client area
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)
@ -93,13 +100,21 @@ static void TakeScreenshot();
//----------------------------------------------------------------------------------
// Initialize Window and Graphics Context (OpenGL)
void InitWindow(int width, int height, char* title)
void InitWindow(int width, int height, const char *title)
{
InitWindowEx(width, height, title, true, NULL);
}
// Initialize Window and Graphics Context (OpenGL) with extended parameters
void InitWindowEx(int width, int height, const char* title, bool resizable, const char *cursorImage)
{
glfwSetErrorCallback(ErrorCallback);
if (!glfwInit()) exit(1);
//glfwWindowHint(GLFW_SAMPLES, 4); // If called before windows creation, enables multisampling x4 (MSAA), default is 0
//glfwDefaultWindowHints() // Set default windows hints
//glfwWindowHint(GLFW_SAMPLES, 4); // If called before windows creation, enables multisampling x4 (MSAA), default is 0
if (!resizable) glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
window = glfwCreateWindow(width, height, title, NULL, NULL);
@ -114,6 +129,7 @@ void InitWindow(int width, int height, char* title)
}
glfwSetWindowSizeCallback(window, WindowSizeCallback);
glfwSetCursorEnterCallback(window, CursorEnterCallback);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, KeyCallback);
@ -125,6 +141,17 @@ void InitWindow(int width, int height, char* title)
previousTime = glfwGetTime();
LoadDefaultFont();
if (cursorImage != NULL)
{
// Load image as texture
cursor = LoadTexture(cursorImage);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
customCursor = true;
}
srand(time(NULL)); // Initialize random seed
}
// Close Window and Terminate Context
@ -136,6 +163,24 @@ void CloseWindow()
glfwTerminate();
}
// Set a custom cursor icon/image
void SetCustomCursor(const char *cursorImage)
{
if (customCursor) UnloadTexture(cursor);
cursor = LoadTexture(cursorImage);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
customCursor = true;
}
// Set a custom key to exit program
// NOTE: default exitKey is ESCAPE
void SetExitKey(int key)
{
exitKey = key;
}
// Detect if KEY_ESCAPE pressed or Close icon pressed
bool WindowShouldClose()
{
@ -197,6 +242,8 @@ void BeginDrawing()
// End canvas drawing and Swap Buffers (Double Buffering)
void EndDrawing()
{
if (customCursor && cursorOnScreen) DrawTexture(cursor, GetMouseX(), GetMouseY(), WHITE);
glfwSwapBuffers(window); // Swap back and front buffers
glfwPollEvents(); // Register keyboard/mouse events
@ -294,6 +341,12 @@ int GetHexValue(Color color)
return ((color.a << 24) + (color.r << 16) + (color.g << 8) + color.b);
}
// Returns a random value between min and max (both included)
int GetRandomValue(int min, int max)
{
return (rand()%(abs(max-min)+1) - abs(min));
}
//----------------------------------------------------------------------------------
// Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions
//----------------------------------------------------------------------------------
@ -529,14 +582,14 @@ bool IsGamepadButtonUp(int gamepad, int button)
// GLFW3 Error Callback, runs on GLFW3 error
static void ErrorCallback(int error, const char *description)
{
//printf(description);
fprintf(stderr, "%s", description);
printf(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)
if (key == exitKey && action == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GL_TRUE);
@ -552,6 +605,12 @@ static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, i
}
}
static void CursorEnterCallback(GLFWwindow* window, int enter)
{
if (enter == GL_TRUE) cursorOnScreen = true;
else cursorOnScreen = false;
}
// GLFW3 WindowSize Callback, runs when window is resized
static void WindowSizeCallback(GLFWwindow* window, int width, int height)
{

View file

@ -181,8 +181,6 @@ void DrawSphereWires(Vector3 centerPos, float radius, Color color)
// 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!
{
static int count = 0;
Vector3 a = { position.x, position.y + height, position.z };
Vector3 d = { 0.0f, 1.0f, 0.0f };
Vector3 p;
@ -202,7 +200,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
glPushMatrix();
//glTranslatef(centerPos.x, centerPos.y, centerPos.z);
glRotatef(DEG2RAD*count, 0.0f, 1.0f, 0.0f);
//glRotatef(degrees, 0.0f, 1.0f, 0.0f);
//glScalef(1.0f, 1.0f, 1.0f);
// Draw cone top
@ -239,7 +237,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
{
glPushMatrix();
//glTranslatef(centerPos.x, centerPos.y, centerPos.z);
glRotatef(DEG2RAD*count, 0.0f, 1.0f, 0.0f);
//glRotatef(degrees, 0.0f, 1.0f, 0.0f);
//glScalef(1.0f, 1.0f, 1.0f);
// Draw cylinder top (pointed cap)
@ -290,8 +288,6 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
glPopMatrix();
}
count += 1;
}
// Draw a cylinder/cone wires

View file

@ -1,6 +1,6 @@
/*********************************************************************************************
*
* raylib 1.0.2 (www.raylib.com)
* raylib 1.0.3 (www.raylib.com)
*
* A simple and easy-to-use library to learn C videogames programming
*
@ -236,10 +236,13 @@ 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 InitWindow(int width, int height, const char *title); // Initialize Window and Graphics Context (OpenGL)
void InitWindowEx(int width, int height, const char* title, bool resizable, const char *cursorImage);
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 SetCustomCursor(const char *cursorImage); // Set a custom cursor icon/image
void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
void ClearBackground(Color color); // Sets Background Color
void BeginDrawing(); // Setup drawing canvas to start drawing
@ -255,6 +258,8 @@ float GetFrameTime(); // Returns time in secon
Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
int GetHexValue(Color color); // Returns hexadecimal value for a Color
int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
//------------------------------------------------------------------------------------
// Input Handling Functions (Module: core)
//------------------------------------------------------------------------------------
@ -296,8 +301,9 @@ void DrawRectangleV(Vector2 position, Vector2 size, Color color);
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 DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points
void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines
bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
@ -323,6 +329,7 @@ Texture2D CreateTexture2D(Image image);
//------------------------------------------------------------------------------------
SpriteFont GetDefaultFont(); // Get the default SpriteFont
SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
SpriteFont LoadFontRBMF(const char *fileName);
void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
void DrawText(const char *text, int posX, int posY, int fontSize, 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

View file

@ -102,23 +102,13 @@ void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
}
// Draw a color-filled circle
// TODO: Review, on some GPUs is drawn with a weird transparency (GL_POLYGON_SMOOTH issue?)
void DrawCircle(int centerX, int centerY, float radius, Color color)
{
glEnable(GL_POLYGON_SMOOTH);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); // Deprecated on OGL 3.0
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);
glVertex2f(centerX + sin(degInRad) * radius, centerY + cos(degInRad) * radius);
}
glEnd();
DrawPoly((Vector2){centerX, centerY}, 360, radius, 0, color);
glDisable(GL_POLYGON_SMOOTH);
@ -283,9 +273,30 @@ void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
glEnd();
}
// Draw a regular polygon of n sides (Vector version)
void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color)
{
if (sides < 3) sides = 3;
glPushMatrix();
glTranslatef(center.x, center.y, 0);
glRotatef(rotation, 0, 0, 1);
glBegin(GL_TRIANGLE_FAN);
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2f(0, 0);
for (int i=0; i <= sides; i++)
{
glVertex2f(radius*cos(i*2*PI/sides), radius*sin(i*2*PI/sides));
}
glEnd();
glPopMatrix();
}
// 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)
void DrawPolyEx(Vector2 *points, int numPoints, Color color)
{
if (numPoints >= 3)
{
@ -307,7 +318,7 @@ void DrawPoly(Vector2 *points, int numPoints, Color color)
// Draw polygon lines
// NOTE: Array num elements MUST be passed as parameter to function
void DrawPolyLine(Vector2 *points, int numPoints, Color color)
void DrawPolyExLines(Vector2 *points, int numPoints, Color color)
{
if (numPoints >= 2)
{
@ -327,6 +338,40 @@ void DrawPolyLine(Vector2 *points, int numPoints, Color color)
}
}
// Check if point is inside rectangle
bool CheckCollisionPointRec(Vector2 point, Rectangle rec)
{
bool collision = false;
if ((point.x >= rec.x) && (point.x <= (rec.x + rec.width)) && (point.y >= rec.y) && (point.y <= (rec.y + rec.height))) collision = true;
return collision;
}
// Check if point is inside circle
bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius)
{
return CheckCollisionCircles(point, 0, center, radius);
}
// Check if point is inside a triangle defined by three points (p1, p2, p3)
bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3)
{
bool collision = false;
float alpha = ((p2.y - p3.y)*(point.x - p3.x) + (p3.x - p2.x)*(point.y - p3.y)) /
((p2.y - p3.y)*(p1.x - p3.x) + (p3.x - p2.x)*(p1.y - p3.y));
float beta = ((p3.y - p1.y)*(point.x - p3.x) + (p1.x - p3.x)*(point.y - p3.y)) /
((p2.y - p3.y)*(p1.x - p3.x) + (p3.x - p2.x)*(p1.y - p3.y));
float gamma = 1.0f - alpha - beta;
if ((alpha > 0) && (beta > 0) & (gamma > 0)) collision = true;
return collision;
}
// Check collision between two rectangles
bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2)
{

View file

@ -65,9 +65,11 @@ static SpriteFont defaultFont; // Default font provided by raylib
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
static bool PixelIsMagenta(Color p); // Check if a pixel is magenta
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 int GetNextPOT(int num); // Calculate next power-of-two value for a given value
static SpriteFont LoadRBMF(const char *fileName); // Load a rBMF font file (raylib BitMap Font)
static const char *GetExtension(const char *fileName);
//----------------------------------------------------------------------------------
// Module Functions Definition
@ -203,80 +205,90 @@ 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;
int pix = 0;
for (int i = 0; i < (imgWidth * imgHeight * 4); i += 4)
// Check file extension
if (strcmp(GetExtension(fileName),"rbmf") == 0) spriteFont = LoadRBMF(fileName);
else
{
imgDataPixel[pix].r = imgData[i];
imgDataPixel[pix].g = imgData[i+1];
imgDataPixel[pix].b = imgData[i+2];
imgDataPixel[pix].a = imgData[i+3];
pix++;
}
// Use stb_image to load image data!
int imgWidth;
int imgHeight;
int imgBpp;
stbi_image_free(imgData);
byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4); // Force loading to 4 components (RGBA)
// At this point we have a pixel array with all the data...
// Convert array to pixel array for working convenience
Color *imgDataPixel = (Color *)malloc(imgWidth * imgHeight * sizeof(Color));
Color *imgDataPixelPOT = NULL;
// 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);
int pix = 0;
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 < (imgWidth * imgHeight * 4); i += 4)
{
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;
}
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);
fprintf(stderr, "SpriteFont data parsed correctly!\n");
fprintf(stderr, "SpriteFont num chars: %i\n", numChars);
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 != imgHeight))
{
// 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;
}
}
fprintf(stderr, "SpriteFont texture converted to POT: %i %i\n", potWidth, potHeight);
}
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;
}
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;
}
@ -289,31 +301,23 @@ void UnloadSpriteFont(SpriteFont spriteFont)
// 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
// NOTE: chars spacing is proportional to fontSize
void DrawText(const char* text, int posX, int posY, int fontSize, Color color)
{
Vector2 position = { (float)posX, (float)posY };
DrawTextEx(defaultFont, text, position, fontSize, 1, color);
}
int defaultFontSize = 10; // Default Font chars height in pixel
// 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
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
va_list args;
va_start(args, text);
vsprintf(buffer, text, args); // NOTE: We use vsprintf() defined in <stdarg.h>
va_end(args);
int spacing = fontSize / defaultFontSize;
//strcat(buffer, "\0"); // We add a end-of-string mark at the end (not needed)
return buffer;
DrawTextEx(defaultFont, text, position, fontSize, spacing, color);
}
// Draw text using SpriteFont
// NOTE: If font size is lower than base size, base size is used
// NOTE: chars spacing is NOT proportional to fontSize
void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint)
{
int length = strlen(text);
@ -345,7 +349,7 @@ void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int f
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;
positionX += ((spriteFont.charSet[(int)text[i] - FIRST_CHAR].w) * scaleFactor + spacing);
}
glEnd();
@ -354,6 +358,22 @@ void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int f
glDisable(GL_TEXTURE_2D);
}
// 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;
}
// Measure string width for default font
int MeasureText(const char *text, int fontSize)
{
@ -518,3 +538,131 @@ static int GetNextPOT(int num)
return num;
}
// Load a rBMF font file (raylib BitMap Font)
static SpriteFont LoadRBMF(const char *fileName)
{
// rBMF Info Header (16 bytes)
typedef struct {
char id[4]; // rBMF file identifier
char version; // rBMF file version
// 4 MSB --> main version
// 4 LSB --> subversion
char firstChar; // First character in the font
// NOTE: Depending on charDataType, it could be useless
short imgWidth; // Image width - always POT (power-of-two)
short imgHeight; // Image height - always POT (power-of-two)
short numChars; // Number of characters contained
short charHeight; // Characters height - the same for all characters
char compType; // Compression type:
// 4 MSB --> image data compression
// 4 LSB --> chars data compression
char charsDataType; // Char data type provided
} rbmfInfoHeader;
SpriteFont spriteFont;
Image image;
rbmfInfoHeader rbmfHeader;
unsigned int *rbmfFileData;
unsigned char *rbmfCharWidthData;
int charsDivisor = 1; // Every char is separated from the consecutive by a 1 pixel divisor, horizontally and vertically
FILE *rbmfFile = fopen(fileName, "rb"); // Define a pointer to bitmap file and open it in read-binary mode
fread(&rbmfHeader, sizeof(rbmfInfoHeader), 1, rbmfFile);
//printf("rBMF info: %i %i %i %i\n", rbmfHeader.imgWidth, rbmfHeader.imgHeight, rbmfHeader.numChars, rbmfHeader.charHeight);
spriteFont.numChars = (int)rbmfHeader.numChars;
image.width = (int)rbmfHeader.imgWidth;
image.height = (int)rbmfHeader.imgHeight;
int numPixelBits = rbmfHeader.imgWidth * rbmfHeader.imgHeight / 32;
rbmfFileData = (unsigned int *)malloc(numPixelBits * sizeof(unsigned int));
for(int i = 0; i < numPixelBits; i++) fread(&rbmfFileData[i], sizeof(unsigned int), 1, rbmfFile);
rbmfCharWidthData = (unsigned char *)malloc(spriteFont.numChars * sizeof(unsigned char));
for(int i = 0; i < spriteFont.numChars; i++) fread(&rbmfCharWidthData[i], sizeof(unsigned char), 1, rbmfFile);
printf("Just read image data and width data... Starting image reconstruction...");
// Re-construct image from rbmfFileData
//-----------------------------------------
image.pixels = (Color *)malloc(image.width * image.height * sizeof(Color));
for (int i = 0; i < image.width * image.height; i++) image.pixels[i] = BLANK; // Initialize array
int counter = 0; // Font data elements counter
// Fill image data (convert from bit to pixel!)
for (int i = 0; i < image.width * image.height; i += 32)
{
for (int j = 31; j >= 0; j--)
{
if (BIT_CHECK(rbmfFileData[counter], j)) image.pixels[i+j] = WHITE;
}
counter++;
}
printf("Image reconstructed correctly... now converting it to texture...");
spriteFont.texture = CreateTexture2D(image);
UnloadImage(image); // Unload image data
printf("Starting charSet reconstruction...\n");
// Reconstruct charSet using rbmfCharWidthData, rbmfHeader.charHeight, charsDivisor, rbmfHeader.numChars
spriteFont.charSet = (Character *)malloc(spriteFont.numChars * sizeof(Character)); // Allocate space for our character data
int currentLine = 0;
int currentPosX = charsDivisor;
int testPosX = charsDivisor;
for (int i = 0; i < spriteFont.numChars; i++)
{
spriteFont.charSet[i].value = (int)rbmfHeader.firstChar + i;
spriteFont.charSet[i].x = currentPosX;
spriteFont.charSet[i].y = charsDivisor + currentLine * ((int)rbmfHeader.charHeight + charsDivisor);
spriteFont.charSet[i].w = (int)rbmfCharWidthData[i];
spriteFont.charSet[i].h = (int)rbmfHeader.charHeight;
testPosX += (spriteFont.charSet[i].w + charsDivisor);
if (testPosX > spriteFont.texture.width)
{
currentLine++;
currentPosX = 2 * charsDivisor + (int)rbmfCharWidthData[i];
testPosX = currentPosX;
spriteFont.charSet[i].x = charsDivisor;
spriteFont.charSet[i].y = charsDivisor + currentLine * (rbmfHeader.charHeight + charsDivisor);
}
else currentPosX = testPosX;
//printf("Char %i data: %i %i %i %i\n", spriteFont.charSet[i].value, spriteFont.charSet[i].x, spriteFont.charSet[i].y, spriteFont.charSet[i].w, spriteFont.charSet[i].h);
}
printf("CharSet reconstructed correctly... Data should be ready...\n");
fclose(rbmfFile);
free(rbmfFileData); // Now we can free loaded data from RAM memory
free(rbmfCharWidthData);
return spriteFont;
}
static const char *GetExtension(const char *fileName)
{
const char *dot = strrchr(fileName, '.');
if(!dot || dot == fileName) return "";
return dot + 1;
}