Road to raylib 1.1 - Testing rlgl
This commit is contained in:
parent
1c8dce429e
commit
96f520ff6d
13 changed files with 2537 additions and 1314 deletions
242
src/core.c
242
src/core.c
|
@ -28,15 +28,19 @@
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
|
||||||
|
|
||||||
#include <GLFW/glfw3.h> // GLFW3 lib: Windows, OpenGL context and Input management
|
#include <GLFW/glfw3.h> // GLFW3 lib: Windows, OpenGL context and Input management
|
||||||
//#include <GL/gl.h> // OpenGL functions (GLFW3 already includes gl.h)
|
//#include <GL/gl.h> // OpenGL functions (GLFW3 already includes gl.h)
|
||||||
#include <stdio.h> // Standard input / output lib
|
#include <stdio.h> // Standard input / output lib
|
||||||
#include <stdlib.h> // Declares malloc() and free() for memory management, rand()
|
#include <stdlib.h> // Declares malloc() and free() for memory management, rand()
|
||||||
#include <time.h> // Useful to initialize random seed
|
#include <time.h> // Useful to initialize random seed
|
||||||
#include <math.h> // Math related functions, tan() used to set perspective
|
#include <math.h> // Math related functions, tan() used to set perspective
|
||||||
#include "vector3.h" // Basic Vector3 functions
|
//#include "vector3.h" // Basic Vector3 functions, not required any more, replaced by raymath
|
||||||
#include "utils.h" // WritePNG() function
|
#include "utils.h" // WritePNG() function
|
||||||
|
|
||||||
|
#include "raymath.h" // Required for data type Matrix and Matrix 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!
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -47,7 +51,7 @@
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Types and Structures Definition
|
// Types and Structures Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
typedef Color pixel;
|
// ...
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Global Variables Definition
|
// Global Variables Definition
|
||||||
|
@ -62,7 +66,7 @@ static double targetTime = 0; // Desired time for one frame, if 0
|
||||||
|
|
||||||
static int windowWidth, windowHeight; // Required to switch between windowed/fullscren mode (F11)
|
static int windowWidth, windowHeight; // Required to switch between windowed/fullscren mode (F11)
|
||||||
static const char *windowTitle; // Required to switch between windowed/fullscren mode (F11)
|
static const char *windowTitle; // Required to switch between windowed/fullscren mode (F11)
|
||||||
static int exitKey = GLFW_KEY_ESCAPE;
|
static int exitKey = GLFW_KEY_ESCAPE; // Default exit key (ESC)
|
||||||
|
|
||||||
static bool customCursor = false; // Tracks if custom cursor has been set
|
static bool customCursor = false; // Tracks if custom cursor has been set
|
||||||
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
|
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
|
||||||
|
@ -77,8 +81,10 @@ static char currentMouseState[3] = { 0 }; // Required to check if mouse btn pr
|
||||||
static char previousGamepadState[32] = {0}; // Required to check if gamepad btn pressed/released once
|
static char previousGamepadState[32] = {0}; // Required to check if gamepad btn pressed/released once
|
||||||
static char currentGamepadState[32] = {0}; // Required to check if gamepad btn pressed/released once
|
static char currentGamepadState[32] = {0}; // Required to check if gamepad btn pressed/released once
|
||||||
|
|
||||||
static int previousMouseWheelY = 0;
|
static int previousMouseWheelY = 0; // Required to track mouse wheel variation
|
||||||
static int currentMouseWheelY = 0;
|
static int currentMouseWheelY = 0; // Required to track mouse wheel variation
|
||||||
|
|
||||||
|
static Color background = { 0, 0, 0, 0 }; // Screen background color
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Other Modules Functions Declaration (required by core)
|
// Other Modules Functions Declaration (required by core)
|
||||||
|
@ -89,13 +95,11 @@ extern void UnloadDefaultFont(); // [Module: text] Unloads default f
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Declaration
|
// 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 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 KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed
|
||||||
static void ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); // GLFW3 Srolling Callback, runs on mouse wheel
|
static void ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); // GLFW3 Srolling Callback, runs on mouse wheel
|
||||||
static void CursorEnterCallback(GLFWwindow* window, int enter); // GLFW3 Cursor Enter Callback, cursor enters client area
|
static void CursorEnterCallback(GLFWwindow* window, int enter); // GLFW3 Cursor Enter Callback, cursor enters client area
|
||||||
static void WindowSizeCallback(GLFWwindow* window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
|
static void WindowSizeCallback(GLFWwindow* window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
|
||||||
static void CameraLookAt(Vector3 position, Vector3 target, Vector3 up); // Setup camera view (updates MODELVIEW matrix)
|
|
||||||
static void TakeScreenshot(); // Takes a bitmap (BMP) screenshot and saves it in the same folder as executable
|
static void TakeScreenshot(); // Takes a bitmap (BMP) screenshot and saves it in the same folder as executable
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -116,9 +120,17 @@ void InitWindowEx(int width, int height, const char* title, bool resizable, cons
|
||||||
if (!glfwInit()) exit(1);
|
if (!glfwInit()) exit(1);
|
||||||
|
|
||||||
//glfwDefaultWindowHints() // Set default windows hints
|
//glfwDefaultWindowHints() // Set default windows hints
|
||||||
//glfwWindowHint(GLFW_SAMPLES, 4); // If called before windows creation, enables multisampling x4 (MSAA), default is 0
|
|
||||||
if (!resizable) glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
|
if (!resizable) glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
|
||||||
|
|
||||||
|
#ifdef USE_OPENGL_33
|
||||||
|
//glfwWindowHint(GLFW_SAMPLES, 4); // Enables multisampling x4 (MSAA), default is 0
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE);
|
||||||
|
#endif
|
||||||
|
|
||||||
window = glfwCreateWindow(width, height, title, NULL, NULL);
|
window = glfwCreateWindow(width, height, title, NULL, NULL);
|
||||||
|
|
||||||
windowWidth = width;
|
windowWidth = width;
|
||||||
|
@ -140,21 +152,41 @@ void InitWindowEx(int width, int height, const char* title, bool resizable, cons
|
||||||
glfwSwapInterval(0); // Disables GPU v-sync (if set), so frames are not limited to screen refresh rate (60Hz -> 60 FPS)
|
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
|
// If not set, swap interval uses GPU v-sync configuration
|
||||||
// Framerate can be setup using SetTargetFPS()
|
// Framerate can be setup using SetTargetFPS()
|
||||||
InitGraphicsDevice();
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
#ifdef USE_OPENGL_33
|
||||||
|
rlglInit(); // Init rlgl
|
||||||
|
#endif
|
||||||
|
//------------------------------------------------------
|
||||||
|
|
||||||
|
int fbWidth, fbHeight;
|
||||||
|
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
|
||||||
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
rlglInitGraphicsDevice(fbWidth, fbHeight);
|
||||||
|
//------------------------------------------------------
|
||||||
|
|
||||||
previousTime = glfwGetTime();
|
previousTime = glfwGetTime();
|
||||||
|
|
||||||
LoadDefaultFont();
|
LoadDefaultFont(); // NOTE: External function (defined in module: text)
|
||||||
|
|
||||||
if (cursorImage != NULL) SetCustomCursor(cursorImage);
|
if (cursorImage != NULL) SetCustomCursor(cursorImage);
|
||||||
|
|
||||||
srand(time(NULL)); // Initialize random seed
|
srand(time(NULL)); // Initialize random seed
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE); // Default background color for raylib games :P
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close Window and Terminate Context
|
// Close Window and Terminate Context
|
||||||
void CloseWindow()
|
void CloseWindow()
|
||||||
{
|
{
|
||||||
UnloadDefaultFont();
|
UnloadDefaultFont();
|
||||||
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
#ifdef USE_OPENGL_33
|
||||||
|
rlglClose(); // De-init rlgl
|
||||||
|
#endif
|
||||||
|
//------------------------------------------------------
|
||||||
|
|
||||||
glfwDestroyWindow(window);
|
glfwDestroyWindow(window);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
@ -210,7 +242,10 @@ void ToggleFullscreen()
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
glfwSetKeyCallback(window, KeyCallback);
|
glfwSetKeyCallback(window, KeyCallback);
|
||||||
|
|
||||||
InitGraphicsDevice();
|
int fbWidth, fbHeight;
|
||||||
|
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
|
||||||
|
|
||||||
|
rlglInitGraphicsDevice(fbWidth, fbHeight);
|
||||||
|
|
||||||
LoadDefaultFont();
|
LoadDefaultFont();
|
||||||
}
|
}
|
||||||
|
@ -219,13 +254,12 @@ void ToggleFullscreen()
|
||||||
// Sets Background Color
|
// Sets Background Color
|
||||||
void ClearBackground(Color color)
|
void ClearBackground(Color color)
|
||||||
{
|
{
|
||||||
// Color values clamp to 0.0f(0) and 1.0f(255)
|
if ((color.r != background.r) || (color.g != background.g) || (color.b != background.b) || (color.a != background.a))
|
||||||
float r = (float)color.r / 255;
|
{
|
||||||
float g = (float)color.g / 255;
|
rlClearColor(color.r, color.g, color.b, color.a);
|
||||||
float b = (float)color.b / 255;
|
|
||||||
float a = (float)color.a / 255;
|
background = color;
|
||||||
|
}
|
||||||
glClearColor(r, g, b, a);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup drawing canvas to start drawing
|
// Setup drawing canvas to start drawing
|
||||||
|
@ -235,11 +269,14 @@ void BeginDrawing()
|
||||||
updateTime = currentTime - previousTime;
|
updateTime = currentTime - previousTime;
|
||||||
previousTime = currentTime;
|
previousTime = currentTime;
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers, Depth Buffer is used for 3D
|
rlClearScreenBuffers();
|
||||||
|
|
||||||
glLoadIdentity(); // Reset current matrix (MODELVIEW)
|
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
|
||||||
|
|
||||||
glTranslatef(0.375, 0.375, 0); // HACK to have 2D pixel-perfect drawing on OpenGL
|
//#ifdef USE_OPENGL_11
|
||||||
|
// rlTranslatef(0.375, 0.375, 0); // HACK to have 2D pixel-perfect drawing on OpenGL
|
||||||
|
// NOTE: Not required with OpenGL 3.3+
|
||||||
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// End canvas drawing and Swap Buffers (Double Buffering)
|
// End canvas drawing and Swap Buffers (Double Buffering)
|
||||||
|
@ -247,6 +284,12 @@ void EndDrawing()
|
||||||
{
|
{
|
||||||
if (customCursor && cursorOnScreen) DrawTexture(cursor, GetMouseX(), GetMouseY(), WHITE);
|
if (customCursor && cursorOnScreen) DrawTexture(cursor, GetMouseX(), GetMouseY(), WHITE);
|
||||||
|
|
||||||
|
//------------------------------------------------------
|
||||||
|
#ifdef USE_OPENGL_33
|
||||||
|
rlglDraw(); // Draw Buffers
|
||||||
|
#endif
|
||||||
|
//------------------------------------------------------
|
||||||
|
|
||||||
glfwSwapBuffers(window); // Swap back and front buffers
|
glfwSwapBuffers(window); // Swap back and front buffers
|
||||||
glfwPollEvents(); // Register keyboard/mouse events
|
glfwPollEvents(); // Register keyboard/mouse events
|
||||||
|
|
||||||
|
@ -271,34 +314,48 @@ void EndDrawing()
|
||||||
// Initializes 3D mode for drawing (Camera setup)
|
// Initializes 3D mode for drawing (Camera setup)
|
||||||
void Begin3dMode(Camera camera)
|
void Begin3dMode(Camera camera)
|
||||||
{
|
{
|
||||||
glMatrixMode(GL_PROJECTION); // Switch to projection matrix
|
//------------------------------------------------------
|
||||||
|
#ifdef USE_OPENGL_33
|
||||||
|
rlglDraw(); // Draw Buffers
|
||||||
|
#endif
|
||||||
|
//------------------------------------------------------
|
||||||
|
|
||||||
|
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
|
||||||
|
|
||||||
glPushMatrix(); // Save previous matrix, which contains the settings for the 2d ortho projection
|
rlPushMatrix(); // Save previous matrix, which contains the settings for the 2d ortho projection
|
||||||
glLoadIdentity(); // Reset current matrix (PROJECTION)
|
rlLoadIdentity(); // Reset current matrix (PROJECTION)
|
||||||
|
|
||||||
// Setup perspective projection
|
// Setup perspective projection
|
||||||
float aspect = (GLfloat)windowWidth/(GLfloat)windowHeight;
|
float aspect = (GLfloat)windowWidth/(GLfloat)windowHeight;
|
||||||
double top = 0.1f*tan(45.0f*PI / 360.0);
|
double top = 0.1f*tan(45.0f*PI / 360.0);
|
||||||
double right = top*aspect;
|
double right = top*aspect;
|
||||||
|
|
||||||
glFrustum(-right, right, -top, top, 0.1f, 100.0f);
|
rlFrustum(-right, right, -top, top, 0.1f, 100.0f);
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW); // Switch back to modelview matrix
|
rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
|
||||||
glLoadIdentity(); // Reset current matrix (MODELVIEW)
|
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
|
||||||
|
|
||||||
CameraLookAt(camera.position, camera.target, camera.up); // Setup Camera view
|
// Setup Camera view
|
||||||
|
Matrix matLookAt = MatrixLookAt(camera.position, camera.target, camera.up);
|
||||||
|
rlMultMatrixf(GetMatrixVector(matLookAt)); // Multiply MODELVIEW matrix by view matrix (camera)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ends 3D mode and returns to default 2D orthographic mode
|
// Ends 3D mode and returns to default 2D orthographic mode
|
||||||
void End3dMode()
|
void End3dMode()
|
||||||
{
|
{
|
||||||
glMatrixMode(GL_PROJECTION); // Switch to projection matrix
|
//------------------------------------------------------
|
||||||
glPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack
|
#ifdef USE_OPENGL_33
|
||||||
|
rlglDraw(); // Draw Buffers
|
||||||
|
#endif
|
||||||
|
//------------------------------------------------------
|
||||||
|
|
||||||
|
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
|
||||||
|
rlPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW); // Get back to modelview matrix
|
rlMatrixMode(RL_MODELVIEW); // Get back to modelview matrix
|
||||||
glLoadIdentity(); // Reset current matrix (MODELVIEW)
|
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
|
||||||
|
|
||||||
glTranslatef(0.375, 0.375, 0); // HACK to ensure pixel-perfect drawing on OpenGL (after exiting 3D mode)
|
//rlTranslatef(0.375, 0.375, 0); // HACK to ensure pixel-perfect drawing on OpenGL (after exiting 3D mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set target FPS for the game
|
// Set target FPS for the game
|
||||||
|
@ -649,125 +706,32 @@ static void CursorEnterCallback(GLFWwindow* window, int enter)
|
||||||
|
|
||||||
// GLFW3 WindowSize Callback, runs when window is resized
|
// GLFW3 WindowSize Callback, runs when window is resized
|
||||||
static void WindowSizeCallback(GLFWwindow* window, int width, int height)
|
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize Graphics Device (OpenGL stuff)
|
|
||||||
static void InitGraphicsDevice()
|
|
||||||
{
|
{
|
||||||
int fbWidth, fbHeight;
|
int fbWidth, fbHeight;
|
||||||
|
|
||||||
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
|
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
|
||||||
|
|
||||||
glViewport(0, 0, fbWidth, fbHeight); // Set viewport width and height
|
// If window is resized, graphics device is re-initialized
|
||||||
|
// NOTE: Aspect ratio does not change, so, image can be deformed
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers, depth buffer is used for 3D
|
rlglInitGraphicsDevice(fbWidth, fbHeight);
|
||||||
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)
|
|
||||||
|
|
||||||
// TODO: Review all shapes/models are drawn CCW and enable backface culling
|
|
||||||
|
|
||||||
//glEnable(GL_CULL_FACE); // Enable backface culling (Disabled by default)
|
|
||||||
//glCullFace(GL_BACK); // Cull the Back face (default)
|
|
||||||
//glFrontFace(GL_CCW); // Front face are defined counter clockwise (default)
|
|
||||||
|
|
||||||
glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation)
|
|
||||||
// Possible options: GL_SMOOTH (Color interpolation) or GL_FLAT (no interpolation)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup camera view (updates MODELVIEW matrix)
|
|
||||||
static void CameraLookAt(Vector3 position, Vector3 target, Vector3 up)
|
|
||||||
{
|
|
||||||
float rotMatrix[16]; // Matrix to store camera rotation
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
rotMatrix[0] = rotX.x;
|
|
||||||
rotMatrix[1] = rotY.x;
|
|
||||||
rotMatrix[2] = rotZ.x;
|
|
||||||
rotMatrix[3] = 0.0f;
|
|
||||||
rotMatrix[4] = rotX.y;
|
|
||||||
rotMatrix[5] = rotY.y;
|
|
||||||
rotMatrix[6] = rotZ.y;
|
|
||||||
rotMatrix[7] = 0.0f;
|
|
||||||
rotMatrix[8] = rotX.z;
|
|
||||||
rotMatrix[9] = rotY.z;
|
|
||||||
rotMatrix[10] = rotZ.z;
|
|
||||||
rotMatrix[11] = 0.0f;
|
|
||||||
rotMatrix[12] = 0.0f;
|
|
||||||
rotMatrix[13] = 0.0f;
|
|
||||||
rotMatrix[14] = 0.0f;
|
|
||||||
rotMatrix[15] = 1.0f;
|
|
||||||
|
|
||||||
glMultMatrixf(rotMatrix); // Multiply MODELVIEW matrix by rotation matrix
|
|
||||||
|
|
||||||
glTranslatef(-position.x, -position.y, -position.z); // Translate eye to position
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes a bitmap (BMP) screenshot and saves it in the same folder as executable
|
// Takes a bitmap (BMP) screenshot and saves it in the same folder as executable
|
||||||
static void TakeScreenshot()
|
static void TakeScreenshot()
|
||||||
{
|
{
|
||||||
static int shotNum = 0; // Screenshot number, increments every screenshot take during program execution
|
static int shotNum = 0; // Screenshot number, increments every screenshot take during program execution
|
||||||
|
|
||||||
char buffer[20]; // Buffer to store file name
|
char buffer[20]; // Buffer to store file name
|
||||||
int fbWidth, fbHeight;
|
int fbWidth, fbHeight; // Frame buffer width and height
|
||||||
|
|
||||||
unsigned char *imgData; // Pixel image data array
|
|
||||||
|
|
||||||
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
|
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
|
||||||
|
|
||||||
imgData = (unsigned char *)malloc(fbWidth * fbHeight * sizeof(unsigned char) * 4);
|
unsigned char *imgData = rlglReadScreenPixels(fbWidth, fbHeight);
|
||||||
|
|
||||||
// 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, imgData);
|
|
||||||
|
|
||||||
// TODO: Flip image vertically!
|
|
||||||
|
|
||||||
unsigned char *imgDataFlip = (unsigned char *)malloc(fbWidth * fbHeight * sizeof(unsigned char) * 4);
|
|
||||||
|
|
||||||
for (int y = fbHeight-1; y >= 0; y--)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < (fbWidth*4); x++)
|
|
||||||
{
|
|
||||||
imgDataFlip[x + (fbHeight - y - 1)*fbWidth*4] = imgData[x + (y*fbWidth*4)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(imgData);
|
|
||||||
|
|
||||||
sprintf(buffer, "screenshot%03i.png", shotNum);
|
sprintf(buffer, "screenshot%03i.png", shotNum);
|
||||||
|
|
||||||
// NOTE: BMP directly stores data flipped vertically
|
WritePNG(buffer, imgData, fbWidth, fbHeight);
|
||||||
//WriteBitmap(buffer, imgDataPixel, fbWidth, fbHeight); // Writes pixel data array into a bitmap (BMP) file
|
|
||||||
WritePNG(buffer, imgDataFlip, fbWidth, fbHeight);
|
free(imgData);
|
||||||
|
|
||||||
free(imgDataFlip);
|
|
||||||
|
|
||||||
shotNum++;
|
shotNum++;
|
||||||
}
|
}
|
681
src/models.c
681
src/models.c
|
@ -29,7 +29,10 @@
|
||||||
#include <stdio.h> // Standard input/output functions, used to read model files data
|
#include <stdio.h> // Standard input/output functions, used to read model files data
|
||||||
#include <stdlib.h> // Declares malloc() and free() for memory management
|
#include <stdlib.h> // Declares malloc() and free() for memory management
|
||||||
#include <math.h> // Used for sin, cos, tan
|
#include <math.h> // Used for sin, cos, tan
|
||||||
#include "vector3.h" // Basic Vector3 functions
|
|
||||||
|
#include "raymath.h" // Required for data type Matrix and Matrix functions
|
||||||
|
|
||||||
|
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Defines and Macros
|
// Defines and Macros
|
||||||
|
@ -39,14 +42,30 @@
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Types and Structures Definition
|
// Types and Structures Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
#ifdef USE_OPENGL_11
|
||||||
// Matrix type (OpenGL style 4x4 - right handed)
|
struct Model {
|
||||||
typedef struct Matrix {
|
int numVertices;
|
||||||
float m0, m4, m8, m12;
|
Vector3 *vertices;
|
||||||
float m1, m5, m9, m13;
|
Vector2 *texcoords;
|
||||||
float m2, m6, m10, m14;
|
Vector3 *normals;
|
||||||
float m3, m7, m11, m15;
|
};
|
||||||
} Matrix;
|
#else
|
||||||
|
struct Model {
|
||||||
|
int numVertices;
|
||||||
|
Vector3 *vertices;
|
||||||
|
Vector2 *texcoords;
|
||||||
|
Vector3 *normals;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct Model
|
||||||
|
{
|
||||||
|
GLUint vaoId;
|
||||||
|
Matrix transform;
|
||||||
|
int polyMode;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Global Variables Definition
|
// Global Variables Definition
|
||||||
|
@ -57,8 +76,6 @@ typedef struct Matrix {
|
||||||
// Module specific Functions Declaration
|
// Module specific Functions Declaration
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
static float GetHeightValue(Color pixel);
|
static float GetHeightValue(Color pixel);
|
||||||
static void MatrixTranspose(Matrix *mat);
|
|
||||||
static Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up);
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Functions Definition
|
// Module Functions Definition
|
||||||
|
@ -68,52 +85,66 @@ static Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up);
|
||||||
// NOTE: Cube position is the center position
|
// NOTE: Cube position is the center position
|
||||||
void DrawCube(Vector3 position, float width, float height, float lenght, Color color)
|
void DrawCube(Vector3 position, float width, float height, float lenght, Color color)
|
||||||
{
|
{
|
||||||
glPushMatrix();
|
// THIS WORKS!
|
||||||
glTranslatef(position.x, position.y, position.z);
|
/*
|
||||||
//glRotatef(rotation, 0.0f, 1.0f, 0.0f);
|
Matrix mat = MatrixTranslate(2.0, 0.0, 0.0);
|
||||||
//glScalef(1.0f, 1.0f, 1.0f);
|
MatrixTranspose(&mat);
|
||||||
|
VectorTransform(&position, mat);
|
||||||
|
|
||||||
|
PrintMatrix(mat);
|
||||||
|
*/
|
||||||
|
|
||||||
|
float x = position.x;
|
||||||
|
float y = position.y;
|
||||||
|
float z = position.z;
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
rlPushMatrix();
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
|
||||||
|
// NOTE: Be careful! Function order matters (scale, translate, rotate)
|
||||||
|
//rlScalef(2.0f, 2.0f, 2.0f);
|
||||||
|
//rlTranslatef(2.0f, 0.0f, 0.0f);
|
||||||
|
rlRotatef(45, 0, 1, 0);
|
||||||
|
|
||||||
|
rlBegin(RL_QUADS);
|
||||||
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
// Front Face
|
// Front Face
|
||||||
glNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
|
rlNormal3f(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
|
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z+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
|
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z+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
|
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z+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
|
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Left Of The Texture and Quad
|
||||||
// Back Face
|
// Back Face
|
||||||
glNormal3f( 0.0f, 0.0f,-1.0f); // Normal Pointing Away From Viewer
|
rlNormal3f( 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
|
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z-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
|
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z-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
|
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z-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
|
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Bottom Left Of The Texture and Quad
|
||||||
// Top Face
|
// Top Face
|
||||||
glNormal3f( 0.0f, 1.0f, 0.0f); // Normal Pointing Up
|
rlNormal3f( 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
|
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z-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
|
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x-width/2, y+height/2, z+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
|
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x+width/2, y+height/2, z+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
|
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z-lenght/2); // Top Right Of The Texture and Quad
|
||||||
// Bottom Face
|
// Bottom Face
|
||||||
glNormal3f( 0.0f,-1.0f, 0.0f); // Normal Pointing Down
|
rlNormal3f( 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
|
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x-width/2, y-height/2, z-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
|
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x+width/2, y-height/2, z-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
|
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z+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
|
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z+lenght/2); // Bottom Right Of The Texture and Quad
|
||||||
// Right face
|
// Right face
|
||||||
glNormal3f( 1.0f, 0.0f, 0.0f); // Normal Pointing Right
|
rlNormal3f( 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
|
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z-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
|
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z-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
|
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z+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
|
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Left Of The Texture and Quad
|
||||||
// Left Face
|
// Left Face
|
||||||
glNormal3f(-1.0f, 0.0f, 0.0f); // Normal Pointing Left
|
rlNormal3f(-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
|
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z-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
|
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z+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
|
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z+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
|
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left Of The Texture and Quad
|
||||||
glEnd();
|
rlEnd();
|
||||||
glPopMatrix();
|
rlPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw cube (Vector version)
|
// Draw cube (Vector version)
|
||||||
|
@ -125,9 +156,11 @@ void DrawCubeV(Vector3 position, Vector3 size, Color color)
|
||||||
// Draw cube wires
|
// Draw cube wires
|
||||||
void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color)
|
void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color)
|
||||||
{
|
{
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
// TODO: Draw cube using RL_LINES!
|
||||||
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
|
// Draw sphere
|
||||||
|
@ -143,14 +176,16 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
|
||||||
float lat1, z1, zr1;
|
float lat1, z1, zr1;
|
||||||
float lng, x, y;
|
float lng, x, y;
|
||||||
|
|
||||||
glPushMatrix();
|
// TODO: Review vertex translate/rotate/scale mechanism
|
||||||
glTranslatef(centerPos.x, centerPos.y, centerPos.z);
|
|
||||||
glRotatef(90, 1, 0, 0);
|
rlPushMatrix();
|
||||||
glScalef(radius, radius, radius);
|
rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
|
||||||
|
rlRotatef(90, 1, 0, 0);
|
||||||
|
rlScalef(radius, radius, radius);
|
||||||
|
|
||||||
glBegin(GL_QUAD_STRIP);
|
rlBegin(GL_QUAD_STRIP);
|
||||||
|
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
|
|
||||||
for(int i = 0; i <= rings; i++)
|
for(int i = 0; i <= rings; i++)
|
||||||
{
|
{
|
||||||
|
@ -168,23 +203,25 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
|
||||||
x = cos(lng);
|
x = cos(lng);
|
||||||
y = sin(lng);
|
y = sin(lng);
|
||||||
|
|
||||||
glNormal3f(x * zr0, y * zr0, z0);
|
rlNormal3f(x * zr0, y * zr0, z0);
|
||||||
glVertex3f(x * zr0, y * zr0, z0);
|
rlVertex3f(x * zr0, y * zr0, z0);
|
||||||
|
|
||||||
glNormal3f(x * zr1, y * zr1, z1);
|
rlNormal3f(x * zr1, y * zr1, z1);
|
||||||
glVertex3f(x * zr1, y * zr1, z1);
|
rlVertex3f(x * zr1, y * zr1, z1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glEnd();
|
rlEnd();
|
||||||
glPopMatrix();
|
rlPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw sphere wires
|
// Draw sphere wires
|
||||||
void DrawSphereWires(Vector3 centerPos, float radius, Color color)
|
void DrawSphereWires(Vector3 centerPos, float radius, Color color)
|
||||||
{
|
{
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
// TODO: Draw sphere using RL_LINES!
|
||||||
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
|
// Draw a cylinder/cone
|
||||||
|
@ -200,136 +237,131 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
|
||||||
|
|
||||||
if (radiusTop == 0) // Draw pyramid or cone
|
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
|
//d – axis defined as a normalized vector from base to apex
|
||||||
//a – position of apex (top point)
|
//a – position of apex (top point)
|
||||||
//h – height
|
//h – height
|
||||||
//rd – radius of directrix
|
//rd – radius of directrix
|
||||||
//n – number of radial "slices"
|
//n – number of radial "slices"
|
||||||
|
|
||||||
|
// TODO: Review drawing to use RL_TRIANGLES
|
||||||
|
|
||||||
glPushMatrix();
|
// Draw cone top
|
||||||
//glTranslatef(centerPos.x, centerPos.y, centerPos.z);
|
rlBegin(GL_TRIANGLE_FAN);
|
||||||
//glRotatef(degrees, 0.0f, 1.0f, 0.0f);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
//glScalef(1.0f, 1.0f, 1.0f);
|
rlVertex3f(a.x, a.y, a.z);
|
||||||
|
|
||||||
// Draw cone top
|
for (int i = 0; i <= slices; i++)
|
||||||
glBegin(GL_TRIANGLE_FAN);
|
{
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
float rad = angInc * i;
|
||||||
glVertex3f(a.x, a.y, a.z);
|
p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusBottom);
|
||||||
for (int i = 0; i <= slices; i++)
|
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);
|
||||||
float rad = angInc * i;
|
rlVertex3f(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);
|
rlEnd();
|
||||||
p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
|
|
||||||
glVertex3f(p.x, p.y, p.z);
|
// Draw cone bottom
|
||||||
}
|
rlBegin(GL_TRIANGLE_FAN);
|
||||||
glEnd();
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
|
rlVertex3f(c.x, c.y, c.z);
|
||||||
// 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();
|
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);
|
||||||
|
rlVertex3f(p.x, p.y, p.z);
|
||||||
|
}
|
||||||
|
rlEnd();
|
||||||
}
|
}
|
||||||
else // Draw cylinder
|
else // Draw cylinder
|
||||||
{
|
{
|
||||||
glPushMatrix();
|
|
||||||
//glTranslatef(centerPos.x, centerPos.y, centerPos.z);
|
// TODO: Review drawing to use RL_TRIANGLES
|
||||||
//glRotatef(degrees, 0.0f, 1.0f, 0.0f);
|
|
||||||
//glScalef(1.0f, 1.0f, 1.0f);
|
// Draw cylinder top (pointed cap)
|
||||||
|
rlBegin(GL_TRIANGLE_FAN);
|
||||||
// Draw cylinder top (pointed cap)
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
glBegin(GL_TRIANGLE_FAN);
|
rlVertex3f(c.x, c.y + height, c.z);
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
for (int i = slices; i >= 0; i--)
|
||||||
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);
|
||||||
float rad = angInc * i;
|
p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusTop) + height;
|
||||||
p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusTop);
|
p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusTop);
|
||||||
p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusTop) + height;
|
rlVertex3f(p.x, p.y, p.z);
|
||||||
p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusTop);
|
}
|
||||||
glVertex3f(p.x, p.y, p.z);
|
rlEnd();
|
||||||
}
|
|
||||||
glEnd();
|
// Draw cylinder sides
|
||||||
|
rlBegin(GL_TRIANGLE_STRIP);
|
||||||
// Draw cylinder sides
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
glBegin(GL_TRIANGLE_STRIP);
|
for (int i = slices; i >= 0; i--)
|
||||||
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);
|
||||||
float rad = angInc * i;
|
p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusTop) + height;
|
||||||
p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusTop);
|
p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusTop);
|
||||||
p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusTop) + height;
|
rlVertex3f(p.x, p.y, p.z);
|
||||||
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.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusBottom);
|
p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
|
||||||
p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusBottom);
|
rlVertex3f(p.x, p.y, p.z);
|
||||||
p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
|
}
|
||||||
glVertex3f(p.x, p.y, p.z);
|
rlEnd();
|
||||||
}
|
|
||||||
glEnd();
|
// Draw cylinder bottom
|
||||||
|
rlBegin(GL_TRIANGLE_FAN);
|
||||||
// Draw cylinder bottom
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
glBegin(GL_TRIANGLE_FAN);
|
rlVertex3f(c.x, c.y, c.z);
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
for (int i = slices; i >= 0; i--)
|
||||||
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);
|
||||||
float rad = angInc * i;
|
p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusBottom);
|
||||||
p.x = c.x + (((e0.x * cos(rad)) + (e1.x * sin(rad))) * radiusBottom);
|
p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
|
||||||
p.y = c.y + (((e0.y * cos(rad)) + (e1.y * sin(rad))) * radiusBottom);
|
rlVertex3f(p.x, p.y, p.z);
|
||||||
p.z = c.z + (((e0.z * cos(rad)) + (e1.z * sin(rad))) * radiusBottom);
|
}
|
||||||
glVertex3f(p.x, p.y, p.z);
|
rlEnd();
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
glPopMatrix();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a cylinder/cone wires
|
// Draw a cylinder/cone wires
|
||||||
void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color)
|
void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color)
|
||||||
{
|
{
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
// TODO: Draw sphere using RL_LINES!
|
||||||
|
|
||||||
|
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
DrawCylinder(position, radiusTop, radiusBottom, height, slices, color);
|
DrawCylinder(position, radiusTop, radiusBottom, height, slices, color);
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a plane
|
// Draw a plane
|
||||||
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color)
|
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color)
|
||||||
{
|
{
|
||||||
|
// TODO: Review vertex translate/rotate/scale mechanism
|
||||||
|
|
||||||
// NOTE: Plane is always created on XZ ground and then rotated
|
// NOTE: Plane is always created on XZ ground and then rotated
|
||||||
glPushMatrix();
|
rlPushMatrix();
|
||||||
glTranslatef(centerPos.x, centerPos.y, centerPos.z);
|
rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
|
||||||
|
|
||||||
// TODO: Review multiples rotations Gimbal-Lock... use matrix or quaternions...
|
// TODO: Review multiples rotations Gimbal-Lock... use matrix or quaternions...
|
||||||
glRotatef(rotation.x, 1, 0, 0);
|
rlRotatef(rotation.x, 1, 0, 0);
|
||||||
glRotatef(rotation.y, 0, 1, 0);
|
rlRotatef(rotation.y, 0, 1, 0);
|
||||||
glRotatef(rotation.z, 0, 0, 1);
|
rlRotatef(rotation.z, 0, 0, 1);
|
||||||
glScalef(size.x, 1.0f, size.y);
|
rlScalef(size.x, 1.0f, size.y);
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
rlBegin(GL_QUADS);
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
rlNormal3f(0.0f, 1.0f, 0.0f);
|
||||||
glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f, 0.0f, -0.5f);
|
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(-0.5f, 0.0f, -0.5f);
|
||||||
glTexCoord2f(1.0f, 0.0f); glVertex3f(0.5f, 0.0f, -0.5f);
|
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(0.5f, 0.0f, -0.5f);
|
||||||
glTexCoord2f(1.0f, 1.0f); glVertex3f(0.5f, 0.0f, 0.5f);
|
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(0.5f, 0.0f, 0.5f);
|
||||||
glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, 0.0f, 0.5f);
|
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(-0.5f, 0.0f, 0.5f);
|
||||||
glEnd();
|
rlEnd();
|
||||||
|
rlPopMatrix();
|
||||||
glPopMatrix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a plane with divisions
|
// Draw a plane with divisions
|
||||||
|
@ -341,71 +373,75 @@ void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX,
|
||||||
float texPieceW = 1 / size.x;
|
float texPieceW = 1 / size.x;
|
||||||
float texPieceH = 1 / size.y;
|
float texPieceH = 1 / size.y;
|
||||||
|
|
||||||
|
// TODO: Review vertex translate/rotate/scale mechanism
|
||||||
|
|
||||||
// NOTE: Plane is always created on XZ ground and then rotated
|
// NOTE: Plane is always created on XZ ground and then rotated
|
||||||
glPushMatrix();
|
rlPushMatrix();
|
||||||
glTranslatef(-size.x / 2, 0.0f, -size.y / 2);
|
rlTranslatef(-size.x / 2, 0.0f, -size.y / 2);
|
||||||
glTranslatef(centerPos.x, centerPos.y, centerPos.z);
|
rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
|
||||||
|
|
||||||
// TODO: Review multiples rotations Gimbal-Lock... use matrix or quaternions...
|
// TODO: Review multiples rotations Gimbal-Lock... use matrix or quaternions...
|
||||||
glRotatef(rotation.x, 1, 0, 0);
|
rlRotatef(rotation.x, 1, 0, 0);
|
||||||
glRotatef(rotation.y, 0, 1, 0);
|
rlRotatef(rotation.y, 0, 1, 0);
|
||||||
glRotatef(rotation.z, 0, 0, 1);
|
rlRotatef(rotation.z, 0, 0, 1);
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
rlBegin(RL_QUADS);
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
rlNormal3f(0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
for (int z = 0; z < slicesZ; z++)
|
for (int z = 0; z < slicesZ; z++)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < slicesX; x++)
|
for (int x = 0; x < slicesX; x++)
|
||||||
{
|
{
|
||||||
// Draw the plane quad by quad (with textcoords)
|
// Draw the plane quad by quad (with textcoords)
|
||||||
glTexCoord2f((float)x * texPieceW, (float)z * texPieceH);
|
rlTexCoord2f((float)x * texPieceW, (float)z * texPieceH);
|
||||||
glVertex3f((float)x * quadWidth, 0.0f, (float)z * quadLenght);
|
rlVertex3f((float)x * quadWidth, 0.0f, (float)z * quadLenght);
|
||||||
|
|
||||||
glTexCoord2f((float)x * texPieceW + texPieceW, (float)z * texPieceH);
|
rlTexCoord2f((float)x * texPieceW + texPieceW, (float)z * texPieceH);
|
||||||
glVertex3f((float)x * quadWidth + quadWidth, 0.0f, (float)z * quadLenght);
|
rlVertex3f((float)x * quadWidth + quadWidth, 0.0f, (float)z * quadLenght);
|
||||||
|
|
||||||
glTexCoord2f((float)x * texPieceW + texPieceW, (float)z * texPieceH + texPieceH);
|
rlTexCoord2f((float)x * texPieceW + texPieceW, (float)z * texPieceH + texPieceH);
|
||||||
glVertex3f((float)x * quadWidth + quadWidth, 0.0f, (float)z * quadLenght + quadLenght);
|
rlVertex3f((float)x * quadWidth + quadWidth, 0.0f, (float)z * quadLenght + quadLenght);
|
||||||
|
|
||||||
glTexCoord2f((float)x * texPieceW, (float)z * texPieceH + texPieceH);
|
rlTexCoord2f((float)x * texPieceW, (float)z * texPieceH + texPieceH);
|
||||||
glVertex3f((float)x * quadWidth, 0.0f, (float)z * quadLenght + quadLenght);
|
rlVertex3f((float)x * quadWidth, 0.0f, (float)z * quadLenght + quadLenght);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glEnd();
|
rlEnd();
|
||||||
|
|
||||||
glPopMatrix();
|
rlPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a grid centered at (0, 0, 0)
|
// Draw a grid centered at (0, 0, 0)
|
||||||
void DrawGrid(int slices, float spacing)
|
void DrawGrid(int slices, float spacing)
|
||||||
{
|
{
|
||||||
int halfSlices = slices / 2;
|
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();
|
rlBegin(RL_LINES);
|
||||||
glScalef(spacing, 1.0f, spacing);
|
for(int i = -halfSlices; i <= halfSlices; i++)
|
||||||
|
{
|
||||||
glBegin(GL_LINES);
|
if (i == 0)
|
||||||
for(int i = -halfSlices; i <= halfSlices; i++)
|
|
||||||
{
|
{
|
||||||
if (i == 0) glColor3f(0.5f, 0.5f, 0.5f);
|
rlColor3f(0.5f, 0.5f, 0.5f);
|
||||||
else glColor3f(0.75f, 0.75f, 0.75f);
|
rlColor3f(0.5f, 0.5f, 0.5f);
|
||||||
|
rlColor3f(0.5f, 0.5f, 0.5f);
|
||||||
glVertex3f((float)i, 0.0f, (float)-halfSlices);
|
rlColor3f(0.5f, 0.5f, 0.5f);
|
||||||
glVertex3f((float)i, 0.0f, (float)halfSlices);
|
|
||||||
|
|
||||||
glVertex3f((float)-halfSlices, 0.0f, (float)i);
|
|
||||||
glVertex3f((float)halfSlices, 0.0f, (float)i);
|
|
||||||
}
|
}
|
||||||
glEnd();
|
else
|
||||||
|
{
|
||||||
glPopMatrix();
|
rlColor3f(0.75f, 0.75f, 0.75f);
|
||||||
|
rlColor3f(0.75f, 0.75f, 0.75f);
|
||||||
//glDisable(GL_LINE_SMOOTH);
|
rlColor3f(0.75f, 0.75f, 0.75f);
|
||||||
|
rlColor3f(0.75f, 0.75f, 0.75f);
|
||||||
|
}
|
||||||
|
|
||||||
|
rlVertex3f((float)i*spacing, 0.0f, (float)-halfSlices*spacing);
|
||||||
|
rlVertex3f((float)i*spacing, 0.0f, (float)halfSlices*spacing);
|
||||||
|
|
||||||
|
rlVertex3f((float)-halfSlices*spacing, 0.0f, (float)i*spacing);
|
||||||
|
rlVertex3f((float)halfSlices*spacing, 0.0f, (float)i*spacing);
|
||||||
|
}
|
||||||
|
rlEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw gizmo (with or without orbits)
|
// Draw gizmo (with or without orbits)
|
||||||
|
@ -418,44 +454,47 @@ void DrawGizmo(Vector3 position, bool orbits)
|
||||||
//glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
|
//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)
|
//glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
|
||||||
|
|
||||||
glPushMatrix();
|
// GL_LINE_SMOOTH is very poorly supported on desktop GL.
|
||||||
glTranslatef(position.x, position.y, position.z);
|
// A lot of drivers ignore it, so most people avoid using...
|
||||||
//glRotatef(rotation, 0, 1, 0);
|
|
||||||
glScalef(lenght, lenght, lenght);
|
|
||||||
|
|
||||||
glBegin(GL_LINES);
|
rlPushMatrix();
|
||||||
glColor3f(1.0f, 0.0f, 0.0f);
|
rlTranslatef(position.x, position.y, position.z);
|
||||||
glVertex3f(0.0f, 0.0f, 0.0f);
|
//glRotatef(rotation, 0, 1, 0);
|
||||||
glVertex3f(1.0f, 0.0f, 0.0f);
|
rlScalef(lenght, lenght, lenght);
|
||||||
|
|
||||||
|
rlBegin(GL_LINES);
|
||||||
|
rlColor3f(1.0f, 0.0f, 0.0f);
|
||||||
|
rlVertex3f(0.0f, 0.0f, 0.0f);
|
||||||
|
rlVertex3f(1.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
glColor3f(0.0f, 1.0f, 0.0f);
|
rlColor3f(0.0f, 1.0f, 0.0f);
|
||||||
glVertex3f(0.0f, 0.0f, 0.0f);
|
rlVertex3f(0.0f, 0.0f, 0.0f);
|
||||||
glVertex3f(0.0f, 1.0f, 0.0f);
|
rlVertex3f(0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
glColor3f(0.0f, 0.0f, 1.0f);
|
rlColor3f(0.0f, 0.0f, 1.0f);
|
||||||
glVertex3f(0.0f, 0.0f, 0.0f);
|
rlVertex3f(0.0f, 0.0f, 0.0f);
|
||||||
glVertex3f(0.0f, 0.0f, 1.0f);
|
rlVertex3f(0.0f, 0.0f, 1.0f);
|
||||||
glEnd();
|
rlEnd();
|
||||||
|
|
||||||
if (orbits)
|
if (orbits)
|
||||||
{
|
{
|
||||||
glBegin(GL_LINE_LOOP);
|
rlBegin(GL_LINE_LOOP);
|
||||||
glColor4f(1.0f, 0.0f, 0.0f, 0.4f);
|
rlColor4f(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);
|
for (int i=0; i < 360; i++) rlVertex3f(sin(DEG2RAD*i) * radius, 0, cos(DEG2RAD*i) * radius);
|
||||||
glEnd();
|
rlEnd();
|
||||||
|
|
||||||
glBegin(GL_LINE_LOOP);
|
rlBegin(GL_LINE_LOOP);
|
||||||
glColor4f(0.0f, 1.0f, 0.0f, 0.4f);
|
rlColor4f(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);
|
for (int i=0; i < 360; i++) rlVertex3f(sin(DEG2RAD*i) * radius, cos(DEG2RAD*i) * radius, 0);
|
||||||
glEnd();
|
rlEnd();
|
||||||
|
|
||||||
glBegin(GL_LINE_LOOP);
|
rlBegin(GL_LINE_LOOP);
|
||||||
glColor4f(0.0f, 0.0f, 1.0f, 0.4f);
|
rlColor4f(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);
|
for (int i=0; i < 360; i++) rlVertex3f(0, sin(DEG2RAD*i) * radius, cos(DEG2RAD*i) * radius);
|
||||||
glEnd();
|
rlEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
glPopMatrix();
|
rlPopMatrix();
|
||||||
|
|
||||||
//glDisable(GL_LINE_SMOOTH);
|
//glDisable(GL_LINE_SMOOTH);
|
||||||
}
|
}
|
||||||
|
@ -464,7 +503,7 @@ void DrawGizmo(Vector3 position, bool orbits)
|
||||||
// TODO: Add comments explaining this function process
|
// TODO: Add comments explaining this function process
|
||||||
Model LoadModel(const char *fileName)
|
Model LoadModel(const char *fileName)
|
||||||
{
|
{
|
||||||
Model model;
|
struct Model model;
|
||||||
|
|
||||||
char dataType;
|
char dataType;
|
||||||
char comments[200];
|
char comments[200];
|
||||||
|
@ -664,6 +703,12 @@ Model LoadModel(const char *fileName)
|
||||||
|
|
||||||
fclose(objFile);
|
fclose(objFile);
|
||||||
|
|
||||||
|
#ifdef USE_OPENGL_33
|
||||||
|
|
||||||
|
// TODO: Use loaded data to generate VAO
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -749,6 +794,12 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
|
||||||
trisCounter += 2;
|
trisCounter += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_OPENGL_33
|
||||||
|
|
||||||
|
// TODO: Use loaded data to generate VAO
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
@ -767,6 +818,8 @@ void DrawModel(Model model, Vector3 position, float scale, Color color)
|
||||||
// NOTE: For models we use Vertex Arrays (OpenGL 1.1)
|
// NOTE: For models we use Vertex Arrays (OpenGL 1.1)
|
||||||
//static int rotation = 0;
|
//static int rotation = 0;
|
||||||
|
|
||||||
|
// NOTE: Add OpenGL 3.3+ VAOs-based drawing! --> Move this stuff to rlgl?
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex array
|
glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex array
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Enable texture coords array
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Enable texture coords array
|
||||||
glEnableClientState(GL_NORMAL_ARRAY); // Enable normals array
|
glEnableClientState(GL_NORMAL_ARRAY); // Enable normals array
|
||||||
|
@ -776,41 +829,60 @@ void DrawModel(Model model, Vector3 position, float scale, Color color)
|
||||||
glNormalPointer(GL_FLOAT, 0, model.normals); // Pointer to normals 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)
|
//glColorPointer(4, GL_UNSIGNED_BYTE, 0, model.colors); // Pointer to colors array (NOT USED)
|
||||||
|
|
||||||
glPushMatrix();
|
rlPushMatrix();
|
||||||
glTranslatef(position.x, position.y, position.z);
|
rlTranslatef(position.x, position.y, position.z);
|
||||||
//glRotatef(rotation * GetFrameTime(), 0, 1, 0);
|
//glRotatef(rotation * GetFrameTime(), 0, 1, 0);
|
||||||
glScalef(scale, scale, scale);
|
rlScalef(scale, scale, scale);
|
||||||
|
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, model.numVertices);
|
glDrawArrays(GL_TRIANGLES, 0, model.numVertices);
|
||||||
glPopMatrix();
|
rlPopMatrix();
|
||||||
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY); // Disable vertex array
|
glDisableClientState(GL_VERTEX_ARRAY); // Disable vertex array
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Disable texture coords array
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Disable texture coords array
|
||||||
glDisableClientState(GL_NORMAL_ARRAY); // Disable normals array
|
glDisableClientState(GL_NORMAL_ARRAY); // Disable normals array
|
||||||
|
|
||||||
//rotation += 10;
|
//rotation += 10;
|
||||||
|
|
||||||
|
// Model drawing in OpenGL 3.3+, transform is passed to shader
|
||||||
|
/*
|
||||||
|
glUseProgram(shaderProgram); // Use our shader
|
||||||
|
|
||||||
|
Matrix modelview = MatrixMultiply(model.transform, view);
|
||||||
|
|
||||||
|
glUniformMatrix4fv(projectionMatrixLoc, 1, false, GetMatrixVector(projection));
|
||||||
|
glUniformMatrix4fv(modelviewMatrixLoc, 1, false, GetMatrixVector(modelview));
|
||||||
|
glUniform1i(textureLoc, 0);
|
||||||
|
|
||||||
|
glBindVertexArray(model.vaoId);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, model.texId);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, model.numVertices);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures
|
||||||
|
glBindVertexArray(0); // Unbind VAO
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a textured model
|
// Draw a textured model
|
||||||
void DrawModelEx(Model model, Texture2D texture, Vector3 position, float scale, Color tint)
|
void DrawModelEx(Model model, Texture2D texture, Vector3 position, float scale, Color tint)
|
||||||
{
|
{
|
||||||
glEnable(GL_TEXTURE_2D);
|
rlEnableTexture(texture.glId);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture.glId);
|
|
||||||
|
|
||||||
DrawModel(model, position, scale, tint);
|
DrawModel(model, position, scale, tint);
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
rlDisableTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a model wires
|
// Draw a model wires
|
||||||
void DrawModelWires(Model model, Vector3 position, float scale, Color color)
|
void DrawModelWires(Model model, Vector3 position, float scale, Color color)
|
||||||
{
|
{
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
// TODO: Draw model using RL_LINES... or look for a way to deal with polygon mode!
|
||||||
|
|
||||||
|
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
DrawModel(model, position, scale, color);
|
DrawModel(model, position, scale, color);
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a billboard
|
// Draw a billboard
|
||||||
|
@ -842,20 +914,18 @@ void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size,
|
||||||
Vector3 c = VectorAdd(center, p2);
|
Vector3 c = VectorAdd(center, p2);
|
||||||
Vector3 d = VectorSubtract(center, p1);
|
Vector3 d = VectorSubtract(center, p1);
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
rlEnableTexture(texture.glId);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture.glId);
|
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
rlBegin(RL_QUADS);
|
||||||
glColor4ub(tint.r, tint.g, tint.b, tint.a);
|
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
|
||||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
rlNormal3f(0.0f, 1.0f, 0.0f);
|
||||||
glTexCoord2f(0.0f, 0.0f); glVertex3f(a.x, a.y, a.z);
|
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(a.x, a.y, a.z);
|
||||||
glTexCoord2f(1.0f, 0.0f); glVertex3f(b.x, b.y, b.z);
|
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(b.x, b.y, b.z);
|
||||||
glTexCoord2f(1.0f, 1.0f); glVertex3f(c.x, c.y, c.z);
|
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(c.x, c.y, c.z);
|
||||||
glTexCoord2f(0.0f, 1.0f); glVertex3f(d.x, d.y, d.z);
|
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(d.x, d.y, d.z);
|
||||||
glEnd();
|
rlEnd();
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
rlDisableTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a billboard (part of a texture defined by a rectangle)
|
// Draw a billboard (part of a texture defined by a rectangle)
|
||||||
|
@ -887,92 +957,33 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vec
|
||||||
Vector3 c = VectorAdd(center, p2);
|
Vector3 c = VectorAdd(center, p2);
|
||||||
Vector3 d = VectorSubtract(center, p1);
|
Vector3 d = VectorSubtract(center, p1);
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D); // Enable textures usage
|
rlEnableTexture(texture.glId);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture.glId);
|
rlBegin(RL_QUADS);
|
||||||
|
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
|
||||||
glBegin(GL_QUADS);
|
|
||||||
glColor4ub(tint.r, tint.g, tint.b, tint.a);
|
|
||||||
|
|
||||||
// Bottom-left corner for texture and quad
|
// Bottom-left corner for texture and quad
|
||||||
glTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
|
rlTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
|
||||||
glVertex3f(a.x, a.y, a.z);
|
rlVertex3f(a.x, a.y, a.z);
|
||||||
|
|
||||||
// Bottom-right corner for texture and quad
|
// Bottom-right corner for texture and quad
|
||||||
glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
|
rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
|
||||||
glVertex3f(b.x, b.y, b.z);
|
rlVertex3f(b.x, b.y, b.z);
|
||||||
|
|
||||||
// Top-right corner for texture and quad
|
// Top-right corner for texture and quad
|
||||||
glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
|
rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
|
||||||
glVertex3f(c.x, c.y, c.z);
|
rlVertex3f(c.x, c.y, c.z);
|
||||||
|
|
||||||
// Top-left corner for texture and quad
|
// Top-left corner for texture and quad
|
||||||
glTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
|
rlTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
|
||||||
glVertex3f(d.x, d.y, d.z);
|
rlVertex3f(d.x, d.y, d.z);
|
||||||
glEnd();
|
rlEnd();
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D); // Disable textures usage
|
rlDisableTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get current vertex y altitude (proportional to pixel colors in grayscale)
|
// Get current vertex y altitude (proportional to pixel colors in grayscale)
|
||||||
static float GetHeightValue(Color pixel)
|
static float GetHeightValue(Color pixel)
|
||||||
{
|
{
|
||||||
return (((float)pixel.r + (float)pixel.g + (float)pixel.b)/3);
|
return (((float)pixel.r + (float)pixel.g + (float)pixel.b)/3);
|
||||||
}
|
|
||||||
|
|
||||||
// Returns camera look-at matrix (view matrix)
|
|
||||||
static Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up)
|
|
||||||
{
|
|
||||||
Matrix result;
|
|
||||||
|
|
||||||
Vector3 z = VectorSubtract(eye, target);
|
|
||||||
VectorNormalize(&z);
|
|
||||||
Vector3 x = VectorCrossProduct(up, z);
|
|
||||||
VectorNormalize(&x);
|
|
||||||
Vector3 y = VectorCrossProduct(z, x);
|
|
||||||
VectorNormalize(&y);
|
|
||||||
|
|
||||||
result.m0 = x.x;
|
|
||||||
result.m1 = x.y;
|
|
||||||
result.m2 = x.z;
|
|
||||||
result.m3 = -((x.x * eye.x) + (x.y * eye.y) + (x.z * eye.z));
|
|
||||||
result.m4 = y.x;
|
|
||||||
result.m5 = y.y;
|
|
||||||
result.m6 = y.z;
|
|
||||||
result.m7 = -((y.x * eye.x) + (y.y * eye.y) + (y.z * eye.z));
|
|
||||||
result.m8 = z.x;
|
|
||||||
result.m9 = z.y;
|
|
||||||
result.m10 = z.z;
|
|
||||||
result.m11 = -((z.x * eye.x) + (z.y * eye.y) + (z.z * eye.z));
|
|
||||||
result.m12 = 0;
|
|
||||||
result.m13 = 0;
|
|
||||||
result.m14 = 0;
|
|
||||||
result.m15 = 1;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transposes provided matrix
|
|
||||||
static void MatrixTranspose(Matrix *mat)
|
|
||||||
{
|
|
||||||
Matrix temp;
|
|
||||||
|
|
||||||
temp.m0 = mat->m0;
|
|
||||||
temp.m1 = mat->m4;
|
|
||||||
temp.m2 = mat->m8;
|
|
||||||
temp.m3 = mat->m12;
|
|
||||||
temp.m4 = mat->m1;
|
|
||||||
temp.m5 = mat->m5;
|
|
||||||
temp.m6 = mat->m9;
|
|
||||||
temp.m7 = mat->m13;
|
|
||||||
temp.m8 = mat->m2;
|
|
||||||
temp.m9 = mat->m6;
|
|
||||||
temp.m10 = mat->m10;
|
|
||||||
temp.m11 = mat->m14;
|
|
||||||
temp.m12 = mat->m3;
|
|
||||||
temp.m13 = mat->m7;
|
|
||||||
temp.m14 = mat->m11;
|
|
||||||
temp.m15 = mat->m15;
|
|
||||||
|
|
||||||
*mat = temp;
|
|
||||||
}
|
}
|
18
src/raylib.h
18
src/raylib.h
|
@ -1,15 +1,17 @@
|
||||||
/*********************************************************************************************
|
/*********************************************************************************************
|
||||||
*
|
*
|
||||||
* raylib 1.0.6 (www.raylib.com)
|
* raylib 1.1 (www.raylib.com)
|
||||||
*
|
*
|
||||||
* A simple and easy-to-use library to learn videogames programming
|
* A simple and easy-to-use library to learn videogames programming
|
||||||
*
|
*
|
||||||
* Features:
|
* Features:
|
||||||
* Library written in plain C code (C99)
|
* Library written in plain C code (C99)
|
||||||
* Uses C# PascalCase/camelCase notation
|
* Uses C# PascalCase/camelCase notation
|
||||||
* Hardware accelerated with OpenGL 1.1
|
* Hardware accelerated with OpenGL (1.1, 3.3+ or ES2)
|
||||||
|
* Unique OpenGL abstraction layer [rlgl]
|
||||||
* Powerful fonts module with SpriteFonts support
|
* Powerful fonts module with SpriteFonts support
|
||||||
* Basic 3d support for Shapes and Models
|
* Basic 3d support for Shapes, Models, Heightmaps and Billboards
|
||||||
|
* Powerful math module for Vector and Matrix operations [raymath]
|
||||||
* Audio loading and playing
|
* Audio loading and playing
|
||||||
*
|
*
|
||||||
* Used external libs:
|
* Used external libs:
|
||||||
|
@ -23,8 +25,9 @@
|
||||||
* 32bit Textures - All loaded images are converted automatically to RGBA textures
|
* 32bit Textures - All loaded images are converted automatically to RGBA textures
|
||||||
* SpriteFonts - All loaded sprite-font images are converted to RGBA and POT textures
|
* SpriteFonts - All loaded sprite-font images are converted to RGBA and POT textures
|
||||||
* One custom default font is loaded automatically when InitWindow()
|
* One custom default font is loaded automatically when InitWindow()
|
||||||
|
* If using OpenGL 3.3+, one default shader is loaded automatically (internally defined)
|
||||||
*
|
*
|
||||||
* -- LICENSE (raylib v1.0, November 2013) --
|
* -- LICENSE (raylib v1.1, March 2014) --
|
||||||
*
|
*
|
||||||
* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
* 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:
|
* BSD-like license that allows static linking with closed source software:
|
||||||
|
@ -213,12 +216,7 @@ typedef struct Camera {
|
||||||
} Camera;
|
} Camera;
|
||||||
|
|
||||||
// Basic 3d Model type
|
// Basic 3d Model type
|
||||||
typedef struct Model {
|
typedef struct Model Model;
|
||||||
int numVertices;
|
|
||||||
Vector3 *vertices;
|
|
||||||
Vector2 *texcoords;
|
|
||||||
Vector3 *normals;
|
|
||||||
} Model;
|
|
||||||
|
|
||||||
// Basic Sound source and buffer
|
// Basic Sound source and buffer
|
||||||
typedef struct Sound {
|
typedef struct Sound {
|
||||||
|
|
548
src/raymath.c
548
src/raymath.c
|
@ -199,6 +199,28 @@ Vector3 VectorReflect(Vector3 vector, Vector3 normal)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transforms a Vector3 with a given Matrix
|
||||||
|
void VectorTransform(Vector3 *v, Matrix mat)
|
||||||
|
{
|
||||||
|
float x = v->x;
|
||||||
|
float y = v->y;
|
||||||
|
float z = v->z;
|
||||||
|
|
||||||
|
//MatrixTranspose(&mat);
|
||||||
|
|
||||||
|
v->x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12;
|
||||||
|
v->y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13;
|
||||||
|
v->z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Return a Vector3 init to zero
|
||||||
|
Vector3 VectorZero()
|
||||||
|
{
|
||||||
|
Vector3 zero = { 0.0, 0.0, 0.0 };
|
||||||
|
|
||||||
|
return zero;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Functions Definition - Matrix math
|
// Module Functions Definition - Matrix math
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -234,17 +256,17 @@ float MatrixDeterminant(Matrix mat)
|
||||||
float result;
|
float result;
|
||||||
|
|
||||||
// Cache the matrix values (speed optimization)
|
// Cache the matrix values (speed optimization)
|
||||||
float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
|
float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
|
||||||
float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
|
float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
|
||||||
float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
|
float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
|
||||||
float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15;
|
float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15;
|
||||||
|
|
||||||
result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
|
result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
|
||||||
a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
|
a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
|
||||||
a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
|
a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
|
||||||
a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
|
a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
|
||||||
a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
|
a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
|
||||||
a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
|
a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -261,21 +283,21 @@ void MatrixTranspose(Matrix *mat)
|
||||||
Matrix temp;
|
Matrix temp;
|
||||||
|
|
||||||
temp.m0 = mat->m0;
|
temp.m0 = mat->m0;
|
||||||
temp.m1 = mat->m4;
|
temp.m1 = mat->m4;
|
||||||
temp.m2 = mat->m8;
|
temp.m2 = mat->m8;
|
||||||
temp.m3 = mat->m12;
|
temp.m3 = mat->m12;
|
||||||
temp.m4 = mat->m1;
|
temp.m4 = mat->m1;
|
||||||
temp.m5 = mat->m5;
|
temp.m5 = mat->m5;
|
||||||
temp.m6 = mat->m9;
|
temp.m6 = mat->m9;
|
||||||
temp.m7 = mat->m13;
|
temp.m7 = mat->m13;
|
||||||
temp.m8 = mat->m2;
|
temp.m8 = mat->m2;
|
||||||
temp.m9 = mat->m6;
|
temp.m9 = mat->m6;
|
||||||
temp.m10 = mat->m10;
|
temp.m10 = mat->m10;
|
||||||
temp.m11 = mat->m14;
|
temp.m11 = mat->m14;
|
||||||
temp.m12 = mat->m3;
|
temp.m12 = mat->m3;
|
||||||
temp.m13 = mat->m7;
|
temp.m13 = mat->m7;
|
||||||
temp.m14 = mat->m11;
|
temp.m14 = mat->m11;
|
||||||
temp.m15 = mat->m15;
|
temp.m15 = mat->m15;
|
||||||
|
|
||||||
*mat = temp;
|
*mat = temp;
|
||||||
}
|
}
|
||||||
|
@ -285,50 +307,50 @@ void MatrixInvert(Matrix *mat)
|
||||||
{
|
{
|
||||||
Matrix temp;
|
Matrix temp;
|
||||||
|
|
||||||
// Cache the matrix values (speed optimization)
|
// Cache the matrix values (speed optimization)
|
||||||
float a00 = mat->m0, a01 = mat->m1, a02 = mat->m2, a03 = mat->m3;
|
float a00 = mat->m0, a01 = mat->m1, a02 = mat->m2, a03 = mat->m3;
|
||||||
float a10 = mat->m4, a11 = mat->m5, a12 = mat->m6, a13 = mat->m7;
|
float a10 = mat->m4, a11 = mat->m5, a12 = mat->m6, a13 = mat->m7;
|
||||||
float a20 = mat->m8, a21 = mat->m9, a22 = mat->m10, a23 = mat->m11;
|
float a20 = mat->m8, a21 = mat->m9, a22 = mat->m10, a23 = mat->m11;
|
||||||
float a30 = mat->m12, a31 = mat->m13, a32 = mat->m14, a33 = mat->m15;
|
float a30 = mat->m12, a31 = mat->m13, a32 = mat->m14, a33 = mat->m15;
|
||||||
|
|
||||||
float b00 = a00*a11 - a01*a10;
|
|
||||||
float b01 = a00*a12 - a02*a10;
|
|
||||||
float b02 = a00*a13 - a03*a10;
|
|
||||||
float b03 = a01*a12 - a02*a11;
|
|
||||||
float b04 = a01*a13 - a03*a11;
|
|
||||||
float b05 = a02*a13 - a03*a12;
|
|
||||||
float b06 = a20*a31 - a21*a30;
|
|
||||||
float b07 = a20*a32 - a22*a30;
|
|
||||||
float b08 = a20*a33 - a23*a30;
|
|
||||||
float b09 = a21*a32 - a22*a31;
|
|
||||||
float b10 = a21*a33 - a23*a31;
|
|
||||||
float b11 = a22*a33 - a23*a32;
|
|
||||||
|
|
||||||
// Calculate the invert determinant (inlined to avoid double-caching)
|
float b00 = a00*a11 - a01*a10;
|
||||||
float invDet = 1/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06);
|
float b01 = a00*a12 - a02*a10;
|
||||||
|
float b02 = a00*a13 - a03*a10;
|
||||||
|
float b03 = a01*a12 - a02*a11;
|
||||||
|
float b04 = a01*a13 - a03*a11;
|
||||||
|
float b05 = a02*a13 - a03*a12;
|
||||||
|
float b06 = a20*a31 - a21*a30;
|
||||||
|
float b07 = a20*a32 - a22*a30;
|
||||||
|
float b08 = a20*a33 - a23*a30;
|
||||||
|
float b09 = a21*a32 - a22*a31;
|
||||||
|
float b10 = a21*a33 - a23*a31;
|
||||||
|
float b11 = a22*a33 - a23*a32;
|
||||||
|
|
||||||
|
// Calculate the invert determinant (inlined to avoid double-caching)
|
||||||
|
float invDet = 1/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06);
|
||||||
|
|
||||||
printf("%f\n", invDet);
|
printf("%f\n", invDet);
|
||||||
|
|
||||||
temp.m0 = (a11*b11 - a12*b10 + a13*b09)*invDet;
|
temp.m0 = (a11*b11 - a12*b10 + a13*b09)*invDet;
|
||||||
temp.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet;
|
temp.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet;
|
||||||
temp.m2 = (a31*b05 - a32*b04 + a33*b03)*invDet;
|
temp.m2 = (a31*b05 - a32*b04 + a33*b03)*invDet;
|
||||||
temp.m3 = (-a21*b05 + a22*b04 - a23*b03)*invDet;
|
temp.m3 = (-a21*b05 + a22*b04 - a23*b03)*invDet;
|
||||||
temp.m4 = (-a10*b11 + a12*b08 - a13*b07)*invDet;
|
temp.m4 = (-a10*b11 + a12*b08 - a13*b07)*invDet;
|
||||||
temp.m5 = (a00*b11 - a02*b08 + a03*b07)*invDet;
|
temp.m5 = (a00*b11 - a02*b08 + a03*b07)*invDet;
|
||||||
temp.m6 = (-a30*b05 + a32*b02 - a33*b01)*invDet;
|
temp.m6 = (-a30*b05 + a32*b02 - a33*b01)*invDet;
|
||||||
temp.m7 = (a20*b05 - a22*b02 + a23*b01)*invDet;
|
temp.m7 = (a20*b05 - a22*b02 + a23*b01)*invDet;
|
||||||
temp.m8 = (a10*b10 - a11*b08 + a13*b06)*invDet;
|
temp.m8 = (a10*b10 - a11*b08 + a13*b06)*invDet;
|
||||||
temp.m9 = (-a00*b10 + a01*b08 - a03*b06)*invDet;
|
temp.m9 = (-a00*b10 + a01*b08 - a03*b06)*invDet;
|
||||||
temp.m10 = (a30*b04 - a31*b02 + a33*b00)*invDet;
|
temp.m10 = (a30*b04 - a31*b02 + a33*b00)*invDet;
|
||||||
temp.m11 = (-a20*b04 + a21*b02 - a23*b00)*invDet;
|
temp.m11 = (-a20*b04 + a21*b02 - a23*b00)*invDet;
|
||||||
temp.m12 = (-a10*b09 + a11*b07 - a12*b06)*invDet;
|
temp.m12 = (-a10*b09 + a11*b07 - a12*b06)*invDet;
|
||||||
temp.m13 = (a00*b09 - a01*b07 + a02*b06)*invDet;
|
temp.m13 = (a00*b09 - a01*b07 + a02*b06)*invDet;
|
||||||
temp.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet;
|
temp.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet;
|
||||||
temp.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet;
|
temp.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet;
|
||||||
|
|
||||||
PrintMatrix(temp);
|
PrintMatrix(temp);
|
||||||
|
|
||||||
*mat = temp;
|
*mat = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize provided matrix
|
// Normalize provided matrix
|
||||||
|
@ -337,21 +359,21 @@ void MatrixNormalize(Matrix *mat)
|
||||||
float det = MatrixDeterminant(*mat);
|
float det = MatrixDeterminant(*mat);
|
||||||
|
|
||||||
mat->m0 /= det;
|
mat->m0 /= det;
|
||||||
mat->m1 /= det;
|
mat->m1 /= det;
|
||||||
mat->m2 /= det;
|
mat->m2 /= det;
|
||||||
mat->m3 /= det;
|
mat->m3 /= det;
|
||||||
mat->m4 /= det;
|
mat->m4 /= det;
|
||||||
mat->m5 /= det;
|
mat->m5 /= det;
|
||||||
mat->m6 /= det;
|
mat->m6 /= det;
|
||||||
mat->m7 /= det;
|
mat->m7 /= det;
|
||||||
mat->m8 /= det;
|
mat->m8 /= det;
|
||||||
mat->m9 /= det;
|
mat->m9 /= det;
|
||||||
mat->m10 /= det;
|
mat->m10 /= det;
|
||||||
mat->m11 /= det;
|
mat->m11 /= det;
|
||||||
mat->m12 /= det;
|
mat->m12 /= det;
|
||||||
mat->m13 /= det;
|
mat->m13 /= det;
|
||||||
mat->m14 /= det;
|
mat->m14 /= det;
|
||||||
mat->m15 /= det;
|
mat->m15 /= det;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns identity matrix
|
// Returns identity matrix
|
||||||
|
@ -368,21 +390,21 @@ Matrix MatrixAdd(Matrix left, Matrix right)
|
||||||
Matrix result = MatrixIdentity();
|
Matrix result = MatrixIdentity();
|
||||||
|
|
||||||
result.m0 = left.m0 + right.m0;
|
result.m0 = left.m0 + right.m0;
|
||||||
result.m1 = left.m1 + right.m1;
|
result.m1 = left.m1 + right.m1;
|
||||||
result.m2 = left.m2 + right.m2;
|
result.m2 = left.m2 + right.m2;
|
||||||
result.m3 = left.m3 + right.m3;
|
result.m3 = left.m3 + right.m3;
|
||||||
result.m4 = left.m4 + right.m4;
|
result.m4 = left.m4 + right.m4;
|
||||||
result.m5 = left.m5 + right.m5;
|
result.m5 = left.m5 + right.m5;
|
||||||
result.m6 = left.m6 + right.m6;
|
result.m6 = left.m6 + right.m6;
|
||||||
result.m7 = left.m7 + right.m7;
|
result.m7 = left.m7 + right.m7;
|
||||||
result.m8 = left.m8 + right.m8;
|
result.m8 = left.m8 + right.m8;
|
||||||
result.m9 = left.m9 + right.m9;
|
result.m9 = left.m9 + right.m9;
|
||||||
result.m10 = left.m10 + right.m10;
|
result.m10 = left.m10 + right.m10;
|
||||||
result.m11 = left.m11 + right.m11;
|
result.m11 = left.m11 + right.m11;
|
||||||
result.m12 = left.m12 + right.m12;
|
result.m12 = left.m12 + right.m12;
|
||||||
result.m13 = left.m13 + right.m13;
|
result.m13 = left.m13 + right.m13;
|
||||||
result.m14 = left.m14 + right.m14;
|
result.m14 = left.m14 + right.m14;
|
||||||
result.m15 = left.m15 + right.m15;
|
result.m15 = left.m15 + right.m15;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -393,21 +415,21 @@ Matrix MatrixSubstract(Matrix left, Matrix right)
|
||||||
Matrix result = MatrixIdentity();
|
Matrix result = MatrixIdentity();
|
||||||
|
|
||||||
result.m0 = left.m0 - right.m0;
|
result.m0 = left.m0 - right.m0;
|
||||||
result.m1 = left.m1 - right.m1;
|
result.m1 = left.m1 - right.m1;
|
||||||
result.m2 = left.m2 - right.m2;
|
result.m2 = left.m2 - right.m2;
|
||||||
result.m3 = left.m3 - right.m3;
|
result.m3 = left.m3 - right.m3;
|
||||||
result.m4 = left.m4 - right.m4;
|
result.m4 = left.m4 - right.m4;
|
||||||
result.m5 = left.m5 - right.m5;
|
result.m5 = left.m5 - right.m5;
|
||||||
result.m6 = left.m6 - right.m6;
|
result.m6 = left.m6 - right.m6;
|
||||||
result.m7 = left.m7 - right.m7;
|
result.m7 = left.m7 - right.m7;
|
||||||
result.m8 = left.m8 - right.m8;
|
result.m8 = left.m8 - right.m8;
|
||||||
result.m9 = left.m9 - right.m9;
|
result.m9 = left.m9 - right.m9;
|
||||||
result.m10 = left.m10 - right.m10;
|
result.m10 = left.m10 - right.m10;
|
||||||
result.m11 = left.m11 - right.m11;
|
result.m11 = left.m11 - right.m11;
|
||||||
result.m12 = left.m12 - right.m12;
|
result.m12 = left.m12 - right.m12;
|
||||||
result.m13 = left.m13 - right.m13;
|
result.m13 = left.m13 - right.m13;
|
||||||
result.m14 = left.m14 - right.m14;
|
result.m14 = left.m14 - right.m14;
|
||||||
result.m15 = left.m15 - right.m15;
|
result.m15 = left.m15 - right.m15;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -476,51 +498,51 @@ Matrix MatrixFromAxisAngle(Vector3 axis, float angle)
|
||||||
|
|
||||||
Matrix mat = MatrixIdentity();
|
Matrix mat = MatrixIdentity();
|
||||||
|
|
||||||
float x = axis.x, y = axis.y, z = axis.z;
|
float x = axis.x, y = axis.y, z = axis.z;
|
||||||
|
|
||||||
float length = sqrt(x*x + y*y + z*z);
|
float length = sqrt(x*x + y*y + z*z);
|
||||||
|
|
||||||
if ((length != 1) && (length != 0))
|
if ((length != 1) && (length != 0))
|
||||||
{
|
{
|
||||||
length = 1 / length;
|
length = 1 / length;
|
||||||
x *= length;
|
x *= length;
|
||||||
y *= length;
|
y *= length;
|
||||||
z *= length;
|
z *= length;
|
||||||
}
|
}
|
||||||
|
|
||||||
float s = sin(angle);
|
|
||||||
float c = cos(angle);
|
|
||||||
float t = 1-c;
|
|
||||||
|
|
||||||
// Cache some matrix values (speed optimization)
|
|
||||||
float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
|
|
||||||
float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
|
|
||||||
float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
|
|
||||||
|
|
||||||
// Construct the elements of the rotation matrix
|
|
||||||
float b00 = x*x*t + c, b01 = y*x*t + z*s, b02 = z*x*t - y*s;
|
|
||||||
float b10 = x*y*t - z*s, b11 = y*y*t + c, b12 = z*y*t + x*s;
|
|
||||||
float b20 = x*z*t + y*s, b21 = y*z*t - x*s, b22 = z*z*t + c;
|
|
||||||
|
|
||||||
// Perform rotation-specific matrix multiplication
|
|
||||||
result.m0 = a00*b00 + a10*b01 + a20*b02;
|
|
||||||
result.m1 = a01*b00 + a11*b01 + a21*b02;
|
|
||||||
result.m2 = a02*b00 + a12*b01 + a22*b02;
|
|
||||||
result.m3 = a03*b00 + a13*b01 + a23*b02;
|
|
||||||
result.m4 = a00*b10 + a10*b11 + a20*b12;
|
|
||||||
result.m5 = a01*b10 + a11*b11 + a21*b12;
|
|
||||||
result.m6 = a02*b10 + a12*b11 + a22*b12;
|
|
||||||
result.m7 = a03*b10 + a13*b11 + a23*b12;
|
|
||||||
result.m8 = a00*b20 + a10*b21 + a20*b22;
|
|
||||||
result.m9 = a01*b20 + a11*b21 + a21*b22;
|
|
||||||
result.m10 = a02*b20 + a12*b21 + a22*b22;
|
|
||||||
result.m11 = a03*b20 + a13*b21 + a23*b22;
|
|
||||||
result.m12 = mat.m12;
|
|
||||||
result.m13 = mat.m13;
|
|
||||||
result.m14 = mat.m14;
|
|
||||||
result.m15 = mat.m15;
|
|
||||||
|
|
||||||
return result;
|
float s = sin(angle);
|
||||||
|
float c = cos(angle);
|
||||||
|
float t = 1-c;
|
||||||
|
|
||||||
|
// Cache some matrix values (speed optimization)
|
||||||
|
float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
|
||||||
|
float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
|
||||||
|
float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
|
||||||
|
|
||||||
|
// Construct the elements of the rotation matrix
|
||||||
|
float b00 = x*x*t + c, b01 = y*x*t + z*s, b02 = z*x*t - y*s;
|
||||||
|
float b10 = x*y*t - z*s, b11 = y*y*t + c, b12 = z*y*t + x*s;
|
||||||
|
float b20 = x*z*t + y*s, b21 = y*z*t - x*s, b22 = z*z*t + c;
|
||||||
|
|
||||||
|
// Perform rotation-specific matrix multiplication
|
||||||
|
result.m0 = a00*b00 + a10*b01 + a20*b02;
|
||||||
|
result.m1 = a01*b00 + a11*b01 + a21*b02;
|
||||||
|
result.m2 = a02*b00 + a12*b01 + a22*b02;
|
||||||
|
result.m3 = a03*b00 + a13*b01 + a23*b02;
|
||||||
|
result.m4 = a00*b10 + a10*b11 + a20*b12;
|
||||||
|
result.m5 = a01*b10 + a11*b11 + a21*b12;
|
||||||
|
result.m6 = a02*b10 + a12*b11 + a22*b12;
|
||||||
|
result.m7 = a03*b10 + a13*b11 + a23*b12;
|
||||||
|
result.m8 = a00*b20 + a10*b21 + a20*b22;
|
||||||
|
result.m9 = a01*b20 + a11*b21 + a21*b22;
|
||||||
|
result.m10 = a02*b20 + a12*b21 + a22*b22;
|
||||||
|
result.m11 = a03*b20 + a13*b21 + a23*b22;
|
||||||
|
result.m12 = mat.m12;
|
||||||
|
result.m13 = mat.m13;
|
||||||
|
result.m14 = mat.m14;
|
||||||
|
result.m15 = mat.m15;
|
||||||
|
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create rotation matrix from axis and angle
|
// Create rotation matrix from axis and angle
|
||||||
|
@ -645,35 +667,35 @@ Matrix MatrixMultiply(Matrix left, Matrix right)
|
||||||
{
|
{
|
||||||
Matrix result;
|
Matrix result;
|
||||||
|
|
||||||
// Cache the matrix values (speed optimization)
|
// Cache the matrix values (speed optimization)
|
||||||
float a00 = left.m0, a01 = left.m1, a02 = left.m2, a03 = left.m3;
|
float a00 = left.m0, a01 = left.m1, a02 = left.m2, a03 = left.m3;
|
||||||
float a10 = left.m4, a11 = left.m5, a12 = left.m6, a13 = left.m7;
|
float a10 = left.m4, a11 = left.m5, a12 = left.m6, a13 = left.m7;
|
||||||
float a20 = left.m8, a21 = left.m9, a22 = left.m10, a23 = left.m11;
|
float a20 = left.m8, a21 = left.m9, a22 = left.m10, a23 = left.m11;
|
||||||
float a30 = left.m12, a31 = left.m13, a32 = left.m14, a33 = left.m15;
|
float a30 = left.m12, a31 = left.m13, a32 = left.m14, a33 = left.m15;
|
||||||
|
|
||||||
float b00 = right.m0, b01 = right.m1, b02 = right.m2, b03 = right.m3;
|
float b00 = right.m0, b01 = right.m1, b02 = right.m2, b03 = right.m3;
|
||||||
float b10 = right.m4, b11 = right.m5, b12 = right.m6, b13 = right.m7;
|
float b10 = right.m4, b11 = right.m5, b12 = right.m6, b13 = right.m7;
|
||||||
float b20 = right.m8, b21 = right.m9, b22 = right.m10, b23 = right.m11;
|
float b20 = right.m8, b21 = right.m9, b22 = right.m10, b23 = right.m11;
|
||||||
float b30 = right.m12, b31 = right.m13, b32 = right.m14, b33 = right.m15;
|
float b30 = right.m12, b31 = right.m13, b32 = right.m14, b33 = right.m15;
|
||||||
|
|
||||||
result.m0 = b00*a00 + b01*a10 + b02*a20 + b03*a30;
|
result.m0 = b00*a00 + b01*a10 + b02*a20 + b03*a30;
|
||||||
result.m1 = b00*a01 + b01*a11 + b02*a21 + b03*a31;
|
result.m1 = b00*a01 + b01*a11 + b02*a21 + b03*a31;
|
||||||
result.m2 = b00*a02 + b01*a12 + b02*a22 + b03*a32;
|
result.m2 = b00*a02 + b01*a12 + b02*a22 + b03*a32;
|
||||||
result.m3 = b00*a03 + b01*a13 + b02*a23 + b03*a33;
|
result.m3 = b00*a03 + b01*a13 + b02*a23 + b03*a33;
|
||||||
result.m4 = b10*a00 + b11*a10 + b12*a20 + b13*a30;
|
result.m4 = b10*a00 + b11*a10 + b12*a20 + b13*a30;
|
||||||
result.m5 = b10*a01 + b11*a11 + b12*a21 + b13*a31;
|
result.m5 = b10*a01 + b11*a11 + b12*a21 + b13*a31;
|
||||||
result.m6 = b10*a02 + b11*a12 + b12*a22 + b13*a32;
|
result.m6 = b10*a02 + b11*a12 + b12*a22 + b13*a32;
|
||||||
result.m7 = b10*a03 + b11*a13 + b12*a23 + b13*a33;
|
result.m7 = b10*a03 + b11*a13 + b12*a23 + b13*a33;
|
||||||
result.m8 = b20*a00 + b21*a10 + b22*a20 + b23*a30;
|
result.m8 = b20*a00 + b21*a10 + b22*a20 + b23*a30;
|
||||||
result.m9 = b20*a01 + b21*a11 + b22*a21 + b23*a31;
|
result.m9 = b20*a01 + b21*a11 + b22*a21 + b23*a31;
|
||||||
result.m10 = b20*a02 + b21*a12 + b22*a22 + b23*a32;
|
result.m10 = b20*a02 + b21*a12 + b22*a22 + b23*a32;
|
||||||
result.m11 = b20*a03 + b21*a13 + b22*a23 + b23*a33;
|
result.m11 = b20*a03 + b21*a13 + b22*a23 + b23*a33;
|
||||||
result.m12 = b30*a00 + b31*a10 + b32*a20 + b33*a30;
|
result.m12 = b30*a00 + b31*a10 + b32*a20 + b33*a30;
|
||||||
result.m13 = b30*a01 + b31*a11 + b32*a21 + b33*a31;
|
result.m13 = b30*a01 + b31*a11 + b32*a21 + b33*a31;
|
||||||
result.m14 = b30*a02 + b31*a12 + b32*a22 + b33*a32;
|
result.m14 = b30*a02 + b31*a12 + b32*a22 + b33*a32;
|
||||||
result.m15 = b30*a03 + b31*a13 + b32*a23 + b33*a33;
|
result.m15 = b30*a03 + b31*a13 + b32*a23 + b33*a33;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns perspective projection matrix
|
// Returns perspective projection matrix
|
||||||
|
@ -681,28 +703,28 @@ Matrix MatrixFrustum(double left, double right, double bottom, double top, doubl
|
||||||
{
|
{
|
||||||
Matrix result;
|
Matrix result;
|
||||||
|
|
||||||
float rl = (right - left);
|
float rl = (right - left);
|
||||||
float tb = (top - bottom);
|
float tb = (top - bottom);
|
||||||
float fn = (far - near);
|
float fn = (far - near);
|
||||||
|
|
||||||
result.m0 = (near*2) / rl;
|
result.m0 = (near*2) / rl;
|
||||||
result.m1 = 0;
|
result.m1 = 0;
|
||||||
result.m2 = 0;
|
result.m2 = 0;
|
||||||
result.m3 = 0;
|
result.m3 = 0;
|
||||||
result.m4 = 0;
|
result.m4 = 0;
|
||||||
result.m5 = (near*2) / tb;
|
result.m5 = (near*2) / tb;
|
||||||
result.m6 = 0;
|
result.m6 = 0;
|
||||||
result.m7 = 0;
|
result.m7 = 0;
|
||||||
result.m8 = (right + left) / rl;
|
result.m8 = (right + left) / rl;
|
||||||
result.m9 = (top + bottom) / tb;
|
result.m9 = (top + bottom) / tb;
|
||||||
result.m10 = -(far + near) / fn;
|
result.m10 = -(far + near) / fn;
|
||||||
result.m11 = -1;
|
result.m11 = -1;
|
||||||
result.m12 = 0;
|
result.m12 = 0;
|
||||||
result.m13 = 0;
|
result.m13 = 0;
|
||||||
result.m14 = -(far*near*2) / fn;
|
result.m14 = -(far*near*2) / fn;
|
||||||
result.m15 = 0;
|
result.m15 = 0;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns perspective projection matrix
|
// Returns perspective projection matrix
|
||||||
|
@ -720,25 +742,25 @@ Matrix MatrixOrtho(double left, double right, double bottom, double top, double
|
||||||
Matrix result;
|
Matrix result;
|
||||||
|
|
||||||
float rl = (right - left);
|
float rl = (right - left);
|
||||||
float tb = (top - bottom);
|
float tb = (top - bottom);
|
||||||
float fn = (far - near);
|
float fn = (far - near);
|
||||||
|
|
||||||
result.m0 = 2 / rl;
|
result.m0 = 2 / rl;
|
||||||
result.m1 = 0;
|
result.m1 = 0;
|
||||||
result.m2 = 0;
|
result.m2 = 0;
|
||||||
result.m3 = 0;
|
result.m3 = 0;
|
||||||
result.m4 = 0;
|
result.m4 = 0;
|
||||||
result.m5 = 2 / tb;
|
result.m5 = 2 / tb;
|
||||||
result.m6 = 0;
|
result.m6 = 0;
|
||||||
result.m7 = 0;
|
result.m7 = 0;
|
||||||
result.m8 = 0;
|
result.m8 = 0;
|
||||||
result.m9 = 0;
|
result.m9 = 0;
|
||||||
result.m10 = -2 / fn;
|
result.m10 = -2 / fn;
|
||||||
result.m11 = 0;
|
result.m11 = 0;
|
||||||
result.m12 = -(left + right) / rl;
|
result.m12 = -(left + right) / rl;
|
||||||
result.m13 = -(top + bottom) / tb;
|
result.m13 = -(top + bottom) / tb;
|
||||||
result.m14 = -(far + near) / fn;
|
result.m14 = -(far + near) / fn;
|
||||||
result.m15 = 1;
|
result.m15 = 1;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -747,7 +769,7 @@ Matrix MatrixOrtho(double left, double right, double bottom, double top, double
|
||||||
Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up)
|
Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up)
|
||||||
{
|
{
|
||||||
Matrix result;
|
Matrix result;
|
||||||
|
|
||||||
Vector3 z = VectorSubtract(eye, target);
|
Vector3 z = VectorSubtract(eye, target);
|
||||||
VectorNormalize(&z);
|
VectorNormalize(&z);
|
||||||
Vector3 x = VectorCrossProduct(up, z);
|
Vector3 x = VectorCrossProduct(up, z);
|
||||||
|
@ -793,7 +815,7 @@ void PrintMatrix(Matrix m)
|
||||||
// Calculates the length of a quaternion
|
// Calculates the length of a quaternion
|
||||||
float QuaternionLength(Quaternion quat)
|
float QuaternionLength(Quaternion quat)
|
||||||
{
|
{
|
||||||
return sqrt(quat.x*quat.x + quat.y*quat.y + quat.z*quat.z + quat.w*quat.w);
|
return sqrt(quat.x*quat.x + quat.y*quat.y + quat.z*quat.z + quat.w*quat.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize provided quaternion
|
// Normalize provided quaternion
|
||||||
|
@ -818,15 +840,15 @@ Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2)
|
||||||
{
|
{
|
||||||
Quaternion result;
|
Quaternion result;
|
||||||
|
|
||||||
float qax = q1.x, qay = q1.y, qaz = q1.z, qaw = q1.w;
|
float qax = q1.x, qay = q1.y, qaz = q1.z, qaw = q1.w;
|
||||||
float qbx = q2.x, qby = q2.y, qbz = q2.z, qbw = q2.w;
|
float qbx = q2.x, qby = q2.y, qbz = q2.z, qbw = q2.w;
|
||||||
|
|
||||||
result.x = qax*qbw + qaw*qbx + qay*qbz - qaz*qby;
|
result.x = qax*qbw + qaw*qbx + qay*qbz - qaz*qby;
|
||||||
result.y = qay*qbw + qaw*qby + qaz*qbx - qax*qbz;
|
result.y = qay*qbw + qaw*qby + qaz*qbx - qax*qbz;
|
||||||
result.z = qaz*qbw + qaw*qbz + qax*qby - qay*qbx;
|
result.z = qaz*qbw + qaw*qbz + qax*qby - qay*qbx;
|
||||||
result.w = qaw*qbw - qax*qbx - qay*qby - qaz*qbz;
|
result.w = qaw*qbw - qax*qbx - qay*qby - qaz*qbz;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates spherical linear interpolation between two quaternions
|
// Calculates spherical linear interpolation between two quaternions
|
||||||
|
@ -834,9 +856,9 @@ Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
|
||||||
{
|
{
|
||||||
Quaternion result;
|
Quaternion result;
|
||||||
|
|
||||||
float cosHalfTheta = q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w;
|
float cosHalfTheta = q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w;
|
||||||
|
|
||||||
if (abs(cosHalfTheta) >= 1.0) result = q1;
|
if (abs(cosHalfTheta) >= 1.0) result = q1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float halfTheta = acos(cosHalfTheta);
|
float halfTheta = acos(cosHalfTheta);
|
||||||
|
@ -859,9 +881,9 @@ Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
|
||||||
result.z = (q1.z*ratioA + q2.z*ratioB);
|
result.z = (q1.z*ratioA + q2.z*ratioB);
|
||||||
result.w = (q1.w*ratioA + q2.w*ratioB);
|
result.w = (q1.w*ratioA + q2.w*ratioB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a quaternion from a given rotation matrix
|
// Returns a quaternion from a given rotation matrix
|
||||||
|
@ -947,42 +969,42 @@ Matrix QuaternionToMatrix(Quaternion q)
|
||||||
{
|
{
|
||||||
Matrix result;
|
Matrix result;
|
||||||
|
|
||||||
float x = q.x, y = q.y, z = q.z, w = q.w;
|
float x = q.x, y = q.y, z = q.z, w = q.w;
|
||||||
|
|
||||||
float x2 = x + x;
|
float x2 = x + x;
|
||||||
float y2 = y + y;
|
float y2 = y + y;
|
||||||
float z2 = z + z;
|
float z2 = z + z;
|
||||||
|
|
||||||
float xx = x*x2;
|
float xx = x*x2;
|
||||||
float xy = x*y2;
|
float xy = x*y2;
|
||||||
float xz = x*z2;
|
float xz = x*z2;
|
||||||
|
|
||||||
float yy = y*y2;
|
float yy = y*y2;
|
||||||
float yz = y*z2;
|
float yz = y*z2;
|
||||||
float zz = z*z2;
|
float zz = z*z2;
|
||||||
|
|
||||||
float wx = w*x2;
|
float wx = w*x2;
|
||||||
float wy = w*y2;
|
float wy = w*y2;
|
||||||
float wz = w*z2;
|
float wz = w*z2;
|
||||||
|
|
||||||
result.m0 = 1 - (yy + zz);
|
result.m0 = 1 - (yy + zz);
|
||||||
result.m1 = xy - wz;
|
result.m1 = xy - wz;
|
||||||
result.m2 = xz + wy;
|
result.m2 = xz + wy;
|
||||||
result.m3 = 0;
|
result.m3 = 0;
|
||||||
result.m4 = xy + wz;
|
result.m4 = xy + wz;
|
||||||
result.m5 = 1 - (xx + zz);
|
result.m5 = 1 - (xx + zz);
|
||||||
result.m6 = yz - wx;
|
result.m6 = yz - wx;
|
||||||
result.m7 = 0;
|
result.m7 = 0;
|
||||||
result.m8 = xz - wy;
|
result.m8 = xz - wy;
|
||||||
result.m9 = yz + wx;
|
result.m9 = yz + wx;
|
||||||
result.m10 = 1 - (xx + yy);
|
result.m10 = 1 - (xx + yy);
|
||||||
result.m11 = 0;
|
result.m11 = 0;
|
||||||
result.m12 = 0;
|
result.m12 = 0;
|
||||||
result.m13 = 0;
|
result.m13 = 0;
|
||||||
result.m14 = 0;
|
result.m14 = 0;
|
||||||
result.m15 = 1;
|
result.m15 = 1;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the axis and the angle for a given quaternion
|
// Returns the axis and the angle for a given quaternion
|
||||||
|
|
|
@ -91,6 +91,8 @@ void VectorNormalize(Vector3 *v); // Normalize provided ve
|
||||||
float VectorDistance(Vector3 v1, Vector3 v2); // Calculate distance between two points
|
float VectorDistance(Vector3 v1, Vector3 v2); // Calculate distance between two points
|
||||||
Vector3 VectorLerp(Vector3 v1, Vector3 v2, float amount); // Calculate linear interpolation between two vectors
|
Vector3 VectorLerp(Vector3 v1, Vector3 v2, float amount); // Calculate linear interpolation between two vectors
|
||||||
Vector3 VectorReflect(Vector3 vector, Vector3 normal); // Calculate reflected vector to normal
|
Vector3 VectorReflect(Vector3 vector, Vector3 normal); // Calculate reflected vector to normal
|
||||||
|
void VectorTransform(Vector3 *v, Matrix mat); // Transforms a Vector3 with a given Matrix
|
||||||
|
Vector3 VectorZero(); // Return a Vector3 init to zero
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Functions Declaration to work with Matrix
|
// Functions Declaration to work with Matrix
|
||||||
|
|
1364
src/rlgl.c
Normal file
1364
src/rlgl.c
Normal file
File diff suppressed because it is too large
Load diff
117
src/rlgl.h
Normal file
117
src/rlgl.h
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
/*********************************************************************************************
|
||||||
|
*
|
||||||
|
* rlgl - raylib OpenGL abstraction layer
|
||||||
|
*
|
||||||
|
* raylib now uses OpenGL 1.1 style functions (rlVertex) that are mapped to selected OpenGL version:
|
||||||
|
* OpenGL 1.1 - Direct map rl* -> gl*
|
||||||
|
* OpenGL 3.3+ - Vertex data is stored in VAOs, call rlglDraw() to render
|
||||||
|
* OpenGL ES 2 - Same behaviour as OpenGL 3.3+ (NOT TESTED)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||||
|
*
|
||||||
|
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||||
|
* will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||||
|
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||||
|
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||||
|
* in the product documentation would be appreciated but is not required.
|
||||||
|
*
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||||
|
* as being the original software.
|
||||||
|
*
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*
|
||||||
|
**********************************************************************************************/
|
||||||
|
|
||||||
|
#ifndef RLGL_H
|
||||||
|
#define RLGL_H
|
||||||
|
|
||||||
|
// Select desired OpenGL version
|
||||||
|
//#define USE_OPENGL_11
|
||||||
|
#define USE_OPENGL_33
|
||||||
|
//#define USE_OPENGL_ES2
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Defines and Macros
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#define MAX_LINES_BATCH 1024
|
||||||
|
#define MAX_TRIANGLES_BATCH 2048
|
||||||
|
#define MAX_QUADS_BATCH 8192
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
typedef unsigned char byte;
|
||||||
|
|
||||||
|
typedef enum { RL_PROJECTION, RL_MODELVIEW, RL_TEXTURE } MatrixMode;
|
||||||
|
|
||||||
|
typedef enum { RL_LINES, RL_TRIANGLES, RL_QUADS } DrawMode;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" { // Prevents name mangling of functions
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Functions Declaration - Matrix operations
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
void rlMatrixMode(int mode); // Choose the current matrix to be transformed
|
||||||
|
void rlPushMatrix(); // TODO: REVIEW: Required? - Push the current matrix to stack
|
||||||
|
void rlPopMatrix(); // TODO: REVIEW: Required? - Pop lattest inserted matrix from stack
|
||||||
|
void rlLoadIdentity(); // Reset current matrix to identity matrix
|
||||||
|
void rlTranslatef(float x, float y, float z); // Multiply the current matrix by a translation matrix
|
||||||
|
void rlRotatef(float angleDeg, float x, float y, float z); // Multiply the current matrix by a rotation matrix
|
||||||
|
void rlScalef(float x, float y, float z); // Multiply the current matrix by a scaling matrix
|
||||||
|
void rlMultMatrixf(float *mat); // Multiply the current matrix by another matrix
|
||||||
|
void rlFrustum(double left, double right, double bottom, double top, double near, double far);
|
||||||
|
void rlOrtho(double left, double right, double bottom, double top, double near, double far);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Functions Declaration - Vertex level operations
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
void rlBegin(int mode); // Initialize drawing mode (how to organize vertex)
|
||||||
|
void rlEnd(); // Finish vertex providing
|
||||||
|
void rlVertex2i(int x, int y); // Define one vertex (position) - 2 int
|
||||||
|
void rlVertex2f(float x, float y); // Define one vertex (position) - 2 float
|
||||||
|
void rlVertex3f(float x, float y, float z); // Define one vertex (position) - 3 float
|
||||||
|
void rlTexCoord2f(float x, float y); // Define one vertex (texture coordinate) - 2 float
|
||||||
|
void rlNormal3f(float x, float y, float z); // Define one vertex (normal) - 3 float
|
||||||
|
void rlColor4ub(byte r, byte g, byte b, byte a); // Define one vertex (color) - 4 byte
|
||||||
|
void rlColor3f(float x, float y, float z); // Define one vertex (color) - 3 float
|
||||||
|
void rlColor4f(float x, float y, float z, float w); // Define one vertex (color) - 4 float
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Functions Declaration - OpenGL equivalent functions (common to 1.1, 3.3+, ES2)
|
||||||
|
// NOTE: This functions are used to completely abstract raylib code from OpenGL layer
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
void rlEnableTexture(unsigned int id); // Enable texture usage
|
||||||
|
void rlDisableTexture(); // Disable texture usage
|
||||||
|
void rlDeleteTextures(unsigned int id); // Delete OpenGL texture
|
||||||
|
void rlClearColor(byte r, byte g, byte b, byte a); // Clear color buffer with color
|
||||||
|
void rlClearScreenBuffers(); // Clear used screen buffers (color and depth)
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Functions Declaration - rlgl functionality
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
#ifdef USE_OPENGL_33
|
||||||
|
void rlglInit(); // Initialize rlgl (shaders, VAO, VBO...)
|
||||||
|
void rlglClose(); // De-init rlgl
|
||||||
|
void rlglDraw(); // Draw VAOs
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void rlglInitGraphicsDevice(int fbWidth, int fbHeight); // Initialize Graphics Device (OpenGL stuff)
|
||||||
|
unsigned int rlglTexture(int width, int height, unsigned char *pixels); // Create OpenGL texture
|
||||||
|
byte *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
|
||||||
|
|
||||||
|
#ifdef USE_OPENGL_33
|
||||||
|
void PrintProjectionMatrix(); // DEBUG: Print projection matrix
|
||||||
|
void PrintModelviewMatrix(); // DEBUG: Print modelview matrix
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // RLGL_H
|
305
src/shapes.c
305
src/shapes.c
|
@ -25,10 +25,11 @@
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
#include <GL/gl.h> // OpenGL functions
|
|
||||||
#include <stdlib.h> // Required for abs() function
|
#include <stdlib.h> // Required for abs() function
|
||||||
#include <math.h> // Math related functions, sin() and cos() used on DrawCircle*
|
#include <math.h> // Math related functions, sin() and cos() used on DrawCircle*
|
||||||
// sqrt() and pow() and abs() used on CheckCollision*
|
// sqrt() and pow() and abs() used on CheckCollision*
|
||||||
|
|
||||||
|
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Defines and Macros
|
// Defines and Macros
|
||||||
|
@ -57,149 +58,116 @@
|
||||||
// Draw a pixel
|
// Draw a pixel
|
||||||
void DrawPixel(int posX, int posY, Color color)
|
void DrawPixel(int posX, int posY, Color color)
|
||||||
{
|
{
|
||||||
glBegin(GL_POINTS);
|
rlBegin(RL_LINES);
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
glVertex2i(posX, posY);
|
rlVertex2i(posX, posY);
|
||||||
glEnd();
|
rlVertex2i(posX + 1, posY + 1);
|
||||||
|
rlEnd();
|
||||||
// NOTE1: Alternative method to draw a pixel (GL_LINES)
|
|
||||||
/*
|
|
||||||
glBegin(GL_LINES);
|
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
|
||||||
glVertex2i(posX, posY);
|
|
||||||
glVertex2i(posX+1, posY+1);
|
|
||||||
glEnd();
|
|
||||||
*/
|
|
||||||
// NOTE2: Alternative method to draw a pixel (glPoint())
|
|
||||||
/*
|
|
||||||
glEnable(GL_POINT_SMOOTH);
|
|
||||||
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); // Deprecated on OGL 3.0
|
|
||||||
|
|
||||||
glPointSize(1.0f);
|
|
||||||
glPoint((float)posX, (float)posY, 0.0f);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a pixel (Vector version)
|
// Draw a pixel (Vector version)
|
||||||
void DrawPixelV(Vector2 position, Color color)
|
void DrawPixelV(Vector2 position, Color color)
|
||||||
{
|
{
|
||||||
glBegin(GL_POINTS);
|
rlBegin(RL_LINES);
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
glVertex2f(position.x, position.y);
|
rlVertex2f(position.x, position.y);
|
||||||
glEnd();
|
rlVertex2i(position.x + 1, position.y + 1);
|
||||||
|
rlEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a line
|
// Draw a line
|
||||||
void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color)
|
void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color)
|
||||||
{
|
{
|
||||||
glBegin(GL_LINES);
|
rlBegin(RL_LINES);
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
glVertex2i(startPosX, startPosY);
|
rlVertex2i(startPosX, startPosY);
|
||||||
glVertex2i(endPosX, endPosY);
|
rlVertex2i(endPosX, endPosY);
|
||||||
glEnd();
|
rlEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a line (Vector version)
|
// Draw a line (Vector version)
|
||||||
void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
|
void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
|
||||||
{
|
{
|
||||||
glBegin(GL_LINES);
|
rlBegin(RL_LINES);
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
glVertex2f(startPos.x, startPos.y);
|
rlVertex2f(startPos.x, startPos.y);
|
||||||
glVertex2f(endPos.x, endPos.y);
|
rlVertex2f(endPos.x, endPos.y);
|
||||||
glEnd();
|
rlEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a color-filled circle
|
// Draw a color-filled circle
|
||||||
// TODO: Review, on some GPUs is drawn with a weird transparency (GL_POLYGON_SMOOTH issue?)
|
// TODO: Review, on some GPUs is drawn with a weird transparency (GL_POLYGON_SMOOTH issue?)
|
||||||
void DrawCircle(int centerX, int centerY, float radius, Color color)
|
void DrawCircle(int centerX, int centerY, float radius, Color color)
|
||||||
{
|
{
|
||||||
glEnable(GL_POLYGON_SMOOTH);
|
|
||||||
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); // Deprecated on OGL 3.0
|
|
||||||
|
|
||||||
DrawPoly((Vector2){centerX, centerY}, 360, radius, 0, color);
|
DrawPoly((Vector2){centerX, centerY}, 360, radius, 0, color);
|
||||||
|
|
||||||
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);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a gradient-filled circle
|
// Draw a gradient-filled circle
|
||||||
// NOTE: Gradient goes from center (color1) to border (color2)
|
// NOTE: Gradient goes from center (color1) to border (color2)
|
||||||
void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2)
|
void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2)
|
||||||
{
|
{
|
||||||
glBegin(GL_TRIANGLE_FAN);
|
rlBegin(RL_TRIANGLES);
|
||||||
glColor4ub(color1.r, color1.g, color1.b, color1.a);
|
for (int i=0; i <= 360; i += 2) //i++ --> Step = 1.0 pixels
|
||||||
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);
|
rlColor4ub(color1.r, color1.g, color1.b, color1.a);
|
||||||
|
rlVertex2i(centerX, centerY);
|
||||||
|
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
|
||||||
|
rlVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius);
|
||||||
|
rlVertex2f(centerX + sin(DEG2RAD*(i+1)) * radius, centerY + cos(DEG2RAD*(i+1)) * radius);
|
||||||
}
|
}
|
||||||
glEnd();
|
rlEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a color-filled circle (Vector version)
|
// Draw a color-filled circle (Vector version)
|
||||||
void DrawCircleV(Vector2 center, float radius, Color color)
|
void DrawCircleV(Vector2 center, float radius, Color color)
|
||||||
{
|
{
|
||||||
glEnable(GL_POLYGON_SMOOTH);
|
rlBegin(RL_TRIANGLES);
|
||||||
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
|
for (int i=0; i < 360; i += 2)
|
||||||
|
|
||||||
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);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
|
rlVertex2i(center.x, center.y);
|
||||||
|
rlVertex2f(center.x + sin(DEG2RAD*i) * radius, center.y + cos(DEG2RAD*i) * radius);
|
||||||
|
rlVertex2f(center.x + sin(DEG2RAD*(i+1)) * radius, center.y + cos(DEG2RAD*(i+1)) * radius);
|
||||||
}
|
}
|
||||||
glEnd();
|
rlEnd();
|
||||||
|
|
||||||
glDisable(GL_POLYGON_SMOOTH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw circle outline
|
// Draw circle outline
|
||||||
void DrawCircleLines(int centerX, int centerY, float radius, Color color)
|
void DrawCircleLines(int centerX, int centerY, float radius, Color color)
|
||||||
{
|
{
|
||||||
glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
|
//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)
|
//glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
|
||||||
|
|
||||||
glBegin(GL_LINE_LOOP);
|
rlBegin(RL_LINES);
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
|
|
||||||
// NOTE: Circle outline is drawn pixel by pixel every degree (0 to 360)
|
// NOTE: Circle outline is drawn pixel by pixel every degree (0 to 360)
|
||||||
for (int i=0; i < 360; i++)
|
for (int i=0; i < 360; i++)
|
||||||
{
|
{
|
||||||
glVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius);
|
rlVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius);
|
||||||
|
rlVertex2f(centerX + sin(DEG2RAD*(i+1)) * radius, centerY + cos(DEG2RAD*(i+1)) * radius);
|
||||||
}
|
}
|
||||||
glEnd();
|
rlEnd();
|
||||||
|
|
||||||
// NOTE: Alternative method to draw circle outline
|
//glDisable(GL_LINE_SMOOTH);
|
||||||
/*
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
// TODO: Draw all lines with line smooth??? --> Do it before drawing lines VAO
|
||||||
DrawCircle(centerX, centerY, radius, color);
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
||||||
*/
|
|
||||||
glDisable(GL_LINE_SMOOTH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a color-filled rectangle
|
// Draw a color-filled rectangle
|
||||||
void DrawRectangle(int posX, int posY, int width, int height, Color color)
|
void DrawRectangle(int posX, int posY, int width, int height, Color color)
|
||||||
{
|
{
|
||||||
glBegin(GL_QUADS);
|
rlBegin(RL_QUADS);
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
glVertex2i(posX, posY);
|
rlTexCoord2f(0.0f, 0.0f);
|
||||||
glVertex2i(posX + width, posY);
|
rlVertex2i(posX, posY);
|
||||||
glVertex2i(posX + width, posY + height);
|
rlTexCoord2f(0.0f, 1.0f);
|
||||||
glVertex2i(posX, posY + height);
|
rlVertex2i(posX, posY + height);
|
||||||
glEnd();
|
rlTexCoord2f(1.0f, 1.0f);
|
||||||
|
rlVertex2i(posX + width, posY + height);
|
||||||
|
rlTexCoord2f(1.0f, 0.0f);
|
||||||
|
rlVertex2i(posX + width, posY);
|
||||||
|
rlEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a color-filled rectangle
|
// Draw a color-filled rectangle
|
||||||
|
@ -212,73 +180,73 @@ void DrawRectangleRec(Rectangle rec, Color color)
|
||||||
// NOTE: Gradient goes from bottom (color1) to top (color2)
|
// NOTE: Gradient goes from bottom (color1) to top (color2)
|
||||||
void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2)
|
void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2)
|
||||||
{
|
{
|
||||||
glBegin(GL_QUADS);
|
rlBegin(RL_QUADS);
|
||||||
glColor4ub(color1.r, color1.g, color1.b, color1.a);
|
rlColor4ub(color1.r, color1.g, color1.b, color1.a);
|
||||||
glVertex2i(posX, posY);
|
rlVertex2i(posX, posY);
|
||||||
glVertex2i(posX + width, posY);
|
rlColor4ub(color1.r, color1.g, color1.b, color1.a);
|
||||||
glColor4ub(color2.r, color2.g, color2.b, color2.a);
|
rlVertex2i(posX, posY + height);
|
||||||
glVertex2i(posX + width, posY + height);
|
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
|
||||||
glVertex2i(posX, posY + height);
|
rlVertex2i(posX + width, posY + height);
|
||||||
glEnd();
|
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
|
||||||
|
rlVertex2i(posX + width, posY);
|
||||||
|
rlEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a color-filled rectangle (Vector version)
|
// Draw a color-filled rectangle (Vector version)
|
||||||
void DrawRectangleV(Vector2 position, Vector2 size, Color color)
|
void DrawRectangleV(Vector2 position, Vector2 size, Color color)
|
||||||
{
|
{
|
||||||
glBegin(GL_QUADS);
|
rlBegin(RL_QUADS);
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
glVertex2i(position.x, position.y);
|
rlVertex2i(position.x, position.y);
|
||||||
glVertex2i(position.x + size.x, position.y);
|
rlVertex2i(position.x, position.y + size.y);
|
||||||
glVertex2i(position.x + size.x, position.y + size.y);
|
rlVertex2i(position.x + size.x, position.y + size.y);
|
||||||
glVertex2i(position.x, position.y + size.y);
|
rlVertex2i(position.x + size.x, position.y);
|
||||||
glEnd();
|
rlEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw rectangle outline
|
// Draw rectangle outline
|
||||||
void DrawRectangleLines(int posX, int posY, int width, int height, Color color)
|
void DrawRectangleLines(int posX, int posY, int width, int height, Color color)
|
||||||
{
|
{
|
||||||
//glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
|
rlBegin(RL_LINES);
|
||||||
//glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
|
rlVertex2i(posX, posY);
|
||||||
// NOTE: Lines are rasterized using the "Diamond Exit" rule so, it's nearly impossible to obtain a pixel-perfect engine
|
rlVertex2i(posX + width - 1, posY);
|
||||||
// NOTE: Recommended trying to avoid using lines, at least >1.0f pixel lines with anti-aliasing (glLineWidth function)
|
|
||||||
|
rlVertex2i(posX + width - 1, posY);
|
||||||
glBegin(GL_LINE_LOOP);
|
rlVertex2i(posX + width - 1, posY + height - 1);
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
|
||||||
glVertex2i(posX, posY);
|
rlVertex2i(posX + width - 1, posY + height - 1);
|
||||||
glVertex2i(posX + width - 1, posY);
|
rlVertex2i(posX, posY + height - 1);
|
||||||
glVertex2i(posX + width - 1, posY + height - 1);
|
|
||||||
glVertex2i(posX, posY + height - 1);
|
rlVertex2i(posX, posY + height - 1);
|
||||||
glEnd();
|
rlVertex2i(posX, posY);
|
||||||
|
rlEnd();
|
||||||
// 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);
|
|
||||||
*/
|
|
||||||
//glDisable(GL_LINE_SMOOTH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a triangle
|
// Draw a triangle
|
||||||
void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
|
void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
|
||||||
{
|
{
|
||||||
glBegin(GL_TRIANGLES);
|
rlBegin(RL_TRIANGLES);
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
glVertex2f(v1.x, v1.y);
|
rlVertex2f(v1.x, v1.y);
|
||||||
glVertex2f(v2.x, v2.y);
|
rlVertex2f(v2.x, v2.y);
|
||||||
glVertex2f(v3.x, v3.y);
|
rlVertex2f(v3.x, v3.y);
|
||||||
glEnd();
|
rlEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
|
void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
|
||||||
{
|
{
|
||||||
glBegin(GL_LINE_LOOP);
|
rlBegin(RL_LINES);
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
glVertex2f(v1.x, v1.y);
|
rlVertex2f(v1.x, v1.y);
|
||||||
glVertex2f(v2.x, v2.y);
|
rlVertex2f(v2.x, v2.y);
|
||||||
glVertex2f(v3.x, v3.y);
|
|
||||||
glEnd();
|
rlVertex2f(v2.x, v2.y);
|
||||||
|
rlVertex2f(v3.x, v3.y);
|
||||||
|
|
||||||
|
rlVertex2f(v3.x, v3.y);
|
||||||
|
rlVertex2f(v1.x, v1.y);
|
||||||
|
rlEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a regular polygon of n sides (Vector version)
|
// Draw a regular polygon of n sides (Vector version)
|
||||||
|
@ -286,20 +254,20 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col
|
||||||
{
|
{
|
||||||
if (sides < 3) sides = 3;
|
if (sides < 3) sides = 3;
|
||||||
|
|
||||||
glPushMatrix();
|
rlPushMatrix();
|
||||||
glTranslatef(center.x, center.y, 0);
|
|
||||||
glRotatef(rotation, 0, 0, 1);
|
|
||||||
|
|
||||||
glBegin(GL_TRIANGLE_FAN);
|
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
|
||||||
glVertex2f(0, 0);
|
|
||||||
|
|
||||||
for (int i=0; i <= sides; i++)
|
rlRotatef(rotation, 0, 0, 1); // TODO: compute vertex rotation manually!
|
||||||
{
|
|
||||||
glVertex2f(radius*cos(i*2*PI/sides), radius*sin(i*2*PI/sides));
|
rlBegin(RL_TRIANGLES);
|
||||||
|
for (int i=0; i < 360; i += 2)
|
||||||
|
{
|
||||||
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
|
rlVertex2i(center.x, center.y);
|
||||||
|
rlVertex2f(center.x + sin(DEG2RAD*i) * radius, center.y + cos(DEG2RAD*i) * radius);
|
||||||
|
rlVertex2f(center.x + sin(DEG2RAD*(i+1)) * radius, center.y + cos(DEG2RAD*(i+1)) * radius);
|
||||||
}
|
}
|
||||||
glEnd();
|
rlEnd();
|
||||||
glPopMatrix();
|
rlPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a closed polygon defined by points
|
// Draw a closed polygon defined by points
|
||||||
|
@ -308,19 +276,16 @@ void DrawPolyEx(Vector2 *points, int numPoints, Color color)
|
||||||
{
|
{
|
||||||
if (numPoints >= 3)
|
if (numPoints >= 3)
|
||||||
{
|
{
|
||||||
glEnable(GL_POLYGON_SMOOTH);
|
rlBegin(RL_TRIANGLES);
|
||||||
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
|
|
||||||
glBegin(GL_POLYGON);
|
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
|
||||||
|
|
||||||
for (int i = 0; i < numPoints; i++)
|
for (int i = 0; i < numPoints - 2; i++)
|
||||||
{
|
{
|
||||||
glVertex2f(points[i].x, points[i].y);
|
rlVertex2f(points[i].x, points[i].y);
|
||||||
|
rlVertex2f(points[i+1].x, points[i+1].y);
|
||||||
|
rlVertex2f(points[i+2].x, points[i+2].y);
|
||||||
}
|
}
|
||||||
glEnd();
|
rlEnd();
|
||||||
|
|
||||||
glDisable(GL_POLYGON_SMOOTH);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,22 +295,22 @@ void DrawPolyExLines(Vector2 *points, int numPoints, Color color)
|
||||||
{
|
{
|
||||||
if (numPoints >= 2)
|
if (numPoints >= 2)
|
||||||
{
|
{
|
||||||
//glEnable(GL_LINE_SMOOTH); // Smoothies circle outline (anti-aliasing applied)
|
rlBegin(RL_LINES);
|
||||||
//glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Best quality for line smooth (anti-aliasing best algorithm)
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
|
|
||||||
glBegin(GL_LINE_LOOP);
|
|
||||||
glColor4ub(color.r, color.g, color.b, color.a);
|
|
||||||
|
|
||||||
for (int i = 0; i < numPoints; i++)
|
for (int i = 0; i < numPoints - 1; i++)
|
||||||
{
|
{
|
||||||
glVertex2f(points[i].x, points[i].y);
|
rlVertex2f(points[i].x, points[i].y);
|
||||||
|
rlVertex2f(points[i+1].x, points[i+1].y);
|
||||||
}
|
}
|
||||||
glEnd();
|
rlEnd();
|
||||||
|
|
||||||
//glDisable(GL_LINE_SMOOTH);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition - Collision Detection functions
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Check if point is inside rectangle
|
// Check if point is inside rectangle
|
||||||
bool CheckCollisionPointRec(Vector2 point, Rectangle rec)
|
bool CheckCollisionPointRec(Vector2 point, Rectangle rec)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,5 +11,4 @@ void main()
|
||||||
{
|
{
|
||||||
// Output pixel color
|
// Output pixel color
|
||||||
pixelColor = texture(texture0, fragTexCoord) * fragColor;
|
pixelColor = texture(texture0, fragTexCoord) * fragColor;
|
||||||
//pixelColor = fragColor;
|
|
||||||
}
|
}
|
154
src/text.c
154
src/text.c
|
@ -28,12 +28,13 @@
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
#include <GL/gl.h> // OpenGL functions
|
|
||||||
#include <stdlib.h> // Declares malloc() and free() for memory management
|
#include <stdlib.h> // Declares malloc() and free() for memory management
|
||||||
#include <string.h> // String management functions (just strlen() is used)
|
#include <string.h> // String management functions (just strlen() is used)
|
||||||
#include <stdarg.h> // Used for functions with variable number of parameters (FormatText())
|
#include <stdarg.h> // Used for functions with variable number of parameters (FormatText())
|
||||||
#include "stb_image.h" // Used to read image data (multiple formats support)
|
#include "stb_image.h" // Used to read image data (multiple formats support)
|
||||||
|
|
||||||
|
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Defines and Macros
|
// Defines and Macros
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -63,6 +64,11 @@ struct Character {
|
||||||
static SpriteFont defaultFont; // Default font provided by raylib
|
static SpriteFont defaultFont; // Default font provided by raylib
|
||||||
// NOTE: defaultFont is loaded on InitWindow and disposed on CloseWindow [module: core]
|
// NOTE: defaultFont is loaded on InitWindow and disposed on CloseWindow [module: core]
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Other Modules Functions Declaration (required by text)
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
//...
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Declaration
|
// Module specific Functions Declaration
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -78,9 +84,11 @@ static const char *GetExtension(const char *fileName);
|
||||||
extern void LoadDefaultFont()
|
extern void LoadDefaultFont()
|
||||||
{
|
{
|
||||||
defaultFont.numChars = 96; // We know our default font has 94 chars
|
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
|
Image image;
|
||||||
|
image.width = 128; // We know our default font image is 128 pixels width
|
||||||
|
image.height = 64; // We know our default font image is 64 pixels height
|
||||||
|
|
||||||
// Default font is directly defined here (data generated from a sprite font image)
|
// Default font is directly defined here (data generated from a sprite font image)
|
||||||
// This way, we reconstruct SpriteFont without creating large global variables
|
// 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
|
// This data is automatically allocated to Stack and automatically deallocated at the end of this function
|
||||||
|
@ -115,7 +123,31 @@ extern void LoadDefaultFont()
|
||||||
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,
|
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 };
|
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 };
|
||||||
|
|
||||||
|
// Re-construct image from defaultFontData and generate OpenGL texture
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
image.pixels = (Color *)malloc(image.width * image.height * sizeof(Color));
|
||||||
|
|
||||||
|
for (int i = 0; i < image.width * image.height; i++) image.pixels[i] = BLANK; // Initialize array
|
||||||
|
|
||||||
|
int counter = 0; // Font data elements counter
|
||||||
|
|
||||||
|
// Fill imgData with defaultFontData (convert from bit to pixel!)
|
||||||
|
for (int i = 0; i < image.width * image.height; i += 32)
|
||||||
|
{
|
||||||
|
for (int j = 31; j >= 0; j--)
|
||||||
|
{
|
||||||
|
if (BIT_CHECK(defaultFontData[counter], j)) image.pixels[i+j] = WHITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
|
||||||
|
if (counter > 256) counter = 0; // Security check...
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultFont.texture = CreateTexture(image); // Convert loaded image to OpenGL texture
|
||||||
|
|
||||||
|
UnloadImage(image);
|
||||||
|
|
||||||
// Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, numChars
|
// Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, numChars
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
defaultFont.charSet = (Character *)malloc(defaultFont.numChars * sizeof(Character)); // Allocate space for our character data
|
defaultFont.charSet = (Character *)malloc(defaultFont.numChars * sizeof(Character)); // Allocate space for our character data
|
||||||
|
@ -145,53 +177,11 @@ extern void LoadDefaultFont()
|
||||||
}
|
}
|
||||||
else currentPosX = testPosX;
|
else currentPosX = testPosX;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-construct image from defaultFontData and generate OpenGL texture
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
Color *imgDataPixel = (Color *)malloc(defaultFont.texture.width * defaultFont.texture.height * sizeof(Color));
|
|
||||||
|
|
||||||
for (int i = 0; i < defaultFont.texture.width * defaultFont.texture.height; i++) imgDataPixel[i] = BLANK; // Initialize array
|
|
||||||
|
|
||||||
int counter = 0; // Font data elements counter
|
|
||||||
|
|
||||||
// Fill imgData with defaultFontData (convert from bit to pixel!)
|
|
||||||
for (int i = 0; i < defaultFont.texture.width * defaultFont.texture.height; i += 32)
|
|
||||||
{
|
|
||||||
for (int j = 31; j >= 0; j--)
|
|
||||||
{
|
|
||||||
if (BIT_CHECK(defaultFontData[counter], j)) imgDataPixel[i+j] = WHITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
counter++;
|
|
||||||
|
|
||||||
if (counter > 256) counter = 0; // Security check...
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert loaded data to OpenGL texture
|
|
||||||
//----------------------------------------
|
|
||||||
GLuint id;
|
|
||||||
glGenTextures(1, &id); // Generate pointer to the texture
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); // Set texture to clamp on x-axis
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); // Set texture to clamp on y-axis
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
|
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, defaultFont.texture.width, defaultFont.texture.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgDataPixel);
|
|
||||||
|
|
||||||
// NOTE: Not using mipmappings (texture for 2D drawing)
|
|
||||||
// At this point we have the image converted to texture and uploaded to GPU
|
|
||||||
|
|
||||||
free(imgDataPixel); // Now we can free loaded data from RAM memory
|
|
||||||
|
|
||||||
defaultFont.texture.glId = id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void UnloadDefaultFont()
|
extern void UnloadDefaultFont()
|
||||||
{
|
{
|
||||||
glDeleteTextures(1, &defaultFont.texture.glId);
|
rlDeleteTextures(defaultFont.texture.glId);
|
||||||
free(defaultFont.charSet);
|
free(defaultFont.charSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,6 +196,8 @@ SpriteFont LoadSpriteFont(const char* fileName)
|
||||||
{
|
{
|
||||||
SpriteFont spriteFont;
|
SpriteFont spriteFont;
|
||||||
|
|
||||||
|
Image image;
|
||||||
|
|
||||||
// Check file extension
|
// Check file extension
|
||||||
if (strcmp(GetExtension(fileName),"rbmf") == 0) spriteFont = LoadRBMF(fileName);
|
if (strcmp(GetExtension(fileName),"rbmf") == 0) spriteFont = LoadRBMF(fileName);
|
||||||
else
|
else
|
||||||
|
@ -270,24 +262,13 @@ SpriteFont LoadSpriteFont(const char* fileName)
|
||||||
|
|
||||||
free(imgDataPixel);
|
free(imgDataPixel);
|
||||||
|
|
||||||
// Convert loaded data to OpenGL texture
|
image.pixels = imgDataPixelPOT;
|
||||||
//----------------------------------------
|
image.width = potWidth;
|
||||||
GLuint id;
|
image.height = potHeight;
|
||||||
glGenTextures(1, &id); // Generate pointer to the texture
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
spriteFont.texture = CreateTexture(image); // Convert loaded image to OpenGL texture
|
||||||
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
|
UnloadImage(image);
|
||||||
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;
|
return spriteFont;
|
||||||
|
@ -296,7 +277,7 @@ SpriteFont LoadSpriteFont(const char* fileName)
|
||||||
// Unload SpriteFont from GPU memory
|
// Unload SpriteFont from GPU memory
|
||||||
void UnloadSpriteFont(SpriteFont spriteFont)
|
void UnloadSpriteFont(SpriteFont spriteFont)
|
||||||
{
|
{
|
||||||
glDeleteTextures(1, &spriteFont.texture.glId);
|
rlDeleteTextures(spriteFont.texture.glId);
|
||||||
free(spriteFont.charSet);
|
free(spriteFont.charSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,28 +311,34 @@ void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int f
|
||||||
if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
|
if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
|
||||||
else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
|
else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
rlEnableTexture(spriteFont.texture.glId);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, spriteFont.texture.glId);
|
|
||||||
|
|
||||||
// Optimized to use one draw call per string
|
// Optimized to use one draw call per string
|
||||||
glBegin(GL_QUADS);
|
rlBegin(RL_QUADS);
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
c = spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR];
|
c = spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR];
|
||||||
|
|
||||||
glColor4ub(tint.r, tint.g, tint.b, tint.a);
|
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
|
||||||
glNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
|
rlNormal3f(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);
|
rlTexCoord2f((float)c.x / spriteFont.texture.width, (float)c.y / spriteFont.texture.height);
|
||||||
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);
|
rlVertex2f(positionX, position.y);
|
||||||
glTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)c.y / spriteFont.texture.height); glVertex2f(positionX + (c.w) * scaleFactor, position.y);
|
|
||||||
|
rlTexCoord2f((float)c.x / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height);
|
||||||
|
rlVertex2f(positionX, position.y + (c.h) * scaleFactor);
|
||||||
|
|
||||||
|
rlTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height);
|
||||||
|
rlVertex2f(positionX + (c.w) * scaleFactor, position.y + (c.h) * scaleFactor);
|
||||||
|
|
||||||
|
rlTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)c.y / spriteFont.texture.height);
|
||||||
|
rlVertex2f(positionX + (c.w) * scaleFactor, position.y);
|
||||||
|
|
||||||
positionX += ((spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR].w) * scaleFactor + spacing);
|
positionX += ((spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR].w) * scaleFactor + spacing);
|
||||||
}
|
}
|
||||||
glEnd();
|
rlEnd();
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
rlDisableTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Formatting of text with variables to 'embed'
|
// Formatting of text with variables to 'embed'
|
||||||
|
@ -417,21 +404,18 @@ void DrawFPS(int posX, int posY)
|
||||||
char buffer[20];
|
char buffer[20];
|
||||||
|
|
||||||
if (counter < refreshRate)
|
if (counter < refreshRate)
|
||||||
{
|
{
|
||||||
sprintf(buffer, "%2.0f FPS", fps);
|
|
||||||
DrawText(buffer, posX, posY, 20, LIME);
|
|
||||||
|
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fps = GetFPS();
|
fps = GetFPS();
|
||||||
refreshRate = fps;
|
refreshRate = fps;
|
||||||
sprintf(buffer, "%2.0f FPS", fps);
|
|
||||||
DrawText(buffer, posX, posY, 20, LIME);
|
|
||||||
|
|
||||||
counter = 0;
|
counter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sprintf(buffer, "%2.0f FPS", fps);
|
||||||
|
DrawText(buffer, posX, posY, 20, LIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
222
src/textures.c
222
src/textures.c
|
@ -28,12 +28,13 @@
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
#include <GL/gl.h> // OpenGL functions
|
|
||||||
#include <stdlib.h> // Declares malloc() and free() for memory management
|
#include <stdlib.h> // Declares malloc() and free() for memory management
|
||||||
#include "stb_image.h" // Used to read image data (multiple formats support)
|
#include "stb_image.h" // Used to read image data (multiple formats support)
|
||||||
|
|
||||||
#include "utils.h" // rRES data decompression utility function
|
#include "utils.h" // rRES data decompression utility function
|
||||||
|
|
||||||
|
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Defines and Macros
|
// Defines and Macros
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -49,6 +50,11 @@ typedef unsigned char byte;
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// It's lonely here...
|
// It's lonely here...
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Other Modules Functions Declaration (required by text)
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
//...
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Declaration
|
// Module specific Functions Declaration
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -238,43 +244,6 @@ Texture2D LoadTextureFromRES(const char *rresName, int resId)
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a Texture2D from Image data
|
|
||||||
// NOTE: Image is not unloaded, it should be done manually...
|
|
||||||
Texture2D CreateTexture(Image image)
|
|
||||||
{
|
|
||||||
Texture2D texture;
|
|
||||||
|
|
||||||
// Convert image data to OpenGL texture
|
|
||||||
//----------------------------------------
|
|
||||||
GLuint id;
|
|
||||||
glGenTextures(1, &id); // Generate Pointer to the Texture
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
|
||||||
|
|
||||||
// NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used!
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repead on x-axis
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repead on y-axis
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
|
|
||||||
|
|
||||||
// Trilinear filtering
|
|
||||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Activate use of mipmaps (must be available)
|
|
||||||
//glGenerateMipmap(GL_TEXTURE_2D); // OpenGL 3.3!
|
|
||||||
|
|
||||||
// Upload texture to GPU
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.pixels);
|
|
||||||
|
|
||||||
// NOTE: Not using mipmappings (texture for 2D drawing)
|
|
||||||
// At this point we have the image converted to texture and uploaded to GPU
|
|
||||||
|
|
||||||
texture.glId = id;
|
|
||||||
texture.width = image.width;
|
|
||||||
texture.height = image.height;
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unload image from CPU memory (RAM)
|
// Unload image from CPU memory (RAM)
|
||||||
void UnloadImage(Image image)
|
void UnloadImage(Image image)
|
||||||
{
|
{
|
||||||
|
@ -284,7 +253,7 @@ void UnloadImage(Image image)
|
||||||
// Unload texture from GPU memory
|
// Unload texture from GPU memory
|
||||||
void UnloadTexture(Texture2D texture)
|
void UnloadTexture(Texture2D texture)
|
||||||
{
|
{
|
||||||
glDeleteTextures(1, &texture.glId);
|
rlDeleteTextures(texture.glId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a Texture2D
|
// Draw a Texture2D
|
||||||
|
@ -302,101 +271,126 @@ void DrawTextureV(Texture2D texture, Vector2 position, Color tint)
|
||||||
// Draw a Texture2D with extended parameters
|
// Draw a Texture2D with extended parameters
|
||||||
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint)
|
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint)
|
||||||
{
|
{
|
||||||
glEnable(GL_TEXTURE_2D); // Enable textures usage
|
rlEnableTexture(texture.glId);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture.glId);
|
// TODO: Apply rotation to vertex! --> rotate from origin CW (0, 0)
|
||||||
|
// TODO: Compute vertex scaling!
|
||||||
|
|
||||||
glPushMatrix();
|
// NOTE: Rotation is applied before translation and scaling, even being called in inverse order...
|
||||||
// NOTE: Rotation is applied before translation and scaling, even being called in inverse order...
|
// NOTE: Rotation point is upper-left corner
|
||||||
// NOTE: Rotation point is upper-left corner
|
//rlTranslatef(position.x, position.y, 0);
|
||||||
glTranslatef(position.x, position.y, 0);
|
//rlScalef(scale, scale, 1.0f);
|
||||||
glScalef(scale, scale, 1.0f);
|
//rlRotatef(rotation, 0, 0, 1);
|
||||||
glRotatef(rotation, 0, 0, 1);
|
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
rlBegin(RL_QUADS);
|
||||||
glColor4ub(tint.r, tint.g, tint.b, tint.a);
|
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
|
||||||
glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
|
rlNormal3f(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
|
rlTexCoord2f(0.0f, 0.0f);
|
||||||
glTexCoord2f(1.0f, 1.0f); glVertex2f(texture.width, texture.height); // Top-right corner for texture and quad
|
rlVertex2f(position.x, position.y); // Bottom-left corner for texture and quad
|
||||||
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, texture.height); // Top-left corner for texture and quad
|
|
||||||
glEnd();
|
rlTexCoord2f(0.0f, 1.0f);
|
||||||
glPopMatrix();
|
rlVertex2f(position.x, position.y + texture.height); // Bottom-right corner for texture and quad
|
||||||
|
|
||||||
|
rlTexCoord2f(1.0f, 1.0f);
|
||||||
|
rlVertex2f(position.x + texture.width, position.y + texture.height); // Top-right corner for texture and quad
|
||||||
|
|
||||||
|
rlTexCoord2f(1.0f, 0.0f);
|
||||||
|
rlVertex2f(position.x + texture.width, position.y); // Top-left corner for texture and quad
|
||||||
|
rlEnd();
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D); // Disable textures usage
|
rlDisableTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a part of a texture (defined by a rectangle)
|
// Draw a part of a texture (defined by a rectangle)
|
||||||
void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint)
|
void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint)
|
||||||
{
|
{
|
||||||
glEnable(GL_TEXTURE_2D); // Enable textures usage
|
rlEnableTexture(texture.glId);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture.glId);
|
rlBegin(RL_QUADS);
|
||||||
|
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
|
||||||
glPushMatrix();
|
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
|
||||||
glTranslatef(position.x, position.y, 0);
|
|
||||||
//glScalef(1.0f, 1.0f, 1.0f);
|
|
||||||
//glRotatef(rotation, 0, 0, 1);
|
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
// Bottom-left corner for texture and quad
|
||||||
glColor4ub(tint.r, tint.g, tint.b, tint.a);
|
rlTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
|
||||||
glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
|
rlVertex2f(position.x, position.y);
|
||||||
|
|
||||||
// Bottom-left corner for texture and quad
|
// Bottom-right corner for texture and quad
|
||||||
glTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
|
rlTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
|
||||||
glVertex2f(0.0f, 0.0f);
|
rlVertex2f(position.x, position.y + sourceRec.height);
|
||||||
|
|
||||||
// Bottom-right corner for texture and quad
|
// Top-right corner for texture and quad
|
||||||
glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
|
rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
|
||||||
glVertex2f(sourceRec.width, 0.0f);
|
rlVertex2f(position.x + sourceRec.width, position.y + sourceRec.height);
|
||||||
|
|
||||||
// Top-right corner for texture and quad
|
// Top-left corner for texture and quad
|
||||||
glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
|
rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
|
||||||
glVertex2f(sourceRec.width, sourceRec.height);
|
rlVertex2f(position.x + sourceRec.width, position.y);
|
||||||
|
rlEnd();
|
||||||
// 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
|
rlDisableTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a part of a texture (defined by a rectangle) with 'pro' parameters
|
// Draw a part of a texture (defined by a rectangle) with 'pro' parameters
|
||||||
// TODO: Test this function...
|
// TODO: Test this function...
|
||||||
void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint)
|
void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint)
|
||||||
{
|
{
|
||||||
glEnable(GL_TEXTURE_2D); // Enable textures usage
|
rlEnableTexture(texture.glId);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture.glId);
|
// TODO: Apply translation, rotation and scaling of vertex manually!
|
||||||
|
|
||||||
glPushMatrix();
|
//rlTranslatef(-origin.x, -origin.y, 0);
|
||||||
glTranslatef(-origin.x, -origin.y, 0);
|
//rlRotatef(rotation, 0, 0, 1);
|
||||||
glRotatef(rotation, 0, 0, 1);
|
//rlTranslatef(destRec.x + origin.x, destRec.y + origin.y, 0);
|
||||||
glTranslatef(destRec.x + origin.x, destRec.y + origin.y, 0);
|
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
rlBegin(RL_QUADS);
|
||||||
glColor4ub(tint.r, tint.g, tint.b, tint.a);
|
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
|
||||||
glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
|
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
|
||||||
|
|
||||||
// Bottom-left corner for texture and quad
|
// Bottom-left corner for texture and quad
|
||||||
glTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
|
rlTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
|
||||||
glVertex2f(0.0f, 0.0f);
|
rlVertex2f(0.0f, 0.0f);
|
||||||
|
|
||||||
// Bottom-right corner for texture and quad
|
// Bottom-right corner for texture and quad
|
||||||
glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
|
rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
|
||||||
glVertex2f(destRec.width, 0.0f);
|
rlVertex2f(destRec.width, 0.0f);
|
||||||
|
|
||||||
// Top-right corner for texture and quad
|
// Top-right corner for texture and quad
|
||||||
glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
|
rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
|
||||||
glVertex2f(destRec.width, destRec.height);
|
rlVertex2f(destRec.width, destRec.height);
|
||||||
|
|
||||||
// Top-left corner for texture and quad
|
// Top-left corner for texture and quad
|
||||||
glTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
|
rlTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
|
||||||
glVertex2f(0.0f, destRec.height);
|
rlVertex2f(0.0f, destRec.height);
|
||||||
glEnd();
|
rlEnd();
|
||||||
glPopMatrix();
|
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D); // Disable textures usage
|
rlDisableTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture2D CreateTexture(Image image)
|
||||||
|
{
|
||||||
|
Texture2D texture;
|
||||||
|
|
||||||
|
unsigned char *img = malloc(image.width * image.height * 4);
|
||||||
|
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < image.width * image.height * 4; i += 4)
|
||||||
|
{
|
||||||
|
img[i] = image.pixels[j].r;
|
||||||
|
img[i+1] = image.pixels[j].g;
|
||||||
|
img[i+2] = image.pixels[j].b;
|
||||||
|
img[i+3] = image.pixels[j].a;
|
||||||
|
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture.glId = rlglTexture(image.width, image.height, img);
|
||||||
|
|
||||||
|
texture.width = image.width;
|
||||||
|
texture.height = image.height;
|
||||||
|
|
||||||
|
free(img);
|
||||||
|
|
||||||
|
return texture;
|
||||||
}
|
}
|
140
src/vector3.c
140
src/vector3.c
|
@ -1,140 +0,0 @@
|
||||||
/*********************************************************************************************
|
|
||||||
*
|
|
||||||
* raylib.vector3
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
|
||||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
|
||||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
|
||||||
* in the product documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
|
||||||
* as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
*
|
|
||||||
**********************************************************************************************/
|
|
||||||
|
|
||||||
#include "vector3.h"
|
|
||||||
|
|
||||||
#include <math.h> // Used for fabs(), sqrt()
|
|
||||||
|
|
||||||
// Add two vectors
|
|
||||||
Vector3 VectorAdd(Vector3 v1, Vector3 v2)
|
|
||||||
{
|
|
||||||
Vector3 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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scale provided vector
|
|
||||||
void VectorScale(Vector3 *v, float 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normalize provided vector
|
|
||||||
void VectorNormalize(Vector3 *v)
|
|
||||||
{
|
|
||||||
float length, ilength;
|
|
||||||
|
|
||||||
length = VectorLength(*v);
|
|
||||||
|
|
||||||
if (length == 0) length = 1;
|
|
||||||
|
|
||||||
ilength = 1.0/length;
|
|
||||||
|
|
||||||
v->x *= ilength;
|
|
||||||
v->y *= ilength;
|
|
||||||
v->z *= ilength;
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
/*********************************************************************************************
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
|
||||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
|
||||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
|
||||||
* in the product documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
|
||||||
* as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
*
|
|
||||||
**********************************************************************************************/
|
|
||||||
|
|
||||||
#ifndef VECTOR3_H
|
|
||||||
#define VECTOR3_H
|
|
||||||
|
|
||||||
#include "raylib.h" // Defines Vector3 structure
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" { // Prevents name mangling of functions
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
|
||||||
// Global Variables Definition
|
|
||||||
//------------------------------------------------------------------------------------
|
|
||||||
// It's lonely here...
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
|
||||||
// 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
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // VECTOR3_H
|
|
Loading…
Add table
Add a link
Reference in a new issue