New matrix location points, lighting and physics engine modules with examplespull/69/head
| @ -0,0 +1,190 @@ | |||
| /******************************************************************************************* | |||
| * | |||
| * raylib [lighting] example - Basic Phong lighting | |||
| * | |||
| * Welcome to raylib! | |||
| * | |||
| * To test examples, just press F6 and execute raylib_compile_execute script | |||
| * Note that compiled executable is placed in the same folder as .c file | |||
| * | |||
| * You can find all basic examples on C:\raylib\raylib\examples folder or | |||
| * raylib official webpage: www.raylib.com | |||
| * | |||
| * Enjoy using raylib. :) | |||
| * | |||
| * This example has been created using raylib 1.3 (www.raylib.com) | |||
| * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) | |||
| * | |||
| * Copyright (c) 2015 Ramon Santamaria (@raysan5) | |||
| * | |||
| ********************************************************************************************/ | |||
| #include "raylib.h" | |||
| #define SHININESS_SPEED 1.0f | |||
| #define LIGHT_SPEED 0.25f | |||
| int main() | |||
| { | |||
| // Initialization | |||
| //-------------------------------------------------------------------------------------- | |||
| const int screenWidth = 800; | |||
| const int screenHeight = 450; | |||
| SetConfigFlags(FLAG_MSAA_4X_HINT); | |||
| InitWindow(screenWidth, screenHeight, "raylib [lighting] example - blinn phong lighting"); | |||
| SetTargetFPS(60); | |||
| // Camera initialization | |||
| Camera camera = {{ 10.0, 8.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }}; | |||
| // Model initialization | |||
| Vector3 position = { 0.0, 0.0, 0.0 }; | |||
| Model model = LoadModel("resources/model/dwarf.obj"); | |||
| // Shader shader = LoadShader("resources/shaders/phong.vs", "resources/shaders/phong.fs"); | |||
| SetModelShader(&model, shader); | |||
| // Shader locations initialization | |||
| int lIntensityLoc = GetShaderLocation(shader, "light_intensity"); | |||
| int lAmbientLoc = GetShaderLocation(shader, "light_ambientColor"); | |||
| int lDiffuseLoc = GetShaderLocation(shader, "light_diffuseColor"); | |||
| int lSpecularLoc = GetShaderLocation(shader, "light_specularColor"); | |||
| int lSpecIntensityLoc = GetShaderLocation(shader, "light_specIntensity"); | |||
| int mAmbientLoc = GetShaderLocation(shader, "mat_ambientColor"); | |||
| int mSpecularLoc = GetShaderLocation(shader, "mat_specularColor"); | |||
| int mGlossLoc = GetShaderLocation(shader, "mat_glossiness"); | |||
| // Camera and light vectors shader locations | |||
| int cameraLoc = GetShaderLocation(shader, "cameraPos"); | |||
| int lightLoc = GetShaderLocation(shader, "lightPos"); | |||
| // Light and material definitions | |||
| Light directionalLight; | |||
| Material blinnMaterial; | |||
| // 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); | |||
| // 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); | |||
| // 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 | |||
| while (!WindowShouldClose()) // Detect window close button or ESC key | |||
| { | |||
| // Update | |||
| //---------------------------------------------------------------------------------- | |||
| // Update camera position and its float array for shader | |||
| 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; | |||
| } | |||
| else if(IsKeyDown(KEY_DOWN)) | |||
| { | |||
| blinnMaterial.glossiness[0] -= SHININESS_SPEED; | |||
| if(blinnMaterial.glossiness[0] < 0) blinnMaterial.glossiness[0] = 0; | |||
| } | |||
| // Light X movement | |||
| if(IsKeyDown(KEY_D)) | |||
| { | |||
| directionalLight.position[0] += LIGHT_SPEED; | |||
| } | |||
| else if(IsKeyDown(KEY_A)) | |||
| { | |||
| directionalLight.position[0] -= 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; | |||
| } | |||
| // Light Z movement | |||
| if(IsKeyDown(KEY_S)) | |||
| { | |||
| directionalLight.position[2] += LIGHT_SPEED; | |||
| } | |||
| else if(IsKeyDown(KEY_W)) | |||
| { | |||
| directionalLight.position[2] -= 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); | |||
| // Send material values to shader | |||
| SetShaderValue(shader, mAmbientLoc, blinnMaterial.ambientColor, 3); | |||
| SetShaderValue(shader, mSpecularLoc, blinnMaterial.specularColor, 3); | |||
| SetShaderValue(shader, mGlossLoc, blinnMaterial.glossiness, 1); | |||
| // Send camera and light transform values to shader | |||
| SetShaderValue(shader, cameraLoc, cameraPosition, 3); | |||
| SetShaderValue(shader, lightLoc, directionalLight.position, 3); | |||
| //---------------------------------------------------------------------------------- | |||
| // Draw | |||
| //---------------------------------------------------------------------------------- | |||
| BeginDrawing(); | |||
| ClearBackground(RAYWHITE); | |||
| Begin3dMode(camera); | |||
| DrawModel(model, position, 0.1f, (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); | |||
| End3dMode(); | |||
| // Draw FPS | |||
| DrawFPS(10, 10); | |||
| EndDrawing(); | |||
| //---------------------------------------------------------------------------------- | |||
| } | |||
| // De-Initialization | |||
| //-------------------------------------------------------------------------------------- | |||
| // Unload all loaded data | |||
| UnloadShader(shader); | |||
| UnloadModel(model); | |||
| CloseWindow(); // Close window and OpenGL context | |||
| //-------------------------------------------------------------------------------------- | |||
| return 0; | |||
| } | |||
| @ -0,0 +1,144 @@ | |||
| /******************************************************************************************* | |||
| * | |||
| * raylib [physics] example - Basic rigidbody | |||
| * | |||
| * Welcome to raylib! | |||
| * | |||
| * To test examples, just press F6 and execute raylib_compile_execute script | |||
| * Note that compiled executable is placed in the same folder as .c file | |||
| * | |||
| * You can find all basic examples on C:\raylib\raylib\examples folder or | |||
| * raylib official webpage: www.raylib.com | |||
| * | |||
| * Enjoy using raylib. :) | |||
| * | |||
| * This example has been created using raylib 1.3 (www.raylib.com) | |||
| * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) | |||
| * | |||
| * Copyright (c) 2015 Ramon Santamaria (@raysan5) | |||
| * | |||
| ********************************************************************************************/ | |||
| #include "raylib.h" | |||
| #define OBJECT_SIZE 50 | |||
| #define PLAYER_INDEX 0 | |||
| int main() | |||
| { | |||
| // Initialization | |||
| //-------------------------------------------------------------------------------------- | |||
| int screenWidth = 800; | |||
| int screenHeight = 450; | |||
| InitWindow(screenWidth, screenHeight, "raylib [physics] example - basic rigidbody"); | |||
| SetTargetFPS(60); // Enable v-sync | |||
| InitPhysics(); // Initialize internal physics values (max rigidbodies/colliders available: 1024) | |||
| // Physics initialization | |||
| Physics worldPhysics = {true, false, (Vector2){0, -9.81f}}; | |||
| // Set internal physics settings | |||
| SetPhysics(worldPhysics); | |||
| // Object initialization | |||
| Transform player = (Transform){(Vector2){(screenWidth - OBJECT_SIZE) / 2, (screenHeight - OBJECT_SIZE) / 2}, 0.0f, (Vector2){OBJECT_SIZE, OBJECT_SIZE}}; | |||
| AddCollider(PLAYER_INDEX, (Collider){true, RectangleCollider, (Rectangle){player.position.x, player.position.y, player.scale.x, player.scale.y}, 0}); | |||
| AddRigidbody(PLAYER_INDEX, (Rigidbody){true, 1.0f, (Vector2){0, 0}, (Vector2){0, 0}, false, false, true, 0.5f, 1.0f}); | |||
| // Floor initialization | |||
| // NOTE: floor doesn't need a rigidbody because it's a static physic object, just a collider to collide with other dynamic colliders (with rigidbody) | |||
| Transform floor = (Transform){(Vector2){0, screenHeight * 0.8f}, 0.0f, (Vector2){screenWidth, screenHeight * 0.2f}}; | |||
| AddCollider(PLAYER_INDEX + 1, (Collider){true, RectangleCollider, (Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, 0}); | |||
| // Object properties initialization | |||
| float moveSpeed = 6.0f; | |||
| float jumpForce = 4.5f; | |||
| //-------------------------------------------------------------------------------------- | |||
| // Main game loop | |||
| while (!WindowShouldClose()) // Detect window close button or ESC key | |||
| { | |||
| // Update | |||
| //---------------------------------------------------------------------------------- | |||
| // Update object physics | |||
| // NOTE: all physics detections and reactions are calculated in ApplyPhysics() function (You will live happier :D) | |||
| ApplyPhysics(PLAYER_INDEX, &player.position); | |||
| // Check jump button input | |||
| if(IsKeyDown(KEY_SPACE) && GetRigidbody(PLAYER_INDEX).isGrounded) | |||
| { | |||
| // Reset object Y velocity to avoid double jumping cases but keep the same X velocity that it already has | |||
| SetRigidbodyVelocity(PLAYER_INDEX, (Vector2){GetRigidbody(PLAYER_INDEX).velocity.x, 0}); | |||
| // Add jumping force in Y axis | |||
| AddRigidbodyForce(PLAYER_INDEX, (Vector2){0, jumpForce}); | |||
| } | |||
| // Check movement buttons input | |||
| if(IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) | |||
| { | |||
| // Set rigidbody velocity in X based on moveSpeed value and apply the same Y velocity that it already has | |||
| SetRigidbodyVelocity(PLAYER_INDEX, (Vector2){moveSpeed, GetRigidbody(PLAYER_INDEX).velocity.y}); | |||
| } | |||
| else if(IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) | |||
| { | |||
| // Set rigidbody velocity in X based on moveSpeed negative value and apply the same Y velocity that it already has | |||
| SetRigidbodyVelocity(PLAYER_INDEX, (Vector2){-moveSpeed, GetRigidbody(PLAYER_INDEX).velocity.y}); | |||
| } | |||
| // Check debug mode toggle button input | |||
| if(IsKeyPressed(KEY_P)) | |||
| { | |||
| // Update program physics value | |||
| worldPhysics.debug = !worldPhysics.debug; | |||
| // Update internal physics value | |||
| SetPhysics(worldPhysics); | |||
| } | |||
| //---------------------------------------------------------------------------------- | |||
| // Draw | |||
| //---------------------------------------------------------------------------------- | |||
| BeginDrawing(); | |||
| ClearBackground(RAYWHITE); | |||
| // Draw information | |||
| DrawText("Use LEFT / RIGHT to MOVE and SPACE to JUMP", (screenWidth - MeasureText("Use LEFT / RIGHT to MOVE and SPACE to JUMP", 20)) / 2, screenHeight * 0.20f, 20, LIGHTGRAY); | |||
| DrawText("Use P to switch DEBUG MODE", (screenWidth - MeasureText("Use P to switch DEBUG MODE", 20)) / 2, screenHeight * 0.3f, 20, LIGHTGRAY); | |||
| // Check if debug mode is enabled | |||
| if(worldPhysics.debug) | |||
| { | |||
| // Draw every internal physics stored collider if it is active | |||
| for(int i = 0; i < 2; i++) | |||
| { | |||
| if(GetCollider(i).enabled) | |||
| { | |||
| DrawRectangleLines(GetCollider(i).bounds.x, GetCollider(i).bounds.y, GetCollider(i).bounds.width, GetCollider(i).bounds.height, GREEN); | |||
| } | |||
| } | |||
| } | |||
| else | |||
| { | |||
| // Draw player | |||
| DrawRectangleRec((Rectangle){player.position.x, player.position.y, player.scale.x, player.scale.y}, GRAY); | |||
| // Draw floor | |||
| DrawRectangleRec((Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, BLACK); | |||
| } | |||
| EndDrawing(); | |||
| //---------------------------------------------------------------------------------- | |||
| } | |||
| // De-Initialization | |||
| //-------------------------------------------------------------------------------------- | |||
| CloseWindow(); // Close window and OpenGL context | |||
| //-------------------------------------------------------------------------------------- | |||
| return 0; | |||
| } | |||
| @ -0,0 +1,76 @@ | |||
| #version 330 | |||
| // Vertex shader input data | |||
| in vec2 fragTexCoord; | |||
| in vec3 fragNormal; | |||
| // Diffuse data | |||
| uniform sampler2D texture0; | |||
| uniform vec4 tintColor; | |||
| // Light attributes | |||
| uniform vec3 light_ambientColor = vec3(0.6, 0.3, 0); | |||
| uniform vec3 light_diffuseColor = vec3(1, 0.5, 0); | |||
| uniform vec3 light_specularColor = vec3(0, 1, 0); | |||
| uniform float light_intensity = 1; | |||
| uniform float light_specIntensity = 1; | |||
| // Material attributes | |||
| uniform vec3 mat_ambientColor = vec3(1, 1, 1); | |||
| uniform vec3 mat_specularColor = vec3(1, 1, 1); | |||
| uniform float mat_glossiness = 50; | |||
| // World attributes | |||
| uniform vec3 lightPos; | |||
| uniform vec3 cameraPos; | |||
| // Fragment shader output data | |||
| out vec4 fragColor; | |||
| vec3 AmbientLighting() | |||
| { | |||
| return mat_ambientColor * light_ambientColor; | |||
| } | |||
| vec3 DiffuseLighting(in vec3 N, in vec3 L) | |||
| { | |||
| // Lambertian reflection calculation | |||
| float diffuse = clamp(dot(N, L), 0, 1); | |||
| return tintColor.xyz * light_diffuseColor * light_intensity * diffuse; | |||
| } | |||
| vec3 SpecularLighting(in vec3 N, in vec3 L, in vec3 V) | |||
| { | |||
| float specular = 0; | |||
| // Calculate specular reflection only if the surface is oriented to the light source | |||
| if(dot(N, L) > 0) | |||
| { | |||
| // Calculate half vector | |||
| vec3 H = normalize(L + V); | |||
| // Calculate specular intensity | |||
| specular = pow(dot(N, H), 3 + mat_glossiness); | |||
| } | |||
| return mat_specularColor * light_specularColor * light_specIntensity * specular; | |||
| } | |||
| void main() | |||
| { | |||
| // Normalize input vectors | |||
| vec3 L = normalize(lightPos); | |||
| vec3 V = normalize(cameraPos); | |||
| vec3 N = normalize(fragNormal); | |||
| vec3 ambient = AmbientLighting(); | |||
| vec3 diffuse = DiffuseLighting(N, L); | |||
| vec3 specular = SpecularLighting(N, L, V); | |||
| // Get base color from texture | |||
| vec4 textureColor = texture(texture0, fragTexCoord); | |||
| vec3 finalColor = textureColor.rgb; | |||
| fragColor = vec4(finalColor * (ambient + diffuse + specular), textureColor.a); | |||
| } | |||
| @ -0,0 +1,28 @@ | |||
| #version 330 | |||
| // Vertex input data | |||
| in vec3 vertexPosition; | |||
| in vec2 vertexTexCoord; | |||
| in vec3 vertexNormal; | |||
| // Projection and model data | |||
| uniform mat4 projectionMatrix; | |||
| uniform mat4 modelviewMatrix; | |||
| uniform mat4 modelMatrix; | |||
| // Attributes to fragment shader | |||
| out vec2 fragTexCoord; | |||
| out vec3 fragNormal; | |||
| void main() | |||
| { | |||
| // Send texture coord to fragment shader | |||
| fragTexCoord = vertexTexCoord; | |||
| // Calculate view vector normal from model | |||
| mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); | |||
| fragNormal = normalize(normalMatrix * vertexNormal); | |||
| // Calculate final vertex position | |||
| gl_Position = projectionMatrix * modelviewMatrix * vec4(vertexPosition, 1.0); | |||
| } | |||
| @ -0,0 +1,76 @@ | |||
| #version 330 | |||
| // Vertex shader input data | |||
| in vec2 fragTexCoord; | |||
| in vec3 fragNormal; | |||
| // Diffuse data | |||
| uniform sampler2D texture0; | |||
| uniform vec4 tintColor; | |||
| // Light attributes | |||
| uniform vec3 light_ambientColor = vec3(0.6, 0.3, 0); | |||
| uniform vec3 light_diffuseColor = vec3(1, 0.5, 0); | |||
| uniform vec3 light_specularColor = vec3(0, 1, 0); | |||
| uniform float light_intensity = 1; | |||
| uniform float light_specIntensity = 1; | |||
| // Material attributes | |||
| uniform vec3 mat_ambientColor = vec3(1, 1, 1); | |||
| uniform vec3 mat_specularColor = vec3(1, 1, 1); | |||
| uniform float mat_glossiness = 50; | |||
| // World attributes | |||
| uniform vec3 lightPos; | |||
| uniform vec3 cameraPos; | |||
| // Fragment shader output data | |||
| out vec4 fragColor; | |||
| vec3 AmbientLighting() | |||
| { | |||
| return mat_ambientColor * light_ambientColor; | |||
| } | |||
| vec3 DiffuseLighting(in vec3 N, in vec3 L) | |||
| { | |||
| // Lambertian reflection calculation | |||
| float diffuse = clamp(dot(N, L), 0, 1); | |||
| return tintColor.xyz * light_diffuseColor * light_intensity * diffuse; | |||
| } | |||
| vec3 SpecularLighting(in vec3 N, in vec3 L, in vec3 V) | |||
| { | |||
| float specular = 0; | |||
| // Calculate specular reflection only if the surface is oriented to the light source | |||
| if(dot(N, L) > 0) | |||
| { | |||
| // Calculate half vector | |||
| vec3 H = normalize(L + V); | |||
| // Calculate specular intensity | |||
| specular = pow(dot(N, H), 3 + mat_glossiness); | |||
| } | |||
| return mat_specularColor * light_specularColor * light_specIntensity * specular; | |||
| } | |||
| void main() | |||
| { | |||
| // Normalize input vectors | |||
| vec3 L = normalize(lightPos); | |||
| vec3 V = normalize(cameraPos); | |||
| vec3 N = normalize(fragNormal); | |||
| vec3 ambient = AmbientLighting(); | |||
| vec3 diffuse = DiffuseLighting(N, L); | |||
| vec3 specular = SpecularLighting(N, L, V); | |||
| // Get base color from texture | |||
| vec4 textureColor = texture(texture0, fragTexCoord); | |||
| vec3 finalColor = textureColor.rgb; | |||
| fragColor = vec4(finalColor * (ambient + diffuse + specular), textureColor.a); | |||
| } | |||
| @ -0,0 +1,28 @@ | |||
| #version 330 | |||
| // Vertex input data | |||
| in vec3 vertexPosition; | |||
| in vec2 vertexTexCoord; | |||
| in vec3 vertexNormal; | |||
| // Projection and model data | |||
| uniform mat4 projectionMatrix; | |||
| uniform mat4 modelviewMatrix; | |||
| uniform mat4 modelMatrix; | |||
| // Attributes to fragment shader | |||
| out vec2 fragTexCoord; | |||
| out vec3 fragNormal; | |||
| void main() | |||
| { | |||
| // Send texture coord to fragment shader | |||
| fragTexCoord = vertexTexCoord; | |||
| // Calculate view vector normal from model | |||
| mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); | |||
| fragNormal = normalize(normalMatrix * vertexNormal); | |||
| // Calculate final vertex position | |||
| gl_Position = projectionMatrix * modelviewMatrix * vec4(vertexPosition, 1.0); | |||
| } | |||
| @ -0,0 +1,124 @@ | |||
| /********************************************************************************************** | |||
| * | |||
| * 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 <string.h> | |||
| //---------------------------------------------------------------------------------- | |||
| // 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; | |||
| } | |||
| @ -0,0 +1,87 @@ | |||
| /******************************************************************************************* | |||
| * | |||
| * 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 | |||
| @ -0,0 +1,272 @@ | |||
| /********************************************************************************************** | |||
| * | |||
| * raylib physics engine module - Basic functions to apply physics to 2D objects | |||
| * | |||
| * 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 PHYSICS_STANDALONE // NOTE: To use the physics module as standalone lib, just uncomment this line | |||
| #if defined(PHYSICS_STANDALONE) | |||
| #include "physics.h" | |||
| #else | |||
| #include "raylib.h" | |||
| #endif | |||
| #include <math.h> | |||
| #include <stdio.h> | |||
| //---------------------------------------------------------------------------------- | |||
| // Defines and Macros | |||
| //---------------------------------------------------------------------------------- | |||
| #define MAX_ELEMENTS 1024 // Stored rigidbodies and colliders array length | |||
| #define DECIMAL_FIX 0.01f // Decimal margin for collision checks (avoid rigidbodies shake) | |||
| //---------------------------------------------------------------------------------- | |||
| // Types and Structures Definition | |||
| //---------------------------------------------------------------------------------- | |||
| // ... | |||
| //---------------------------------------------------------------------------------- | |||
| // Global Variables Definition | |||
| //---------------------------------------------------------------------------------- | |||
| static Physics physics; | |||
| static Collider colliders[MAX_ELEMENTS]; | |||
| static Rigidbody rigidbodies[MAX_ELEMENTS]; | |||
| static bool collisionChecker = false; | |||
| //---------------------------------------------------------------------------------- | |||
| // Module Functions Definition | |||
| //---------------------------------------------------------------------------------- | |||
| void InitPhysics() | |||
| { | |||
| for (int i = 0; i < MAX_ELEMENTS; i++) | |||
| { | |||
| rigidbodies[i].enabled = false; | |||
| rigidbodies[i].mass = 0.0f; | |||
| rigidbodies[i].velocity = (Vector2){0, 0}; | |||
| rigidbodies[i].acceleration = (Vector2){0, 0}; | |||
| rigidbodies[i].isGrounded = false; | |||
| rigidbodies[i].isContact = false; | |||
| rigidbodies[i].friction = 0.0f; | |||
| colliders[i].enabled = false; | |||
| colliders[i].bounds = (Rectangle){0, 0, 0, 0}; | |||
| colliders[i].radius = 0; | |||
| } | |||
| } | |||
| void SetPhysics(Physics settings) | |||
| { | |||
| physics = settings; | |||
| // To get good results, gravity needs to be 1:10 from original parameter | |||
| physics.gravity = (Vector2){physics.gravity.x / 10, physics.gravity.y / 10}; | |||
| } | |||
| void AddCollider(int index, Collider collider) | |||
| { | |||
| colliders[index] = collider; | |||
| } | |||
| void AddRigidbody(int index, Rigidbody rigidbody) | |||
| { | |||
| rigidbodies[index] = rigidbody; | |||
| } | |||
| void ApplyPhysics(int index, Vector2 *position) | |||
| { | |||
| if (rigidbodies[index].enabled) | |||
| { | |||
| // Apply gravity | |||
| rigidbodies[index].velocity.y += rigidbodies[index].acceleration.y; | |||
| rigidbodies[index].velocity.x += rigidbodies[index].acceleration.x; | |||
| rigidbodies[index].velocity.y += physics.gravity.y; | |||
| rigidbodies[index].velocity.x += physics.gravity.x; | |||
| // Apply friction to velocity | |||
| if (rigidbodies[index].isGrounded) | |||
| { | |||
| if (rigidbodies[index].velocity.x > DECIMAL_FIX) | |||
| { | |||
| rigidbodies[index].velocity.x -= rigidbodies[index].friction; | |||
| } | |||
| else if (rigidbodies[index].velocity.x < -DECIMAL_FIX) | |||
| { | |||
| rigidbodies[index].velocity.x += rigidbodies[index].friction; | |||
| } | |||
| else | |||
| { | |||
| rigidbodies[index].velocity.x = 0; | |||
| } | |||
| } | |||
| if (rigidbodies[index].velocity.y > DECIMAL_FIX) | |||
| { | |||
| rigidbodies[index].velocity.y -= rigidbodies[index].friction; | |||
| } | |||
| else if (rigidbodies[index].velocity.y < -DECIMAL_FIX) | |||
| { | |||
| rigidbodies[index].velocity.y += rigidbodies[index].friction; | |||
| } | |||
| else | |||
| { | |||
| rigidbodies[index].velocity.y = 0; | |||
| } | |||
| // Apply friction to acceleration | |||
| if (rigidbodies[index].isGrounded) | |||
| { | |||
| if (rigidbodies[index].acceleration.x > DECIMAL_FIX) | |||
| { | |||
| rigidbodies[index].acceleration.x -= rigidbodies[index].friction; | |||
| } | |||
| else if (rigidbodies[index].acceleration.x < -DECIMAL_FIX) | |||
| { | |||
| rigidbodies[index].acceleration.x += rigidbodies[index].friction; | |||
| } | |||
| else | |||
| { | |||
| rigidbodies[index].acceleration.x = 0; | |||
| } | |||
| } | |||
| if (rigidbodies[index].acceleration.y > DECIMAL_FIX) | |||
| { | |||
| rigidbodies[index].acceleration.y -= rigidbodies[index].friction; | |||
| } | |||
| else if (rigidbodies[index].acceleration.y < -DECIMAL_FIX) | |||
| { | |||
| rigidbodies[index].acceleration.y += rigidbodies[index].friction; | |||
| } | |||
| else | |||
| { | |||
| rigidbodies[index].acceleration.y = 0; | |||
| } | |||
| // Update position vector | |||
| position->x += rigidbodies[index].velocity.x; | |||
| position->y -= rigidbodies[index].velocity.y; | |||
| // Update collider bounds | |||
| colliders[index].bounds.x = position->x; | |||
| colliders[index].bounds.y = position->y; | |||
| // Check collision with other colliders | |||
| collisionChecker = false; | |||
| rigidbodies[index].isContact = false; | |||
| for (int j = 0; j < MAX_ELEMENTS; j++) | |||
| { | |||
| if (index != j) | |||
| { | |||
| if (colliders[index].enabled && colliders[j].enabled) | |||
| { | |||
| if (colliders[index].type == RectangleCollider) | |||
| { | |||
| if (colliders[j].type == RectangleCollider) | |||
| { | |||
| if (CheckCollisionRecs(colliders[index].bounds, colliders[j].bounds)) | |||
| { | |||
| collisionChecker = true; | |||
| if ((colliders[index].bounds.y + colliders[index].bounds.height <= colliders[j].bounds.y) == false) | |||
| { | |||
| rigidbodies[index].isContact = true; | |||
| } | |||
| } | |||
| } | |||
| else | |||
| { | |||
| if (CheckCollisionCircleRec((Vector2){colliders[j].bounds.x, colliders[j].bounds.y}, colliders[j].radius, colliders[index].bounds)) | |||
| { | |||
| collisionChecker = true; | |||
| } | |||
| } | |||
| } | |||
| else | |||
| { | |||
| if (colliders[j].type == RectangleCollider) | |||
| { | |||
| if (CheckCollisionCircleRec((Vector2){colliders[index].bounds.x, colliders[index].bounds.y}, colliders[index].radius, colliders[j].bounds)) | |||
| { | |||
| collisionChecker = true; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| if (CheckCollisionCircles((Vector2){colliders[j].bounds.x, colliders[j].bounds.y}, colliders[j].radius, (Vector2){colliders[index].bounds.x, colliders[index].bounds.y}, colliders[index].radius)) | |||
| { | |||
| collisionChecker = true; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| // Update grounded rigidbody state | |||
| rigidbodies[index].isGrounded = collisionChecker; | |||
| // Set grounded state if needed (fix overlap and set y velocity) | |||
| if (collisionChecker && rigidbodies[index].velocity.y != 0) | |||
| { | |||
| position->y += rigidbodies[index].velocity.y; | |||
| rigidbodies[index].velocity.y = -rigidbodies[index].velocity.y * rigidbodies[index].bounciness; | |||
| } | |||
| if (rigidbodies[index].isContact) | |||
| { | |||
| position->x -= rigidbodies[index].velocity.x; | |||
| rigidbodies[index].velocity.x = rigidbodies[index].velocity.x; | |||
| } | |||
| } | |||
| } | |||
| void SetRigidbodyEnabled(int index, bool state) | |||
| { | |||
| rigidbodies[index].enabled = state; | |||
| } | |||
| void SetRigidbodyVelocity(int index, Vector2 velocity) | |||
| { | |||
| rigidbodies[index].velocity.x = velocity.x; | |||
| rigidbodies[index].velocity.y = velocity.y; | |||
| } | |||
| void AddRigidbodyForce(int index, Vector2 force) | |||
| { | |||
| rigidbodies[index].acceleration.x = force.x * rigidbodies[index].mass; | |||
| rigidbodies[index].acceleration.y = force.y * rigidbodies[index].mass; | |||
| } | |||
| void SetColliderEnabled(int index, bool state) | |||
| { | |||
| colliders[index].enabled = state; | |||
| } | |||
| Collider GetCollider(int index) | |||
| { | |||
| return colliders[index]; | |||
| } | |||
| Rigidbody GetRigidbody(int index) | |||
| { | |||
| return rigidbodies[index]; | |||
| } | |||
| @ -0,0 +1,99 @@ | |||
| /********************************************************************************************** | |||
| * | |||
| * raylib physics engine module - Basic functions to apply physics to 2D objects | |||
| * | |||
| * 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 PHYSICS_H | |||
| #define PHYSICS_H | |||
| //---------------------------------------------------------------------------------- | |||
| // Defines and Macros | |||
| //---------------------------------------------------------------------------------- | |||
| // ... | |||
| //---------------------------------------------------------------------------------- | |||
| // Types and Structures Definition | |||
| //---------------------------------------------------------------------------------- | |||
| typedef enum { RectangleCollider, CircleCollider } ColliderType; | |||
| // Physics struct | |||
| typedef struct Physics { | |||
| bool enabled; | |||
| bool debug; // Should be used by programmer for testing purposes | |||
| Vector2 gravity; | |||
| } Physics; | |||
| // Transform struct | |||
| typedef struct Transform { | |||
| Vector2 position; | |||
| float rotation; | |||
| Vector2 scale; | |||
| } Transform; | |||
| // Rigidbody struct | |||
| typedef struct Rigidbody { | |||
| bool enabled; | |||
| float mass; | |||
| Vector2 acceleration; | |||
| Vector2 velocity; | |||
| bool isGrounded; | |||
| bool isContact; // Avoid freeze player when touching floor | |||
| bool applyGravity; | |||
| float friction; // 0.0f to 1.0f | |||
| float bounciness; // 0.0f to 1.0f | |||
| } Rigidbody; | |||
| // Collider struct | |||
| typedef struct Collider { | |||
| bool enabled; | |||
| ColliderType type; | |||
| Rectangle bounds; // Just used for RectangleCollider type | |||
| int radius; // Just used for CircleCollider type | |||
| } Collider; | |||
| #ifdef __cplusplus | |||
| extern "C" { // Prevents name mangling of functions | |||
| #endif | |||
| //---------------------------------------------------------------------------------- | |||
| // Module Functions Declaration | |||
| //---------------------------------------------------------------------------------- | |||
| void InitPhysics(); // Initialize all internal physics values | |||
| void SetPhysics(Physics settings); // Set physics settings values using Physics data type to overwrite internal physics settings | |||
| void AddRigidbody(int index, Rigidbody rigidbody); // Initialize a new rigidbody with parameters to internal index slot | |||
| void AddCollider(int index, Collider collider); // Initialize a new Collider with parameters to internal index slot | |||
| void ApplyPhysics(int index, Vector2 *position); // Apply physics to internal rigidbody, physics calculations are applied to position pointer parameter | |||
| void SetRigidbodyEnabled(int index, bool state); // Set enabled state to a defined rigidbody | |||
| void SetRigidbodyVelocity(int index, Vector2 velocity); // Set velocity of rigidbody (without considering of mass value) | |||
| void AddRigidbodyForce(int index, Vector2 force); // Set rigidbody force (considering mass value) | |||
| void SetColliderEnabled(int index, bool state); // Set enabled state to a defined collider | |||
| Rigidbody GetRigidbody(int index); // Returns the internal rigidbody data defined by index parameter | |||
| Collider GetCollider(int index); // Returns the internal collider data defined by index parameter | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif // PHYSICS_H | |||