diff --git a/examples/oculus_glfw_sample/oculus_glfw_sample.c b/examples/oculus_glfw_sample/oculus_glfw_sample.c index 5166bac64..9f438185f 100644 --- a/examples/oculus_glfw_sample/oculus_glfw_sample.c +++ b/examples/oculus_glfw_sample/oculus_glfw_sample.c @@ -30,7 +30,7 @@ #define RLGL_STANDALONE #include "rlgl.h" -//#define PLATFORM_OCULUS +#define PLATFORM_OCULUS #if defined(PLATFORM_OCULUS) #include "OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL @@ -72,7 +72,7 @@ typedef struct OculusMirror { typedef struct OculusLayer { ovrViewScaleDesc viewScaleDesc; ovrLayerEyeFov eyeLayer; // layer 0 - //ovrLayerQuad quadLayer; // layer 1 + //ovrLayerQuad quadLayer; // TODO: layer 1: '2D' quad for GUI Matrix eyeProjections[2]; int width; int height; @@ -222,6 +222,7 @@ int main(void) layer.eyeLayer.RenderPose[0] = eyePoses[0]; layer.eyeLayer.RenderPose[1] = eyePoses[1]; #endif + Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up); //---------------------------------------------------------------------------------- // Draw @@ -229,13 +230,12 @@ int main(void) #if defined(PLATFORM_OCULUS) SetOculusBuffer(session, buffer); #endif - - rlClearScreenBuffers(); // Clear current framebuffers + rlClearScreenBuffers(); // Clear current framebuffer(s) #if defined(PLATFORM_OCULUS) for (int eye = 0; eye < 2; eye++) { - glViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h); + 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){ eyePoses[eye].Orientation.x, eyePoses[eye].Orientation.y, eyePoses[eye].Orientation.z, eyePoses[eye].Orientation.w }; QuaternionInvert(&eyeRPose); @@ -244,32 +244,39 @@ int main(void) Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); Matrix modelview = MatrixMultiply(matView, eyeView); - Matrix mvp = MatrixMultiply(modelview, layer.eyeProjections[eye]); + //Matrix mvp = MatrixMultiply(modelview, layer.eyeProjections[eye]); + + SetMatrixModelview(modelview); + SetMatrixProjection(layer.eyeProjections[eye]); #else // 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 #endif 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); - - matProj = MatrixOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0); - MatrixTranspose(&matProj); - matView = MatrixIdentity(); - mvp = MatrixMultiply(matView, matProj); + rlglDraw(); +#if !defined(PLATFORM_OCULUS) + // Draw '2D' elements in the scene (GUI) // TODO: 2D drawing on Oculus Rift: requires an ovrLayerQuad layer - DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 300.0f, 20.0f }, DARKGRAY); + 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 + + DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 600.0f, 20.0f }, DARKGRAY); // NOTE: Internal buffers drawing (2D data) - rlglDraw(mvp); - + rlglDraw(); +#endif #if defined(PLATFORM_OCULUS) } @@ -593,14 +600,12 @@ static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height) desc.Width = width; desc.Height = height; desc.MipLevels = 1; - desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; + 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); - //eyeLayer.ColorTexture[0] = buffer.textureChain; // <------------------- ??? - if (!OVR_SUCCESS(result)) TraceLog(LOG_WARNING, "OVR: Failed to create swap textures buffer"); int textureCount = 0; @@ -672,9 +677,11 @@ static void SetOculusBuffer(ovrSession session, OculusBuffer buffer) 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); + //glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye) //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - //glEnable(GL_FRAMEBUFFER_SRGB); + + // Required if OculusBuffer format is OVR_FORMAT_R8G8B8A8_UNORM_SRGB + glEnable(GL_FRAMEBUFFER_SRGB); } // Unset Oculus buffer diff --git a/examples/oculus_glfw_sample/rlgl.c b/examples/oculus_glfw_sample/rlgl.c index dcc84c2f7..329ccd6ea 100644 --- a/examples/oculus_glfw_sample/rlgl.c +++ b/examples/oculus_glfw_sample/rlgl.c @@ -28,40 +28,38 @@ #include "rlgl.h" -#include // Standard input / output lib -#include // Declares malloc() and free() for memory management, rand() -#include // Declares strcmp(), strlen(), strtok() +#include // Required for: fopen(), fclose(), fread()... [Used only on ReadTextFile()] +#include // Required for: malloc(), free(), rand() +#include // Required for: strcmp(), strlen(), strtok() #ifndef RLGL_STANDALONE - #include "raymath.h" // Required for Vector3 and Matrix functions + #include "raymath.h" // Required for Vector3 and Matrix functions #endif #if defined(GRAPHICS_API_OPENGL_11) - #ifdef __APPLE__ // OpenGL include for OSX - #include + #ifdef __APPLE__ + #include // OpenGL 1.1 library for OSX #else - #include // Basic OpenGL include + #include // OpenGL 1.1 library #endif #endif #if defined(GRAPHICS_API_OPENGL_33) - #ifdef __APPLE__ // OpenGL include for OSX - #include + #ifdef __APPLE__ + #include // OpenGL 3 library for OSX #else - //#define GLEW_STATIC - //#include // GLEW header, includes OpenGL headers - #include "glad.h" // glad header, includes OpenGL headers + #include "glad.h" // GLAD library, includes OpenGL headers #endif #endif #if defined(GRAPHICS_API_OPENGL_ES2) - #include - #include - #include + #include // EGL library + #include // OpenGL ES 2.0 library + #include // OpenGL ES 2.0 extensions library #endif #if defined(RLGL_STANDALONE) - #include // Used for functions with variable number of parameters (TraceLog()) + #include // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()] #endif //---------------------------------------------------------------------------------- @@ -171,7 +169,6 @@ static Matrix modelview; static Matrix projection; static Matrix *currentMatrix; static int currentMatrixMode; -static Matrix customMVP; static DrawMode currentDrawMode; @@ -913,8 +910,8 @@ void rlglInit(void) vaoSupported = true; npotSupported = true; - // NOTE: We don't need to check again supported extensions but we do (in case GLEW is replaced sometime) // We get a list of available extensions and we check for some of them (compressed textures) + // NOTE: We don't need to check again supported extensions but we do (GLAD already dealt with that) glGetIntegerv(GL_NUM_EXTENSIONS, &numExt); const char *extList[numExt]; @@ -1083,10 +1080,8 @@ void rlglClose(void) } // Drawing batches: triangles, quads, lines -void rlglDraw(Matrix mvp) +void rlglDraw(void) { - customMVP = mvp; - #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) /* for (int i = 0; i < modelsCount; i++) @@ -1548,10 +1543,10 @@ void rlglLoadMesh(Mesh *mesh, bool dynamic) mesh->vboId[5] = 0; // Vertex texcoords2 VBO mesh->vboId[6] = 0; // Vertex indices VBO +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) int drawHint = GL_STATIC_DRAW; if (dynamic) drawHint = GL_DYNAMIC_DRAW; -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) GLuint vaoId = 0; // Vertex Array Objects (VAO) GLuint vboId[7]; // Vertex Buffer Objects (VBOs) @@ -1677,6 +1672,7 @@ void rlglLoadMesh(Mesh *mesh, bool dynamic) // Update vertex data on GPU (upload new data to one buffer) void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex) { +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Activate mesh VAO if (vaoSupported) glBindVertexArray(mesh.vaoId); @@ -1732,6 +1728,7 @@ void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex) //mesh.vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); // Now we can modify vertices //glUnmapBuffer(GL_ARRAY_BUFFER); +#endif } // Draw a 3d mesh with material and transform @@ -2156,19 +2153,19 @@ void UnloadShader(Shader shader) } } -// Set custom shader to be used on batch draw +// Begin custom shader mode void BeginShaderMode(Shader shader) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) if (currentShader.id != shader.id) { - //rlglDraw(); + rlglDraw(); currentShader = shader; } #endif } -// Set default shader to be used in batch draw +// End custom shader mode (returns to default shader) void EndShaderMode(void) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) @@ -2254,13 +2251,25 @@ void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat) #endif } +// Set a custom projection matrix (replaces internal projection matrix) +void SetMatrixProjection(Matrix proj) +{ + projection = proj; +} + +// Set a custom modelview matrix (replaces internal modelview matrix) +void SetMatrixModelview(Matrix view) +{ + modelview = view; +} + // Begin blending mode (alpha, additive, multiplied) // NOTE: Only 3 blending modes supported, default blend mode is alpha void BeginBlendMode(int mode) { if ((blendMode != mode) && (mode < 3)) { - //rlglDraw(); + rlglDraw(); switch (mode) { @@ -2283,8 +2292,11 @@ void EndBlendMode(void) // Create a new light, initialize it and add to pool Light CreateLight(int type, Vector3 position, Color diffuse) { + Light light = NULL; + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Allocate dynamic memory - Light light = (Light)malloc(sizeof(LightData)); + light = (Light)malloc(sizeof(LightData)); // Initialize light values with generic values light->id = lightsCount; @@ -2301,13 +2313,18 @@ Light CreateLight(int type, Vector3 position, Color diffuse) // Increase enabled lights count lightsCount++; - +#else + // TODO: Support OpenGL 1.1 lighting system + TraceLog(WARNING, "Lighting currently not supported on OpenGL 1.1"); +#endif + return light; } // Destroy a light and take it out of the list void DestroyLight(Light light) { +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Free dynamic memory allocation free(lights[light->id]); @@ -2325,6 +2342,7 @@ void DestroyLight(Light light) // Decrease enabled physic objects count lightsCount--; +#endif } //---------------------------------------------------------------------------------- @@ -2869,9 +2887,9 @@ static void DrawDefaultBuffers(void) glUseProgram(currentShader.id); // Create modelview-projection matrix - //Matrix matMVP = MatrixMultiply(modelview, projection); + Matrix matMVP = MatrixMultiply(modelview, projection); - glUniformMatrix4fv(currentShader.mvpLoc, 1, false, MatrixToFloat(customMVP)); //customMVP + glUniformMatrix4fv(currentShader.mvpLoc, 1, false, MatrixToFloat(matMVP)); glUniform4f(currentShader.tintColorLoc, 1.0f, 1.0f, 1.0f, 1.0f); glUniform1i(currentShader.mapTexture0Loc, 0); @@ -3062,7 +3080,7 @@ static void UnloadDefaultBuffers(void) free(quads.indices); } -// Sets shader uniform values for lights array +// Setup shader uniform values for lights array // NOTE: It would be far easier with shader UBOs but are not supported on OpenGL ES 2.0f static void SetShaderLights(Shader shader) { diff --git a/examples/oculus_glfw_sample/rlgl.h b/examples/oculus_glfw_sample/rlgl.h index e7e600369..2a578a1f5 100644 --- a/examples/oculus_glfw_sample/rlgl.h +++ b/examples/oculus_glfw_sample/rlgl.h @@ -32,15 +32,15 @@ //#define RLGL_STANDALONE // NOTE: To use rlgl as standalone lib, just uncomment this line #ifndef RLGL_STANDALONE - #include "raylib.h" // Required for typedef(s): Model, Shader, Texture2D - #include "utils.h" // Required for function TraceLog() + #include "raylib.h" // Required for: Model, Shader, Texture2D + #include "utils.h" // Required for: TraceLog() #endif #ifdef RLGL_STANDALONE #define RAYMATH_STANDALONE #endif -#include "raymath.h" // Required for types: Vector3, Matrix +#include "raymath.h" // Required for: Vector3, Matrix // Select desired OpenGL version // NOTE: Those preprocessor defines are only used on rlgl module, @@ -291,7 +291,7 @@ int rlGetVersion(void); // Returns current OpenGL versio //------------------------------------------------------------------------------------ void rlglInit(void); // Initialize rlgl (shaders, VAO, VBO...) void rlglClose(void); // De-init rlgl -void rlglDraw(Matrix mvp); // Draw VAO/VBO +void rlglDraw(void); // Draw VAO/VBO void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Initialize Graphics (OpenGL stuff) unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load texture in GPU @@ -329,6 +329,9 @@ void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // S void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int) void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4) +void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix) +void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix) + void BeginShaderMode(Shader shader); // Begin custom shader drawing void EndShaderMode(void); // End custom shader drawing (use default shader) void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)