Merge pull request #66 from victorfisac/develop

New matrix location points, lighting and physics engine modules with examples
This commit is contained in:
Ray 2015-12-24 12:42:48 +01:00
commit e8c79f53a6
19 changed files with 7774 additions and 93 deletions

View File

@ -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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

@ -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);
}

76
shaders/gl330/phong.fs Normal file
View File

@ -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);
}

28
shaders/gl330/phong.vs Normal file
View File

@ -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);
}

View File

@ -92,7 +92,7 @@ typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
bool musicEnabled = false;
static bool musicEnabled = false;
static Music currentMusic; // Current music loaded
// NOTE: Only one music file playing at a time

BIN
src/libraylib.a Normal file

Binary file not shown.

124
src/lighting.c Normal file
View File

@ -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;
}

87
src/lighting.h Normal file
View File

@ -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

View File

@ -64,7 +64,7 @@ static VertexData LoadOBJ(const char *fileName);
// Draw cube
// NOTE: Cube position is the center position
void DrawCube(Vector3 position, float width, float height, float lenght, Color color)
void DrawCube(Vector3 position, float width, float height, float length, Color color)
{
float x = 0.0f;
float y = 0.0f;
@ -81,58 +81,58 @@ void DrawCube(Vector3 position, float width, float height, float lenght, Color c
rlColor4ub(color.r, color.g, color.b, color.a);
// Front Face -----------------------------------------------------
rlVertex3f(x-width/2, y-height/2, z+lenght/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Right
rlVertex3f(x-width/2, y+height/2, z+lenght/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
rlVertex3f(x+width/2, y+height/2, z+lenght/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Left
rlVertex3f(x+width/2, y-height/2, z+lenght/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
// Back Face ------------------------------------------------------
rlVertex3f(x-width/2, y-height/2, z-lenght/2); // Bottom Left
rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left
rlVertex3f(x+width/2, y-height/2, z-lenght/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 Left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-lenght/2); // Top Right
rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Bottom Right
rlVertex3f(x-width/2, y+height/2, z-lenght/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 Right
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left
// Top Face -------------------------------------------------------
rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left
rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Bottom Left
rlVertex3f(x+width/2, y+height/2, z+lenght/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); // Bottom Left
rlVertex3f(x+width/2, y+height/2, z+length/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-lenght/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left
rlVertex3f(x+width/2, y+height/2, z+lenght/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-lenght/2); // Top Left
rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Right
rlVertex3f(x-width/2, y-height/2, z+lenght/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); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Top Right
rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Right
rlVertex3f(x-width/2, y-height/2, z-lenght/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 Right
rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Left
// Right face -----------------------------------------------------
rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-lenght/2); // Top Right
rlVertex3f(x+width/2, y+height/2, z+lenght/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); // Top Left
rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z+lenght/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-lenght/2); // Bottom Right
rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Left
rlVertex3f(x-width/2, y+height/2, z-lenght/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
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Right
rlVertex3f(x-width/2, y-height/2, z+lenght/2); // Bottom Left
rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z-lenght/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 Left
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Right
rlEnd();
rlPopMatrix();
}
@ -144,7 +144,7 @@ void DrawCubeV(Vector3 position, Vector3 size, Color color)
}
// Draw cube wires
void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color)
void DrawCubeWires(Vector3 position, float width, float height, float length, Color color)
{
float x = 0.0f;
float y = 0.0f;
@ -160,62 +160,62 @@ void DrawCubeWires(Vector3 position, float width, float height, float lenght, Co
// Front Face -----------------------------------------------------
// Bottom Line
rlVertex3f(x-width/2, y-height/2, z+lenght/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z+lenght/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); // Bottom Right
// Left Line
rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z+lenght/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 Right
// Top Line
rlVertex3f(x+width/2, y+height/2, z+lenght/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z+lenght/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
// Right Line
rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z+lenght/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 Left
// Back Face ------------------------------------------------------
// Bottom Line
rlVertex3f(x-width/2, y-height/2, z-lenght/2); // Bottom Left
rlVertex3f(x+width/2, y-height/2, z-lenght/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); // Bottom Right
// Left Line
rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Bottom Right
rlVertex3f(x+width/2, y+height/2, z-lenght/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 Right
// Top Line
rlVertex3f(x+width/2, y+height/2, z-lenght/2); // Top Right
rlVertex3f(x-width/2, y+height/2, z-lenght/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
// Right Line
rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left
rlVertex3f(x-width/2, y-height/2, z-lenght/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 Left
// Top Face -------------------------------------------------------
// Left Line
rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Left Front
rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left Back
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+lenght/2); // Top Right Front
rlVertex3f(x+width/2, y+height/2, z-lenght/2); // Top Right Back
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+lenght/2); // Top Left Front
rlVertex3f(x-width/2, y-height/2, z-lenght/2); // Top Left Back
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+lenght/2); // Top Right Front
rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Top Right Back
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();
}
// Draw cube
// NOTE: Cube position is the center position
void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float lenght, Color color)
void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color)
{
float x = position.x;
float y = position.y;
@ -233,40 +233,40 @@ void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float hei
rlColor4ub(color.r, color.g, color.b, color.a);
// Front Face
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z+lenght/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z+lenght/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left Of The Texture and Quad
// Back Face
rlNormal3f( 0.0f, 0.0f,-1.0f); // Normal Pointing Away From Viewer
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z-lenght/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z-lenght/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Left Of The Texture and Quad
// Top Face
rlNormal3f( 0.0f, 1.0f, 0.0f); // Normal Pointing Up
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x+width/2, y+height/2, z+lenght/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z-lenght/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x-width/2, y+height/2, z+length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x+width/2, y+height/2, z+length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right Of The Texture and Quad
// Bottom Face
rlNormal3f( 0.0f,-1.0f, 0.0f); // Normal Pointing Down
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x-width/2, y-height/2, z-lenght/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z+lenght/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x+width/2, y-height/2, z-length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Right Of The Texture and Quad
// Right face
rlNormal3f( 1.0f, 0.0f, 0.0f); // Normal Pointing Right
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z-lenght/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z-lenght/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z+lenght/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z+lenght/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Left Of The Texture and Quad
// Left Face
rlNormal3f(-1.0f, 0.0f, 0.0f); // Normal Pointing Left
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z-lenght/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z+lenght/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left Of The Texture and Quad
rlEnd();
//rlPopMatrix();
@ -534,12 +534,12 @@ void DrawGrid(int slices, float spacing)
void DrawGizmo(Vector3 position)
{
// NOTE: RGB = XYZ
float lenght = 1.0f;
float length = 1.0f;
rlPushMatrix();
rlTranslatef(position.x, position.y, position.z);
//rlRotatef(rotation, 0, 1, 0);
rlScalef(lenght, lenght, lenght);
rlScalef(length, length, length);
rlBegin(RL_LINES);
rlColor3f(1.0f, 0.0f, 0.0f); rlVertex3f(0.0f, 0.0f, 0.0f);
@ -1164,6 +1164,13 @@ void DrawModelWires(Model model, Vector3 position, float scale, Color color)
rlglDrawModel(model, position, 0.0f, rotationAxis, vScale, color, true);
}
// Draw a model wires (with texture if set) with extended parameters
void DrawModelWiresEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color tint)
{
// NOTE: Rotation must be provided in degrees, it's converted to radians inside rlglDrawModel()
rlglDrawModel(model, position, rotationAngle, rotationAxis, scale, tint, true);
}
// Draw a billboard
void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint)
{

272
src/physics.c Normal file
View File

@ -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];
}

99
src/physics.h Normal file
View File

@ -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

View File

@ -329,7 +329,9 @@ typedef struct Shader {
// Uniforms
int projectionLoc; // Projection matrix uniform location point (vertex shader)
int modelviewLoc; // ModeView matrix uniform location point (vertex shader)
int modelviewLoc; // ModelView matrix uniform location point (vertex shader)
int modelLoc; // Model transformation matrix uniform location point (vertex shader)
int viewLoc; // View transformation matrix uniform location point (vertex shader)
int tintColorLoc; // Color uniform location point (fragment shader)
int mapDiffuseLoc; // Diffuse map texture uniform location point (fragment shader)
@ -366,6 +368,26 @@ typedef struct Wave {
short channels;
} 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];
} Light;
// Material type
typedef struct Material {
float ambientColor[3];
float diffuseColor[3];
float specularColor[3];
float glossiness[1];
float normalDepth[1];
} Material;
// Texture formats
// NOTE: Support depends on OpenGL version and platform
typedef enum {
@ -411,6 +433,44 @@ typedef enum {
// Camera system modes
typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode;
// Collider types
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
@ -666,6 +726,7 @@ void SetModelTexture(Model *model, Texture2D texture);
void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
void DrawModelEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color tint); // Draw a model with extended parameters
void DrawModelWires(Model model, Vector3 position, float scale, Color color); // Draw a model wires (with texture if set)
void DrawModelWiresEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
@ -699,6 +760,45 @@ void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textur
void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied)
//----------------------------------------------------------------------------------
// Lighting System Functions (engine-module: lighting)
// 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)
//----------------------------------------------------------------------------------
// Physics System Functions (engine-module: physics)
//----------------------------------------------------------------------------------
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
//------------------------------------------------------------------------------------
// Audio Loading and Playing Functions (Module: audio)
//------------------------------------------------------------------------------------

View File

@ -1094,6 +1094,7 @@ void rlglInit(void)
// Modifies global variables: postproFbo, postproQuad
void rlglInitPostpro(void)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
postproFbo = rlglLoadFBO(screenWidth, screenHeight);
if (postproFbo.id > 0)
@ -1120,6 +1121,7 @@ void rlglInitPostpro(void)
// NOTE: postproFbo.colorTextureId must be assigned to postproQuad model shader
}
#endif
}
// Load a framebuffer object
@ -1195,11 +1197,13 @@ FBO rlglLoadFBO(int width, int height)
// Unload framebuffer object
void rlglUnloadFBO(FBO fbo)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glDeleteFramebuffers(1, &fbo.id);
glDeleteTextures(1, &fbo.colorTextureId);
glDeleteTextures(1, &fbo.depthTextureId);
TraceLog(INFO, "[FBO ID %i] Unloaded framebuffer object successfully", fbo.id);
#endif
}
// Vertex Buffer Object deinitialization (memory free)
@ -1498,6 +1502,8 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r
glUseProgram(model.shader.id);
// Apply transformation provided in model.transform matrix
// TODO: review if at this point the modelview matrix just contains view matrix values
Matrix viewworld = modelview; // Store view matrix before applying model transformations
Matrix modelviewworld = MatrixMultiply(model.transform, modelview); // World-space transformation
// Apply transformations provided in function
@ -1513,6 +1519,8 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r
// NOTE: Drawing in OpenGL 3.3+, transform is passed to shader
glUniformMatrix4fv(model.shader.projectionLoc, 1, false, GetMatrixVector(projection));
glUniformMatrix4fv(model.shader.modelLoc, 1, false, GetMatrixVector(transform));
glUniformMatrix4fv(model.shader.viewLoc, 1, false, GetMatrixVector(viewworld));
glUniformMatrix4fv(model.shader.modelviewLoc, 1, false, GetMatrixVector(modelviewworld));
// Apply color tinting to model
@ -1935,7 +1943,8 @@ void rlglGenerateMipmaps(unsigned int textureId)
{
#if defined(GRAPHICS_API_OPENGL_11)
// Compute required mipmaps
void *data = rlglReadTexturePixels(textureId, UNCOMPRESSED_R8G8B8A8); // TODO: Detect internal format
// TODO: rlglReadTexturePixels() needs Texture2D type parameter, not unsigned int parameter
void *data; // = rlglReadTexturePixels(textureId, UNCOMPRESSED_R8G8B8A8); // TODO: Detect internal format
// NOTE: data size is reallocated to fit mipmaps data
int mipmapCount = GenerateMipmaps(data, width, height);
@ -2242,6 +2251,8 @@ Shader LoadShader(char *vsFileName, char *fsFileName)
// Get handles to GLSL uniform locations (vertex shader)
shader.modelviewLoc = glGetUniformLocation(shader.id, "modelviewMatrix");
shader.modelLoc = glGetUniformLocation(shader.id, "modelMatrix");
shader.viewLoc = glGetUniformLocation(shader.id, "viewMatrix");
shader.projectionLoc = glGetUniformLocation(shader.id, "projectionMatrix");
// Get handles to GLSL uniform locations (fragment shader)
@ -2781,6 +2792,8 @@ static Shader LoadDefaultShader(void)
// Get handles to GLSL uniform locations (vertex shader)
shader.modelviewLoc = glGetUniformLocation(shader.id, "modelviewMatrix");
shader.modelLoc = glGetUniformLocation(shader.id, "modelMatrix");
shader.viewLoc = glGetUniformLocation(shader.id, "viewMatrix");
shader.projectionLoc = glGetUniformLocation(shader.id, "projectionMatrix");
// Get handles to GLSL uniform locations (fragment shader)
@ -2861,6 +2874,8 @@ static Shader LoadSimpleShader(void)
// Get handles to GLSL uniform locations (vertex shader)
shader.modelviewLoc = glGetUniformLocation(shader.id, "modelviewMatrix");
shader.modelLoc = glGetUniformLocation(shader.id, "modelMatrix");
shader.viewLoc = glGetUniformLocation(shader.id, "viewMatrix");
shader.projectionLoc = glGetUniformLocation(shader.id, "projectionMatrix");
// Get handles to GLSL uniform locations (fragment shader)

View File

@ -160,7 +160,9 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
// Uniforms
int projectionLoc; // Projection matrix uniform location point (vertex shader)
int modelviewLoc; // ModeView matrix uniform location point (vertex shader)
int modelviewLoc; // ModelView matrix uniform location point (vertex shader)
int modelLoc; // Model transformation matrix uniform location point (vertex shader)
int viewLoc; // View transformation matrix uniform location point (vertex shader)
int tintColorLoc; // Color uniform location point (fragment shader)
int mapDiffuseLoc; // Diffuse map texture uniform location point (fragment shader)