From 5e7686695fcfe32bbf956990ced0a02b7c881af1 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 11 Jan 2016 13:29:55 +0100 Subject: [PATCH] Review Light/Material system Simplified for the user (more intuitive and clear) Removed lighting module dependency --- examples/lighting_blinn_phong.c | 101 ++++++++++---------------- src/core.c | 19 ++++- src/lighting.c | 124 -------------------------------- src/lighting.h | 87 ---------------------- src/raylib.h | 27 +++---- src/raymath.c | 57 +++++++++------ src/raymath.h | 3 +- src/rlgl.c | 12 ++-- 8 files changed, 110 insertions(+), 320 deletions(-) delete mode 100644 src/lighting.c delete mode 100644 src/lighting.h diff --git a/examples/lighting_blinn_phong.c b/examples/lighting_blinn_phong.c index d4ff548a7..65dbb4f21 100644 --- a/examples/lighting_blinn_phong.c +++ b/examples/lighting_blinn_phong.c @@ -50,29 +50,28 @@ int main() int lightLoc = GetShaderLocation(shader, "lightPos"); // Light and material definitions - Light directionalLight; - Material blinnMaterial; + Light light; + Material matBlinn; // Light initialization - SetLightPosition(&directionalLight, (Vector3){5.0f, 1.0f, 1.0f}); - SetLightRotation(&directionalLight, (Vector3){5.0f, 1.0f, 1.0f}); - SetLightIntensity(&directionalLight, 1); - SetLightAmbientColor(&directionalLight, (Vector3){0.6f, 0.3f, 0}); - SetLightDiffuseColor(&directionalLight, (Vector3){1, 1, 1}); - SetLightSpecularColor(&directionalLight, (Vector3){1, 1, 1}); - SetLightSpecIntensity(&directionalLight, 1); + light.position = (Vector3){ 5.0f, 1.0f, 1.0f }; + light.direction = (Vector3){ 5.0f, 1.0f, 1.0f }; + light.intensity = 1.0f; + light.diffuse = WHITE; + light.ambient = (Color){ 150, 75, 0, 255 }; + light.specular = WHITE; + light.specIntensity = 1.0f; // Material initialization - SetMaterialAmbientColor(&blinnMaterial, (Vector3){0.2f, 0.2f, 0.2f}); - SetMaterialDiffuseColor(&blinnMaterial, (Vector3){1.0f, 1.0f, 1.0f}); - SetMaterialSpecularColor(&blinnMaterial, (Vector3){1.0f, 1.0f, 1.0f}); - SetMaterialGlossiness(&blinnMaterial, 50); + matBlinn.diffuse = WHITE; + matBlinn.ambient = (Color){ 50, 50, 50, 255 }; + matBlinn.specular = WHITE; + matBlinn.glossiness = 50.0f; // Setup camera SetCameraMode(CAMERA_FREE); // Set camera mode SetCameraPosition(camera.position); // Set internal camera position to match our camera position SetCameraTarget(camera.target); // Set internal camera target to match our camera target - float cameraPosition[3] = { camera.position.x, camera.position.y, camera.position.z }; // Camera position vector in float array //-------------------------------------------------------------------------------------- // Main game loop @@ -81,69 +80,44 @@ int main() // Update //---------------------------------------------------------------------------------- - // Update camera position and its float array for shader + // Update camera position UpdateCamera(&camera); - cameraPosition[0] = camera.position.x; - cameraPosition[1] = camera.position.y; - cameraPosition[2] = camera.position.z; // Glossiness input control - if(IsKeyDown(KEY_UP)) - { - blinnMaterial.glossiness[0] += SHININESS_SPEED; - } + if(IsKeyDown(KEY_UP)) matBlinn.glossiness += SHININESS_SPEED; else if(IsKeyDown(KEY_DOWN)) { - blinnMaterial.glossiness[0] -= SHININESS_SPEED; - - if(blinnMaterial.glossiness[0] < 0) blinnMaterial.glossiness[0] = 0; + matBlinn.glossiness -= SHININESS_SPEED; + if( matBlinn.glossiness < 0) matBlinn.glossiness = 0.0f; } // Light X movement - if(IsKeyDown(KEY_D)) - { - directionalLight.position[0] += LIGHT_SPEED; - } - else if(IsKeyDown(KEY_A)) - { - directionalLight.position[0] -= LIGHT_SPEED; - } + if (IsKeyDown(KEY_D)) light.position.x += LIGHT_SPEED; + else if(IsKeyDown(KEY_A)) light.position.x -= LIGHT_SPEED; // Light Y movement - if(IsKeyDown(KEY_LEFT_SHIFT)) - { - directionalLight.position[1] += LIGHT_SPEED; - } - else if(IsKeyDown(KEY_LEFT_CONTROL)) - { - directionalLight.position[1] -= LIGHT_SPEED; - } + if (IsKeyDown(KEY_LEFT_SHIFT)) light.position.y += LIGHT_SPEED; + else if (IsKeyDown(KEY_LEFT_CONTROL)) light.position.y -= LIGHT_SPEED; // Light Z movement - if(IsKeyDown(KEY_S)) - { - directionalLight.position[2] += LIGHT_SPEED; - } - else if(IsKeyDown(KEY_W)) - { - directionalLight.position[2] -= LIGHT_SPEED; - } + if (IsKeyDown(KEY_S)) light.position.z += LIGHT_SPEED; + else if (IsKeyDown(KEY_W)) light.position.z -= LIGHT_SPEED; // Send light values to shader - SetShaderValue(shader, lIntensityLoc, directionalLight.intensity, 1); - SetShaderValue(shader, lAmbientLoc, directionalLight.ambientColor, 3); - SetShaderValue(shader, lDiffuseLoc, directionalLight.diffuseColor, 3); - SetShaderValue(shader, lSpecularLoc, directionalLight.specularColor, 3); - SetShaderValue(shader, lSpecIntensityLoc, directionalLight.specularIntensity, 1); + SetShaderValue(shader, lIntensityLoc, &light.intensity, 1); + SetShaderValue(shader, lAmbientLoc, ColorToFloat(light.ambient), 3); + SetShaderValue(shader, lDiffuseLoc, ColorToFloat(light.diffuse), 3); + SetShaderValue(shader, lSpecularLoc, ColorToFloat(light.specular), 3); + SetShaderValue(shader, lSpecIntensityLoc, &light.specIntensity, 1); // Send material values to shader - SetShaderValue(shader, mAmbientLoc, blinnMaterial.ambientColor, 3); - SetShaderValue(shader, mSpecularLoc, blinnMaterial.specularColor, 3); - SetShaderValue(shader, mGlossLoc, blinnMaterial.glossiness, 1); + SetShaderValue(shader, mAmbientLoc, ColorToFloat(matBlinn.ambient), 3); + SetShaderValue(shader, mSpecularLoc, ColorToFloat(matBlinn.specular), 3); + SetShaderValue(shader, mGlossLoc, &matBlinn.glossiness, 1); // Send camera and light transform values to shader - SetShaderValue(shader, cameraLoc, cameraPosition, 3); - SetShaderValue(shader, lightLoc, directionalLight.position, 3); + SetShaderValue(shader, cameraLoc, VectorToFloat(camera.position), 3); + SetShaderValue(shader, lightLoc, VectorToFloat(light.position), 3); //---------------------------------------------------------------------------------- // Draw @@ -154,14 +128,12 @@ int main() Begin3dMode(camera); - DrawModel(model, position, 4.0f, (Color){255 * blinnMaterial.diffuseColor[0], 255 * blinnMaterial.diffuseColor[1], 255 * blinnMaterial.diffuseColor[2], 255}); - - DrawSphere((Vector3){directionalLight.position[0], directionalLight.position[1], directionalLight.position[2]}, 1, YELLOW); + DrawModel(model, position, 4.0f, matBlinn.diffuse); + DrawSphere(light.position, 1.0f, YELLOW); End3dMode(); - // Draw FPS - DrawFPS(10, 10); + DrawFPS(10, 10); // Draw FPS EndDrawing(); //---------------------------------------------------------------------------------- @@ -169,7 +141,6 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- - // Unload all loaded data UnloadShader(shader); UnloadModel(model); diff --git a/src/core.c b/src/core.c index 708f2d22d..f1445cce7 100644 --- a/src/core.c +++ b/src/core.c @@ -519,7 +519,7 @@ void BeginDrawing(void) rlLoadIdentity(); // Reset current matrix (MODELVIEW) - rlMultMatrixf(GetMatrixVector(downscaleView)); // If downscale required, apply it here + rlMultMatrixf(MatrixToFloat(downscaleView)); // If downscale required, apply it here //rlTranslatef(0.375, 0.375, 0); // HACK to have 2D pixel-perfect drawing on OpenGL 1.1 // NOTE: Not required with OpenGL 3.3+ @@ -533,7 +533,7 @@ void BeginDrawingEx(int blendMode, Shader shader, Matrix transform) SetBlendMode(blendMode); SetPostproShader(shader); - rlMultMatrixf(GetMatrixVector(transform)); + rlMultMatrixf(MatrixToFloat(transform)); } // End canvas drawing and Swap Buffers (Double Buffering) @@ -588,7 +588,7 @@ void Begin3dMode(Camera camera) // Setup Camera view Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up); - rlMultMatrixf(GetMatrixVector(matView)); // Multiply MODELVIEW matrix by view matrix (camera) + rlMultMatrixf(MatrixToFloat(matView)); // Multiply MODELVIEW matrix by view matrix (camera) } // Ends 3D mode and returns to default 2D orthographic mode @@ -630,6 +630,19 @@ float GetFrameTime(void) return (float)roundedFrameTime; // Time in seconds to run a frame } +// Converts Color to float array and normalizes +float *ColorToFloat(Color color) +{ + static float buffer[4]; + + buffer[0] = (float)color.r/255; + buffer[1] = (float)color.g/255; + buffer[2] = (float)color.b/255; + buffer[3] = (float)color.a/255; + + return buffer; +} + // Returns a Color struct from hexadecimal value Color GetColor(int hexValue) { diff --git a/src/lighting.c b/src/lighting.c deleted file mode 100644 index 9014dcd48..000000000 --- a/src/lighting.c +++ /dev/null @@ -1,124 +0,0 @@ -/********************************************************************************************** -* -* raylib lighting engine module - Lighting and materials management functions -* -* Copyright (c) 2015 Victor Fisac and Ramon Santamaria -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ - -//#define LIGHTING_STANDALONE // NOTE: To use the lighting module as standalone lib, just uncomment this line - -#if defined(LIGHTING_STANDALONE) - #include "lighting.h" -#else - #include "raylib.h" -#endif - -#include - -//---------------------------------------------------------------------------------- -// Defines and Macros -//---------------------------------------------------------------------------------- -//... - -//---------------------------------------------------------------------------------- -// Types and Structures Definitions -//---------------------------------------------------------------------------------- -//... - -//---------------------------------------------------------------------------------- -// Module Functions Declarations -//---------------------------------------------------------------------------------- - -// Lights functions -void SetLightPosition(Light *light, Vector3 position) -{ - light->position[0] = position.x; - light->position[1] = position.y; - light->position[2] = position.z; -} - -void SetLightRotation(Light *light, Vector3 rotation) -{ - light->rotation[0] = rotation.x; - light->rotation[1] = rotation.y; - light->rotation[2] = rotation.z; -} - -void SetLightIntensity(Light *light, float intensity) -{ - light->intensity[0] = intensity; -} - -void SetLightAmbientColor(Light *light, Vector3 color) -{ - light->ambientColor[0] = color.x; - light->ambientColor[1] = color.y; - light->ambientColor[2] = color.z; -} - -void SetLightDiffuseColor(Light *light, Vector3 color) -{ - light->diffuseColor[0] = color.x; - light->diffuseColor[1] = color.y; - light->diffuseColor[2] = color.z; -} - -void SetLightSpecularColor(Light *light, Vector3 color) -{ - light->specularColor[0] = color.x; - light->specularColor[1] = color.y; - light->specularColor[2] = color.z; -} - -void SetLightSpecIntensity(Light *light, float specIntensity) -{ - light->specularIntensity[0] = specIntensity; -} - -// Materials functions -void SetMaterialAmbientColor(Material *material, Vector3 color) -{ - material->ambientColor[0] = color.x; - material->ambientColor[1] = color.y; - material->ambientColor[2] = color.z; -} - -void SetMaterialDiffuseColor(Material *material, Vector3 color) -{ - material->diffuseColor[0] = color.x; - material->diffuseColor[1] = color.y; - material->diffuseColor[2] = color.z; -} - -void SetMaterialSpecularColor(Material *material, Vector3 color) -{ - material->specularColor[0] = color.x; - material->specularColor[1] = color.y; - material->specularColor[2] = color.z; -} - -void SetMaterialGlossiness(Material *material, float glossiness) -{ - material->glossiness[0] = glossiness; -} - -void SetMaterialNormalDepth(Material *material, float depth) -{ - material->normalDepth[0] = depth; -} diff --git a/src/lighting.h b/src/lighting.h deleted file mode 100644 index e1fc4e50b..000000000 --- a/src/lighting.h +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************************* -* -* raylib lighting engine module - Lighting and materials management functions -* -* Copyright (c) 2015 Victor Fisac and Ramon Santamaria -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ - -#ifndef LIGHTING_H -#define LIGHTING_H - -//---------------------------------------------------------------------------------- -// Defines and Macros -//---------------------------------------------------------------------------------- -//... - -//---------------------------------------------------------------------------------- -// Types and Structures Definition -// NOTE: Below types are required for LIGHTING_STANDALONE usage -//---------------------------------------------------------------------------------- -// Vector3 type -typedef struct Vector3 { - float x; - float y; - float z; -} Vector3; - -// Light type -typedef struct Light { - float position[3]; - float rotation[3]; - float intensity[1]; - float ambientColor[3]; - float diffuseColor[3]; - float specularColor[3]; - float specularIntensity[1]; -} Light; - -// Material type -typedef struct Material { - float ambientColor[3]; - float diffuseColor[3]; - float specularColor[3]; - float glossiness[1]; - float normalDepth[1]; -} Material; - -//---------------------------------------------------------------------------------- -// Module Functions Definitions -// NOTE: light and material structs uses float pointers instead of vectors to be compatible with SetShaderValue() -//---------------------------------------------------------------------------------- -// Lights functions -void SetLightPosition(Light *light, Vector3 position); // Set light position converting position vector to float pointer -void SetLightRotation(Light *light, Vector3 rotation); // Set light rotation converting rotation vector to float pointer -void SetLightIntensity(Light *light, float intensity); // Set light intensity value -void SetLightAmbientColor(Light *light, Vector3 color); // Set light ambient color value (it will be multiplied by material ambient color) -void SetLightDiffuseColor(Light *light, Vector3 color); // Set light diffuse color (light color) -void SetLightSpecularColor(Light *light, Vector3 color); // Set light specular color (it will be multiplied by material specular color) -void SetLightSpecIntensity(Light *light, float specIntensity); // Set light specular intensity (specular color scalar multiplier) - -// Materials functions -void SetMaterialAmbientColor(Material *material, Vector3 color); // Set material ambient color value (it will be multiplied by light ambient color) -void SetMaterialDiffuseColor(Material *material, Vector3 color); // Set material diffuse color (material color, should use DrawModel() tint parameter) -void SetMaterialSpecularColor(Material *material, Vector3 color); // Set material specular color (it will be multiplied by light specular color) -void SetMaterialGlossiness(Material *material, float glossiness); // Set material glossiness value (recommended values: 0 - 100) -void SetMaterialNormalDepth(Material *material, float depth); // Set normal map depth (B component from RGB type map scalar multiplier) - -#ifdef __cplusplus -} -#endif - -#endif // LIGHTING_H diff --git a/src/raylib.h b/src/raylib.h index b6900a979..4d8d104d5 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -378,22 +378,22 @@ typedef struct Wave { // Light type typedef struct Light { - float position[3]; - float rotation[3]; - float intensity[1]; - float ambientColor[3]; - float diffuseColor[3]; - float specularColor[3]; - float specularIntensity[1]; + Vector3 position; + Vector3 direction; + float intensity; + float specIntensity; + Color diffuse; + Color ambient; + Color specular; } Light; // Material type typedef struct Material { - float ambientColor[3]; - float diffuseColor[3]; - float specularColor[3]; - float glossiness[1]; - float normalDepth[1]; + Color diffuse; + Color ambient; + Color specular; + float glossiness; + float normalDepth; } Material; // Texture formats @@ -535,6 +535,9 @@ float GetFrameTime(void); // Returns time in s Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value int GetHexValue(Color color); // Returns hexadecimal value for a Color +float *ColorToFloat(Color color); // Converts Color to float array and normalizes +float *VectorToFloat(Vector3 vec); // Converts Vector3 to float array (defined in raymath module) +float *MatrixToVector(Matrix mat); // Converts Matrix to float array (defined in raymath module) int GetRandomValue(int min, int max); // Returns a random value between min and max (both included) Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f diff --git a/src/raymath.c b/src/raymath.c index eb773e5f6..5feef59db 100644 --- a/src/raymath.c +++ b/src/raymath.c @@ -43,6 +43,18 @@ // Module Functions Definition - Vector3 math //---------------------------------------------------------------------------------- +// Converts Vector3 to float array +float *VectorToFloat(Vector3 vec) +{ + static float buffer[3]; + + buffer[0] = vec.x; + buffer[1] = vec.y; + buffer[2] = vec.z; + + return buffer; +} + // Add two vectors Vector3 VectorAdd(Vector3 v1, Vector3 v2) { @@ -225,31 +237,32 @@ Vector3 VectorZero(void) // Module Functions Definition - Matrix math //---------------------------------------------------------------------------------- -// Returns an OpenGL-ready vector (glMultMatrixf) -// NOTE: Returned vector is row-major instead column-major as expected, -// it means, returned vector is a transposed version of the matrix! -float *GetMatrixVector(Matrix mat) +// Converts Matrix to float array +// NOTE: Returned vector is a transposed version of the Matrix struct, +// it should be this way because, despite raymath use OpenGL column-major convention, +// Matrix struct memory alignment and variables naming are not coherent +float *MatrixToFloat(Matrix mat) { - static float vector[16]; + static float buffer[16]; - vector[0] = mat.m0; - vector[1] = mat.m4; - vector[2] = mat.m8; - vector[3] = mat.m12; - vector[4] = mat.m1; - vector[5] = mat.m5; - vector[6] = mat.m9; - vector[7] = mat.m13; - vector[8] = mat.m2; - vector[9] = mat.m6; - vector[10] = mat.m10; - vector[11] = mat.m14; - vector[12] = mat.m3; - vector[13] = mat.m7; - vector[14] = mat.m11; - vector[15] = mat.m15; + buffer[0] = mat.m0; + buffer[1] = mat.m4; + buffer[2] = mat.m8; + buffer[3] = mat.m12; + buffer[4] = mat.m1; + buffer[5] = mat.m5; + buffer[6] = mat.m9; + buffer[7] = mat.m13; + buffer[8] = mat.m2; + buffer[9] = mat.m6; + buffer[10] = mat.m10; + buffer[11] = mat.m14; + buffer[12] = mat.m3; + buffer[13] = mat.m7; + buffer[14] = mat.m11; + buffer[15] = mat.m15; - return vector; + return buffer; } // Compute matrix determinant diff --git a/src/raymath.h b/src/raymath.h index e140b74ca..507bf52fa 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -79,6 +79,7 @@ extern "C" { // Prevents name mangling of functions //------------------------------------------------------------------------------------ // Functions Declaration to work with Vector3 //------------------------------------------------------------------------------------ +float *VectorToFloat(Vector3 vec); // Converts Vector3 to float array Vector3 VectorAdd(Vector3 v1, Vector3 v2); // Add two vectors Vector3 VectorSubtract(Vector3 v1, Vector3 v2); // Substract two vectors Vector3 VectorCrossProduct(Vector3 v1, Vector3 v2); // Calculate two vectors cross product @@ -97,7 +98,7 @@ Vector3 VectorZero(void); // Return a Vector3 init //------------------------------------------------------------------------------------ // Functions Declaration to work with Matrix //------------------------------------------------------------------------------------ -float *GetMatrixVector(Matrix mat); // Returns an OpenGL-ready vector (glMultMatrixf) +float *MatrixToFloat(Matrix mat); // Converts Matrix to float array float MatrixDeterminant(Matrix mat); // Compute matrix determinant float MatrixTrace(Matrix mat); // Returns the trace of the matrix (sum of the values along the diagonal) void MatrixTranspose(Matrix *mat); // Transposes provided matrix diff --git a/src/rlgl.c b/src/rlgl.c index e8b1ec470..2f525f471 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -1296,8 +1296,8 @@ void rlglDraw(void) { glUseProgram(currentShader.id); - glUniformMatrix4fv(currentShader.projectionLoc, 1, false, GetMatrixVector(projection)); - glUniformMatrix4fv(currentShader.modelviewLoc, 1, false, GetMatrixVector(modelview)); + glUniformMatrix4fv(currentShader.projectionLoc, 1, false, MatrixToFloat(projection)); + glUniformMatrix4fv(currentShader.modelviewLoc, 1, false, MatrixToFloat(modelview)); glUniform1i(currentShader.mapDiffuseLoc, 0); } @@ -1524,10 +1524,10 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r // NOTE: Drawing in OpenGL 3.3+, matrices are passed to shader // TODO: Reduce number of matrices passed to shaders, use only matMVP - glUniformMatrix4fv(model.shader.modelLoc, 1, false, GetMatrixVector(matModel)); - glUniformMatrix4fv(model.shader.viewLoc, 1, false, GetMatrixVector(matView)); - glUniformMatrix4fv(model.shader.projectionLoc, 1, false, GetMatrixVector(matProjection)); - glUniformMatrix4fv(model.shader.modelviewLoc, 1, false, GetMatrixVector(matModelView)); + glUniformMatrix4fv(model.shader.modelLoc, 1, false, MatrixToFloat(matModel)); + glUniformMatrix4fv(model.shader.viewLoc, 1, false, MatrixToFloat(matView)); + glUniformMatrix4fv(model.shader.projectionLoc, 1, false, MatrixToFloat(matProjection)); + glUniformMatrix4fv(model.shader.modelviewLoc, 1, false, MatrixToFloat(matModelView)); // Apply color tinting to model // NOTE: Just update one uniform on fragment shader