From 5631f822bd9195d494915d3b2bb80caf47a65068 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 7 Jun 2016 20:46:03 +0200 Subject: Reorganized device init/close --- examples/oculus_glfw_sample/oculus_glfw_sample.c | 69 ++++++++++++------------ 1 file changed, 35 insertions(+), 34 deletions(-) (limited to 'examples') diff --git a/examples/oculus_glfw_sample/oculus_glfw_sample.c b/examples/oculus_glfw_sample/oculus_glfw_sample.c index 54302de8..e0740f66 100644 --- a/examples/oculus_glfw_sample/oculus_glfw_sample.c +++ b/examples/oculus_glfw_sample/oculus_glfw_sample.c @@ -114,32 +114,10 @@ int main(void) { // Initialization //-------------------------------------------------------------------------------------- - int screenWidth = 1080; - int screenHeight = 600; + int screenWidth = 1080; // Mirror screen width (set to hmdDesc.Resolution.w/2) + int screenHeight = 600; // Mirror screen height (set to hmdDesc.Resolution.h/2) -#if defined(PLATFORM_OCULUS) - ovrResult result = ovr_Initialize(NULL); - if (OVR_FAILURE(result)) TraceLog(LOG_ERROR, "OVR: Could not initialize Oculus device"); - - result = ovr_Create(&session, &luid); - if (OVR_FAILURE(result)) - { - TraceLog(LOG_WARNING, "OVR: Could not create Oculus session"); - ovr_Shutdown(); - } - - hmdDesc = ovr_GetHmdDesc(session); - - TraceLog(LOG_INFO, "OVR: Product Name: %s", hmdDesc.ProductName); - TraceLog(LOG_INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer); - TraceLog(LOG_INFO, "OVR: Product ID: %i", hmdDesc.ProductId); - TraceLog(LOG_INFO, "OVR: Product Type: %i", hmdDesc.Type); - TraceLog(LOG_INFO, "OVR: Serian Number: %s", hmdDesc.SerialNumber); - TraceLog(LOG_INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); - - screenWidth = hmdDesc.Resolution.w/2; - screenHeight = hmdDesc.Resolution.h/2; -#endif + // NOTE: Mirror screen size can be set to any desired resolution! // GLFW3 Initialization + OpenGL 3.3 Context + Extensions //-------------------------------------------------------- @@ -182,10 +160,32 @@ int main(void) //-------------------------------------------------------- #if defined(PLATFORM_OCULUS) + ovrResult result = ovr_Initialize(NULL); + if (OVR_FAILURE(result)) TraceLog(LOG_ERROR, "OVR: Could not initialize Oculus device"); + + result = ovr_Create(&session, &luid); + if (OVR_FAILURE(result)) + { + TraceLog(LOG_WARNING, "OVR: Could not create Oculus session"); + ovr_Shutdown(); + } + + hmdDesc = ovr_GetHmdDesc(session); + + TraceLog(LOG_INFO, "OVR: Product Name: %s", hmdDesc.ProductName); + TraceLog(LOG_INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer); + TraceLog(LOG_INFO, "OVR: Product ID: %i", hmdDesc.ProductId); + TraceLog(LOG_INFO, "OVR: Product Type: %i", hmdDesc.Type); + TraceLog(LOG_INFO, "OVR: Serian Number: %s", hmdDesc.SerialNumber); + TraceLog(LOG_INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); + + //screenWidth = hmdDesc.Resolution.w/2; + //screenHeight = hmdDesc.Resolution.h/2; + // Initialize Oculus Buffers OculusLayer layer = InitOculusLayer(session); 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); // Recenter OVR tracking origin @@ -311,17 +311,15 @@ int main(void) #if defined(PLATFORM_OCULUS) UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers + + ovr_Destroy(session); // Must be called after glfwTerminate() --> no + ovr_Shutdown(); #endif rlglClose(); // Unload rlgl internal buffers and default shader/texture glfwDestroyWindow(window); glfwTerminate(); - -#if defined(PLATFORM_OCULUS) - ovr_Destroy(session); // Must be called after glfwTerminate() - ovr_Shutdown(); -#endif //-------------------------------------------------------------------------------------- return 0; @@ -682,10 +680,13 @@ static void SetOculusBuffer(ovrSession session, OculusBuffer buffer) //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) - //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 - glEnable(GL_FRAMEBUFFER_SRGB); + // NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA) + // 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 -- cgit v1.2.3 From ee795150fa21f239533d4c9ffadf56366c89a8ca Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 7 Jun 2016 23:44:53 +0200 Subject: Updated some code --- examples/oculus_glfw_sample/oculus_glfw_sample.c | 51 ++----- .../oculus_glfw_sample/raylib_rlgl_standalone.c | 80 ++++------ examples/oculus_glfw_sample/raymath.h | 21 +-- examples/oculus_glfw_sample/rlgl.c | 92 ++++++++---- examples/oculus_glfw_sample/rlgl.h | 5 + examples/oculus_glfw_sample/standard_shader.h | 166 +++++++++++++++++++++ src/rlgl.c | 16 +- src/rlgl.h | 5 + 8 files changed, 290 insertions(+), 146 deletions(-) create mode 100644 examples/oculus_glfw_sample/standard_shader.h (limited to 'examples') diff --git a/examples/oculus_glfw_sample/oculus_glfw_sample.c b/examples/oculus_glfw_sample/oculus_glfw_sample.c index e0740f66..73f19883 100644 --- a/examples/oculus_glfw_sample/oculus_glfw_sample.c +++ b/examples/oculus_glfw_sample/oculus_glfw_sample.c @@ -28,7 +28,7 @@ #include // Windows/Context and inputs management #define RLGL_STANDALONE -#include "rlgl.h" +#include "rlgl.h" // rlgl library: OpenGL 1.1 immediate-mode style coding #define PLATFORM_OCULUS @@ -79,14 +79,11 @@ typedef struct OculusLayer { } OculusLayer; #endif -typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType; - //---------------------------------------------------------------------------------- // 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); -static void TraceLog(int msgType, const char *text, ...); // Drawing functions (uses rlgl functionality) static void DrawGrid(int slices, float spacing); @@ -125,10 +122,10 @@ int main(void) if (!glfwInit()) { - TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW"); - exit(EXIT_FAILURE); + TraceLog(WARNING, "GLFW3: Can not initialize GLFW"); + return 1; } - else TraceLog(LOG_INFO, "GLFW3: GLFW initialized successfully"); + else TraceLog(INFO, "GLFW3: GLFW initialized successfully"); glfwWindowHint(GLFW_DEPTH_BITS, 16); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); @@ -141,9 +138,9 @@ int main(void) if (!window) { glfwTerminate(); - exit(EXIT_FAILURE); + return 2; } - else TraceLog(LOG_INFO, "GLFW3: Window created successfully"); + else TraceLog(INFO, "GLFW3: Window created successfully"); glfwSetKeyCallback(window, KeyCallback); @@ -153,10 +150,10 @@ int main(void) // Load OpenGL 3.3 extensions if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { - TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions"); - exit(1); + TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions"); + return 3; } - else TraceLog(LOG_INFO, "GLAD: OpenGL extensions loaded successfully"); + else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully"); //-------------------------------------------------------- #if defined(PLATFORM_OCULUS) @@ -198,7 +195,6 @@ int main(void) rlClearColor(245, 245, 245, 255); // Define clear color rlEnableDepthTest(); // Enable DEPTH_TEST for 3D - Vector2 size = { 200, 200 }; Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; Camera camera; @@ -257,8 +253,8 @@ int main(void) Matrix matProj = MatrixPerspective(camera.fovy, (double)screenWidth/(double)screenHeight, 0.01, 1000.0); MatrixTranspose(&matProj); - SetMatrixModelview(matView); // Replace internal modelview matrix by a custom one - SetMatrixProjection(matProj); // Replace internal projection 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 #endif DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, RAYWHITE); @@ -332,7 +328,7 @@ int main(void) // GLFW3: Error callback static void ErrorCallback(int error, const char* description) { - TraceLog(LOG_ERROR, description); + TraceLog(ERROR, description); } // GLFW3: Keyboard callback @@ -344,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) static void DrawRectangleV(Vector2 position, Vector2 size, Color color) { diff --git a/examples/oculus_glfw_sample/raylib_rlgl_standalone.c b/examples/oculus_glfw_sample/raylib_rlgl_standalone.c index 288418a1..4728160a 100644 --- a/examples/oculus_glfw_sample/raylib_rlgl_standalone.c +++ b/examples/oculus_glfw_sample/raylib_rlgl_standalone.c @@ -18,30 +18,23 @@ * ********************************************************************************************/ -#define GLAD_IMPLEMENTATION #include "glad.h" // Extensions loading library #include // Windows/Context and inputs management #define RLGL_STANDALONE -#include "rlgl.h" +#include "rlgl.h" // rlgl library: OpenGL 1.1 immediate-mode style coding -#include -#include -#include #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 -//---------------------------------------------------------------------------------- -typedef enum { LOG_INFO = 0, LOG_ERROR, LOG_WARNING, LOG_DEBUG, LOG_OTHER } TraceLogType; //---------------------------------------------------------------------------------- // 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); -static void TraceLog(int msgType, const char *text, ...); // Drawing functions (uses rlgl functionality) static void DrawGrid(int slices, float spacing); @@ -66,10 +59,10 @@ int main(void) if (!glfwInit()) { - TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW"); - exit(EXIT_FAILURE); + TraceLog(WARNING, "GLFW3: Can not initialize GLFW"); + return 1; } - else TraceLog(LOG_INFO, "GLFW3: GLFW initialized successfully"); + else TraceLog(INFO, "GLFW3: GLFW initialized successfully"); glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_DEPTH_BITS, 16); @@ -83,9 +76,9 @@ int main(void) if (!window) { glfwTerminate(); - exit(EXIT_FAILURE); + return 2; } - else TraceLog(LOG_INFO, "GLFW3: Window created successfully"); + else TraceLog(INFO, "GLFW3: Window created successfully"); glfwSetKeyCallback(window, KeyCallback); @@ -95,10 +88,10 @@ int main(void) // Load OpenGL 3.3 extensions if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { - TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions"); - exit(1); + TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions"); + 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 @@ -107,7 +100,6 @@ int main(void) rlClearColor(245, 245, 245, 255); // Define clear color rlEnableDepthTest(); // Enable DEPTH_TEST for 3D - Vector2 size = { 200, 200 }; Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; Camera camera; @@ -128,29 +120,45 @@ int main(void) // Draw //---------------------------------------------------------------------------------- rlClearScreenBuffers(); // Clear current framebuffer + // 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); MatrixTranspose(&matProj); 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); DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, RAYWHITE); DrawGrid(10, 1.0f); // 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); MatrixTranspose(&matProj); matView = MatrixIdentity(); - mvp = MatrixMultiply(matView, matProj); - // TODO: 2D drawing on Oculus Rift: requires an ovrLayerQuad layer - DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 300.0f, 20.0f }, DARKGRAY); + 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(mvp); + rlglDraw(); glfwSwapBuffers(window); glfwPollEvents(); @@ -163,7 +171,6 @@ int main(void) glfwDestroyWindow(window); glfwTerminate(); - //-------------------------------------------------------------------------------------- return 0; @@ -176,7 +183,7 @@ int main(void) // GLFW3: Error callback static void ErrorCallback(int error, const char* description) { - TraceLog(LOG_ERROR, description); + TraceLog(ERROR, description); } // 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) static void DrawRectangleV(Vector2 position, Vector2 size, Color color) { diff --git a/examples/oculus_glfw_sample/raymath.h b/examples/oculus_glfw_sample/raymath.h index 2e055e9f..4075a1a9 100644 --- a/examples/oculus_glfw_sample/raymath.h +++ b/examples/oculus_glfw_sample/raymath.h @@ -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 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 void PrintMatrix(Matrix m); // Print matrix utility //------------------------------------------------------------------------------------ // 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) -#include // Used only on PrintMatrix() -#include // Standard math libary: sin(), cos(), tan()... -#include // Used for abs() +#include // Required for: sinf(), cosf(), tan(), fabs() //---------------------------------------------------------------------------------- // Module Functions Definition - Vector3 math @@ -342,15 +339,14 @@ RMDEF Vector3 VectorReflect(Vector3 vector, Vector3 normal) 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) { 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; @@ -871,17 +867,6 @@ RMDEF Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up) 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 //---------------------------------------------------------------------------------- diff --git a/examples/oculus_glfw_sample/rlgl.c b/examples/oculus_glfw_sample/rlgl.c index 329ccd6e..72225634 100644 --- a/examples/oculus_glfw_sample/rlgl.c +++ b/examples/oculus_glfw_sample/rlgl.c @@ -48,7 +48,13 @@ #ifdef __APPLE__ #include // OpenGL 3 library for OSX #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 @@ -62,6 +68,10 @@ #include // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()] #endif +#if !defined(GRAPHICS_API_OPENGL_11) + #include "standard_shader.h" // Standard shader to embed +#endif + //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- @@ -154,10 +164,6 @@ typedef struct { // TODO: Store draw state -> blending mode, shader } DrawCall; -#if defined(RLGL_STANDALONE) -typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType; -#endif - //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- @@ -189,26 +195,27 @@ static bool useTempBuffer = false; // Shader Programs static Shader defaultShader; -static Shader standardShader; -static Shader currentShader; // By default, defaultShader +static Shader standardShader; // Lazy initialization when GetStandardShader() +static Shader currentShader; // By default, defaultShader +static bool standardShaderLoaded = false; // 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 -static bool texCompETC1Supported = false; // ETC1 texture compression support -static bool texCompETC2Supported = false; // ETC2/EAC texture compression support -static bool texCompPVRTSupported = false; // PVR texture compression support -static bool texCompASTCSupported = false; // ASTC texture compression support +static bool texCompETC1Supported = false; // ETC1 texture compression support +static bool texCompETC2Supported = false; // ETC2/EAC texture compression support +static bool texCompPVRTSupported = false; // PVR texture compression support +static bool texCompASTCSupported = false; // ASTC texture compression support // Lighting data -static Light lights[MAX_LIGHTS]; // Lights pool -static int lightsCount; // Counts current enabled physic objects +static Light lights[MAX_LIGHTS]; // Lights pool +static int lightsCount; // Counts current enabled physic objects #endif // Compressed textures support flags -static bool texCompDXTSupported = false; // DDS texture compression support -static bool npotSupported = false; // NPOT textures full support +static bool texCompDXTSupported = false; // DDS texture compression support +static bool npotSupported = false; // NPOT textures full support #if defined(GRAPHICS_API_OPENGL_ES2) // NOTE: VAO functionality is exposed through extensions (OES) @@ -253,7 +260,6 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight); #endif #if defined(RLGL_STANDALONE) -static void TraceLog(int msgType, const char *text, ...); float *MatrixToFloat(Matrix mat); // Converts Matrix to float array #endif @@ -355,7 +361,6 @@ void rlRotatef(float angleDeg, float x, float y, float z) Vector3 axis = (Vector3){ x, y, z }; VectorNormalize(&axis); matRotation = MatrixRotate(axis, angleDeg*DEG2RAD); - MatrixTranspose(&matRotation); *currentMatrix = MatrixMultiply(*currentMatrix, matRotation); @@ -1032,7 +1037,6 @@ void rlglInit(void) // Init default Shader (customized for GL 3.3 and ES2) defaultShader = LoadDefaultShader(); - standardShader = LoadStandardShader(); currentShader = defaultShader; LoadDefaultBuffers(); // Initialize default vertex arrays buffers (lines, triangles, quads) @@ -2185,14 +2189,22 @@ Shader GetDefaultShader(void) } // Get default shader +// NOTE: Inits global variable standardShader Shader GetStandardShader(void) { -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - return standardShader; -#else 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 + + return shader; } // 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) void SetMatrixProjection(Matrix proj) { +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) projection = proj; +#endif } // Set a custom modelview matrix (replaces internal modelview matrix) void SetMatrixModelview(Matrix view) { +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) modelview = view; +#endif } // Begin blending mode (alpha, additive, multiplied) @@ -2564,18 +2580,28 @@ static Shader LoadDefaultShader(void) // Load standard shader // NOTE: This shader supports: -// - Up to 3 different maps: diffuse, normal, specular -// - Material properties: colAmbient, colDiffuse, colSpecular, glossiness -// - Up to 8 lights: Point, Directional or Spot +// - Up to 3 different maps: diffuse, normal, specular +// - Material properties: colAmbient, colDiffuse, colSpecular, glossiness +// - Up to 8 lights: Point, Directional or Spot static Shader LoadStandardShader(void) { - // Load standard shader (TODO: rewrite as char pointers) - Shader shader = { 0 }; //LoadShader("resources/shaders/standard.vs", "resources/shaders/standard.fs"); - - if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Standard shader loaded successfully", shader.id); - else TraceLog(WARNING, "[SHDR ID %i] Standard shader could not be loaded", shader.id); + Shader shader; + + // Load standard shader (embeded in standard_shader.h) + shader.id = LoadShaderProgram(vStandardShaderStr, fStandardShaderStr); - if (shader.id != 0) 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; } @@ -3318,7 +3344,7 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight) #if defined(RLGL_STANDALONE) // Output a trace log message // 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_start(args, text); diff --git a/examples/oculus_glfw_sample/rlgl.h b/examples/oculus_glfw_sample/rlgl.h index 2a578a1f..9c25f710 100644 --- a/examples/oculus_glfw_sample/rlgl.h +++ b/examples/oculus_glfw_sample/rlgl.h @@ -230,6 +230,9 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion; // Color blending modes (pre-defined) typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode; + + // TraceLog message types + typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType; #endif #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 void DestroyLight(Light light); // Destroy a light and take it out of the list + +void TraceLog(int msgType, const char *text, ...); #endif #ifdef __cplusplus diff --git a/examples/oculus_glfw_sample/standard_shader.h b/examples/oculus_glfw_sample/standard_shader.h new file mode 100644 index 00000000..956b5c32 --- /dev/null +++ b/examples/oculus_glfw_sample/standard_shader.h @@ -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"; \ No newline at end of file diff --git a/src/rlgl.c b/src/rlgl.c index 6b99bf19..72225634 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -48,8 +48,13 @@ #ifdef __APPLE__ #include // OpenGL 3 library for OSX #else - #define GLAD_IMPLEMENTATION - #include "external/glad.h" // GLAD extensions loading 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 @@ -159,10 +164,6 @@ typedef struct { // TODO: Store draw state -> blending mode, shader } DrawCall; -#if defined(RLGL_STANDALONE) -typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType; -#endif - //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- @@ -259,7 +260,6 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight); #endif #if defined(RLGL_STANDALONE) -static void TraceLog(int msgType, const char *text, ...); float *MatrixToFloat(Matrix mat); // Converts Matrix to float array #endif @@ -3344,7 +3344,7 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight) #if defined(RLGL_STANDALONE) // Output a trace log message // 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_start(args, text); diff --git a/src/rlgl.h b/src/rlgl.h index 2a578a1f..9c25f710 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -230,6 +230,9 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion; // Color blending modes (pre-defined) typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode; + + // TraceLog message types + typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType; #endif #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 void DestroyLight(Light light); // Destroy a light and take it out of the list + +void TraceLog(int msgType, const char *text, ...); #endif #ifdef __cplusplus -- cgit v1.2.3 From c99fc5108e944ebd269d71037ff2c06f78f9e36f Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 8 Jun 2016 00:31:00 +0200 Subject: Update screenshot --- .../raylib_OculusRiftCV1_test03.png | Bin 182957 -> 170926 bytes 1 file changed, 0 insertions(+), 0 deletions(-) (limited to 'examples') diff --git a/examples/oculus_glfw_sample/raylib_OculusRiftCV1_test03.png b/examples/oculus_glfw_sample/raylib_OculusRiftCV1_test03.png index d2c71795..8ce10495 100644 Binary files a/examples/oculus_glfw_sample/raylib_OculusRiftCV1_test03.png and b/examples/oculus_glfw_sample/raylib_OculusRiftCV1_test03.png differ -- cgit v1.2.3 From 79a6235811de391d8ae9d0b90bf39c2160dc7907 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 8 Jun 2016 00:32:34 +0200 Subject: Stereo rendering test Trying to simulate Oculus Rift CV1 rendering without the device... for Debug pourposes. --- .../oculus_glfw_sample/rlgl_standalone_stereo.c | 394 +++++++++++++++++++++ 1 file changed, 394 insertions(+) create mode 100644 examples/oculus_glfw_sample/rlgl_standalone_stereo.c (limited to 'examples') diff --git a/examples/oculus_glfw_sample/rlgl_standalone_stereo.c b/examples/oculus_glfw_sample/rlgl_standalone_stereo.c new file mode 100644 index 00000000..8582adb4 --- /dev/null +++ b/examples/oculus_glfw_sample/rlgl_standalone_stereo.c @@ -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 // 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(); +} -- cgit v1.2.3 From b79ede4edb522b0cc5e458c49cb45d49ec902758 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Wed, 8 Jun 2016 13:29:56 +0200 Subject: Added distortion shader to render --- examples/oculus_glfw_sample/base.vs | 26 +++ examples/oculus_glfw_sample/distortion.fs | 64 +++++++ .../oculus_glfw_sample/rlgl_standalone_stereo.c | 190 ++++++++++++++++----- 3 files changed, 236 insertions(+), 44 deletions(-) create mode 100644 examples/oculus_glfw_sample/base.vs create mode 100644 examples/oculus_glfw_sample/distortion.fs (limited to 'examples') diff --git a/examples/oculus_glfw_sample/base.vs b/examples/oculus_glfw_sample/base.vs new file mode 100644 index 00000000..638cb8ae --- /dev/null +++ b/examples/oculus_glfw_sample/base.vs @@ -0,0 +1,26 @@ +#version 330 + +// Input vertex attributes +in vec3 vertexPosition; +in vec2 vertexTexCoord; +in vec3 vertexNormal; +in vec4 vertexColor; + +// Input uniform values +uniform mat4 mvpMatrix; + +// Output vertex attributes (to fragment shader) +out vec2 fragTexCoord; +out vec4 fragColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Send vertex attributes to fragment shader + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + + // Calculate final vertex position + gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/examples/oculus_glfw_sample/distortion.fs b/examples/oculus_glfw_sample/distortion.fs new file mode 100644 index 00000000..a9932651 --- /dev/null +++ b/examples/oculus_glfw_sample/distortion.fs @@ -0,0 +1,64 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; + +// Input uniform values +uniform sampler2D texture0; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables +const vec2 LeftLensCenter = vec2(0.2863248, 0.5); +const vec2 RightLensCenter = vec2(0.7136753, 0.5); +const vec2 LeftScreenCenter = vec2(0.25, 0.5); +const vec2 RightScreenCenter = vec2(0.75, 0.5); +const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); +const vec2 ScaleIn = vec2(4, 2.2222); +const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); + +/* +// Another set of default values +ChromaAbCorrection = {1.0, 0.0, 1.0, 0} +DistortionK = {1.0, 0.22, 0.24, 0} +Scale = {0.25, 0.5*AspectRatio, 0, 0} +ScaleIn = {4.0, 2/AspectRatio, 0, 0} +Left Screen Center = {0.25, 0.5, 0, 0} +Left Lens Center = {0.287994117, 0.5, 0, 0} +Right Screen Center = {0.75, 0.5, 0, 0} +Right Lens Center = {0.712005913, 0.5, 0, 0} +*/ + +// Scales input texture coordinates for distortion. +vec2 HmdWarp(vec2 in01, vec2 LensCenter) +{ + vec2 theta = (in01 - LensCenter) * ScaleIn; // Scales to [-1, 1] + float rSq = theta.x * theta.x + theta.y * theta.y; + vec2 rvector = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq); + + return LensCenter + Scale * rvector; +} + +void main() +{ + // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 + + // The following two variables need to be set per eye + vec2 LensCenter = gl_FragCoord.x < 540 ? LeftLensCenter : RightLensCenter; + vec2 ScreenCenter = gl_FragCoord.x < 540 ? LeftScreenCenter : RightScreenCenter; + + //vec2 oTexCoord = (gl_FragCoord.xy + vec2(0.5, 0.5)) / vec2(1280, 800); //Uncomment if using BGE's built-in stereo rendering + + vec2 tc = HmdWarp(fragTexCoord, LensCenter); + + if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) + { + gl_FragColor = vec4(vec3(0.0), 1.0); + } + else + { + //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); //Uncomment if using BGE's built-in stereo rendering + gl_FragColor = texture2D(texture0, tc); + } +} \ No newline at end of file diff --git a/examples/oculus_glfw_sample/rlgl_standalone_stereo.c b/examples/oculus_glfw_sample/rlgl_standalone_stereo.c index 8582adb4..1955d11e 100644 --- a/examples/oculus_glfw_sample/rlgl_standalone_stereo.c +++ b/examples/oculus_glfw_sample/rlgl_standalone_stereo.c @@ -24,11 +24,26 @@ #define RLGL_STANDALONE #include "rlgl.h" // rlgl library: OpenGL 1.1 immediate-mode style coding +#include // Required for: abs() + #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 +#define WHITE (Color){ 255, 255, 255, 255 } // White + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- + +// Rectangle type +typedef struct Rectangle { + int x; + int y; + int width; + int height; +} Rectangle; //---------------------------------------------------------------------------------- // Module specific Functions Declaration @@ -41,6 +56,8 @@ 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); +static void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); +static void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint); //---------------------------------------------------------------------------------- // Main Entry point @@ -52,7 +69,6 @@ int main(void) const int screenWidth = 1080; const int screenHeight = 600; - // GLFW3 Initialization + OpenGL 3.3 Context + Extensions //-------------------------------------------------------- glfwSetErrorCallback(ErrorCallback); @@ -100,6 +116,14 @@ int main(void) rlClearColor(245, 245, 245, 255); // Define clear color rlEnableDepthTest(); // Enable DEPTH_TEST for 3D + Shader distortion = LoadShader("base.vs", "distortion.fs"); + + // TODO: Upload to distortion shader configuration parameters (screen size, etc.) + //SetShaderValue(Shader shader, int uniformLoc, float *value, int size); + + // Create a RenderTexture2D to be used for render to texture + RenderTexture2D target = rlglLoadRenderTexture(screenWidth, screenHeight); + Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; Camera camera; @@ -119,51 +143,75 @@ int main(void) // Draw //---------------------------------------------------------------------------------- + rlEnableRenderTexture(target.id); // Enable render target + 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 + // TODO: Consider every eye fovy + Matrix matProj = MatrixPerspective(camera.fovy, (double)(screenWidth/2)/(double)screenHeight, 0.01, 1000.0); + MatrixTranspose(&matProj); + + // TODO: Recalculate view matrix considering IPD (inter-pupillary-distance) + 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 + // TODO: 2D not drawing properly on stereo rendering + //DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 500.0f, 20.0f }, DARKGRAY); + + // NOTE: Internal buffers drawing (2D data) + rlglDraw(); + } - for (int i = 0; i < 2; i++) - { - rlViewport(i*screenWidth/2, 0, screenWidth/2, screenHeight); + rlDisableRenderTexture(); // Disable render target + + // Set viewport to default framebuffer size (screen size) + rlViewport(0, 0, screenWidth, 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(); - } + // Let rlgl reconfigure internal matrices using OpenGL 1.1 style coding + 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 + + // Draw RenderTexture (fbo) using distortion shader + BeginShaderMode(distortion); + // NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom) + DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE); + EndShaderMode(); glfwSwapBuffers(window); glfwPollEvents(); @@ -172,7 +220,9 @@ int main(void) // De-Initialization //-------------------------------------------------------------------------------------- - rlglClose(); // Unload rlgl internal buffers and default shader/texture + UnloadShader(distortion); + + rlglClose(); // Unload rlgl internal buffers and default shader/texture glfwDestroyWindow(window); glfwTerminate(); @@ -392,3 +442,55 @@ void DrawCubeWires(Vector3 position, float width, float height, float length, Co rlEnd(); rlPopMatrix(); } + +// Draw a part of a texture (defined by a rectangle) +static void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint) +{ + Rectangle destRec = { (int)position.x, (int)position.y, abs(sourceRec.width), abs(sourceRec.height) }; + Vector2 origin = { 0, 0 }; + + DrawTexturePro(texture, sourceRec, destRec, origin, 0.0f, tint); +} + +// Draw a part of a texture (defined by a rectangle) with 'pro' parameters +// NOTE: origin is relative to destination rectangle size +static void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint) +{ + // Check if texture is valid + if (texture.id != 0) + { + if (sourceRec.width < 0) sourceRec.x -= sourceRec.width; + if (sourceRec.height < 0) sourceRec.y -= sourceRec.height; + + rlEnableTexture(texture.id); + + rlPushMatrix(); + rlTranslatef(destRec.x, destRec.y, 0); + rlRotatef(rotation, 0, 0, 1); + rlTranslatef(-origin.x, -origin.y, 0); + + rlBegin(RL_QUADS); + rlColor4ub(tint.r, tint.g, tint.b, tint.a); + rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer + + // Bottom-left corner for texture and quad + rlTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height); + rlVertex2f(0.0f, 0.0f); + + // Bottom-right corner for texture and quad + rlTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height); + rlVertex2f(0.0f, destRec.height); + + // Top-right corner for texture and quad + rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height); + rlVertex2f(destRec.width, destRec.height); + + // Top-left corner for texture and quad + rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height); + rlVertex2f(destRec.width, 0.0f); + rlEnd(); + rlPopMatrix(); + + rlDisableTexture(); + } +} -- cgit v1.2.3 From 5576dea00b54421f96babbdcc7c672ded620455e Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 8 Jun 2016 18:27:43 +0200 Subject: Rename raylib_rlgl_standalone.c to rlgl_standalone.c --- .../oculus_glfw_sample/raylib_rlgl_standalone.c | 389 --------------------- examples/oculus_glfw_sample/rlgl_standalone.c | 389 +++++++++++++++++++++ 2 files changed, 389 insertions(+), 389 deletions(-) delete mode 100644 examples/oculus_glfw_sample/raylib_rlgl_standalone.c create mode 100644 examples/oculus_glfw_sample/rlgl_standalone.c (limited to 'examples') diff --git a/examples/oculus_glfw_sample/raylib_rlgl_standalone.c b/examples/oculus_glfw_sample/raylib_rlgl_standalone.c deleted file mode 100644 index 4728160a..00000000 --- a/examples/oculus_glfw_sample/raylib_rlgl_standalone.c +++ /dev/null @@ -1,389 +0,0 @@ -/******************************************************************************************* -* -* 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 // 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 = 800; - const int screenHeight = 450; - - - // 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 = 45.0f; // Camera field-of-view Y - //-------------------------------------------------------------------------------------- - - // Main game loop - while (!glfwWindowShouldClose(window)) - { - // Update - //---------------------------------------------------------------------------------- - // ... - //---------------------------------------------------------------------------------- - - // Draw - //---------------------------------------------------------------------------------- - rlClearScreenBuffers(); // Clear current framebuffer - - // 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); - 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, 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(); -} diff --git a/examples/oculus_glfw_sample/rlgl_standalone.c b/examples/oculus_glfw_sample/rlgl_standalone.c new file mode 100644 index 00000000..4728160a --- /dev/null +++ b/examples/oculus_glfw_sample/rlgl_standalone.c @@ -0,0 +1,389 @@ +/******************************************************************************************* +* +* 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 // 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 = 800; + const int screenHeight = 450; + + + // 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 = 45.0f; // Camera field-of-view Y + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!glfwWindowShouldClose(window)) + { + // Update + //---------------------------------------------------------------------------------- + // ... + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + rlClearScreenBuffers(); // Clear current framebuffer + + // 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); + 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, 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(); +} -- cgit v1.2.3 From 2d90cc59b6a338f9745dc1be398f8d8bef3f47bf Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 8 Jun 2016 18:48:25 +0200 Subject: Update distortion.fs --- examples/oculus_glfw_sample/distortion.fs | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'examples') diff --git a/examples/oculus_glfw_sample/distortion.fs b/examples/oculus_glfw_sample/distortion.fs index a9932651..cd5951fe 100644 --- a/examples/oculus_glfw_sample/distortion.fs +++ b/examples/oculus_glfw_sample/distortion.fs @@ -33,11 +33,11 @@ Right Lens Center = {0.712005913, 0.5, 0, 0} // Scales input texture coordinates for distortion. vec2 HmdWarp(vec2 in01, vec2 LensCenter) { - vec2 theta = (in01 - LensCenter) * ScaleIn; // Scales to [-1, 1] - float rSq = theta.x * theta.x + theta.y * theta.y; - vec2 rvector = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq); + vec2 theta = (in01 - LensCenter)*ScaleIn; // Scales to [-1, 1] + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 rvector = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); - return LensCenter + Scale * rvector; + return LensCenter + Scale*rvector; } void main() @@ -48,17 +48,12 @@ void main() vec2 LensCenter = gl_FragCoord.x < 540 ? LeftLensCenter : RightLensCenter; vec2 ScreenCenter = gl_FragCoord.x < 540 ? LeftScreenCenter : RightScreenCenter; - //vec2 oTexCoord = (gl_FragCoord.xy + vec2(0.5, 0.5)) / vec2(1280, 800); //Uncomment if using BGE's built-in stereo rendering - vec2 tc = HmdWarp(fragTexCoord, LensCenter); - if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) - { - gl_FragColor = vec4(vec3(0.0), 1.0); - } + if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); else { - //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); //Uncomment if using BGE's built-in stereo rendering - gl_FragColor = texture2D(texture0, tc); + //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); + finalColor = texture2D(texture0, tc); } -} \ No newline at end of file +} -- cgit v1.2.3 From 904ef0d4be1937b067ed55b2bf07b6ba34a78754 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 8 Jun 2016 22:55:38 +0200 Subject: Adjust to standard example screen size --- examples/shaders_standard_lighting.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'examples') diff --git a/examples/shaders_standard_lighting.c b/examples/shaders_standard_lighting.c index ccbe74ca..f2b35171 100644 --- a/examples/shaders_standard_lighting.c +++ b/examples/shaders_standard_lighting.c @@ -22,8 +22,8 @@ int main() { // Initialization //-------------------------------------------------------------------------------------- - int screenWidth = 1280; - int screenHeight = 720; + int screenWidth = 800; + int screenHeight = 450; SetConfigFlags(FLAG_MSAA_4X_HINT); // Enable Multi Sampling Anti Aliasing 4x (if available) -- cgit v1.2.3 From 374e3e7e116af2d4ddd8c402cee0a42d9d5bd318 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 9 Jun 2016 01:23:07 +0200 Subject: Updated to raylib 1.5 --- CHANGELOG | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- LICENSE.md | 2 +- README.md | 63 ++++++++++++++++++++++++++++++--------- ROADMAP.md | 14 ++++++--- examples/Makefile | 2 +- 5 files changed, 148 insertions(+), 22 deletions(-) (limited to 'examples') diff --git a/CHANGELOG b/CHANGELOG index 795a2ee5..5024dc6e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,16 +1,101 @@ changelog --------- -Current Release: raylib 1.4.0 (22 February 2016) +Current Release: raylib 1.5.0 (23 June 2016) NOTE: Only versions marked as 'Release' are available in installer, updates are only available as source. NOTE: Current Release includes all previous updates. +----------------------------------------------- +Release: raylib 1.5.0 (23 June 2016) +----------------------------------------------- +NOTE: + Probably this new version is the biggest boost of the library ever, lots of parts of the library have been redesigned, + lots of bugs have been solved and some **AMAZING** new features have been added. + +HUGE changes: +[core] OCULUS RIFT CV1: Added support for VR witha bunch of Oculus-specific functions to init/close device and Oculus rendering. +[rlgl] MATERIALS SYSTEM: Added support for Materials (.mtl) and multiple material properties: diffuse, specular, normal. +[rlgl] LIGHTING SYSTEM: Added support for up to 8 lights of 3 different types: Omni, Directional and Spot +[physac] REDESIGNED: Improved performance and simplified usage, physic objects are managed internally +[audio] CHIPTUNES: Added support for module audio music (.xm, .mod) loading and playing + +other changes: + +[core] Review Android button inputs +[core] Support Android internal data storage +[core] Renamed WorldToScreen() to GetWorldToScreen() +[core] Removed function SetCustomCursor() +[core] Removed functions BeginDrawingEx(), BeginDrawingPro() +[core] Added support for field-of-view Y (fovy) on 3d Camera +[core] Added 2D camera mode functions: Begin2dMode() - End2dMode() +[core] Translate mouse inputs to Android touch/gestures internally +[core] Translate mouse inputs as touch inputs in HTML5 +[core] Improved function GetKeyPressed() to support multiple keys (including function keys) +[core] Improved gamepad support, specially for RaspberryPi (including multiple gamepads support) +[rlgl] Improved 2D vs 3D drawing system (lines, triangles, quads) +[rlgl] Improved DXT-ETC1 support on HTML5 +[rlgl] Review function: rlglUnproject() +[rlgl] Updated Mesh and Shader structs +[rlgl] Simplified internal (default) dynamic buffers +[rlgl] Added support for indexed and dynamic mesh data +[rlgl] Set fixed vertex attribs location points +[rlgl] Improved mesh data loading support +[rlgl] Added standard shader (embeded) to support materials and lighting: standard_shader.h +[rlgl] Added light functions: CreateLight(), DestroyLight() +[rlgl] Added wire mode functions: rlDisableWireMode(), rlEnableWireMode() +[rlgl] Review function consistency, added: rlglLoadMesh(), rlglUpdateMesh(), rlglDrawMesh(), rlglUnloadMesh() +[rlgl] Replaced SetCustomShader() by: BeginShaderMode() - EndShaderMode() +[rlgl] Replaced SetBlendMode() by: BeginBlendMode() - EndBlendMode() +[rlgl] Added functions to customize internal matrices: SetMatrixProjection(), SetMatrixModelview() +[rlgl] Unified internal shaders to only one default shader +[rlgl] Added support for render to texture (RenderTexture2D): + LoadRenderTexture() - UnloadRenderTexture() + BeginTextureMode() - EndTextureMode() +[rlgl] Removed SetShaderMap*() functions +[rlgl] Redesigned default buffers usage functions: + LoadDefaultBuffers() - UnloadDefaultBuffers() + UpdateDefaultBuffers() - DrawDefaultBuffers() +[shapes] Corrected bug on GetCollisionRec() +[textures] Added support for Nearest-Neighbor image scaling +[textures] Added functions to draw text on image: ImageDrawText(), ImageDrawTextEx() +[text] Reorganized internal functions: Added LoadImageFont() +[text] Security check for unsupported BMFonts +[models] Split mesh creation from model loading on heightmap and cubicmap +[models] Updated BoundingBox collision detections +[models] Added color parameter to DrawBoundigBox() +[models] Removed function: DrawQuad() +[models] Redesigned DrawPlane() to use RL_TRIANGLES +[models] Redesigned DrawRectangleV() to use RL_TRIANGLES +[models] Redesign to accomodate new materials system: LoadMaterial() +[models] Added material functions: LoadDefaultMaterial(), LoadStandardMaterial() +[models] Added MTL material loading support: LoadMTL() +[models] Added function: DrawLight() +[audio] Renamed SoundIsPlaying() to IsSoundPlaying() +[audio] Renamed MusicIsPlaying() to IsMusicPlaying() +[audio] Support multiple Music streams (indexed) +[gestures] Improved and reviewed gestures system +[raymath] Added QuaternionInvert() +[raymath] Removed function: PrintMatrix() +[raygui] Ported to header-only library +[shaders] Added depth drawing shader (requires a depth texture) +[shaders] Reviewed included shaders and added comments +[OpenAL Soft] Updated to latest version (1.17.2) +[GLFW3] Updated to latest version (3.2) +[GLAD] Converted to header only library +[stb] Updated to latest headers versions +[*] Reorganize library folders: external libs moved to src/external folder +[*] Reorganize src folder for Android library +[*] Review external dependencies usage +[*] Improved Linux and OSX build systems +[*] Lots of tweaks and bugs corrected all around + + ----------------------------------------------- Release: raylib 1.4.0 (22 February 2016) ----------------------------------------------- NOTE: - This version supposed another big improvement for raylib, inlcuding new modules and new features. + This version supposed another big improvement for raylib, including new modules and new features. More than 30 new functions have been added to previous raylib version. Around 8 new examples and +10 new game samples have been added. diff --git a/LICENSE.md b/LICENSE.md index 766f6987..e1cd5245 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -7,7 +7,7 @@ source code raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified, BSD-like license that allows static linking with closed source software: -Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com) +Copyright (c) 2013-2016 Ramon Santamaria (@raysan5) 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. diff --git a/README.md b/README.md index 5f6fea7f..8a1f5c96 100644 --- a/README.md +++ b/README.md @@ -101,40 +101,70 @@ Lots of code changes and lot of testing have concluded in this amazing new rayli notes on raylib 1.4 ------------------- -On February 2016, after 4 months of raylib 1.3 release, it comes raylib 1.4. For this new version, lots of parts of the library have been reviewed, lots of bugs have been solved and some interesting features have been added. +On February 2016, after 4 months of raylib 1.3 release, it comes raylib 1.4. For this new version, +lots of parts of the library have been reviewed, lots of bugs have been solved and some interesting features have been added. -First big addition is a set of [Image manipulation functions](https://github.com/raysan5/raylib/blob/develop/src/raylib.h#L673) have been added to crop, resize, colorize, flip, dither and even draw image-to-image or text-to-image. Now a basic image processing can be done before converting the image to texture for usage. +First big addition is a set of [Image manipulation functions](https://github.com/raysan5/raylib/blob/develop/src/raylib.h#L673) have been added to crop, resize, colorize, flip, dither and even draw image-to-image or text-to-image. +Now a basic image processing can be done before converting the image to texture for usage. -SpriteFonts system has been improved, adding support for AngelCode fonts (.fnt) and TrueType Fonts (using [stb_truetype](https://github.com/nothings/stb/blob/master/stb_truetype.h) helper library). Now raylib can read standard .fnt font data and also generate at loading a SpriteFont from a TTF file. +SpriteFonts system has been improved, adding support for AngelCode fonts (.fnt) and TrueType Fonts (using [stb_truetype](https://github.com/nothings/stb/blob/master/stb_truetype.h) helper library). +Now raylib can read standard .fnt font data and also generate at loading a SpriteFont from a TTF file. -New [physac](https://github.com/raysan5/raylib/blob/develop/src/physac.h) physics module for basic 2D physics support. Still in development but already functional. Module comes with some usage examples for basic jump and level interaction and also force-based physic movements. +New [physac](https://github.com/raysan5/raylib/blob/develop/src/physac.h) physics module for basic 2D physics support. Still in development but already functional. +Module comes with some usage examples for basic jump and level interaction and also force-based physic movements. [raymath](https://github.com/raysan5/raylib/blob/develop/src/raymath.h) module has been reviewed; some bugs have been solved and the module has been converted to a header-only file for easier portability, optionally, functions can also be used as inline. -[gestures](https://github.com/raysan5/raylib/blob/develop/src/gestures.c) module has redesigned and simplified, now it can process touch events from any source, including mouse. This way, gestures system can be used on any platform providing an unified way to work with inputs and allowing the user to create multiplatform games with only one source code. +[gestures](https://github.com/raysan5/raylib/blob/develop/src/gestures.c) module has redesigned and simplified, now it can process touch events from any source, including mouse. +This way, gestures system can be used on any platform providing an unified way to work with inputs and allowing the user to create multiplatform games with only one source code. -Raspberry Pi input system has been redesigned to better read raw inputs using generic Linux event handlers (keyboard:`stdin`, mouse:`/dev/input/mouse0`, gamepad:`/dev/input/js0`). Gamepad support has also been added (experimental). +Raspberry Pi input system has been redesigned to better read raw inputs using generic Linux event handlers (keyboard:`stdin`, mouse:`/dev/input/mouse0`, gamepad:`/dev/input/js0`). +Gamepad support has also been added (experimental). -Other important improvements are the functional raycast system for 3D picking, including some ray collision-detection functions, and the addition of two simple functions for persistent data storage. Now raylib user can save and load game data in a file (only some platforms supported). A simple [easings](https://github.com/raysan5/raylib/blob/develop/src/easings.h) module has also been added for values animation. +Other important improvements are the functional raycast system for 3D picking, including some ray collision-detection functions, +and the addition of two simple functions for persistent data storage. Now raylib user can save and load game data in a file (only some platforms supported). +A simple [easings](https://github.com/raysan5/raylib/blob/develop/src/easings.h) module has also been added for values animation. -Up to 8 new code examples have been added to show the new raylib features and +10 complete game samples have been provided to learn how to create some classic games like Arkanoid, Asteroids, Missile Commander, Snake or Tetris. +Up to 8 new code examples have been added to show the new raylib features and +10 complete game samples have been provided to learn +how to create some classic games like Arkanoid, Asteroids, Missile Commander, Snake or Tetris. Lots of code changes and lots of hours of hard work have concluded in this amazing new raylib 1.4. +notes on raylib 1.5 +------------------- + +On June 2016, after 4 months of raylib 1.4 release, arrives raylib 1.5. Probably this new version is the biggest boost of the library ever, +lots of parts of the library have been redesigned, lots of bugs have been solved and some **AMAZING** new features have been added. + +New platform support: **Oculus Rift CV1**. raylib introduces VR support for one the most anticipated VR devices in the market. +Supporting Oculus Rift CV1 device makes raylib the only (or one of the few) C libraries in the market to support VR out-of-the-box. + +New materials system: + +New lighting system: + +Complete gamepad support on Raspberry Pi + +Redesigned physics module: physac + +Up to 8 new code examples have been added to show the new raylib features and the usage of multiple raylib modules as standalone libraries (rlgl, audio). + +Lots of code changes (more than 250 commits) and lots of hours of hard work have concluded in this amazing new raylib 1.5. + features -------- * Written in plain C code (C99) * Uses C# PascalCase/camelCase notation - * Hardware accelerated with OpenGL (1.1, 3.3 or ES2) + * Hardware accelerated with OpenGL (1.1, 2.1, 3.3 or ES2) * Unique OpenGL abstraction layer (usable as standalone module): [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.c) * Powerful fonts module with multiple SpriteFonts formats support (XNA bitmap fonts, AngelCode fonts, TTF) * Outstanding texture formats support, including compressed formats (DXT, ETC, PVRT, ASTC) * Basic 3d support for Shapes, Models, Billboards, Heightmaps and Cubicmaps * Powerful math module for Vector and Matrix operations: [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.c) - * Audio loading and playing with streaming support (WAV and OGG) + * Audio loading and playing with streaming support (WAV, OGG, XM, MOD) * Custom color palette for fancy visuals on raywhite background - * Multiple platforms support: Windows, Linux, Mac, **Android**, **Raspberry Pi** and **HTML5** + * Multiple platforms support: Windows, Linux, Mac, **Android**, **Raspberry Pi**, **HTML5** and **Oculus Rift CV1** raylib uses on its core module the outstanding [GLFW3](http://www.glfw.org/) library. The best option by far I found for multiplatform (Windows, Linux, Mac) window/context and input management (clean, focused, great license, well documented, modern, ...). @@ -191,21 +221,26 @@ If you feel you can help, then, [helpme!](http://www.raylib.com/helpme.htm) acknowledgements --------------- -The following people have contributed in some way to make raylib project a reality. Big thanks to them! +I believe that time is the most valuable resource and the following people have invested part of their time +contributing (in some way or another) to make raylib project better. Huge thanks! - [Zopokx](https://github.com/Zopokx) for testing the web. - [Elendow](http://www.elendow.com) for testing and helping on web development. - Victor Dual for implementating and testing of 3D shapes functions. - - Marc Palau for implementating and testing of 3D shapes functions and helping on development of camera and getures modules. + - Marc Palau for implementating and testing of 3D shapes functions and helping on development of camera and gestures modules. - Kevin Gato for improving texture internal formats support and helping on raygui development. - Daniel Nicolas for improving texture internal formats support and helping on raygui development. - Marc Agüera for testing and using raylib on a real product ([Koala Seasons](http://www.koalaseasons.com)) - Daniel Moreno for testing and using raylib on a real product ([Koala Seasons](http://www.koalaseasons.com)) - Daniel Gomez for testing and using raylib on a real product ([Koala Seasons](http://www.koalaseasons.com)) - Sergio Martinez for helping on raygui development and tools development. - - Victor Fisac for developing physics raylib module (physac) and implementing light shaders and raycast system... and multiple tools and games. + - [Victor Fisac](https://github.com/victorfisac) for developing physics raylib module (physac) and implementing materials and lighting systems... among multiple other improvements and multiple tools and games. - Albert Martos for helping on raygui and porting examples and game-templates to Android and HTML5. - Ian Eito for helping on raygui and porting examples and game-templates to Android and HTML5. + - [procedural](https://github.com/procedural) for testing raylib on Linux, correcting some bugs and adding several mouse functions. + - [Chris Hemingway](https://github.com/cHemingway) for improving raylib on OSX build system. + - [Emanuele Petriglia](https://github.com/LelixSuper) for working on multiple GNU/Linux improvements and developing [TicTacToe](https://github.com/LelixSuper/TicTacToe) raylib game. + - [Joshua Reisenauer](https://github.com/kd7tck) for adding audio modules (XM, MOD) support and audio system redesign. [raysan5]: mailto:raysan5@gmail.com "Ramon Santamaria - Ray San" diff --git a/ROADMAP.md b/ROADMAP.md index aaa1a256..0253ad3d 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -6,16 +6,22 @@ Here it is a wish list of features I would like to add and functions to improve. Note that around the raylib source code there are multiple TODO points with pending revisions/bugs. Check [GitHub Issues](https://github.com/raysan5/raylib/issues) for further details! -raylib 1.5 +raylib 1.x - Redesign Shaders/Textures system, use Materials - Redesign physics module (physac) + [IN PROGRESS] LUA scripting support (wrapper to lua lib) Basic GPU stats sytem (memory, draws, time...) Procedural image generation functions (spot, gradient, noise...) Procedural mesh generation functions (cube, cone, sphere...) Touch-based camera controls for Android Skybox and Fog support - [IN PROGRESS] LUA scripting support (wrapper to lua lib) + +raylib 1.5 + + [DONE] Support Oculus Rift CV1 + [DONE] Redesign Shaders/Textures system -> New Materials system + [DONE] Support lighting: Omni, Directional and Spot lights + [DONE] Redesign physics module (physac) + [DONE] Chiptunes audio modules support raylib 1.4 diff --git a/examples/Makefile b/examples/Makefile index 534adee8..2d2344af 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -2,7 +2,7 @@ # # raylib makefile for desktop platforms, Raspberry Pi and HTML5 (emscripten) # -# Copyright (c) 2015 Ramon Santamaria (@raysan5) +# Copyright (c) 2013-2016 Ramon Santamaria (@raysan5) # # 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. -- cgit v1.2.3 From 3c1be60c6615fdcf8d2e3ddec2c9d7de8174b280 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Thu, 9 Jun 2016 20:02:42 +0200 Subject: Updated examples for new physac header-only --- examples/physics_basic_rigidbody.c | 21 ++++++++++++--------- examples/physics_forces.c | 27 ++++++++++++++------------- 2 files changed, 26 insertions(+), 22 deletions(-) (limited to 'examples') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index cd09f070..8870c55b 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -11,6 +11,9 @@ #include "raylib.h" +#define PHYSAC_IMPLEMENTATION +#include "physac.h" + #define MOVE_VELOCITY 5 #define JUMP_VELOCITY 30 @@ -22,35 +25,35 @@ int main() int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [physac] example - basic rigidbody"); - InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module - SetTargetFPS(60); + InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module // Debug variables bool isDebug = false; // Create rectangle physic object - PhysicObject rectangle = CreatePhysicObject((Vector2){ screenWidth*0.25f, screenHeight/2 }, 0.0f, (Vector2){ 75, 50 }); + PhysicBody rectangle = CreatePhysicBody((Vector2){ screenWidth*0.25f, screenHeight/2 }, 0.0f, (Vector2){ 75, 50 }); rectangle->rigidbody.enabled = true; // Enable physic object rigidbody behaviour rectangle->rigidbody.applyGravity = true; rectangle->rigidbody.friction = 0.1f; rectangle->rigidbody.bounciness = 6.0f; // Create square physic object - PhysicObject square = CreatePhysicObject((Vector2){ screenWidth*0.75f, screenHeight/2 }, 0.0f, (Vector2){ 50, 50 }); + PhysicBody square = CreatePhysicBody((Vector2){ screenWidth*0.75f, screenHeight/2 }, 0.0f, (Vector2){ 50, 50 }); square->rigidbody.enabled = true; // Enable physic object rigidbody behaviour square->rigidbody.applyGravity = true; square->rigidbody.friction = 0.1f; // Create walls physic objects - PhysicObject floor = CreatePhysicObject((Vector2){ screenWidth/2, screenHeight*0.95f }, 0.0f, (Vector2){ screenWidth*0.9f, 100 }); - PhysicObject leftWall = CreatePhysicObject((Vector2){ 0.0f, screenHeight/2 }, 0.0f, (Vector2){ screenWidth*0.1f, screenHeight }); - PhysicObject rightWall = CreatePhysicObject((Vector2){ screenWidth, screenHeight/2 }, 0.0f, (Vector2){ screenWidth*0.1f, screenHeight }); - PhysicObject roof = CreatePhysicObject((Vector2){ screenWidth/2, screenHeight*0.05f }, 0.0f, (Vector2){ screenWidth*0.9f, 100 }); + PhysicBody floor = CreatePhysicBody((Vector2){ screenWidth/2, screenHeight*0.95f }, 0.0f, (Vector2){ screenWidth*0.9f, 100 }); + PhysicBody leftWall = CreatePhysicBody((Vector2){ 0.0f, screenHeight/2 }, 0.0f, (Vector2){ screenWidth*0.1f, screenHeight }); + PhysicBody rightWall = CreatePhysicBody((Vector2){ screenWidth, screenHeight/2 }, 0.0f, (Vector2){ screenWidth*0.1f, screenHeight }); + PhysicBody roof = CreatePhysicBody((Vector2){ screenWidth/2, screenHeight*0.05f }, 0.0f, (Vector2){ screenWidth*0.9f, 100 }); // Create pplatform physic object - PhysicObject platform = CreatePhysicObject((Vector2){ screenWidth/2, screenHeight*0.7f }, 0.0f, (Vector2){ screenWidth*0.25f, 20 }); + PhysicBody platform = CreatePhysicBody((Vector2){ screenWidth/2, screenHeight*0.7f }, 0.0f, (Vector2){ screenWidth*0.25f, 20 }); + SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop diff --git a/examples/physics_forces.c b/examples/physics_forces.c index f4eefa05..3e90a21d 100644 --- a/examples/physics_forces.c +++ b/examples/physics_forces.c @@ -10,15 +10,15 @@ ********************************************************************************************/ #include "raylib.h" -#include "math.h" + +#define PHYSAC_IMPLEMENTATION +#include "physac.h" #define FORCE_AMOUNT 5.0f #define FORCE_RADIUS 150 #define LINE_LENGTH 75 #define TRIANGLE_LENGTH 12 -void DrawRigidbodyCircle(PhysicObject obj, Color color); - int main() { // Initialization @@ -27,29 +27,28 @@ int main() int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [physac] example - forces"); - InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module - SetTargetFPS(60); + InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module // Global variables Vector2 mousePosition; bool isDebug = false; // Create rectangle physic objects - PhysicObject rectangles[3]; + PhysicBody rectangles[3]; for (int i = 0; i < 3; i++) { - rectangles[i] = CreatePhysicObject((Vector2){ screenWidth/4*(i+1), (((i % 2) == 0) ? (screenHeight/3) : (screenHeight/1.5f)) }, 0.0f, (Vector2){ 50, 50 }); + rectangles[i] = CreatePhysicBody((Vector2){ screenWidth/4*(i+1), (((i % 2) == 0) ? (screenHeight/3) : (screenHeight/1.5f)) }, 0.0f, (Vector2){ 50, 50 }); rectangles[i]->rigidbody.enabled = true; // Enable physic object rigidbody behaviour rectangles[i]->rigidbody.friction = 0.1f; } // Create circles physic objects // NOTE: when creating circle physic objects, transform.scale must be { 0, 0 } and object radius must be defined in collider.radius and use this value to draw the circle. - PhysicObject circles[3]; + PhysicBody circles[3]; for (int i = 0; i < 3; i++) { - circles[i] = CreatePhysicObject((Vector2){ screenWidth/4*(i+1), (((i % 2) == 0) ? (screenHeight/1.5f) : (screenHeight/4)) }, 0.0f, (Vector2){ 0, 0 }); + circles[i] = CreatePhysicBody((Vector2){ screenWidth/4*(i+1), (((i % 2) == 0) ? (screenHeight/1.5f) : (screenHeight/4)) }, 0.0f, (Vector2){ 0, 0 }); circles[i]->rigidbody.enabled = true; // Enable physic object rigidbody behaviour circles[i]->rigidbody.friction = 0.1f; circles[i]->collider.type = COLLIDER_CIRCLE; @@ -57,11 +56,12 @@ int main() } // Create walls physic objects - PhysicObject leftWall = CreatePhysicObject((Vector2){ -25, screenHeight/2 }, 0.0f, (Vector2){ 50, screenHeight }); - PhysicObject rightWall = CreatePhysicObject((Vector2){ screenWidth + 25, screenHeight/2 }, 0.0f, (Vector2){ 50, screenHeight }); - PhysicObject topWall = CreatePhysicObject((Vector2){ screenWidth/2, -25 }, 0.0f, (Vector2){ screenWidth, 50 }); - PhysicObject bottomWall = CreatePhysicObject((Vector2){ screenWidth/2, screenHeight + 25 }, 0.0f, (Vector2){ screenWidth, 50 }); + PhysicBody leftWall = CreatePhysicBody((Vector2){ -25, screenHeight/2 }, 0.0f, (Vector2){ 50, screenHeight }); + PhysicBody rightWall = CreatePhysicBody((Vector2){ screenWidth + 25, screenHeight/2 }, 0.0f, (Vector2){ 50, screenHeight }); + PhysicBody topWall = CreatePhysicBody((Vector2){ screenWidth/2, -25 }, 0.0f, (Vector2){ screenWidth, 50 }); + PhysicBody bottomWall = CreatePhysicBody((Vector2){ screenWidth/2, screenHeight + 25 }, 0.0f, (Vector2){ screenWidth, 50 }); + SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop @@ -175,6 +175,7 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- ClosePhysics(); // Unitialize physics module + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- -- cgit v1.2.3 From 77f599885dade4930fb01baca22db6e2ae0c9f20 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Fri, 10 Jun 2016 00:59:48 +0200 Subject: Fixed GLSL 100 shaders texture() doesn't exist in glsl 100, it must use texture2D(). --- examples/resources/shaders/glsl100/bloom.fs | 2 +- examples/resources/shaders/glsl100/grayscale.fs | 2 +- shaders/glsl100/bloom.fs | 2 +- shaders/glsl100/grayscale.fs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'examples') diff --git a/examples/resources/shaders/glsl100/bloom.fs b/examples/resources/shaders/glsl100/bloom.fs index 280d2fb6..128736f2 100644 --- a/examples/resources/shaders/glsl100/bloom.fs +++ b/examples/resources/shaders/glsl100/bloom.fs @@ -26,7 +26,7 @@ void main() } // Texel color fetching from texture sampler - vec4 texelColor = texture(texture0, fragTexCoord); + vec4 texelColor = texture2D(texture0, fragTexCoord); // Calculate final fragment color if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor; diff --git a/examples/resources/shaders/glsl100/grayscale.fs b/examples/resources/shaders/glsl100/grayscale.fs index f92ec335..cf857488 100644 --- a/examples/resources/shaders/glsl100/grayscale.fs +++ b/examples/resources/shaders/glsl100/grayscale.fs @@ -15,7 +15,7 @@ uniform vec4 fragTintColor; void main() { // Texel color fetching from texture sampler - vec4 texelColor = texture(texture0, fragTexCoord)*fragTintColor*fragColor; + vec4 texelColor = texture2D(texture0, fragTexCoord)*fragTintColor*fragColor; // Convert texel color to grayscale using NTSC conversion weights float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); diff --git a/shaders/glsl100/bloom.fs b/shaders/glsl100/bloom.fs index 280d2fb6..128736f2 100644 --- a/shaders/glsl100/bloom.fs +++ b/shaders/glsl100/bloom.fs @@ -26,7 +26,7 @@ void main() } // Texel color fetching from texture sampler - vec4 texelColor = texture(texture0, fragTexCoord); + vec4 texelColor = texture2D(texture0, fragTexCoord); // Calculate final fragment color if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor; diff --git a/shaders/glsl100/grayscale.fs b/shaders/glsl100/grayscale.fs index c76dd8af..15174ea5 100644 --- a/shaders/glsl100/grayscale.fs +++ b/shaders/glsl100/grayscale.fs @@ -15,7 +15,7 @@ uniform vec4 colDiffuse; void main() { // Texel color fetching from texture sampler - vec4 texelColor = texture(texture0, fragTexCoord)*colDiffuse*fragColor; + vec4 texelColor = texture2D(texture0, fragTexCoord)*colDiffuse*fragColor; // Convert texel color to grayscale using NTSC conversion weights float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); -- cgit v1.2.3 From 4c43a407888d516b38191b5df76e373dae6ec58e Mon Sep 17 00:00:00 2001 From: victorfisac Date: Sat, 11 Jun 2016 19:11:30 +0200 Subject: Update physac examples with fixed timestep method --- examples/physics_basic_rigidbody.c | 32 ++++++++++++++++++++++++++++++-- examples/physics_forces.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 3 deletions(-) (limited to 'examples') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index 8870c55b..24570426 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -13,10 +13,13 @@ #define PHYSAC_IMPLEMENTATION #include "physac.h" +#include #define MOVE_VELOCITY 5 #define JUMP_VELOCITY 30 +void* PhysicsThread(void *arg); + int main() { // Initialization @@ -53,6 +56,10 @@ int main() // Create pplatform physic object PhysicBody platform = CreatePhysicBody((Vector2){ screenWidth/2, screenHeight*0.7f }, 0.0f, (Vector2){ screenWidth*0.25f, 20 }); + // Create physics thread + pthread_t tid; + pthread_create(&tid, NULL, &PhysicsThread, NULL); + SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -61,10 +68,9 @@ int main() { // Update //---------------------------------------------------------------------------------- - UpdatePhysics(); // Update all created physic objects // Check rectangle movement inputs - if (IsKeyDown('W') && rectangle->rigidbody.isGrounded) rectangle->rigidbody.velocity.y = JUMP_VELOCITY; + if (IsKeyPressed('W')) rectangle->rigidbody.velocity.y = JUMP_VELOCITY; if (IsKeyDown('A')) rectangle->rigidbody.velocity.x = -MOVE_VELOCITY; else if (IsKeyDown('D')) rectangle->rigidbody.velocity.x = MOVE_VELOCITY; @@ -117,10 +123,32 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- + pthread_cancel(tid); // Destroy physics thread + ClosePhysics(); // Unitialize physics (including all loaded objects) CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; +} + +void* PhysicsThread(void *arg) +{ + // Initialize time variables + double currentTime = GetTime(); + double previousTime = currentTime; + + // Physics update loop + while (!WindowShouldClose()) + { + currentTime = GetTime(); + double deltaTime = (double)(currentTime - previousTime); + previousTime = currentTime; + + // Delta time value needs to be inverse multiplied by physics time step value (1/target fps) + UpdatePhysics(deltaTime/PHYSICS_TIMESTEP); + } + + return NULL; } \ No newline at end of file diff --git a/examples/physics_forces.c b/examples/physics_forces.c index 3e90a21d..397c2331 100644 --- a/examples/physics_forces.c +++ b/examples/physics_forces.c @@ -13,12 +13,15 @@ #define PHYSAC_IMPLEMENTATION #include "physac.h" +#include #define FORCE_AMOUNT 5.0f #define FORCE_RADIUS 150 #define LINE_LENGTH 75 #define TRIANGLE_LENGTH 12 +void* PhysicsThread(void *arg); + int main() { // Initialization @@ -61,6 +64,10 @@ int main() PhysicBody topWall = CreatePhysicBody((Vector2){ screenWidth/2, -25 }, 0.0f, (Vector2){ screenWidth, 50 }); PhysicBody bottomWall = CreatePhysicBody((Vector2){ screenWidth/2, screenHeight + 25 }, 0.0f, (Vector2){ screenWidth, 50 }); + // Create physics thread + pthread_t tid; + pthread_create(&tid, NULL, &PhysicsThread, NULL); + SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -69,7 +76,6 @@ int main() { // Update //---------------------------------------------------------------------------------- - UpdatePhysics(); // Update all created physic objects // Update mouse position value mousePosition = GetMousePosition(); @@ -174,10 +180,32 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- + pthread_cancel(tid); // Destroy physics thread + ClosePhysics(); // Unitialize physics module CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; +} + +void* PhysicsThread(void *arg) +{ + // Initialize time variables + double currentTime = GetTime(); + double previousTime = currentTime; + + // Physics update loop + while (!WindowShouldClose()) + { + currentTime = GetTime(); + double deltaTime = (double)(currentTime - previousTime); + previousTime = currentTime; + + // Delta time value needs to be inverse multiplied by physics time step value (1/target fps) + UpdatePhysics(deltaTime/PHYSICS_TIMESTEP); + } + + return NULL; } \ No newline at end of file -- cgit v1.2.3 From 6a2bbae5216e66e5581d697998efe135ad826c50 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Sun, 12 Jun 2016 22:07:36 +0200 Subject: Updated physics examples with new module changes --- examples/physics_basic_rigidbody.c | 32 +------------------------------- examples/physics_forces.c | 33 +-------------------------------- 2 files changed, 2 insertions(+), 63 deletions(-) (limited to 'examples') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index 24570426..811ab982 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -13,12 +13,10 @@ #define PHYSAC_IMPLEMENTATION #include "physac.h" -#include #define MOVE_VELOCITY 5 #define JUMP_VELOCITY 30 -void* PhysicsThread(void *arg); int main() { @@ -28,7 +26,6 @@ int main() int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [physac] example - basic rigidbody"); - InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module // Debug variables @@ -56,10 +53,6 @@ int main() // Create pplatform physic object PhysicBody platform = CreatePhysicBody((Vector2){ screenWidth/2, screenHeight*0.7f }, 0.0f, (Vector2){ screenWidth*0.25f, 20 }); - // Create physics thread - pthread_t tid; - pthread_create(&tid, NULL, &PhysicsThread, NULL); - SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -122,33 +115,10 @@ int main() } // De-Initialization - //-------------------------------------------------------------------------------------- - pthread_cancel(tid); // Destroy physics thread - + //-------------------------------------------------------------------------------------- ClosePhysics(); // Unitialize physics (including all loaded objects) - CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; -} - -void* PhysicsThread(void *arg) -{ - // Initialize time variables - double currentTime = GetTime(); - double previousTime = currentTime; - - // Physics update loop - while (!WindowShouldClose()) - { - currentTime = GetTime(); - double deltaTime = (double)(currentTime - previousTime); - previousTime = currentTime; - - // Delta time value needs to be inverse multiplied by physics time step value (1/target fps) - UpdatePhysics(deltaTime/PHYSICS_TIMESTEP); - } - - return NULL; } \ No newline at end of file diff --git a/examples/physics_forces.c b/examples/physics_forces.c index 397c2331..28566753 100644 --- a/examples/physics_forces.c +++ b/examples/physics_forces.c @@ -13,15 +13,12 @@ #define PHYSAC_IMPLEMENTATION #include "physac.h" -#include #define FORCE_AMOUNT 5.0f #define FORCE_RADIUS 150 #define LINE_LENGTH 75 #define TRIANGLE_LENGTH 12 -void* PhysicsThread(void *arg); - int main() { // Initialization @@ -30,7 +27,6 @@ int main() int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [physac] example - forces"); - InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module // Global variables @@ -64,10 +60,6 @@ int main() PhysicBody topWall = CreatePhysicBody((Vector2){ screenWidth/2, -25 }, 0.0f, (Vector2){ screenWidth, 50 }); PhysicBody bottomWall = CreatePhysicBody((Vector2){ screenWidth/2, screenHeight + 25 }, 0.0f, (Vector2){ screenWidth, 50 }); - // Create physics thread - pthread_t tid; - pthread_create(&tid, NULL, &PhysicsThread, NULL); - SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -179,33 +171,10 @@ int main() } // De-Initialization - //-------------------------------------------------------------------------------------- - pthread_cancel(tid); // Destroy physics thread - + //-------------------------------------------------------------------------------------- ClosePhysics(); // Unitialize physics module - CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; -} - -void* PhysicsThread(void *arg) -{ - // Initialize time variables - double currentTime = GetTime(); - double previousTime = currentTime; - - // Physics update loop - while (!WindowShouldClose()) - { - currentTime = GetTime(); - double deltaTime = (double)(currentTime - previousTime); - previousTime = currentTime; - - // Delta time value needs to be inverse multiplied by physics time step value (1/target fps) - UpdatePhysics(deltaTime/PHYSICS_TIMESTEP); - } - - return NULL; } \ No newline at end of file -- cgit v1.2.3 From 97fc266ad461db9da51877341f6097660cbf305a Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 14 Jun 2016 17:20:00 +0200 Subject: Updated raylib Oculus example --- examples/core_oculus_rift.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'examples') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index faf15d7f..2871407b 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -47,15 +47,24 @@ int main() BeginDrawing(); ClearBackground(RAYWHITE); + + BeginOculusDrawing(); + + for (int eye = 0; eye < 2; eye++) + { + Begin3dMode(camera); + + SetOculusMatrix(eye); + + DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); + DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); - Begin3dMode(camera); - - DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); - DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); - - DrawGrid(10, 1.0f); - - End3dMode(); + DrawGrid(10, 1.0f); + + End3dMode(); + } + + EndOculusDrawing() EndDrawing(); //---------------------------------------------------------------------------------- -- cgit v1.2.3 From 56bd9da07cbc6db9806380c79351ab0c5747c8f5 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 14 Jun 2016 18:37:06 +0200 Subject: Update Oculus sample (will be moved soon) --- examples/oculus_glfw_sample/oculus_glfw_sample.c | 50 ++- examples/oculus_glfw_sample/raymath.h | 18 +- examples/oculus_glfw_sample/rlgl.c | 421 ++++++++++++++++++++++- examples/oculus_glfw_sample/rlgl.h | 12 +- examples/oculus_glfw_sample/standard_shader.h | 46 ++- 5 files changed, 481 insertions(+), 66 deletions(-) (limited to 'examples') diff --git a/examples/oculus_glfw_sample/oculus_glfw_sample.c b/examples/oculus_glfw_sample/oculus_glfw_sample.c index 73f19883..8fddf5b9 100644 --- a/examples/oculus_glfw_sample/oculus_glfw_sample.c +++ b/examples/oculus_glfw_sample/oculus_glfw_sample.c @@ -23,8 +23,7 @@ #include #include -#define GLAD_IMPLEMENTATION -#include "glad.h" // Extensions loading library +#include "glad.h" #include // Windows/Context and inputs management #define RLGL_STANDALONE @@ -148,33 +147,34 @@ int main(void) 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"); + rlglLoadExtensions(glfwGetProcAddress); + + // 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 //-------------------------------------------------------- #if defined(PLATFORM_OCULUS) ovrResult result = ovr_Initialize(NULL); - if (OVR_FAILURE(result)) TraceLog(LOG_ERROR, "OVR: Could not initialize Oculus device"); + if (OVR_FAILURE(result)) TraceLog(ERROR, "OVR: Could not initialize Oculus device"); result = ovr_Create(&session, &luid); if (OVR_FAILURE(result)) { - TraceLog(LOG_WARNING, "OVR: Could not create Oculus session"); + TraceLog(WARNING, "OVR: Could not create Oculus session"); ovr_Shutdown(); } hmdDesc = ovr_GetHmdDesc(session); - TraceLog(LOG_INFO, "OVR: Product Name: %s", hmdDesc.ProductName); - TraceLog(LOG_INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer); - TraceLog(LOG_INFO, "OVR: Product ID: %i", hmdDesc.ProductId); - TraceLog(LOG_INFO, "OVR: Product Type: %i", hmdDesc.Type); - TraceLog(LOG_INFO, "OVR: Serian Number: %s", hmdDesc.SerialNumber); - TraceLog(LOG_INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); + TraceLog(INFO, "OVR: Product Name: %s", hmdDesc.ProductName); + TraceLog(INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer); + TraceLog(INFO, "OVR: Product ID: %i", hmdDesc.ProductId); + TraceLog(INFO, "OVR: Product Type: %i", hmdDesc.Type); + TraceLog(INFO, "OVR: Serian Number: %s", hmdDesc.SerialNumber); + TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); //screenWidth = hmdDesc.Resolution.w/2; //screenHeight = hmdDesc.Resolution.h/2; @@ -188,20 +188,14 @@ int main(void) // Recenter OVR tracking origin ovr_RecenterTrackingOrigin(session); #endif - - // 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 = 45.0f; // Camera field-of-view Y + + Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; //-------------------------------------------------------------------------------------- // Main game loop @@ -293,7 +287,7 @@ int main(void) // Get session status information ovrSessionStatus sessionStatus; ovr_GetSessionStatus(session, &sessionStatus); - if (sessionStatus.ShouldQuit) TraceLog(LOG_WARNING, "OVR: Session should quit..."); + if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit..."); if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session); #endif @@ -581,12 +575,12 @@ static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height) ovrResult result = ovr_CreateTextureSwapChainGL(session, &desc, &buffer.textureChain); - if (!OVR_SUCCESS(result)) TraceLog(LOG_WARNING, "OVR: Failed to create swap textures buffer"); + if (!OVR_SUCCESS(result)) TraceLog(WARNING, "OVR: Failed to create swap textures buffer"); int textureCount = 0; ovr_GetTextureSwapChainLength(session, buffer.textureChain, &textureCount); - if (!OVR_SUCCESS(result) || !textureCount) TraceLog(LOG_WARNING, "OVR: Unable to count swap chain textures"); + if (!OVR_SUCCESS(result) || !textureCount) TraceLog(WARNING, "OVR: Unable to count swap chain textures"); for (int i = 0; i < textureCount; ++i) { @@ -682,7 +676,7 @@ static OculusMirror LoadOculusMirror(ovrSession session, int width, int height) mirrorDesc.Width = mirror.width; mirrorDesc.Height = mirror.height; - if (!OVR_SUCCESS(ovr_CreateMirrorTextureGL(session, &mirrorDesc, &mirror.texture))) TraceLog(LOG_WARNING, "Could not create mirror texture"); + if (!OVR_SUCCESS(ovr_CreateMirrorTextureGL(session, &mirrorDesc, &mirror.texture))) TraceLog(WARNING, "Could not create mirror texture"); glGenFramebuffers(1, &mirror.fboId); diff --git a/examples/oculus_glfw_sample/raymath.h b/examples/oculus_glfw_sample/raymath.h index 4075a1a9..10eabb6b 100644 --- a/examples/oculus_glfw_sample/raymath.h +++ b/examples/oculus_glfw_sample/raymath.h @@ -47,10 +47,16 @@ #include "raylib.h" // Required for structs: Vector3, Matrix #endif +#ifdef __cplusplus + #define RMEXTERN extern "C" // Functions visible from other files (no name mangling of functions in C++) +#else + #define RMEXTERN extern // Functions visible from other files +#endif + #if defined(RAYMATH_EXTERN_INLINE) - #define RMDEF extern inline + #define RMDEF RMEXTERN inline // Functions are embeded inline (compiler generated code) #else - #define RMDEF extern + #define RMDEF RMEXTERN #endif //---------------------------------------------------------------------------------- @@ -105,10 +111,6 @@ typedef struct Quaternion { #ifndef RAYMATH_EXTERN_INLINE -#ifdef __cplusplus -extern "C" { -#endif - //------------------------------------------------------------------------------------ // Functions Declaration to work with Vector3 //------------------------------------------------------------------------------------ @@ -166,10 +168,6 @@ RMDEF Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle); // Returns RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle); // Returns the rotation angle and axis for a given quaternion RMDEF void QuaternionTransform(Quaternion *q, Matrix mat); // Transform a quaternion given a transformation matrix -#ifdef __cplusplus -} -#endif - #endif // notdef RAYMATH_EXTERN_INLINE #endif // RAYMATH_H diff --git a/examples/oculus_glfw_sample/rlgl.c b/examples/oculus_glfw_sample/rlgl.c index 72225634..1e392889 100644 --- a/examples/oculus_glfw_sample/rlgl.c +++ b/examples/oculus_glfw_sample/rlgl.c @@ -72,6 +72,10 @@ #include "standard_shader.h" // Standard shader to embed #endif +#if defined(RLGL_OCULUS_SUPPORT) + #include "external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL +#endif + //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- @@ -159,11 +163,45 @@ typedef struct { // Draw call type // NOTE: Used to track required draw-calls, organized by texture typedef struct { - GLuint textureId; int vertexCount; - // TODO: Store draw state -> blending mode, shader + GLuint vaoId; + GLuint textureId; + GLuint shaderId; + + Matrix projection; + Matrix modelview; + + // TODO: Store additional draw state data + //int blendMode; + //Guint fboId; } DrawCall; +#if defined(RLGL_OCULUS_SUPPORT) +typedef struct OculusBuffer { + ovrTextureSwapChain textureChain; + GLuint depthId; + GLuint fboId; + int width; + int height; +} OculusBuffer; + +typedef struct OculusMirror { + ovrMirrorTexture texture; + GLuint fboId; + int width; + int height; +} OculusMirror; + +typedef struct OculusLayer { + ovrViewScaleDesc viewScaleDesc; + ovrLayerEyeFov eyeLayer; // layer 0 + //ovrLayerQuad quadLayer; // TODO: layer 1: '2D' quad for GUI + Matrix eyeProjections[2]; + int width; + int height; +} OculusLayer; +#endif + //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- @@ -213,6 +251,17 @@ static Light lights[MAX_LIGHTS]; // Lights pool static int lightsCount; // Counts current enabled physic objects #endif +#if defined(RLGL_OCULUS_SUPPORT) +// OVR device variables +static ovrSession session; // Oculus session (pointer to ovrHmdStruct) +static ovrHmdDesc hmdDesc; // Oculus device descriptor parameters +static ovrGraphicsLuid luid; // Oculus locally unique identifier for the program (64 bit) +static OculusLayer layer; // Oculus drawing layer (similar to photoshop) +static OculusBuffer buffer; // Oculus internal buffers (texture chain and fbo) +static OculusMirror mirror; // Oculus mirror texture and fbo +static unsigned int frameIndex = 0; // Oculus frames counter, used to discard frames from chain +#endif + // Compressed textures support flags static bool texCompDXTSupported = false; // DDS texture compression support static bool npotSupported = false; // NPOT textures full support @@ -228,15 +277,14 @@ static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays; static int blendMode = 0; // White texture useful for plain color polys (required by shader) -// NOTE: It's required in shapes and models modules! -unsigned int whiteTexture; +static unsigned int whiteTexture; //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) static void LoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int compressedFormat); -static unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr); // Load custom shader strings and return program id +static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShaderStr); // Load custom shader strings and return program id static Shader LoadDefaultShader(void); // Load default shader (just vertex positioning and texture coloring) static Shader LoadStandardShader(void); // Load standard shader (support materials and lighting) @@ -254,6 +302,16 @@ static void SetShaderLights(Shader shader); // Sets shader uniform values for li static char *ReadTextFile(const char *fileName); #endif +#if defined(RLGL_OCULUS_SUPPORT) // Oculus Rift functions +static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height); // Load Oculus required buffers +static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer); // Unload texture required buffers +static OculusMirror LoadOculusMirror(ovrSession session, int width, int height); // Load Oculus mirror buffers +static void UnloadOculusMirror(ovrSession session, OculusMirror mirror); // Unload Oculus mirror buffers +static void BlitOculusMirror(ovrSession session, OculusMirror mirror); // Copy Oculus screen buffer to mirror texture +static OculusLayer InitOculusLayer(ovrSession session); // Init Oculus layer (similar to photoshop) +static Matrix FromOvrMatrix(ovrMatrix4f ovrM); // Convert from Oculus ovrMatrix4f struct to raymath Matrix struct +#endif + #if defined(GRAPHICS_API_OPENGL_11) static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight); static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight); @@ -1146,6 +1204,23 @@ void rlglInitGraphics(int offsetX, int offsetY, int width, int height) TraceLog(INFO, "OpenGL graphic device initialized successfully"); } +// Load OpenGL extensions +// NOTE: External loader function could be passed as a pointer +void rlglLoadExtensions(void *loader) +{ +#if defined(GRAPHICS_API_OPENGL_33) + // NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions + if (!gladLoadGLLoader((GLADloadproc)loader)) TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions"); + else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully"); + + if (GLAD_GL_VERSION_3_3) TraceLog(INFO, "OpenGL 3.3 Core profile supported"); + else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported"); + + // With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans + //if (GLAD_GL_ARB_vertex_array_object) // Use GL_ARB_vertex_array_object +#endif +} + // Get world coordinates from screen coordinates Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view) { @@ -1177,11 +1252,13 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma GLuint id = 0; // Check texture format support by OpenGL 1.1 (compressed textures not supported) - if ((rlGetVersion() == OPENGL_11) && (textureFormat >= 8)) +#if defined(GRAPHICS_API_OPENGL_11) + if (textureFormat >= 8) { TraceLog(WARNING, "OpenGL 1.1 does not support GPU compressed texture formats"); return id; } +#endif if ((!texCompDXTSupported) && ((textureFormat == COMPRESSED_DXT1_RGB) || (textureFormat == COMPRESSED_DXT1_RGBA) || (textureFormat == COMPRESSED_DXT3_RGBA) || (textureFormat == COMPRESSED_DXT5_RGBA))) @@ -1795,8 +1872,13 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) // NOTE: standard shader specific locations are got at render time to keep Shader struct as simple as possible (with just default shader locations) if (material.shader.id == standardShader.id) { + // Transpose and inverse model transformations matrix for fragment normal calculations + Matrix transInvTransform = transform; + MatrixTranspose(&transInvTransform); + MatrixInvert(&transInvTransform); + // Send model transformations matrix to shader - glUniformMatrix4fv(glGetUniformLocation(material.shader.id, "modelMatrix"), 1, false, MatrixToFloat(transform)); + glUniformMatrix4fv(glGetUniformLocation(material.shader.id, "modelMatrix"), 1, false, MatrixToFloat(transInvTransform)); // Send view transformation matrix to shader. View matrix 8, 9 and 10 are view direction vector axis values (target - position) glUniform3f(glGetUniformLocation(material.shader.id, "viewDir"), matView.m8, matView.m9, matView.m10); @@ -2095,6 +2177,24 @@ void *rlglReadTexturePixels(Texture2D texture) return pixels; } +/* +// TODO: Record draw calls to be processed in batch +// NOTE: Global state must be kept +void rlglRecordDraw(void) +{ + // TODO: Before adding a new draw, check if anything changed from last stored draw +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + draws[drawsCounter].vaoId = currentState.vaoId; // lines.id, trangles.id, quads.id? + draws[drawsCounter].textureId = currentState.textureId; // whiteTexture? + draws[drawsCounter].shaderId = currentState.shaderId; // defaultShader.id + draws[drawsCounter].projection = projection; + draws[drawsCounter].modelview = modelview; + draws[drawsCounter].vertexCount = currentState.vertexCount; + + drawsCounter++; +#endif +} +*/ //---------------------------------------------------------------------------------- // Module Functions Definition - Shaders Functions @@ -2361,6 +2461,130 @@ void DestroyLight(Light light) #endif } +#if defined(RLGL_OCULUS_SUPPORT) +// Init Oculus Rift device +// NOTE: Device initialization should be done before window creation? +void InitOculusDevice(void) +{ + // Initialize Oculus device + ovrResult result = ovr_Initialize(NULL); + if (OVR_FAILURE(result)) TraceLog(WARNING, "OVR: Could not initialize Oculus device"); + + result = ovr_Create(&session, &luid); + if (OVR_FAILURE(result)) + { + TraceLog(WARNING, "OVR: Could not create Oculus session"); + ovr_Shutdown(); + } + + hmdDesc = ovr_GetHmdDesc(session); + + TraceLog(INFO, "OVR: Product Name: %s", hmdDesc.ProductName); + TraceLog(INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer); + TraceLog(INFO, "OVR: Product ID: %i", hmdDesc.ProductId); + TraceLog(INFO, "OVR: Product Type: %i", hmdDesc.Type); + //TraceLog(INFO, "OVR: Serial Number: %s", hmdDesc.SerialNumber); + TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); + + // NOTE: Oculus mirror is set to defined screenWidth and screenHeight... + // ...ideally, it should be (hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2) + + // Initialize Oculus Buffers + layer = InitOculusLayer(session); + buffer = LoadOculusBuffer(session, layer.width, layer.height); + mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2); // NOTE: hardcoded... + layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain); + + // Recenter OVR tracking origin + ovr_RecenterTrackingOrigin(session); +} + +// Close Oculus Rift device +void CloseOculusDevice(void) +{ + UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer + UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers + + ovr_Destroy(session); // Free Oculus session data + ovr_Shutdown(); // Close Oculus device connection +} + +// Update Oculus Rift tracking (position and orientation) +void UpdateOculusTracking(void) +{ + frameIndex++; + + ovrPosef eyePoses[2]; + ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime); + + layer.eyeLayer.RenderPose[0] = eyePoses[0]; + layer.eyeLayer.RenderPose[1] = eyePoses[1]; +} + +void SetOculusMatrix(int eye) +{ + rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h); + + Quaternion eyeRPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, + layer.eyeLayer.RenderPose[eye].Orientation.y, + layer.eyeLayer.RenderPose[eye].Orientation.z, + layer.eyeLayer.RenderPose[eye].Orientation.w }; + QuaternionInvert(&eyeRPose); + Matrix eyeOrientation = QuaternionToMatrix(eyeRPose); + Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, + -layer.eyeLayer.RenderPose[eye].Position.y, + -layer.eyeLayer.RenderPose[eye].Position.z); + + Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); + Matrix modelEyeView = MatrixMultiply(modelview, eyeView); // Using internal camera modelview matrix + + SetMatrixModelview(modelEyeView); + SetMatrixProjection(layer.eyeProjections[eye]); +} + +void BeginOculusDrawing(void) +{ + GLuint currentTexId; + int currentIndex; + + ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, ¤tIndex); + ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, ¤tTexId); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0); + //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) + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Same as rlClearScreenBuffers() + + // NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA) + // 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); +} + +void EndOculusDrawing(void) +{ + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + ovr_CommitTextureSwapChain(session, buffer.textureChain); + + ovrLayerHeader *layers = &layer.eyeLayer.Header; + ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1); + + // Blit mirror texture to back buffer + BlitOculusMirror(session, mirror); + + // Get session status information + ovrSessionStatus sessionStatus; + ovr_GetSessionStatus(session, &sessionStatus); + if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit..."); + if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session); +} +#endif + //---------------------------------------------------------------------------------- // Module specific Functions Definition //---------------------------------------------------------------------------------- @@ -2403,7 +2627,7 @@ static void LoadCompressedTexture(unsigned char *data, int width, int height, in } // Load custom shader strings and return program id -static unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr) +static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShaderStr) { unsigned int program = 0; @@ -3341,6 +3565,187 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight) } #endif +#if defined(RLGL_OCULUS_SUPPORT) +// Load Oculus required buffers: texture-swap-chain, fbo, texture-depth +static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height) +{ + OculusBuffer buffer; + buffer.width = width; + buffer.height = height; + + // Create OVR texture chain + ovrTextureSwapChainDesc desc = {}; + desc.Type = ovrTexture_2D; + desc.ArraySize = 1; + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; // Requires glEnable(GL_FRAMEBUFFER_SRGB); + desc.SampleCount = 1; + desc.StaticImage = ovrFalse; + + ovrResult result = ovr_CreateTextureSwapChainGL(session, &desc, &buffer.textureChain); + + if (!OVR_SUCCESS(result)) TraceLog(WARNING, "OVR: Failed to create swap textures buffer"); + + int textureCount = 0; + ovr_GetTextureSwapChainLength(session, buffer.textureChain, &textureCount); + + if (!OVR_SUCCESS(result) || !textureCount) TraceLog(WARNING, "OVR: Unable to count swap chain textures"); + + for (int i = 0; i < textureCount; ++i) + { + GLuint chainTexId; + ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, i, &chainTexId); + glBindTexture(GL_TEXTURE_2D, chainTexId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + glBindTexture(GL_TEXTURE_2D, 0); + + /* + // Setup framebuffer object (using depth texture) + glGenFramebuffers(1, &buffer.fboId); + glGenTextures(1, &buffer.depthId); + glBindTexture(GL_TEXTURE_2D, buffer.depthId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, buffer.width, buffer.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + */ + + // Setup framebuffer object (using depth renderbuffer) + glGenFramebuffers(1, &buffer.fboId); + glGenRenderbuffers(1, &buffer.depthId); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId); + glBindRenderbuffer(GL_RENDERBUFFER, buffer.depthId); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, buffer.width, buffer.height); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, buffer.depthId); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + return buffer; +} + +// Unload texture required buffers +static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer) +{ + if (buffer.textureChain) + { + ovr_DestroyTextureSwapChain(session, buffer.textureChain); + buffer.textureChain = NULL; + } + + if (buffer.depthId != 0) glDeleteTextures(1, &buffer.depthId); + if (buffer.fboId != 0) glDeleteFramebuffers(1, &buffer.fboId); +} + +// Load Oculus mirror buffers +static OculusMirror LoadOculusMirror(ovrSession session, int width, int height) +{ + OculusMirror mirror; + mirror.width = width; + mirror.height = height; + + ovrMirrorTextureDesc mirrorDesc; + memset(&mirrorDesc, 0, sizeof(mirrorDesc)); + mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; + mirrorDesc.Width = mirror.width; + mirrorDesc.Height = mirror.height; + + if (!OVR_SUCCESS(ovr_CreateMirrorTextureGL(session, &mirrorDesc, &mirror.texture))) TraceLog(WARNING, "Could not create mirror texture"); + + glGenFramebuffers(1, &mirror.fboId); + + return mirror; +} + +// Unload Oculus mirror buffers +static void UnloadOculusMirror(ovrSession session, OculusMirror mirror) +{ + if (mirror.fboId != 0) glDeleteFramebuffers(1, &mirror.fboId); + if (mirror.texture) ovr_DestroyMirrorTexture(session, mirror.texture); +} + +// Copy Oculus screen buffer to mirror texture +static void BlitOculusMirror(ovrSession session, OculusMirror mirror) +{ + GLuint mirrorTextureId; + + ovr_GetMirrorTextureBufferGL(session, mirror.texture, &mirrorTextureId); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, mirror.fboId); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mirrorTextureId, 0); + glBlitFramebuffer(0, 0, mirror.width, mirror.height, 0, mirror.height, mirror.width, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); +} + +// Init Oculus layer (similar to photoshop) +static OculusLayer InitOculusLayer(ovrSession session) +{ + OculusLayer layer = { 0 }; + + layer.viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f; + + memset(&layer.eyeLayer, 0, sizeof(ovrLayerEyeFov)); + layer.eyeLayer.Header.Type = ovrLayerType_EyeFov; + layer.eyeLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft; + + ovrEyeRenderDesc eyeRenderDescs[2]; + + for (int eye = 0; eye < 2; eye++) + { + eyeRenderDescs[eye] = ovr_GetRenderDesc(session, eye, hmdDesc.DefaultEyeFov[eye]); + ovrMatrix4f ovrPerspectiveProjection = ovrMatrix4f_Projection(eyeRenderDescs[eye].Fov, 0.01f, 10000.0f, ovrProjection_None); //ovrProjection_ClipRangeOpenGL); + layer.eyeProjections[eye] = FromOvrMatrix(ovrPerspectiveProjection); // NOTE: struct ovrMatrix4f { float M[4][4] } --> struct Matrix + + layer.viewScaleDesc.HmdToEyeOffset[eye] = eyeRenderDescs[eye].HmdToEyeOffset; + layer.eyeLayer.Fov[eye] = eyeRenderDescs[eye].Fov; + + ovrSizei eyeSize = ovr_GetFovTextureSize(session, eye, layer.eyeLayer.Fov[eye], 1.0f); + layer.eyeLayer.Viewport[eye].Size = eyeSize; + layer.eyeLayer.Viewport[eye].Pos.x = layer.width; + layer.eyeLayer.Viewport[eye].Pos.y = 0; + + layer.height = eyeSize.h; //std::max(renderTargetSize.y, (uint32_t)eyeSize.h); + layer.width += eyeSize.w; + } + + return layer; +} + +// Convert from Oculus ovrMatrix4f struct to raymath Matrix struct +static Matrix FromOvrMatrix(ovrMatrix4f ovrmat) +{ + Matrix rmat; + + rmat.m0 = ovrmat.M[0][0]; + rmat.m1 = ovrmat.M[1][0]; + rmat.m2 = ovrmat.M[2][0]; + rmat.m3 = ovrmat.M[3][0]; + rmat.m4 = ovrmat.M[0][1]; + rmat.m5 = ovrmat.M[1][1]; + rmat.m6 = ovrmat.M[2][1]; + rmat.m7 = ovrmat.M[3][1]; + rmat.m8 = ovrmat.M[0][2]; + rmat.m9 = ovrmat.M[1][2]; + rmat.m10 = ovrmat.M[2][2]; + rmat.m11 = ovrmat.M[3][2]; + rmat.m12 = ovrmat.M[0][3]; + rmat.m13 = ovrmat.M[1][3]; + rmat.m14 = ovrmat.M[2][3]; + rmat.m15 = ovrmat.M[3][3]; + + MatrixTranspose(&rmat); + + return rmat; +} +#endif + #if defined(RLGL_STANDALONE) // Output a trace log message // NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning diff --git a/examples/oculus_glfw_sample/rlgl.h b/examples/oculus_glfw_sample/rlgl.h index 9c25f710..93e155b7 100644 --- a/examples/oculus_glfw_sample/rlgl.h +++ b/examples/oculus_glfw_sample/rlgl.h @@ -48,7 +48,7 @@ // Choose opengl version here or just define it at compile time: -DGRAPHICS_API_OPENGL_33 //#define GRAPHICS_API_OPENGL_11 // Only available on PLATFORM_DESKTOP -//#define GRAPHICS_API_OPENGL_33 // Only available on PLATFORM_DESKTOP +//#define GRAPHICS_API_OPENGL_33 // Only available on PLATFORM_DESKTOP or Oculus Rift CV1 //#define GRAPHICS_API_OPENGL_ES2 // Only available on PLATFORM_ANDROID or PLATFORM_RPI or PLATFORM_WEB // Security check in case no GRAPHICS_API_OPENGL_* defined @@ -296,6 +296,7 @@ void rlglInit(void); // Initialize rlgl (shaders, VAO void rlglClose(void); // De-init rlgl void rlglDraw(void); // Draw VAO/VBO void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Initialize Graphics (OpenGL stuff) +void rlglLoadExtensions(void *loader); // Load OpenGL extensions unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load texture in GPU RenderTexture2D rlglLoadRenderTexture(int width, int height); // Load a texture to be used for rendering (fbo with color and depth attachments) @@ -346,6 +347,15 @@ void DestroyLight(Light light); // Destroy a void TraceLog(int msgType, const char *text, ...); #endif +#if defined(RLGL_OCULUS_SUPPORT) +void InitOculusDevice(void); // Init Oculus Rift device +void CloseOculusDevice(void); // Close Oculus Rift device +void UpdateOculusTracking(void); // Update Oculus Rift tracking (position and orientation) +void SetOculusMatrix(int eye); // Set internal projection and modelview matrix depending on eyes tracking data +void BeginOculusDrawing(void); // Begin Oculus drawing configuration +void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) +#endif + #ifdef __cplusplus } #endif diff --git a/examples/oculus_glfw_sample/standard_shader.h b/examples/oculus_glfw_sample/standard_shader.h index 956b5c32..a4bc9694 100644 --- a/examples/oculus_glfw_sample/standard_shader.h +++ b/examples/oculus_glfw_sample/standard_shader.h @@ -1,6 +1,6 @@ // Vertex shader definition to embed, no external file required -const static unsigned char vStandardShaderStr[] = +static const char vStandardShaderStr[] = #if defined(GRAPHICS_API_OPENGL_21) "#version 120 \n" #elif defined(GRAPHICS_API_OPENGL_ES2) @@ -37,7 +37,7 @@ const static unsigned char vStandardShaderStr[] = "} \n"; // Fragment shader definition to embed, no external file required -const static unsigned char fStandardShaderStr[] = +static const char fStandardShaderStr[] = #if defined(GRAPHICS_API_OPENGL_21) "#version 120 \n" #elif defined(GRAPHICS_API_OPENGL_ES2) @@ -85,13 +85,13 @@ const static unsigned char fStandardShaderStr[] = "{\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 brightness = clamp(float(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n))), 0.0, 1.0);\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" +" spec = pow(dot(n, h), 3.0 + glossiness)*s;\n" " }\n" " return (diff*l.diffuse.rgb + spec*colSpecular.rgb);\n" "}\n" @@ -99,23 +99,23 @@ const static unsigned char fStandardShaderStr[] = "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 diff = clamp(float(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" +" spec = pow(dot(n, h), 3.0 + 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 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1.0));\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" +" float diff = clamp(float(dot(n, lightDir)), 0.0, 1.0)*l.intensity;\n" +" float attenuation = clamp(float(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" @@ -125,37 +125,45 @@ const static unsigned char fStandardShaderStr[] = " if (diffAttenuation > 0.0)\n" " {\n" " vec3 h = normalize(lightDir + v);\n" -" spec = pow(dot(n, h), 3 + glossiness)*s;\n" +" spec = pow(dot(n, h), 3.0 + 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" +" mat3 normalMatrix = mat3(modelMatrix);\n" " vec3 normal = normalize(normalMatrix*fragNormal);\n" " vec3 n = normalize(normal);\n" " vec3 v = normalize(viewDir);\n" +#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) +" vec4 texelColor = texture2D(texture0, fragTexCoord);\n" +#elif defined(GRAPHICS_API_OPENGL_33) " vec4 texelColor = texture(texture0, fragTexCoord);\n" +#endif " vec3 lighting = colAmbient.rgb;\n" " if (useNormal == 1)\n" " {\n" +#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) +" n *= texture2D(texture1, fragTexCoord).rgb;\n" +#elif defined(GRAPHICS_API_OPENGL_33) " n *= texture(texture1, fragTexCoord).rgb;\n" +#endif " n = normalize(n);\n" " }\n" " float spec = 1.0;\n" +#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) +" if (useSpecular == 1) spec *= normalize(texture2D(texture2, fragTexCoord).r);\n" +#elif defined(GRAPHICS_API_OPENGL_33) " if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r);\n" +#endif " 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" +" if(lights[i].type == 0) lighting += CalcPointLight(lights[i], n, v, spec);\n" +" else if(lights[i].type == 1) lighting += CalcDirectionalLight(lights[i], n, v, spec);\n" +" else if(lights[i].type == 2) lighting += CalcSpotLight(lights[i], n, v, spec);\n" " }\n" " }\n" #if defined(GRAPHICS_API_OPENGL_33) @@ -163,4 +171,4 @@ const static unsigned char fStandardShaderStr[] = #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"; \ No newline at end of file +"}\n"; -- cgit v1.2.3 From d1a5374ac42e054ca65793f7358fc21bbcf393b9 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 14 Jun 2016 18:38:57 +0200 Subject: raylib Oculus Rift CV1 example... IT WORKS!!! --- examples/core_oculus_rift.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'examples') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index 2871407b..86517829 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -2,6 +2,9 @@ * * raylib [core] example - Oculus Rift CV1 * +* Compile example using: +* gcc -o $(NAME_PART).exe $(FILE_NAME) -L. -L..\src\external\OculusSDK\LibOVR -lLibOVRRT32_1 -lraylib -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) * @@ -21,8 +24,8 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [core] example - oculus rift"); InitOculusDevice(); - - // Define the camera to look into our 3d world + + // Define the camera to look into our 3d world 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 @@ -30,8 +33,8 @@ int main() camera.fovy = 45.0f; // Camera field-of-view Y Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; - - SetTargetFPS(90); // Set our game to run at 90 frames-per-second + + //SetTargetFPS(90); // Set our game to run at 90 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop @@ -58,13 +61,13 @@ int main() DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); - + DrawGrid(10, 1.0f); End3dMode(); } - EndOculusDrawing() + EndOculusDrawing(); EndDrawing(); //---------------------------------------------------------------------------------- @@ -72,7 +75,7 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- - CloseOculusdevice(); // Close Oculus Rift device + CloseOculusDevice(); // Close Oculus Rift device CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- -- cgit v1.2.3 From 54537e8f0b57df2f3f15d8e46309672f46e4775a Mon Sep 17 00:00:00 2001 From: victorfisac Date: Tue, 14 Jun 2016 20:23:46 +0200 Subject: Fixed bug in delta time calculation... and added PHYSAC_NO_THREADS define. Improved physac example drawing frames per second in screen. --- examples/physics_basic_rigidbody.c | 2 ++ examples/physics_forces.c | 4 +++- src/physac.h | 26 ++++++++++++++++---------- 3 files changed, 21 insertions(+), 11 deletions(-) (limited to 'examples') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index 811ab982..5223f46a 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -110,6 +110,8 @@ int main() // Draw help message DrawText("Use WASD to move rectangle and ARROWS to move square", screenWidth/2 - MeasureText("Use WASD to move rectangle and ARROWS to move square", 20)/2, screenHeight*0.075f, 20, LIGHTGRAY); + DrawFPS(10, 10); + EndDrawing(); //---------------------------------------------------------------------------------- } diff --git a/examples/physics_forces.c b/examples/physics_forces.c index 28566753..87510552 100644 --- a/examples/physics_forces.c +++ b/examples/physics_forces.c @@ -164,7 +164,9 @@ int main() // Draw help messages DrawText("Use LEFT MOUSE BUTTON to apply a force", screenWidth/2 - MeasureText("Use LEFT MOUSE BUTTON to apply a force", 20)/2, screenHeight*0.075f, 20, LIGHTGRAY); - DrawText("Use R to reset objects position", screenWidth/2 - MeasureText("Use R to reset objects position", 20)/2, screenHeight*0.875f, 20, GRAY); + DrawText("Use R to reset objects position", screenWidth/2 - MeasureText("Use R to reset objects position", 20)/2, screenHeight*0.875f, 20, GRAY); + + DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/src/physac.h b/src/physac.h index ea8801c3..5ce3970e 100644 --- a/src/physac.h +++ b/src/physac.h @@ -178,8 +178,10 @@ PHYSACDEF Rectangle TransformToRectangle(Transform transform); #include // Required for: cos(), sin(), abs(), fminf() #include // Required for typedef unsigned long long int uint64_t, used by hi-res timer -#include // Required for: pthread_create() -#include "utils.h" // Required for: TraceLog() + +#ifndef PHYSAC_NO_THREADS + #include // Required for: pthread_create() +#endif #if defined(PLATFORM_DESKTOP) // Functions required to query time on Windows @@ -234,9 +236,11 @@ PHYSACDEF void InitPhysics(Vector2 gravity) physicBodiesCount = 0; gravityForce = gravity; - // Create physics thread - pthread_t tid; - pthread_create(&tid, NULL, &PhysicsThread, NULL); + #ifndef PHYSAC_NO_THREADS // NOTE: if defined, user will need to create a thread for PhysicsThread function manually + // Create physics thread + pthread_t tid; + pthread_create(&tid, NULL, &PhysicsThread, NULL); + #endif } // Update physic objects, calculating physic behaviours and collisions detection @@ -768,7 +772,6 @@ static void InitTimer(void) { baseTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; } - else TraceLog(WARNING, "No hi-resolution timer available"); #endif previousTime = GetCurrentTime(); // Get time as double @@ -777,22 +780,25 @@ static void InitTimer(void) // Time measure returned are microseconds static double GetCurrentTime(void) { + double time; + #if defined(PLATFORM_DESKTOP) unsigned long long int clockFrequency, currentTime; QueryPerformanceFrequency(&clockFrequency); QueryPerformanceCounter(¤tTime); - - return (double)(currentTime/clockFrequency); + #endif #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - uint64_t time = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec; + uint64_t temp = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec; - return (double)(time - baseTime)*1e-9; + time = (double)(temp - baseTime)*1e-9; #endif + + return time; } // Returns the dot product of two Vector2 -- cgit v1.2.3 From 1a8fbe5cf0b982cf74434f1ba4654fced71a0450 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Tue, 14 Jun 2016 20:31:48 +0200 Subject: Add pthread external library to source... and add instructions in physac examples to run it successful. --- .gitignore | 3 ++- examples/physics_basic_rigidbody.c | 4 ++++ examples/physics_forces.c | 5 +++++ src/external/pthread/pthreadGC2.dll | Bin 0 -> 119888 bytes 4 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 src/external/pthread/pthreadGC2.dll (limited to 'examples') diff --git a/.gitignore b/.gitignore index b221a37b..cf9cdfe1 100644 --- a/.gitignore +++ b/.gitignore @@ -72,4 +72,5 @@ src/libraylib.bc # external libraries DLLs !src/external/glfw3/lib/win32/glfw3.dll !src/external/openal_soft/lib/win32/OpenAL32.dll -!src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll \ No newline at end of file +!src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll +!src/external/pthread/pthreadGC2.dll \ No newline at end of file diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index 5223f46a..b85f7543 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -5,6 +5,10 @@ * 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) * +* +* Compile example using: +* cmd /c IF NOT EXIST pthreadGC2.dll copy C:\raylib\raylib\src\external\pthread\pthreadGC2.dll $(CURRENT_DIRECTORY) /Y +* * Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/examples/physics_forces.c b/examples/physics_forces.c index 87510552..7de85483 100644 --- a/examples/physics_forces.c +++ b/examples/physics_forces.c @@ -5,6 +5,11 @@ * 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) * +* NOTE: This example requires raylib module [rlgl] +* +* Compile example using: +* cmd /c IF NOT EXIST pthreadGC2.dll copy C:\raylib\raylib\src\external\pthread\pthreadGC2.dll $(CURRENT_DIRECTORY) /Y +* * Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5) * ********************************************************************************************/ diff --git a/src/external/pthread/pthreadGC2.dll b/src/external/pthread/pthreadGC2.dll new file mode 100644 index 00000000..67b9289d Binary files /dev/null and b/src/external/pthread/pthreadGC2.dll differ -- cgit v1.2.3 From 4e84ded7ef3b165081e08a83d95bf54387a413ca Mon Sep 17 00:00:00 2001 From: victorfisac Date: Tue, 14 Jun 2016 20:38:49 +0200 Subject: Fixed spacing and set UpdatePhysics() function as static... and remove static from PhysicsThread(). --- examples/physics_basic_rigidbody.c | 8 +- examples/physics_forces.c | 2 +- src/physac.h | 418 ++++++++++++++++++------------------- 3 files changed, 213 insertions(+), 215 deletions(-) (limited to 'examples') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index b85f7543..084bfb0e 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -21,7 +21,6 @@ #define MOVE_VELOCITY 5 #define JUMP_VELOCITY 30 - int main() { // Initialization @@ -30,7 +29,7 @@ int main() int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [physac] example - basic rigidbody"); - InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module + // InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module // Debug variables bool isDebug = false; @@ -64,8 +63,7 @@ int main() while (!WindowShouldClose()) // Detect window close button or ESC key { // Update - //---------------------------------------------------------------------------------- - + //---------------------------------------------------------------------------------- // Check rectangle movement inputs if (IsKeyPressed('W')) rectangle->rigidbody.velocity.y = JUMP_VELOCITY; if (IsKeyDown('A')) rectangle->rigidbody.velocity.x = -MOVE_VELOCITY; @@ -121,7 +119,7 @@ int main() } // De-Initialization - //-------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------- ClosePhysics(); // Unitialize physics (including all loaded objects) CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/physics_forces.c b/examples/physics_forces.c index 7de85483..efe8e240 100644 --- a/examples/physics_forces.c +++ b/examples/physics_forces.c @@ -178,7 +178,7 @@ int main() } // De-Initialization - //-------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------- ClosePhysics(); // Unitialize physics module CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/src/physac.h b/src/physac.h index 4f9b736f..b8cc8f15 100644 --- a/src/physac.h +++ b/src/physac.h @@ -146,7 +146,7 @@ typedef struct PhysicBodyData { // Module Functions Declaration //---------------------------------------------------------------------------------- PHYSACDEF void InitPhysics(Vector2 gravity); // Initializes pointers array (just pointers, fixed size) -PHYSACDEF void UpdatePhysics(double deltaTime); // Update physic objects, calculating physic behaviours and collisions detection +PHYSACDEF void* PhysicsThread(void *arg); // Physics calculations thread function PHYSACDEF void ClosePhysics(); // Unitialize all physic objects and empty the objects pool PHYSACDEF PhysicBody CreatePhysicBody(Vector2 position, float rotation, Vector2 scale); // Create a new physic body dinamically, initialize it and add to pool @@ -219,7 +219,7 @@ static Vector2 gravityForce; // Gravity f //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- -static void* PhysicsThread(void *arg); // Physics calculations thread function +static void UpdatePhysics(double deltaTime); // Update physic objects, calculating physic behaviours and collisions detection static void InitTimer(void); // Initialize hi-resolution timer static double GetCurrentTime(void); // Time measure returned are microseconds static float Vector2DotProduct(Vector2 v1, Vector2 v2); // Returns the dot product of two Vector2 @@ -243,8 +243,214 @@ PHYSACDEF void InitPhysics(Vector2 gravity) #endif } +// Unitialize all physic objects and empty the objects pool +PHYSACDEF void ClosePhysics() +{ + // Exit physics thread loop + physicsThreadEnabled = false; + + // Free all dynamic memory allocations + for (int i = 0; i < physicBodiesCount; i++) PHYSAC_FREE(physicBodies[i]); + + // Reset enabled physic objects count + physicBodiesCount = 0; +} + +// Create a new physic body dinamically, initialize it and add to pool +PHYSACDEF PhysicBody CreatePhysicBody(Vector2 position, float rotation, Vector2 scale) +{ + // Allocate dynamic memory + PhysicBody obj = (PhysicBody)PHYSAC_MALLOC(sizeof(PhysicBodyData)); + + // Initialize physic body values with generic values + obj->id = physicBodiesCount; + obj->enabled = true; + + obj->transform = (Transform){ (Vector2){ position.x - scale.x/2, position.y - scale.y/2 }, rotation, scale }; + + obj->rigidbody.enabled = false; + obj->rigidbody.mass = 1.0f; + obj->rigidbody.acceleration = (Vector2){ 0.0f, 0.0f }; + obj->rigidbody.velocity = (Vector2){ 0.0f, 0.0f }; + obj->rigidbody.applyGravity = false; + obj->rigidbody.isGrounded = false; + obj->rigidbody.friction = 0.0f; + obj->rigidbody.bounciness = 0.0f; + + obj->collider.enabled = true; + obj->collider.type = COLLIDER_RECTANGLE; + obj->collider.bounds = TransformToRectangle(obj->transform); + obj->collider.radius = 0.0f; + + // Add new physic body to the pointers array + physicBodies[physicBodiesCount] = obj; + + // Increase enabled physic bodies count + physicBodiesCount++; + + return obj; +} + +// Destroy a specific physic body and take it out of the list +PHYSACDEF void DestroyPhysicBody(PhysicBody pbody) +{ + // Free dynamic memory allocation + PHYSAC_FREE(physicBodies[pbody->id]); + + // Remove *obj from the pointers array + for (int i = pbody->id; i < physicBodiesCount; i++) + { + // Resort all the following pointers of the array + if ((i + 1) < physicBodiesCount) + { + physicBodies[i] = physicBodies[i + 1]; + physicBodies[i]->id = physicBodies[i + 1]->id; + } + else PHYSAC_FREE(physicBodies[i]); + } + + // Decrease enabled physic bodies count + physicBodiesCount--; +} + +// Apply directional force to a physic body +PHYSACDEF void ApplyForce(PhysicBody pbody, Vector2 force) +{ + if (pbody->rigidbody.enabled) + { + pbody->rigidbody.velocity.x += force.x/pbody->rigidbody.mass; + pbody->rigidbody.velocity.y += force.y/pbody->rigidbody.mass; + } +} + +// Apply radial force to all physic objects in range +PHYSACDEF void ApplyForceAtPosition(Vector2 position, float force, float radius) +{ + for (int i = 0; i < physicBodiesCount; i++) + { + if (physicBodies[i]->rigidbody.enabled) + { + // Calculate direction and distance between force and physic body position + Vector2 distance = (Vector2){ physicBodies[i]->transform.position.x - position.x, physicBodies[i]->transform.position.y - position.y }; + + if (physicBodies[i]->collider.type == COLLIDER_RECTANGLE) + { + distance.x += physicBodies[i]->transform.scale.x/2; + distance.y += physicBodies[i]->transform.scale.y/2; + } + + float distanceLength = Vector2Length(distance); + + // Check if physic body is in force range + if (distanceLength <= radius) + { + // Normalize force direction + distance.x /= distanceLength; + distance.y /= -distanceLength; + + // Calculate final force + Vector2 finalForce = { distance.x*force, distance.y*force }; + + // Apply force to the physic body + ApplyForce(physicBodies[i], finalForce); + } + } + } +} + +// Convert Transform data type to Rectangle (position and scale) +PHYSACDEF Rectangle TransformToRectangle(Transform transform) +{ + return (Rectangle){transform.position.x, transform.position.y, transform.scale.x, transform.scale.y}; +} + +// Physics calculations thread function +PHYSACDEF void* PhysicsThread(void *arg) +{ + // Initialize thread loop state + physicsThreadEnabled = true; + + // Initialize hi-resolution timer + InitTimer(); + + // Physics update loop + while (physicsThreadEnabled) + { + currentTime = GetCurrentTime(); + double deltaTime = (double)(currentTime - previousTime); + previousTime = currentTime; + + // Delta time value needs to be inverse multiplied by physics time step value (1/target fps) + UpdatePhysics(deltaTime/PHYSICS_TIMESTEP); + } + + return NULL; +} + +//---------------------------------------------------------------------------------- +// Module specific Functions Definition +//---------------------------------------------------------------------------------- +// Initialize hi-resolution timer +static void InitTimer(void) +{ +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) + struct timespec now; + + if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) // Success + { + baseTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; + } +#endif + + previousTime = GetCurrentTime(); // Get time as double +} + +// Time measure returned are microseconds +static double GetCurrentTime(void) +{ + double time; + +#if defined(PLATFORM_DESKTOP) + unsigned long long int clockFrequency, currentTime; + + QueryPerformanceFrequency(&clockFrequency); + QueryPerformanceCounter(¤tTime); + + time = (double)((double)currentTime/(double)clockFrequency); +#endif + +#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + uint64_t temp = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec; + + time = (double)(temp - baseTime)*1e-9; +#endif + + return time; +} + +// Returns the dot product of two Vector2 +static float Vector2DotProduct(Vector2 v1, Vector2 v2) +{ + float result; + + result = v1.x*v2.x + v1.y*v2.y; + + return result; +} + +static float Vector2Length(Vector2 v) +{ + float result; + + result = sqrt(v.x*v.x + v.y*v.y); + + return result; +} + // Update physic objects, calculating physic behaviours and collisions detection -PHYSACDEF void UpdatePhysics(double deltaTime) +static void UpdatePhysics(double deltaTime) { for (int i = 0; i < physicBodiesCount; i++) { @@ -615,210 +821,4 @@ PHYSACDEF void UpdatePhysics(double deltaTime) } } -// Unitialize all physic objects and empty the objects pool -PHYSACDEF void ClosePhysics() -{ - // Exit physics thread loop - physicsThreadEnabled = false; - - // Free all dynamic memory allocations - for (int i = 0; i < physicBodiesCount; i++) PHYSAC_FREE(physicBodies[i]); - - // Reset enabled physic objects count - physicBodiesCount = 0; -} - -// Create a new physic body dinamically, initialize it and add to pool -PHYSACDEF PhysicBody CreatePhysicBody(Vector2 position, float rotation, Vector2 scale) -{ - // Allocate dynamic memory - PhysicBody obj = (PhysicBody)PHYSAC_MALLOC(sizeof(PhysicBodyData)); - - // Initialize physic body values with generic values - obj->id = physicBodiesCount; - obj->enabled = true; - - obj->transform = (Transform){ (Vector2){ position.x - scale.x/2, position.y - scale.y/2 }, rotation, scale }; - - obj->rigidbody.enabled = false; - obj->rigidbody.mass = 1.0f; - obj->rigidbody.acceleration = (Vector2){ 0.0f, 0.0f }; - obj->rigidbody.velocity = (Vector2){ 0.0f, 0.0f }; - obj->rigidbody.applyGravity = false; - obj->rigidbody.isGrounded = false; - obj->rigidbody.friction = 0.0f; - obj->rigidbody.bounciness = 0.0f; - - obj->collider.enabled = true; - obj->collider.type = COLLIDER_RECTANGLE; - obj->collider.bounds = TransformToRectangle(obj->transform); - obj->collider.radius = 0.0f; - - // Add new physic body to the pointers array - physicBodies[physicBodiesCount] = obj; - - // Increase enabled physic bodies count - physicBodiesCount++; - - return obj; -} - -// Destroy a specific physic body and take it out of the list -PHYSACDEF void DestroyPhysicBody(PhysicBody pbody) -{ - // Free dynamic memory allocation - PHYSAC_FREE(physicBodies[pbody->id]); - - // Remove *obj from the pointers array - for (int i = pbody->id; i < physicBodiesCount; i++) - { - // Resort all the following pointers of the array - if ((i + 1) < physicBodiesCount) - { - physicBodies[i] = physicBodies[i + 1]; - physicBodies[i]->id = physicBodies[i + 1]->id; - } - else PHYSAC_FREE(physicBodies[i]); - } - - // Decrease enabled physic bodies count - physicBodiesCount--; -} - -// Apply directional force to a physic body -PHYSACDEF void ApplyForce(PhysicBody pbody, Vector2 force) -{ - if (pbody->rigidbody.enabled) - { - pbody->rigidbody.velocity.x += force.x/pbody->rigidbody.mass; - pbody->rigidbody.velocity.y += force.y/pbody->rigidbody.mass; - } -} - -// Apply radial force to all physic objects in range -PHYSACDEF void ApplyForceAtPosition(Vector2 position, float force, float radius) -{ - for (int i = 0; i < physicBodiesCount; i++) - { - if (physicBodies[i]->rigidbody.enabled) - { - // Calculate direction and distance between force and physic body position - Vector2 distance = (Vector2){ physicBodies[i]->transform.position.x - position.x, physicBodies[i]->transform.position.y - position.y }; - - if (physicBodies[i]->collider.type == COLLIDER_RECTANGLE) - { - distance.x += physicBodies[i]->transform.scale.x/2; - distance.y += physicBodies[i]->transform.scale.y/2; - } - - float distanceLength = Vector2Length(distance); - - // Check if physic body is in force range - if (distanceLength <= radius) - { - // Normalize force direction - distance.x /= distanceLength; - distance.y /= -distanceLength; - - // Calculate final force - Vector2 finalForce = { distance.x*force, distance.y*force }; - - // Apply force to the physic body - ApplyForce(physicBodies[i], finalForce); - } - } - } -} - -// Convert Transform data type to Rectangle (position and scale) -PHYSACDEF Rectangle TransformToRectangle(Transform transform) -{ - return (Rectangle){transform.position.x, transform.position.y, transform.scale.x, transform.scale.y}; -} - -//---------------------------------------------------------------------------------- -// Module specific Functions Definition -//---------------------------------------------------------------------------------- -// Physics calculations thread function -static void* PhysicsThread(void *arg) -{ - // Initialize thread loop state - physicsThreadEnabled = true; - - // Initialize hi-resolution timer - InitTimer(); - - // Physics update loop - while (physicsThreadEnabled) - { - currentTime = GetCurrentTime(); - double deltaTime = (double)(currentTime - previousTime); - previousTime = currentTime; - - // Delta time value needs to be inverse multiplied by physics time step value (1/target fps) - UpdatePhysics(deltaTime/PHYSICS_TIMESTEP); - } - - return NULL; -} - -// Initialize hi-resolution timer -static void InitTimer(void) -{ -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) - struct timespec now; - - if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) // Success - { - baseTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; - } -#endif - - previousTime = GetCurrentTime(); // Get time as double -} - -// Time measure returned are microseconds -static double GetCurrentTime(void) -{ - double time; - -#if defined(PLATFORM_DESKTOP) - unsigned long long int clockFrequency, currentTime; - - QueryPerformanceFrequency(&clockFrequency); - QueryPerformanceCounter(¤tTime); - - time = (double)((double)currentTime/(double)clockFrequency); -#endif - -#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - uint64_t temp = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec; - - time = (double)(temp - baseTime)*1e-9; -#endif - - return time; -} - -// Returns the dot product of two Vector2 -static float Vector2DotProduct(Vector2 v1, Vector2 v2) -{ - float result; - - result = v1.x*v2.x + v1.y*v2.y; - - return result; -} - -static float Vector2Length(Vector2 v) -{ - float result; - - result = sqrt(v.x*v.x + v.y*v.y); - - return result; -} - #endif // PHYSAC_IMPLEMENTATION \ No newline at end of file -- cgit v1.2.3 From 1879a8129e786e859cc2984e294ef9c22663f923 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Tue, 14 Jun 2016 20:40:12 +0200 Subject: Fixed little bug in physac example --- examples/physics_basic_rigidbody.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index 084bfb0e..75720c97 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -29,7 +29,7 @@ int main() int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [physac] example - basic rigidbody"); - // InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module + InitPhysics((Vector2){ 0.0f, -9.81f/2 }); // Initialize physics module // Debug variables bool isDebug = false; -- cgit v1.2.3 From 3468af213f88cd367eac43826ad49f9e9fc730f4 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 15 Jun 2016 00:54:55 +0200 Subject: Reviewing Oculus rendering... --- examples/core_oculus_rift.c | 4 ++++ src/rlgl.c | 42 ++++++++++++++++++++++++------------------ 2 files changed, 28 insertions(+), 18 deletions(-) (limited to 'examples') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index 86517829..3c9d7840 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -55,6 +55,8 @@ int main() for (int eye = 0; eye < 2; eye++) { + // TODO: Probably projection and view matrices could be created here... + // ...without the need to create it internally through Begin3dMode() Begin3dMode(camera); SetOculusMatrix(eye); @@ -64,6 +66,8 @@ int main() DrawGrid(10, 1.0f); + // TODO: Call internal buffers drawing directly (rlglDraw()) and... + // ...reset internal matrices, instead of letting End3dMode() do that End3dMode(); } diff --git a/src/rlgl.c b/src/rlgl.c index 5d6fd9d7..fec03926 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -2519,26 +2519,39 @@ void UpdateOculusTracking(void) layer.eyeLayer.RenderPose[0] = eyePoses[0]; layer.eyeLayer.RenderPose[1] = eyePoses[1]; + + // Get session status information + ovrSessionStatus sessionStatus; + ovr_GetSessionStatus(session, &sessionStatus); + + if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit..."); + if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session); + //if (sessionStatus.HmdPresent) // HMD is present. + //if (sessionStatus.DisplayLost) // HMD was unplugged or the display driver was manually disabled or encountered a TDR. + //if (sessionStatus.HmdMounted) // HMD is on the user's head. + //if (sessionStatus.IsVisible) // the game or experience has VR focus and is visible in the HMD. } void SetOculusMatrix(int eye) { rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h); - Quaternion eyeRPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, - layer.eyeLayer.RenderPose[eye].Orientation.y, - layer.eyeLayer.RenderPose[eye].Orientation.z, - layer.eyeLayer.RenderPose[eye].Orientation.w }; - QuaternionInvert(&eyeRPose); - Matrix eyeOrientation = QuaternionToMatrix(eyeRPose); + Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, + layer.eyeLayer.RenderPose[eye].Orientation.y, + layer.eyeLayer.RenderPose[eye].Orientation.z, + layer.eyeLayer.RenderPose[eye].Orientation.w }; + QuaternionInvert(&eyeRenderPose); + Matrix eyeOrientation = QuaternionToMatrix(eyeRenderPose); Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, -layer.eyeLayer.RenderPose[eye].Position.y, -layer.eyeLayer.RenderPose[eye].Position.z); - Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); - Matrix modelEyeView = MatrixMultiply(modelview, eyeView); // Using internal camera modelview matrix + Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement + Matrix eyeModelView = MatrixMultiply(modelview, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement - SetMatrixModelview(modelEyeView); + // TODO: Find a better way to get camera view matrix (instead of using internal modelview) + + SetMatrixModelview(eyeModelView); SetMatrixProjection(layer.eyeProjections[eye]); } @@ -2554,20 +2567,19 @@ void BeginOculusDrawing(void) glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0); //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) - //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Same as rlClearScreenBuffers() - // NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA) // 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); + //glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye) rlClearScreenBuffers(); // Clear current framebuffer(s) } void EndOculusDrawing(void) { + // Unbind current framebuffer (Oculus buffer) glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); @@ -2578,12 +2590,6 @@ void EndOculusDrawing(void) // Blit mirror texture to back buffer BlitOculusMirror(session, mirror); - - // Get session status information - ovrSessionStatus sessionStatus; - ovr_GetSessionStatus(session, &sessionStatus); - if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit..."); - if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session); } #endif -- cgit v1.2.3 From 24c9b1f717bd9a6510667907614928188a6b6a6f Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 17 Jun 2016 13:54:45 +0200 Subject: Improving Oculus Rift example... Under design... looking for the easiest and most comprehensive way for the user to use VR... --- examples/core_oculus_rift.c | 40 ++++++++++++++++++++++------------------ src/core.c | 10 ++++++++++ src/raylib.h | 3 ++- src/rlgl.c | 10 +++++----- src/rlgl.h | 2 +- 5 files changed, 40 insertions(+), 25 deletions(-) (limited to 'examples') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index 3c9d7840..32e6b1c6 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -51,27 +51,31 @@ int main() ClearBackground(RAYWHITE); - BeginOculusDrawing(); + Begin3dMode(camera); + //BeginOculusDrawing(camera); // Add it to Begin3dMode() ? - for (int eye = 0; eye < 2; eye++) - { - // TODO: Probably projection and view matrices could be created here... - // ...without the need to create it internally through Begin3dMode() - Begin3dMode(camera); + for (int eye = 0; eye < 2; eye++) + { + // TODO: Probably projection and view matrices could be created here... + // ...without the need to create it internally through Begin3dMode() + //Begin3dMode(camera); + + SetOculusView(eye); + + DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); + DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); + + DrawGrid(10, 1.0f); + + // TODO: Call internal buffers drawing directly (rlglDraw()) and... + // ...reset internal matrices, instead of letting End3dMode() do that + //End3dMode(); - SetOculusMatrix(eye); - - DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); - DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); - - DrawGrid(10, 1.0f); - - // TODO: Call internal buffers drawing directly (rlglDraw()) and... - // ...reset internal matrices, instead of letting End3dMode() do that - End3dMode(); - } + DrawDefaultBuffers(); // Process internal dynamic buffers + } - EndOculusDrawing(); + End3dMode(); + //EndOculusDrawing(); // Add it to End3dMode() ? EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/src/core.c b/src/core.c index 7c2dbcb9..eef81bad 100644 --- a/src/core.c +++ b/src/core.c @@ -606,6 +606,8 @@ void Begin3dMode(Camera camera) rlMultMatrixf(MatrixToFloat(cameraView)); // Multiply MODELVIEW matrix by view matrix (camera) rlEnableDepthTest(); // Enable DEPTH_TEST for 3D + + //if (vrEnabled) BeginVrMode(); } // Ends 3D mode and returns to default 2D orthographic mode @@ -1015,6 +1017,14 @@ Matrix GetCameraMatrix(Camera camera) return MatrixLookAt(camera.position, camera.target, camera.up); } +// Update and draw default buffers vertex data +// NOTE: This data has been stored dynamically during frame on each Draw*() call +void DrawDefaultBuffers(void) +{ + rlglUpdateDefaultBuffers(); // Upload frame vertex data to GPU + rlglDrawDefaultBuffers(); // Draw vertex data into framebuffer +} + //---------------------------------------------------------------------------------- // Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions //---------------------------------------------------------------------------------- diff --git a/src/raylib.h b/src/raylib.h index 0c9f0280..ed787892 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -572,6 +572,7 @@ void EndTextureMode(void); // Ends drawing to r Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix) +void DrawDefaultBuffers(void); // Update and draw default buffers vertex data (stored dynamically in frame) void SetTargetFPS(int fps); // Set target FPS (maximum) float GetFPS(void); // Returns current FPS @@ -853,7 +854,7 @@ void DestroyLight(Light light); // Destroy a void InitOculusDevice(void); // Init Oculus Rift device void CloseOculusDevice(void); // Close Oculus Rift device void UpdateOculusTracking(void); // Update Oculus Rift tracking (position and orientation) -void SetOculusMatrix(int eye); // Set internal projection and modelview matrix depending on eyes tracking data +void SetOculusView(int eye); // Set internal projection and modelview matrix depending on eyes tracking data void BeginOculusDrawing(void); // Begin Oculus drawing configuration void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) diff --git a/src/rlgl.c b/src/rlgl.c index 6d003869..d68b9109 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -297,8 +297,8 @@ static void UnloadDefaultShader(void); // Unload default shader static void UnloadStandardShader(void); // Unload standard shader static void LoadDefaultBuffers(void); // Load default internal buffers (lines, triangles, quads) -static void UpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data -static void DrawDefaultBuffers(void); // Draw default internal buffers vertex data +void rlglUpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data +void rlglDrawDefaultBuffers(void); // Draw default internal buffers vertex data static void UnloadDefaultBuffers(void); // Unload default internal buffers vertex data from CPU and GPU static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array @@ -2542,7 +2542,7 @@ void UpdateOculusTracking(void) //if (sessionStatus.IsVisible) // the game or experience has VR focus and is visible in the HMD. } -void SetOculusMatrix(int eye) +void SetOculusView(int eye) { rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h); @@ -3089,7 +3089,7 @@ static void LoadDefaultBuffers(void) // Update default internal buffers (VAOs/VBOs) with vertex array data // NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0) // TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (change flag required) -static void UpdateDefaultBuffers(void) +void rlglUpdateDefaultBuffers(void) { // Update lines vertex buffers if (lines.vCounter > 0) @@ -3159,7 +3159,7 @@ static void UpdateDefaultBuffers(void) // Draw default internal buffers vertex data // NOTE: We draw in this order: lines, triangles, quads -static void DrawDefaultBuffers(void) +void rlglDrawDefaultBuffers(void) { // Set current shader and upload current MVP matrix if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0)) diff --git a/src/rlgl.h b/src/rlgl.h index 3322d80c..8904b9ac 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -357,7 +357,7 @@ void TraceLog(int msgType, const char *text, ...); void InitOculusDevice(void); // Init Oculus Rift device void CloseOculusDevice(void); // Close Oculus Rift device void UpdateOculusTracking(void); // Update Oculus Rift tracking (position and orientation) -void SetOculusMatrix(int eye); // Set internal projection and modelview matrix depending on eyes tracking data +void SetOculusView(int eye); // Set internal projection and modelview matrix depending on eyes tracking data void BeginOculusDrawing(void); // Begin Oculus drawing configuration void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) #endif -- cgit v1.2.3 From 6062201e8f543c227a0adbb77f3a0941772be889 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 21 Jun 2016 08:59:29 +0200 Subject: Simplify Oculus example... ...to align it with standard raylib code. Final goal would be having the same code work for every platform with no changes... --- examples/core_oculus_rift.c | 12 +----------- src/core.c | 5 +++-- src/rlgl.c | 12 +++++++++++- src/rlgl.h | 1 + 4 files changed, 16 insertions(+), 14 deletions(-) (limited to 'examples') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index 32e6b1c6..e0ab61fd 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -52,14 +52,9 @@ int main() ClearBackground(RAYWHITE); Begin3dMode(camera); - //BeginOculusDrawing(camera); // Add it to Begin3dMode() ? - + for (int eye = 0; eye < 2; eye++) { - // TODO: Probably projection and view matrices could be created here... - // ...without the need to create it internally through Begin3dMode() - //Begin3dMode(camera); - SetOculusView(eye); DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); @@ -67,15 +62,10 @@ int main() DrawGrid(10, 1.0f); - // TODO: Call internal buffers drawing directly (rlglDraw()) and... - // ...reset internal matrices, instead of letting End3dMode() do that - //End3dMode(); - DrawDefaultBuffers(); // Process internal dynamic buffers } End3dMode(); - //EndOculusDrawing(); // Add it to End3dMode() ? EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/src/core.c b/src/core.c index eef81bad..af82e092 100644 --- a/src/core.c +++ b/src/core.c @@ -607,13 +607,14 @@ void Begin3dMode(Camera camera) rlEnableDepthTest(); // Enable DEPTH_TEST for 3D - //if (vrEnabled) BeginVrMode(); + if (VrEnabled()) BeginOculusDrawing(); } // Ends 3D mode and returns to default 2D orthographic mode void End3dMode(void) { - rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) + if (VrEnabled()) EndOculusDrawing(); + else rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) rlMatrixMode(RL_PROJECTION); // Switch to projection matrix rlPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack diff --git a/src/rlgl.c b/src/rlgl.c index 2d4d951c..eee19ef4 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -76,7 +76,7 @@ #include "standard_shader.h" // Standard shader to embed #endif -#define RLGL_OCULUS_SUPPORT // Enable Oculus Rift code +//#define RLGL_OCULUS_SUPPORT // Enable Oculus Rift code #if defined(RLGL_OCULUS_SUPPORT) #include "external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL #endif @@ -268,6 +268,7 @@ static unsigned int frameIndex = 0; // Oculus frames counter, used to discar #endif static bool vrSimulator = false; // VR simulator (stereo rendering on window, without vr device) +static bool vrEnabled = false; // VR enabled flag (required by core module) // Compressed textures support flags static bool texCompDXTSupported = false; // DDS texture compression support @@ -2523,6 +2524,7 @@ void InitOculusDevice(void) } #else vrSimulator = true; + vrEnabled = true; #endif if (vrSimulator) @@ -2548,6 +2550,14 @@ void CloseOculusDevice(void) // TODO: Unload stereo framebuffer and texture // TODO: Unload oculus-distortion shader } + + vrEnabled = false; +} + +// Track stereoscopic rendering +bool VrEnabled(void) +{ + return vrEnabled; } // Update Oculus Rift tracking (position and orientation) diff --git a/src/rlgl.h b/src/rlgl.h index e2e1dde6..c0e93a65 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -362,6 +362,7 @@ void UpdateOculusTracking(void); // Update Oculus Rift tracking (posi void SetOculusView(int eye); // Set internal projection and modelview matrix depending on eyes tracking data void BeginOculusDrawing(void); // Begin Oculus drawing configuration void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) +bool VrEnabled(void); // Track stereoscopic rendering #ifdef __cplusplus } -- cgit v1.2.3 From c28a5fbd62e82f776f4399a1e561c7c4f4bff898 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 21 Jun 2016 13:44:56 +0200 Subject: Code tweak --- examples/oculus_glfw_sample/rlgl_standalone_stereo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/oculus_glfw_sample/rlgl_standalone_stereo.c b/examples/oculus_glfw_sample/rlgl_standalone_stereo.c index 1955d11e..fa7f3e4a 100644 --- a/examples/oculus_glfw_sample/rlgl_standalone_stereo.c +++ b/examples/oculus_glfw_sample/rlgl_standalone_stereo.c @@ -184,7 +184,7 @@ int main(void) 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 + rlOrtho(0.0, screenWidth/2, screenHeight, 0.0, 0.0, 1.0); // Recalculate internal projection matrix rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix rlLoadIdentity(); // Reset internal modelview matrix #endif -- cgit v1.2.3 From e913de58c73ff82fbcd8f23b8cb1fd1a88664164 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 21 Jun 2016 13:45:35 +0200 Subject: Added distortion shader for testing --- examples/resources/shaders/base.vs | 26 ++++++++++++++ examples/resources/shaders/distortion.fs | 59 ++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 examples/resources/shaders/base.vs create mode 100644 examples/resources/shaders/distortion.fs (limited to 'examples') diff --git a/examples/resources/shaders/base.vs b/examples/resources/shaders/base.vs new file mode 100644 index 00000000..638cb8ae --- /dev/null +++ b/examples/resources/shaders/base.vs @@ -0,0 +1,26 @@ +#version 330 + +// Input vertex attributes +in vec3 vertexPosition; +in vec2 vertexTexCoord; +in vec3 vertexNormal; +in vec4 vertexColor; + +// Input uniform values +uniform mat4 mvpMatrix; + +// Output vertex attributes (to fragment shader) +out vec2 fragTexCoord; +out vec4 fragColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Send vertex attributes to fragment shader + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + + // Calculate final vertex position + gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/examples/resources/shaders/distortion.fs b/examples/resources/shaders/distortion.fs new file mode 100644 index 00000000..cd5951fe --- /dev/null +++ b/examples/resources/shaders/distortion.fs @@ -0,0 +1,59 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; + +// Input uniform values +uniform sampler2D texture0; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables +const vec2 LeftLensCenter = vec2(0.2863248, 0.5); +const vec2 RightLensCenter = vec2(0.7136753, 0.5); +const vec2 LeftScreenCenter = vec2(0.25, 0.5); +const vec2 RightScreenCenter = vec2(0.75, 0.5); +const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); +const vec2 ScaleIn = vec2(4, 2.2222); +const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); + +/* +// Another set of default values +ChromaAbCorrection = {1.0, 0.0, 1.0, 0} +DistortionK = {1.0, 0.22, 0.24, 0} +Scale = {0.25, 0.5*AspectRatio, 0, 0} +ScaleIn = {4.0, 2/AspectRatio, 0, 0} +Left Screen Center = {0.25, 0.5, 0, 0} +Left Lens Center = {0.287994117, 0.5, 0, 0} +Right Screen Center = {0.75, 0.5, 0, 0} +Right Lens Center = {0.712005913, 0.5, 0, 0} +*/ + +// Scales input texture coordinates for distortion. +vec2 HmdWarp(vec2 in01, vec2 LensCenter) +{ + vec2 theta = (in01 - LensCenter)*ScaleIn; // Scales to [-1, 1] + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 rvector = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); + + return LensCenter + Scale*rvector; +} + +void main() +{ + // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 + + // The following two variables need to be set per eye + vec2 LensCenter = gl_FragCoord.x < 540 ? LeftLensCenter : RightLensCenter; + vec2 ScreenCenter = gl_FragCoord.x < 540 ? LeftScreenCenter : RightScreenCenter; + + vec2 tc = HmdWarp(fragTexCoord, LensCenter); + + if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); + else + { + //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); + finalColor = texture2D(texture0, tc); + } +} -- cgit v1.2.3 From 5f7ac64c44543383b10ec6a56e5ec1db5706276e Mon Sep 17 00:00:00 2001 From: raysan5 Date: Fri, 24 Jun 2016 19:49:36 +0200 Subject: Removed function SetModelTexture() It's more educational to go through new material system, so, I decide to remove this function to avoid students confusion... --- CHANGELOG | 7 ++++--- examples/models_cubicmap.c | 2 +- examples/models_heightmap.c | 2 +- examples/models_obj_loading.c | 2 +- examples/shaders_custom_uniform.c | 2 +- examples/shaders_postprocessing.c | 2 +- games/raylib_demo/raylib_demo.c | 4 ++-- src/models.c | 7 ------- src/raylib.h | 1 - 9 files changed, 11 insertions(+), 18 deletions(-) (limited to 'examples') diff --git a/CHANGELOG b/CHANGELOG index 5024dc6e..300c9089 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,20 +1,20 @@ changelog --------- -Current Release: raylib 1.5.0 (23 June 2016) +Current Release: raylib 1.5.0 (xx June 2016) NOTE: Only versions marked as 'Release' are available in installer, updates are only available as source. NOTE: Current Release includes all previous updates. ----------------------------------------------- -Release: raylib 1.5.0 (23 June 2016) +Release: raylib 1.5.0 (xx June 2016) ----------------------------------------------- NOTE: Probably this new version is the biggest boost of the library ever, lots of parts of the library have been redesigned, lots of bugs have been solved and some **AMAZING** new features have been added. HUGE changes: -[core] OCULUS RIFT CV1: Added support for VR witha bunch of Oculus-specific functions to init/close device and Oculus rendering. +[rlgl] OCULUS RIFT CV1: Added support for VR witha bunch of Oculus-specific functions to init/close device and Oculus rendering. [rlgl] MATERIALS SYSTEM: Added support for Materials (.mtl) and multiple material properties: diffuse, specular, normal. [rlgl] LIGHTING SYSTEM: Added support for up to 8 lights of 3 different types: Omni, Directional and Spot [physac] REDESIGNED: Improved performance and simplified usage, physic objects are managed internally @@ -65,6 +65,7 @@ other changes: [models] Updated BoundingBox collision detections [models] Added color parameter to DrawBoundigBox() [models] Removed function: DrawQuad() +[models] Removed function: SetModelTexture() [models] Redesigned DrawPlane() to use RL_TRIANGLES [models] Redesigned DrawRectangleV() to use RL_TRIANGLES [models] Redesign to accomodate new materials system: LoadMaterial() diff --git a/examples/models_cubicmap.c b/examples/models_cubicmap.c index 1ca27dfd..89bc75cf 100644 --- a/examples/models_cubicmap.c +++ b/examples/models_cubicmap.c @@ -29,7 +29,7 @@ int main() // NOTE: By default each cube is mapped to one part of texture atlas Texture2D texture = LoadTexture("resources/cubicmap_atlas.png"); // Load map texture - SetModelTexture(&map, texture); // Bind texture to map model + map.material.texDiffuse = texture; // Set map diffuse texture Vector3 mapPosition = { -16.0f, 0.0f, -8.0f }; // Set model position diff --git a/examples/models_heightmap.c b/examples/models_heightmap.c index c8e5ff35..90e5f5bb 100644 --- a/examples/models_heightmap.c +++ b/examples/models_heightmap.c @@ -26,7 +26,7 @@ int main() Image image = LoadImage("resources/heightmap.png"); // Load heightmap image (RAM) Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM) Model map = LoadHeightmap(image, (Vector3){ 16, 8, 16 }); // Load heightmap model with defined size - SetModelTexture(&map, texture); // Bind texture to model + map.material.texDiffuse = texture; // Set map diffuse texture Vector3 mapPosition = { -8.0f, 0.0f, -8.0f }; // Set model position (depends on model scaling!) UnloadImage(image); // Unload heightmap image from RAM, already uploaded to VRAM diff --git a/examples/models_obj_loading.c b/examples/models_obj_loading.c index e8dd0adc..a6969f70 100644 --- a/examples/models_obj_loading.c +++ b/examples/models_obj_loading.c @@ -25,7 +25,7 @@ int main() Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture - SetModelTexture(&dwarf, texture); // Bind texture to model + dwarf.material.texDiffuse = texture; // Set dwarf model diffuse texture Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position SetTargetFPS(60); // Set our game to run at 60 frames-per-second diff --git a/examples/shaders_custom_uniform.c b/examples/shaders_custom_uniform.c index 516d5087..c4f87259 100644 --- a/examples/shaders_custom_uniform.c +++ b/examples/shaders_custom_uniform.c @@ -34,7 +34,7 @@ int main() Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture (diffuse map) - SetModelTexture(&dwarf, texture); // Bind texture to model + dwarf.material.texDiffuse = texture; // Set dwarf model diffuse texture Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position diff --git a/examples/shaders_postprocessing.c b/examples/shaders_postprocessing.c index 5e8b5a80..43d21e08 100644 --- a/examples/shaders_postprocessing.c +++ b/examples/shaders_postprocessing.c @@ -34,7 +34,7 @@ int main() Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture (diffuse map) - SetModelTexture(&dwarf, texture); // Bind texture to model + dwarf.material.texDiffuse = texture; // Set dwarf model diffuse texture Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position diff --git a/games/raylib_demo/raylib_demo.c b/games/raylib_demo/raylib_demo.c index 7f6f291a..22213b46 100644 --- a/games/raylib_demo/raylib_demo.c +++ b/games/raylib_demo/raylib_demo.c @@ -202,8 +202,8 @@ int main() camera = (Camera){{ 0.0, 12.0, 15.0 }, { 0.0, 3.0, 0.0 }, { 0.0, 1.0, 0.0 }}; catTexture = LoadTexture("resources/catsham.png"); // Load model texture - cat = LoadModel("resources/cat.obj"); // Load OBJ model - SetModelTexture(&cat, catTexture); + cat = LoadModel("resources/cat.obj"); // Load OBJ model + cat.material.texDiffuse = texture; // Set cat model diffuse texture fxWav = LoadSound("resources/audio/weird.wav"); // Load WAV audio file fxOgg = LoadSound("resources/audio/tanatana.ogg"); // Load OGG audio file diff --git a/src/models.c b/src/models.c index 8deabcb0..a4bcde8f 100644 --- a/src/models.c +++ b/src/models.c @@ -808,13 +808,6 @@ void UnloadMaterial(Material material) rlDeleteTextures(material.texSpecular.id); } -// Link a texture to a model -void SetModelTexture(Model *model, Texture2D texture) -{ - if (texture.id <= 0) model->material.texDiffuse = GetDefaultTexture(); // Use default white texture - else model->material.texDiffuse = texture; -} - // Generate a mesh from heightmap static Mesh GenMeshHeightmap(Image heightmap, Vector3 size) { diff --git a/src/raylib.h b/src/raylib.h index ed787892..641f4c09 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -795,7 +795,6 @@ Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d mod Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based) void UnloadModel(Model model); // Unload 3d model from memory -void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model Material LoadMaterial(const char *fileName); // Load material data (from file) Material LoadDefaultMaterial(void); // Load default material (uses default models shader) -- cgit v1.2.3 From f9f33926f79b972b10c275d7d742c92337a7b0a2 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 25 Jun 2016 22:41:45 +0200 Subject: Corrected window size to unify with other examples --- examples/core_color_select.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'examples') diff --git a/examples/core_color_select.c b/examples/core_color_select.c index 118dc88a..002a6931 100644 --- a/examples/core_color_select.c +++ b/examples/core_color_select.c @@ -16,7 +16,7 @@ int main() // Initialization //-------------------------------------------------------------------------------------- int screenWidth = 800; - int screenHeight = 400; + int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [core] example - color selection (collision detection)"); @@ -30,7 +30,7 @@ int main() for (int i = 0; i < 21; i++) { colorsRecs[i].x = 20 + 100*(i%7) + 10*(i%7); - colorsRecs[i].y = 40 + 100*(i/7) + 10*(i/7); + colorsRecs[i].y = 60 + 100*(i/7) + 10*(i/7); colorsRecs[i].width = 100; colorsRecs[i].height = 100; } -- cgit v1.2.3 From 8fb84d9e638dea9b4eaaee52b61e1a7ea6681005 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 25 Jun 2016 23:29:03 +0200 Subject: Updated to new rlgl --- examples/oculus_glfw_sample/rlgl_standalone.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'examples') diff --git a/examples/oculus_glfw_sample/rlgl_standalone.c b/examples/oculus_glfw_sample/rlgl_standalone.c index 4728160a..33e91631 100644 --- a/examples/oculus_glfw_sample/rlgl_standalone.c +++ b/examples/oculus_glfw_sample/rlgl_standalone.c @@ -96,11 +96,19 @@ int main(void) // 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 }; + // Initialize viewport and internal projection/modelview matrices + rlViewport(0, 0, screenWidth, screenHeight); + rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix + rlLoadIdentity(); // Reset current matrix (PROJECTION) + rlOrtho(0, screenWidth, screenHeight, 0, 0.0f, 1.0f); // Orthographic projection with top-left corner at (0,0) + rlMatrixMode(RL_MODELVIEW); // Switch back to MODELVIEW matrix + rlLoadIdentity(); // Reset current matrix (MODELVIEW) + + rlClearColor(245, 245, 245, 255); // Define clear color + rlEnableDepthTest(); // Enable DEPTH_TEST for 3D + + Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; // Cube default position (center) Camera camera; camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position -- cgit v1.2.3 From 4ff85c2ac257eb5494626dae30e79c5f48430609 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 26 Jun 2016 10:22:17 +0200 Subject: Added notes about chromatic aberration --- examples/resources/shaders/distortion.fs | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'examples') diff --git a/examples/resources/shaders/distortion.fs b/examples/resources/shaders/distortion.fs index cd5951fe..79bc5fa1 100644 --- a/examples/resources/shaders/distortion.fs +++ b/examples/resources/shaders/distortion.fs @@ -56,4 +56,14 @@ void main() //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); finalColor = texture2D(texture0, tc); } + + /* + // Chromatic aberration is caused when a lens can't focus every color to the same focal point. + // A simple way to fake this effect, and render it as a quick full-screen post-process, + // is to apply an offset to each color channel in a fragment shader. + vec4 rValue = texture2D(texture0, fragTexCoord - rOffset); + vec4 gValue = texture2D(texture0, fragTexCoord - gOffset); + vec4 bValue = texture2D(texture0, fragTexCoord - bOffset); + finalColor = vec4(rValue.r, gValue.g, bValue.b, 1.0); + */ } -- cgit v1.2.3 From 9127b5a57d317c3be76be48deb7395069ae6ab12 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 26 Jun 2016 15:36:12 +0200 Subject: Enable/Disable VR experience --- examples/core_oculus_rift.c | 4 +- src/rlgl.c | 113 ++++++++++++++++++++++++-------------------- src/rlgl.h | 1 + 3 files changed, 67 insertions(+), 51 deletions(-) (limited to 'examples') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index e0ab61fd..4fe35607 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -30,7 +30,7 @@ int main() 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 = 45.0f; // Camera field-of-view Y + camera.fovy = 60.0f; // Camera field-of-view Y Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; @@ -43,6 +43,8 @@ int main() // Update //---------------------------------------------------------------------------------- UpdateOculusTracking(); + + if (IsKeyPressed(KEY_SPACE)) ToggleVR(); //---------------------------------------------------------------------------------- // Draw diff --git a/src/rlgl.c b/src/rlgl.c index ea65b6a4..d21d3e4c 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -267,8 +267,9 @@ static OculusMirror mirror; // Oculus mirror texture and fbo static unsigned int frameIndex = 0; // Oculus frames counter, used to discard frames from chain #endif -static bool oculusEnabled = false; // Oculus device enabled flag (required by core module) +static bool oculusReady = false; // Oculus device ready flag static bool oculusSimulator = false; // Oculus device simulator +static bool vrEnabled = false; // VR experience enabled (Oculus device or simulator) static RenderTexture2D stereoFbo; static Shader distortion; @@ -2480,7 +2481,7 @@ void InitOculusDevice(void) if (OVR_FAILURE(result)) { TraceLog(WARNING, "OVR: Could not initialize Oculus device"); - oculusEnabled = false; + oculusReady = false; } else { @@ -2489,7 +2490,7 @@ void InitOculusDevice(void) { TraceLog(WARNING, "OVR: Could not create Oculus session"); ovr_Shutdown(); - oculusEnabled = false; + oculusReady = false; } else { @@ -2514,14 +2515,15 @@ void InitOculusDevice(void) // Recenter OVR tracking origin ovr_RecenterTrackingOrigin(session); - oculusEnabled = true; + oculusReady = true; + vrEnabled = true; } } #else - oculusEnabled = false; + oculusReady = false; #endif - if (!oculusEnabled) + if (!oculusReady) { TraceLog(WARNING, "VR: Initializing Oculus simulator"); @@ -2533,6 +2535,7 @@ void InitOculusDevice(void) distortion = LoadShader("resources/shaders/base.vs", "resources/shaders/distortion.fs"); oculusSimulator = true; + vrEnabled = true; } } @@ -2540,7 +2543,7 @@ void InitOculusDevice(void) void CloseOculusDevice(void) { #if defined(RLGL_OCULUS_SUPPORT) - if (oculusEnabled) + if (oculusReady) { UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers @@ -2558,20 +2561,26 @@ void CloseOculusDevice(void) UnloadShader(distortion); } - oculusEnabled = false; + oculusReady = false; } // Detect if oculus device is available bool IsOculusReady(void) { - return (oculusEnabled || oculusSimulator); + return (oculusReady || oculusSimulator) && vrEnabled; +} + +// Enable/Disable VR experience (Oculus device or simulator) +void ToggleVR(void) +{ + vrEnabled = !vrEnabled; } // Update Oculus Rift tracking (position and orientation) void UpdateOculusTracking(void) { #if defined(RLGL_OCULUS_SUPPORT) - if (oculusEnabled) + if (oculusReady) { frameIndex++; @@ -2604,54 +2613,58 @@ void SetOculusView(int eye) { Matrix eyeProjection; Matrix eyeModelView; - -#if defined(RLGL_OCULUS_SUPPORT) - if (oculusEnabled) + + if (vrEnabled) { - rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h); - - Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, - layer.eyeLayer.RenderPose[eye].Orientation.y, - layer.eyeLayer.RenderPose[eye].Orientation.z, - layer.eyeLayer.RenderPose[eye].Orientation.w }; - QuaternionInvert(&eyeRenderPose); - Matrix eyeOrientation = QuaternionToMatrix(eyeRenderPose); - Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, - -layer.eyeLayer.RenderPose[eye].Position.y, - -layer.eyeLayer.RenderPose[eye].Position.z); - - Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement - eyeModelView = MatrixMultiply(modelview, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement - - // TODO: Find a better way to get camera view matrix (instead of using internal modelview) - - eyeProjection = layer.eyeProjections[eye]; - } - else +#if defined(RLGL_OCULUS_SUPPORT) + if (oculusReady) + { + rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, + layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h); + + Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, + layer.eyeLayer.RenderPose[eye].Orientation.y, + layer.eyeLayer.RenderPose[eye].Orientation.z, + layer.eyeLayer.RenderPose[eye].Orientation.w }; + QuaternionInvert(&eyeRenderPose); + Matrix eyeOrientation = QuaternionToMatrix(eyeRenderPose); + Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, + -layer.eyeLayer.RenderPose[eye].Position.y, + -layer.eyeLayer.RenderPose[eye].Position.z); + + Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement + eyeModelView = MatrixMultiply(modelview, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement + + // TODO: Find a better way to get camera view matrix (instead of using internal modelview) + + eyeProjection = layer.eyeProjections[eye]; + } + else #endif - { - // Setup viewport and projection/modelview matrices using tracking data - rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight); - - // NOTE: fovy vaule hardcoded to 45.0 degrees - eyeProjection = MatrixPerspective(45.0, (double)(screenWidth/2)/(double)screenHeight, 0.01, 1000.0); - MatrixTranspose(&eyeProjection); - - // TODO: Compute eyes IPD and apply to current modelview matrix (camera) - Matrix eyeView = MatrixIdentity(); - - eyeModelView = MatrixMultiply(modelview, eyeView); - } + { + // Setup viewport and projection/modelview matrices using tracking data + rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight); + + // NOTE: fovy value hardcoded to 60 degrees (Oculus Rift CV1 vertical FOV is 100 degrees) + eyeProjection = MatrixPerspective(60.0, (double)(screenWidth/2)/(double)screenHeight, 0.01, 1000.0); + MatrixTranspose(&eyeProjection); + + // TODO: Compute eyes IPD and apply to current modelview matrix (camera) + Matrix eyeView = MatrixIdentity(); + + eyeModelView = MatrixMultiply(modelview, eyeView); + } - SetMatrixModelview(eyeModelView); - SetMatrixProjection(eyeProjection); + SetMatrixModelview(eyeModelView); + SetMatrixProjection(eyeProjection); + } } // Begin Oculus drawing configuration void BeginOculusDrawing(void) { #if defined(RLGL_OCULUS_SUPPORT) - if (oculusEnabled) + if (oculusReady) { GLuint currentTexId; int currentIndex; @@ -2684,7 +2697,7 @@ void BeginOculusDrawing(void) void EndOculusDrawing(void) { #if defined(RLGL_OCULUS_SUPPORT) - if (oculusEnabled) + if (oculusReady) { // Unbind current framebuffer (Oculus buffer) glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); diff --git a/src/rlgl.h b/src/rlgl.h index 0f9c7a80..675bb74f 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -362,6 +362,7 @@ void SetOculusView(int eye); // Set internal projection and model void BeginOculusDrawing(void); // Begin Oculus drawing configuration void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) bool IsOculusReady(void); // Detect if oculus device (or simulator) is ready +void ToggleVR(void); // Enable/Disable VR experience (Oculus device or simulator) #ifdef __cplusplus } -- cgit v1.2.3 From a8bed54586d721cb08dacceedcd669afcf582e67 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 27 Jun 2016 18:30:18 +0200 Subject: Corrected stream playing with index --- examples/audio_music_stream.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'examples') diff --git a/examples/audio_music_stream.c b/examples/audio_music_stream.c index 8c668cce..e135a6e4 100644 --- a/examples/audio_music_stream.c +++ b/examples/audio_music_stream.c @@ -24,7 +24,7 @@ int main() InitAudioDevice(); // Initialize audio device - PlayMusicStream("resources/audio/guitar_noodling.ogg"); // Play music stream + PlayMusicStream(0, "resources/audio/guitar_noodling.ogg"); // Play music stream int framesCounter = 0; float timePlayed = 0.0f; @@ -52,18 +52,18 @@ int main() { volume = 1.0; framesCounter = 0; - PlayMusicStream("resources/audio/another_file.ogg"); + PlayMusicStream(1, "resources/audio/another_file.ogg"); } SetMusicVolume(volume); } */ - if (IsWindowMinimized()) PauseMusicStream(); - else ResumeMusicStream(); + if (IsWindowMinimized()) PauseMusicStream(0); + else ResumeMusicStream(0); - timePlayed = GetMusicTimePlayed()/GetMusicTimeLength()*100*4; // We scale by 4 to fit 400 pixels + timePlayed = GetMusicTimePlayed(0)/GetMusicTimeLength(0)*100*4; // We scale by 4 to fit 400 pixels - UpdateMusicStream(); // Update music buffer with new stream data + UpdateMusicStream(0); // Update music buffer with new stream data //---------------------------------------------------------------------------------- // Draw -- cgit v1.2.3 From e977915577c1e5a7d46f85e385a27872e6a3f626 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 27 Jun 2016 18:31:23 +0200 Subject: Review examples makefile for RPI --- examples/Makefile | 53 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 22 deletions(-) (limited to 'examples') diff --git a/examples/Makefile b/examples/Makefile index 2d2344af..15df3ec9 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -78,44 +78,38 @@ endif #CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes # define any directories containing required header files +INCLUDES = -I. -I../src -I../src/external + ifeq ($(PLATFORM),PLATFORM_RPI) - INCLUDES = -I. -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads + INCLUDES += -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads endif ifeq ($(PLATFORM),PLATFORM_DESKTOP) # add standard directories for GNU/Linux ifeq ($(PLATFORM_OS),LINUX) - INCLUDES = -I. -I../src -I/usr/local/include/raylib/ - else ifeq ($(PLATFORM_OS),OSX) - INCLUDES = -I. -I../src - else - INCLUDES = -I. -I../../src -IC:/raylib/raylib/src + INCLUDES += -I/usr/local/include/raylib/ + else ifeq ($(PLATFORM_OS),WINDOWS) # external libraries headers # GLFW3 - INCLUDES += -I../../external/glfw3/include + INCLUDES += -I../src/external/glfw3/include # OpenAL Soft - INCLUDES += -I../../external/openal_soft/include + INCLUDES += -I../src/external/openal_soft/include endif endif # define library paths containing required libs +LFLAGS = -L. -L../src + ifeq ($(PLATFORM),PLATFORM_RPI) - LFLAGS = -L. -L../../src -L/opt/vc/lib + LFLAGS += -L/opt/vc/lib endif ifeq ($(PLATFORM),PLATFORM_DESKTOP) # add standard directories for GNU/Linux - ifeq ($(PLATFORM_OS),LINUX) - LFLAGS = -L. -L../../src - else ifeq ($(PLATFORM_OS),OSX) - LFLAGS = -L. -L../src - else - LFLAGS = -L. -L../../src -LC:/raylib/raylib/src + ifeq ($(PLATFORM_OS),WINDOWS) # external libraries to link with # GLFW3 - LFLAGS += -L../../external/glfw3/lib/$(LIBPATH) - ifneq ($(PLATFORM_OS),OSX) + LFLAGS += -L../src/external/glfw3/lib/$(LIBPATH) # OpenAL Soft - LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH) - endif + LFLAGS += -L../src/external/openal_soft/lib/$(LIBPATH) endif endif @@ -148,7 +142,7 @@ ifeq ($(PLATFORM),PLATFORM_RPI) endif ifeq ($(PLATFORM),PLATFORM_WEB) # just adjust the correct path to libraylib.bc - LIBS = ../src/libraylib.bc + LIBS = ../release/html5/libraylib.bc endif # define additional parameters and flags for windows @@ -178,6 +172,8 @@ EXAMPLES = \ core_3d_picking \ core_3d_camera_free \ core_3d_camera_first_person \ + core_2d_camera \ + core_oculus_rift \ shapes_logo_raylib \ shapes_basic_shapes \ shapes_colors_palette \ @@ -208,6 +204,7 @@ EXAMPLES = \ shaders_shapes_textures \ shaders_custom_uniform \ shaders_postprocessing \ + shaders_standard_lighting \ audio_sound_loading \ audio_music_stream \ fix_dylib \ @@ -287,7 +284,15 @@ core_3d_camera_free: core_3d_camera_free.c # compile [core] example - 3d camera first person core_3d_camera_first_person: core_3d_camera_first_person.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) - + +# compile [core] example - 2d camera +core_2d_camera: core_2d_camera.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) + +# compile [core] example - oculus rift +core_oculus_rift: core_oculus_rift.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) + # compile [shapes] example - raylib logo (with basic shapes) shapes_logo_raylib: shapes_logo_raylib.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) @@ -411,7 +416,11 @@ shaders_custom_uniform: shaders_custom_uniform.c # compile [shaders] example - postprocessing shader shaders_postprocessing: shaders_postprocessing.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) - + +# compile [shaders] example - standard lighting +shaders_standard_lighting: shaders_standard_lighting.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) + # compile [audio] example - sound loading and playing (WAV and OGG) audio_sound_loading: audio_sound_loading.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) -- cgit v1.2.3 From c4922c9e8854f9c936b28c3f8b00162b407ae503 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 27 Jun 2016 18:32:56 +0200 Subject: Reorganize shaders to respective folders --- examples/resources/shaders/base.vs | 26 ---- examples/resources/shaders/distortion.fs | 69 ---------- examples/resources/shaders/glsl100/distortion.fs | 68 ++++++++++ examples/resources/shaders/glsl330/distortion.fs | 69 ++++++++++ examples/resources/shaders/standard.fs | 155 ----------------------- examples/resources/shaders/standard.vs | 23 ---- shaders/glsl100/standard.fs | 155 +++++++++++++++++++++++ shaders/glsl100/standard.vs | 23 ++++ shaders/glsl330/standard.fs | 155 +++++++++++++++++++++++ shaders/glsl330/standard.vs | 23 ++++ src/rlgl.c | 2 +- 11 files changed, 494 insertions(+), 274 deletions(-) delete mode 100644 examples/resources/shaders/base.vs delete mode 100644 examples/resources/shaders/distortion.fs create mode 100644 examples/resources/shaders/glsl100/distortion.fs create mode 100644 examples/resources/shaders/glsl330/distortion.fs delete mode 100644 examples/resources/shaders/standard.fs delete mode 100644 examples/resources/shaders/standard.vs create mode 100644 shaders/glsl100/standard.fs create mode 100644 shaders/glsl100/standard.vs create mode 100644 shaders/glsl330/standard.fs create mode 100644 shaders/glsl330/standard.vs (limited to 'examples') diff --git a/examples/resources/shaders/base.vs b/examples/resources/shaders/base.vs deleted file mode 100644 index 638cb8ae..00000000 --- a/examples/resources/shaders/base.vs +++ /dev/null @@ -1,26 +0,0 @@ -#version 330 - -// Input vertex attributes -in vec3 vertexPosition; -in vec2 vertexTexCoord; -in vec3 vertexNormal; -in vec4 vertexColor; - -// Input uniform values -uniform mat4 mvpMatrix; - -// Output vertex attributes (to fragment shader) -out vec2 fragTexCoord; -out vec4 fragColor; - -// NOTE: Add here your custom variables - -void main() -{ - // Send vertex attributes to fragment shader - fragTexCoord = vertexTexCoord; - fragColor = vertexColor; - - // Calculate final vertex position - gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); -} \ No newline at end of file diff --git a/examples/resources/shaders/distortion.fs b/examples/resources/shaders/distortion.fs deleted file mode 100644 index 79bc5fa1..00000000 --- a/examples/resources/shaders/distortion.fs +++ /dev/null @@ -1,69 +0,0 @@ -#version 330 - -// Input vertex attributes (from vertex shader) -in vec2 fragTexCoord; - -// Input uniform values -uniform sampler2D texture0; - -// Output fragment color -out vec4 finalColor; - -// NOTE: Add here your custom variables -const vec2 LeftLensCenter = vec2(0.2863248, 0.5); -const vec2 RightLensCenter = vec2(0.7136753, 0.5); -const vec2 LeftScreenCenter = vec2(0.25, 0.5); -const vec2 RightScreenCenter = vec2(0.75, 0.5); -const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); -const vec2 ScaleIn = vec2(4, 2.2222); -const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); - -/* -// Another set of default values -ChromaAbCorrection = {1.0, 0.0, 1.0, 0} -DistortionK = {1.0, 0.22, 0.24, 0} -Scale = {0.25, 0.5*AspectRatio, 0, 0} -ScaleIn = {4.0, 2/AspectRatio, 0, 0} -Left Screen Center = {0.25, 0.5, 0, 0} -Left Lens Center = {0.287994117, 0.5, 0, 0} -Right Screen Center = {0.75, 0.5, 0, 0} -Right Lens Center = {0.712005913, 0.5, 0, 0} -*/ - -// Scales input texture coordinates for distortion. -vec2 HmdWarp(vec2 in01, vec2 LensCenter) -{ - vec2 theta = (in01 - LensCenter)*ScaleIn; // Scales to [-1, 1] - float rSq = theta.x*theta.x + theta.y*theta.y; - vec2 rvector = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); - - return LensCenter + Scale*rvector; -} - -void main() -{ - // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 - - // The following two variables need to be set per eye - vec2 LensCenter = gl_FragCoord.x < 540 ? LeftLensCenter : RightLensCenter; - vec2 ScreenCenter = gl_FragCoord.x < 540 ? LeftScreenCenter : RightScreenCenter; - - vec2 tc = HmdWarp(fragTexCoord, LensCenter); - - if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); - else - { - //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); - finalColor = texture2D(texture0, tc); - } - - /* - // Chromatic aberration is caused when a lens can't focus every color to the same focal point. - // A simple way to fake this effect, and render it as a quick full-screen post-process, - // is to apply an offset to each color channel in a fragment shader. - vec4 rValue = texture2D(texture0, fragTexCoord - rOffset); - vec4 gValue = texture2D(texture0, fragTexCoord - gOffset); - vec4 bValue = texture2D(texture0, fragTexCoord - bOffset); - finalColor = vec4(rValue.r, gValue.g, bValue.b, 1.0); - */ -} diff --git a/examples/resources/shaders/glsl100/distortion.fs b/examples/resources/shaders/glsl100/distortion.fs new file mode 100644 index 00000000..3a1a45d3 --- /dev/null +++ b/examples/resources/shaders/glsl100/distortion.fs @@ -0,0 +1,68 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; + +// Input uniform values +uniform sampler2D texture0; + +// NOTE: Add here your custom variables +const vec2 LeftLensCenter = vec2(0.2863248, 0.5); +const vec2 RightLensCenter = vec2(0.7136753, 0.5); +const vec2 LeftScreenCenter = vec2(0.25, 0.5); +const vec2 RightScreenCenter = vec2(0.75, 0.5); +const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); +const vec2 ScaleIn = vec2(4, 2.2222); +const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); + +/* +// Another set of default values +ChromaAbCorrection = {1.0, 0.0, 1.0, 0} +DistortionK = {1.0, 0.22, 0.24, 0} +Scale = {0.25, 0.5*AspectRatio, 0, 0} +ScaleIn = {4.0, 2/AspectRatio, 0, 0} +Left Screen Center = {0.25, 0.5, 0, 0} +Left Lens Center = {0.287994117, 0.5, 0, 0} +Right Screen Center = {0.75, 0.5, 0, 0} +Right Lens Center = {0.712005913, 0.5, 0, 0} +*/ + +// Scales input texture coordinates for distortion. +vec2 HmdWarp(vec2 in01, vec2 LensCenter) +{ + vec2 theta = (in01 - LensCenter)*ScaleIn; // Scales to [-1, 1] + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 rvector = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); + + return LensCenter + Scale*rvector; +} + +void main() +{ + // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 + + // The following two variables need to be set per eye + vec2 LensCenter = fragTexCoord.x < 540 ? LeftLensCenter : RightLensCenter; + vec2 ScreenCenter = fragTexCoord.x < 540 ? LeftScreenCenter : RightScreenCenter; + + vec2 tc = HmdWarp(fragTexCoord, LensCenter); + + if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); + else + { + //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); + gl_FragColor = texture2D(texture0, tc); + } + + /* + // Chromatic aberration is caused when a lens can't focus every color to the same focal point. + // A simple way to fake this effect, and render it as a quick full-screen post-process, + // is to apply an offset to each color channel in a fragment shader. + vec4 rValue = texture2D(texture0, fragTexCoord - rOffset); + vec4 gValue = texture2D(texture0, fragTexCoord - gOffset); + vec4 bValue = texture2D(texture0, fragTexCoord - bOffset); + finalColor = vec4(rValue.r, gValue.g, bValue.b, 1.0); + */ +} diff --git a/examples/resources/shaders/glsl330/distortion.fs b/examples/resources/shaders/glsl330/distortion.fs new file mode 100644 index 00000000..e43f8451 --- /dev/null +++ b/examples/resources/shaders/glsl330/distortion.fs @@ -0,0 +1,69 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; + +// Input uniform values +uniform sampler2D texture0; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables +const vec2 LeftLensCenter = vec2(0.2863248, 0.5); +const vec2 RightLensCenter = vec2(0.7136753, 0.5); +const vec2 LeftScreenCenter = vec2(0.25, 0.5); +const vec2 RightScreenCenter = vec2(0.75, 0.5); +const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); +const vec2 ScaleIn = vec2(4, 2.2222); +const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); + +/* +// Another set of default values +ChromaAbCorrection = {1.0, 0.0, 1.0, 0} +DistortionK = {1.0, 0.22, 0.24, 0} +Scale = {0.25, 0.5*AspectRatio, 0, 0} +ScaleIn = {4.0, 2/AspectRatio, 0, 0} +Left Screen Center = {0.25, 0.5, 0, 0} +Left Lens Center = {0.287994117, 0.5, 0, 0} +Right Screen Center = {0.75, 0.5, 0, 0} +Right Lens Center = {0.712005913, 0.5, 0, 0} +*/ + +// Scales input texture coordinates for distortion. +vec2 HmdWarp(vec2 in01, vec2 LensCenter) +{ + vec2 theta = (in01 - LensCenter)*ScaleIn; // Scales to [-1, 1] + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 rvector = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); + + return LensCenter + Scale*rvector; +} + +void main() +{ + // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 + + // The following two variables need to be set per eye + vec2 LensCenter = fragTexCoord.x < 540 ? LeftLensCenter : RightLensCenter; + vec2 ScreenCenter = fragTexCoord.x < 540 ? LeftScreenCenter : RightScreenCenter; + + vec2 tc = HmdWarp(fragTexCoord, LensCenter); + + if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); + else + { + //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); + finalColor = texture2D(texture0, tc); + } + + /* + // Chromatic aberration is caused when a lens can't focus every color to the same focal point. + // A simple way to fake this effect, and render it as a quick full-screen post-process, + // is to apply an offset to each color channel in a fragment shader. + vec4 rValue = texture2D(texture0, fragTexCoord - rOffset); + vec4 gValue = texture2D(texture0, fragTexCoord - gOffset); + vec4 bValue = texture2D(texture0, fragTexCoord - bOffset); + finalColor = vec4(rValue.r, gValue.g, bValue.b, 1.0); + */ +} diff --git a/examples/resources/shaders/standard.fs b/examples/resources/shaders/standard.fs deleted file mode 100644 index e5a6d1bc..00000000 --- a/examples/resources/shaders/standard.fs +++ /dev/null @@ -1,155 +0,0 @@ -#version 330 - -in vec3 fragPosition; -in vec2 fragTexCoord; -in vec4 fragColor; -in vec3 fragNormal; - -out vec4 finalColor; - -uniform sampler2D texture0; -uniform sampler2D texture1; -uniform sampler2D texture2; - -uniform vec4 colAmbient; -uniform vec4 colDiffuse; -uniform vec4 colSpecular; -uniform float glossiness; - -uniform int useNormal; -uniform int useSpecular; - -uniform mat4 modelMatrix; -uniform vec3 viewDir; - -struct Light { - int enabled; - int type; - vec3 position; - vec3 direction; - vec4 diffuse; - float intensity; - float radius; - float coneAngle; -}; - -const int maxLights = 8; -uniform int lightsCount; -uniform Light lights[maxLights]; - -vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s) -{ - vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); - vec3 surfaceToLight = l.position - surfacePos; - - // Diffuse shading - float brightness = clamp(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n)), 0, 1); - float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity; - - // Specular shading - float spec = 0.0; - if (diff > 0.0) - { - vec3 h = normalize(-l.direction + v); - spec = pow(dot(n, h), 3 + glossiness)*s; - } - - return (diff*l.diffuse.rgb + spec*colSpecular.rgb); -} - -vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s) -{ - vec3 lightDir = normalize(-l.direction); - - // Diffuse shading - float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity; - - // Specular shading - float spec = 0.0; - if (diff > 0.0) - { - vec3 h = normalize(lightDir + v); - spec = pow(dot(n, h), 3 + glossiness)*s; - } - - // Combine results - return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb); -} - -vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s) -{ - vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); - vec3 lightToSurface = normalize(surfacePos - l.position); - vec3 lightDir = normalize(-l.direction); - - // Diffuse shading - float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity; - - // Spot attenuation - float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0); - attenuation = dot(lightToSurface, -lightDir); - - float lightToSurfaceAngle = degrees(acos(attenuation)); - if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0; - - float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle; - - // Combine diffuse and attenuation - float diffAttenuation = diff*attenuation; - - // Specular shading - float spec = 0.0; - if (diffAttenuation > 0.0) - { - vec3 h = normalize(lightDir + v); - spec = pow(dot(n, h), 3 + glossiness)*s; - } - - return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb)); -} - -void main() -{ - // Calculate fragment normal in screen space - // NOTE: important to multiply model matrix by fragment normal to apply model transformation (rotation and scale) - mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); - vec3 normal = normalize(normalMatrix*fragNormal); - - // Normalize normal and view direction vectors - vec3 n = normalize(normal); - vec3 v = normalize(viewDir); - - // Calculate diffuse texture color fetching - vec4 texelColor = texture(texture0, fragTexCoord); - vec3 lighting = colAmbient.rgb; - - // Calculate normal texture color fetching or set to maximum normal value by default - if (useNormal == 1) - { - n *= texture(texture1, fragTexCoord).rgb; - n = normalize(n); - } - - // Calculate specular texture color fetching or set to maximum specular value by default - float spec = 1.0; - if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r); - - for (int i = 0; i < lightsCount; i++) - { - // Check if light is enabled - if (lights[i].enabled == 1) - { - // Calculate lighting based on light type - switch (lights[i].type) - { - case 0: lighting += CalcPointLight(lights[i], n, v, spec); break; - case 1: lighting += CalcDirectionalLight(lights[i], n, v, spec); break; - case 2: lighting += CalcSpotLight(lights[i], n, v, spec); break; - default: break; - } - } - } - - // Calculate final fragment color - finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); -} diff --git a/examples/resources/shaders/standard.vs b/examples/resources/shaders/standard.vs deleted file mode 100644 index fc0a5ff4..00000000 --- a/examples/resources/shaders/standard.vs +++ /dev/null @@ -1,23 +0,0 @@ -#version 330 - -in vec3 vertexPosition; -in vec3 vertexNormal; -in vec2 vertexTexCoord; -in vec4 vertexColor; - -out vec3 fragPosition; -out vec2 fragTexCoord; -out vec4 fragColor; -out vec3 fragNormal; - -uniform mat4 mvpMatrix; - -void main() -{ - fragPosition = vertexPosition; - fragTexCoord = vertexTexCoord; - fragColor = vertexColor; - fragNormal = vertexNormal; - - gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); -} \ No newline at end of file diff --git a/shaders/glsl100/standard.fs b/shaders/glsl100/standard.fs new file mode 100644 index 00000000..d5daa445 --- /dev/null +++ b/shaders/glsl100/standard.fs @@ -0,0 +1,155 @@ +#version 100 + +precision mediump float; + +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec4 fragColor; +varying vec3 fragNormal; + +uniform sampler2D texture0; +uniform sampler2D texture1; +uniform sampler2D texture2; + +uniform vec4 colAmbient; +uniform vec4 colDiffuse; +uniform vec4 colSpecular; +uniform float glossiness; + +uniform int useNormal; +uniform int useSpecular; + +uniform mat4 modelMatrix; +uniform vec3 viewDir; + +struct Light { + int enabled; + int type; + vec3 position; + vec3 direction; + vec4 diffuse; + float intensity; + float radius; + float coneAngle; +}; + +const int maxLights = 8; +uniform int lightsCount; +uniform Light lights[maxLights]; + +vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s) +{ + vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); + vec3 surfaceToLight = l.position - surfacePos; + + // Diffuse shading + float brightness = clamp(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n)), 0, 1); + float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity; + + // Specular shading + float spec = 0.0; + if (diff > 0.0) + { + vec3 h = normalize(-l.direction + v); + spec = pow(dot(n, h), 3 + glossiness)*s; + } + + return (diff*l.diffuse.rgb + spec*colSpecular.rgb); +} + +vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s) +{ + vec3 lightDir = normalize(-l.direction); + + // Diffuse shading + float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity; + + // Specular shading + float spec = 0.0; + if (diff > 0.0) + { + vec3 h = normalize(lightDir + v); + spec = pow(dot(n, h), 3 + glossiness)*s; + } + + // Combine results + return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb); +} + +vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s) +{ + vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); + vec3 lightToSurface = normalize(surfacePos - l.position); + vec3 lightDir = normalize(-l.direction); + + // Diffuse shading + float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity; + + // Spot attenuation + float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0); + attenuation = dot(lightToSurface, -lightDir); + + float lightToSurfaceAngle = degrees(acos(attenuation)); + if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0; + + float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle; + + // Combine diffuse and attenuation + float diffAttenuation = diff*attenuation; + + // Specular shading + float spec = 0.0; + if (diffAttenuation > 0.0) + { + vec3 h = normalize(lightDir + v); + spec = pow(dot(n, h), 3 + glossiness)*s; + } + + return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb)); +} + +void main() +{ + // Calculate fragment normal in screen space + // NOTE: important to multiply model matrix by fragment normal to apply model transformation (rotation and scale) + mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); + vec3 normal = normalize(normalMatrix*fragNormal); + + // Normalize normal and view direction vectors + vec3 n = normalize(normal); + vec3 v = normalize(viewDir); + + // Calculate diffuse texture color fetching + vec4 texelColor = texture2D(texture0, fragTexCoord); + vec3 lighting = colAmbient.rgb; + + // Calculate normal texture color fetching or set to maximum normal value by default + if (useNormal == 1) + { + n *= texture2D(texture1, fragTexCoord).rgb; + n = normalize(n); + } + + // Calculate specular texture color fetching or set to maximum specular value by default + float spec = 1.0; + if (useSpecular == 1) spec *= normalize(texture2D(texture2, fragTexCoord).r); + + for (int i = 0; i < lightsCount; i++) + { + // Check if light is enabled + if (lights[i].enabled == 1) + { + // Calculate lighting based on light type + switch (lights[i].type) + { + case 0: lighting += CalcPointLight(lights[i], n, v, spec); break; + case 1: lighting += CalcDirectionalLight(lights[i], n, v, spec); break; + case 2: lighting += CalcSpotLight(lights[i], n, v, spec); break; + default: break; + } + } + } + + // Calculate final fragment color + gl_FragColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); +} diff --git a/shaders/glsl100/standard.vs b/shaders/glsl100/standard.vs new file mode 100644 index 00000000..49c5a3eb --- /dev/null +++ b/shaders/glsl100/standard.vs @@ -0,0 +1,23 @@ +#version 100 + +attribute vec3 vertexPosition; +attribute vec3 vertexNormal; +attribute vec2 vertexTexCoord; +attribute vec4 vertexColor; + +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec4 fragColor; +varying vec3 fragNormal; + +uniform mat4 mvpMatrix; + +void main() +{ + fragPosition = vertexPosition; + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + fragNormal = vertexNormal; + + gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/shaders/glsl330/standard.fs b/shaders/glsl330/standard.fs new file mode 100644 index 00000000..e5a6d1bc --- /dev/null +++ b/shaders/glsl330/standard.fs @@ -0,0 +1,155 @@ +#version 330 + +in vec3 fragPosition; +in vec2 fragTexCoord; +in vec4 fragColor; +in vec3 fragNormal; + +out vec4 finalColor; + +uniform sampler2D texture0; +uniform sampler2D texture1; +uniform sampler2D texture2; + +uniform vec4 colAmbient; +uniform vec4 colDiffuse; +uniform vec4 colSpecular; +uniform float glossiness; + +uniform int useNormal; +uniform int useSpecular; + +uniform mat4 modelMatrix; +uniform vec3 viewDir; + +struct Light { + int enabled; + int type; + vec3 position; + vec3 direction; + vec4 diffuse; + float intensity; + float radius; + float coneAngle; +}; + +const int maxLights = 8; +uniform int lightsCount; +uniform Light lights[maxLights]; + +vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s) +{ + vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); + vec3 surfaceToLight = l.position - surfacePos; + + // Diffuse shading + float brightness = clamp(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n)), 0, 1); + float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity; + + // Specular shading + float spec = 0.0; + if (diff > 0.0) + { + vec3 h = normalize(-l.direction + v); + spec = pow(dot(n, h), 3 + glossiness)*s; + } + + return (diff*l.diffuse.rgb + spec*colSpecular.rgb); +} + +vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s) +{ + vec3 lightDir = normalize(-l.direction); + + // Diffuse shading + float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity; + + // Specular shading + float spec = 0.0; + if (diff > 0.0) + { + vec3 h = normalize(lightDir + v); + spec = pow(dot(n, h), 3 + glossiness)*s; + } + + // Combine results + return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb); +} + +vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s) +{ + vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); + vec3 lightToSurface = normalize(surfacePos - l.position); + vec3 lightDir = normalize(-l.direction); + + // Diffuse shading + float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity; + + // Spot attenuation + float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0); + attenuation = dot(lightToSurface, -lightDir); + + float lightToSurfaceAngle = degrees(acos(attenuation)); + if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0; + + float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle; + + // Combine diffuse and attenuation + float diffAttenuation = diff*attenuation; + + // Specular shading + float spec = 0.0; + if (diffAttenuation > 0.0) + { + vec3 h = normalize(lightDir + v); + spec = pow(dot(n, h), 3 + glossiness)*s; + } + + return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb)); +} + +void main() +{ + // Calculate fragment normal in screen space + // NOTE: important to multiply model matrix by fragment normal to apply model transformation (rotation and scale) + mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); + vec3 normal = normalize(normalMatrix*fragNormal); + + // Normalize normal and view direction vectors + vec3 n = normalize(normal); + vec3 v = normalize(viewDir); + + // Calculate diffuse texture color fetching + vec4 texelColor = texture(texture0, fragTexCoord); + vec3 lighting = colAmbient.rgb; + + // Calculate normal texture color fetching or set to maximum normal value by default + if (useNormal == 1) + { + n *= texture(texture1, fragTexCoord).rgb; + n = normalize(n); + } + + // Calculate specular texture color fetching or set to maximum specular value by default + float spec = 1.0; + if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r); + + for (int i = 0; i < lightsCount; i++) + { + // Check if light is enabled + if (lights[i].enabled == 1) + { + // Calculate lighting based on light type + switch (lights[i].type) + { + case 0: lighting += CalcPointLight(lights[i], n, v, spec); break; + case 1: lighting += CalcDirectionalLight(lights[i], n, v, spec); break; + case 2: lighting += CalcSpotLight(lights[i], n, v, spec); break; + default: break; + } + } + } + + // Calculate final fragment color + finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); +} diff --git a/shaders/glsl330/standard.vs b/shaders/glsl330/standard.vs new file mode 100644 index 00000000..fc0a5ff4 --- /dev/null +++ b/shaders/glsl330/standard.vs @@ -0,0 +1,23 @@ +#version 330 + +in vec3 vertexPosition; +in vec3 vertexNormal; +in vec2 vertexTexCoord; +in vec4 vertexColor; + +out vec3 fragPosition; +out vec2 fragTexCoord; +out vec4 fragColor; +out vec3 fragNormal; + +uniform mat4 mvpMatrix; + +void main() +{ + fragPosition = vertexPosition; + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + fragNormal = vertexNormal; + + gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/src/rlgl.c b/src/rlgl.c index 69c80faf..fa57e9ac 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -2538,7 +2538,7 @@ void InitOculusDevice(void) // Load oculus-distortion shader (oculus parameters setup internally) // TODO: Embed coulus distortion shader (in this function like default shader?) - distortion = LoadShader("resources/shaders/base.vs", "resources/shaders/distortion.fs"); + distortion = LoadShader("resources/shaders/glsl330/base.vs", "resources/shaders/glsl330/distortion.fs"); oculusSimulator = true; vrEnabled = true; -- cgit v1.2.3 From 5a4eb34c39e404fdd5804299111477a10dd3895d Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 27 Jun 2016 18:59:03 +0200 Subject: Corrected issue on distortion shader --- examples/core_oculus_rift.c | 4 +++- examples/resources/shaders/glsl100/distortion.fs | 10 +++------- examples/resources/shaders/glsl330/distortion.fs | 22 ++++++++++------------ 3 files changed, 16 insertions(+), 20 deletions(-) (limited to 'examples') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index 4fe35607..95b89106 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -63,11 +63,13 @@ int main() DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); DrawGrid(10, 1.0f); - + DrawDefaultBuffers(); // Process internal dynamic buffers } End3dMode(); + + DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/resources/shaders/glsl100/distortion.fs b/examples/resources/shaders/glsl100/distortion.fs index 3a1a45d3..19e6656a 100644 --- a/examples/resources/shaders/glsl100/distortion.fs +++ b/examples/resources/shaders/glsl100/distortion.fs @@ -44,17 +44,13 @@ void main() // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 // The following two variables need to be set per eye - vec2 LensCenter = fragTexCoord.x < 540 ? LeftLensCenter : RightLensCenter; - vec2 ScreenCenter = fragTexCoord.x < 540 ? LeftScreenCenter : RightScreenCenter; + vec2 LensCenter = fragTexCoord.x < 0.5 ? LeftLensCenter : RightLensCenter; + vec2 ScreenCenter = fragTexCoord.x < 0.5 ? LeftScreenCenter : RightScreenCenter; vec2 tc = HmdWarp(fragTexCoord, LensCenter); if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); - else - { - //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); - gl_FragColor = texture2D(texture0, tc); - } + else gl_FragColor = texture2D(texture0, tc); /* // Chromatic aberration is caused when a lens can't focus every color to the same focal point. diff --git a/examples/resources/shaders/glsl330/distortion.fs b/examples/resources/shaders/glsl330/distortion.fs index e43f8451..c8777c18 100644 --- a/examples/resources/shaders/glsl330/distortion.fs +++ b/examples/resources/shaders/glsl330/distortion.fs @@ -17,6 +17,7 @@ const vec2 RightScreenCenter = vec2(0.75, 0.5); const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); const vec2 ScaleIn = vec2(4, 2.2222); const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); +const vec4 ChromaAbCorrection = vec4(0.99599999, -0.0040000002, 1.0140001, 0.0); /* // Another set of default values @@ -45,25 +46,22 @@ void main() // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 // The following two variables need to be set per eye - vec2 LensCenter = fragTexCoord.x < 540 ? LeftLensCenter : RightLensCenter; - vec2 ScreenCenter = fragTexCoord.x < 540 ? LeftScreenCenter : RightScreenCenter; + vec2 LensCenter = fragTexCoord.x < 0.5 ? LeftLensCenter : RightLensCenter; + vec2 ScreenCenter = fragTexCoord.x < 0.5 ? LeftScreenCenter : RightScreenCenter; vec2 tc = HmdWarp(fragTexCoord, LensCenter); - if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); - else - { - //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); - finalColor = texture2D(texture0, tc); - } + if (any(bvec2(clamp(tc, ScreenCenter - vec2(0.25, 0.5), ScreenCenter + vec2(0.25, 0.5)) - tc))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); + else finalColor = texture2D(texture0, tc); - /* // Chromatic aberration is caused when a lens can't focus every color to the same focal point. // A simple way to fake this effect, and render it as a quick full-screen post-process, // is to apply an offset to each color channel in a fragment shader. - vec4 rValue = texture2D(texture0, fragTexCoord - rOffset); - vec4 gValue = texture2D(texture0, fragTexCoord - gOffset); - vec4 bValue = texture2D(texture0, fragTexCoord - bOffset); + /* + vec4 rValue = texture2D(texture0, fragTexCoord - ChromaAbCorrection.x); + vec4 gValue = texture2D(texture0, fragTexCoord - ChromaAbCorrection.y); + vec4 bValue = texture2D(texture0, fragTexCoord - ChromaAbCorrection.z); + finalColor = vec4(rValue.r, gValue.g, bValue.b, 1.0); */ } -- cgit v1.2.3 From 6fbf6a1c234ab7db9b975109c3c2138f83684442 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 27 Jun 2016 19:18:53 +0200 Subject: Redesigned distortion shader, added chromatic aberration --- examples/resources/shaders/glsl100/distortion.fs | 51 ++++++++++++----------- examples/resources/shaders/glsl330/distortion.fs | 53 ++++++++++++------------ 2 files changed, 53 insertions(+), 51 deletions(-) (limited to 'examples') diff --git a/examples/resources/shaders/glsl100/distortion.fs b/examples/resources/shaders/glsl100/distortion.fs index 19e6656a..d7b687bf 100644 --- a/examples/resources/shaders/glsl100/distortion.fs +++ b/examples/resources/shaders/glsl100/distortion.fs @@ -29,36 +29,37 @@ Right Screen Center = {0.75, 0.5, 0, 0} Right Lens Center = {0.712005913, 0.5, 0, 0} */ -// Scales input texture coordinates for distortion. -vec2 HmdWarp(vec2 in01, vec2 LensCenter) -{ - vec2 theta = (in01 - LensCenter)*ScaleIn; // Scales to [-1, 1] - float rSq = theta.x*theta.x + theta.y*theta.y; - vec2 rvector = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); - - return LensCenter + Scale*rvector; -} - void main() { - // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 - // The following two variables need to be set per eye vec2 LensCenter = fragTexCoord.x < 0.5 ? LeftLensCenter : RightLensCenter; vec2 ScreenCenter = fragTexCoord.x < 0.5 ? LeftScreenCenter : RightScreenCenter; + + // Scales input texture coordinates for distortion: vec2 HmdWarp(vec2 fragTexCoord, vec2 LensCenter) + vec2 theta = (fragTexCoord - LensCenter)*ScaleIn; // Scales to [-1, 1] + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 theta1 = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); + //vec2 tc = LensCenter + Scale*theta1; + + // Detect whether blue texture coordinates are out of range since these will scaled out the furthest + vec2 thetaBlue = theta1*(ChromaAbParam.z + ChromaAbParam.w*rSq); + vec2 tcBlue = LensCenter + Scale*thetaBlue; - vec2 tc = HmdWarp(fragTexCoord, LensCenter); + if (any(bvec2(clamp(tcBlue, ScreenCenter - vec2(0.25, 0.5), ScreenCenter + vec2(0.25, 0.5)) - tcBlue))) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); + else + { + // Do blue texture lookup + float blue = texture2D(texture0, tcBlue).b; - if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); - else gl_FragColor = texture2D(texture0, tc); - - /* - // Chromatic aberration is caused when a lens can't focus every color to the same focal point. - // A simple way to fake this effect, and render it as a quick full-screen post-process, - // is to apply an offset to each color channel in a fragment shader. - vec4 rValue = texture2D(texture0, fragTexCoord - rOffset); - vec4 gValue = texture2D(texture0, fragTexCoord - gOffset); - vec4 bValue = texture2D(texture0, fragTexCoord - bOffset); - finalColor = vec4(rValue.r, gValue.g, bValue.b, 1.0); - */ + // Do green lookup (no scaling) + vec2 tcGreen = LensCenter + Scale*theta1; + float green = texture2D(texture0, tcGreen).g; + + // Do red scale and lookup + vec2 thetaRed = theta1*(ChromaAbParam.x + ChromaAbParam.y*rSq); + vec2 tcRed = LensCenter + Scale*thetaRed; + float red = texture2D(texture0, tcRed).r; + + gl_FragColor = vec4(red, green, blue, 1.0); + } } diff --git a/examples/resources/shaders/glsl330/distortion.fs b/examples/resources/shaders/glsl330/distortion.fs index c8777c18..4cd9937f 100644 --- a/examples/resources/shaders/glsl330/distortion.fs +++ b/examples/resources/shaders/glsl330/distortion.fs @@ -17,7 +17,7 @@ const vec2 RightScreenCenter = vec2(0.75, 0.5); const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); const vec2 ScaleIn = vec2(4, 2.2222); const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); -const vec4 ChromaAbCorrection = vec4(0.99599999, -0.0040000002, 1.0140001, 0.0); +const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); /* // Another set of default values @@ -31,37 +31,38 @@ Right Screen Center = {0.75, 0.5, 0, 0} Right Lens Center = {0.712005913, 0.5, 0, 0} */ -// Scales input texture coordinates for distortion. -vec2 HmdWarp(vec2 in01, vec2 LensCenter) -{ - vec2 theta = (in01 - LensCenter)*ScaleIn; // Scales to [-1, 1] - float rSq = theta.x*theta.x + theta.y*theta.y; - vec2 rvector = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); - - return LensCenter + Scale*rvector; -} - void main() { - // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 - // The following two variables need to be set per eye vec2 LensCenter = fragTexCoord.x < 0.5 ? LeftLensCenter : RightLensCenter; vec2 ScreenCenter = fragTexCoord.x < 0.5 ? LeftScreenCenter : RightScreenCenter; + + // Scales input texture coordinates for distortion: vec2 HmdWarp(vec2 fragTexCoord, vec2 LensCenter) + vec2 theta = (fragTexCoord - LensCenter)*ScaleIn; // Scales to [-1, 1] + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 theta1 = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); + //vec2 tc = LensCenter + Scale*theta1; + + // Detect whether blue texture coordinates are out of range since these will scaled out the furthest + vec2 thetaBlue = theta1*(ChromaAbParam.z + ChromaAbParam.w*rSq); + vec2 tcBlue = LensCenter + Scale*thetaBlue; - vec2 tc = HmdWarp(fragTexCoord, LensCenter); + if (any(bvec2(clamp(tcBlue, ScreenCenter - vec2(0.25, 0.5), ScreenCenter + vec2(0.25, 0.5)) - tcBlue))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); + else + { + // Do blue texture lookup + float blue = texture(texture0, tcBlue).b; - if (any(bvec2(clamp(tc, ScreenCenter - vec2(0.25, 0.5), ScreenCenter + vec2(0.25, 0.5)) - tc))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); - else finalColor = texture2D(texture0, tc); - - // Chromatic aberration is caused when a lens can't focus every color to the same focal point. - // A simple way to fake this effect, and render it as a quick full-screen post-process, - // is to apply an offset to each color channel in a fragment shader. - /* - vec4 rValue = texture2D(texture0, fragTexCoord - ChromaAbCorrection.x); - vec4 gValue = texture2D(texture0, fragTexCoord - ChromaAbCorrection.y); - vec4 bValue = texture2D(texture0, fragTexCoord - ChromaAbCorrection.z); + // Do green lookup (no scaling) + vec2 tcGreen = LensCenter + Scale*theta1; + float green = texture(texture0, tcGreen).g; + + // Do red scale and lookup + vec2 thetaRed = theta1*(ChromaAbParam.x + ChromaAbParam.y*rSq); + vec2 tcRed = LensCenter + Scale*thetaRed; + float red = texture(texture0, tcRed).r; - finalColor = vec4(rValue.r, gValue.g, bValue.b, 1.0); - */ + finalColor = vec4(red, green, blue, 1.0); + } } + -- cgit v1.2.3 From be61d2f8c1d3ce4579b4e74557fb4773624bf00c Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 27 Jun 2016 20:09:10 +0200 Subject: Added missing parameter --- examples/resources/shaders/glsl100/distortion.fs | 1 + 1 file changed, 1 insertion(+) (limited to 'examples') diff --git a/examples/resources/shaders/glsl100/distortion.fs b/examples/resources/shaders/glsl100/distortion.fs index d7b687bf..a0a6cc18 100644 --- a/examples/resources/shaders/glsl100/distortion.fs +++ b/examples/resources/shaders/glsl100/distortion.fs @@ -16,6 +16,7 @@ const vec2 RightScreenCenter = vec2(0.75, 0.5); const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); const vec2 ScaleIn = vec2(4, 2.2222); const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); +const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); /* // Another set of default values -- cgit v1.2.3 From f88c95ce2d48730a7c4025a65d7b65402ffb8467 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 30 Jun 2016 00:26:56 +0200 Subject: Updated examples and makefile --- examples/Makefile | 5 +++++ examples/core_2d_camera.c | 4 ++-- examples/core_oculus_rift.c | 2 +- examples/core_world_screen.c | 1 - 4 files changed, 8 insertions(+), 4 deletions(-) (limited to 'examples') diff --git a/examples/Makefile b/examples/Makefile index 15df3ec9..711f03a7 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -173,6 +173,7 @@ EXAMPLES = \ core_3d_camera_free \ core_3d_camera_first_person \ core_2d_camera \ + core_world_screen \ core_oculus_rift \ shapes_logo_raylib \ shapes_basic_shapes \ @@ -288,6 +289,10 @@ core_3d_camera_first_person: core_3d_camera_first_person.c # compile [core] example - 2d camera core_2d_camera: core_2d_camera.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) + +# compile [core] example - world screen +core_world_screen: core_world_screen.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) # compile [core] example - oculus rift core_oculus_rift: core_oculus_rift.c diff --git a/examples/core_2d_camera.c b/examples/core_2d_camera.c index 73e1d65f..f2f219ef 100644 --- a/examples/core_2d_camera.c +++ b/examples/core_2d_camera.c @@ -23,8 +23,8 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera"); Rectangle player = { 400, 280, 40, 40 }; - Rectangle buildings[MAX_BUILDINGS] = { 0, 0, 0, 0 }; - Color buildColors[MAX_BUILDINGS] = { 80, 80, 80, 255 }; + Rectangle buildings[MAX_BUILDINGS]; + Color buildColors[MAX_BUILDINGS]; int spacing = 0; diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index 95b89106..c073d3d6 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -34,7 +34,7 @@ int main() Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; - //SetTargetFPS(90); // Set our game to run at 90 frames-per-second + SetTargetFPS(90); // Set our game to run at 90 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop diff --git a/examples/core_world_screen.c b/examples/core_world_screen.c index f3798830..aa9505e8 100644 --- a/examples/core_world_screen.c +++ b/examples/core_world_screen.c @@ -63,7 +63,6 @@ int main() DrawText("Enemy: 100 / 100", cubeScreenPosition.x - MeasureText("Enemy: 100 / 100", 20) / 2, cubeScreenPosition.y, 20, BLACK); DrawText("Text is always on top of the cube", (screenWidth - MeasureText("Text is always on top of the cube", 20)) / 2, 25, 20, GRAY); - EndDrawing(); //---------------------------------------------------------------------------------- -- cgit v1.2.3 From ee72654b557202a673f042484c83d3020ae618b8 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 4 Jul 2016 01:29:23 +0200 Subject: Redesigned stereo rendering mechanism Now it's easier for the user! Just init Oculus device and get stereo rendering! --- examples/core_oculus_rift.c | 11 +- examples/resources/shaders/glsl330/distortion.fs | 9 +- src/core.c | 18 +- src/raylib.h | 2 - src/rlgl.c | 443 ++++++++++++----------- src/rlgl.h | 4 - 6 files changed, 251 insertions(+), 236 deletions(-) (limited to 'examples') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index c073d3d6..131a21c2 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -50,22 +50,15 @@ int main() // Draw //---------------------------------------------------------------------------------- BeginDrawing(); - + ClearBackground(RAYWHITE); - + Begin3dMode(camera); - for (int eye = 0; eye < 2; eye++) - { - SetOculusView(eye); - DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); DrawGrid(10, 1.0f); - - DrawDefaultBuffers(); // Process internal dynamic buffers - } End3dMode(); diff --git a/examples/resources/shaders/glsl330/distortion.fs b/examples/resources/shaders/glsl330/distortion.fs index 4cd9937f..62856341 100644 --- a/examples/resources/shaders/glsl330/distortion.fs +++ b/examples/resources/shaders/glsl330/distortion.fs @@ -10,12 +10,13 @@ uniform sampler2D texture0; out vec4 finalColor; // NOTE: Add here your custom variables -const vec2 LeftLensCenter = vec2(0.2863248, 0.5); -const vec2 RightLensCenter = vec2(0.7136753, 0.5); +const vec2 LeftLensCenter = vec2(0.288, 0.5); +const vec2 RightLensCenter = vec2(0.712, 0.5); const vec2 LeftScreenCenter = vec2(0.25, 0.5); const vec2 RightScreenCenter = vec2(0.75, 0.5); -const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); -const vec2 ScaleIn = vec2(4, 2.2222); +uniform vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); +uniform vec2 ScaleIn = vec2(4, 2.2222); + const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); diff --git a/src/core.c b/src/core.c index 47ce5cea..a8557831 100644 --- a/src/core.c +++ b/src/core.c @@ -520,6 +520,8 @@ void BeginDrawing(void) currentTime = GetTime(); // Number of elapsed seconds since InitTimer() was called updateTime = currentTime - previousTime; previousTime = currentTime; + + if (IsOculusReady()) BeginOculusDrawing(); rlClearScreenBuffers(); // Clear current framebuffers rlLoadIdentity(); // Reset current matrix (MODELVIEW) @@ -533,6 +535,8 @@ void BeginDrawing(void) void EndDrawing(void) { rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) + + if (IsOculusReady()) EndOculusDrawing(); SwapBuffers(); // Copy back buffer to front buffer PollInputEvents(); // Poll user events @@ -608,15 +612,11 @@ void Begin3dMode(Camera camera) rlMultMatrixf(MatrixToFloat(cameraView)); // Multiply MODELVIEW matrix by view matrix (camera) rlEnableDepthTest(); // Enable DEPTH_TEST for 3D - - if (IsOculusReady()) BeginOculusDrawing(); } // Ends 3D mode and returns to default 2D orthographic mode void End3dMode(void) -{ - if (IsOculusReady()) EndOculusDrawing(); - +{ rlglDraw(); // Process internal buffers (update + draw) rlMatrixMode(RL_PROJECTION); // Switch to projection matrix @@ -1021,14 +1021,6 @@ Matrix GetCameraMatrix(Camera camera) return MatrixLookAt(camera.position, camera.target, camera.up); } -// Update and draw default buffers vertex data -// NOTE: This data has been stored dynamically during frame on each Draw*() call -void DrawDefaultBuffers(void) -{ - rlglUpdateDefaultBuffers(); // Upload frame vertex data to GPU - rlglDrawDefaultBuffers(); // Draw vertex data into framebuffer -} - //---------------------------------------------------------------------------------- // Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions //---------------------------------------------------------------------------------- diff --git a/src/raylib.h b/src/raylib.h index 6bacfc67..89fc457f 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -572,7 +572,6 @@ void EndTextureMode(void); // Ends drawing to r Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix) -void DrawDefaultBuffers(void); // Update and draw default buffers vertex data (stored dynamically in frame) void SetTargetFPS(int fps); // Set target FPS (maximum) float GetFPS(void); // Returns current FPS @@ -853,7 +852,6 @@ void DestroyLight(Light light); // Destroy a void InitOculusDevice(void); // Init Oculus Rift device void CloseOculusDevice(void); // Close Oculus Rift device void UpdateOculusTracking(void); // Update Oculus Rift tracking (position and orientation) -void SetOculusView(int eye); // Set internal projection and modelview matrix depending on eyes tracking data void BeginOculusDrawing(void); // Begin Oculus drawing configuration void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) bool IsOculusReady(void); // Detect if oculus device (or simulator) is ready diff --git a/src/rlgl.c b/src/rlgl.c index d3ffdd8b..57e6b894 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -276,9 +276,10 @@ static unsigned int frameIndex = 0; // Oculus frames counter, used to discar static bool oculusReady = false; // Oculus device ready flag static bool oculusSimulator = false; // Oculus device simulator static bool vrEnabled = false; // VR experience enabled (Oculus device or simulator) +static bool vrControl = true; // VR controlled by user code, instead of internally static RenderTexture2D stereoFbo; -static Shader distortion; +static Shader distortionShader; // Compressed textures support flags static bool texCompDXTSupported = false; // DDS texture compression support @@ -315,10 +316,13 @@ static void UnloadDefaultShader(void); // Unload default shader static void UnloadStandardShader(void); // Unload standard shader static void LoadDefaultBuffers(void); // Load default internal buffers (lines, triangles, quads) -void rlglUpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data -void rlglDrawDefaultBuffers(void); // Draw default internal buffers vertex data +static void UpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data +static void DrawDefaultBuffers(int eyesCount); // Draw default internal buffers vertex data static void UnloadDefaultBuffers(void); // Unload default internal buffers vertex data from CPU and GPU +// Set internal projection and modelview matrix depending on eyes tracking data +static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView); + static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array static char *ReadTextFile(const char *fileName); @@ -1205,15 +1209,14 @@ void rlglClose(void) void rlglDraw(void) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) -/* - for (int i = 0; i < modelsCount; i++) - { - rlglDrawMesh(models[i]->mesh, models[i]->material, models[i]->transform); - } -*/ - // NOTE: Default buffers always drawn at the end - rlglUpdateDefaultBuffers(); - rlglDrawDefaultBuffers(); + // NOTE: In a future version, models could be stored in a stack... + //for (int i = 0; i < modelsCount; i++) rlglDrawMesh(models[i]->mesh, models[i]->material, models[i]->transform); + + // NOTE: Default buffers upload and draw + UpdateDefaultBuffers(); + + if (vrEnabled && vrControl) DrawDefaultBuffers(2); + else DrawDefaultBuffers(1); #endif } @@ -1865,26 +1868,23 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) #endif #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + int eyesCount = 1; + if (vrEnabled) eyesCount = 2; + glUseProgram(material.shader.id); + // Upload to shader material.colDiffuse + float vColorDiffuse[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 }; + glUniform4fv(material.shader.tintColorLoc, 1, vColorDiffuse); + // At this point the modelview matrix just contains the view matrix (camera) // That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix() Matrix matView = modelview; // View matrix (camera) Matrix matProjection = projection; // Projection matrix (perspective) - + // Calculate model-view matrix combining matModel and matView Matrix matModelView = MatrixMultiply(transform, matView); // Transform to camera-space coordinates - // Calculate model-view-projection matrix (MVP) - Matrix matMVP = MatrixMultiply(matModelView, matProjection); // Transform to screen-space coordinates - - // Send combined model-view-projection matrix to shader - glUniformMatrix4fv(material.shader.mvpLoc, 1, false, MatrixToFloat(matMVP)); - - // Upload to shader material.colDiffuse - float vColorDiffuse[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 }; - glUniform4fv(material.shader.tintColorLoc, 1, vColorDiffuse); - // Check if using standard shader to get location points // NOTE: standard shader specific locations are got at render time to keep Shader struct as simple as possible (with just default shader locations) if (material.shader.id == standardShader.id) @@ -1989,9 +1989,20 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) if (mesh.indices != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]); } - // Draw call! - if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw - else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount); + for (int eye = 0; eye < eyesCount; eye++) + { + if (eyesCount == 2) SetOculusView(eye, matProjection, matModelView); + + // Calculate model-view-projection matrix (MVP) + Matrix matMVP = MatrixMultiply(modelview, projection); // Transform to screen-space coordinates + + // Send combined model-view-projection matrix to shader + glUniformMatrix4fv(material.shader.mvpLoc, 1, false, MatrixToFloat(matMVP)); + + // Draw call! + if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw + else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount); + } if (material.texNormal.id != 0) { @@ -2016,6 +2027,10 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) } glUseProgram(0); // Unbind shader program + + // Restore projection/modelview matrices + projection = matProjection; + modelview = matView; #endif } @@ -2538,7 +2553,7 @@ void InitOculusDevice(void) // Load oculus-distortion shader (oculus parameters setup internally) // TODO: Embed coulus distortion shader (in this function like default shader?) - distortion = LoadShader("resources/shaders/glsl330/base.vs", "resources/shaders/glsl330/distortion.fs"); + distortionShader = LoadShader("resources/shaders/glsl330/base.vs", "resources/shaders/glsl330/distortion.fs"); oculusSimulator = true; vrEnabled = true; @@ -2564,7 +2579,7 @@ void CloseOculusDevice(void) rlDeleteRenderTextures(stereoFbo); // Unload oculus-distortion shader - UnloadShader(distortion); + UnloadShader(distortionShader); } oculusReady = false; @@ -2615,13 +2630,13 @@ void UpdateOculusTracking(void) } // Set internal projection and modelview matrix depending on eyes tracking data -void SetOculusView(int eye) -{ - Matrix eyeProjection; - Matrix eyeModelView; - +static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView) +{ if (vrEnabled) { + Matrix eyeProjection = matProjection; + Matrix eyeModelView = matModelView; + #if defined(RLGL_OCULUS_SUPPORT) if (oculusReady) { @@ -2639,10 +2654,8 @@ void SetOculusView(int eye) -layer.eyeLayer.RenderPose[eye].Position.z); Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement - eyeModelView = MatrixMultiply(modelview, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement + eyeModelView = MatrixMultiply(matModelView, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement - // TODO: Find a better way to get camera view matrix (instead of using internal modelview) - eyeProjection = layer.eyeProjections[eye]; } else @@ -2651,28 +2664,43 @@ void SetOculusView(int eye) // Setup viewport and projection/modelview matrices using tracking data rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight); - float hmdIPD = 0.064f; - float hmdHScreenSize = 0.14976f; - float hmdVScreenSize = 0.0936f; - //float hmdVScreenCenter = 0.04675f; - float hmdEyeToScreenDistance = 0.041f; - float hmdLensSeparationDistance = 0.064f; + static float IPD = 0.064f; // InterpupillaryDistance + float HScreenSize = 0.14976f; + float VScreenSize = 0.0936f; // HScreenSize/(1280.0f/800.0f) + float VScreenCenter = 0.04675f; + float EyeToScreenDistance = 0.041f; + float LensSeparationDistance = 0.064f; //0.0635f (DK1) - //NOTE: fovy value hardcoded to 60 degrees (Oculus Rift CV1 vertical FOV is 100 degrees) - //float halfScreenDistance = hmdVScreenSize/2.0f; - //float yfov = 2.0f*atan(halfScreenDistance/hmdEyeToScreenDistance); - - float viewCenter = (float)hmdHScreenSize*0.25f; - float eyeProjectionShift = viewCenter - hmdLensSeparationDistance*0.5f; - float projectionCenterOffset = 4.0f*eyeProjectionShift/(float)hmdHScreenSize; - + // NOTE: fovy value obtained from device parameters (Oculus Rift CV1) + float halfScreenDistance = VScreenSize/2.0f; + float fovy = 2.0f*atan(halfScreenDistance/EyeToScreenDistance)*RAD2DEG; + + float viewCenter = (float)HScreenSize*0.25f; + float eyeProjectionShift = viewCenter - LensSeparationDistance*0.5f; + float projectionCenterOffset = 4.0f*eyeProjectionShift/(float)HScreenSize; +/* + static float scale[2] = { 0.25, 0.45 }; + + if (IsKeyDown(KEY_RIGHT)) scale[0] += 0.01; + else if (IsKeyDown(KEY_LEFT)) scale[0] -= 0.01; + else if (IsKeyDown(KEY_UP)) scale[1] += 0.01; + else if (IsKeyDown(KEY_DOWN)) scale[1] -= 0.01; + SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "Scale"), scale, 2); + + if (IsKeyDown(KEY_N)) IPD += 0.02; + else if (IsKeyDown(KEY_M)) IPD -= 0.02; +*/ // The matrixes for offsetting the projection and view for each eye, to achieve stereo effect Vector3 projectionOffset = { -projectionCenterOffset, 0.0f, 0.0f }; - Vector3 viewOffset = { -hmdIPD/2.0f, 0.0f, 0.0f }; + + // Camera movement might seem more natural if we model the head. + // Our axis of rotation is the base of our head, so we might want to add + // some y (base of head to eye level) and -z (center of head to eye protrusion) to the camera positions. + Vector3 viewOffset = { -IPD/2.0f, 0.075f, 0.045f }; // Negate the left eye versions - if (eye == 1) + if (eye == 0) { projectionOffset.x *= -1.0f; viewOffset.x *= -1.0f; @@ -2680,29 +2708,18 @@ void SetOculusView(int eye) // Adjust the view and projection matrixes // View matrix is translated based on the eye offset - Matrix projCenter = MatrixPerspective(60.0, (double)((float)screenWidth*0.5f)/(double)screenHeight, 0.01, 1000.0); + Matrix projCenter = MatrixPerspective(fovy, (double)((float)screenWidth*0.5f)/(double)screenHeight, 0.01, 1000.0); Matrix projTranslation = MatrixTranslate(projectionOffset.x, projectionOffset.y, projectionOffset.z); Matrix viewTranslation = MatrixTranslate(viewOffset.x, viewOffset.y, viewOffset.z); eyeProjection = MatrixMultiply(projCenter, projTranslation); // projection - eyeModelView = MatrixMultiply(modelview, viewTranslation); // modelview + eyeModelView = MatrixMultiply(matModelView, viewTranslation); // modelview MatrixTranspose(&eyeProjection); - - /* - // NOTE: fovy value hardcoded to 60 degrees (Oculus Rift CV1 vertical FOV is 100 degrees) - eyeProjection = MatrixPerspective(60.0, (double)(screenWidth/2)/(double)screenHeight, 0.01, 1000.0); - MatrixTranspose(&eyeProjection); - - // TODO: Compute eyes IPD and apply to current modelview matrix (camera) - Matrix eyeView = MatrixIdentity(); - - eyeModelView = MatrixMultiply(modelview, eyeView); - */ } - SetMatrixModelview(eyeModelView); + SetMatrixModelview(eyeModelView); // ERROR! We are modifying modelview for next eye!!! SetMatrixProjection(eyeProjection); } } @@ -2738,6 +2755,8 @@ void BeginOculusDrawing(void) //glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye) rlClearScreenBuffers(); // Clear current framebuffer(s) + + vrControl = true; } // End Oculus drawing process (and desktop mirror) @@ -2777,40 +2796,44 @@ void EndOculusDrawing(void) rlLoadIdentity(); // Reset internal modelview matrix // Draw RenderTexture (stereoFbo) using distortion shader - BeginShaderMode(distortion); + currentShader = distortionShader; - rlEnableTexture(stereoFbo.texture.id); + rlEnableTexture(stereoFbo.texture.id); - rlPushMatrix(); - rlBegin(RL_QUADS); - rlColor4ub(255, 255, 255, 255); - rlNormal3f(0.0f, 0.0f, 1.0f); + rlPushMatrix(); + rlBegin(RL_QUADS); + rlColor4ub(255, 255, 255, 255); + rlNormal3f(0.0f, 0.0f, 1.0f); - // Bottom-left corner for texture and quad - rlTexCoord2f(0.0f, 1.0f); - rlVertex2f(0.0f, 0.0f); + // Bottom-left corner for texture and quad + rlTexCoord2f(0.0f, 1.0f); + rlVertex2f(0.0f, 0.0f); - // Bottom-right corner for texture and quad - rlTexCoord2f(0.0f, 0.0f); - rlVertex2f(0.0f, stereoFbo.texture.height); + // Bottom-right corner for texture and quad + rlTexCoord2f(0.0f, 0.0f); + rlVertex2f(0.0f, stereoFbo.texture.height); - // Top-right corner for texture and quad - rlTexCoord2f(1.0f, 0.0f); - rlVertex2f(stereoFbo.texture.width, stereoFbo.texture.height); + // Top-right corner for texture and quad + rlTexCoord2f(1.0f, 0.0f); + rlVertex2f(stereoFbo.texture.width, stereoFbo.texture.height); - // Top-left corner for texture and quad - rlTexCoord2f(1.0f, 1.0f); - rlVertex2f(stereoFbo.texture.width, 0.0f); - rlEnd(); - rlPopMatrix(); + // Top-left corner for texture and quad + rlTexCoord2f(1.0f, 1.0f); + rlVertex2f(stereoFbo.texture.width, 0.0f); + rlEnd(); + rlPopMatrix(); - rlDisableTexture(); - - //rlglDraw(); - EndShaderMode(); + rlDisableTexture(); + + UpdateDefaultBuffers(); + DrawDefaultBuffers(1); + + currentShader = defaultShader; } rlDisableDepthTest(); + + vrControl = false; } //---------------------------------------------------------------------------------- @@ -3303,7 +3326,7 @@ static void LoadDefaultBuffers(void) // Update default internal buffers (VAOs/VBOs) with vertex array data // NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0) // TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (change flag required) -void rlglUpdateDefaultBuffers(void) +static void UpdateDefaultBuffers(void) { // Update lines vertex buffers if (lines.vCounter > 0) @@ -3373,146 +3396,154 @@ void rlglUpdateDefaultBuffers(void) // Draw default internal buffers vertex data // NOTE: We draw in this order: lines, triangles, quads -void rlglDrawDefaultBuffers(void) +static void DrawDefaultBuffers(int eyesCount) { - // Set current shader and upload current MVP matrix - if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0)) - { - glUseProgram(currentShader.id); - - // Create modelview-projection matrix - Matrix matMVP = MatrixMultiply(modelview, projection); - - glUniformMatrix4fv(currentShader.mvpLoc, 1, false, MatrixToFloat(matMVP)); - glUniform4f(currentShader.tintColorLoc, 1.0f, 1.0f, 1.0f, 1.0f); - glUniform1i(currentShader.mapTexture0Loc, 0); - - // NOTE: Additional map textures not considered for default buffers drawing - } - - // Draw lines buffers - if (lines.vCounter > 0) + Matrix matProjection = projection; + Matrix matModelView = modelview; + + for (int eye = 0; eye < eyesCount; eye++) { - glBindTexture(GL_TEXTURE_2D, whiteTexture); + if (eyesCount == 2) SetOculusView(eye, matProjection, matModelView); - if (vaoSupported) + // Set current shader and upload current MVP matrix + if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0)) { - glBindVertexArray(lines.vaoId); + glUseProgram(currentShader.id); + + // Create modelview-projection matrix + Matrix matMVP = MatrixMultiply(modelview, projection); + + glUniformMatrix4fv(currentShader.mvpLoc, 1, false, MatrixToFloat(matMVP)); + glUniform4f(currentShader.tintColorLoc, 1.0f, 1.0f, 1.0f, 1.0f); + glUniform1i(currentShader.mapTexture0Loc, 0); + + // NOTE: Additional map textures not considered for default buffers drawing } - else + + // Draw lines buffers + if (lines.vCounter > 0) { - // Bind vertex attrib: position (shader-location = 0) - glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[0]); - glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); - glEnableVertexAttribArray(currentShader.vertexLoc); - - // Bind vertex attrib: color (shader-location = 3) - glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[1]); - glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); - glEnableVertexAttribArray(currentShader.colorLoc); - } + glBindTexture(GL_TEXTURE_2D, whiteTexture); - glDrawArrays(GL_LINES, 0, lines.vCounter); - - if (!vaoSupported) glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindTexture(GL_TEXTURE_2D, 0); - } + if (vaoSupported) + { + glBindVertexArray(lines.vaoId); + } + else + { + // Bind vertex attrib: position (shader-location = 0) + glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[0]); + glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(currentShader.vertexLoc); + + // Bind vertex attrib: color (shader-location = 3) + glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[1]); + glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); + glEnableVertexAttribArray(currentShader.colorLoc); + } - // Draw triangles buffers - if (triangles.vCounter > 0) - { - glBindTexture(GL_TEXTURE_2D, whiteTexture); + glDrawArrays(GL_LINES, 0, lines.vCounter); - if (vaoSupported) - { - glBindVertexArray(triangles.vaoId); - } - else - { - // Bind vertex attrib: position (shader-location = 0) - glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[0]); - glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); - glEnableVertexAttribArray(currentShader.vertexLoc); - - // Bind vertex attrib: color (shader-location = 3) - glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[1]); - glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); - glEnableVertexAttribArray(currentShader.colorLoc); + if (!vaoSupported) glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); } - glDrawArrays(GL_TRIANGLES, 0, triangles.vCounter); + // Draw triangles buffers + if (triangles.vCounter > 0) + { + glBindTexture(GL_TEXTURE_2D, whiteTexture); - if (!vaoSupported) glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindTexture(GL_TEXTURE_2D, 0); - } + if (vaoSupported) + { + glBindVertexArray(triangles.vaoId); + } + else + { + // Bind vertex attrib: position (shader-location = 0) + glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[0]); + glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(currentShader.vertexLoc); + + // Bind vertex attrib: color (shader-location = 3) + glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[1]); + glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); + glEnableVertexAttribArray(currentShader.colorLoc); + } - // Draw quads buffers - if (quads.vCounter > 0) - { - int quadsCount = 0; - int numIndicesToProcess = 0; - int indicesOffset = 0; + glDrawArrays(GL_TRIANGLES, 0, triangles.vCounter); - if (vaoSupported) - { - glBindVertexArray(quads.vaoId); + if (!vaoSupported) glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); } - else + + // Draw quads buffers + if (quads.vCounter > 0) { - // Bind vertex attrib: position (shader-location = 0) - glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[0]); - glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); - glEnableVertexAttribArray(currentShader.vertexLoc); - - // Bind vertex attrib: texcoord (shader-location = 1) - glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[1]); - glVertexAttribPointer(currentShader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0); - glEnableVertexAttribArray(currentShader.texcoordLoc); - - // Bind vertex attrib: color (shader-location = 3) - glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[2]); - glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); - glEnableVertexAttribArray(currentShader.colorLoc); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]); - } + int quadsCount = 0; + int numIndicesToProcess = 0; + int indicesOffset = 0; - //TraceLog(DEBUG, "Draws required per frame: %i", drawsCounter); + if (vaoSupported) + { + glBindVertexArray(quads.vaoId); + } + else + { + // Bind vertex attrib: position (shader-location = 0) + glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[0]); + glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(currentShader.vertexLoc); + + // Bind vertex attrib: texcoord (shader-location = 1) + glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[1]); + glVertexAttribPointer(currentShader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(currentShader.texcoordLoc); + + // Bind vertex attrib: color (shader-location = 3) + glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[2]); + glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); + glEnableVertexAttribArray(currentShader.colorLoc); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]); + } - for (int i = 0; i < drawsCounter; i++) - { - quadsCount = draws[i].vertexCount/4; - numIndicesToProcess = quadsCount*6; // Get number of Quads * 6 index by Quad + //TraceLog(DEBUG, "Draws required per frame: %i", drawsCounter); - //TraceLog(DEBUG, "Quads to render: %i - Vertex Count: %i", quadsCount, draws[i].vertexCount); + for (int i = 0; i < drawsCounter; i++) + { + quadsCount = draws[i].vertexCount/4; + numIndicesToProcess = quadsCount*6; // Get number of Quads * 6 index by Quad - glBindTexture(GL_TEXTURE_2D, draws[i].textureId); + //TraceLog(DEBUG, "Quads to render: %i - Vertex Count: %i", quadsCount, draws[i].vertexCount); - // NOTE: The final parameter tells the GPU the offset in bytes from the start of the index buffer to the location of the first index to process -#if defined(GRAPHICS_API_OPENGL_33) - glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_INT, (GLvoid *)(sizeof(GLuint)*indicesOffset)); -#elif defined(GRAPHICS_API_OPENGL_ES2) - glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_SHORT, (GLvoid *)(sizeof(GLushort)*indicesOffset)); -#endif - //GLenum err; - //if ((err = glGetError()) != GL_NO_ERROR) TraceLog(INFO, "OpenGL error: %i", (int)err); //GL_INVALID_ENUM! + glBindTexture(GL_TEXTURE_2D, draws[i].textureId); - indicesOffset += draws[i].vertexCount/4*6; - } + // NOTE: The final parameter tells the GPU the offset in bytes from the start of the index buffer to the location of the first index to process + #if defined(GRAPHICS_API_OPENGL_33) + glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_INT, (GLvoid *)(sizeof(GLuint)*indicesOffset)); + #elif defined(GRAPHICS_API_OPENGL_ES2) + glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_SHORT, (GLvoid *)(sizeof(GLushort)*indicesOffset)); + #endif + //GLenum err; + //if ((err = glGetError()) != GL_NO_ERROR) TraceLog(INFO, "OpenGL error: %i", (int)err); //GL_INVALID_ENUM! - if (!vaoSupported) - { - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } + indicesOffset += draws[i].vertexCount/4*6; + } - glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures - } + if (!vaoSupported) + { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } - if (vaoSupported) glBindVertexArray(0); // Unbind VAO + glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures + } - glUseProgram(0); // Unbind shader program + if (vaoSupported) glBindVertexArray(0); // Unbind VAO + glUseProgram(0); // Unbind shader program + } + // Reset draws counter drawsCounter = 1; draws[0].textureId = whiteTexture; @@ -3529,6 +3560,10 @@ void rlglDrawDefaultBuffers(void) // Reset depth for next draw currentDepth = -1.0f; + + // Restore projection/modelview matrices + projection = matProjection; + modelview = matModelView; } // Unload default internal buffers vertex data from CPU and GPU diff --git a/src/rlgl.h b/src/rlgl.h index 675bb74f..f52af6f9 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -303,9 +303,6 @@ void rlglClose(void); // De-init rlgl void rlglDraw(void); // Draw VAO/VBO void rlglLoadExtensions(void *loader); // Load OpenGL extensions -void rlglUpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data -void rlglDrawDefaultBuffers(void); // Draw default internal buffers vertex data - unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load texture in GPU RenderTexture2D rlglLoadRenderTexture(int width, int height); // Load a texture to be used for rendering (fbo with color and depth attachments) void rlglUpdateTexture(unsigned int id, int width, int height, int format, void *data); // Update GPU texture with new data @@ -358,7 +355,6 @@ void TraceLog(int msgType, const char *text, ...); void InitOculusDevice(void); // Init Oculus Rift device void CloseOculusDevice(void); // Close Oculus Rift device void UpdateOculusTracking(void); // Update Oculus Rift tracking (position and orientation) -void SetOculusView(int eye); // Set internal projection and modelview matrix depending on eyes tracking data void BeginOculusDrawing(void); // Begin Oculus drawing configuration void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) bool IsOculusReady(void); // Detect if oculus device (or simulator) is ready -- cgit v1.2.3 From 2ff2096b36d80078cbda5e61ff77d7fedeeeaeb5 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 4 Jul 2016 18:35:50 +0200 Subject: Moved Oculus enable drawing to user side... Still thinking about the best way to manage this... --- examples/core_oculus_rift.c | 4 ++++ src/core.c | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'examples') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index 131a21c2..734ba8fd 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -52,6 +52,8 @@ int main() BeginDrawing(); ClearBackground(RAYWHITE); + + if (IsOculusReady()) BeginOculusDrawing(); Begin3dMode(camera); @@ -62,6 +64,8 @@ int main() End3dMode(); + if (IsOculusReady()) EndOculusDrawing(); + DrawFPS(10, 10); EndDrawing(); diff --git a/src/core.c b/src/core.c index a8557831..f8a83e25 100644 --- a/src/core.c +++ b/src/core.c @@ -521,7 +521,7 @@ void BeginDrawing(void) updateTime = currentTime - previousTime; previousTime = currentTime; - if (IsOculusReady()) BeginOculusDrawing(); + //if (IsOculusReady()) BeginOculusDrawing(); rlClearScreenBuffers(); // Clear current framebuffers rlLoadIdentity(); // Reset current matrix (MODELVIEW) @@ -536,7 +536,7 @@ void EndDrawing(void) { rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) - if (IsOculusReady()) EndOculusDrawing(); + //if (IsOculusReady()) EndOculusDrawing(); SwapBuffers(); // Copy back buffer to front buffer PollInputEvents(); // Poll user events @@ -2675,7 +2675,7 @@ static void *MouseThread(void *arg) int mouseRelX = 0; int mouseRelY = 0; - while (1) + while (!windowShouldClose) { if (read(mouseStream, &mouse, sizeof(MouseEvent)) == (int)sizeof(MouseEvent)) { -- cgit v1.2.3 From bc80174357392c0a16b74cd4a9e497a1de367760 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 6 Jul 2016 00:54:38 +0200 Subject: VR Functions renaming (for generic HMD device) Stereo rendering has been moved again to Begin3dMode() and End3dMode(), it has some limitations but makes more sense... --- examples/core_oculus_rift.c | 19 ++++++++----------- src/core.c | 8 ++++---- src/raylib.h | 29 +++++++++++++++++++++-------- src/rlgl.c | 45 +++++++++++++++++++++++---------------------- src/rlgl.h | 16 ++++++++-------- 5 files changed, 64 insertions(+), 53 deletions(-) (limited to 'examples') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index 734ba8fd..fa70c487 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -23,7 +23,8 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [core] example - oculus rift"); - InitOculusDevice(); + // NOTE: If device is not available, it fallbacks to default device (simulator) + InitVrDevice(HMD_OCULUS_RIFT_CV1); // Init VR device (Oculus Rift CV1) // Define the camera to look into our 3d world Camera camera; @@ -42,9 +43,9 @@ int main() { // Update //---------------------------------------------------------------------------------- - UpdateOculusTracking(); + UpdateVrTracking(); - if (IsKeyPressed(KEY_SPACE)) ToggleVR(); + if (IsKeyPressed(KEY_SPACE)) ToggleVrMode(); //---------------------------------------------------------------------------------- // Draw @@ -52,20 +53,16 @@ int main() BeginDrawing(); ClearBackground(RAYWHITE); - - if (IsOculusReady()) BeginOculusDrawing(); Begin3dMode(camera); DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); - + DrawGrid(10, 1.0f); - + End3dMode(); - - if (IsOculusReady()) EndOculusDrawing(); - + DrawFPS(10, 10); EndDrawing(); @@ -74,7 +71,7 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- - CloseOculusDevice(); // Close Oculus Rift device + CloseVrDevice(); // Close VR device CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/src/core.c b/src/core.c index f8a83e25..107fc0a0 100644 --- a/src/core.c +++ b/src/core.c @@ -521,8 +521,6 @@ void BeginDrawing(void) updateTime = currentTime - previousTime; previousTime = currentTime; - //if (IsOculusReady()) BeginOculusDrawing(); - rlClearScreenBuffers(); // Clear current framebuffers rlLoadIdentity(); // Reset current matrix (MODELVIEW) rlMultMatrixf(MatrixToFloat(downscaleView)); // If downscale required, apply it here @@ -535,8 +533,6 @@ void BeginDrawing(void) void EndDrawing(void) { rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) - - //if (IsOculusReady()) EndOculusDrawing(); SwapBuffers(); // Copy back buffer to front buffer PollInputEvents(); // Poll user events @@ -590,6 +586,8 @@ void End2dMode(void) void Begin3dMode(Camera camera) { rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) + + if (IsVrDeviceReady()) BeginVrDrawing(); rlMatrixMode(RL_PROJECTION); // Switch to projection matrix @@ -618,6 +616,8 @@ void Begin3dMode(Camera camera) void End3dMode(void) { rlglDraw(); // Process internal buffers (update + draw) + + if (IsVrDeviceReady()) EndVrDrawing(); rlMatrixMode(RL_PROJECTION); // Switch to projection matrix rlPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack diff --git a/src/raylib.h b/src/raylib.h index 89fc457f..227f83f2 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -527,6 +527,19 @@ typedef struct GestureEvent { // Camera system modes typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode; +// Head Mounted Display devices +typedef enum { + HMD_DEFAULT_DEVICE = 0, + HMD_OCULUS_RIFT_DK2, + HMD_OCULUS_RIFT_CV1, + HMD_VALVE_HTC_VIVE, + HMD_SAMSUNG_GEAR_VR, + HMD_GOOGLE_CARDBOARD, + HMD_SONY_PLAYSTATION_VR, + HMD_RAZER_OSVR, + HMD_FOVE_VR, +} HmdDevice; + #ifdef __cplusplus extern "C" { // Prevents name mangling of functions #endif @@ -846,16 +859,16 @@ Light CreateLight(int type, Vector3 position, Color diffuse); // Create a void DestroyLight(Light light); // Destroy a light and take it out of the list //------------------------------------------------------------------------------------ -// Oculus Rift CV1 Functions (Module: rlgl) +// VR experience Functions (Module: rlgl) // NOTE: This functions are useless when using OpenGL 1.1 //------------------------------------------------------------------------------------ -void InitOculusDevice(void); // Init Oculus Rift device -void CloseOculusDevice(void); // Close Oculus Rift device -void UpdateOculusTracking(void); // Update Oculus Rift tracking (position and orientation) -void BeginOculusDrawing(void); // Begin Oculus drawing configuration -void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) -bool IsOculusReady(void); // Detect if oculus device (or simulator) is ready -void ToggleVR(void); // Enable/Disable VR experience (Oculus device or simulator) +void InitVrDevice(int hmdDevice); // Init VR device +void CloseVrDevice(void); // Close VR device +void UpdateVrTracking(void); // Update VR tracking (position and orientation) +void BeginVrDrawing(void); // Begin VR drawing configuration +void EndVrDrawing(void); // End VR drawing process (and desktop mirror) +bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready +void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator) //------------------------------------------------------------------------------------ // Audio Loading and Playing Functions (Module: audio) diff --git a/src/rlgl.c b/src/rlgl.c index af2d57cb..a71142b0 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -322,7 +322,7 @@ static void DrawDefaultBuffers(int eyesCount); // Draw default internal buffers static void UnloadDefaultBuffers(void); // Unload default internal buffers vertex data from CPU and GPU // Set internal projection and modelview matrix depending on eyes tracking data -static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView); +static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView); static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array @@ -2001,7 +2001,7 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) for (int eye = 0; eye < eyesCount; eye++) { - if (eyesCount == 2) SetOculusView(eye, matProjection, matModelView); + if (eyesCount == 2) SetStereoView(eye, matProjection, matModelView); else modelview = matModelView; // Calculate model-view-projection matrix (MVP) @@ -2504,8 +2504,9 @@ void DestroyLight(Light light) #endif } -// Init Oculus Rift device (or Oculus device simulator) -void InitOculusDevice(void) +// Init VR device (or simulator) +// NOTE: If device is not available, it fallbacks to default device (simulator) +void InitVrDevice(int hmdDevice) { #if defined(RLGL_OCULUS_SUPPORT) // Initialize Oculus device @@ -2557,7 +2558,7 @@ void InitOculusDevice(void) if (!oculusReady) { - TraceLog(WARNING, "VR: Initializing Oculus simulator"); + TraceLog(WARNING, "HMD Device not found: Initializing VR simulator"); // Initialize framebuffer and textures for stereo rendering stereoFbo = rlglLoadRenderTexture(screenWidth, screenHeight); @@ -2571,8 +2572,8 @@ void InitOculusDevice(void) } } -// Close Oculus Rift device (or Oculus device simulator) -void CloseOculusDevice(void) +// Close VR device (or simulator) +void CloseVrDevice(void) { #if defined(RLGL_OCULUS_SUPPORT) if (oculusReady) @@ -2596,20 +2597,20 @@ void CloseOculusDevice(void) oculusReady = false; } -// Detect if oculus device is available -bool IsOculusReady(void) +// Detect if VR device is available +bool IsVrDeviceReady(void) { return (oculusReady || oculusSimulator) && vrEnabled; } -// Enable/Disable VR experience (Oculus device or simulator) -void ToggleVR(void) +// Enable/Disable VR experience (device or simulator) +void ToggleVrMode(void) { vrEnabled = !vrEnabled; } -// Update Oculus Rift tracking (position and orientation) -void UpdateOculusTracking(void) +// Update VR tracking (position and orientation) +void UpdateVrTracking(void) { #if defined(RLGL_OCULUS_SUPPORT) if (oculusReady) @@ -2641,7 +2642,7 @@ void UpdateOculusTracking(void) } // Set internal projection and modelview matrix depending on eyes tracking data -static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView) +static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView) { if (vrEnabled) { @@ -2675,12 +2676,12 @@ static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView) // Setup viewport and projection/modelview matrices using tracking data rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight); - static float IPD = 0.064f; // InterpupillaryDistance + static float IPD = 0.064f; // InterpupillaryDistance float HScreenSize = 0.14976f; - float VScreenSize = 0.0936f; // HScreenSize/(1280.0f/800.0f) - float VScreenCenter = 0.04675f; + float VScreenSize = 0.0936f; // HScreenSize/(1280.0f/800.0f) (DK2) + float VScreenCenter = 0.04675f; // VScreenSize/2 float EyeToScreenDistance = 0.041f; - float LensSeparationDistance = 0.064f; //0.0635f (DK1) + float LensSeparationDistance = 0.064f; //0.0635f (DK1) // NOTE: fovy value obtained from device parameters (Oculus Rift CV1) float halfScreenDistance = VScreenSize/2.0f; @@ -2730,13 +2731,13 @@ static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView) MatrixTranspose(&eyeProjection); } - SetMatrixModelview(eyeModelView); // ERROR! We are modifying modelview for next eye!!! + SetMatrixModelview(eyeModelView); SetMatrixProjection(eyeProjection); } } // Begin Oculus drawing configuration -void BeginOculusDrawing(void) +void BeginVrDrawing(void) { #if defined(RLGL_OCULUS_SUPPORT) if (oculusReady) @@ -2771,7 +2772,7 @@ void BeginOculusDrawing(void) } // End Oculus drawing process (and desktop mirror) -void EndOculusDrawing(void) +void EndVrDrawing(void) { #if defined(RLGL_OCULUS_SUPPORT) if (oculusReady) @@ -3414,7 +3415,7 @@ static void DrawDefaultBuffers(int eyesCount) for (int eye = 0; eye < eyesCount; eye++) { - if (eyesCount == 2) SetOculusView(eye, matProjection, matModelView); + if (eyesCount == 2) SetStereoView(eye, matProjection, matModelView); // Set current shader and upload current MVP matrix if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0)) diff --git a/src/rlgl.h b/src/rlgl.h index f52af6f9..f984c0c6 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -350,15 +350,15 @@ Light CreateLight(int type, Vector3 position, Color diffuse); // Create a void DestroyLight(Light light); // Destroy a light and take it out of the list void TraceLog(int msgType, const char *text, ...); -#endif -void InitOculusDevice(void); // Init Oculus Rift device -void CloseOculusDevice(void); // Close Oculus Rift device -void UpdateOculusTracking(void); // Update Oculus Rift tracking (position and orientation) -void BeginOculusDrawing(void); // Begin Oculus drawing configuration -void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) -bool IsOculusReady(void); // Detect if oculus device (or simulator) is ready -void ToggleVR(void); // Enable/Disable VR experience (Oculus device or simulator) +void InitVrDevice(int hmdDevice); // Init VR device +void CloseVrDevice(void); // Close VR device +void UpdateVrTracking(void); // Update VR tracking (position and orientation) +void BeginVrDrawing(void); // Begin VR drawing configuration +void EndVrDrawing(void); // End VR drawing process (and desktop mirror) +bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready +void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator) +#endif #ifdef __cplusplus } -- cgit v1.2.3 From 09cc27ca7a6d29434bd5f6274788d5a6a8de4ad6 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Wed, 6 Jul 2016 08:47:19 +0200 Subject: Added screenshot for example core_oculus_rift --- examples/core_oculus_rift.png | Bin 0 -> 154835 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 examples/core_oculus_rift.png (limited to 'examples') diff --git a/examples/core_oculus_rift.png b/examples/core_oculus_rift.png new file mode 100644 index 00000000..04a3e067 Binary files /dev/null and b/examples/core_oculus_rift.png differ -- cgit v1.2.3 From 884e13ac2faea7ea91af1fa5a4c1cfaf44dfb4af Mon Sep 17 00:00:00 2001 From: raysan5 Date: Fri, 8 Jul 2016 20:32:06 +0200 Subject: Updated VR support -IN PROGRESS- - Embedded VR distortion shader - Ready to support multiple VR devices - Fallback to VR Simulator if device not ready - Support mono rendering over stereo rendering --- examples/resources/shaders/glsl100/distortion.fs | 20 +- examples/resources/shaders/glsl330/distortion.fs | 21 +- src/rlgl.c | 505 +++++++++++++---------- src/shader_distortion.h | 91 ++++ 4 files changed, 376 insertions(+), 261 deletions(-) create mode 100644 src/shader_distortion.h (limited to 'examples') diff --git a/examples/resources/shaders/glsl100/distortion.fs b/examples/resources/shaders/glsl100/distortion.fs index a0a6cc18..f19c88ae 100644 --- a/examples/resources/shaders/glsl100/distortion.fs +++ b/examples/resources/shaders/glsl100/distortion.fs @@ -8,28 +8,16 @@ varying vec2 fragTexCoord; // Input uniform values uniform sampler2D texture0; -// NOTE: Add here your custom variables +// NOTE: Default parameters for Oculus Rift device const vec2 LeftLensCenter = vec2(0.2863248, 0.5); const vec2 RightLensCenter = vec2(0.7136753, 0.5); const vec2 LeftScreenCenter = vec2(0.25, 0.5); const vec2 RightScreenCenter = vec2(0.75, 0.5); -const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); -const vec2 ScaleIn = vec2(4, 2.2222); -const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); +const vec2 Scale = vec2(0.25, 0.45); +const vec2 ScaleIn = vec2(4.0, 2.2222); +const vec4 HmdWarpParam = vec4(1.0, 0.22, 0.24, 0.0); const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); -/* -// Another set of default values -ChromaAbCorrection = {1.0, 0.0, 1.0, 0} -DistortionK = {1.0, 0.22, 0.24, 0} -Scale = {0.25, 0.5*AspectRatio, 0, 0} -ScaleIn = {4.0, 2/AspectRatio, 0, 0} -Left Screen Center = {0.25, 0.5, 0, 0} -Left Lens Center = {0.287994117, 0.5, 0, 0} -Right Screen Center = {0.75, 0.5, 0, 0} -Right Lens Center = {0.712005913, 0.5, 0, 0} -*/ - void main() { // The following two variables need to be set per eye diff --git a/examples/resources/shaders/glsl330/distortion.fs b/examples/resources/shaders/glsl330/distortion.fs index 62856341..635b86ac 100644 --- a/examples/resources/shaders/glsl330/distortion.fs +++ b/examples/resources/shaders/glsl330/distortion.fs @@ -9,29 +9,16 @@ uniform sampler2D texture0; // Output fragment color out vec4 finalColor; -// NOTE: Add here your custom variables +// NOTE: Default parameters for Oculus Rift device const vec2 LeftLensCenter = vec2(0.288, 0.5); const vec2 RightLensCenter = vec2(0.712, 0.5); const vec2 LeftScreenCenter = vec2(0.25, 0.5); const vec2 RightScreenCenter = vec2(0.75, 0.5); -uniform vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); -uniform vec2 ScaleIn = vec2(4, 2.2222); - -const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); +const vec2 Scale = vec2(0.25, 0.45); +const vec2 ScaleIn = vec2(4.0, 2.2222); +const vec4 HmdWarpParam = vec4(1.0, 0.22, 0.24, 0.0); const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); -/* -// Another set of default values -ChromaAbCorrection = {1.0, 0.0, 1.0, 0} -DistortionK = {1.0, 0.22, 0.24, 0} -Scale = {0.25, 0.5*AspectRatio, 0, 0} -ScaleIn = {4.0, 2/AspectRatio, 0, 0} -Left Screen Center = {0.25, 0.5, 0, 0} -Left Lens Center = {0.287994117, 0.5, 0, 0} -Right Screen Center = {0.75, 0.5, 0, 0} -Right Lens Center = {0.712005913, 0.5, 0, 0} -*/ - void main() { // The following two variables need to be set per eye diff --git a/src/rlgl.c b/src/rlgl.c index 25a6745c..7cb6a751 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -74,7 +74,11 @@ #endif #if !defined(GRAPHICS_API_OPENGL_11) && !defined(RLGL_NO_STANDARD_SHADER) - #include "standard_shader.h" // Standard shader to embed + #include "shader_standard.h" // Standard shader to be embedded +#endif + +#if !defined(GRAPHICS_API_OPENGL_11) && !defined(RLGL_NO_DISTORTION_SHADER) + #include "shader_distortion.h" // Distortion shader to be embedded #endif //#define RLGL_OCULUS_SUPPORT // Enable Oculus Rift code @@ -288,13 +292,14 @@ static OculusMirror mirror; // Oculus mirror texture and fbo static unsigned int frameIndex = 0; // Oculus frames counter, used to discard frames from chain #endif -static bool oculusReady = false; // Oculus device ready flag -static bool oculusSimulator = false; // Oculus device simulator -static bool vrEnabled = false; // VR experience enabled (Oculus device or simulator) -static bool vrControl = true; // VR controlled by user code, instead of internally +static bool vrDeviceReady = false; // VR device ready flag +static bool vrSimulator = false; // VR simulator enabled flag +static bool vrEnabled = false; // VR experience enabled (device or simulator) +static bool vrRendering = true; // VR stereo rendering enabled/disabled flag + // NOTE: This flag is useful to render data over stereo image (i.e. FPS) -static RenderTexture2D stereoFbo; -static Shader distortionShader; +static RenderTexture2D stereoFbo; // Stereo rendering framebuffer +static Shader distortionShader; // Stereo rendering distortion shader (simulator) // Compressed textures support flags static bool texCompDXTSupported = false; // DDS texture compression support @@ -335,12 +340,12 @@ static void UpdateDefaultBuffers(void); // Update default internal buffers ( static void DrawDefaultBuffers(int eyesCount); // Draw default internal buffers vertex data static void UnloadDefaultBuffers(void); // Unload default internal buffers vertex data from CPU and GPU +// Configure stereo rendering (including distortion shader) with HMD device parameters +static void SetupVrDevice(VrDeviceInfo info); + // Set internal projection and modelview matrix depending on eyes tracking data static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView); -// Configure stereo rendering (including distortion shader) with HMD device parameters -static void SetupVrDevice(VrDeviceInfo hmd); - static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array static char *ReadTextFile(const char *fileName); @@ -1233,7 +1238,7 @@ void rlglDraw(void) // NOTE: Default buffers upload and draw UpdateDefaultBuffers(); - if (vrEnabled && vrControl) DrawDefaultBuffers(2); + if (vrEnabled && vrRendering) DrawDefaultBuffers(2); else DrawDefaultBuffers(1); #endif } @@ -2532,66 +2537,65 @@ void DestroyLight(Light light) // NOTE: If device is not available, it fallbacks to default device (simulator) void InitVrDevice(int hmdDevice) { -#if defined(RLGL_OCULUS_SUPPORT) - // Initialize Oculus device - ovrResult result = ovr_Initialize(NULL); - if (OVR_FAILURE(result)) + switch (hmdDevice) { - TraceLog(WARNING, "OVR: Could not initialize Oculus device"); - oculusReady = false; - } - else - { - result = ovr_Create(&session, &luid); - if (OVR_FAILURE(result)) + case HMD_DEFAULT_DEVICE: TraceLog(INFO, "Initializing default VR Device (Oculus Rift CV1)"); + case HMD_OCULUS_RIFT_DK2: + case HMD_OCULUS_RIFT_CV1: { - TraceLog(WARNING, "OVR: Could not create Oculus session"); - ovr_Shutdown(); - oculusReady = false; - } - else - { - hmdDesc = ovr_GetHmdDesc(session); - - TraceLog(INFO, "OVR: Product Name: %s", hmdDesc.ProductName); - TraceLog(INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer); - TraceLog(INFO, "OVR: Product ID: %i", hmdDesc.ProductId); - TraceLog(INFO, "OVR: Product Type: %i", hmdDesc.Type); - //TraceLog(INFO, "OVR: Serial Number: %s", hmdDesc.SerialNumber); - TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); - - // NOTE: Oculus mirror is set to defined screenWidth and screenHeight... - // ...ideally, it should be (hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2) - - // Initialize Oculus Buffers - layer = InitOculusLayer(session); - buffer = LoadOculusBuffer(session, layer.width, layer.height); - mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2); // NOTE: hardcoded... - layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain); - - // Recenter OVR tracking origin - ovr_RecenterTrackingOrigin(session); - - oculusReady = true; - vrEnabled = true; - } - } +#if defined(RLGL_OCULUS_SUPPORT) + vrDeviceReady = InitOculusDevice(); #else - oculusReady = false; + TraceLog(WARNING, "Oculus Rift not supported by default, recompile raylib with Oculus support"); #endif + } break; + case HMD_VALVE_HTC_VIVE: + case HMD_SAMSUNG_GEAR_VR: + case HMD_GOOGLE_CARDBOARD: + case HMD_SONY_PLAYSTATION_VR: + case HMD_RAZER_OSVR: + case HMD_FOVE_VR: TraceLog(WARNING, "VR Device not supported"); + default: break; + } - if (!oculusReady) + if (!vrDeviceReady) { - TraceLog(WARNING, "HMD Device not found: Initializing VR simulator"); + TraceLog(WARNING, "VR Device not found: Initializing VR Simulator"); // Initialize framebuffer and textures for stereo rendering stereoFbo = rlglLoadRenderTexture(screenWidth, screenHeight); - // Load oculus-distortion shader (oculus parameters setup internally) - // TODO: Embed coulus distortion shader (in this function like default shader?) - distortionShader = LoadShader("resources/shaders/glsl330/base.vs", "resources/shaders/glsl330/distortion.fs"); + // Load distortion shader (initialized by default with Oculus Rift CV1 parameters) + distortionShader.id = LoadShaderProgram(vDistortionShaderStr, fDistortionShaderStr); + if (distortionShader.id != 0) LoadDefaultShaderLocations(&distortionShader); + + VrDeviceInfo info = { 0 }; - oculusSimulator = true; + if ((hmdDevice == HMD_DEFAULT_DEVICE) || + (hmdDevice == HMD_OCULUS_RIFT_DK2) || + (hmdDevice == HMD_OCULUS_RIFT_CV1)) + { + info.hResolution = 1280; // HMD horizontal resolution in pixels + info.vResolution = 800; // HMD vertical resolution in pixels + info.hScreenSize = 0.14976f;; // HMD horizontal size in meters + info.vScreenSize = 0.09356f; // HMD vertical size in meters + info.vScreenCenter = 0.04675f; // HMD screen center in meters + info.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters + info.lensSeparationDistance = 0.0635f; // HMD lens separation distance in meters + info.interpupillaryDistance = 0.064f; // HMD IPD (distance between pupils) in meters + info.distortionK[0] = 1.0f; // HMD lens distortion constant parameter 0 + info.distortionK[1] = 0.22f; // HMD lens distortion constant parameter 1 + info.distortionK[2] = 0.24f; // HMD lens distortion constant parameter 2 + info.distortionK[3] = 0.0f; // HMD lens distortion constant parameter 3 + info.chromaAbCorrection[0] = 0.996f; // HMD chromatic aberration correction parameter 0 + info.chromaAbCorrection[1] = -0.004f; // HMD chromatic aberration correction parameter 1 + info.chromaAbCorrection[2] = 1.014f; // HMD chromatic aberration correction parameter 2 + info.chromaAbCorrection[3] = 0.0f; // HMD chromatic aberration correction parameter 3 + } + + SetupVrDevice(info); + + vrSimulator = true; vrEnabled = true; } } @@ -2600,14 +2604,7 @@ void InitVrDevice(int hmdDevice) void CloseVrDevice(void) { #if defined(RLGL_OCULUS_SUPPORT) - if (oculusReady) - { - UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer - UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers - - ovr_Destroy(session); // Free Oculus session data - ovr_Shutdown(); // Close Oculus device connection - } + if (vrDeviceReady) CloseOculusDevice(); else #endif { @@ -2618,13 +2615,13 @@ void CloseVrDevice(void) UnloadShader(distortionShader); } - oculusReady = false; + vrDeviceReady = false; } // Detect if VR device is available bool IsVrDeviceReady(void) { - return (oculusReady || oculusSimulator) && vrEnabled; + return (vrDeviceReady || vrSimulator) && vrEnabled; } // Enable/Disable VR experience (device or simulator) @@ -2637,27 +2634,7 @@ void ToggleVrMode(void) void UpdateVrTracking(void) { #if defined(RLGL_OCULUS_SUPPORT) - if (oculusReady) - { - frameIndex++; - - ovrPosef eyePoses[2]; - ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime); - - layer.eyeLayer.RenderPose[0] = eyePoses[0]; - layer.eyeLayer.RenderPose[1] = eyePoses[1]; - - // Get session status information - ovrSessionStatus sessionStatus; - ovr_GetSessionStatus(session, &sessionStatus); - - if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit..."); - if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session); - //if (sessionStatus.HmdPresent) // HMD is present. - //if (sessionStatus.DisplayLost) // HMD was unplugged or the display driver was manually disabled or encountered a TDR. - //if (sessionStatus.HmdMounted) // HMD is on the user's head. - //if (sessionStatus.IsVisible) // the game or experience has VR focus and is visible in the HMD. - } + if (vrDeviceReady) UpdateOculusTracking(); else #endif { @@ -2665,116 +2642,13 @@ void UpdateVrTracking(void) } } -// Set internal projection and modelview matrix depending on eyes tracking data -static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView) -{ - if (vrEnabled) - { - Matrix eyeProjection = matProjection; - Matrix eyeModelView = matModelView; - -#if defined(RLGL_OCULUS_SUPPORT) - if (oculusReady) - { - rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, - layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h); - - Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, - layer.eyeLayer.RenderPose[eye].Orientation.y, - layer.eyeLayer.RenderPose[eye].Orientation.z, - layer.eyeLayer.RenderPose[eye].Orientation.w }; - QuaternionInvert(&eyeRenderPose); - Matrix eyeOrientation = QuaternionToMatrix(eyeRenderPose); - Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, - -layer.eyeLayer.RenderPose[eye].Position.y, - -layer.eyeLayer.RenderPose[eye].Position.z); - - Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement - eyeModelView = MatrixMultiply(matModelView, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement - - eyeProjection = layer.eyeProjections[eye]; - } - else -#endif - { - // Setup viewport and projection/modelview matrices using tracking data - rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight); - - static float IPD = 0.064f; // InterpupillaryDistance - float HScreenSize = 0.14976f; - float VScreenSize = 0.09356f; // HScreenSize/(1280.0f/800.0f) (DK2) - float VScreenCenter = 0.04675f; // VScreenSize/2 - float EyeToScreenDistance = 0.041f; - float LensSeparationDistance = 0.0635f; //0.0635f (DK2) - - // NOTE: fovy value obtained from device parameters (Oculus Rift CV1) - float halfScreenDistance = VScreenSize/2.0f; - float fovy = 2.0f*atan(halfScreenDistance/EyeToScreenDistance)*RAD2DEG; - - float viewCenter = (float)HScreenSize*0.25f; - float eyeProjectionShift = viewCenter - LensSeparationDistance*0.5f; - float projectionCenterOffset = eyeProjectionShift/(float)HScreenSize; //4.0f*eyeProjectionShift/(float)HScreenSize; -/* - static float scale[2] = { 0.25, 0.45 }; - - if (IsKeyDown(KEY_RIGHT)) scale[0] += 0.01; - else if (IsKeyDown(KEY_LEFT)) scale[0] -= 0.01; - else if (IsKeyDown(KEY_UP)) scale[1] += 0.01; - else if (IsKeyDown(KEY_DOWN)) scale[1] -= 0.01; - - SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "Scale"), scale, 2); - - if (IsKeyDown(KEY_N)) IPD += 0.02; - else if (IsKeyDown(KEY_M)) IPD -= 0.02; -*/ - // The matrixes for offsetting the projection and view for each eye, to achieve stereo effect - Vector3 projectionOffset = { -projectionCenterOffset, 0.0f, 0.0f }; - - // Camera movement might seem more natural if we model the head. - // Our axis of rotation is the base of our head, so we might want to add - // some y (base of head to eye level) and -z (center of head to eye protrusion) to the camera positions. - Vector3 viewOffset = { -IPD/2.0f, 0.075f, 0.045f }; - - // Negate the left eye versions - if (eye == 0) - { - projectionOffset.x *= -1.0f; - viewOffset.x *= -1.0f; - } - - // Adjust the view and projection matrixes - // View matrix is translated based on the eye offset - Matrix projCenter = MatrixPerspective(fovy, (double)((float)screenWidth*0.5f)/(double)screenHeight, 0.01, 1000.0); - - Matrix projTranslation = MatrixTranslate(projectionOffset.x, projectionOffset.y, projectionOffset.z); - Matrix viewTranslation = MatrixTranslate(viewOffset.x, viewOffset.y, viewOffset.z); - - eyeProjection = MatrixMultiply(projCenter, projTranslation); // projection - eyeModelView = MatrixMultiply(matModelView, viewTranslation); // modelview - - MatrixTranspose(&eyeProjection); - } - - SetMatrixModelview(eyeModelView); - SetMatrixProjection(eyeProjection); - } -} - // Begin Oculus drawing configuration void BeginVrDrawing(void) { #if defined(RLGL_OCULUS_SUPPORT) - if (oculusReady) + if (vrDeviceReady) { - GLuint currentTexId; - int currentIndex; - - ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, ¤tIndex); - ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, ¤tTexId); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0); - //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0); // Already binded + BeginOculusDrawing(); } else #endif @@ -2792,26 +2666,16 @@ void BeginVrDrawing(void) //glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye) rlClearScreenBuffers(); // Clear current framebuffer(s) - vrControl = true; + vrRendering = true; } // End Oculus drawing process (and desktop mirror) void EndVrDrawing(void) { #if defined(RLGL_OCULUS_SUPPORT) - if (oculusReady) + if (vrDeviceReady) { - // Unbind current framebuffer (Oculus buffer) - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - - ovr_CommitTextureSwapChain(session, buffer.textureChain); - - ovrLayerHeader *layers = &layer.eyeLayer.Header; - ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1); - - // Blit mirror texture to back buffer - BlitOculusMirror(session, mirror); + EndOculusDrawing(); } else #endif @@ -2869,7 +2733,7 @@ void EndVrDrawing(void) rlDisableDepthTest(); - vrControl = false; + vrRendering = false; } //---------------------------------------------------------------------------------- @@ -3890,25 +3754,34 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight) // Configure stereo rendering (including distortion shader) with HMD device parameters static void SetupVrDevice(VrDeviceInfo hmd) { + // NOTE: fovy value obtained from device parameters (Oculus Rift CV1) + //float fovy = 2.0f*atan((VScreenSize*0.5f)/EyeToScreenDistance)*RAD2DEG; + + //float eyeProjectionShift = ; + //float projectionOffset = (HScreenSize*0.25f - LensSeparationDistance*0.5f)/(float)HScreenSize; + // Compute aspect ratio and FOV - float aspect = ((float)hmd.hResolution/2.0f)/(float)hmd.vResolution; + //float aspect = ((float)hmd.hResolution/2.0f)/(float)hmd.vResolution; + float aspect = (float)screenWidth*0.5f/(float)screenHeight; // Fov-y is normally computed with: 2*atan2(hmd.vScreenSize, 2*hmd.eyeToScreenDistance)*RAD2DEG // ...but with lens distortion it is increased (see Oculus SDK Documentation) float radius = -1.0 - (4*(hmd.hScreenSize/4 - hmd.lensSeparationDistance/2)/hmd.hScreenSize); float distScale = (hmd.distortionK[0] + hmd.distortionK[1]*pow(radius, 2) + hmd.distortionK[2]*pow(radius, 4) + hmd.distortionK[3]*pow(radius, 6)); - float fovy = 2*atan2(hmd.vScreenSize*distScale, 2*hmd.eyeToScreenDistance)*RAD2DEG; + //float fovy = 2.0f*atan2(hmd.vScreenSize*distScale, 2*hmd.eyeToScreenDistance)*RAD2DEG; + float fovy = 2.0f*atan((hmd.vScreenSize*0.5f)/hmd.eyeToScreenDistance)*RAD2DEG; // Compute camera projection matrices - Matrix proj = MatrixPerspective(fovy, aspect, 0.1, 10000); - float projOffset = 4*(hmd.hScreenSize/4 - hmd.interpupillaryDistance/2)/hmd.hScreenSize; + Matrix proj = MatrixPerspective(fovy, aspect, 0.01, 1000.0); + //float projOffset = 4.0f*(hmd.hScreenSize/4 - hmd.interpupillaryDistance/2)/hmd.hScreenSize; + float projOffset = (hmd.hScreenSize*0.25f - hmd.lensSeparationDistance*0.5f)/hmd.hScreenSize; - //Matrix projLeft = MatrixMultiply(MatrixTranslation(projOffset, 0.0, 0.0), proj); - //matrix projRight = MatrixMultiply(MatrixTranslation(-projOffset, 0.0, 0.0)), proj); + //Matrix projLeft = MatrixMultiply(MatrixTranslate(projOffset, 0.0, 0.0), proj); + //matrix projRight = MatrixMultiply(MatrixTranslate(-projOffset, 0.0, 0.0)), proj); // Compute camera transformation matrices - //Matrix viewTransformLeft = MatrixTranslation(-hmd.interpupillaryDistance/2, 0.0, 0.0 ); - //Matrix viewTransformRight = MatrixTranslation(hmd.interpupillaryDistance/2, 0.0, 0.0 ); + //Matrix viewTransformLeft = MatrixTranslate(-hmd.interpupillaryDistance/2, 0.0, 0.0 ); + //Matrix viewTransformRight = MatrixTranslate(hmd.interpupillaryDistance/2, 0.0, 0.0 ); // Compute eyes Viewports // Rectangle viewportLeft = { 0, 0, hmd.hResolution/2, hmd.vResolution }; @@ -3916,50 +3789,226 @@ static void SetupVrDevice(VrDeviceInfo hmd) // Distortion shader parameters float lensShift = 4*(hmd.hScreenSize/4 - hmd.lensSeparationDistance/2)/hmd.hScreenSize; - float leftLensCenter[2] = { lensShift, 0.0f }; - float rightLensCenter[2] = { -lensShift, 0.0f }; + float leftLensCenter[2] = { lensShift, 0.0f }; // REVIEW!!! + float rightLensCenter[2] = { -lensShift, 0.0f }; // REVIEW!!! float leftScreenCenter[2] = { 0.25f, 0.5f }; float rightScreenCenter[2] = { 0.75f, 0.5f }; - float scaleIn[2] = { 1.0f, 1.0f/aspect }; - float scale[2] = { 1.0f/distScale, 1.0f*aspect/distScale }; + float scaleIn[2] = { 1.0f, 1.0f/aspect }; // REVIEW!!! + float scale[2] = { 1.0f/distScale, 1.0f*aspect/distScale }; // REVIEW!!! // Distortion shader parameters update - SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "leftLensCenter"), leftLensCenter, 2); - SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "rightLensCenter"), rightLensCenter, 2); + //SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "leftLensCenter"), leftLensCenter, 2); + //SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "rightLensCenter"), rightLensCenter, 2); SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "leftScreenCenter"), leftScreenCenter, 2); SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "rightScreenCenter"), rightScreenCenter, 2); - SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "scale"), scale, 2); - SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "scaleIn"), scaleIn, 2); + //SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "scale"), scale, 2); + //SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "scaleIn"), scaleIn, 2); SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "hmdWarpParam"), hmd.distortionK, 4); SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "chromaAbParam"), hmd.chromaAbCorrection, 4); } +// Set internal projection and modelview matrix depending on eyes tracking data +static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView) +{ + if (vrEnabled) + { + Matrix eyeProjection = matProjection; + Matrix eyeModelView = matModelView; + #if defined(RLGL_OCULUS_SUPPORT) -static void InitOculusDevice(void) + if (vrDeviceReady) + { + rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, + layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h); + + Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, + layer.eyeLayer.RenderPose[eye].Orientation.y, + layer.eyeLayer.RenderPose[eye].Orientation.z, + layer.eyeLayer.RenderPose[eye].Orientation.w }; + QuaternionInvert(&eyeRenderPose); + Matrix eyeOrientation = QuaternionToMatrix(eyeRenderPose); + Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, + -layer.eyeLayer.RenderPose[eye].Position.y, + -layer.eyeLayer.RenderPose[eye].Position.z); + + Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement + eyeModelView = MatrixMultiply(matModelView, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement + + eyeProjection = layer.eyeProjections[eye]; + } + else +#endif + { + // Setup viewport and projection/modelview matrices using tracking data + rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight); + + float HScreenSize = 0.14976f; + float VScreenSize = 0.09356f; // HScreenSize/(1280.0f/800.0f) (DK2) + float VScreenCenter = 0.04675f; // VScreenSize/2 + float EyeToScreenDistance = 0.041f; + float LensSeparationDistance = 0.0635f; // DK2 + float InterpupillaryDistance = 0.064f; // IPD + + // NOTE: fovy value obtained from device parameters (Oculus Rift CV1) + float halfScreenDistance = VScreenSize/2.0f; + float fovy = 2.0f*atan(halfScreenDistance/EyeToScreenDistance)*RAD2DEG; + + float viewCenter = (float)HScreenSize*0.25f; + float eyeProjectionShift = viewCenter - LensSeparationDistance*0.5f; + float projectionCenterOffset = eyeProjectionShift/(float)HScreenSize; //4.0f*eyeProjectionShift/(float)HScreenSize; +/* + static float scale[2] = { 0.25, 0.45 }; + + if (IsKeyDown(KEY_RIGHT)) scale[0] += 0.01; + else if (IsKeyDown(KEY_LEFT)) scale[0] -= 0.01; + else if (IsKeyDown(KEY_UP)) scale[1] += 0.01; + else if (IsKeyDown(KEY_DOWN)) scale[1] -= 0.01; + + SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "Scale"), scale, 2); + + if (IsKeyDown(KEY_N)) IPD += 0.02; + else if (IsKeyDown(KEY_M)) IPD -= 0.02; +*/ + // The matrixes for offsetting the projection and view for each eye, to achieve stereo effect + Vector3 projectionOffset = { -projectionCenterOffset, 0.0f, 0.0f }; + + // Camera movement might seem more natural if we model the head. + // Our axis of rotation is the base of our head, so we might want to add + // some y (base of head to eye level) and -z (center of head to eye protrusion) to the camera positions. + Vector3 viewOffset = { -InterpupillaryDistance/2.0f, 0.075f, 0.045f }; + + // Negate the left eye versions + if (eye == 0) + { + projectionOffset.x *= -1.0f; + viewOffset.x *= -1.0f; + } + + // Adjust the view and projection matrixes + // View matrix is translated based on the eye offset + Matrix projCenter = MatrixPerspective(fovy, (double)((float)screenWidth*0.5f)/(double)screenHeight, 0.01, 1000.0); + + Matrix projTranslation = MatrixTranslate(projectionOffset.x, projectionOffset.y, projectionOffset.z); + Matrix viewTranslation = MatrixTranslate(viewOffset.x, viewOffset.y, viewOffset.z); + + eyeProjection = MatrixMultiply(projCenter, projTranslation); // projection + eyeModelView = MatrixMultiply(matModelView, viewTranslation); // modelview + + MatrixTranspose(&eyeProjection); + } + + SetMatrixModelview(eyeModelView); + SetMatrixProjection(eyeProjection); + } +} + +#if defined(RLGL_OCULUS_SUPPORT) +// Initialize Oculus device +static bool InitOculusDevice(void) { + bool oculusReady = false; + + ovrResult result = ovr_Initialize(NULL); + + if (OVR_FAILURE(result)) TraceLog(WARNING, "OVR: Could not initialize Oculus device"); + else + { + result = ovr_Create(&session, &luid); + if (OVR_FAILURE(result)) + { + TraceLog(WARNING, "OVR: Could not create Oculus session"); + ovr_Shutdown(); + } + else + { + hmdDesc = ovr_GetHmdDesc(session); + + TraceLog(INFO, "OVR: Product Name: %s", hmdDesc.ProductName); + TraceLog(INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer); + TraceLog(INFO, "OVR: Product ID: %i", hmdDesc.ProductId); + TraceLog(INFO, "OVR: Product Type: %i", hmdDesc.Type); + //TraceLog(INFO, "OVR: Serial Number: %s", hmdDesc.SerialNumber); + TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); + + // NOTE: Oculus mirror is set to defined screenWidth and screenHeight... + // ...ideally, it should be (hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2) + + // Initialize Oculus Buffers + layer = InitOculusLayer(session); + buffer = LoadOculusBuffer(session, layer.width, layer.height); + mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2); // NOTE: hardcoded... + layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain); + + // Recenter OVR tracking origin + ovr_RecenterTrackingOrigin(session); + + oculusReady = true; + vrEnabled = true; + } + } + return oculusReady; } static void CloseOculusDevice(void) { - + UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer + UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers + + ovr_Destroy(session); // Free Oculus session data + ovr_Shutdown(); // Close Oculus device connection } static void UpdateOculusTracking(void) { + frameIndex++; + + ovrPosef eyePoses[2]; + ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime); + + layer.eyeLayer.RenderPose[0] = eyePoses[0]; + layer.eyeLayer.RenderPose[1] = eyePoses[1]; + // Get session status information + ovrSessionStatus sessionStatus; + ovr_GetSessionStatus(session, &sessionStatus); + + if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit..."); + if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session); + //if (sessionStatus.HmdPresent) // HMD is present. + //if (sessionStatus.DisplayLost) // HMD was unplugged or the display driver was manually disabled or encountered a TDR. + //if (sessionStatus.HmdMounted) // HMD is on the user's head. + //if (sessionStatus.IsVisible) // the game or experience has VR focus and is visible in the HMD. } static void BeginOculusDrawing(void) { + GLuint currentTexId; + int currentIndex; + ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, ¤tIndex); + ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, ¤tTexId); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0); + //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0); // Already binded } static void EndOculusDrawing(void) { + // Unbind current framebuffer (Oculus buffer) + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + ovr_CommitTextureSwapChain(session, buffer.textureChain); + + ovrLayerHeader *layers = &layer.eyeLayer.Header; + ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1); + + // Blit mirror texture to back buffer + BlitOculusMirror(session, mirror); } // Load Oculus required buffers: texture-swap-chain, fbo, texture-depth diff --git a/src/shader_distortion.h b/src/shader_distortion.h new file mode 100644 index 00000000..e4ce5d6c --- /dev/null +++ b/src/shader_distortion.h @@ -0,0 +1,91 @@ + +// Vertex shader definition to embed, no external file required +static const char vDistortionShaderStr[] = +#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 vec2 vertexTexCoord; \n" +"attribute vec4 vertexColor; \n" +"varying vec2 fragTexCoord; \n" +"varying vec4 fragColor; \n" +#elif defined(GRAPHICS_API_OPENGL_33) +"#version 330 \n" +"in vec3 vertexPosition; \n" +"in vec2 vertexTexCoord; \n" +"in vec4 vertexColor; \n" +"out vec2 fragTexCoord; \n" +"out vec4 fragColor; \n" +#endif +"uniform mat4 mvpMatrix; \n" +"void main() \n" +"{ \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 +static const char fDistortionShaderStr[] = +#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 vec2 fragTexCoord; \n" +"varying vec4 fragColor; \n" +#elif defined(GRAPHICS_API_OPENGL_33) +"#version 330 \n" +"in vec2 fragTexCoord; \n" +"in vec4 fragColor; \n" +"out vec4 finalColor; \n" +#endif +"uniform sampler2D texture0; \n" +"uniform vec2 leftLensCenter = vec2(0.288, 0.5); \n" +"uniform vec2 rightLensCenter = vec2(0.712, 0.5); \n" +"uniform vec2 leftScreenCenter = vec2(0.25, 0.5); \n" +"uniform vec2 rightScreenCenter = vec2(0.75, 0.5); \n" +"uniform vec2 scale = vec2(0.25, 0.45); \n" +"uniform vec2 scaleIn = vec2(4, 2.2222); \n" +"uniform vec4 hmdWarpParam = vec4(1, 0.22, 0.24, 0); \n" +"uniform vec4 chromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); \n" +"void main() \n" +"{ \n" +" vec2 lensCenter = fragTexCoord.x < 0.5 ? leftLensCenter : rightLensCenter; \n" +" vec2 screenCenter = fragTexCoord.x < 0.5 ? leftScreenCenter : rightScreenCenter; \n" +" vec2 theta = (fragTexCoord - lensCenter)*scaleIn; \n" +" float rSq = theta.x*theta.x + theta.y*theta.y; \n" +" vec2 theta1 = theta*(hmdWarpParam.x + hmdWarpParam.y*rSq + hmdWarpParam.z*rSq*rSq + hmdWarpParam.w*rSq*rSq*rSq); \n" +" vec2 thetaBlue = theta1*(chromaAbParam.z + chromaAbParam.w*rSq); \n" +" vec2 tcBlue = lensCenter + scale*thetaBlue; \n" +" if (any(bvec2(clamp(tcBlue, screenCenter - vec2(0.25, 0.5), screenCenter + vec2(0.25, 0.5)) - tcBlue))) \n" +" { \n" +" finalColor = vec4(0.0, 0.0, 0.0, 1.0); \n" +" } \n" +" else \n" +" { \n" +#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) +" float blue = texture2D(texture0, tcBlue).b; \n" +" vec2 tcGreen = lensCenter + scale*theta1; \n" +" float green = texture2D(texture0, tcGreen).g; \n" +#elif defined(GRAPHICS_API_OPENGL_33) +" float blue = texture(texture0, tcBlue).b; \n" +" vec2 tcGreen = lensCenter + scale*theta1; \n" +" float green = texture(texture0, tcGreen).g; \n" +#endif +" vec2 thetaRed = theta1*(chromaAbParam.x + chromaAbParam.y*rSq); \n" +" vec2 tcRed = lensCenter + scale*thetaRed; \n" +#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) +" float red = texture2D(texture0, tcRed).r; \n" +" gl_FragColor = vec4(red, green, blue, 1.0); \n" +#elif defined(GRAPHICS_API_OPENGL_33) +" float red = texture(texture0, tcRed).r; \n" +" finalColor = vec4(red, green, blue, 1.0); \n" +#endif +" } \n" +"} \n"; -- cgit v1.2.3 From d587cc0e36a45798bad7ff1c01d7ba84723d011e Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 10 Jul 2016 20:07:54 +0200 Subject: Setup values for Oculus Rift DK2 Oculus Rift CV1 default values seem not to be available... --- examples/core_oculus_rift.c | 4 ++-- examples/resources/shaders/glsl100/distortion.fs | 4 ++-- examples/resources/shaders/glsl330/distortion.fs | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'examples') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index fa70c487..b8a60f7a 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -18,8 +18,8 @@ int main() { // Initialization //-------------------------------------------------------------------------------------- - int screenWidth = 1080; - int screenHeight = 600; + int screenWidth = 1280; + int screenHeight = 800; InitWindow(screenWidth, screenHeight, "raylib [core] example - oculus rift"); diff --git a/examples/resources/shaders/glsl100/distortion.fs b/examples/resources/shaders/glsl100/distortion.fs index f19c88ae..50116ce0 100644 --- a/examples/resources/shaders/glsl100/distortion.fs +++ b/examples/resources/shaders/glsl100/distortion.fs @@ -8,13 +8,13 @@ varying vec2 fragTexCoord; // Input uniform values uniform sampler2D texture0; -// NOTE: Default parameters for Oculus Rift device +// NOTE: Default parameters for Oculus Rift DK2 device const vec2 LeftLensCenter = vec2(0.2863248, 0.5); const vec2 RightLensCenter = vec2(0.7136753, 0.5); const vec2 LeftScreenCenter = vec2(0.25, 0.5); const vec2 RightScreenCenter = vec2(0.75, 0.5); const vec2 Scale = vec2(0.25, 0.45); -const vec2 ScaleIn = vec2(4.0, 2.2222); +const vec2 ScaleIn = vec2(4.0, 2.5); const vec4 HmdWarpParam = vec4(1.0, 0.22, 0.24, 0.0); const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); diff --git a/examples/resources/shaders/glsl330/distortion.fs b/examples/resources/shaders/glsl330/distortion.fs index 635b86ac..cb4be8fc 100644 --- a/examples/resources/shaders/glsl330/distortion.fs +++ b/examples/resources/shaders/glsl330/distortion.fs @@ -9,13 +9,13 @@ uniform sampler2D texture0; // Output fragment color out vec4 finalColor; -// NOTE: Default parameters for Oculus Rift device -const vec2 LeftLensCenter = vec2(0.288, 0.5); -const vec2 RightLensCenter = vec2(0.712, 0.5); +// NOTE: Default parameters for Oculus Rift DK2 device +const vec2 LeftLensCenter = vec2(0.2863248, 0.5); +const vec2 RightLensCenter = vec2(0.7136753, 0.5); const vec2 LeftScreenCenter = vec2(0.25, 0.5); const vec2 RightScreenCenter = vec2(0.75, 0.5); const vec2 Scale = vec2(0.25, 0.45); -const vec2 ScaleIn = vec2(4.0, 2.2222); +const vec2 ScaleIn = vec2(4.0, 2.5); const vec4 HmdWarpParam = vec4(1.0, 0.22, 0.24, 0.0); const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); -- cgit v1.2.3 From 84d1b19f61865d1bad32c9e159955a30efa57103 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 11 Jul 2016 14:43:58 +0200 Subject: Added custom Oculus CV1 parameters Matching the same stereo rendering result given by Oculus PC SDK for Oculus Rift CV1 is very difficult because hardware has changed a lot and DK2 distortion shader and parameters don't fit on CV1. Some custom parameters have been calculated to simulate kind of CV1 stereo rendering. Further work is required on this point. --- examples/core_oculus_rift.c | 6 ++- src/rlgl.c | 94 +++++++++++++++++++++++++++++---------------- 2 files changed, 65 insertions(+), 35 deletions(-) (limited to 'examples') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index b8a60f7a..88e411d4 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -18,8 +18,10 @@ int main() { // Initialization //-------------------------------------------------------------------------------------- - int screenWidth = 1280; - int screenHeight = 800; + int screenWidth = 1080; + int screenHeight = 600; + + // NOTE: screenWidth/screenHeight should match VR device aspect ratio InitWindow(screenWidth, screenHeight, "raylib [core] example - oculus rift"); diff --git a/src/rlgl.c b/src/rlgl.c index 65249f5e..25005870 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -2570,38 +2570,62 @@ void InitVrDevice(int hmdDevice) if (!vrDeviceReady) { - TraceLog(WARNING, "VR Device not found: Initializing VR Simulator (Oculus Rift DK2)"); + TraceLog(WARNING, "VR Device not found: Initializing VR Simulator (Oculus Rift CV1)"); + if (hmdDevice == HMD_OCULUS_RIFT_DK2) + { + // Oculus Rift DK2 parameters + hmd.hResolution = 1280; // HMD horizontal resolution in pixels + hmd.vResolution = 800; // HMD vertical resolution in pixels + hmd.hScreenSize = 0.14976f; // HMD horizontal size in meters + hmd.vScreenSize = 0.09356f; // HMD vertical size in meters + hmd.vScreenCenter = 0.04678f; // HMD screen center in meters + hmd.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters + hmd.lensSeparationDistance = 0.0635f; // HMD lens separation distance in meters + hmd.interpupillaryDistance = 0.064f; // HMD IPD (distance between pupils) in meters + hmd.distortionK[0] = 1.0f; // HMD lens distortion constant parameter 0 + hmd.distortionK[1] = 0.22f; // HMD lens distortion constant parameter 1 + hmd.distortionK[2] = 0.24f; // HMD lens distortion constant parameter 2 + hmd.distortionK[3] = 0.0f; // HMD lens distortion constant parameter 3 + hmd.chromaAbCorrection[0] = 0.996f; // HMD chromatic aberration correction parameter 0 + hmd.chromaAbCorrection[1] = -0.004f; // HMD chromatic aberration correction parameter 1 + hmd.chromaAbCorrection[2] = 1.014f; // HMD chromatic aberration correction parameter 2 + hmd.chromaAbCorrection[3] = 0.0f; // HMD chromatic aberration correction parameter 3 + } + else if ((hmdDevice == HMD_DEFAULT_DEVICE) || (hmdDevice == HMD_OCULUS_RIFT_CV1)) + { + // Oculus Rift CV1 parameters + // NOTE: CV1 represents a complete HMD redesign compared to previous versions, + // new Fresnel-hybrid-asymmetric lenses have been added and, consequently, + // previous parameters (DK2) and distortion shader (DK2) doesn't work any more. + // I just defined a set of parameters for simulator that approximate to CV1 stereo rendering + // but result is not the same obtained with Oculus PC SDK. + hmd.hResolution = 2160; // HMD horizontal resolution in pixels + hmd.vResolution = 1200; // HMD vertical resolution in pixels + hmd.hScreenSize = 0.133793f; // HMD horizontal size in meters + hmd.vScreenSize = 0.0669; // HMD vertical size in meters + hmd.vScreenCenter = 0.04678f; // HMD screen center in meters + hmd.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters + hmd.lensSeparationDistance = 0.07f; // HMD lens separation distance in meters + hmd.interpupillaryDistance = 0.07f; // HMD IPD (distance between pupils) in meters + hmd.distortionK[0] = 1.0f; // HMD lens distortion constant parameter 0 + hmd.distortionK[1] = 0.22f; // HMD lens distortion constant parameter 1 + hmd.distortionK[2] = 0.24f; // HMD lens distortion constant parameter 2 + hmd.distortionK[3] = 0.0f; // HMD lens distortion constant parameter 3 + hmd.chromaAbCorrection[0] = 0.996f; // HMD chromatic aberration correction parameter 0 + hmd.chromaAbCorrection[1] = -0.004f; // HMD chromatic aberration correction parameter 1 + hmd.chromaAbCorrection[2] = 1.014f; // HMD chromatic aberration correction parameter 2 + hmd.chromaAbCorrection[3] = 0.0f; // HMD chromatic aberration correction parameter 3 + } + // Initialize framebuffer and textures for stereo rendering + // NOTE: screen size should match HMD aspect ratio vrConfig.stereoFbo = rlglLoadRenderTexture(screenWidth, screenHeight); // Load distortion shader (initialized by default with Oculus Rift CV1 parameters) vrConfig.distortionShader.id = LoadShaderProgram(vDistortionShaderStr, fDistortionShaderStr); if (vrConfig.distortionShader.id != 0) LoadDefaultShaderLocations(&vrConfig.distortionShader); - if ((hmdDevice == HMD_DEFAULT_DEVICE) || - (hmdDevice == HMD_OCULUS_RIFT_DK2) || - (hmdDevice == HMD_OCULUS_RIFT_CV1)) - { - // NOTE: Oculus Rift DK2 parameters - hmd.hResolution = 1280; // HMD horizontal resolution in pixels - hmd.vResolution = 800; // HMD vertical resolution in pixels - hmd.hScreenSize = 0.14976f;; // HMD horizontal size in meters - hmd.vScreenSize = 0.09356f; // HMD vertical size in meters - hmd.vScreenCenter = 0.04675f; // HMD screen center in meters - hmd.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters - hmd.lensSeparationDistance = 0.0635f; // HMD lens separation distance in meters - hmd.interpupillaryDistance = 0.064f; // HMD IPD (distance between pupils) in meters - hmd.distortionK[0] = 1.0f; // HMD lens distortion constant parameter 0 - hmd.distortionK[1] = 0.22f; // HMD lens distortion constant parameter 1 - hmd.distortionK[2] = 0.24f; // HMD lens distortion constant parameter 2 - hmd.distortionK[3] = 0.0f; // HMD lens distortion constant parameter 3 - hmd.chromaAbCorrection[0] = 0.996f; // HMD chromatic aberration correction parameter 0 - hmd.chromaAbCorrection[1] = -0.004f; // HMD chromatic aberration correction parameter 1 - hmd.chromaAbCorrection[2] = 1.014f; // HMD chromatic aberration correction parameter 2 - hmd.chromaAbCorrection[3] = 0.0f; // HMD chromatic aberration correction parameter 3 - } - SetStereoConfig(hmd); vrSimulator = true; @@ -3761,9 +3785,8 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight) static void SetStereoConfig(VrDeviceInfo hmd) { // Compute aspect ratio - //float aspect = ((float)hmd.hResolution*0.5f)/(float)hmd.vResolution; - float aspect = (float)screenWidth*0.5f/(float)screenHeight; - + float aspect = ((float)hmd.hResolution*0.5f)/(float)hmd.vResolution; + // Compute lens parameters float lensShift = (hmd.hScreenSize*0.25f - hmd.lensSeparationDistance*0.5f)/hmd.hScreenSize; float leftLensCenter[2] = { 0.25 + lensShift, 0.5f }; @@ -3779,12 +3802,19 @@ static void SetStereoConfig(VrDeviceInfo hmd) hmd.distortionK[1]*lensRadiusSq + hmd.distortionK[2]*lensRadiusSq*lensRadiusSq + hmd.distortionK[3]*lensRadiusSq*lensRadiusSq*lensRadiusSq; - + + TraceLog(DEBUG, "VR: Distortion Scale: %f", distortionScale); + float normScreenWidth = 0.5f; float normScreenHeight = 1.0f; float scaleIn[2] = { 2/normScreenWidth, 2/normScreenHeight/aspect }; float scale[2] = { normScreenWidth*0.5/distortionScale, normScreenHeight*0.5*aspect/distortionScale }; + TraceLog(DEBUG, "VR: Distortion Shader: LeftLensCenter = { %f, %f }", leftLensCenter[0], leftLensCenter[1]); + TraceLog(DEBUG, "VR: Distortion Shader: RightLensCenter = { %f, %f }", rightLensCenter[0], rightLensCenter[1]); + TraceLog(DEBUG, "VR: Distortion Shader: Scale = { %f, %f }", scale[0], scale[1]); + TraceLog(DEBUG, "VR: Distortion Shader: ScaleIn = { %f, %f }", scaleIn[0], scaleIn[1]); + // Update distortion shader with lens and distortion-scale parameters SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "leftLensCenter"), leftLensCenter, 2); SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "rightLensCenter"), rightLensCenter, 2); @@ -3798,8 +3828,9 @@ static void SetStereoConfig(VrDeviceInfo hmd) // Fovy is normally computed with: 2*atan2(hmd.vScreenSize, 2*hmd.eyeToScreenDistance)*RAD2DEG // ...but with lens distortion it is increased (see Oculus SDK Documentation) - float fovy = 2.0f*atan2(hmd.vScreenSize*0.5f*distortionScale, hmd.eyeToScreenDistance)*RAD2DEG; // Really need distortionScale? - + //float fovy = 2.0f*atan2(hmd.vScreenSize*0.5f*distortionScale, hmd.eyeToScreenDistance)*RAD2DEG; // Really need distortionScale? + float fovy = 2.0f*atan2(hmd.vScreenSize*0.5f, hmd.eyeToScreenDistance)*RAD2DEG; + // Compute camera projection matrices float projOffset = 4.0f*lensShift; // Scaled to projection space coordinates [-1..1] Matrix proj = MatrixPerspective(fovy, aspect, 0.01, 1000.0); @@ -3820,9 +3851,6 @@ static void SetStereoConfig(VrDeviceInfo hmd) // Compute eyes Viewports //vrConfig.eyesViewport[0] = (Rectangle){ 0, 0, hmd.hResolution/2, hmd.vResolution }; //vrConfig.eyesViewport[1] = (Rectangle){ hmd.hResolution/2, 0, hmd.hResolution/2, hmd.vResolution }; - - //https://forums.oculus.com/vip/discussion/3413/calculating-the-distortion-shader-parameters - //https://vrwiki.wikispaces.com/Theory+%26+practice } // Set internal projection and modelview matrix depending on eyes tracking data -- cgit v1.2.3 From 3876f19d6a385001a4238ec27bcf3d7643dd190f Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 12 Jul 2016 01:54:47 +0200 Subject: Corrected some issues on OpenGL ES --- examples/Makefile | 5 +++-- examples/models_obj_loading.c | 2 +- examples/resources/shaders/glsl100/grayscale.fs | 4 ++-- examples/resources/shaders/glsl100/swirl.fs | 8 ++++---- examples/resources/shaders/glsl330/swirl.fs | 6 +++--- 5 files changed, 13 insertions(+), 12 deletions(-) (limited to 'examples') diff --git a/examples/Makefile b/examples/Makefile index 711f03a7..d20e229b 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -120,8 +120,9 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) # libraries for Debian GNU/Linux desktop compiling # requires the following packages: # libglfw3-dev libopenal-dev libegl1-mesa-dev - LIBS = -lraylib -lglfw3 -lGL -lopenal -lm -pthread -ldl -lX11 \ - -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor + LIBS = -lraylib -lglfw3 -lGL -lopenal -lm -pthread -ldl + # on XWindow could require also below libraries, just uncomment + #LIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor else ifeq ($(PLATFORM_OS),OSX) # libraries for OS X 10.9 desktop compiling diff --git a/examples/models_obj_loading.c b/examples/models_obj_loading.c index a6969f70..50d42d2e 100644 --- a/examples/models_obj_loading.c +++ b/examples/models_obj_loading.c @@ -49,7 +49,7 @@ int main() DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture - DrawGrid(10, 1.0f); // Draw a grid + DrawGrid(10, 1.0f); // Draw a grid DrawGizmo(position); // Draw gizmo diff --git a/examples/resources/shaders/glsl100/grayscale.fs b/examples/resources/shaders/glsl100/grayscale.fs index cf857488..15174ea5 100644 --- a/examples/resources/shaders/glsl100/grayscale.fs +++ b/examples/resources/shaders/glsl100/grayscale.fs @@ -8,14 +8,14 @@ varying vec4 fragColor; // Input uniform values uniform sampler2D texture0; -uniform vec4 fragTintColor; +uniform vec4 colDiffuse; // NOTE: Add here your custom variables void main() { // Texel color fetching from texture sampler - vec4 texelColor = texture2D(texture0, fragTexCoord)*fragTintColor*fragColor; + vec4 texelColor = texture2D(texture0, fragTexCoord)*colDiffuse*fragColor; // Convert texel color to grayscale using NTSC conversion weights float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); diff --git a/examples/resources/shaders/glsl100/swirl.fs b/examples/resources/shaders/glsl100/swirl.fs index 0d6d24f2..ca7668b2 100644 --- a/examples/resources/shaders/glsl100/swirl.fs +++ b/examples/resources/shaders/glsl100/swirl.fs @@ -8,7 +8,7 @@ varying vec4 fragColor; // Input uniform values uniform sampler2D texture0; -uniform vec4 fragTintColor; +uniform vec4 colDiffuse; // NOTE: Add here your custom variables @@ -18,7 +18,7 @@ const float renderHeight = 480.0; // Use uniforms instead... float radius = 250.0; float angle = 0.8; -uniform vec2 center = vec2(200.0, 200.0); +uniform vec2 center; void main() { @@ -39,7 +39,7 @@ void main() } tc += center; - vec3 color = texture2D(texture0, tc/texSize).rgb; + vec4 color = texture2D(texture0, tc/texSize)*colDiffuse*fragColor;; - gl_FragColor = vec4(color, 1.0);; + gl_FragColor = vec4(color.rgb, 1.0);; } \ No newline at end of file diff --git a/examples/resources/shaders/glsl330/swirl.fs b/examples/resources/shaders/glsl330/swirl.fs index 80c16cc9..5d238ac9 100644 --- a/examples/resources/shaders/glsl330/swirl.fs +++ b/examples/resources/shaders/glsl330/swirl.fs @@ -6,7 +6,7 @@ in vec4 fragColor; // Input uniform values uniform sampler2D texture0; -uniform vec4 fragTintColor; +uniform vec4 colDiffuse; // Output fragment color out vec4 finalColor; @@ -40,7 +40,7 @@ void main() } tc += center; - vec3 color = texture(texture0, tc/texSize).rgb; + vec4 color = texture2D(texture0, tc/texSize)*colDiffuse*fragColor;; - finalColor = vec4(color, 1.0);; + finalColor = vec4(color.rgb, 1.0);; } \ No newline at end of file -- cgit v1.2.3