6 Commits
1.0.4 ... 1.0.6

Author SHA1 Message Date
raysan5
a68818e320 Update to version 1.0.6
Check CHANGELOG for the list of changes in this release!
2014-03-16 20:59:02 +01:00
raysan5
0a71a92eeb Text formatting 2014-03-16 20:27:58 +01:00
raysan5
4127638f92 Deleted for a better replace... soon... 2014-03-16 19:20:00 +01:00
raysan5
451568e5a9 The future of raylib!
Mapping of OpenGL 1.1 immediate mode functions to OpenGL 3.2+ (and
OpenGL ES 2.0) programmable pipeline
2014-03-02 16:06:01 +01:00
raysan5
174cd86d08 3D useful maths
Some useful functions to work with Vector3, Matrix and Quaternions
2014-03-02 16:03:25 +01:00
raysan5
43b13d623b Update to version 1.0.5
Check CHANGELOG for changes
2014-01-28 21:21:29 +01:00
26 changed files with 2502 additions and 296 deletions

View File

@@ -1,11 +1,35 @@
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: 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)
-----------------------------------------------
[audio] LoadSound() - Corrected a bug, WAV file was not closed!
[core] GetMouseWheelMove() - Added, check mouse wheel Y movement
[texture] CreateTexture2D() renamed to CreateTexture()
[models] LoadHeightmap() - Added, Heightmap can be loaded as a Model
[tool] rREM updated, now supports (partially) drag and drop of files
-----------------------------------------------
Release: raylib 1.0.4 (23 January 2014)
-----------------------------------------------

View File

@@ -11,12 +11,6 @@
#include "raylib.h"
// Useful function for fade-ins and fade-outs
Color Fade(Color col, float alpha)
{
return (Color){col.r, col.g, col.b, col.a*alpha};
}
int main()
{
// Initialization

View File

@@ -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
*
@@ -65,6 +65,7 @@
#define KEY_SPACE 32
#define KEY_ESCAPE 256
#define KEY_ENTER 257
#define KEY_BACKSPACE 259
#define KEY_RIGHT 262
#define KEY_LEFT 263
#define KEY_DOWN 264
@@ -278,6 +279,7 @@ bool IsMouseButtonUp(int button); // Detect if a mouse but
int GetMouseX(); // Returns mouse position X
int GetMouseY(); // Returns mouse position Y
Vector2 GetMousePosition(); // Returns mouse position XY
int GetMouseWheelMove(); // Returns mouse wheel movement Y
bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
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)
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 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 UnloadTexture(Texture2D texture); // Unload texture from GPU memory
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 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
@@ -370,17 +373,13 @@ void DrawGizmo(Vector3 position, bool orbits);
//------------------------------------------------------------------------------------
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 LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
void UnloadModel(Model model); // Unload 3d model from memory
void DrawModel(Model model, Vector3 position, float scale, Color color); // Draw a model
void DrawModelEx(Model model, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a textured model
void DrawModelWires(Model model, Vector3 position, float scale, Color color); // Draw a model wires
// NOTE: The following functions work but are incomplete or require some revision
// DrawHeightmap is extremely inefficient and can impact performance up to 60%
void DrawBillboard(Camera camera, Texture2D texture, Vector3 basePos, float size, Color tint); // REVIEW: Draw a billboard (raylib 1.x)
void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 basePos, float size, Color tint); // REVIEW: Draw a billboard (raylib 1.x)
void DrawHeightmap(Image heightmap, Vector3 centerPos, Vector3 scale, Color color); // REVIEW: Draw heightmap using image map (raylib 1.x)
void DrawHeightmapEx(Image heightmap, Texture2D texture, Vector3 centerPos, Vector3 scale, Color tint); // REVIEW: Draw textured heightmap (raylib 1.x)
void DrawBillboard(Camera camera, Texture2D texture, Vector3 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)

Binary file not shown.

View File

@@ -504,6 +504,8 @@ static Wave LoadWAV(char *fileName)
wave.channels = waveFormat.numChannels;
wave.bitsPerSample = waveFormat.bitsPerSample;
fclose(wavFile);
return wave;
}

View File

@@ -33,7 +33,7 @@
#include <stdio.h> // Standard input / output lib
#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 <math.h> // Math related functions, tan() used to set perspective
#include "vector3.h" // Basic Vector3 functions
#include "utils.h" // WritePNG() function
@@ -77,6 +77,9 @@ static char currentMouseState[3] = { 0 }; // Required to check if mouse btn pr
static char previousGamepadState[32] = {0}; // Required to check if gamepad btn pressed/released once
static char currentGamepadState[32] = {0}; // Required to check if gamepad btn pressed/released once
static int previousMouseWheelY = 0;
static int currentMouseWheelY = 0;
//----------------------------------------------------------------------------------
// Other Modules Functions Declaration (required by core)
//----------------------------------------------------------------------------------
@@ -89,10 +92,10 @@ extern void UnloadDefaultFont(); // [Module: text] Unloads default f
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 ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); // GLFW3 Srolling Callback, runs on mouse wheel
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)
static void TakeScreenshot(); // Takes a bitmap (BMP) screenshot and saves it in the same folder as executable
//----------------------------------------------------------------------------------
@@ -133,6 +136,7 @@ void InitWindowEx(int width, int height, const char* title, bool resizable, cons
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, KeyCallback);
glfwSetScrollCallback(window, ScrollCallback);
glfwSwapInterval(0); // Disables GPU v-sync (if set), so frames are not limited to screen refresh rate (60Hz -> 60 FPS)
// If not set, swap interval uses GPU v-sync configuration
// Framerate can be setup using SetTargetFPS()
@@ -142,14 +146,7 @@ void InitWindowEx(int width, int height, const char* title, bool resizable, cons
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
}
@@ -194,7 +191,11 @@ void ToggleFullscreen()
{
fullscreen = !fullscreen; // Toggle fullscreen flag
UnloadDefaultFont();
glfwDestroyWindow(window); // Destroy the current window (we will recreate it!)
// TODO: WARNING! All loaded resources are lost, we loose Context!
// NOTE: Window aspect ratio is always windowWidth / windowHeight
if (fullscreen) window = glfwCreateWindow(windowWidth, windowHeight, windowTitle, glfwGetPrimaryMonitor(), NULL); // Fullscreen mode
@@ -210,6 +211,8 @@ void ToggleFullscreen()
glfwSetKeyCallback(window, KeyCallback);
InitGraphicsDevice();
LoadDefaultFont();
}
}
@@ -268,15 +271,18 @@ void EndDrawing()
// Initializes 3D mode for drawing (Camera setup)
void Begin3dMode(Camera camera)
{
//glEnable(GL_LIGHTING); // TODO: Setup proper lighting system (raylib 1.x)
glMatrixMode(GL_PROJECTION); // Switch to projection matrix
glPushMatrix(); // Save previous matrix, which contains the settings for the 2d ortho projection
glLoadIdentity(); // Reset current matrix (PROJECTION)
SetPerspective(45.0f, (GLfloat)windowWidth/(GLfloat)windowHeight, 0.1f, 100.0f); // Setup perspective projection
// 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
glLoadIdentity(); // Reset current matrix (MODELVIEW)
@@ -293,8 +299,6 @@ void End3dMode()
glLoadIdentity(); // Reset current matrix (MODELVIEW)
glTranslatef(0.375, 0.375, 0); // HACK to ensure pixel-perfect drawing on OpenGL (after exiting 3D mode)
//glDisable(GL_LIGHTING); // TODO: Setup proper lighting system (raylib 1.x)
}
// Set target FPS for the game
@@ -498,6 +502,16 @@ Vector2 GetMousePosition()
return position;
}
// Returns mouse wheel movement Y
int GetMouseWheelMove()
{
previousMouseWheelY = currentMouseWheelY;
currentMouseWheelY = 0;
return previousMouseWheelY;
}
// Detect if a gamepad is available
bool IsGamepadAvailable(int gamepad)
{
@@ -553,7 +567,7 @@ bool IsGamepadButtonDown(int gamepad, int button)
buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
if (buttons[button] == GLFW_PRESS)
if ((buttons != NULL) && (buttons[button] == GLFW_PRESS))
{
return true;
}
@@ -584,7 +598,7 @@ bool IsGamepadButtonUp(int gamepad, int button)
buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
if (buttons[button] == GLFW_RELEASE)
if ((buttons != NULL) && (buttons[button] == GLFW_RELEASE))
{
return true;
}
@@ -602,6 +616,12 @@ static void ErrorCallback(int error, const char *description)
//fprintf(stderr, description);
}
// GLFW3 Srolling Callback, runs on mouse wheel
static void ScrollCallback(GLFWwindow* window, double xoffset, double yoffset)
{
currentMouseWheelY = (int)yoffset;
}
// GLFW3 Keyboard Callback, runs on key pressed
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
@@ -662,21 +682,6 @@ static void InitGraphicsDevice()
glMatrixMode(GL_MODELVIEW); // Switch back to MODELVIEW matrix
glLoadIdentity(); // Reset current matrix (MODELVIEW)
glDisable(GL_LIGHTING); // Lighting Disabled...
// TODO: Create an efficient Lighting System with proper functions (raylib 1.x)
/*
glEnable(GL_COLOR_MATERIAL); // Enable materials, causes some glMaterial atributes to track the current color (glColor)...
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // Material types and where to apply them
// NOTE: ONLY works with lighting; defines how light interacts with material
glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmbient); // Define ambient light color property
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDiffuse); // Define diffuse light color property
glLightfv(GL_LIGHT1, GL_POSITION, lightPosition); // Define light position
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1); // Enable light one (8 lights available at the same time)
*/
// TODO: Review all shapes/models are drawn CCW and enable backface culling
//glEnable(GL_CULL_FACE); // Enable backface culling (Disabled by default)
@@ -725,19 +730,6 @@ static void CameraLookAt(Vector3 position, Vector3 target, Vector3 up)
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
static void TakeScreenshot()
{

View File

@@ -39,7 +39,14 @@
//----------------------------------------------------------------------------------
// 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
@@ -49,14 +56,16 @@
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
// No private (static) functions in this module
static float GetHeightValue(Color pixel);
static void MatrixTranspose(Matrix *mat);
static Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up);
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
// 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)
{
glPushMatrix();
@@ -465,100 +474,100 @@ Model LoadModel(const char *fileName)
int numTexCoords = 0;
int numTriangles = 0;
FILE* objfile;
FILE* objFile;
objfile = fopen(fileName, "rt");
objFile = fopen(fileName, "rt");
while(!feof(objfile))
while(!feof(objFile))
{
fscanf(objfile, "%c", &dataType);
fscanf(objFile, "%c", &dataType);
switch(dataType)
{
case '#': // It's a comment
{
fgets(comments, 200, objfile);
fgets(comments, 200, objFile);
} break;
case 'v':
{
fscanf(objfile, "%c", &dataType);
fscanf(objFile, "%c", &dataType);
if (dataType == 't') // Read texCoord
{
fgets(comments, 200, objfile);
fscanf(objfile, "%c", &dataType);
fgets(comments, 200, objFile);
fscanf(objFile, "%c", &dataType);
while (dataType == 'v')
{
fgets(comments, 200, objfile);
fscanf(objfile, "%c", &dataType);
fgets(comments, 200, objFile);
fscanf(objFile, "%c", &dataType);
}
if (dataType == '#')
{
fscanf(objfile, "%i", &numTexCoords);
fscanf(objFile, "%i", &numTexCoords);
}
else printf("Ouch! Something was wrong...");
fgets(comments, 200, objfile);
fgets(comments, 200, objFile);
}
else if (dataType == 'n') // Read normals
{
fgets(comments, 200, objfile);
fscanf(objfile, "%c", &dataType);
fgets(comments, 200, objFile);
fscanf(objFile, "%c", &dataType);
while (dataType == 'v')
{
fgets(comments, 200, objfile);
fscanf(objfile, "%c", &dataType);
fgets(comments, 200, objFile);
fscanf(objFile, "%c", &dataType);
}
if (dataType == '#')
{
fscanf(objfile, "%i", &numNormals);
fscanf(objFile, "%i", &numNormals);
}
else printf("Ouch! Something was wrong...");
fgets(comments, 200, objfile);
fgets(comments, 200, objFile);
}
else // Read vertex
{
fgets(comments, 200, objfile);
fscanf(objfile, "%c", &dataType);
fgets(comments, 200, objFile);
fscanf(objFile, "%c", &dataType);
while (dataType == 'v')
{
fgets(comments, 200, objfile);
fscanf(objfile, "%c", &dataType);
fgets(comments, 200, objFile);
fscanf(objFile, "%c", &dataType);
}
if (dataType == '#')
{
fscanf(objfile, "%i", &numVertex);
fscanf(objFile, "%i", &numVertex);
}
else printf("Ouch! Something was wrong...");
fgets(comments, 200, objfile);
fgets(comments, 200, objFile);
}
} break;
case 'f':
{
fgets(comments, 200, objfile);
fscanf(objfile, "%c", &dataType);
fgets(comments, 200, objFile);
fscanf(objFile, "%c", &dataType);
while (dataType == 'f')
{
fgets(comments, 200, objfile);
fscanf(objfile, "%c", &dataType);
fgets(comments, 200, objFile);
fscanf(objFile, "%c", &dataType);
}
if (dataType == '#')
{
fscanf(objfile, "%i", &numTriangles);
fscanf(objFile, "%i", &numTriangles);
}
else printf("Ouch! Something was wrong...");
fgets(comments, 200, objfile);
fgets(comments, 200, objFile);
} break;
default: break;
@@ -581,51 +590,51 @@ Model LoadModel(const char *fileName)
int countMaxVertex = 0;
rewind(objfile);
rewind(objFile);
while(!feof(objfile))
while(!feof(objFile))
{
fscanf(objfile, "%c", &dataType);
fscanf(objFile, "%c", &dataType);
switch(dataType)
{
case '#':
{
fgets(comments, 200, objfile);
fgets(comments, 200, objFile);
} break;
case 'v':
{
fscanf(objfile, "%c", &dataType);
fscanf(objFile, "%c", &dataType);
if (dataType == 't') // Read texCoord
{
float useless = 0;
fscanf(objfile, "%f %f %f", &midTexCoords[countTexCoords].x, &midTexCoords[countTexCoords].y, &useless);
fscanf(objFile, "%f %f %f", &midTexCoords[countTexCoords].x, &midTexCoords[countTexCoords].y, &useless);
countTexCoords++;
fscanf(objfile, "%c", &dataType);
fscanf(objFile, "%c", &dataType);
}
else if (dataType == 'n') // Read normals
{
fscanf(objfile, "%f %f %f", &midNormals[countNormals].x, &midNormals[countNormals].y, &midNormals[countNormals].z );
fscanf(objFile, "%f %f %f", &midNormals[countNormals].x, &midNormals[countNormals].y, &midNormals[countNormals].z );
countNormals++;
fscanf(objfile, "%c", &dataType);
fscanf(objFile, "%c", &dataType);
}
else // Read vertex
{
fscanf(objfile, "%f %f %f", &midVertices[countVertex].x, &midVertices[countVertex].y, &midVertices[countVertex].z );
fscanf(objFile, "%f %f %f", &midVertices[countVertex].x, &midVertices[countVertex].y, &midVertices[countVertex].z );
countVertex++;
fscanf(objfile, "%c", &dataType);
fscanf(objFile, "%c", &dataType);
}
} break;
case 'f':
{
int vNum, vtNum, vnNum;
fscanf(objfile, "%c", &dataType);
fscanf(objfile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
fscanf(objFile, "%c", &dataType);
fscanf(objFile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
model.vertices[countMaxVertex] = midVertices[vNum-1];
model.normals[countMaxVertex] = midNormals[vnNum-1];
@@ -633,7 +642,7 @@ Model LoadModel(const char *fileName)
model.texcoords[countMaxVertex].y = -midTexCoords[vtNum-1].y;
countMaxVertex++;
fscanf(objfile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
fscanf(objFile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
model.vertices[countMaxVertex] = midVertices[vNum-1];
model.normals[countMaxVertex] = midNormals[vnNum-1];
@@ -641,7 +650,7 @@ Model LoadModel(const char *fileName)
model.texcoords[countMaxVertex].y = -midTexCoords[vtNum-1].y;
countMaxVertex++;
fscanf(objfile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
fscanf(objFile, "%i/%i/%i", &vNum, &vtNum, &vnNum);
model.vertices[countMaxVertex] = midVertices[vNum-1];
model.normals[countMaxVertex] = midNormals[vnNum-1];
@@ -653,19 +662,18 @@ Model LoadModel(const char *fileName)
}
}
fclose(objfile);
fclose(objFile);
return model;
}
// Load a heightmap image as a 3d model
// TODO: Just do it...
Model LoadHeightmap(Image heightmap, Vector3 resolution)
Model LoadHeightmap(Image heightmap, float maxHeight)
{
Model model;
int mapX = heightmap.width;
int mapZ = heightmap.height;
int mapZ = heightmap.height;
// NOTE: One vertex per pixel
// TODO: Consider resolution when generating model data?
@@ -676,17 +684,72 @@ Model LoadHeightmap(Image heightmap, Vector3 resolution)
model.vertices = (Vector3 *)malloc(model.numVertices * sizeof(Vector3));
model.normals = (Vector3 *)malloc(model.numVertices * sizeof(Vector3));
model.texcoords = (Vector2 *)malloc(model.numVertices * sizeof(Vector2));
for(int z = 0; z < mapZ; z++)
{
for(int x = 0; x < mapX; x++)
{
// TODO: Fill vertices array with data
}
}
//SmoothHeightmap(&model); // TODO: Smooth vertex interpolation
int vCounter = 0;
int trisCounter = 0;
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
//----------------------------------------------------------
// one triangle - 3 vertex
model.vertices[vCounter].x = x;
model.vertices[vCounter].y = GetHeightValue(heightmap.pixels[x + z*mapX])*scaleFactor;
model.vertices[vCounter].z = z;
model.vertices[vCounter+1].x = x;
model.vertices[vCounter+1].y = GetHeightValue(heightmap.pixels[x + (z+1)*mapX])*scaleFactor;
model.vertices[vCounter+1].z = z+1;
model.vertices[vCounter+2].x = x+1;
model.vertices[vCounter+2].y = GetHeightValue(heightmap.pixels[(x+1) + z*mapX])*scaleFactor;
model.vertices[vCounter+2].z = z;
// another triangle - 3 vertex
model.vertices[vCounter+3] = model.vertices[vCounter+2];
model.vertices[vCounter+4] = model.vertices[vCounter+1];
model.vertices[vCounter+5].x = x+1;
model.vertices[vCounter+5].y = GetHeightValue(heightmap.pixels[(x+1) + (z+1)*mapX])*scaleFactor;
model.vertices[vCounter+5].z = z+1;
// Fill texcoords array with data
//--------------------------------------------------------------
model.texcoords[vCounter].x = (float)x / (mapX-1);
model.texcoords[vCounter].y = (float)z / (mapZ-1);
model.texcoords[vCounter+1].x = (float)x / (mapX-1);
model.texcoords[vCounter+1].y = (float)(z+1) / (mapZ-1);
model.texcoords[vCounter+2].x = (float)(x+1) / (mapX-1);
model.texcoords[vCounter+2].y = (float)z / (mapZ-1);
model.texcoords[vCounter+3] = model.texcoords[vCounter+2];
model.texcoords[vCounter+4] = model.texcoords[vCounter+1];
model.texcoords[vCounter+5].x = (float)(x+1) / (mapX-1);
model.texcoords[vCounter+5].y = (float)(z+1) / (mapZ-1);
// Fill normals array with data
//--------------------------------------------------------------
// TODO: Review normals calculation
model.normals[vCounter] = (Vector3){ 0.0f, 1.0f, 0.0f };
model.normals[vCounter+1] = (Vector3){ 0.0f, 1.0f, 0.0f };
model.normals[vCounter+2] = (Vector3){ 0.0f, 1.0f, 0.0f };
model.normals[vCounter+3] = (Vector3){ 0.0f, 1.0f, 0.0f };
model.normals[vCounter+4] = (Vector3){ 0.0f, 1.0f, 0.0f };
model.normals[vCounter+5] = (Vector3){ 0.0f, 1.0f, 0.0f };
vCounter += 6;
trisCounter += 2;
}
}
return model;
}
@@ -702,6 +765,7 @@ void UnloadModel(Model model)
void DrawModel(Model model, Vector3 position, float scale, Color color)
{
// NOTE: For models we use Vertex Arrays (OpenGL 1.1)
//static int rotation = 0;
glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex array
glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Enable texture coords array
@@ -725,6 +789,8 @@ void DrawModel(Model model, Vector3 position, float scale, Color color)
glDisableClientState(GL_VERTEX_ARRAY); // Disable vertex array
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Disable texture coords array
glDisableClientState(GL_NORMAL_ARRAY); // Disable normals array
//rotation += 10;
}
// Draw a textured model
@@ -748,97 +814,165 @@ void DrawModelWires(Model model, Vector3 position, float scale, Color color)
}
// 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 };
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);
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);
}
// 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
// NOTE: Billboard size will maintain sourceRec aspect ratio, size will represent billboard width
Vector2 sizeRatio = { size, size * (float)sourceRec.height/sourceRec.width };
glEnable(GL_TEXTURE_2D);
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);
// 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
}
// Draw a heightmap using a provided image data
void DrawHeightmap(Image heightmap, Vector3 centerPos, Vector3 scale, Color color)
// Get current vertex y altitude (proportional to pixel colors in grayscale)
static float GetHeightValue(Color pixel)
{
// NOTE: Pixel-data is interpreted as grey-scale (even being a color image)
// NOTE: Heightmap resolution will depend on image size (one quad per pixel)
// TODO: Review how this function works... probably we need:
// Model LoadHeightmap(Image heightmap, Vector3 resolution);
// NOTE: We are allocating and de-allocating vertex data every frame! --> framerate drops 80%! CRAZY!
Vector3 *terrainVertex = (Vector3 *)malloc(heightmap.width * heightmap.height * sizeof(Vector3));
for (int z = 0; z < heightmap.height; z++)
{
for (int x = 0; x < heightmap.width; x++)
{
terrainVertex[z*heightmap.height + x].x = (float)(x*scale.x);
terrainVertex[z*heightmap.height + x].y = ((float)heightmap.pixels[z*heightmap.height + x].r +
(float)heightmap.pixels[z*heightmap.height + x].g +
(float)heightmap.pixels[z*heightmap.height + x].b) / 3 * scale.y;
terrainVertex[z*heightmap.height + x].z = (float)(-z*scale.z);
}
}
// TODO: Texture coordinates and normals computing
for (int z = 0; z < heightmap.height-1; z++)
{
glBegin(GL_TRIANGLE_STRIP);
for (int x = 0; x < heightmap.width; x++)
{
glColor3f((float)heightmap.pixels[z*heightmap.height + x].r / 255.0f,
(float)heightmap.pixels[z*heightmap.height + x].g / 255.0f,
(float)heightmap.pixels[z*heightmap.height + x].b / 255.0f);
glVertex3f(terrainVertex[z*heightmap.height + x].x, terrainVertex[z*heightmap.height + x].y, terrainVertex[z*heightmap.height + x].z);
glVertex3f(terrainVertex[(z+1)*heightmap.height + x].x, terrainVertex[(z+1)*heightmap.height + x].y, terrainVertex[(z+1)*heightmap.height + x].z);
}
glEnd();
}
free(terrainVertex);
return (((float)pixel.r + (float)pixel.g + (float)pixel.b)/3);
}
void DrawHeightmapEx(Image heightmap, Texture2D texture, Vector3 centerPos, Vector3 scale, Color tint)
// Returns camera look-at matrix (view matrix)
static Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up)
{
glEnable(GL_TEXTURE_2D);
Matrix result;
glBindTexture(GL_TEXTURE_2D, texture.glId);
Vector3 z = VectorSubtract(eye, target);
VectorNormalize(&z);
Vector3 x = VectorCrossProduct(up, z);
VectorNormalize(&x);
Vector3 y = VectorCrossProduct(z, x);
VectorNormalize(&y);
// NOTE: No texture coordinates or normals defined at this moment...
DrawHeightmap(heightmap, centerPos, scale, tint);
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;
glDisable(GL_TEXTURE_2D);
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;
}

View File

@@ -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
*
@@ -65,6 +65,7 @@
#define KEY_SPACE 32
#define KEY_ESCAPE 256
#define KEY_ENTER 257
#define KEY_BACKSPACE 259
#define KEY_RIGHT 262
#define KEY_LEFT 263
#define KEY_DOWN 264
@@ -278,6 +279,7 @@ bool IsMouseButtonUp(int button); // Detect if a mouse but
int GetMouseX(); // Returns mouse position X
int GetMouseY(); // Returns mouse position Y
Vector2 GetMousePosition(); // Returns mouse position XY
int GetMouseWheelMove(); // Returns mouse wheel movement Y
bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
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)
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 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 UnloadTexture(Texture2D texture); // Unload texture from GPU memory
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 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
@@ -370,17 +373,13 @@ void DrawGizmo(Vector3 position, bool orbits);
//------------------------------------------------------------------------------------
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 LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
void UnloadModel(Model model); // Unload 3d model from memory
void DrawModel(Model model, Vector3 position, float scale, Color color); // Draw a model
void DrawModelEx(Model model, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a textured model
void DrawModelWires(Model model, Vector3 position, float scale, Color color); // Draw a model wires
// NOTE: The following functions work but are incomplete or require some revision
// DrawHeightmap is extremely inefficient and can impact performance up to 60%
void DrawBillboard(Camera camera, Texture2D texture, Vector3 basePos, float size, Color tint); // REVIEW: Draw a billboard (raylib 1.x)
void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 basePos, float size, Color tint); // REVIEW: Draw a billboard (raylib 1.x)
void DrawHeightmap(Image heightmap, Vector3 centerPos, Vector3 scale, Color color); // REVIEW: Draw heightmap using image map (raylib 1.x)
void DrawHeightmapEx(Image heightmap, Texture2D texture, Vector3 centerPos, Vector3 scale, Color tint); // REVIEW: Draw textured heightmap (raylib 1.x)
void DrawBillboard(Camera camera, Texture2D texture, Vector3 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)

1014
src/raymath.c Normal file

File diff suppressed because it is too large Load Diff

139
src/raymath.h Normal file
View File

@@ -0,0 +1,139 @@
/*********************************************************************************************
*
* raymath
*
* Some useful functions to work with Vector3, Matrix and Quaternions
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#ifndef RAYMATH_H
#define RAYMATH_H
//#define RAYMATH_STANDALONE // NOTE: To use raymath as standalone lib, just uncomment this line
#ifndef RAYMATH_STANDALONE
#include "raylib.h" // Required for typedef: Vector3
#endif
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#ifndef PI
#define PI 3.14159265358979323846
#endif
#define DEG2RAD (PI / 180.0)
#define RAD2DEG (180.0 / PI)
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
#ifdef RAYMATH_STANDALONE
// Vector3 type
typedef struct Vector3 {
float x;
float y;
float z;
} Vector3;
#endif
// 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;
// Quaternion type
typedef struct Quaternion {
float x;
float y;
float z;
float w;
} Quaternion;
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
//------------------------------------------------------------------------------------
// Functions Declaration to work with Vector3
//------------------------------------------------------------------------------------
Vector3 VectorAdd(Vector3 v1, Vector3 v2); // Add two vectors
Vector3 VectorSubtract(Vector3 v1, Vector3 v2); // Substract two vectors
Vector3 VectorCrossProduct(Vector3 v1, Vector3 v2); // Calculate two vectors cross product
Vector3 VectorPerpendicular(Vector3 v); // Calculate one vector perpendicular vector
float VectorDotProduct(Vector3 v1, Vector3 v2); // Calculate two vectors dot product
float VectorLength(const Vector3 v); // Calculate vector lenght
void VectorScale(Vector3 *v, float scale); // Scale provided vector
void VectorNegate(Vector3 *v); // Negate provided vector (invert direction)
void VectorNormalize(Vector3 *v); // Normalize provided vector
float VectorDistance(Vector3 v1, Vector3 v2); // Calculate distance between two points
Vector3 VectorLerp(Vector3 v1, Vector3 v2, float amount); // Calculate linear interpolation between two vectors
Vector3 VectorReflect(Vector3 vector, Vector3 normal); // Calculate reflected vector to normal
//------------------------------------------------------------------------------------
// Functions Declaration to work with Matrix
//------------------------------------------------------------------------------------
float *GetMatrixVector(Matrix mat); // Returns an OpenGL-ready vector (glMultMatrixf)
float MatrixDeterminant(Matrix mat); // Compute matrix determinant
float MatrixTrace(Matrix mat); // Returns the trace of the matrix (sum of the values along the diagonal)
void MatrixTranspose(Matrix *mat); // Transposes provided matrix
void MatrixInvert(Matrix *mat); // Invert provided matrix
void MatrixNormalize(Matrix *mat); // Normalize provided matrix
Matrix MatrixIdentity(); // Returns identity matrix
Matrix MatrixAdd(Matrix left, Matrix right); // Add two matrices
Matrix MatrixSubstract(Matrix left, Matrix right); // Substract two matrices (left - right)
Matrix MatrixTranslate(float x, float y, float z); // Returns translation matrix
Matrix MatrixRotate(float angleX, float angleY, float angleZ); // Returns rotation matrix
Matrix MatrixRotateAroundAxis(Vector3 axis, float angle); // Returns rotation matrix for an angle around an specified axis
Matrix MatrixRotateAroundAxis2(Vector3 axis, float angle); // Returns rotation matrix for an angle around an specified axis (test another implemntation)
Matrix MatrixFromQuaternion(Quaternion q); // Returns rotation matrix for a given quaternion
Matrix MatrixRotateX(float angle); // Returns x-rotation matrix (angle in radians)
Matrix MatrixRotateY(float angle); // Returns y-rotation matrix (angle in radians)
Matrix MatrixRotateZ(float angle); // Returns z-rotation matrix (angle in radians)
Matrix MatrixScale(float x, float y, float z); // Returns scaling matrix
Matrix MatrixMultiply(Matrix left, Matrix right); // Returns two matrix multiplication
Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far); // Returns perspective projection matrix
Matrix MatrixPerspective(double fovy, double aspect, double near, double far); // Returns perspective projection matrix
Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far); // Returns orthographic projection matrix
Matrix MatrixLookAt(Vector3 position, Vector3 target, Vector3 up); // Returns camera look-at matrix (view matrix)
void PrintMatrix(Matrix m); // Print matrix utility
//------------------------------------------------------------------------------------
// Functions Declaration to work with Quaternions
//------------------------------------------------------------------------------------
float QuaternionLength(Quaternion quat); // Calculates the length of a quaternion
void QuaternionNormalize(Quaternion *q); // Normalize provided quaternion
Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2); // Calculate two quaternion multiplication
Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float slerp); // Calculates spherical linear interpolation between two quaternions
Quaternion QuaternionFromMatrix(Matrix matrix); // Returns a quaternion from a given rotation matrix
Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle); // Returns rotation quaternion for an angle around an axis
Matrix QuaternionToMatrix(Quaternion q); // Calculates the matrix from the given quaternion
void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle); // Returns the axis and the angle for a given quaternion
#ifdef __cplusplus
}
#endif
#endif // RAYMATH_H

View File

@@ -61,8 +61,16 @@ void DrawPixel(int posX, int posY, Color color)
glColor4ub(color.r, color.g, color.b, color.a);
glVertex2i(posX, posY);
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);
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.y <= rec2.y)
{
{
retRec.x = rec2.x;
retRec.y = rec2.y;
retRec.width = rec1.width - dxx;
@@ -443,7 +451,7 @@ Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2)
else
{
if (rec1.y <= rec2.y)
{
{
retRec.x = rec1.x;
retRec.y = rec2.y;
retRec.width = rec2.width - dxx;

15
src/simple150.frag Normal file
View File

@@ -0,0 +1,15 @@
#version 150
uniform sampler2D texture0;
in vec2 fragTexCoord;
in vec4 fragColor;
out vec4 pixelColor;
void main()
{
// Output pixel color
pixelColor = texture(texture0, fragTexCoord) * fragColor;
//pixelColor = fragColor;
}

21
src/simple150.vert Normal file
View File

@@ -0,0 +1,21 @@
#version 150
uniform mat4 projectionMatrix;
uniform mat4 modelviewMatrix;
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec4 vertexColor;
out vec2 fragTexCoord;
out vec4 fragColor;
void main()
{
// Pass some variables to the fragment shader
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;
// Apply all matrix transformations to vertex
gl_Position = projectionMatrix * modelviewMatrix * vec4(vertexPosition, 1.0);
}

514
src/stb_image_write.h Normal file
View File

@@ -0,0 +1,514 @@
/* stbiw-0.92 - public domain - http://nothings.org/stb/stb_image_write.h
writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010
no warranty implied; use at your own risk
Before #including,
#define STB_IMAGE_WRITE_IMPLEMENTATION
in the file that you want to have the implementation.
ABOUT:
This header file is a library for writing images to C stdio. It could be
adapted to write to memory or a general streaming interface; let me know.
The PNG output is not optimal; it is 20-50% larger than the file
written by a decent optimizing implementation. This library is designed
for source code compactness and simplicitly, not optimal image file size
or run-time performance.
USAGE:
There are three functions, one for each image file format:
int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
Each function returns 0 on failure and non-0 on success.
The functions create an image file defined by the parameters. The image
is a rectangle of pixels stored from left-to-right, top-to-bottom.
Each pixel contains 'comp' channels of data stored interleaved with 8-bits
per channel, in the following order: 1=L, 2=LA, 3=RGB, 4=RGBA. (L is
luminance, i.e. monochrome "color", i.e. grey value.) The rectangle is
'w' pixels wide and 'h' pixels tall. The *data pointer points to the
first byte of the top-left-most pixel. For PNG, "stride_in_bytes" is
the distance in bytes from the first byte of a row of pixels to the
first byte of the next row of pixels. Other file formats assume the
first byte of the each row of pixels begins immediately after the last
byte of the previous row.
PNG creates output files with the same number of components as the input.
The BMP and TGA formats expand Y to RGB in the file format. BMP does not
output alpha.
PNG supports writing rectangles of data even when the bytes storing rows of
data are not consecutive in memory (e.g. sub-rectangles of a larger image),
by supplying the stride between the beginning of adjacent rows. The other
formats do not. (Thus you cannot write an in-memory BMP through the BMP
writer, both because it is in BGR order and because it may have padding
at the end of the line.)
*/
#ifndef INCLUDE_STB_IMAGE_WRITE_H
#define INCLUDE_STB_IMAGE_WRITE_H
#ifdef __cplusplus
extern "C" {
#endif
extern int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
extern int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
extern int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
#ifdef __cplusplus
}
#endif
#endif//INCLUDE_STB_IMAGE_WRITE_H
#ifdef STB_IMAGE_WRITE_IMPLEMENTATION
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
typedef unsigned int stbiw_uint32;
typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
static void writefv(FILE *f, const char *fmt, va_list v)
{
while (*fmt) {
switch (*fmt++) {
case ' ': break;
case '1': { unsigned char x = (unsigned char) va_arg(v, int); fputc(x,f); break; }
case '2': { int x = va_arg(v,int); unsigned char b[2];
b[0] = (unsigned char) x; b[1] = (unsigned char) (x>>8);
fwrite(b,2,1,f); break; }
case '4': { stbiw_uint32 x = va_arg(v,int); unsigned char b[4];
b[0]=(unsigned char)x; b[1]=(unsigned char)(x>>8);
b[2]=(unsigned char)(x>>16); b[3]=(unsigned char)(x>>24);
fwrite(b,4,1,f); break; }
default:
assert(0);
return;
}
}
}
static void write3(FILE *f, unsigned char a, unsigned char b, unsigned char c)
{
unsigned char arr[3];
arr[0] = a, arr[1] = b, arr[2] = c;
fwrite(arr, 3, 1, f);
}
static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad)
{
unsigned char bg[3] = { 255, 0, 255}, px[3];
stbiw_uint32 zero = 0;
int i,j,k, j_end;
if (y <= 0)
return;
if (vdir < 0)
j_end = -1, j = y-1;
else
j_end = y, j = 0;
for (; j != j_end; j += vdir) {
for (i=0; i < x; ++i) {
unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
if (write_alpha < 0)
fwrite(&d[comp-1], 1, 1, f);
switch (comp) {
case 1:
case 2: write3(f, d[0],d[0],d[0]);
break;
case 4:
if (!write_alpha) {
// composite against pink background
for (k=0; k < 3; ++k)
px[k] = bg[k] + ((d[k] - bg[k]) * d[3])/255;
write3(f, px[1-rgb_dir],px[1],px[1+rgb_dir]);
break;
}
/* FALLTHROUGH */
case 3:
write3(f, d[1-rgb_dir],d[1],d[1+rgb_dir]);
break;
}
if (write_alpha > 0)
fwrite(&d[comp-1], 1, 1, f);
}
fwrite(&zero,scanline_pad,1,f);
}
}
static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, int comp, void *data, int alpha, int pad, const char *fmt, ...)
{
FILE *f;
if (y < 0 || x < 0) return 0;
f = fopen(filename, "wb");
if (f) {
va_list v;
va_start(v, fmt);
writefv(f, fmt, v);
va_end(v);
write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad);
fclose(f);
}
return f != NULL;
}
int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
{
int pad = (-x*3) & 3;
return outfile(filename,-1,-1,x,y,comp,(void *) data,0,pad,
"11 4 22 4" "4 44 22 444444",
'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
}
int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
{
int has_alpha = !(comp & 1);
return outfile(filename, -1,-1, x, y, comp, (void *) data, has_alpha, 0,
"111 221 2222 11", 0,0,2, 0,0,0, 0,0,x,y, 24+8*has_alpha, 8*has_alpha);
}
// stretchy buffer; stbi__sbpush() == vector<>::push_back() -- stbi__sbcount() == vector<>::size()
#define stbi__sbraw(a) ((int *) (a) - 2)
#define stbi__sbm(a) stbi__sbraw(a)[0]
#define stbi__sbn(a) stbi__sbraw(a)[1]
#define stbi__sbneedgrow(a,n) ((a)==0 || stbi__sbn(a)+n >= stbi__sbm(a))
#define stbi__sbmaybegrow(a,n) (stbi__sbneedgrow(a,(n)) ? stbi__sbgrow(a,n) : 0)
#define stbi__sbgrow(a,n) stbi__sbgrowf((void **) &(a), (n), sizeof(*(a)))
#define stbi__sbpush(a, v) (stbi__sbmaybegrow(a,1), (a)[stbi__sbn(a)++] = (v))
#define stbi__sbcount(a) ((a) ? stbi__sbn(a) : 0)
#define stbi__sbfree(a) ((a) ? free(stbi__sbraw(a)),0 : 0)
static void *stbi__sbgrowf(void **arr, int increment, int itemsize)
{
int m = *arr ? 2*stbi__sbm(*arr)+increment : increment+1;
void *p = realloc(*arr ? stbi__sbraw(*arr) : 0, itemsize * m + sizeof(int)*2);
assert(p);
if (p) {
if (!*arr) ((int *) p)[1] = 0;
*arr = (void *) ((int *) p + 2);
stbi__sbm(*arr) = m;
}
return *arr;
}
static unsigned char *stbi__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount)
{
while (*bitcount >= 8) {
stbi__sbpush(data, (unsigned char) *bitbuffer);
*bitbuffer >>= 8;
*bitcount -= 8;
}
return data;
}
static int stbi__zlib_bitrev(int code, int codebits)
{
int res=0;
while (codebits--) {
res = (res << 1) | (code & 1);
code >>= 1;
}
return res;
}
static unsigned int stbi__zlib_countm(unsigned char *a, unsigned char *b, int limit)
{
int i;
for (i=0; i < limit && i < 258; ++i)
if (a[i] != b[i]) break;
return i;
}
static unsigned int stbi__zhash(unsigned char *data)
{
stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
return hash;
}
#define stbi__zlib_flush() (out = stbi__zlib_flushf(out, &bitbuf, &bitcount))
#define stbi__zlib_add(code,codebits) \
(bitbuf |= (code) << bitcount, bitcount += (codebits), stbi__zlib_flush())
#define stbi__zlib_huffa(b,c) stbi__zlib_add(stbi__zlib_bitrev(b,c),c)
// default huffman tables
#define stbi__zlib_huff1(n) stbi__zlib_huffa(0x30 + (n), 8)
#define stbi__zlib_huff2(n) stbi__zlib_huffa(0x190 + (n)-144, 9)
#define stbi__zlib_huff3(n) stbi__zlib_huffa(0 + (n)-256,7)
#define stbi__zlib_huff4(n) stbi__zlib_huffa(0xc0 + (n)-280,8)
#define stbi__zlib_huff(n) ((n) <= 143 ? stbi__zlib_huff1(n) : (n) <= 255 ? stbi__zlib_huff2(n) : (n) <= 279 ? stbi__zlib_huff3(n) : stbi__zlib_huff4(n))
#define stbi__zlib_huffb(n) ((n) <= 143 ? stbi__zlib_huff1(n) : stbi__zlib_huff2(n))
#define stbi__ZHASH 16384
unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
{
static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 };
static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 };
static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 };
static unsigned char disteb[] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 };
unsigned int bitbuf=0;
int i,j, bitcount=0;
unsigned char *out = NULL;
unsigned char **hash_table[stbi__ZHASH]; // 64KB on the stack!
if (quality < 5) quality = 5;
stbi__sbpush(out, 0x78); // DEFLATE 32K window
stbi__sbpush(out, 0x5e); // FLEVEL = 1
stbi__zlib_add(1,1); // BFINAL = 1
stbi__zlib_add(1,2); // BTYPE = 1 -- fixed huffman
for (i=0; i < stbi__ZHASH; ++i)
hash_table[i] = NULL;
i=0;
while (i < data_len-3) {
// hash next 3 bytes of data to be compressed
int h = stbi__zhash(data+i)&(stbi__ZHASH-1), best=3;
unsigned char *bestloc = 0;
unsigned char **hlist = hash_table[h];
int n = stbi__sbcount(hlist);
for (j=0; j < n; ++j) {
if (hlist[j]-data > i-32768) { // if entry lies within window
int d = stbi__zlib_countm(hlist[j], data+i, data_len-i);
if (d >= best) best=d,bestloc=hlist[j];
}
}
// when hash table entry is too long, delete half the entries
if (hash_table[h] && stbi__sbn(hash_table[h]) == 2*quality) {
memcpy(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality);
stbi__sbn(hash_table[h]) = quality;
}
stbi__sbpush(hash_table[h],data+i);
if (bestloc) {
// "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal
h = stbi__zhash(data+i+1)&(stbi__ZHASH-1);
hlist = hash_table[h];
n = stbi__sbcount(hlist);
for (j=0; j < n; ++j) {
if (hlist[j]-data > i-32767) {
int e = stbi__zlib_countm(hlist[j], data+i+1, data_len-i-1);
if (e > best) { // if next match is better, bail on current match
bestloc = NULL;
break;
}
}
}
}
if (bestloc) {
int d = data+i - bestloc; // distance back
assert(d <= 32767 && best <= 258);
for (j=0; best > lengthc[j+1]-1; ++j);
stbi__zlib_huff(j+257);
if (lengtheb[j]) stbi__zlib_add(best - lengthc[j], lengtheb[j]);
for (j=0; d > distc[j+1]-1; ++j);
stbi__zlib_add(stbi__zlib_bitrev(j,5),5);
if (disteb[j]) stbi__zlib_add(d - distc[j], disteb[j]);
i += best;
} else {
stbi__zlib_huffb(data[i]);
++i;
}
}
// write out final bytes
for (;i < data_len; ++i)
stbi__zlib_huffb(data[i]);
stbi__zlib_huff(256); // end of block
// pad with 0 bits to byte boundary
while (bitcount)
stbi__zlib_add(0,1);
for (i=0; i < stbi__ZHASH; ++i)
(void) stbi__sbfree(hash_table[i]);
{
// compute adler32 on input
unsigned int i=0, s1=1, s2=0, blocklen = data_len % 5552;
int j=0;
while (j < data_len) {
for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1;
s1 %= 65521, s2 %= 65521;
j += blocklen;
blocklen = 5552;
}
stbi__sbpush(out, (unsigned char) (s2 >> 8));
stbi__sbpush(out, (unsigned char) s2);
stbi__sbpush(out, (unsigned char) (s1 >> 8));
stbi__sbpush(out, (unsigned char) s1);
}
*out_len = stbi__sbn(out);
// make returned pointer freeable
memmove(stbi__sbraw(out), out, *out_len);
return (unsigned char *) stbi__sbraw(out);
}
unsigned int stbi__crc32(unsigned char *buffer, int len)
{
static unsigned int crc_table[256];
unsigned int crc = ~0u;
int i,j;
if (crc_table[1] == 0)
for(i=0; i < 256; i++)
for (crc_table[i]=i, j=0; j < 8; ++j)
crc_table[i] = (crc_table[i] >> 1) ^ (crc_table[i] & 1 ? 0xedb88320 : 0);
for (i=0; i < len; ++i)
crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
return ~crc;
}
#define stbi__wpng4(o,a,b,c,d) ((o)[0]=(unsigned char)(a),(o)[1]=(unsigned char)(b),(o)[2]=(unsigned char)(c),(o)[3]=(unsigned char)(d),(o)+=4)
#define stbi__wp32(data,v) stbi__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
#define stbi__wptag(data,s) stbi__wpng4(data, s[0],s[1],s[2],s[3])
static void stbi__wpcrc(unsigned char **data, int len)
{
unsigned int crc = stbi__crc32(*data - len - 4, len+4);
stbi__wp32(*data, crc);
}
static unsigned char stbi__paeth(int a, int b, int c)
{
int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c);
if (pa <= pb && pa <= pc) return (unsigned char) a;
if (pb <= pc) return (unsigned char) b;
return (unsigned char) c;
}
unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
{
int ctype[5] = { -1, 0, 4, 2, 6 };
unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
unsigned char *out,*o, *filt, *zlib;
signed char *line_buffer;
int i,j,k,p,zlen;
if (stride_bytes == 0)
stride_bytes = x * n;
filt = (unsigned char *) malloc((x*n+1) * y); if (!filt) return 0;
line_buffer = (signed char *) malloc(x * n); if (!line_buffer) { free(filt); return 0; }
for (j=0; j < y; ++j) {
static int mapping[] = { 0,1,2,3,4 };
static int firstmap[] = { 0,1,0,5,6 };
int *mymap = j ? mapping : firstmap;
int best = 0, bestval = 0x7fffffff;
for (p=0; p < 2; ++p) {
for (k= p?best:0; k < 5; ++k) {
int type = mymap[k],est=0;
unsigned char *z = pixels + stride_bytes*j;
for (i=0; i < n; ++i)
switch (type) {
case 0: line_buffer[i] = z[i]; break;
case 1: line_buffer[i] = z[i]; break;
case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
case 4: line_buffer[i] = (signed char) (z[i] - stbi__paeth(0,z[i-stride_bytes],0)); break;
case 5: line_buffer[i] = z[i]; break;
case 6: line_buffer[i] = z[i]; break;
}
for (i=n; i < x*n; ++i) {
switch (type) {
case 0: line_buffer[i] = z[i]; break;
case 1: line_buffer[i] = z[i] - z[i-n]; break;
case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
case 4: line_buffer[i] = z[i] - stbi__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
case 6: line_buffer[i] = z[i] - stbi__paeth(z[i-n], 0,0); break;
}
}
if (p) break;
for (i=0; i < x*n; ++i)
est += abs((signed char) line_buffer[i]);
if (est < bestval) { bestval = est; best = k; }
}
}
// when we get here, best contains the filter type, and line_buffer contains the data
filt[j*(x*n+1)] = (unsigned char) best;
memcpy(filt+j*(x*n+1)+1, line_buffer, x*n);
}
free(line_buffer);
zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory
free(filt);
if (!zlib) return 0;
// each tag requires 12 bytes of overhead
out = (unsigned char *) malloc(8 + 12+13 + 12+zlen + 12);
if (!out) return 0;
*out_len = 8 + 12+13 + 12+zlen + 12;
o=out;
memcpy(o,sig,8); o+= 8;
stbi__wp32(o, 13); // header length
stbi__wptag(o, "IHDR");
stbi__wp32(o, x);
stbi__wp32(o, y);
*o++ = 8;
*o++ = (unsigned char) ctype[n];
*o++ = 0;
*o++ = 0;
*o++ = 0;
stbi__wpcrc(&o,13);
stbi__wp32(o, zlen);
stbi__wptag(o, "IDAT");
memcpy(o, zlib, zlen); o += zlen; free(zlib);
stbi__wpcrc(&o, zlen);
stbi__wp32(o,0);
stbi__wptag(o, "IEND");
stbi__wpcrc(&o,0);
assert(o == out + *out_len);
return out;
}
int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes)
{
FILE *f;
int len;
unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
if (!png) return 0;
f = fopen(filename, "wb");
if (!f) { free(png); return 0; }
fwrite(png, 1, len, f);
fclose(f);
free(png);
return 1;
}
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
/* Revision history
0.92 (2010-08-01)
casts to unsigned char to fix warnings
0.91 (2010-07-17)
first public release
0.90 first internal release
*/

View File

@@ -8,7 +8,7 @@
* stb_image - Multiple formats image loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
*
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
@@ -37,8 +37,9 @@
//----------------------------------------------------------------------------------
// 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)))
@@ -125,7 +126,7 @@ extern void LoadDefaultFont()
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].y = charsDivisor + currentLine * (charsHeight + charsDivisor);
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;
else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
glDisable(GL_LIGHTING); // When drawing text, disable LIGHTING
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, spriteFont.texture.glId);
glPushMatrix();
// Optimized to use one draw call per string
glBegin(GL_QUADS);
for(int i = 0; i < length; i++)
{
c = spriteFont.charSet[(int)text[i] - FIRST_CHAR];
glColor4ub(tint.r, tint.g, tint.b, tint.a);
glNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
glTexCoord2f((float)c.x / spriteFont.texture.width, (float)c.y / spriteFont.texture.height); glVertex2f(positionX, position.y);
glTexCoord2f((float)c.x / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height); glVertex2f(positionX, position.y + (c.h) * scaleFactor);
glTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height); glVertex2f(positionX + (c.w) * scaleFactor, position.y + (c.h) * scaleFactor);
glTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)c.y / spriteFont.texture.height); glVertex2f(positionX + (c.w) * scaleFactor, position.y);
positionX += ((spriteFont.charSet[(int)text[i] - FIRST_CHAR].w) * 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);
}
@@ -361,16 +357,13 @@ void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int f
// 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
static char buffer[MAX_FORMATTEXT_LENGTH];
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;
}
@@ -393,7 +386,7 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int
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;
@@ -491,7 +484,7 @@ static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Char
while((xPosToRead < imgWidth) &&
!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].y = lineSpacing + lineToRead * (charHeight + lineSpacing);
tempCharSet[index].h = charHeight;
@@ -611,7 +604,7 @@ static SpriteFont LoadRBMF(const char *fileName)
printf("Image reconstructed correctly... now converting it to texture...");
spriteFont.texture = CreateTexture2D(image);
spriteFont.texture = CreateTexture(image);
UnloadImage(image); // Unload image data

View File

@@ -218,37 +218,11 @@ Image LoadImageFromRES(const char *rresName, int resId)
Texture2D LoadTexture(const char *fileName)
{
Texture2D texture;
int imgWidth;
int imgHeight;
int imgBpp;
Image image;
// NOTE: Using stb_image to load images (Supports: BMP, TGA, PNG, JPG, ...)
// Force loading to 4 components (RGBA)
byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
// Convert loaded data to OpenGL texture
//----------------------------------------
GLuint id;
glGenTextures(1, &id); // Generate Pointer to the Texture
glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repead on x-axis
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repead on y-axis
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imgWidth, imgHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgData);
// NOTE: Not using mipmappings (texture for 2D drawing)
// At this point we have the image converted to texture and uploaded to GPU
stbi_image_free(imgData); // Now we can free loaded data from RAM memory
texture.glId = id;
texture.width = imgWidth;
texture.height = imgHeight;
image = LoadImage(fileName);
texture = CreateTexture(image);
UnloadImage(image);
return texture;
}
@@ -259,31 +233,14 @@ Texture2D LoadTextureFromRES(const char *rresName, int resId)
Texture2D texture;
Image image = LoadImageFromRES(rresName, resId);
texture = CreateTexture2D(image);
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...)
texture = CreateTexture(image);
return texture;
}
// Create a Texture2D from Image data
// NOTE: Image is not unloaded, it should be done manually...
Texture2D CreateTexture2D(Image image)
Texture2D CreateTexture(Image image)
{
Texture2D texture;
@@ -294,11 +251,18 @@ Texture2D CreateTexture2D(Image image)
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_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);
// 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);
}
// 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
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint)
{

View File

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

BIN
tests/heightmap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

77
tests/test_billboard.c Normal file
View File

@@ -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 - raysan@raysanweb.com)
*
********************************************************************************************/
#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
tests/test_formattext.c Normal file
View File

@@ -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 - raysan@raysanweb.com)
*
********************************************************************************************/
#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
tests/test_heightmap.c Normal file
View File

@@ -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 - raysan@raysanweb.com)
*
********************************************************************************************/
#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;
}

View File

@@ -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 - raysan@raysanweb.com)
*
********************************************************************************************/
#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
tests/test_mouse_wheel.c Normal file
View File

@@ -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 - raysan@raysanweb.com)
*
********************************************************************************************/
#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
tests/test_random.c Normal file
View File

@@ -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 - raysan@raysanweb.com)
*
********************************************************************************************/
#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;
}

View File

@@ -8,29 +8,23 @@
*
***********************************************************************************************/
rrem creates a .rres resource with embedded files and a .h header to access embedded data
Usage example:
1) Create 'resources.rres' and 'resources.h' including 3 files:
rrem image01.png image02.jpg sound03.wav
rrem image01.png image02.jpg sound03.wav
2) In your raylib program, just add at top:
#include "resources.h"
3) When a resource is required, just load it using:
Texture2D mytex = LoadTextureFromRES("resources.rres", RES_image01);
Sound mysound = LoadSoundFromRES("resources.rres", RES_sound03);
Note that you can check resources id names in resources.h file
Have fun! :)
Have fun! :)

Binary file not shown.