Merge remote-tracking branch 'refs/remotes/raysan5/develop' into develop

This commit is contained in:
Joshua Reisenauer
2016-06-07 16:07:57 -07:00
17 changed files with 9814 additions and 9068 deletions

View File

@@ -28,7 +28,7 @@
#include <GLFW/glfw3.h> // Windows/Context and inputs management #include <GLFW/glfw3.h> // Windows/Context and inputs management
#define RLGL_STANDALONE #define RLGL_STANDALONE
#include "rlgl.h" #include "rlgl.h" // rlgl library: OpenGL 1.1 immediate-mode style coding
#define PLATFORM_OCULUS #define PLATFORM_OCULUS
@@ -79,14 +79,11 @@ typedef struct OculusLayer {
} OculusLayer; } OculusLayer;
#endif #endif
typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module specific Functions Declaration // Module specific Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
static void ErrorCallback(int error, const char* description); static void ErrorCallback(int error, const char* description);
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
static void TraceLog(int msgType, const char *text, ...);
// Drawing functions (uses rlgl functionality) // Drawing functions (uses rlgl functionality)
static void DrawGrid(int slices, float spacing); static void DrawGrid(int slices, float spacing);
@@ -114,8 +111,50 @@ int main(void)
{ {
// Initialization // Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
int screenWidth = 1080; int screenWidth = 1080; // Mirror screen width (set to hmdDesc.Resolution.w/2)
int screenHeight = 600; int screenHeight = 600; // Mirror screen height (set to hmdDesc.Resolution.h/2)
// NOTE: Mirror screen size can be set to any desired resolution!
// GLFW3 Initialization + OpenGL 3.3 Context + Extensions
//--------------------------------------------------------
glfwSetErrorCallback(ErrorCallback);
if (!glfwInit())
{
TraceLog(WARNING, "GLFW3: Can not initialize GLFW");
return 1;
}
else TraceLog(INFO, "GLFW3: GLFW initialized successfully");
glfwWindowHint(GLFW_DEPTH_BITS, 16);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight, "raylib oculus sample", NULL, NULL);
if (!window)
{
glfwTerminate();
return 2;
}
else TraceLog(INFO, "GLFW3: Window created successfully");
glfwSetKeyCallback(window, KeyCallback);
glfwMakeContextCurrent(window);
glfwSwapInterval(0);
// Load OpenGL 3.3 extensions
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions");
return 3;
}
else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully");
//--------------------------------------------------------
#if defined(PLATFORM_OCULUS) #if defined(PLATFORM_OCULUS)
ovrResult result = ovr_Initialize(NULL); ovrResult result = ovr_Initialize(NULL);
@@ -137,55 +176,13 @@ int main(void)
TraceLog(LOG_INFO, "OVR: Serian Number: %s", hmdDesc.SerialNumber); TraceLog(LOG_INFO, "OVR: Serian Number: %s", hmdDesc.SerialNumber);
TraceLog(LOG_INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); TraceLog(LOG_INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h);
screenWidth = hmdDesc.Resolution.w/2; //screenWidth = hmdDesc.Resolution.w/2;
screenHeight = hmdDesc.Resolution.h/2; //screenHeight = hmdDesc.Resolution.h/2;
#endif
// GLFW3 Initialization + OpenGL 3.3 Context + Extensions
//--------------------------------------------------------
glfwSetErrorCallback(ErrorCallback);
if (!glfwInit())
{
TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW");
exit(EXIT_FAILURE);
}
else TraceLog(LOG_INFO, "GLFW3: GLFW initialized successfully");
glfwWindowHint(GLFW_DEPTH_BITS, 16);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight, "raylib oculus sample", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
else TraceLog(LOG_INFO, "GLFW3: Window created successfully");
glfwSetKeyCallback(window, KeyCallback);
glfwMakeContextCurrent(window);
glfwSwapInterval(0);
// Load OpenGL 3.3 extensions
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
exit(1);
}
else TraceLog(LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
//--------------------------------------------------------
#if defined(PLATFORM_OCULUS)
// Initialize Oculus Buffers // Initialize Oculus Buffers
OculusLayer layer = InitOculusLayer(session); OculusLayer layer = InitOculusLayer(session);
OculusBuffer buffer = LoadOculusBuffer(session, layer.width, layer.height); OculusBuffer buffer = LoadOculusBuffer(session, layer.width, layer.height);
OculusMirror mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2); OculusMirror mirror = LoadOculusMirror(session, screenWidth, screenHeight);
layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain); layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain);
// Recenter OVR tracking origin // Recenter OVR tracking origin
@@ -198,7 +195,6 @@ int main(void)
rlClearColor(245, 245, 245, 255); // Define clear color rlClearColor(245, 245, 245, 255); // Define clear color
rlEnableDepthTest(); // Enable DEPTH_TEST for 3D rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
Vector2 size = { 200, 200 };
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
Camera camera; Camera camera;
@@ -257,8 +253,8 @@ int main(void)
Matrix matProj = MatrixPerspective(camera.fovy, (double)screenWidth/(double)screenHeight, 0.01, 1000.0); Matrix matProj = MatrixPerspective(camera.fovy, (double)screenWidth/(double)screenHeight, 0.01, 1000.0);
MatrixTranspose(&matProj); MatrixTranspose(&matProj);
SetMatrixModelview(matView); // Replace internal modelview matrix by a custom one SetMatrixModelview(matView); // Replace internal modelview matrix by a custom one
SetMatrixProjection(matProj); // Replace internal projection matrix by a custom one SetMatrixProjection(matProj); // Replace internal projection matrix by a custom one
#endif #endif
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, RAYWHITE); DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, RAYWHITE);
@@ -311,17 +307,15 @@ int main(void)
#if defined(PLATFORM_OCULUS) #if defined(PLATFORM_OCULUS)
UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer
UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers
ovr_Destroy(session); // Must be called after glfwTerminate() --> no
ovr_Shutdown();
#endif #endif
rlglClose(); // Unload rlgl internal buffers and default shader/texture rlglClose(); // Unload rlgl internal buffers and default shader/texture
glfwDestroyWindow(window); glfwDestroyWindow(window);
glfwTerminate(); glfwTerminate();
#if defined(PLATFORM_OCULUS)
ovr_Destroy(session); // Must be called after glfwTerminate()
ovr_Shutdown();
#endif
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;
@@ -334,7 +328,7 @@ int main(void)
// GLFW3: Error callback // GLFW3: Error callback
static void ErrorCallback(int error, const char* description) static void ErrorCallback(int error, const char* description)
{ {
TraceLog(LOG_ERROR, description); TraceLog(ERROR, description);
} }
// GLFW3: Keyboard callback // GLFW3: Keyboard callback
@@ -346,29 +340,6 @@ static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, i
} }
} }
// Output a trace log message
static void TraceLog(int msgType, const char *text, ...)
{
va_list args;
va_start(args, text);
switch(msgType)
{
case LOG_INFO: fprintf(stdout, "INFO: "); break;
case LOG_ERROR: fprintf(stdout, "ERROR: "); break;
case LOG_WARNING: fprintf(stdout, "WARNING: "); break;
case LOG_DEBUG: fprintf(stdout, "DEBUG: "); break;
default: break;
}
vfprintf(stdout, text, args);
fprintf(stdout, "\n");
va_end(args);
//if (msgType == LOG_ERROR) exit(1);
}
// Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally) // Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally)
static void DrawRectangleV(Vector2 position, Vector2 size, Color color) static void DrawRectangleV(Vector2 position, Vector2 size, Color color)
{ {
@@ -682,10 +653,13 @@ static void SetOculusBuffer(ovrSession session, OculusBuffer buffer)
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0); // Already binded //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0); // Already binded
//glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye) //glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye)
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Same as rlClearScreenBuffers()
// Required if OculusBuffer format is OVR_FORMAT_R8G8B8A8_UNORM_SRGB // NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA)
glEnable(GL_FRAMEBUFFER_SRGB); // and performs linear-to-gamma conversion in GLSL or does not care about gamma-correction, then:
// - Require OculusBuffer format to be OVR_FORMAT_R8G8B8A8_UNORM_SRGB
// - Do NOT enable GL_FRAMEBUFFER_SRGB
//glEnable(GL_FRAMEBUFFER_SRGB);
} }
// Unset Oculus buffer // Unset Oculus buffer

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

After

Width:  |  Height:  |  Size: 167 KiB

View File

@@ -18,30 +18,23 @@
* *
********************************************************************************************/ ********************************************************************************************/
#define GLAD_IMPLEMENTATION
#include "glad.h" // Extensions loading library #include "glad.h" // Extensions loading library
#include <GLFW/glfw3.h> // Windows/Context and inputs management #include <GLFW/glfw3.h> // Windows/Context and inputs management
#define RLGL_STANDALONE #define RLGL_STANDALONE
#include "rlgl.h" #include "rlgl.h" // rlgl library: OpenGL 1.1 immediate-mode style coding
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#define RED (Color){ 230, 41, 55, 255 } // Red #define RED (Color){ 230, 41, 55, 255 } // Red
#define MAROON (Color){ 190, 33, 55, 255 } // Maroon #define MAROON (Color){ 190, 33, 55, 255 } // Maroon
#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo) #define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray #define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
//----------------------------------------------------------------------------------
typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module specific Functions Declaration // Module specific Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
static void ErrorCallback(int error, const char* description); static void ErrorCallback(int error, const char* description);
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
static void TraceLog(int msgType, const char *text, ...);
// Drawing functions (uses rlgl functionality) // Drawing functions (uses rlgl functionality)
static void DrawGrid(int slices, float spacing); static void DrawGrid(int slices, float spacing);
@@ -66,10 +59,10 @@ int main(void)
if (!glfwInit()) if (!glfwInit())
{ {
TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW"); TraceLog(WARNING, "GLFW3: Can not initialize GLFW");
exit(EXIT_FAILURE); return 1;
} }
else TraceLog(LOG_INFO, "GLFW3: GLFW initialized successfully"); else TraceLog(INFO, "GLFW3: GLFW initialized successfully");
glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_DEPTH_BITS, 16); glfwWindowHint(GLFW_DEPTH_BITS, 16);
@@ -83,9 +76,9 @@ int main(void)
if (!window) if (!window)
{ {
glfwTerminate(); glfwTerminate();
exit(EXIT_FAILURE); return 2;
} }
else TraceLog(LOG_INFO, "GLFW3: Window created successfully"); else TraceLog(INFO, "GLFW3: Window created successfully");
glfwSetKeyCallback(window, KeyCallback); glfwSetKeyCallback(window, KeyCallback);
@@ -95,10 +88,10 @@ int main(void)
// Load OpenGL 3.3 extensions // Load OpenGL 3.3 extensions
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{ {
TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions"); TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions");
exit(1); return 3;
} }
else TraceLog(LOG_INFO, "GLAD: OpenGL extensions loaded successfully"); else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully");
//-------------------------------------------------------- //--------------------------------------------------------
// Initialize rlgl internal buffers and OpenGL state // Initialize rlgl internal buffers and OpenGL state
@@ -107,7 +100,6 @@ int main(void)
rlClearColor(245, 245, 245, 255); // Define clear color rlClearColor(245, 245, 245, 255); // Define clear color
rlEnableDepthTest(); // Enable DEPTH_TEST for 3D rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
Vector2 size = { 200, 200 };
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
Camera camera; Camera camera;
@@ -128,29 +120,45 @@ int main(void)
// Draw // Draw
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
rlClearScreenBuffers(); // Clear current framebuffer rlClearScreenBuffers(); // Clear current framebuffer
// Calculate projection matrix (from perspective) and view matrix from camera look at // Calculate projection matrix (from perspective) and view matrix from camera look at
Matrix matProj = MatrixPerspective(camera.fovy, (double)screenWidth/(double)screenHeight, 0.01, 1000.0); Matrix matProj = MatrixPerspective(camera.fovy, (double)screenWidth/(double)screenHeight, 0.01, 1000.0);
MatrixTranspose(&matProj); MatrixTranspose(&matProj);
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up); Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
Matrix mvp = MatrixMultiply(matView, matProj);
SetMatrixModelview(matView); // Replace internal modelview matrix by a custom one
SetMatrixProjection(matProj); // Replace internal projection matrix by a custom one
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, RAYWHITE); DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, RAYWHITE);
DrawGrid(10, 1.0f); DrawGrid(10, 1.0f);
// NOTE: Internal buffers drawing (3D data) // NOTE: Internal buffers drawing (3D data)
rlglDraw(mvp); rlglDraw();
// Draw '2D' elements in the scene (GUI)
#define RLGL_CREATE_MATRIX_MANUALLY
#if defined(RLGL_CREATE_MATRIX_MANUALLY)
matProj = MatrixOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0); matProj = MatrixOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0);
MatrixTranspose(&matProj); MatrixTranspose(&matProj);
matView = MatrixIdentity(); matView = MatrixIdentity();
mvp = MatrixMultiply(matView, matProj);
// TODO: 2D drawing on Oculus Rift: requires an ovrLayerQuad layer SetMatrixModelview(matView); // Replace internal modelview matrix by a custom one
DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 300.0f, 20.0f }, DARKGRAY); SetMatrixProjection(matProj); // Replace internal projection matrix by a custom one
#else // Let rlgl generate and multiply matrix internally
rlMatrixMode(RL_PROJECTION); // Enable internal projection matrix
rlLoadIdentity(); // Reset internal projection matrix
rlOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0); // Recalculate internal projection matrix
rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix
rlLoadIdentity(); // Reset internal modelview matrix
#endif
DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 600.0f, 20.0f }, DARKGRAY);
// NOTE: Internal buffers drawing (2D data) // NOTE: Internal buffers drawing (2D data)
rlglDraw(mvp); rlglDraw();
glfwSwapBuffers(window); glfwSwapBuffers(window);
glfwPollEvents(); glfwPollEvents();
@@ -163,7 +171,6 @@ int main(void)
glfwDestroyWindow(window); glfwDestroyWindow(window);
glfwTerminate(); glfwTerminate();
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;
@@ -176,7 +183,7 @@ int main(void)
// GLFW3: Error callback // GLFW3: Error callback
static void ErrorCallback(int error, const char* description) static void ErrorCallback(int error, const char* description)
{ {
TraceLog(LOG_ERROR, description); TraceLog(ERROR, description);
} }
// GLFW3: Keyboard callback // GLFW3: Keyboard callback
@@ -188,29 +195,6 @@ static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, i
} }
} }
// Output a trace log message
static void TraceLog(int msgType, const char *text, ...)
{
va_list args;
va_start(args, text);
switch(msgType)
{
case LOG_INFO: fprintf(stdout, "INFO: "); break;
case LOG_ERROR: fprintf(stdout, "ERROR: "); break;
case LOG_WARNING: fprintf(stdout, "WARNING: "); break;
case LOG_DEBUG: fprintf(stdout, "DEBUG: "); break;
default: break;
}
vfprintf(stdout, text, args);
fprintf(stdout, "\n");
va_end(args);
//if (msgType == LOG_ERROR) exit(1);
}
// Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally) // Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally)
static void DrawRectangleV(Vector2 position, Vector2 size, Color color) static void DrawRectangleV(Vector2 position, Vector2 size, Color color)
{ {

View File

@@ -151,7 +151,6 @@ RMDEF Matrix MatrixFrustum(double left, double right, double bottom, double top,
RMDEF Matrix MatrixPerspective(double fovy, double aspect, double near, double far); // Returns perspective projection matrix RMDEF Matrix MatrixPerspective(double fovy, double aspect, double near, double far); // Returns perspective projection matrix
RMDEF Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far); // Returns orthographic projection matrix RMDEF Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far); // Returns orthographic projection matrix
RMDEF Matrix MatrixLookAt(Vector3 position, Vector3 target, Vector3 up); // Returns camera look-at matrix (view matrix) RMDEF Matrix MatrixLookAt(Vector3 position, Vector3 target, Vector3 up); // Returns camera look-at matrix (view matrix)
RMDEF void PrintMatrix(Matrix m); // Print matrix utility
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Functions Declaration to work with Quaternions // Functions Declaration to work with Quaternions
@@ -178,9 +177,7 @@ RMDEF void QuaternionTransform(Quaternion *q, Matrix mat); // Transfo
#if defined(RAYMATH_IMPLEMENTATION) || defined(RAYMATH_EXTERN_INLINE) #if defined(RAYMATH_IMPLEMENTATION) || defined(RAYMATH_EXTERN_INLINE)
#include <stdio.h> // Used only on PrintMatrix() #include <math.h> // Required for: sinf(), cosf(), tan(), fabs()
#include <math.h> // Standard math libary: sin(), cos(), tan()...
#include <stdlib.h> // Used for abs()
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Definition - Vector3 math // Module Functions Definition - Vector3 math
@@ -342,15 +339,14 @@ RMDEF Vector3 VectorReflect(Vector3 vector, Vector3 normal)
return result; return result;
} }
// Transforms a Vector3 with a given Matrix // Transforms a Vector3 by a given Matrix
// TODO: Review math (matrix transpose required?)
RMDEF void VectorTransform(Vector3 *v, Matrix mat) RMDEF void VectorTransform(Vector3 *v, Matrix mat)
{ {
float x = v->x; float x = v->x;
float y = v->y; float y = v->y;
float z = v->z; float z = v->z;
//MatrixTranspose(&mat);
v->x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12; 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->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; v->z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14;
@@ -871,17 +867,6 @@ RMDEF Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up)
return result; return result;
} }
// Print matrix utility (for debug)
RMDEF void PrintMatrix(Matrix m)
{
printf("----------------------\n");
printf("%2.2f %2.2f %2.2f %2.2f\n", m.m0, m.m4, m.m8, m.m12);
printf("%2.2f %2.2f %2.2f %2.2f\n", m.m1, m.m5, m.m9, m.m13);
printf("%2.2f %2.2f %2.2f %2.2f\n", m.m2, m.m6, m.m10, m.m14);
printf("%2.2f %2.2f %2.2f %2.2f\n", m.m3, m.m7, m.m11, m.m15);
printf("----------------------\n");
}
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Definition - Quaternion math // Module Functions Definition - Quaternion math
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@@ -48,7 +48,13 @@
#ifdef __APPLE__ #ifdef __APPLE__
#include <OpenGL/gl3.h> // OpenGL 3 library for OSX #include <OpenGL/gl3.h> // OpenGL 3 library for OSX
#else #else
#include "glad.h" // GLAD library, includes OpenGL headers #define GLAD_IMPLEMENTATION
#if defined(RLGL_STANDALONE)
#include "glad.h" // GLAD extensions loading library, includes OpenGL headers
#else
#include "external/glad.h" // GLAD extensions loading library, includes OpenGL headers
#endif
#endif #endif
#endif #endif
@@ -62,6 +68,10 @@
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()] #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()]
#endif #endif
#if !defined(GRAPHICS_API_OPENGL_11)
#include "standard_shader.h" // Standard shader to embed
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@@ -154,10 +164,6 @@ typedef struct {
// TODO: Store draw state -> blending mode, shader // TODO: Store draw state -> blending mode, shader
} DrawCall; } DrawCall;
#if defined(RLGL_STANDALONE)
typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Global Variables Definition // Global Variables Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@@ -189,26 +195,27 @@ static bool useTempBuffer = false;
// Shader Programs // Shader Programs
static Shader defaultShader; static Shader defaultShader;
static Shader standardShader; static Shader standardShader; // Lazy initialization when GetStandardShader()
static Shader currentShader; // By default, defaultShader static Shader currentShader; // By default, defaultShader
static bool standardShaderLoaded = false;
// Flags for supported extensions // Flags for supported extensions
static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support VAO extension) static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support VAO extension)
// Compressed textures support flags // Compressed textures support flags
static bool texCompETC1Supported = false; // ETC1 texture compression support static bool texCompETC1Supported = false; // ETC1 texture compression support
static bool texCompETC2Supported = false; // ETC2/EAC texture compression support static bool texCompETC2Supported = false; // ETC2/EAC texture compression support
static bool texCompPVRTSupported = false; // PVR texture compression support static bool texCompPVRTSupported = false; // PVR texture compression support
static bool texCompASTCSupported = false; // ASTC texture compression support static bool texCompASTCSupported = false; // ASTC texture compression support
// Lighting data // Lighting data
static Light lights[MAX_LIGHTS]; // Lights pool static Light lights[MAX_LIGHTS]; // Lights pool
static int lightsCount; // Counts current enabled physic objects static int lightsCount; // Counts current enabled physic objects
#endif #endif
// Compressed textures support flags // Compressed textures support flags
static bool texCompDXTSupported = false; // DDS texture compression support static bool texCompDXTSupported = false; // DDS texture compression support
static bool npotSupported = false; // NPOT textures full support static bool npotSupported = false; // NPOT textures full support
#if defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_ES2)
// NOTE: VAO functionality is exposed through extensions (OES) // NOTE: VAO functionality is exposed through extensions (OES)
@@ -253,7 +260,6 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight);
#endif #endif
#if defined(RLGL_STANDALONE) #if defined(RLGL_STANDALONE)
static void TraceLog(int msgType, const char *text, ...);
float *MatrixToFloat(Matrix mat); // Converts Matrix to float array float *MatrixToFloat(Matrix mat); // Converts Matrix to float array
#endif #endif
@@ -355,7 +361,6 @@ void rlRotatef(float angleDeg, float x, float y, float z)
Vector3 axis = (Vector3){ x, y, z }; Vector3 axis = (Vector3){ x, y, z };
VectorNormalize(&axis); VectorNormalize(&axis);
matRotation = MatrixRotate(axis, angleDeg*DEG2RAD); matRotation = MatrixRotate(axis, angleDeg*DEG2RAD);
MatrixTranspose(&matRotation); MatrixTranspose(&matRotation);
*currentMatrix = MatrixMultiply(*currentMatrix, matRotation); *currentMatrix = MatrixMultiply(*currentMatrix, matRotation);
@@ -1032,7 +1037,6 @@ void rlglInit(void)
// Init default Shader (customized for GL 3.3 and ES2) // Init default Shader (customized for GL 3.3 and ES2)
defaultShader = LoadDefaultShader(); defaultShader = LoadDefaultShader();
standardShader = LoadStandardShader();
currentShader = defaultShader; currentShader = defaultShader;
LoadDefaultBuffers(); // Initialize default vertex arrays buffers (lines, triangles, quads) LoadDefaultBuffers(); // Initialize default vertex arrays buffers (lines, triangles, quads)
@@ -2185,14 +2189,22 @@ Shader GetDefaultShader(void)
} }
// Get default shader // Get default shader
// NOTE: Inits global variable standardShader
Shader GetStandardShader(void) Shader GetStandardShader(void)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
return standardShader;
#else
Shader shader = { 0 }; Shader shader = { 0 };
return shader;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if (standardShaderLoaded) shader = standardShader;
else
{
// Lazy initialization of standard shader
standardShader = LoadStandardShader();
shader = standardShader;
}
#endif #endif
return shader;
} }
// Get shader uniform location // Get shader uniform location
@@ -2254,13 +2266,17 @@ void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat)
// Set a custom projection matrix (replaces internal projection matrix) // Set a custom projection matrix (replaces internal projection matrix)
void SetMatrixProjection(Matrix proj) void SetMatrixProjection(Matrix proj)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
projection = proj; projection = proj;
#endif
} }
// Set a custom modelview matrix (replaces internal modelview matrix) // Set a custom modelview matrix (replaces internal modelview matrix)
void SetMatrixModelview(Matrix view) void SetMatrixModelview(Matrix view)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
modelview = view; modelview = view;
#endif
} }
// Begin blending mode (alpha, additive, multiplied) // Begin blending mode (alpha, additive, multiplied)
@@ -2564,18 +2580,28 @@ static Shader LoadDefaultShader(void)
// Load standard shader // Load standard shader
// NOTE: This shader supports: // NOTE: This shader supports:
// - Up to 3 different maps: diffuse, normal, specular // - Up to 3 different maps: diffuse, normal, specular
// - Material properties: colAmbient, colDiffuse, colSpecular, glossiness // - Material properties: colAmbient, colDiffuse, colSpecular, glossiness
// - Up to 8 lights: Point, Directional or Spot // - Up to 8 lights: Point, Directional or Spot
static Shader LoadStandardShader(void) static Shader LoadStandardShader(void)
{ {
// Load standard shader (TODO: rewrite as char pointers) Shader shader;
Shader shader = { 0 }; //LoadShader("resources/shaders/standard.vs", "resources/shaders/standard.fs");
// Load standard shader (embeded in standard_shader.h)
shader.id = LoadShaderProgram(vStandardShaderStr, fStandardShaderStr);
if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Standard shader loaded successfully", shader.id); if (shader.id != 0)
else TraceLog(WARNING, "[SHDR ID %i] Standard shader could not be loaded", shader.id); {
LoadDefaultShaderLocations(&shader);
if (shader.id != 0) LoadDefaultShaderLocations(&shader); TraceLog(INFO, "[SHDR ID %i] Standard shader loaded successfully", shader.id);
standardShaderLoaded = true;
}
else
{
TraceLog(WARNING, "[SHDR ID %i] Standard shader could not be loaded, using default shader", shader.id);
shader = GetDefaultShader();
}
return shader; return shader;
} }
@@ -3318,7 +3344,7 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight)
#if defined(RLGL_STANDALONE) #if defined(RLGL_STANDALONE)
// Output a trace log message // Output a trace log message
// NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning // NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning
static void TraceLog(int msgType, const char *text, ...) void TraceLog(int msgType, const char *text, ...)
{ {
va_list args; va_list args;
va_start(args, text); va_start(args, text);

View File

@@ -230,6 +230,9 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
// Color blending modes (pre-defined) // Color blending modes (pre-defined)
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode; typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
// TraceLog message types
typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@@ -339,6 +342,8 @@ void EndBlendMode(void); // End blend
Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool
void DestroyLight(Light light); // Destroy a light and take it out of the list void DestroyLight(Light light); // Destroy a light and take it out of the list
void TraceLog(int msgType, const char *text, ...);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -0,0 +1,394 @@
/*******************************************************************************************
*
* raylib [rlgl] example - Using rlgl module as standalone module
*
* NOTE: This example requires OpenGL 3.3 or ES2 versions for shaders support,
* OpenGL 1.1 does not support shaders but it can also be used.
*
* Compile rlgl module using:
* gcc -c rlgl.c -Wall -std=c99 -DRLGL_STANDALONE -DRAYMATH_IMPLEMENTATION -DGRAPHICS_API_OPENGL_33
*
* Compile example using:
* gcc -o $(NAME_PART).exe $(FILE_NAME) rlgl.o -lglfw3 -lopengl32 -lgdi32 -std=c99
*
* This example has been created using raylib 1.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "glad.h" // Extensions loading library
#include <GLFW/glfw3.h> // Windows/Context and inputs management
#define RLGL_STANDALONE
#include "rlgl.h" // rlgl library: OpenGL 1.1 immediate-mode style coding
#define RED (Color){ 230, 41, 55, 255 } // Red
#define MAROON (Color){ 190, 33, 55, 255 } // Maroon
#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
static void ErrorCallback(int error, const char* description);
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
// Drawing functions (uses rlgl functionality)
static void DrawGrid(int slices, float spacing);
static void DrawCube(Vector3 position, float width, float height, float length, Color color);
static void DrawCubeWires(Vector3 position, float width, float height, float length, Color color);
static void DrawRectangleV(Vector2 position, Vector2 size, Color color);
//----------------------------------------------------------------------------------
// Main Entry point
//----------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 1080;
const int screenHeight = 600;
// GLFW3 Initialization + OpenGL 3.3 Context + Extensions
//--------------------------------------------------------
glfwSetErrorCallback(ErrorCallback);
if (!glfwInit())
{
TraceLog(WARNING, "GLFW3: Can not initialize GLFW");
return 1;
}
else TraceLog(INFO, "GLFW3: GLFW initialized successfully");
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_DEPTH_BITS, 16);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight, "rlgl standalone", NULL, NULL);
if (!window)
{
glfwTerminate();
return 2;
}
else TraceLog(INFO, "GLFW3: Window created successfully");
glfwSetKeyCallback(window, KeyCallback);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
// Load OpenGL 3.3 extensions
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions");
return 3;
}
else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully");
//--------------------------------------------------------
// Initialize rlgl internal buffers and OpenGL state
rlglInit();
rlglInitGraphics(0, 0, screenWidth, screenHeight);
rlClearColor(245, 245, 245, 255); // Define clear color
rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
Camera camera;
camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
camera.fovy = 60.0f; // Camera field-of-view Y
//--------------------------------------------------------------------------------------
// Main game loop
while (!glfwWindowShouldClose(window))
{
// Update
//----------------------------------------------------------------------------------
// ...
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
rlClearScreenBuffers(); // Clear current framebuffer
for (int i = 0; i < 2; i++)
{
rlViewport(i*screenWidth/2, 0, screenWidth/2, screenHeight);
// Calculate projection matrix (from perspective) and view matrix from camera look at
Matrix matProj = MatrixPerspective(camera.fovy, (double)(screenWidth/2)/(double)screenHeight, 0.01, 1000.0);
MatrixTranspose(&matProj);
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
SetMatrixModelview(matView); // Replace internal modelview matrix by a custom one
SetMatrixProjection(matProj); // Replace internal projection matrix by a custom one
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, RAYWHITE);
DrawGrid(10, 1.0f);
// NOTE: Internal buffers drawing (3D data)
rlglDraw();
// Draw '2D' elements in the scene (GUI)
#define RLGL_CREATE_MATRIX_MANUALLY
#if defined(RLGL_CREATE_MATRIX_MANUALLY)
matProj = MatrixOrtho(0.0, screenWidth/2, screenHeight, 0.0, 0.0, 1.0);
MatrixTranspose(&matProj);
matView = MatrixIdentity();
SetMatrixModelview(matView); // Replace internal modelview matrix by a custom one
SetMatrixProjection(matProj); // Replace internal projection matrix by a custom one
#else // Let rlgl generate and multiply matrix internally
rlMatrixMode(RL_PROJECTION); // Enable internal projection matrix
rlLoadIdentity(); // Reset internal projection matrix
rlOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0); // Recalculate internal projection matrix
rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix
rlLoadIdentity(); // Reset internal modelview matrix
#endif
DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 600.0f, 20.0f }, DARKGRAY);
// NOTE: Internal buffers drawing (2D data)
rlglDraw();
}
glfwSwapBuffers(window);
glfwPollEvents();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
rlglClose(); // Unload rlgl internal buffers and default shader/texture
glfwDestroyWindow(window);
glfwTerminate();
//--------------------------------------------------------------------------------------
return 0;
}
//----------------------------------------------------------------------------------
// Module specific Functions Definitions
//----------------------------------------------------------------------------------
// GLFW3: Error callback
static void ErrorCallback(int error, const char* description)
{
TraceLog(ERROR, description);
}
// GLFW3: Keyboard callback
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GL_TRUE);
}
}
// Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally)
static void DrawRectangleV(Vector2 position, Vector2 size, Color color)
{
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(position.x, position.y);
rlVertex2i(position.x, position.y + size.y);
rlVertex2i(position.x + size.x, position.y + size.y);
rlVertex2i(position.x, position.y);
rlVertex2i(position.x + size.x, position.y + size.y);
rlVertex2i(position.x + size.x, position.y);
rlEnd();
}
// Draw a grid centered at (0, 0, 0)
static void DrawGrid(int slices, float spacing)
{
int halfSlices = slices / 2;
rlBegin(RL_LINES);
for(int i = -halfSlices; i <= halfSlices; i++)
{
if (i == 0)
{
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
rlColor3f(0.5f, 0.5f, 0.5f);
}
else
{
rlColor3f(0.75f, 0.75f, 0.75f);
rlColor3f(0.75f, 0.75f, 0.75f);
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 cube
// NOTE: Cube position is the center position
void DrawCube(Vector3 position, float width, float height, float length, Color color)
{
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
rlPushMatrix();
// NOTE: Be careful! Function order matters (rotate -> scale -> translate)
rlTranslatef(position.x, position.y, position.z);
//rlScalef(2.0f, 2.0f, 2.0f);
//rlRotatef(45, 0, 1, 0);
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
// Front Face -----------------------------------------------------
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
// Back Face ------------------------------------------------------
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
// Top Face -------------------------------------------------------
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
rlVertex3f(x-width/2, y+height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y+height/2, z+length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
rlVertex3f(x+width/2, y+height/2, z+length/2); // Bottom Right
// Bottom Face ----------------------------------------------------
rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Top Right
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Left
// Right face -----------------------------------------------------
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Left
// Left Face ------------------------------------------------------
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Right
rlEnd();
rlPopMatrix();
}
// Draw cube wires
void DrawCubeWires(Vector3 position, float width, float height, float length, Color color)
{
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
rlPushMatrix();
rlTranslatef(position.x, position.y, position.z);
//rlRotatef(45, 0, 1, 0);
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
// Front Face -----------------------------------------------------
// Bottom Line
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
// Left Line
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right
// Top Line
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
// Right Line
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left
// Back Face ------------------------------------------------------
// Bottom Line
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
// Left Line
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
// Top Line
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
// Right Line
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left
// Top Face -------------------------------------------------------
// Left Line
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left Front
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left Back
// Right Line
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right Front
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right Back
// Bottom Face ---------------------------------------------------
// Left Line
rlVertex3f(x-width/2, y-height/2, z+length/2); // Top Left Front
rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Left Back
// Right Line
rlVertex3f(x+width/2, y-height/2, z+length/2); // Top Right Front
rlVertex3f(x+width/2, y-height/2, z-length/2); // Top Right Back
rlEnd();
rlPopMatrix();
}

View File

@@ -0,0 +1,166 @@
// Vertex shader definition to embed, no external file required
const static unsigned char vStandardShaderStr[] =
#if defined(GRAPHICS_API_OPENGL_21)
"#version 120 \n"
#elif defined(GRAPHICS_API_OPENGL_ES2)
"#version 100 \n"
#endif
#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
"attribute vec3 vertexPosition; \n"
"attribute vec3 vertexNormal; \n"
"attribute vec2 vertexTexCoord; \n"
"attribute vec4 vertexColor; \n"
"varying vec3 fragPosition; \n"
"varying vec3 fragNormal; \n"
"varying vec2 fragTexCoord; \n"
"varying vec4 fragColor; \n"
#elif defined(GRAPHICS_API_OPENGL_33)
"#version 330 \n"
"in vec3 vertexPosition; \n"
"in vec3 vertexNormal; \n"
"in vec2 vertexTexCoord; \n"
"in vec4 vertexColor; \n"
"out vec3 fragPosition; \n"
"out vec3 fragNormal; \n"
"out vec2 fragTexCoord; \n"
"out vec4 fragColor; \n"
#endif
"uniform mat4 mvpMatrix; \n"
"void main() \n"
"{ \n"
" fragPosition = vertexPosition; \n"
" fragNormal = vertexNormal; \n"
" fragTexCoord = vertexTexCoord; \n"
" fragColor = vertexColor; \n"
" gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); \n"
"} \n";
// Fragment shader definition to embed, no external file required
const static unsigned char fStandardShaderStr[] =
#if defined(GRAPHICS_API_OPENGL_21)
"#version 120 \n"
#elif defined(GRAPHICS_API_OPENGL_ES2)
"#version 100 \n"
"precision mediump float; \n" // precision required for OpenGL ES2 (WebGL)
#endif
#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
"varying vec3 fragPosition; \n"
"varying vec3 fragNormal; \n"
"varying vec2 fragTexCoord; \n"
"varying vec4 fragColor; \n"
#elif defined(GRAPHICS_API_OPENGL_33)
"#version 330 \n"
"in vec3 fragPosition; \n"
"in vec3 fragNormal; \n"
"in vec2 fragTexCoord; \n"
"in vec4 fragColor; \n"
"out vec4 finalColor; \n"
#endif
"uniform sampler2D texture0; \n"
"uniform sampler2D texture1; \n"
"uniform sampler2D texture2; \n"
"uniform vec4 colAmbient; \n"
"uniform vec4 colDiffuse; \n"
"uniform vec4 colSpecular; \n"
"uniform float glossiness; \n"
"uniform int useNormal; \n"
"uniform int useSpecular; \n"
"uniform mat4 modelMatrix; \n"
"uniform vec3 viewDir; \n"
"struct Light { \n"
" int enabled; \n"
" int type; \n"
" vec3 position; \n"
" vec3 direction; \n"
" vec4 diffuse; \n"
" float intensity; \n"
" float radius; \n"
" float coneAngle; }; \n"
"const int maxLights = 8; \n"
"uniform int lightsCount; \n"
"uniform Light lights[maxLights]; \n"
"\n"
"vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s) \n"
"{\n"
" vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1));\n"
" vec3 surfaceToLight = l.position - surfacePos;\n"
" float brightness = clamp(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n)), 0, 1);\n"
" float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity;\n"
" float spec = 0.0;\n"
" if (diff > 0.0)\n"
" {\n"
" vec3 h = normalize(-l.direction + v);\n"
" spec = pow(dot(n, h), 3 + glossiness)*s;\n"
" }\n"
" return (diff*l.diffuse.rgb + spec*colSpecular.rgb);\n"
"}\n"
"\n"
"vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s)\n"
"{\n"
" vec3 lightDir = normalize(-l.direction);\n"
" float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity;\n"
" float spec = 0.0;\n"
" if (diff > 0.0)\n"
" {\n"
" vec3 h = normalize(lightDir + v);\n"
" spec = pow(dot(n, h), 3 + glossiness)*s;\n"
" }\n"
" return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb);\n"
"}\n"
"\n"
"vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s)\n"
"{\n"
" vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1));\n"
" vec3 lightToSurface = normalize(surfacePos - l.position);\n"
" vec3 lightDir = normalize(-l.direction);\n"
" float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity;\n"
" float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0);\n"
" attenuation = dot(lightToSurface, -lightDir);\n"
" float lightToSurfaceAngle = degrees(acos(attenuation));\n"
" if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0;\n"
" float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle;\n"
" float diffAttenuation = diff*attenuation;\n"
" float spec = 0.0;\n"
" if (diffAttenuation > 0.0)\n"
" {\n"
" vec3 h = normalize(lightDir + v);\n"
" spec = pow(dot(n, h), 3 + glossiness)*s;\n"
" }\n"
" return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));\n"
"}\n"
"\n"
"void main()\n"
"{\n"
" mat3 normalMatrix = transpose(inverse(mat3(modelMatrix)));\n"
" vec3 normal = normalize(normalMatrix*fragNormal);\n"
" vec3 n = normalize(normal);\n"
" vec3 v = normalize(viewDir);\n"
" vec4 texelColor = texture(texture0, fragTexCoord);\n"
" vec3 lighting = colAmbient.rgb;\n"
" if (useNormal == 1)\n"
" {\n"
" n *= texture(texture1, fragTexCoord).rgb;\n"
" n = normalize(n);\n"
" }\n"
" float spec = 1.0;\n"
" if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r);\n"
" for (int i = 0; i < lightsCount; i++)\n"
" {\n"
" if (lights[i].enabled == 1)\n"
" {\n"
" switch (lights[i].type)\n"
" {\n"
" case 0: lighting += CalcPointLight(lights[i], n, v, spec); break;\n"
" case 1: lighting += CalcDirectionalLight(lights[i], n, v, spec); break;\n"
" case 2: lighting += CalcSpotLight(lights[i], n, v, spec); break;\n"
" default: break;\n"
" }\n"
" }\n"
" }\n"
#if defined(GRAPHICS_API_OPENGL_33)
" finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); \n"
#elif defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
" gl_FragColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); \n"
#endif
"} \n";

View File

@@ -92,13 +92,7 @@ else
endif endif
# define all object files required # define all object files required
ifeq ($(PLATFORM),PLATFORM_DESKTOP) OBJS = core.o rlgl.o shapes.o text.o textures.o models.o audio.o utils.o camera.o gestures.o stb_vorbis.o
OBJS = core.o rlgl.o glad.o shapes.o text.o textures.o models.o audio.o utils.o camera.o gestures.o stb_vorbis.o
else
#GLAD only required on desktop platform
OBJS = core.o rlgl.o shapes.o text.o textures.o models.o audio.o stb_vorbis.o utils.o camera.o gestures.o
endif
# typing 'make' will invoke the default target entry called 'all', # typing 'make' will invoke the default target entry called 'all',
# in this case, the 'default' target entry is raylib # in this case, the 'default' target entry is raylib
@@ -153,10 +147,6 @@ camera.o: camera.c
gestures.o: gestures.c gestures.o: gestures.c
$(CC) -c gestures.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) $(CC) -c gestures.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
# compile glad module
glad.o: external/glad.c
$(CC) -c external/glad.c $(CFLAGS) $(INCLUDES)
# compile stb_vorbis library # compile stb_vorbis library
stb_vorbis.o: external/stb_vorbis.c stb_vorbis.o: external/stb_vorbis.c
$(CC) -c external/stb_vorbis.c -O1 $(INCLUDES) -D$(PLATFORM) $(CC) -c external/stb_vorbis.c -O1 $(INCLUDES) -D$(PLATFORM)

View File

@@ -46,13 +46,13 @@ LOCAL_SRC_FILES :=\
../../models.c \ ../../models.c \
../../utils.c \ ../../utils.c \
../../audio.c \ ../../audio.c \
../../stb_vorbis.c \ ../../external/stb_vorbis.c \
# Required includes paths (.h) # Required includes paths (.h)
LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/include $(LOCAL_PATH)/../.. LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/include $(LOCAL_PATH)/../..
# Required flags for compilation: defines PLATFORM_ANDROID and GRAPHICS_API_OPENGL_ES2 # Required flags for compilation: defines PLATFORM_ANDROID and GRAPHICS_API_OPENGL_ES2
LOCAL_CFLAGS := -Wall -std=c99 -Wno-missing-braces -g -DPLATFORM_ANDROID -DGRAPHICS_API_OPENGL_ES2 LOCAL_CFLAGS := -Wall -std=c99 -Wno-missing-braces -DPLATFORM_ANDROID -DGRAPHICS_API_OPENGL_ES2
# Build the static library libraylib.a # Build the static library libraylib.a
include $(BUILD_STATIC_LIBRARY) include $(BUILD_STATIC_LIBRARY)

7684
src/external/glad.c vendored

File diff suppressed because one or more lines are too long

7678
src/external/glad.h vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -48,7 +48,13 @@
#ifdef __APPLE__ #ifdef __APPLE__
#include <OpenGL/gl3.h> // OpenGL 3 library for OSX #include <OpenGL/gl3.h> // OpenGL 3 library for OSX
#else #else
#include "external/glad.h" // GLAD library, includes OpenGL headers #define GLAD_IMPLEMENTATION
#if defined(RLGL_STANDALONE)
#include "glad.h" // GLAD extensions loading library, includes OpenGL headers
#else
#include "external/glad.h" // GLAD extensions loading library, includes OpenGL headers
#endif
#endif #endif
#endif #endif
@@ -62,6 +68,10 @@
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()] #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()]
#endif #endif
#if !defined(GRAPHICS_API_OPENGL_11)
#include "standard_shader.h" // Standard shader to embed
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@@ -154,10 +164,6 @@ typedef struct {
// TODO: Store draw state -> blending mode, shader // TODO: Store draw state -> blending mode, shader
} DrawCall; } DrawCall;
#if defined(RLGL_STANDALONE)
typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Global Variables Definition // Global Variables Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@@ -189,26 +195,27 @@ static bool useTempBuffer = false;
// Shader Programs // Shader Programs
static Shader defaultShader; static Shader defaultShader;
static Shader standardShader; static Shader standardShader; // Lazy initialization when GetStandardShader()
static Shader currentShader; // By default, defaultShader static Shader currentShader; // By default, defaultShader
static bool standardShaderLoaded = false;
// Flags for supported extensions // Flags for supported extensions
static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support VAO extension) static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support VAO extension)
// Compressed textures support flags // Compressed textures support flags
static bool texCompETC1Supported = false; // ETC1 texture compression support static bool texCompETC1Supported = false; // ETC1 texture compression support
static bool texCompETC2Supported = false; // ETC2/EAC texture compression support static bool texCompETC2Supported = false; // ETC2/EAC texture compression support
static bool texCompPVRTSupported = false; // PVR texture compression support static bool texCompPVRTSupported = false; // PVR texture compression support
static bool texCompASTCSupported = false; // ASTC texture compression support static bool texCompASTCSupported = false; // ASTC texture compression support
// Lighting data // Lighting data
static Light lights[MAX_LIGHTS]; // Lights pool static Light lights[MAX_LIGHTS]; // Lights pool
static int lightsCount; // Counts current enabled physic objects static int lightsCount; // Counts current enabled physic objects
#endif #endif
// Compressed textures support flags // Compressed textures support flags
static bool texCompDXTSupported = false; // DDS texture compression support static bool texCompDXTSupported = false; // DDS texture compression support
static bool npotSupported = false; // NPOT textures full support static bool npotSupported = false; // NPOT textures full support
#if defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_ES2)
// NOTE: VAO functionality is exposed through extensions (OES) // NOTE: VAO functionality is exposed through extensions (OES)
@@ -253,7 +260,6 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight);
#endif #endif
#if defined(RLGL_STANDALONE) #if defined(RLGL_STANDALONE)
static void TraceLog(int msgType, const char *text, ...);
float *MatrixToFloat(Matrix mat); // Converts Matrix to float array float *MatrixToFloat(Matrix mat); // Converts Matrix to float array
#endif #endif
@@ -1031,7 +1037,6 @@ void rlglInit(void)
// Init default Shader (customized for GL 3.3 and ES2) // Init default Shader (customized for GL 3.3 and ES2)
defaultShader = LoadDefaultShader(); defaultShader = LoadDefaultShader();
standardShader = LoadStandardShader();
currentShader = defaultShader; currentShader = defaultShader;
LoadDefaultBuffers(); // Initialize default vertex arrays buffers (lines, triangles, quads) LoadDefaultBuffers(); // Initialize default vertex arrays buffers (lines, triangles, quads)
@@ -2184,14 +2189,22 @@ Shader GetDefaultShader(void)
} }
// Get default shader // Get default shader
// NOTE: Inits global variable standardShader
Shader GetStandardShader(void) Shader GetStandardShader(void)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
return standardShader;
#else
Shader shader = { 0 }; Shader shader = { 0 };
return shader;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if (standardShaderLoaded) shader = standardShader;
else
{
// Lazy initialization of standard shader
standardShader = LoadStandardShader();
shader = standardShader;
}
#endif #endif
return shader;
} }
// Get shader uniform location // Get shader uniform location
@@ -2567,18 +2580,22 @@ static Shader LoadDefaultShader(void)
// Load standard shader // Load standard shader
// NOTE: This shader supports: // NOTE: This shader supports:
// - Up to 3 different maps: diffuse, normal, specular // - Up to 3 different maps: diffuse, normal, specular
// - Material properties: colAmbient, colDiffuse, colSpecular, glossiness // - Material properties: colAmbient, colDiffuse, colSpecular, glossiness
// - Up to 8 lights: Point, Directional or Spot // - Up to 8 lights: Point, Directional or Spot
static Shader LoadStandardShader(void) static Shader LoadStandardShader(void)
{ {
// Load standard shader (TODO: rewrite as char pointers) Shader shader;
Shader shader = LoadShader("resources/shaders/standard.vs", "resources/shaders/standard.fs");
// Load standard shader (embeded in standard_shader.h)
shader.id = LoadShaderProgram(vStandardShaderStr, fStandardShaderStr);
if (shader.id != 0) if (shader.id != 0)
{ {
LoadDefaultShaderLocations(&shader); LoadDefaultShaderLocations(&shader);
TraceLog(INFO, "[SHDR ID %i] Standard shader loaded successfully", shader.id); TraceLog(INFO, "[SHDR ID %i] Standard shader loaded successfully", shader.id);
standardShaderLoaded = true;
} }
else else
{ {
@@ -3327,7 +3344,7 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight)
#if defined(RLGL_STANDALONE) #if defined(RLGL_STANDALONE)
// Output a trace log message // Output a trace log message
// NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning // NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning
static void TraceLog(int msgType, const char *text, ...) void TraceLog(int msgType, const char *text, ...)
{ {
va_list args; va_list args;
va_start(args, text); va_start(args, text);

View File

@@ -230,6 +230,9 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
// Color blending modes (pre-defined) // Color blending modes (pre-defined)
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode; typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
// TraceLog message types
typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@@ -339,6 +342,8 @@ void EndBlendMode(void); // End blend
Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool
void DestroyLight(Light light); // Destroy a light and take it out of the list void DestroyLight(Light light); // Destroy a light and take it out of the list
void TraceLog(int msgType, const char *text, ...);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

166
src/standard_shader.h Normal file
View File

@@ -0,0 +1,166 @@
// Vertex shader definition to embed, no external file required
const static unsigned char vStandardShaderStr[] =
#if defined(GRAPHICS_API_OPENGL_21)
"#version 120 \n"
#elif defined(GRAPHICS_API_OPENGL_ES2)
"#version 100 \n"
#endif
#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
"attribute vec3 vertexPosition; \n"
"attribute vec3 vertexNormal; \n"
"attribute vec2 vertexTexCoord; \n"
"attribute vec4 vertexColor; \n"
"varying vec3 fragPosition; \n"
"varying vec3 fragNormal; \n"
"varying vec2 fragTexCoord; \n"
"varying vec4 fragColor; \n"
#elif defined(GRAPHICS_API_OPENGL_33)
"#version 330 \n"
"in vec3 vertexPosition; \n"
"in vec3 vertexNormal; \n"
"in vec2 vertexTexCoord; \n"
"in vec4 vertexColor; \n"
"out vec3 fragPosition; \n"
"out vec3 fragNormal; \n"
"out vec2 fragTexCoord; \n"
"out vec4 fragColor; \n"
#endif
"uniform mat4 mvpMatrix; \n"
"void main() \n"
"{ \n"
" fragPosition = vertexPosition; \n"
" fragNormal = vertexNormal; \n"
" fragTexCoord = vertexTexCoord; \n"
" fragColor = vertexColor; \n"
" gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); \n"
"} \n";
// Fragment shader definition to embed, no external file required
const static unsigned char fStandardShaderStr[] =
#if defined(GRAPHICS_API_OPENGL_21)
"#version 120 \n"
#elif defined(GRAPHICS_API_OPENGL_ES2)
"#version 100 \n"
"precision mediump float; \n" // precision required for OpenGL ES2 (WebGL)
#endif
#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
"varying vec3 fragPosition; \n"
"varying vec3 fragNormal; \n"
"varying vec2 fragTexCoord; \n"
"varying vec4 fragColor; \n"
#elif defined(GRAPHICS_API_OPENGL_33)
"#version 330 \n"
"in vec3 fragPosition; \n"
"in vec3 fragNormal; \n"
"in vec2 fragTexCoord; \n"
"in vec4 fragColor; \n"
"out vec4 finalColor; \n"
#endif
"uniform sampler2D texture0; \n"
"uniform sampler2D texture1; \n"
"uniform sampler2D texture2; \n"
"uniform vec4 colAmbient; \n"
"uniform vec4 colDiffuse; \n"
"uniform vec4 colSpecular; \n"
"uniform float glossiness; \n"
"uniform int useNormal; \n"
"uniform int useSpecular; \n"
"uniform mat4 modelMatrix; \n"
"uniform vec3 viewDir; \n"
"struct Light { \n"
" int enabled; \n"
" int type; \n"
" vec3 position; \n"
" vec3 direction; \n"
" vec4 diffuse; \n"
" float intensity; \n"
" float radius; \n"
" float coneAngle; }; \n"
"const int maxLights = 8; \n"
"uniform int lightsCount; \n"
"uniform Light lights[maxLights]; \n"
"\n"
"vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s) \n"
"{\n"
" vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1));\n"
" vec3 surfaceToLight = l.position - surfacePos;\n"
" float brightness = clamp(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n)), 0, 1);\n"
" float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity;\n"
" float spec = 0.0;\n"
" if (diff > 0.0)\n"
" {\n"
" vec3 h = normalize(-l.direction + v);\n"
" spec = pow(dot(n, h), 3 + glossiness)*s;\n"
" }\n"
" return (diff*l.diffuse.rgb + spec*colSpecular.rgb);\n"
"}\n"
"\n"
"vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s)\n"
"{\n"
" vec3 lightDir = normalize(-l.direction);\n"
" float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity;\n"
" float spec = 0.0;\n"
" if (diff > 0.0)\n"
" {\n"
" vec3 h = normalize(lightDir + v);\n"
" spec = pow(dot(n, h), 3 + glossiness)*s;\n"
" }\n"
" return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb);\n"
"}\n"
"\n"
"vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s)\n"
"{\n"
" vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1));\n"
" vec3 lightToSurface = normalize(surfacePos - l.position);\n"
" vec3 lightDir = normalize(-l.direction);\n"
" float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity;\n"
" float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0);\n"
" attenuation = dot(lightToSurface, -lightDir);\n"
" float lightToSurfaceAngle = degrees(acos(attenuation));\n"
" if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0;\n"
" float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle;\n"
" float diffAttenuation = diff*attenuation;\n"
" float spec = 0.0;\n"
" if (diffAttenuation > 0.0)\n"
" {\n"
" vec3 h = normalize(lightDir + v);\n"
" spec = pow(dot(n, h), 3 + glossiness)*s;\n"
" }\n"
" return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));\n"
"}\n"
"\n"
"void main()\n"
"{\n"
" mat3 normalMatrix = transpose(inverse(mat3(modelMatrix)));\n"
" vec3 normal = normalize(normalMatrix*fragNormal);\n"
" vec3 n = normalize(normal);\n"
" vec3 v = normalize(viewDir);\n"
" vec4 texelColor = texture(texture0, fragTexCoord);\n"
" vec3 lighting = colAmbient.rgb;\n"
" if (useNormal == 1)\n"
" {\n"
" n *= texture(texture1, fragTexCoord).rgb;\n"
" n = normalize(n);\n"
" }\n"
" float spec = 1.0;\n"
" if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r);\n"
" for (int i = 0; i < lightsCount; i++)\n"
" {\n"
" if (lights[i].enabled == 1)\n"
" {\n"
" switch (lights[i].type)\n"
" {\n"
" case 0: lighting += CalcPointLight(lights[i], n, v, spec); break;\n"
" case 1: lighting += CalcDirectionalLight(lights[i], n, v, spec); break;\n"
" case 2: lighting += CalcSpotLight(lights[i], n, v, spec); break;\n"
" default: break;\n"
" }\n"
" }\n"
" }\n"
#if defined(GRAPHICS_API_OPENGL_33)
" finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); \n"
#elif defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21)
" gl_FragColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); \n"
#endif
"} \n";