9b6c09c32 Merge pull request #5049 from wwderw/master 0b125a5fd Update Makefile 0b7dda8ab Merge pull request #5050 from katanya04/master 3d93b3026 Update font load message 78a06990c Merge pull request #5041 from PanicTitan/master 82b80a699 Review formatting, avoid variable 71b302846 Review formatting, avoid variable 8823aba9d Update rprand.h 6b9a685ba Merge pull request #5048 from veins1/patch-4 14582a9f0 Merge pull request #5047 from RomainPlmg/#5009-fix-colorreplace-alpha 093e5200d Update Makefile 0405de794 Fix for music stopping too early d03ac97ef GetMusicTimePlayed fix for music shorter than buffer size 34af70866 [rtextures] Fix ImageColorReplace() alpha issue #5009 e00c5eb8b Merge pull request #5043 from vinnyhorgan/master cbea2ff50 Merge pull request #5046 from maiconpintoabreu/updatestream-music 3320a2c83 Fix to prevent UpdateMusicStream to run without music playing e7c043529 Merge pull request #5044 from backspaceoverload/fix-HalfToFloat 44ebf3238 Fix HalfToFloat Mantissa hex value 901afadbf fix warning log macro in rlgl f34e24068 Merge pull request #5042 from Sir-Irk/ImageDrawLineEx_fix fce3102f1 Remove excess comments 9f03d7c42 fixing comments 0c69c43c3 fix ImageDrawLineEx to be able to draw even numbered thicknesses 9e908e4a7 Update core_custom_frame_control.c to work properly on web 20a07a65d Merge pull request #5037 from garrisonhh/fix-gaussian-blur 8dbacafbe fix overflow in cast for ImageBlurGaussian 55a567471 Merge pull request #5036 from sleeptightAnsiC/update_glfw_mappings_h 930890555 [glfw] update mappings.h using GenerateMappings.cmake defbeee1a Merge pull request #5020 from Emil2010/master d972582bc Merge pull request #5025 from zedeckj/master 595756498 Merge pull request #5026 from jonathandw743/sdlfix eaea8e0b0 Merge pull request #5033 from wwderw/master 8ef51850b Update raudio.c a92f67bf3 Merge pull request #5031 from AmityWilder/safety-comments 205b6a092 Merge branch 'raysan5:master' into safety-comments 9f6d37ecb Update raylib_api.* by CI d4f09984a Add safety notes to 'Update_' functions 79c29cbe2 fixed compile error for PLATFORM sdl e91a3697f Fixed typo 910f4083e update dr_libs 7f8dfc6c6 Merge pull request #5018 from maiconpintoabreu/fix-zig-wasm-win-mac f1600a0c7 Fix issue on zig build emscripten run if the user has not installed emsdk 46f01e315 Merge pull request #5013 from maiconpintoabreu/zig-examples 2e74133a6 Merge pull request #5014 from fosskers/colin/cl-binding 7f32b9a96 Merge pull request #5015 from Sir-Irk/gltf_model_fix 8cf932c82 Merge pull request #5016 from Sir-Irk/fix_pbr_example_tangents ed509193d remving w multiply on the tangent itself f86295732 fixing shader tangents to be vec4 bee524e5e fixing offset for processing tangents for gltf loading eef1bac3e fix misspelling 0cae8890b Remove -fno-stack-protector as it is not needed and add requestFullscreen on exported methods 1db006b08 docs: mention another Common Lisp binding 8f50436dc Fix comments 6e9c3acaa Add run examples using zig and emscripten for web bdda18656 Merge pull request #5011 from maiconpintoabreu/update-emsdk-fix-touch d659037fb Update emsdk version for zig build to fix the issue with the EM_BOOL c35e13647 Merge branch 'master' of https://github.com/raysan5/raylib 44f670899 REVIEWED: Avoid `rtext` dependency on `rcore_desktop_sdl` #4959 e09dcf611 Merge pull request #5006 from ElDigoXD/patch-1 6266d0f41 Fix typo on config.h b67737608 Delete shader in case compilation fails 1abac023b Update rcore.c 8b0230f5b Merge pull request #5002 from mlorenc227/master 518ad8b01 Fix ScanDirectoryFilesRecursively 4bc8d3761 Merge pull request #4999 from danilwhale/raylib-cs.bleedingedge 43bad2612 docs: add Raylib-cs.BleedingEdge to the bindings fd4375a74 Merge pull request #4992 from M374LX/rgfw-update 17a618758 Merge pull request #4995 from Not-Nik/zig-raygui-options abf255fbe Merge pull request #4993 from Marcos-cat/master 106bcf460 add uiua bindings to the list 96c898852 Update RGFW 3e336e447 Reviewed warning 59bcf680a Code gardening... 8a3a8ee8e Update shapes_digital_clock.c 533c12c38 Small security tweaks 5f497d068 REVIEWED: `shapes_digital_clock` example cb369f8df Merge pull request #4985 from hmz-rhl/master 3f228f459 [examples] : adding new fancy clock 8d319b100 Merge pull request #4983 from M374LX/miniaudio-update d218db9ee Merge pull request #4982 from LainLayer/rgfw-timeout 59338c2c2 Update raylib_api.* by CI 714de02a8 Merge pull request #4980 from williewillus/pr4980 c81097505 Merge pull request #4981 from garrisonhh/add-build-zig-zon-license 53faf7ae7 Merge pull request #4977 from jestarray/patch-2 bb5b5434a Update miniaudio to v0.11.22 51958d6e2 changed `RGFW_window_eventWait` timeout to -1 b52a9f8a0 Add LICENSE to build.zig.zon 19ae6f2c2 [rshapes] Fix incorrect parameter names in DrawRectangleGradientEx 58a6846c8 Update raylib_api.* by CI 296e3af47 add const qualifier to ImageDrawTriangleFan and ImageDrawTriangleStrip arguments 924c87db3 Merge pull request #4976 from M374LX/rgfw-update-dev 6eeaf1dd5 Update RGFW to 1.7.5-dev c1bb53738 Merge pull request #4974 from M374LX/rgfw-escape-fix 9bf4388a4 Merge pull request #4965 from M374LX/rgfw-update 3414d96ea Update raylib_api.* by CI 20c0c92bd Merge pull request #4963 from meowstr/master bc2b2864e RGFW: fix Escape always closing the window b26f6d34b Allow passing options to raygui in build.zig b9c2ecc44 Merge pull request #4969 from M374LX/update-comments 8f2ecfba4 Update raylib_api.* by CI 341817261 Update comments 015db1641 Merge pull request #4964 from M374LX/axes-comment a9525bfbc Update RGFW to 1.7 16f398b46 Update comment (gamepad axes) 6d5aedbd3 Add DrawEllipseV and DrawEllipseLinesV 913c23648 REVIEWED: `MAX_GAMEPAD_AXES` 341bfb22c REVIEWED: `MAX_GAMEPAD_AXEX` for consistency #4960 2afae1b3e Merge pull request #4962 from M374LX/rgfw-rctrl f9fa63366 Merge pull request #4958 from M374LX/unused-var c0cf57f8f RGFW backend: add missing Right Control key 299f5350a Remove unused variable 2d952d8e9 Update raylib_api.* by CI d7148f5f9 REDESIGNED: Base64 encoding/decoding functions 5ddd13b77 REVIEWED: Hexadecimal formatting to be consistent 8d9c1cecb Update raylib_api.* by CI afb52b19a WARNING: REDESIGNED: `EncodeDataBase64()`, NULL terminated string returned 21f0fe2a7 Removed some spaces e3b9dbe75 Merge pull request #4947 from padmadevd/master b6daa48a9 Update rcore_android.c a1d57e83f Merge pull request #4948 from parzivail/bug/meshnormals 21e711b13 Fix typo in mesh animNormals 5da2d1011 Update rcore_android.c 2be18e2c5 Merge pull request #4944 from Pivok7/master 0ffc8c517 Pbr example fix 8c99a508c REVIEWED: `WindowSizeCallback()`, GLFW a51d33444 Merge branch 'master' of https://github.com/raysan5/raylib 9d4c31533 Update rtext.c 15a0cf89b Merge pull request #4936 from lumenkeyes/master ba3121914 Merge pull request #4937 from Bigfoot71/fix-gen-tangents 5076d5743 Merge pull request #4938 from JeffM2501/const_save_callback 4a1e9931a Update raylib_api.* by CI aa684a33d make save file callback match const correctness of calling function d135eef46 fix and improve `GenMeshTangents` 6f11e27bb fix typo dea6a2477 build.zig fix: link EGL for Android 63b988ade Update raylib_api.* by CI f7d03efb4 REVIEWED: `DecodeDataBase64()`, follow convention: 3083f0cd4 REVIEWED: `SaveFileText()`, const input text 693c9c292 Formatting tweaks 4ac31f7cd Merge pull request #4928 from JeffM2501/unload_default_font ebaa922f6 Properly clean up the default font on unload, it may be reused if the window is created again 7e0727836 Update rprand.h 1402e830b Merge pull request #4926 from karl-zylinski/draw-sphere-normals 6fad12db7 Merge pull request #4927 from lumenkeyes/master 35de7b26a catch error in build.zig eae3fd83d properly detect if abi is android c4b9c0e03 properly generate android triple in build.zig a15548fb5 Add normals to DrawSphereEx 3d6e24af4 Merge pull request #4906 from Bigfoot71/fix-clip 512b1bed4 Merge pull request #4925 from JeffM2501/animated_meshes_GL11 e07e3354a Merge branch 'animated_meshes_GL11' of github.com:JeffM2501/raylib into animated_meshes_GL11 ee2ab11cc Use the animated verts and normals in GL 1.1 if they exist 95c96b345 Use the animated verts and normals in GL 1.1 if they exist 31d63d08e Merge pull request #4922 from Bigfoot71/review-file-dir-2 a7ad2d196 Merge pull request #4918 from JeffM2501/default_font_image_leaks 3d292a6c3 Merge pull request #4923 from JeffM2501/gltf_bone_fix e53a43b7b Assign meshes without bone weights to the bone they are attached to so they animate. 38aec920b makes `path` static in `ScanDirectoryFilesRecursively` 03988d2ce added a NULL check in `UnloadDirectoryFiles` c08714438 Merge branch 'raysan5:master' into fix-clip 82c87d1f6 Merge pull request #4920 from MrScautHD/patch-1 8533d284c Update BINDINGS.md 94c5de33a Make the default font loadable before InitWindow, for use with the image API. Make the default font loader early out if we have already loaded parts of it, so we don't leak memory 461c9c9d9 review tabs a7333a9da review near/far git-subtree-dir: libs/raylib git-subtree-split: 9b6c09c32f7283e849918aef220ec4fa629af8d2
347 lines
17 KiB
C
347 lines
17 KiB
C
/*******************************************************************************************
|
|
*
|
|
* raylib [shaders] example - Basic PBR
|
|
*
|
|
* Example complexity rating: [★★★★] 4/4
|
|
*
|
|
* Example originally created with raylib 5.0, last time updated with raylib 5.1-dev
|
|
*
|
|
* Example contributed by Afan OLOVCIC (@_DevDad) and reviewed by Ramon Santamaria (@raysan5)
|
|
*
|
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
|
* BSD-like license that allows static linking with closed source software
|
|
*
|
|
* Copyright (c) 2023-2025 Afan OLOVCIC (@_DevDad)
|
|
*
|
|
* Model: "Old Rusty Car" (https://skfb.ly/LxRy) by Renafox,
|
|
* licensed under Creative Commons Attribution-NonCommercial
|
|
* (http://creativecommons.org/licenses/by-nc/4.0/)
|
|
*
|
|
********************************************************************************************/
|
|
|
|
#include "raylib.h"
|
|
|
|
#if defined(PLATFORM_DESKTOP)
|
|
#define GLSL_VERSION 330
|
|
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
|
#define GLSL_VERSION 100
|
|
#endif
|
|
|
|
#include <stdlib.h> // Required for: NULL
|
|
|
|
#define MAX_LIGHTS 4 // Max dynamic lights supported by shader
|
|
|
|
//----------------------------------------------------------------------------------
|
|
// Types and Structures Definition
|
|
//----------------------------------------------------------------------------------
|
|
|
|
// Light type
|
|
typedef enum {
|
|
LIGHT_DIRECTIONAL = 0,
|
|
LIGHT_POINT,
|
|
LIGHT_SPOT
|
|
} LightType;
|
|
|
|
// Light data
|
|
typedef struct {
|
|
int type;
|
|
int enabled;
|
|
Vector3 position;
|
|
Vector3 target;
|
|
float color[4];
|
|
float intensity;
|
|
|
|
// Shader light parameters locations
|
|
int typeLoc;
|
|
int enabledLoc;
|
|
int positionLoc;
|
|
int targetLoc;
|
|
int colorLoc;
|
|
int intensityLoc;
|
|
} Light;
|
|
|
|
//----------------------------------------------------------------------------------
|
|
// Global Variables Definition
|
|
//----------------------------------------------------------------------------------
|
|
static int lightCount = 0; // Current number of dynamic lights that have been created
|
|
|
|
//----------------------------------------------------------------------------------
|
|
// Module specific Functions Declaration
|
|
//----------------------------------------------------------------------------------
|
|
// Create a light and get shader locations
|
|
static Light CreateLight(int type, Vector3 position, Vector3 target, Color color, float intensity, Shader shader);
|
|
|
|
// Update light properties on shader
|
|
// NOTE: Light shader locations should be available
|
|
static void UpdateLight(Shader shader, Light light);
|
|
|
|
//----------------------------------------------------------------------------------
|
|
// Main Entry Point
|
|
//----------------------------------------------------------------------------------
|
|
int main()
|
|
{
|
|
// Initialization
|
|
//--------------------------------------------------------------------------------------
|
|
const int screenWidth = 800;
|
|
const int screenHeight = 450;
|
|
|
|
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
|
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - basic pbr");
|
|
|
|
// Define the camera to look into our 3d world
|
|
Camera camera = { 0 };
|
|
camera.position = (Vector3){ 2.0f, 2.0f, 6.0f }; // Camera position
|
|
camera.target = (Vector3){ 0.0f, 0.5f, 0.0f }; // Camera looking at point
|
|
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
|
camera.fovy = 45.0f; // Camera field-of-view Y
|
|
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
|
|
|
// Load PBR shader and setup all required locations
|
|
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/pbr.vs", GLSL_VERSION),
|
|
TextFormat("resources/shaders/glsl%i/pbr.fs", GLSL_VERSION));
|
|
shader.locs[SHADER_LOC_MAP_ALBEDO] = GetShaderLocation(shader, "albedoMap");
|
|
// WARNING: Metalness, roughness, and ambient occlusion are all packed into a MRA texture
|
|
// They are passed as to the SHADER_LOC_MAP_METALNESS location for convenience,
|
|
// shader already takes care of it accordingly
|
|
shader.locs[SHADER_LOC_MAP_METALNESS] = GetShaderLocation(shader, "mraMap");
|
|
shader.locs[SHADER_LOC_MAP_NORMAL] = GetShaderLocation(shader, "normalMap");
|
|
// WARNING: Similar to the MRA map, the emissive map packs different information
|
|
// into a single texture: it stores height and emission data
|
|
// It is binded to SHADER_LOC_MAP_EMISSION location an properly processed on shader
|
|
shader.locs[SHADER_LOC_MAP_EMISSION] = GetShaderLocation(shader, "emissiveMap");
|
|
shader.locs[SHADER_LOC_COLOR_DIFFUSE] = GetShaderLocation(shader, "albedoColor");
|
|
|
|
// Setup additional required shader locations, including lights data
|
|
shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
|
|
int lightCountLoc = GetShaderLocation(shader, "numOfLights");
|
|
int maxLightCount = MAX_LIGHTS;
|
|
SetShaderValue(shader, lightCountLoc, &maxLightCount, SHADER_UNIFORM_INT);
|
|
|
|
// Setup ambient color and intensity parameters
|
|
float ambientIntensity = 0.02f;
|
|
Color ambientColor = (Color){ 26, 32, 135, 255 };
|
|
Vector3 ambientColorNormalized = (Vector3){ ambientColor.r/255.0f, ambientColor.g/255.0f, ambientColor.b/255.0f };
|
|
SetShaderValue(shader, GetShaderLocation(shader, "ambientColor"), &ambientColorNormalized, SHADER_UNIFORM_VEC3);
|
|
SetShaderValue(shader, GetShaderLocation(shader, "ambient"), &ambientIntensity, SHADER_UNIFORM_FLOAT);
|
|
|
|
// Get location for shader parameters that can be modified in real time
|
|
int metallicValueLoc = GetShaderLocation(shader, "metallicValue");
|
|
int roughnessValueLoc = GetShaderLocation(shader, "roughnessValue");
|
|
int emissiveIntensityLoc = GetShaderLocation(shader, "emissivePower");
|
|
int emissiveColorLoc = GetShaderLocation(shader, "emissiveColor");
|
|
int textureTilingLoc = GetShaderLocation(shader, "tiling");
|
|
|
|
// Load old car model using PBR maps and shader
|
|
// WARNING: We know this model consists of a single model.meshes[0] and
|
|
// that model.materials[0] is by default assigned to that mesh
|
|
// There could be more complex models consisting of multiple meshes and
|
|
// multiple materials defined for those meshes... but always 1 mesh = 1 material
|
|
Model car = LoadModel("resources/models/old_car_new.glb");
|
|
|
|
// Assign already setup PBR shader to model.materials[0], used by models.meshes[0]
|
|
car.materials[0].shader = shader;
|
|
|
|
// Setup materials[0].maps default parameters
|
|
car.materials[0].maps[MATERIAL_MAP_ALBEDO].color = WHITE;
|
|
car.materials[0].maps[MATERIAL_MAP_METALNESS].value = 1.0f;
|
|
car.materials[0].maps[MATERIAL_MAP_ROUGHNESS].value = 0.0f;
|
|
car.materials[0].maps[MATERIAL_MAP_OCCLUSION].value = 1.0f;
|
|
car.materials[0].maps[MATERIAL_MAP_EMISSION].color = (Color){ 255, 162, 0, 255 };
|
|
|
|
// Setup materials[0].maps default textures
|
|
car.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = LoadTexture("resources/old_car_d.png");
|
|
car.materials[0].maps[MATERIAL_MAP_METALNESS].texture = LoadTexture("resources/old_car_mra.png");
|
|
car.materials[0].maps[MATERIAL_MAP_NORMAL].texture = LoadTexture("resources/old_car_n.png");
|
|
car.materials[0].maps[MATERIAL_MAP_EMISSION].texture = LoadTexture("resources/old_car_e.png");
|
|
|
|
// Load floor model mesh and assign material parameters
|
|
// NOTE: A basic plane shape can be generated instead of being loaded from a model file
|
|
Model floor = LoadModel("resources/models/plane.glb");
|
|
//Mesh floorMesh = GenMeshPlane(10, 10, 10, 10);
|
|
//GenMeshTangents(&floorMesh); // TODO: Review tangents generation
|
|
//Model floor = LoadModelFromMesh(floorMesh);
|
|
|
|
// Assign material shader for our floor model, same PBR shader
|
|
floor.materials[0].shader = shader;
|
|
|
|
floor.materials[0].maps[MATERIAL_MAP_ALBEDO].color = WHITE;
|
|
floor.materials[0].maps[MATERIAL_MAP_METALNESS].value = 0.8f;
|
|
floor.materials[0].maps[MATERIAL_MAP_ROUGHNESS].value = 0.1f;
|
|
floor.materials[0].maps[MATERIAL_MAP_OCCLUSION].value = 1.0f;
|
|
floor.materials[0].maps[MATERIAL_MAP_EMISSION].color = BLACK;
|
|
|
|
floor.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = LoadTexture("resources/road_a.png");
|
|
floor.materials[0].maps[MATERIAL_MAP_METALNESS].texture = LoadTexture("resources/road_mra.png");
|
|
floor.materials[0].maps[MATERIAL_MAP_NORMAL].texture = LoadTexture("resources/road_n.png");
|
|
|
|
// Models texture tiling parameter can be stored in the Material struct if required (CURRENTLY NOT USED)
|
|
// NOTE: Material.params[4] are available for generic parameters storage (float)
|
|
Vector2 carTextureTiling = (Vector2){ 0.5f, 0.5f };
|
|
Vector2 floorTextureTiling = (Vector2){ 0.5f, 0.5f };
|
|
|
|
// Create some lights
|
|
Light lights[MAX_LIGHTS] = { 0 };
|
|
lights[0] = CreateLight(LIGHT_POINT, (Vector3){ -1.0f, 1.0f, -2.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, YELLOW, 4.0f, shader);
|
|
lights[1] = CreateLight(LIGHT_POINT, (Vector3){ 2.0f, 1.0f, 1.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, GREEN, 3.3f, shader);
|
|
lights[2] = CreateLight(LIGHT_POINT, (Vector3){ -2.0f, 1.0f, 1.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, RED, 8.3f, shader);
|
|
lights[3] = CreateLight(LIGHT_POINT, (Vector3){ 1.0f, 1.0f, -2.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, BLUE, 2.0f, shader);
|
|
|
|
// Setup material texture maps usage in shader
|
|
// NOTE: By default, the texture maps are always used
|
|
int usage = 1;
|
|
SetShaderValue(shader, GetShaderLocation(shader, "useTexAlbedo"), &usage, SHADER_UNIFORM_INT);
|
|
SetShaderValue(shader, GetShaderLocation(shader, "useTexNormal"), &usage, SHADER_UNIFORM_INT);
|
|
SetShaderValue(shader, GetShaderLocation(shader, "useTexMRA"), &usage, SHADER_UNIFORM_INT);
|
|
SetShaderValue(shader, GetShaderLocation(shader, "useTexEmissive"), &usage, SHADER_UNIFORM_INT);
|
|
|
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
// Main game loop
|
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
|
{
|
|
// Update
|
|
//----------------------------------------------------------------------------------
|
|
UpdateCamera(&camera, CAMERA_ORBITAL);
|
|
|
|
// Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f })
|
|
float cameraPos[3] = {camera.position.x, camera.position.y, camera.position.z};
|
|
SetShaderValue(shader, shader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3);
|
|
|
|
// Check key inputs to enable/disable lights
|
|
if (IsKeyPressed(KEY_ONE)) { lights[2].enabled = !lights[2].enabled; }
|
|
if (IsKeyPressed(KEY_TWO)) { lights[1].enabled = !lights[1].enabled; }
|
|
if (IsKeyPressed(KEY_THREE)) { lights[3].enabled = !lights[3].enabled; }
|
|
if (IsKeyPressed(KEY_FOUR)) { lights[0].enabled = !lights[0].enabled; }
|
|
|
|
// Update light values on shader (actually, only enable/disable them)
|
|
for (int i = 0; i < MAX_LIGHTS; i++) UpdateLight(shader, lights[i]);
|
|
//----------------------------------------------------------------------------------
|
|
|
|
// Draw
|
|
//----------------------------------------------------------------------------------
|
|
BeginDrawing();
|
|
|
|
ClearBackground(BLACK);
|
|
|
|
BeginMode3D(camera);
|
|
|
|
// Set floor model texture tiling and emissive color parameters on shader
|
|
SetShaderValue(shader, textureTilingLoc, &floorTextureTiling, SHADER_UNIFORM_VEC2);
|
|
Vector4 floorEmissiveColor = ColorNormalize(floor.materials[0].maps[MATERIAL_MAP_EMISSION].color);
|
|
SetShaderValue(shader, emissiveColorLoc, &floorEmissiveColor, SHADER_UNIFORM_VEC4);
|
|
|
|
// Set floor metallic and roughness values
|
|
SetShaderValue(shader, metallicValueLoc, &floor.materials[0].maps[MATERIAL_MAP_METALNESS].value, SHADER_UNIFORM_FLOAT);
|
|
SetShaderValue(shader, roughnessValueLoc, &floor.materials[0].maps[MATERIAL_MAP_ROUGHNESS].value, SHADER_UNIFORM_FLOAT);
|
|
|
|
DrawModel(floor, (Vector3){ 0.0f, 0.0f, 0.0f }, 5.0f, WHITE); // Draw floor model
|
|
|
|
// Set old car model texture tiling, emissive color and emissive intensity parameters on shader
|
|
SetShaderValue(shader, textureTilingLoc, &carTextureTiling, SHADER_UNIFORM_VEC2);
|
|
Vector4 carEmissiveColor = ColorNormalize(car.materials[0].maps[MATERIAL_MAP_EMISSION].color);
|
|
SetShaderValue(shader, emissiveColorLoc, &carEmissiveColor, SHADER_UNIFORM_VEC4);
|
|
float emissiveIntensity = 0.01f;
|
|
SetShaderValue(shader, emissiveIntensityLoc, &emissiveIntensity, SHADER_UNIFORM_FLOAT);
|
|
|
|
// Set old car metallic and roughness values
|
|
SetShaderValue(shader, metallicValueLoc, &car.materials[0].maps[MATERIAL_MAP_METALNESS].value, SHADER_UNIFORM_FLOAT);
|
|
SetShaderValue(shader, roughnessValueLoc, &car.materials[0].maps[MATERIAL_MAP_ROUGHNESS].value, SHADER_UNIFORM_FLOAT);
|
|
|
|
DrawModel(car, (Vector3){ 0.0f, 0.0f, 0.0f }, 0.25f, WHITE); // Draw car model
|
|
|
|
// Draw spheres to show the lights positions
|
|
for (int i = 0; i < MAX_LIGHTS; i++)
|
|
{
|
|
Color lightColor = (Color){ lights[i].color[0]*255, lights[i].color[1]*255, lights[i].color[2]*255, lights[i].color[3]*255 };
|
|
|
|
if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lightColor);
|
|
else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lightColor, 0.3f));
|
|
}
|
|
|
|
EndMode3D();
|
|
|
|
DrawText("Toggle lights: [1][2][3][4]", 10, 40, 20, LIGHTGRAY);
|
|
|
|
DrawText("(c) Old Rusty Car model by Renafox (https://skfb.ly/LxRy)", screenWidth - 320, screenHeight - 20, 10, LIGHTGRAY);
|
|
|
|
DrawFPS(10, 10);
|
|
|
|
EndDrawing();
|
|
//----------------------------------------------------------------------------------
|
|
}
|
|
|
|
// De-Initialization
|
|
//--------------------------------------------------------------------------------------
|
|
// Unbind (disconnect) shader from car.material[0]
|
|
// to avoid UnloadMaterial() trying to unload it automatically
|
|
car.materials[0].shader = (Shader){ 0 };
|
|
UnloadMaterial(car.materials[0]);
|
|
car.materials[0].maps = NULL;
|
|
UnloadModel(car);
|
|
|
|
floor.materials[0].shader = (Shader){ 0 };
|
|
UnloadMaterial(floor.materials[0]);
|
|
floor.materials[0].maps = NULL;
|
|
UnloadModel(floor);
|
|
|
|
UnloadShader(shader); // Unload Shader
|
|
|
|
CloseWindow(); // Close window and OpenGL context
|
|
//--------------------------------------------------------------------------------------
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Create light with provided data
|
|
// NOTE: It updated the global lightCount and it's limited to MAX_LIGHTS
|
|
static Light CreateLight(int type, Vector3 position, Vector3 target, Color color, float intensity, Shader shader)
|
|
{
|
|
Light light = { 0 };
|
|
|
|
if (lightCount < MAX_LIGHTS)
|
|
{
|
|
light.enabled = 1;
|
|
light.type = type;
|
|
light.position = position;
|
|
light.target = target;
|
|
light.color[0] = (float)color.r/255.0f;
|
|
light.color[1] = (float)color.g/255.0f;
|
|
light.color[2] = (float)color.b/255.0f;
|
|
light.color[3] = (float)color.a/255.0f;
|
|
light.intensity = intensity;
|
|
|
|
// NOTE: Shader parameters names for lights must match the requested ones
|
|
light.enabledLoc = GetShaderLocation(shader, TextFormat("lights[%i].enabled", lightCount));
|
|
light.typeLoc = GetShaderLocation(shader, TextFormat("lights[%i].type", lightCount));
|
|
light.positionLoc = GetShaderLocation(shader, TextFormat("lights[%i].position", lightCount));
|
|
light.targetLoc = GetShaderLocation(shader, TextFormat("lights[%i].target", lightCount));
|
|
light.colorLoc = GetShaderLocation(shader, TextFormat("lights[%i].color", lightCount));
|
|
light.intensityLoc = GetShaderLocation(shader, TextFormat("lights[%i].intensity", lightCount));
|
|
|
|
UpdateLight(shader, light);
|
|
|
|
lightCount++;
|
|
}
|
|
|
|
return light;
|
|
}
|
|
|
|
// Send light properties to shader
|
|
// NOTE: Light shader locations should be available
|
|
static void UpdateLight(Shader shader, Light light)
|
|
{
|
|
SetShaderValue(shader, light.enabledLoc, &light.enabled, SHADER_UNIFORM_INT);
|
|
SetShaderValue(shader, light.typeLoc, &light.type, SHADER_UNIFORM_INT);
|
|
|
|
// Send to shader light position values
|
|
float position[3] = { light.position.x, light.position.y, light.position.z };
|
|
SetShaderValue(shader, light.positionLoc, position, SHADER_UNIFORM_VEC3);
|
|
|
|
// Send to shader light target position values
|
|
float target[3] = { light.target.x, light.target.y, light.target.z };
|
|
SetShaderValue(shader, light.targetLoc, target, SHADER_UNIFORM_VEC3);
|
|
SetShaderValue(shader, light.colorLoc, light.color, SHADER_UNIFORM_VEC4);
|
|
SetShaderValue(shader, light.intensityLoc, &light.intensity, SHADER_UNIFORM_FLOAT);
|
|
}
|