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