- New lighting engine module which contains new data types Light and Material. These data types and functions facilitates making a basic 3D iluminated program with a light and a model. - Added lighting engine module example (currently included in raylib.h; it might be compiled by separate and include lighting.h in game source C file). - Corrected some opengl defines control structures and added some TODO to fix raylib-opengl 1.1 source build (note: now source can be compiled without errors, but rlglReadPixels() won't work properly). Note: most of functions of phong version 330 shader are not in v100 shaders, so I couldn't write a version 100 phong shader. These functions are included from version 150.pull/66/head
@ -0,0 +1,180 @@ | |||||
/******************************************************************************************* | |||||
* | |||||
* raylib - Phong lighting shader example | |||||
* | |||||
* This example has been created using raylib v1.3.0 (www.raylib.com) | |||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) | |||||
* | |||||
* Copyright (c) 2015 Ramon Santamaria (Ray San - raysan@raysanweb.com) | |||||
* | |||||
********************************************************************************************/ | |||||
#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 - basic 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,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 Definition | |||||
//---------------------------------------------------------------------------------- | |||||
// 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 Declaration | |||||
// 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 |