Browse Source

Update to version 1.0.6

Check CHANGELOG for the list of changes in this release!
raysan5 11 years ago
parent
commit
a68818e320

+ 17 - 1
CHANGELOG

@@ -1,16 +1,32 @@
 changelog
 changelog
 ---------
 ---------
 
 
-Current Release:    raylib 1.0.4 (January 2014)
+Current Release:    raylib 1.0.6 (March 2014)
 
 
 NOTE: Only versions marked as 'Release' are available on release folder, updates are only available as source.
 NOTE: Only versions marked as 'Release' are available on release folder, updates are only available as source.
 NOTE: Current Release includes all previous updates.
 NOTE: Current Release includes all previous updates.
 
 
+-----------------------------------------------
+Release:     raylib 1.0.6 (16 March 2014)
+-----------------------------------------------
+[core] Removed unused lighting-system code
+[core] Removed SetPerspective() function, calculated directly
+[core] Unload and reload default font on fullscreen toggle
+[core] Corrected bug gamepad buttons checking if no gamepad available 
+[texture] DrawTextureV() - Added, to draw using Vector2 for position
+[texture] LoadTexture() - Redesigned, now uses LoadImage() + CreateTexture()
+[text] FormatText() - Corrected memory leak bug
+[models] Added Matrix struct and related functions
+[models] DrawBillboard() - Reviewed, now it works!
+[models] DrawBillboardRec() - Reviewed, now it works!
+[tests] Added folder with multiple tests for new functions
+
 -----------------------------------------------
 -----------------------------------------------
 Update:     raylib 1.0.5 (28 January 2014)
 Update:     raylib 1.0.5 (28 January 2014)
 -----------------------------------------------
 -----------------------------------------------
 [audio] LoadSound() - Corrected a bug, WAV file was not closed!
 [audio] LoadSound() - Corrected a bug, WAV file was not closed!
 [core] GetMouseWheelMove() - Added, check mouse wheel Y movement
 [core] GetMouseWheelMove() - Added, check mouse wheel Y movement
+[texture] CreateTexture2D() renamed to CreateTexture()
 [models] LoadHeightmap() - Added, Heightmap can be loaded as a Model
 [models] LoadHeightmap() - Added, Heightmap can be loaded as a Model
 [tool] rREM updated, now supports (partially) drag and drop of files 
 [tool] rREM updated, now supports (partially) drag and drop of files 
 
 

+ 8 - 9
release/win32-mingw/include/raylib.h

@@ -1,6 +1,6 @@
 /*********************************************************************************************
 /*********************************************************************************************
 * 
 * 
-*   raylib 1.0.4 (www.raylib.com)
+*   raylib 1.0.6 (www.raylib.com)
 *    
 *    
 *   A simple and easy-to-use library to learn videogames programming
 *   A simple and easy-to-use library to learn videogames programming
 *
 *
@@ -65,6 +65,7 @@
 #define KEY_SPACE            32
 #define KEY_SPACE            32
 #define KEY_ESCAPE          256
 #define KEY_ESCAPE          256
 #define KEY_ENTER           257
 #define KEY_ENTER           257
+#define KEY_BACKSPACE       259
 #define KEY_RIGHT           262
 #define KEY_RIGHT           262
 #define KEY_LEFT            263
 #define KEY_LEFT            263
 #define KEY_DOWN            264
 #define KEY_DOWN            264
@@ -278,6 +279,7 @@ bool IsMouseButtonUp(int button);                       // Detect if a mouse but
 int GetMouseX();                                        // Returns mouse position X
 int GetMouseX();                                        // Returns mouse position X
 int GetMouseY();                                        // Returns mouse position Y
 int GetMouseY();                                        // Returns mouse position Y
 Vector2 GetMousePosition();                             // Returns mouse position XY
 Vector2 GetMousePosition();                             // Returns mouse position XY
+int GetMouseWheelMove();                                // Returns mouse wheel movement Y
 
 
 bool IsGamepadAvailable(int gamepad);                   // Detect if a gamepad is available
 bool IsGamepadAvailable(int gamepad);                   // Detect if a gamepad is available
 Vector2 GetGamepadMovement(int gamepad);                // Return axis movement vector for a gamepad
 Vector2 GetGamepadMovement(int gamepad);                // Return axis movement vector for a gamepad
@@ -323,11 +325,12 @@ Image LoadImage(const char *fileName);
 Image LoadImageFromRES(const char *rresName, int resId);                                           // Load an image from rRES file (raylib Resource)
 Image LoadImageFromRES(const char *rresName, int resId);                                           // Load an image from rRES file (raylib Resource)
 Texture2D LoadTexture(const char *fileName);                                                       // Load an image as texture into GPU memory
 Texture2D LoadTexture(const char *fileName);                                                       // Load an image as texture into GPU memory
 Texture2D LoadTextureFromRES(const char *rresName, int resId);                                     // Load an image as texture from rRES file (raylib Resource)
 Texture2D LoadTextureFromRES(const char *rresName, int resId);                                     // Load an image as texture from rRES file (raylib Resource)
-Texture2D CreateTexture2D(Image image);                                                            // Create a Texture2D from Image data
+Texture2D CreateTexture(Image image);                                                              // Create a Texture2D from Image data
 void UnloadImage(Image image);                                                                     // Unload image from CPU memory (RAM)
 void UnloadImage(Image image);                                                                     // Unload image from CPU memory (RAM)
 void UnloadTexture(Texture2D texture);                                                             // Unload texture from GPU memory
 void UnloadTexture(Texture2D texture);                                                             // Unload texture from GPU memory
 
 
 void DrawTexture(Texture2D texture, int posX, int posY, Color tint);                               // Draw a Texture2D
 void DrawTexture(Texture2D texture, int posX, int posY, Color tint);                               // Draw a Texture2D
+void DrawTextureV(Texture2D texture, Vector2 position, Color tint);                                // Draw a Texture2D with position defined as Vector2
 void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint);  // Draw a Texture2D with extended parameters
 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, Color tint);         // Draw a part of a texture defined by a rectangle
 void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint);         // Draw a part of a texture defined by a rectangle
 void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin,     // Draw a part of a texture defined by a rectangle with 'pro' parameters
 void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin,     // Draw a part of a texture defined by a rectangle with 'pro' parameters
@@ -370,17 +373,13 @@ void DrawGizmo(Vector3 position, bool orbits);
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
 Model LoadModel(const char *fileName);                                                             // Load a 3d model (.OBJ)
 Model LoadModel(const char *fileName);                                                             // Load a 3d model (.OBJ)
 //Model LoadModelFromRES(const char *rresName, int resId);                                         // TODO: Load a 3d model from rRES file (raylib Resource)
 //Model LoadModelFromRES(const char *rresName, int resId);                                         // TODO: Load a 3d model from rRES file (raylib Resource)
+Model LoadHeightmap(Image heightmap, float maxHeight);                                             // Load a heightmap image as a 3d model
 void UnloadModel(Model model);                                                                     // Unload 3d model from memory
 void UnloadModel(Model model);                                                                     // Unload 3d model from memory
 void DrawModel(Model model, Vector3 position, float scale, Color color);                           // Draw a model
 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 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
 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 center, float size, Color tint);                         // Draw a billboard texture
+void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec 
 
 
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
 // Audio Loading and Playing Functions (Module: audio)
 // Audio Loading and Playing Functions (Module: audio)

BIN
release/win32-mingw/lib/libraylib.a


+ 14 - 43
src/core.c

@@ -33,7 +33,7 @@
 #include <stdio.h>          // Standard input / output lib
 #include <stdio.h>          // Standard input / output lib
 #include <stdlib.h>         // Declares malloc() and free() for memory management, rand()
 #include <stdlib.h>         // Declares malloc() and free() for memory management, rand()
 #include <time.h>           // Useful to initialize random seed
 #include <time.h>           // Useful to initialize random seed
-#include <math.h>           // Math related functions, tan() on SetPerspective
+#include <math.h>           // Math related functions, tan() used to set perspective
 #include "vector3.h"        // Basic Vector3 functions
 #include "vector3.h"        // Basic Vector3 functions
 #include "utils.h"          // WritePNG() function
 #include "utils.h"          // WritePNG() function
 
 
@@ -96,7 +96,6 @@ static void ScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
 static void CursorEnterCallback(GLFWwindow* window, int enter);                            // GLFW3 Cursor Enter Callback, cursor enters client area
 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 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 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 TakeScreenshot();                                                              // Takes a bitmap (BMP) screenshot and saves it in the same folder as executable
 
 
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
@@ -147,14 +146,7 @@ void InitWindowEx(int width, int height, const char* title, bool resizable, cons
 
 
     LoadDefaultFont();
     LoadDefaultFont();
     
     
-    if (cursorImage != NULL) 
-    {
-        // Load image as texture
-        cursor = LoadTexture(cursorImage);  
-    
-        glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
-        customCursor = true;
-    }
+    if (cursorImage != NULL) SetCustomCursor(cursorImage);
     
     
     srand(time(NULL));      // Initialize random seed
     srand(time(NULL));      // Initialize random seed
 }
 }
@@ -199,6 +191,8 @@ void ToggleFullscreen()
     {
     {
         fullscreen = !fullscreen;          // Toggle fullscreen flag
         fullscreen = !fullscreen;          // Toggle fullscreen flag
 
 
+        UnloadDefaultFont();
+        
         glfwDestroyWindow(window);         // Destroy the current window (we will recreate it!)
         glfwDestroyWindow(window);         // Destroy the current window (we will recreate it!)
         
         
         // TODO: WARNING! All loaded resources are lost, we loose Context!
         // TODO: WARNING! All loaded resources are lost, we loose Context!
@@ -217,6 +211,8 @@ void ToggleFullscreen()
         glfwSetKeyCallback(window, KeyCallback);
         glfwSetKeyCallback(window, KeyCallback);
 
 
         InitGraphicsDevice();
         InitGraphicsDevice();
+        
+        LoadDefaultFont();
     }
     }
 }
 }
 
 
@@ -275,15 +271,18 @@ void EndDrawing()
 // Initializes 3D mode for drawing (Camera setup)
 // Initializes 3D mode for drawing (Camera setup)
 void Begin3dMode(Camera camera)
 void Begin3dMode(Camera camera)
 {
 {
-    //glEnable(GL_LIGHTING);            // TODO: Setup proper lighting system (raylib 1.x)
-    
     glMatrixMode(GL_PROJECTION);        // Switch to projection matrix
     glMatrixMode(GL_PROJECTION);        // Switch to projection matrix
     
     
     glPushMatrix();                     // Save previous matrix, which contains the settings for the 2d ortho projection
     glPushMatrix();                     // Save previous matrix, which contains the settings for the 2d ortho projection
     glLoadIdentity();                   // Reset current matrix (PROJECTION)
     glLoadIdentity();                   // Reset current matrix (PROJECTION)
     
     
-    SetPerspective(45.0f, (GLfloat)windowWidth/(GLfloat)windowHeight, 0.1f, 100.0f);    // Setup perspective projection
+    // Setup perspective projection
+    float aspect = (GLfloat)windowWidth/(GLfloat)windowHeight;
+    double top = 0.1f*tan(45.0f*PI / 360.0);
+    double right = top*aspect;
 
 
+    glFrustum(-right, right, -top, top, 0.1f, 100.0f);
+    
     glMatrixMode(GL_MODELVIEW);         // Switch back to modelview matrix
     glMatrixMode(GL_MODELVIEW);         // Switch back to modelview matrix
     glLoadIdentity();                   // Reset current matrix (MODELVIEW)
     glLoadIdentity();                   // Reset current matrix (MODELVIEW)
     
     
@@ -300,8 +299,6 @@ void End3dMode()
     glLoadIdentity();                   // Reset current matrix (MODELVIEW)
     glLoadIdentity();                   // Reset current matrix (MODELVIEW)
     
     
     glTranslatef(0.375, 0.375, 0);      // HACK to ensure pixel-perfect drawing on OpenGL (after exiting 3D mode)
     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
 // Set target FPS for the game
@@ -570,7 +567,7 @@ bool IsGamepadButtonDown(int gamepad, int button)
     
     
     buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
     buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
     
     
-    if (buttons[button] == GLFW_PRESS)
+    if ((buttons != NULL) && (buttons[button] == GLFW_PRESS))
     {
     {
         return true;
         return true;
     }
     }
@@ -601,7 +598,7 @@ bool IsGamepadButtonUp(int gamepad, int button)
     
     
     buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
     buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
     
     
-    if (buttons[button] == GLFW_RELEASE)
+    if ((buttons != NULL) && (buttons[button] == GLFW_RELEASE))
     {
     {
         return true;
         return true;
     }
     }
@@ -685,19 +682,6 @@ static void InitGraphicsDevice()
     glMatrixMode(GL_MODELVIEW);                 // Switch back to MODELVIEW matrix
     glMatrixMode(GL_MODELVIEW);                 // Switch back to MODELVIEW matrix
     glLoadIdentity();                           // Reset current matrix (MODELVIEW)
     glLoadIdentity();                           // Reset current matrix (MODELVIEW)
     
     
-    // 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
     // TODO: Review all shapes/models are drawn CCW and enable backface culling
 
 
     //glEnable(GL_CULL_FACE);       // Enable backface culling (Disabled by default)
     //glEnable(GL_CULL_FACE);       // Enable backface culling (Disabled by default)
@@ -746,19 +730,6 @@ static void CameraLookAt(Vector3 position, Vector3 target, Vector3 up)
     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)
-static void SetPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
-{
-   double xmin, xmax, ymin, ymax;
-
-   ymax = zNear * tan(fovy * PI / 360.0);
-   ymin = -ymax;
-   xmin = ymin * aspect;
-   xmax = ymax * aspect;
-
-   glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
-}
-
 // Takes a bitmap (BMP) screenshot and saves it in the same folder as executable
 // Takes a bitmap (BMP) screenshot and saves it in the same folder as executable
 static void TakeScreenshot()
 static void TakeScreenshot()
 {
 {

+ 158 - 31
src/models.c

@@ -39,7 +39,14 @@
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Types and Structures Definition
 // Types and Structures Definition
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
-// ...
+
+// Matrix type (OpenGL style 4x4 - right handed)
+typedef struct Matrix {
+    float m0, m4, m8, m12;
+    float m1, m5, m9, m13;
+    float m2, m6, m10, m14;
+    float m3, m7, m11, m15;
+} Matrix;
 
 
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Global Variables Definition
 // Global Variables Definition
@@ -50,13 +57,15 @@
 // Module specific Functions Declaration
 // Module specific Functions Declaration
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 static float GetHeightValue(Color pixel);
 static float GetHeightValue(Color pixel);
+static void MatrixTranspose(Matrix *mat);
+static Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up);
 
 
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Module Functions Definition
 // Module Functions Definition
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 
 
 // Draw cube
 // Draw cube
-// NOTE: Cube position is de center position
+// NOTE: Cube position is the center position
 void DrawCube(Vector3 position, float width, float height, float lenght, Color color)
 void DrawCube(Vector3 position, float width, float height, float lenght, Color color)
 {
 {
     glPushMatrix();
     glPushMatrix();
@@ -664,7 +673,7 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
     Model model;
     Model model;
     
     
     int mapX = heightmap.width;
     int mapX = heightmap.width;
-	int mapZ = heightmap.height;
+    int mapZ = heightmap.height;
     
     
     // NOTE: One vertex per pixel
     // NOTE: One vertex per pixel
     // TODO: Consider resolution when generating model data?
     // TODO: Consider resolution when generating model data?
@@ -681,11 +690,11 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
     
     
     float scaleFactor = maxHeight/255;    // TODO: Review scaleFactor calculation
     float scaleFactor = maxHeight/255;    // TODO: Review scaleFactor calculation
 
 
-	for(int z = 0; z < mapZ-1; z++)
-	{
-		for(int x = 0; x < mapX-1; x++)
-		{
-			// Fill vertices array with data
+    for(int z = 0; z < mapZ-1; z++)
+    {
+        for(int x = 0; x < mapX-1; x++)
+        {
+            // Fill vertices array with data
             //----------------------------------------------------------
             //----------------------------------------------------------
             
             
             // one triangle - 3 vertex
             // one triangle - 3 vertex
@@ -738,8 +747,8 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
             
             
             vCounter += 6;
             vCounter += 6;
             trisCounter += 2;
             trisCounter += 2;
-		}
-	}
+        }
+    }
 
 
     return model;
     return model;
 }
 }
@@ -805,47 +814,165 @@ void DrawModelWires(Model model, Vector3 position, float scale, Color color)
 }
 }
 
 
 // Draw a billboard
 // Draw a billboard
-void DrawBillboard(Camera camera, Texture2D texture, Vector3 basePos, float size, Color tint)
+void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, 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 };
+    // NOTE: Billboard size will maintain texture aspect ratio, size will be billboard width
     Vector2 sizeRatio = { size, size * (float)texture.height/texture.width };
     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
-
+    Matrix viewMatrix = MatrixLookAt(camera.position, camera.target, camera.up);
+    MatrixTranspose(&viewMatrix);
+    
+    Vector3 right = { viewMatrix.m0, viewMatrix.m4, viewMatrix.m8 };
+    Vector3 up = { viewMatrix.m1, viewMatrix.m5, viewMatrix.m9 };
+/*    
+    d-------c
+    |       |
+    |   *   |
+    |       |
+    a-------b
+*/  
+    VectorScale(&right, sizeRatio.x/2);
+    VectorScale(&up, sizeRatio.y/2);
+    
+    Vector3 p1 = VectorAdd(right, up);
+    Vector3 p2 = VectorSubtract(right, up);
+
+    Vector3 a = VectorSubtract(center, p2);
+    Vector3 b = VectorAdd(center, p1);
+    Vector3 c = VectorAdd(center, p2);
+    Vector3 d = VectorSubtract(center, p1);
+    
     glEnable(GL_TEXTURE_2D);
     glEnable(GL_TEXTURE_2D);
     
     
     glBindTexture(GL_TEXTURE_2D, texture.glId);
     glBindTexture(GL_TEXTURE_2D, texture.glId);
-    
-    DrawPlane(centerPos, sizeRatio, rotation, tint);    // TODO: Review this function...
+      
+    glBegin(GL_QUADS);
+        glColor4ub(tint.r, tint.g, tint.b, tint.a);
+        glNormal3f(0.0f, 1.0f, 0.0f); 
+        glTexCoord2f(0.0f, 0.0f); glVertex3f(a.x, a.y, a.z);
+        glTexCoord2f(1.0f, 0.0f); glVertex3f(b.x, b.y, b.z);
+        glTexCoord2f(1.0f, 1.0f); glVertex3f(c.x, c.y, c.z);
+        glTexCoord2f(0.0f, 1.0f); glVertex3f(d.x, d.y, d.z);
+    glEnd();
     
     
     glDisable(GL_TEXTURE_2D);
     glDisable(GL_TEXTURE_2D);
 }
 }
 
 
 // Draw a billboard (part of a texture defined by a rectangle)
 // 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)
+void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, 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);
+    // NOTE: Billboard size will maintain sourceRec aspect ratio, size will represent billboard width
+    Vector2 sizeRatio = { size, size * (float)sourceRec.height/sourceRec.width };
+
+    Matrix viewMatrix = MatrixLookAt(camera.position, camera.target, camera.up);
+    MatrixTranspose(&viewMatrix);
+    
+    Vector3 right = { viewMatrix.m0, viewMatrix.m4, viewMatrix.m8 };
+    Vector3 up = { viewMatrix.m1, viewMatrix.m5, viewMatrix.m9 };
+/*    
+    d-------c
+    |       |
+    |   *   |
+    |       |
+    a-------b
+*/  
+    VectorScale(&right, sizeRatio.x/2);
+    VectorScale(&up, sizeRatio.y/2);
+
+    Vector3 p1 = VectorAdd(right, up);
+    Vector3 p2 = VectorSubtract(right, up);
+
+    Vector3 a = VectorSubtract(center, p2);
+    Vector3 b = VectorAdd(center, p1);
+    Vector3 c = VectorAdd(center, p2);
+    Vector3 d = VectorSubtract(center, p1);
+    
+    glEnable(GL_TEXTURE_2D);    // Enable textures usage
     
     
     glBindTexture(GL_TEXTURE_2D, texture.glId);
     glBindTexture(GL_TEXTURE_2D, texture.glId);
     
     
-    // TODO: DrawPlane with correct textcoords for source rec.
+    glBegin(GL_QUADS);
+        glColor4ub(tint.r, tint.g, tint.b, tint.a);
+        
+        // Bottom-left corner for texture and quad
+        glTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height); 
+        glVertex3f(a.x, a.y, a.z);
+        
+        // Bottom-right corner for texture and quad
+        glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
+        glVertex3f(b.x, b.y, b.z);
+        
+        // Top-right corner for texture and quad
+        glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height); 
+        glVertex3f(c.x, c.y, c.z);
+        
+        // Top-left corner for texture and quad
+        glTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
+        glVertex3f(d.x, d.y, d.z);
+    glEnd();
     
     
-    glDisable(GL_TEXTURE_2D);
+    glDisable(GL_TEXTURE_2D);    // Disable textures usage
 }
 }
 
 
 // Get current vertex y altitude (proportional to pixel colors in grayscale)
 // Get current vertex y altitude (proportional to pixel colors in grayscale)
 static float GetHeightValue(Color pixel)
 static float GetHeightValue(Color pixel)
 {
 {
     return (((float)pixel.r + (float)pixel.g + (float)pixel.b)/3);
     return (((float)pixel.r + (float)pixel.g + (float)pixel.b)/3);
+}
+
+// Returns camera look-at matrix (view matrix)
+static Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up)
+{
+    Matrix result;
+    
+    Vector3 z = VectorSubtract(eye, target);
+    VectorNormalize(&z);
+    Vector3 x = VectorCrossProduct(up, z);
+    VectorNormalize(&x);
+    Vector3 y = VectorCrossProduct(z, x);
+    VectorNormalize(&y);
+    
+    result.m0 = x.x;
+    result.m1 = x.y;
+    result.m2 = x.z;
+    result.m3 = -((x.x * eye.x) + (x.y * eye.y) + (x.z * eye.z));
+    result.m4 = y.x;
+    result.m5 = y.y;
+    result.m6 = y.z;
+    result.m7 = -((y.x * eye.x) + (y.y * eye.y) + (y.z * eye.z));
+    result.m8 = z.x;
+    result.m9 = z.y;
+    result.m10 = z.z;
+    result.m11 = -((z.x * eye.x) + (z.y * eye.y) + (z.z * eye.z));
+    result.m12 = 0;
+    result.m13 = 0;
+    result.m14 = 0;
+    result.m15 = 1;
+    
+    return result;
+}
+
+// Transposes provided matrix
+static void MatrixTranspose(Matrix *mat)
+{
+    Matrix temp;
+
+    temp.m0 = mat->m0;
+    temp.m1 = mat->m4;
+    temp.m2 = mat->m8;
+    temp.m3 = mat->m12;
+    temp.m4 = mat->m1;
+    temp.m5 = mat->m5;
+    temp.m6 = mat->m9;
+    temp.m7 = mat->m13;
+    temp.m8 = mat->m2;
+    temp.m9 = mat->m6;
+    temp.m10 = mat->m10;
+    temp.m11 = mat->m14;
+    temp.m12 = mat->m3;
+    temp.m13 = mat->m7;
+    temp.m14 = mat->m11;
+    temp.m15 = mat->m15;
+    
+    *mat = temp;
 }
 }

+ 5 - 6
src/raylib.h

@@ -1,6 +1,6 @@
 /*********************************************************************************************
 /*********************************************************************************************
 * 
 * 
-*   raylib 1.0.4 (www.raylib.com)
+*   raylib 1.0.6 (www.raylib.com)
 *    
 *    
 *   A simple and easy-to-use library to learn videogames programming
 *   A simple and easy-to-use library to learn videogames programming
 *
 *
@@ -325,11 +325,12 @@ Image LoadImage(const char *fileName);
 Image LoadImageFromRES(const char *rresName, int resId);                                           // Load an image from rRES file (raylib Resource)
 Image LoadImageFromRES(const char *rresName, int resId);                                           // Load an image from rRES file (raylib Resource)
 Texture2D LoadTexture(const char *fileName);                                                       // Load an image as texture into GPU memory
 Texture2D LoadTexture(const char *fileName);                                                       // Load an image as texture into GPU memory
 Texture2D LoadTextureFromRES(const char *rresName, int resId);                                     // Load an image as texture from rRES file (raylib Resource)
 Texture2D LoadTextureFromRES(const char *rresName, int resId);                                     // Load an image as texture from rRES file (raylib Resource)
-Texture2D CreateTexture(Image image);                                                            // Create a Texture2D from Image data
+Texture2D CreateTexture(Image image);                                                              // Create a Texture2D from Image data
 void UnloadImage(Image image);                                                                     // Unload image from CPU memory (RAM)
 void UnloadImage(Image image);                                                                     // Unload image from CPU memory (RAM)
 void UnloadTexture(Texture2D texture);                                                             // Unload texture from GPU memory
 void UnloadTexture(Texture2D texture);                                                             // Unload texture from GPU memory
 
 
 void DrawTexture(Texture2D texture, int posX, int posY, Color tint);                               // Draw a Texture2D
 void DrawTexture(Texture2D texture, int posX, int posY, Color tint);                               // Draw a Texture2D
+void DrawTextureV(Texture2D texture, Vector2 position, Color tint);                                // Draw a Texture2D with position defined as Vector2
 void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint);  // Draw a Texture2D with extended parameters
 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, Color tint);         // Draw a part of a texture defined by a rectangle
 void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint);         // Draw a part of a texture defined by a rectangle
 void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin,     // Draw a part of a texture defined by a rectangle with 'pro' parameters
 void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin,     // Draw a part of a texture defined by a rectangle with 'pro' parameters
@@ -377,10 +378,8 @@ void UnloadModel(Model model);
 void DrawModel(Model model, Vector3 position, float scale, Color color);                           // Draw a model
 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 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
 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
-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 DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint);                         // Draw a billboard texture
+void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec 
 
 
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
 // Audio Loading and Playing Functions (Module: audio)
 // Audio Loading and Playing Functions (Module: audio)

+ 12 - 4
src/shapes.c

@@ -61,8 +61,16 @@ void DrawPixel(int posX, int posY, Color color)
         glColor4ub(color.r, color.g, color.b, color.a);
         glColor4ub(color.r, color.g, color.b, color.a);
         glVertex2i(posX, posY);
         glVertex2i(posX, posY);
     glEnd();
     glEnd();
-    
-    // NOTE: Alternative method to draw a pixel (point)
+
+    // NOTE1: Alternative method to draw a pixel (GL_LINES)
+/*
+    glBegin(GL_LINES);
+        glColor4ub(color.r, color.g, color.b, color.a);
+        glVertex2i(posX, posY);
+        glVertex2i(posX+1, posY+1);
+    glEnd();
+*/    
+    // NOTE2: Alternative method to draw a pixel (glPoint())
 /*
 /*
     glEnable(GL_POINT_SMOOTH);
     glEnable(GL_POINT_SMOOTH);
     glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);    // Deprecated on OGL 3.0
     glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);    // Deprecated on OGL 3.0
@@ -426,7 +434,7 @@ Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2)
         if (rec1.x <= rec2.x)
         if (rec1.x <= rec2.x)
         {
         {
             if (rec1.y <= rec2.y)
             if (rec1.y <= rec2.y)
-            {	
+            {    
                 retRec.x = rec2.x;
                 retRec.x = rec2.x;
                 retRec.y = rec2.y;
                 retRec.y = rec2.y;
                 retRec.width = rec1.width - dxx;
                 retRec.width = rec1.width - dxx;
@@ -443,7 +451,7 @@ Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2)
         else
         else
         {
         {
             if (rec1.y <= rec2.y)
             if (rec1.y <= rec2.y)
-            {	
+            {    
                 retRec.x = rec1.x;
                 retRec.x = rec1.x;
                 retRec.y = rec2.y;
                 retRec.y = rec2.y;
                 retRec.width = rec2.width - dxx;
                 retRec.width = rec2.width - dxx;

+ 26 - 33
src/text.c

@@ -8,7 +8,7 @@
 *       stb_image - Multiple formats image loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
 *       stb_image - Multiple formats image loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
 *
 *
 *   Copyright (c) 2013 Ramon Santamaria (Ray San - [email protected])
 *   Copyright (c) 2013 Ramon Santamaria (Ray San - [email protected])
-*    
+*
 *   This software is provided "as-is", without any express or implied warranty. In no event 
 *   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.
 *   will the authors be held liable for any damages arising from the use of this software.
 *
 *
@@ -37,8 +37,9 @@
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Defines and Macros
 // Defines and Macros
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
-#define FIRST_CHAR         32
-#define MAX_FONTCHARS  128
+#define FONT_FIRST_CHAR         32
+#define MAX_FONTCHARS          128
+#define MAX_FORMATTEXT_LENGTH   50
 
 
 #define BIT_CHECK(a,b) ((a) & (1<<(b)))
 #define BIT_CHECK(a,b) ((a) & (1<<(b)))
 
 
@@ -125,7 +126,7 @@ extern void LoadDefaultFont()
     
     
     for (int i = 0; i < defaultFont.numChars; i++)
     for (int i = 0; i < defaultFont.numChars; i++)
     {
     {
-        defaultFont.charSet[i].value = FIRST_CHAR + i;
+        defaultFont.charSet[i].value = FONT_FIRST_CHAR + i;  // First char is 32
         defaultFont.charSet[i].x = currentPosX;
         defaultFont.charSet[i].x = currentPosX;
         defaultFont.charSet[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor);
         defaultFont.charSet[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor);
         defaultFont.charSet[i].w = charsWidth[i];
         defaultFont.charSet[i].w = charsWidth[i];
@@ -329,31 +330,26 @@ void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int f
     if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
     if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
     else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
     else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
 
 
-    glDisable(GL_LIGHTING);        // When drawing text, disable LIGHTING
     glEnable(GL_TEXTURE_2D);
     glEnable(GL_TEXTURE_2D);
 
 
     glBindTexture(GL_TEXTURE_2D, spriteFont.texture.glId);
     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) * scaleFactor + spacing);
-            }
-        glEnd();
-        
-    glPopMatrix();
+    // Optimized to use one draw call per string
+    glBegin(GL_QUADS);
+        for(int i = 0; i < length; i++)
+        {
+            c = spriteFont.charSet[(int)text[i] - FONT_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] - FONT_FIRST_CHAR].w) * scaleFactor + spacing);
+        }
+    glEnd();
         
         
     glDisable(GL_TEXTURE_2D);
     glDisable(GL_TEXTURE_2D);
 }
 }
@@ -361,16 +357,13 @@ void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int f
 // Formatting of text with variables to 'embed'
 // Formatting of text with variables to 'embed'
 const char *FormatText(const char *text, ...)
 const char *FormatText(const char *text, ...)
 {
 {
-    int length = strlen(text);
-    char *buffer = malloc(length + 20);  // We add 20 extra characters, should be enough... :P
-
+    static char buffer[MAX_FORMATTEXT_LENGTH];
+    
     va_list args;
     va_list args;
     va_start(args, text);
     va_start(args, text);
     vsprintf(buffer, text, args);        // NOTE: We use vsprintf() defined in <stdarg.h>
     vsprintf(buffer, text, args);        // NOTE: We use vsprintf() defined in <stdarg.h>
     va_end(args);
     va_end(args);
-    
-    //strcat(buffer, "\0");              // We add a end-of-string mark at the end (not needed)
-    
+
     return buffer;
     return buffer;
 }
 }
 
 
@@ -393,7 +386,7 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int
     
     
     for (int i = 0; i < len; i++)
     for (int i = 0; i < len; i++)
     {
     {
-        textWidth += spriteFont.charSet[(int)text[i] - FIRST_CHAR].w;
+        textWidth += spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR].w;
     }
     }
     
     
     if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
     if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
@@ -491,7 +484,7 @@ static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Char
         while((xPosToRead < imgWidth) &&
         while((xPosToRead < imgWidth) &&
               !PixelIsMagenta((imgDataPixel[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*imgWidth + xPosToRead])))
               !PixelIsMagenta((imgDataPixel[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*imgWidth + xPosToRead])))
         {
         {
-            tempCharSet[index].value = FIRST_CHAR + index;
+            tempCharSet[index].value = FONT_FIRST_CHAR + index;
             tempCharSet[index].x = xPosToRead;
             tempCharSet[index].x = xPosToRead;
             tempCharSet[index].y = lineSpacing + lineToRead * (charHeight + lineSpacing);
             tempCharSet[index].y = lineSpacing + lineToRead * (charHeight + lineSpacing);
             tempCharSet[index].h = charHeight;
             tempCharSet[index].h = charHeight;

+ 19 - 49
src/textures.c

@@ -218,37 +218,11 @@ Image LoadImageFromRES(const char *rresName, int resId)
 Texture2D LoadTexture(const char *fileName)
 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, ...)
-    // 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
+    Image image;
     
     
-    texture.glId = id;
-    texture.width = imgWidth;
-    texture.height = imgHeight;
+    image = LoadImage(fileName);
+    texture = CreateTexture(image);
+    UnloadImage(image);
     
     
     return texture;
     return texture;
 }
 }
@@ -264,23 +238,6 @@ Texture2D LoadTextureFromRES(const char *rresName, int resId)
     return texture;
     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;
-}
-
 // Create a Texture2D from Image data
 // Create a Texture2D from Image data
 // NOTE: Image is not unloaded, it should be done manually...
 // NOTE: Image is not unloaded, it should be done manually...
 Texture2D CreateTexture(Image image)
 Texture2D CreateTexture(Image image)
@@ -294,11 +251,18 @@ Texture2D CreateTexture(Image image)
     
     
     glBindTexture(GL_TEXTURE_2D, id);
     glBindTexture(GL_TEXTURE_2D, id);
     
     
+    // NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used!
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);       // Set texture to repead on x-axis
     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_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
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);  // Filter for pixel-perfect drawing, alternative: GL_LINEAR 
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);  // Filter for pixel-perfect drawing, alternative: GL_LINEAR
     
     
+    // Trilinear filtering
+    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);   // Activate use of mipmaps (must be available)
+    //glGenerateMipmap(GL_TEXTURE_2D);    // OpenGL 3.3!
+    
+    // Upload texture to GPU
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.pixels);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.pixels);
     
     
     // NOTE: Not using mipmappings (texture for 2D drawing)
     // NOTE: Not using mipmappings (texture for 2D drawing)
@@ -329,6 +293,12 @@ 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 position defined as Vector2
+void DrawTextureV(Texture2D texture, Vector2 position, Color tint)
+{
+    DrawTextureEx(texture, position, 0, 1.0f, tint);
+}
+
 // Draw a Texture2D with extended parameters
 // Draw a Texture2D with extended parameters
 void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint)
 void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint)
 {
 {

+ 1 - 1
src/vector3.c

@@ -25,7 +25,7 @@
 
 
 #include "vector3.h"
 #include "vector3.h"
 
 
-#include <math.h>
+#include <math.h>       // Used for fabs(), sqrt()
 
 
 // Add two vectors
 // Add two vectors
 Vector3 VectorAdd(Vector3 v1, Vector3 v2)
 Vector3 VectorAdd(Vector3 v1, Vector3 v2)

BIN
tests/heightmap.png


+ 77 - 0
tests/test_billboard.c

@@ -0,0 +1,77 @@
+/*******************************************************************************************
+*
+*   raylib test - Testing DrawBillboard() and DrawBillboardRec()
+*
+*   This example has been created using raylib 1.0 (www.raylib.com)
+*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+*   Copyright (c) 2013 Ramon Santamaria (Ray San - [email protected])
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+int main()
+{
+    // Initialization
+    //--------------------------------------------------------------------------------------
+    int screenWidth = 800;
+    int screenHeight = 450;
+
+    Vector3 position = { 0.0, 0.0, 0.0 };
+    
+    // Define the camera to look into our 3d world
+    Camera camera = {{ 10.0, 8.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }};
+    
+    InitWindow(screenWidth, screenHeight, "raylib test - Billboards");
+    
+    SetTargetFPS(60);   // Set our game to run at 60 frames-per-second
+    
+    Texture2D texture = LoadTexture("resources/raylib_logo.png");
+    Texture2D lena = LoadTexture("resources/lena.png");
+    
+    Rectangle eyesRec = { 225, 240, 155, 50 };
+    //--------------------------------------------------------------------------------------
+    
+    // Main game loop
+    while (!WindowShouldClose())    // Detect window close button or ESC key
+    {
+        // Update
+        //----------------------------------------------------------------------------------
+        if (IsKeyDown(KEY_LEFT)) camera.position.x -= 0.2;
+        if (IsKeyDown(KEY_RIGHT)) camera.position.x += 0.2;
+        if (IsKeyDown(KEY_UP)) camera.position.y -= 0.2;
+        if (IsKeyDown(KEY_DOWN)) camera.position.y += 0.2;
+        //----------------------------------------------------------------------------------
+        
+        // Draw
+        //----------------------------------------------------------------------------------
+        BeginDrawing();
+        
+            ClearBackground(RAYWHITE);
+            
+            Begin3dMode(camera);
+            
+                //DrawBillboard(camera, texture, position, 2.0, WHITE);
+                DrawBillboardRec(camera, lena, eyesRec, position, 4.0, WHITE);
+            
+                DrawGrid(10.0, 1.0);        // Draw a grid
+                
+            End3dMode();
+            
+            DrawFPS(10, 10);
+        
+        EndDrawing();
+        //----------------------------------------------------------------------------------
+    }
+
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+    UnloadTexture(texture);     // Unload texture
+    UnloadTexture(lena);        // Unload texture
+    
+    CloseWindow();              // Close window and OpenGL context
+    //--------------------------------------------------------------------------------------
+    
+    return 0;
+}

+ 62 - 0
tests/test_formattext.c

@@ -0,0 +1,62 @@
+/*******************************************************************************************
+*
+*   raylib test - Testing FormatText() function
+*
+*   This example has been created using raylib 1.0 (www.raylib.com)
+*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+*   Copyright (c) 2013 Ramon Santamaria (Ray San - [email protected])
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+int main()
+{
+    // Initialization
+    //--------------------------------------------------------------------------------------
+    int screenWidth = 800;
+    int screenHeight = 450;
+    
+    int score = 100020;
+    int hiscore = 200450;
+    int lives = 5;
+    
+    InitWindow(screenWidth, screenHeight, "raylib test - FormatText()");
+    
+    SetTargetFPS(60);
+    //--------------------------------------------------------------------------------------
+    
+    // Main game loop
+    while (!WindowShouldClose())    // Detect window close button or ESC key
+    {
+        // Update
+        //----------------------------------------------------------------------------------
+        // TODO: Update your variables here
+        //----------------------------------------------------------------------------------
+        
+        // Draw
+        //----------------------------------------------------------------------------------
+        BeginDrawing();
+        
+            ClearBackground(RAYWHITE);
+            
+            DrawText(FormatText("Score: %08i", score), 80, 80, 20, RED);
+        
+            DrawText(FormatText("HiScore: %08i", hiscore), 80, 120, 20, GREEN);
+            
+            DrawText(FormatText("Lives: %02i", lives), 80, 160, 40, BLUE);
+            
+            DrawText(FormatText("Elapsed Time: %02.02f ms", GetFrameTime()*1000), 80, 220, 20, BLACK);
+        
+        EndDrawing();
+        //----------------------------------------------------------------------------------
+    }
+
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+    CloseWindow();        // Close window and OpenGL context
+    //--------------------------------------------------------------------------------------
+    
+    return 0;
+}

+ 76 - 0
tests/test_heightmap.c

@@ -0,0 +1,76 @@
+/*******************************************************************************************
+*
+*   raylib test - Testing Heightmap Loading and Drawing
+*
+*   This example has been created using raylib 1.0 (www.raylib.com)
+*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+*   Copyright (c) 2013 Ramon Santamaria (Ray San - [email protected])
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+int main()
+{
+    // Initialization
+    //--------------------------------------------------------------------------------------
+    int screenWidth = 800;
+    int screenHeight = 450;
+
+    Vector3 position = { 0.0, 0.0, 0.0 };
+    
+    // Define the camera to look into our 3d world
+    Camera camera = {{ 12.0, 10.0, 12.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }};
+    
+    InitWindow(screenWidth, screenHeight, "raylib test - Heightmap loading and drawing");
+    
+    Image img = LoadImage("heightmap.png");
+    Model map = LoadHeightmap(img, 4);
+    Texture2D tex = CreateTexture(img);
+    UnloadImage(img);
+    
+    SetTargetFPS(60);   // Set our game to run at 60 frames-per-second
+    //--------------------------------------------------------------------------------------
+    
+    // Main game loop
+    while (!WindowShouldClose())    // Detect window close button or ESC key
+    {
+        // Update
+        //----------------------------------------------------------------------------------
+        // ...
+        //----------------------------------------------------------------------------------
+        
+        // Draw
+        //----------------------------------------------------------------------------------
+        BeginDrawing();
+        
+            ClearBackground(RAYWHITE);
+            
+            Begin3dMode(camera);
+            
+                //DrawModel(map, position, 0.5f, MAROON);   
+                DrawModelEx(map, tex, position, 0.5f, WHITE);   // Draw 3d model with texture
+                
+                DrawGrid(10.0, 1.0);        // Draw a grid
+                
+                DrawGizmo(position, false); 
+                
+            End3dMode();
+            
+            DrawFPS(10, 10);
+        
+        EndDrawing();
+        //----------------------------------------------------------------------------------
+    }
+
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+    UnloadTexture(tex);     // Unload texture
+    UnloadModel(map);       // Unload model
+    
+    CloseWindow();          // Close window and OpenGL context
+    //--------------------------------------------------------------------------------------
+    
+    return 0;
+}

+ 60 - 0
tests/test_image_loading.c

@@ -0,0 +1,60 @@
+/*******************************************************************************************
+*
+*   raylib test - Testing LoadImage() and CreateTexture()
+*
+*   This example has been created using raylib 1.0 (www.raylib.com)
+*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+*   Copyright (c) 2013 Ramon Santamaria (Ray San - [email protected])
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+int main()
+{    
+    // Initialization
+    //--------------------------------------------------------------------------------------
+    int screenWidth = 800;
+    int screenHeight = 450;
+
+    InitWindow(screenWidth, screenHeight, "raylib test - Image loading");
+    
+    // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
+
+    Image img = LoadImage("resources/raylib_logo.png");
+    Texture2D texture = CreateTexture(img);
+    UnloadImage(img);
+    //---------------------------------------------------------------------------------------
+    
+    // Main game loop
+    while (!WindowShouldClose())    // Detect window close button or ESC key
+    {
+        // Update
+        //----------------------------------------------------------------------------------
+        // TODO: Update your variables here
+        //----------------------------------------------------------------------------------
+        
+        // Draw
+        //----------------------------------------------------------------------------------
+        BeginDrawing();
+        
+            ClearBackground(RAYWHITE);
+            
+            DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, WHITE);
+            
+            DrawText("this IS a texture!", 360, 370, 10, GRAY);
+        
+        EndDrawing();
+        //----------------------------------------------------------------------------------
+    }
+
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+    UnloadTexture(texture);       // Texture unloading
+    
+    CloseWindow();                // Close window and OpenGL context
+    //--------------------------------------------------------------------------------------
+    
+    return 0;
+}

+ 57 - 0
tests/test_mouse_wheel.c

@@ -0,0 +1,57 @@
+/*******************************************************************************************
+*
+*   raylib test - Testing GetMouseWheelMove()
+*
+*   This example has been created using raylib 1.0 (www.raylib.com)
+*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+*   Copyright (c) 2013 Ramon Santamaria (Ray San - [email protected])
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+int main()
+{
+    // Initialization
+    //--------------------------------------------------------------------------------------
+    int screenWidth = 800;
+    int screenHeight = 450;
+    
+    InitWindow(screenWidth, screenHeight, "raylib test - Mouse wheel");
+    
+    int positionY = 0;
+    int scrollSpeed = 4;    // Scrolling speed in pixels
+    
+    SetTargetFPS(60);
+    //--------------------------------------------------------------------------------------
+    
+    // Main game loop
+    while (!WindowShouldClose())    // Detect window close button or ESC key
+    {
+        // Update
+        //----------------------------------------------------------------------------------
+        positionY -= (GetMouseWheelMove()*scrollSpeed);
+        //----------------------------------------------------------------------------------
+        
+        // Draw
+        //----------------------------------------------------------------------------------
+        BeginDrawing();
+        
+            ClearBackground(RAYWHITE);
+            
+            DrawRectangle(200, positionY, 80, 80, MAROON);
+            
+            DrawText(FormatText("%i", positionY), 10, 10, 20, GRAY);
+        
+        EndDrawing();
+        //----------------------------------------------------------------------------------
+    }
+
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+    CloseWindow();        // Close window and OpenGL context
+    //--------------------------------------------------------------------------------------
+    
+    return 0;
+}

+ 62 - 0
tests/test_random.c

@@ -0,0 +1,62 @@
+/*******************************************************************************************
+*
+*   raylib test - Testing GetRandomValue()
+*
+*   This example has been created using raylib 1.0 (www.raylib.com)
+*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+*   Copyright (c) 2013 Ramon Santamaria (Ray San - [email protected])
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+int main()
+{
+    // Initialization
+    //--------------------------------------------------------------------------------------
+    int screenWidth = 800;
+    int screenHeight = 450;
+    
+    int framesCounter = 0;
+    
+    InitWindow(screenWidth, screenHeight, "raylib test - Random numbers");
+    
+    int randValue = GetRandomValue(-8,5);
+    
+    SetTargetFPS(60);
+    //--------------------------------------------------------------------------------------
+    
+    // Main game loop
+    while (!WindowShouldClose())    // Detect window close button or ESC key
+    {
+        // Update
+        //----------------------------------------------------------------------------------
+        framesCounter++;
+        
+        if ((framesCounter/60)%2)
+        {   
+            randValue = GetRandomValue(-8,5);
+            framesCounter = 0;
+        }
+        //----------------------------------------------------------------------------------
+        
+        // Draw
+        //----------------------------------------------------------------------------------
+        BeginDrawing();
+        
+            ClearBackground(RAYWHITE);
+            
+            DrawText(FormatText("%i", randValue), 120, 120, 60, LIGHTGRAY);
+        
+        EndDrawing();
+        //----------------------------------------------------------------------------------
+    }
+
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+    CloseWindow();        // Close window and OpenGL context
+    //--------------------------------------------------------------------------------------
+    
+    return 0;
+}