Merge branch 'raysan5:master' into master

This commit is contained in:
Raffaele 2021-10-19 14:24:54 +02:00 committed by GitHub
commit 4bb8dfc83c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
111 changed files with 11049 additions and 27036 deletions

1
.gitignore vendored
View File

@ -45,6 +45,7 @@ ipch/
*.db
*.opendb
packages/
!examples/models/resources/models/obj/
# Ignore compiled binaries
*.o

View File

@ -30,6 +30,7 @@ Detailed changes:
[core] REVIEWED: Raspberry RPI/DRM keyboard blocking render loop (#1879) @luizpestana
[core] REVIEWED: Android multi-touch (#1869) by @humbe
[core] REVIEWED: Implemented GetGamepadName() for emscripten by @nbarkhina
[core] REVIEWED: HighDPI support (#1987) by @ArnaudValensi
[rlgl] ADDED: rlUpdateVertexBufferElements() (#1915)
[rlgl] ADDED: rlActiveDrawBuffers() (#1911)
[rlgl] ADDED: rlEnableColorBlend()/rlDisableColorBlend()
@ -43,6 +44,7 @@ Detailed changes:
[shapes] ADDED: RenderPolyLinesEx() (#1758) by @lambertwang
[shapes] ADDED: DrawLineBezierCubic() (#2021) by @SAOMDVN
[textures] ADDED: GetImageColor() #2024
[textures] REMOVED: GenImagePerlinNoise()
[textures] RENAMED: GetTextureData() to LoadImageFromTexture()
[textures] RENAMED: GetScreenData() to LoadImageFromScreen()
[textures] REVIEWED: ExportImage() to use SaveFileData() (#1779)
@ -63,6 +65,7 @@ Detailed changes:
[models] ADDED: GetModelBoundingBox()
[models] ADDED: DrawBillboardPro() (#1759) by @nobytesgiven
[models] ADDED: DrawCubeTextureRec() (#2001) by @tdgroot
[models] ADDED: DrawCylinderEx() and DrawCylinderWiresEx() (#2049) by @Horrowind
[models] REMOVED: DrawBillboardEx()
[models] RENAMED: MeshBoundingBox() to GetMeshBoundingBox()
[models] RENAMED: MeshTangents() to GenMeshTangents()
@ -86,9 +89,11 @@ Detailed changes:
[examples] ADDED: core_custom_frame_control
[examples] ADDED: core_basic_screen_manager
[examples] ADDED: core_split_screen (#1806) by @JeffM2501
[examples] ADDED: core_2d_camera_smooth_pixelperfect (#1771) by @NotManyIdeasDev
[examples] ADDED: shaders_shapes_outline (#1883) by @GoldenThumbs
[examples] ADDED: models_magicavoxel_loading (#1940) by @procfxgen
[examples] ADDED: core_smooth_pixelperfect (#1771) by @NotManyIdeasDev
[examples] ADDED: shaders_texture_outline (#1883) by @GoldenThumbs
[examples] ADDED: models_loading_vox (#1940) by @procfxgen
[examples] REMOVED: models_material_pbr
[examples] REMOVED: models_gltf_animation
[examples] REVIEWED: core_3d_picking
[examples] REVIEWED: core_input_mouse
[examples] REVIEWED: core_vr_simulator, RenderTexture usage
@ -114,6 +119,7 @@ Detailed changes:
[examples] REVIEWED: raylib_opengl_interop
[examples] REVIEWED: rlgl_standalone.c
[examples] REVIEWED: Resources licenses
[examples] REVIEWED: models resources reorganization
[build] ADDED: Zig build file (#2014) by @TommiSinivuo
[build] ADDED: Android VS2019 solution (#2013) by @Kronka
[build] REMOVED: VS2017 project, outdated

View File

@ -4,7 +4,7 @@
raylib is highly inspired by Borland BGI graphics lib and by XNA framework and it's specially well suited for prototyping, tooling, graphical applications, embedded systems and education.
*NOTE for ADVENTURERS: raylib is a programming library to enjoy videogames programming; no fancy interface, no visual helpers, no auto-debugging... just coding in the most pure spartan-programmers way.*
*NOTE for ADVENTURERS: raylib is a programming library to enjoy videogames programming; no fancy interface, no visual helpers, no debug button... just coding in the most pure spartan-programmers way.*
Ready to learn? Jump to [code examples!](http://www.raylib.com/examples.html)

View File

@ -4,18 +4,11 @@
The following people is currently [**sponsoring raylib**](https://github.com/sponsors/raysan5) with a generous donation to allow improving and growing the project!
Note that Sponsors donations vary between sponsors, I just decided not to make any distinction while listing them.
- Eric J. ([@ProfJski](https://github.com/ProfJski))
- devdad ([@devdad](https://github.com/devdad))
- Zach Geis ([@zacgeis](https://github.com/zacgeis))
- minirop ([@minirop](https://github.com/minirop))
- Daniel Gómez ([@Koocachookies](https://github.com/Koocachookies))
- Sergio ([@anidealgift](https://github.com/anidealgift))
- Marc Agüera ([@maguera93](https://github.com/maguera93))
- Pau Fernández ([@pauek](https://github.com/pauek))
- Snowminx ([@Gamerfiend](https://github.com/Gamerfiend))
- NimbusFox ([@NimbusFox](https://github.com/NimbusFox))
- Robin Mattheussen ([@romatthe](https://github.com/romatthe))
- Grant Haywood ([@cinterloper](https://github.com/cinterloper))
- Terry Nguyen ([@terrehbyte](https://github.com/terrehbyte))
@ -25,10 +18,17 @@ Note that Sponsors donations vary between sponsors, I just decided not to make a
- cob ([@majorcob](https://github.com/majorcob))
- Samuel Batista ([@gamedevsam](https://github.com/gamedevsam))
- Merlyn Morgan-Graham ([@kavika13](https://github.com/kavika13))
- Toby4213 ([@Toby4213](https://github.com/Toby4213))
- linus ([@hochbaum](https://github.com/hochbaum))
- Nawarian ([@nawarian](https://github.com/nawarian) - [thephp.website](https://thephp.website/))
- kenzie ([@sme-ek](https://github.com/sme-ek))
- Allan Regush ([@AllanRegush](https://github.com/AllanRegush))
- Jeffery Myers ([@JeffM2501](https://github.com/ProfJski))
- Ryan Roden-Corrent ([@rcorre](https://github.com/ProfJski))
- michaelfiber ([@michaelfiber](https://github.com/ProfJski))
- Nikhilesh S ([@nikki93](https://github.com/ProfJski))
- kevinabraun ([@kevinabraun](https://github.com/ProfJski))
- Matthew Owens ([@MatthewOwens](https://github.com/ProfJski))
- Tim Eilers ([@eilerstim](https://github.com/ProfJski))
### Past raylib GitHub Sponsors
@ -49,10 +49,20 @@ The following people has **sponsored raylib** in the past, allowing the project
- James Ghawaly ([@jghawaly](https://github.com/jghawaly))
- jack ([@Jack-Ji](https://github.com/Jack-Ji))
- Guido Offermans ([@jghawaly](https://github.com/GuidoOffermans))
- devdad ([@devdad](https://github.com/devdad))
- Pau Fernández ([@pauek](https://github.com/pauek))
- Sergio ([@anidealgift](https://github.com/anidealgift))
- Snowminx ([@Gamerfiend](https://github.com/Gamerfiend))
- NimbusFox ([@NimbusFox](https://github.com/NimbusFox))
- Shylie ([@Shylie](https://github.com/Shylie))
- Livio Dal Maso ([@Humeur](https://github.com/Humeur))
- Diego Vaccher ([@denny0754](https://github.com/denny0754))
- Ricardo Alcantara ([@ricardoalcantara](https://github.com/ricardoalcantara))
- Toby4213 ([@Toby4213](https://github.com/Toby4213))
### Notes for Current/Past raylib Sponsor
- **If you are not on the list, feel free to send a PR to add you if desired.**
- **If you want your personal webpage listed along your GitHub account, feel free to send a PR to add it.**
- **If you prefer not to listed in this list, feel free to send a PR to remove it.**
- If you are not on the list, feel free to send a PR to be added (if desired).
- If you want your personal webpage or project listed, feel free to send a PR to be added.
- If you prefer not to be in this list, feel free to send a PR to be remove.

View File

@ -73,7 +73,6 @@ if (${PLATFORM} MATCHES "Android")
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_world_screen.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_mesh_picking.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_material_pbr.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_cubicmap.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_skybox.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_mesh_picking.c)

View File

@ -378,6 +378,7 @@ endif
# Define all object files required
CORE = \
core/core_basic_window \
core/core_basic_screen_manager \
core/core_input_keys \
core/core_input_mouse \
core/core_input_mouse_wheel \
@ -401,7 +402,9 @@ CORE = \
core/core_loading_thread \
core/core_quat_conversion \
core/core_window_flags \
core/core_split_screen
core/core_split_screen \
core/core_smooth_pixelperfect \
core/core_custom_frame_control
SHAPES = \
shapes/shapes_basic_shapes \
@ -440,7 +443,7 @@ TEXTURES = \
textures/textures_bunnymark \
textures/textures_blend_modes \
textures/textures_draw_tiled \
textures/textures_poly
textures/textures_polygon
TEXT = \
text/text_raylib_fonts \
@ -462,17 +465,17 @@ MODELS = \
models/models_cubicmap \
models/models_first_person_maze \
models/models_geometric_shapes \
models/models_material_pbr \
models/models_mesh_generation \
models/models_mesh_picking \
models/models_loading \
models/models_loading_vox \
models/models_loading_gltf \
models/models_orthographic_projection \
models/models_rlgl_solar_system \
models/models_skybox \
models/models_yaw_pitch_roll \
models/models_heightmap \
models/models_waving_cubes \
models/models_magicavoxel_loading
models/models_waving_cubes
SHADERS = \
shaders/shaders_model_shader \
@ -483,6 +486,7 @@ SHADERS = \
shaders/shaders_raymarching \
shaders/shaders_texture_drawing \
shaders/shaders_texture_waves \
shaders/shaders_texture_outline \
shaders/shaders_julia_set \
shaders/shaders_eratosthenes \
shaders/shaders_basic_lighting \

1052
examples/Makefile.Web Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,21 @@
## Building the Examples
The examples assume you have already built the `raylib` library in `../src`.
### With GNU make
- `make` builds all examples
- `make [module]` builds all examples for a particular module (e.g `make core`)
### With Zig
The [Zig](https://ziglang.org/) toolchain can compile `C` and `C++` in addition to `Zig`.
You may find it easier to use than other toolchains, especially when it comes to cross-compiling.
- `zig build` to compile all examples
- `zig build [module]` to compile all examples for a module (e.g. `zig build core`)
- `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`)
## EXAMPLES LIST
### category: core
@ -110,7 +128,7 @@ Examples using raylib models functionality, including models loading/generation
| 72 | [models_cubicmap](models/models_cubicmap.c) | <img src="models/models_cubicmap.png" alt="models_cubicmap" width="200"> | ray | |
| 73 | [models_first_person_maze](models/models_first_person_maze.c) | <img src="models/models_first_person_maze.png" alt="models_first_person_maze" width="200"> | ray | |
| 74 | [models_geometric_shapes](models/models_geometric_shapes.c) | <img src="models/models_geometric_shapes.png" alt="models_geometric_shapes" width="200"> | ray | |
| 75 | [models_material_pbr](models/models_material_pbr.c) | <img src="models/models_material_pbr.png" alt="models_material_pbr" width="200"> | ray | |
| 75 | [...]() | | ray | |
| 76 | [models_mesh_generation](models/models_mesh_generation.c) | <img src="models/models_mesh_generation.png" alt="models_mesh_generation" width="200"> | ray | |
| 77 | [models_mesh_picking](models/models_mesh_picking.c) | <img src="models/models_mesh_picking.png" alt="models_mesh_picking" width="200"> | [Joel Davis](https://github.com/joeld42) | |
| 78 | [models_loading](models/models_loading.c) | <img src="models/models_loading.png" alt="models_loading" width="200"> | ray | |

86
examples/build.zig Normal file
View File

@ -0,0 +1,86 @@
const std = @import("std");
const builtin = @import("builtin");
fn add_module(comptime module: []const u8, b: *std.build.Builder, target: std.zig.CrossTarget) !*std.build.Step {
// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions();
const all = b.step(module, "All " ++ module ++ " examples");
const dir = try std.fs.cwd().openDir(
module,
.{ .iterate = true },
);
var iter = dir.iterate();
while (try iter.next()) |entry| {
if (entry.kind != .File) continue;
const extension_idx = std.mem.lastIndexOf(u8, entry.name, ".c") orelse continue;
const name = entry.name[0..extension_idx];
const path = try std.fs.path.join(b.allocator, &.{ module, entry.name });
// zig's mingw headers do not include pthread.h
if (std.mem.eql(u8, "core_loading_thread", name) and target.getOsTag() == .windows) continue;
const exe = b.addExecutable(name, path);
exe.setTarget(target);
exe.setBuildMode(mode);
exe.linkLibC();
exe.addObjectFile(switch (target.getOsTag()) {
.windows => "../src/raylib.lib",
.linux => "../src/libraylib.a",
else => @panic("Unsupported OS"),
});
exe.addIncludeDir("../src");
exe.addIncludeDir("../src/external");
exe.addIncludeDir("../src/external/glfw/include");
switch (exe.target.toTarget().os.tag) {
.windows => {
exe.linkSystemLibrary("winmm");
exe.linkSystemLibrary("gdi32");
exe.linkSystemLibrary("opengl32");
exe.addIncludeDir("external/glfw/deps/mingw");
},
.linux => {
exe.linkSystemLibrary("GL");
exe.linkSystemLibrary("rt");
exe.linkSystemLibrary("dl");
exe.linkSystemLibrary("m");
exe.linkSystemLibrary("X11");
},
else => {
@panic("Unsupported OS");
},
}
exe.setOutputDir(module);
var run = exe.run();
run.step.dependOn(&b.addInstallArtifact(exe).step);
run.cwd = module;
b.step(name, name).dependOn(&run.step);
all.dependOn(&exe.step);
}
return all;
}
pub fn build(b: *std.build.Builder) !void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b.standardTargetOptions(.{});
const all = b.getInstallStep();
all.dependOn(try add_module("audio", b, target));
all.dependOn(try add_module("core", b, target));
all.dependOn(try add_module("models", b, target));
all.dependOn(try add_module("others", b, target));
all.dependOn(try add_module("physics", b, target));
all.dependOn(try add_module("shaders", b, target));
all.dependOn(try add_module("shapes", b, target));
all.dependOn(try add_module("text", b, target));
all.dependOn(try add_module("textures", b, target));
}

View File

@ -10,7 +10,7 @@
*
* Example contributed by Chris Camacho (@chriscamacho) and reviewed by Ramon Santamaria (@raysan5)
*
* Copyright (c) 2020 Chris Camacho (@chriscamacho) and Ramon Santamaria (@raysan5)
* Copyright (c) 2020-2021 Chris Camacho (@chriscamacho) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
@ -32,15 +32,23 @@ int main(void)
camera.target = (Vector3){ 0.0f, 0.0f, 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 mode type
camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
Mesh mesh = GenMeshCylinder(0.2f, 1.0f, 32);
Model model = LoadModelFromMesh(mesh);
// Load a cylinder model for testing
Model model = LoadModelFromMesh(GenMeshCylinder(0.2f, 1.0f, 32));
// Some required variables
// Generic quaternion for operations
Quaternion q1 = { 0 };
Matrix m1 = { 0 }, m2 = { 0 }, m3 = { 0 }, m4 = { 0 };
Vector3 v1 = { 0 }, v2 = { 0 };
// Transform matrices required to draw 4 cylinders
Matrix m1 = { 0 };
Matrix m2 = { 0 };
Matrix m3 = { 0 };
Matrix m4 = { 0 };
// Generic vectors for rotations
Vector3 v1 = { 0 };
Vector3 v2 = { 0 };
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@ -50,6 +58,10 @@ int main(void)
{
// Update
//--------------------------------------------------------------------------------------
if (v2.x < 0) v2.x += PI*2;
if (v2.y < 0) v2.y += PI*2;
if (v2.z < 0) v2.z += PI*2;
if (!IsKeyDown(KEY_SPACE))
{
v1.x += 0.01f;
@ -68,7 +80,7 @@ int main(void)
q1 = QuaternionFromMatrix(m1);
m3 = QuaternionToMatrix(q1);
v2 = QuaternionToEuler(q1);
v2 = QuaternionToEuler(q1); // Angles returned in radians
m4 = MatrixRotateZYX(v2);
//--------------------------------------------------------------------------------------
@ -83,10 +95,13 @@ int main(void)
model.transform = m1;
DrawModel(model, (Vector3){ -1, 0, 0 }, 1.0f, RED);
model.transform = m2;
DrawModel(model, (Vector3){ 1, 0, 0 }, 1.0f, RED);
model.transform = m3;
DrawModel(model, (Vector3){ 0, 0, 0 }, 1.0f, RED);
model.transform = m4;
DrawModel(model, (Vector3){ 0, 0, -1 }, 1.0f, RED);
@ -94,23 +109,13 @@ int main(void)
EndMode3D();
if (v2.x < 0) v2.x += PI*2;
if (v2.y < 0) v2.y += PI*2;
if (v2.z < 0) v2.z += PI*2;
DrawText(TextFormat("%2.3f", v1.x), 20, 20, 20, (v1.x == v2.x)? GREEN: BLACK);
DrawText(TextFormat("%2.3f", v1.y), 20, 40, 20, (v1.y == v2.y)? GREEN: BLACK);
DrawText(TextFormat("%2.3f", v1.z), 20, 60, 20, (v1.z == v2.z)? GREEN: BLACK);
Color cx,cy,cz;
cx = cy = cz = BLACK;
if (v1.x == v2.x) cx = GREEN;
if (v1.y == v2.y) cy = GREEN;
if (v1.z == v2.z) cz = GREEN;
DrawText(TextFormat("%2.3f", v1.x), 20, 20, 20, cx);
DrawText(TextFormat("%2.3f", v1.y), 20, 40, 20, cy);
DrawText(TextFormat("%2.3f", v1.z), 20, 60, 20, cz);
DrawText(TextFormat("%2.3f", v2.x), 200, 20, 20, cx);
DrawText(TextFormat("%2.3f", v2.y), 200, 40, 20, cy);
DrawText(TextFormat("%2.3f", v2.z), 200, 60, 20, cz);
DrawText(TextFormat("%2.3f", v2.x), 200, 20, 20, (v1.x == v2.x)? GREEN: BLACK);
DrawText(TextFormat("%2.3f", v2.y), 200, 40, 20, (v1.y == v2.y)? GREEN: BLACK);
DrawText(TextFormat("%2.3f", v2.z), 200, 60, 20, (v1.z == v2.z)? GREEN: BLACK);
EndDrawing();
//----------------------------------------------------------------------------------

View File

@ -20,10 +20,12 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [core] example - generate random values");
int framesCounter = 0; // Variable used to count frames
// SetRandomSeed(0xaabbccff); // Set a custom random seed if desired, by default: "time(NULL)"
int randValue = GetRandomValue(-8, 5); // Get a random integer number between -8 and 5 (both included)
int framesCounter = 0; // Variable used to count frames
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------

View File

@ -78,7 +78,6 @@ int main(void)
worldSpaceCamera.target.y = (int)screenSpaceCamera.target.y;
screenSpaceCamera.target.y -= worldSpaceCamera.target.y;
screenSpaceCamera.target.y *= virtualRatio;
//----------------------------------------------------------------------------------
// Draw

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -122,7 +122,7 @@ int main(void)
BeginMode3D(cameraPlayer1);
DrawScene();
EndMode3D();
DrawText("PLAYER1 W/S to move", 0, 0, 20, RED);
DrawText("PLAYER1 W/S to move", 10, 10, 20, RED);
EndTextureMode();
// Draw Player2 view to the render texture
@ -131,7 +131,7 @@ int main(void)
BeginMode3D(cameraPlayer2);
DrawScene();
EndMode3D();
DrawText("PLAYER2 UP/DOWN to move", 0, 0, 20, BLUE);
DrawText("PLAYER2 UP/DOWN to move", 10, 10, 20, BLUE);
EndTextureMode();
// Draw both views render textures to the screen side by side

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -37,17 +37,17 @@ int main(void)
camera.target = (Vector3){ 0.0f, 0.0f, 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 mode type
camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
Model model = LoadModel("resources/guy/guy.iqm"); // Load the animated model mesh and basic data
Texture2D texture = LoadTexture("resources/guy/guytex.png"); // Load model texture and set material
SetMaterialTexture(&model.materials[0], MATERIAL_MAP_DIFFUSE, texture); // Set model material map texture
Model model = LoadModel("resources/models/iqm/guy.iqm"); // Load the animated model mesh and basic data
Texture2D texture = LoadTexture("resources/models/iqm/guytex.png"); // Load model texture and set material
SetMaterialTexture(&model.materials[0], MATERIAL_MAP_DIFFUSE, texture); // Set model material map texture
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
// Load animation data
int animsCount = 0;
ModelAnimation *anims = LoadModelAnimations("resources/guy/guyanim.iqm", &animsCount);
unsigned int animsCount = 0;
ModelAnimation *anims = LoadModelAnimations("resources/models/iqm/guyanim.iqm", &animsCount);
int animFrameCounter = 0;
SetCameraMode(camera, CAMERA_FREE); // Set free camera mode

View File

@ -1,122 +0,0 @@
/*******************************************************************************************
*
* raylib [models] example - Load 3d gltf model with animations and play them
*
* This example has been created using raylib 3.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Example contributed by Hristo Stamenov (@object71) and reviewed by Ramon Santamaria (@raysan5)
*
* Copyright (c) 2021 Hristo Stamenov (@object71) and Ramon Santamaria (@raysan5)
*
********************************************************************************************
*
* To export a model from blender, make sure it is not posed, the vertices need to be in the
* same position as they would be in edit mode.
* and that the scale of your models is set to 0. Scaling can be done from the export menu.
*
********************************************************************************************/
#include "raylib.h"
#include <stdlib.h>
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [models] example - model animation");
// Define the camera to look into our 3d world
Camera camera = { 0 };
camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
camera.target = (Vector3){ 0.0f, 0.0f, 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 mode type
Model model = LoadModel("resources/gltf/rigged_figure.glb"); // Load the animated model mesh and
// basic data
// Texture2D texture = LoadTexture("resources/guy/guytex.png"); // Load model texture and set material
// SetMaterialTexture(&model.materials[0], MAP_DIFFUSE, texture); // Set model material map texture
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
// Load animation data
int animsCount = 0;
ModelAnimation *anims = LoadModelAnimations("resources/gltf/rigged_figure.glb", &animsCount);
int animFrameCounter = 0;
int animationDirection = 1;
SetCameraMode(camera, CAMERA_FREE); // Set free camera mode
SetTargetFPS(30); // 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);
// Play animation when spacebar is held down
if (IsKeyDown(KEY_SPACE))
{
animFrameCounter += animationDirection;
if (animFrameCounter >= anims[0].frameCount || animFrameCounter <= 0)
{
animationDirection *= -1;
animFrameCounter += animationDirection;
}
UpdateModelAnimation(model, anims[0], animFrameCounter);
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
BeginMode3D(camera);
DrawModelEx(model, position, (Vector3){ 1.0f, 0.0f, 0.0f }, -90.0f, (Vector3){ 1.0f, 1.0f, 1.0f }, WHITE);
for (int i = 0; i < model.boneCount; i++)
{
DrawSphere(anims[0].framePoses[animFrameCounter][i].translation, 0.01f, RED);
}
DrawGrid(10, 1.0f); // Draw a grid
EndMode3D();
DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, 10, 20, MAROON);
DrawText("(cc4) Rigged Figure by @Cesium", screenWidth - 200, screenHeight - 20, 10, GRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// UnloadTexture(texture); // Unload texture
// Unload model animations data
for (int i = 0; i < animsCount; i++) UnloadModelAnimation(anims[i]);
RL_FREE(anims);
UnloadModel(model); // Unload model
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@ -4,17 +4,19 @@
*
* raylib supports multiple models file formats:
*
* - OBJ > Text file, must include vertex position-texcoords-normals information,
* if files references some .mtl materials file, it will be loaded (or try to)
* - GLTF > Modern text/binary file format, includes lot of information and it could
* also reference external files, raylib will try loading mesh and materials data
* - IQM > Binary file format including mesh vertex data but also animation data,
* raylib can load .iqm animations.
* - OBJ > Text file format. Must include vertex position-texcoords-normals information,
* if files references some .mtl materials file, it will be loaded (or try to).
* - GLTF > Text/binary file format. Includes lot of information and it could
* also reference external files, raylib will try loading mesh and materials data.
* - IQM > Binary file format. Includes mesh vertex data but also animation data,
* raylib can load .iqm animations.
* - VOX > Binary file format. MagikaVoxel mesh format:
* https://github.com/ephtracy/voxel-model/blob/master/MagicaVoxel-file-format-vox.txt
*
* This example has been created using raylib 2.6 (www.raylib.com)
* This example has been created using raylib 4.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
* Copyright (c) 2014-2021 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
@ -37,13 +39,13 @@ int main(void)
camera.fovy = 45.0f; // Camera field-of-view Y
camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
Model model = LoadModel("resources/models/castle.obj"); // Load model
Texture2D texture = LoadTexture("resources/models/castle_diffuse.png"); // Load model texture
model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture
Model model = LoadModel("resources/models/obj/castle.obj"); // Load model
Texture2D texture = LoadTexture("resources/models/obj/castle_diffuse.png"); // Load model texture
model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
BoundingBox bounds = GetMeshBoundingBox(model.meshes[0]); // Set model bounds
BoundingBox bounds = GetMeshBoundingBox(model.meshes[0]); // Set model bounds
// NOTE: bounds are calculated from the original size of the model,
// if model is scaled on drawing, bounds must be also scaled

View File

@ -1,27 +1,24 @@
/*******************************************************************************************
*
* raylib [models] example - Load 3d gltf model
* raylib [models] example - Load models gltf
*
* This example has been created using raylib 3.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* NOTE: To export a model from Blender, make sure it is not posed, the vertices need to be
* in the same position as they would be in edit mode.
* Also make sure the scale parameter of your models is set to 0.0,
* scaling can be applied from the export menu.
*
* Example contributed by Hristo Stamenov (@object71) and reviewed by Ramon Santamaria (@raysan5)
*
* Copyright (c) 2021 Hristo Stamenov (@object71) and Ramon Santamaria (@raysan5)
*
********************************************************************************************
*
* To export a model from blender, make sure it is not posed, the vertices need to be in the
* same position as they would be in edit mode.
* and that the scale of your models is set to 0. Scaling can be done from the export menu.
*
********************************************************************************************/
#include "raylib.h"
#include <stdlib.h>
#define MAX_MODELS 8
#define MAX_GLTF_MODELS 8
int main(void)
{
@ -40,16 +37,16 @@ int main(void)
camera.fovy = 45.0f; // Camera field-of-view Y
camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
Model model[MAX_MODELS] = { 0 };
model[0] = LoadModel("resources/gltf/raylib_32x32.glb");
model[1] = LoadModel("resources/gltf/rigged_figure.glb");
model[2] = LoadModel("resources/gltf/GearboxAssy.glb");
model[3] = LoadModel("resources/gltf/BoxAnimated.glb");
model[4] = LoadModel("resources/gltf/AnimatedTriangle.gltf");
model[5] = LoadModel("resources/gltf/AnimatedMorphCube.glb");
model[6] = LoadModel("resources/gltf/vertex_colored_object.glb");
model[7] = LoadModel("resources/gltf/girl.glb");
// Load some models
Model model[MAX_GLTF_MODELS] = { 0 };
model[0] = LoadModel("resources/models/gltf/raylib_32x32.glb");
model[1] = LoadModel("resources/models/gltf/rigged_figure.glb");
model[2] = LoadModel("resources/models/gltf/GearboxAssy.glb");
model[3] = LoadModel("resources/models/gltf/BoxAnimated.glb");
model[4] = LoadModel("resources/models/gltf/AnimatedTriangle.gltf");
model[5] = LoadModel("resources/models/gltf/AnimatedMorphCube.glb");
model[6] = LoadModel("resources/models/gltf/vertex_colored_object.glb");
model[7] = LoadModel("resources/models/gltf/girl.glb");
int currentModel = 0;
@ -65,19 +62,20 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&camera);
UpdateCamera(&camera); // Update our camera with inputs
if (IsKeyReleased(KEY_RIGHT))
{
currentModel++;
if (currentModel == MAX_MODELS) currentModel = 0;
if (currentModel == MAX_GLTF_MODELS) currentModel = 0;
}
if (IsKeyReleased(KEY_LEFT))
{
currentModel--;
if (currentModel < 0) currentModel = MAX_MODELS - 1;
if (currentModel < 0) currentModel = MAX_GLTF_MODELS - 1;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
@ -87,8 +85,7 @@ int main(void)
BeginMode3D(camera);
DrawModelEx(model[currentModel], position, (Vector3){ 0.0f, 1.0f, 0.0f }, 180.0f, (Vector3){ 2.0f, 2.0f, 2.0f }, WHITE);
DrawModel(model[currentModel], position, 1.0f, WHITE);
DrawGrid(10, 1.0f); // Draw a grid
EndMode3D();
@ -99,7 +96,7 @@ int main(void)
// De-Initialization
//--------------------------------------------------------------------------------------
for (int i = 0; i < MAX_MODELS; i++) UnloadModel(model[i]); // Unload models
for (int i = 0; i < MAX_GLTF_MODELS; i++) UnloadModel(model[i]); // Unload models
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,130 @@
/*******************************************************************************************
*
* raylib [models] example - Load models vox (MagicaVoxel)
*
* This example has been created using raylib 4.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Example contributed by Johann Nadalutti (@procfxgen) and reviewed by Ramon Santamaria (@raysan5)
*
* Copyright (c) 2021 Johann Nadalutti (@procfxgen) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h" // Required for: MatrixTranslate()
#define MAX_VOX_FILES 3
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
const char *voxFileNames[] = {
"resources/models/vox/chr_knight.vox",
"resources/models/vox/chr_sword.vox",
"resources/models/vox/monu9.vox"
};
InitWindow(screenWidth, screenHeight, "raylib [models] example - magicavoxel loading");
// Define the camera to look into our 3d world
Camera camera = { 0 };
camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
camera.target = (Vector3){ 0.0f, 0.0f, 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 mode type
// Load MagicaVoxel files
Model models[MAX_VOX_FILES] = { 0 };
for (int i = 0; i < MAX_VOX_FILES; i++)
{
// Load VOX file and measure time
double t0 = GetTime()*1000.0;
models[i] = LoadModel(voxFileNames[i]);
double t1 = GetTime()*1000.0;
TraceLog(LOG_WARNING, TextFormat("[%s] File loaded in %.3f ms", voxFileNames[i], t1 - t0));
// Compute model translation matrix to center model on draw position (0, 0 , 0)
BoundingBox bb = GetModelBoundingBox(models[i]);
Vector3 center = { 0 };
center.x = bb.min.x + (((bb.max.x - bb.min.x)/2));
center.z = bb.min.z + (((bb.max.z - bb.min.z)/2));
Matrix matTranslate = MatrixTranslate(-center.x, 0, -center.z);
models[i].transform = matTranslate;
}
int currentModel = 0;
SetCameraMode(camera, CAMERA_ORBITAL); // Set a orbital camera mode
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); // Update our camera to orbit
// Cycle between models on mouse click
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1)%MAX_VOX_FILES;
// Cycle between models on key pressed
if (IsKeyPressed(KEY_RIGHT))
{
currentModel++;
if (currentModel >= MAX_VOX_FILES) currentModel = 0;
}
else if (IsKeyPressed(KEY_LEFT))
{
currentModel--;
if (currentModel < 0) currentModel = MAX_VOX_FILES - 1;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw 3D model
BeginMode3D(camera);
DrawModel(models[currentModel], (Vector3){ 0, 0, 0 }, 1.0f, WHITE);
DrawGrid(10, 1.0);
EndMode3D();
// Display info
DrawRectangle(10, 400, 310, 30, Fade(SKYBLUE, 0.5f));
DrawRectangleLines(10, 400, 310, 30, Fade(DARKBLUE, 0.5f));
DrawText("MOUSE LEFT BUTTON to CYCLE VOX MODELS", 40, 410, 10, BLUE);
DrawText(TextFormat("File: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// Unload models data (GPU VRAM)
for (int i = 0; i < MAX_VOX_FILES; i++) UnloadModel(models[i]);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -1,151 +0,0 @@
/*******************************************************************************************
*
* raylib [models] example - magicavoxel loader and viewer
*
* This example has been created using raylib 3.8 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Example contributed by Johann Nadalutti
*
* Copyright (c) 2021 Johann Nadalutti
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
#include <string.h>
// VOX Files to load and view
#define NUM_VOX_FILES 3
const char* szVoxFiles[] = {
"resources/vox/chr_knight.vox",
"resources/vox/chr_sword.vox",
"resources/vox/monu9.vox"
};
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [models] example - magicavoxel loading");
// Load MagicaVoxel files
Model models[NUM_VOX_FILES] = { 0 };
for (int i = 0; i < NUM_VOX_FILES; i++)
{
// Load MagicaVoxel File and build model
double t0, t1;
t0 = GetTime() * 1000.0;
models[i] = LoadModel(szVoxFiles[i]);
t1 = GetTime() * 1000.0;
TraceLog(LOG_INFO, TextFormat("Vox <%s> loaded in %f ms", GetFileName(szVoxFiles[i]), t1 - t0));
//Compute model's center matrix
BoundingBox bb = GetModelBoundingBox(models[i]);
Vector3 center;
center.x = bb.min.x + (((bb.max.x - bb.min.x) / 2));
center.z = bb.min.z + (((bb.max.z - bb.min.z) / 2));
Matrix matP = MatrixTranslate(-center.x, 0, -center.z);
models[i].transform = matP;
}
// Define the camera to look into our 3d world
Camera camera = { { 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
// Model drawing position
Vector3 position = { 0.0f, 0.0f, 0.0f };
int currentModel = 0;
SetCameraMode(camera, CAMERA_ORBITAL); // Set a orbital camera mode
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); // Update internal camera and our camera
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
{
currentModel = (currentModel + 1) % NUM_VOX_FILES; // Cycle between models
}
if (IsKeyPressed(KEY_RIGHT))
{
currentModel++;
if (currentModel >= NUM_VOX_FILES) currentModel = 0;
}
else if (IsKeyPressed(KEY_LEFT))
{
currentModel--;
if (currentModel < 0) currentModel = NUM_VOX_FILES - 1;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
//Display model
BeginMode3D(camera);
Vector3 rotAxis = { 1,0,0 };
Vector3 scale = { 1,1,1 };
DrawModelEx(models[currentModel], position, rotAxis, 0, scale, WHITE);
//DrawModelWiresEx(models[currentModel], position, rotAxis, -90.0f, scale, BLACK);
DrawGrid(10, 1.0);
EndMode3D();
//Display debug infos
DrawRectangle(30, 400, 310, 30, Fade(SKYBLUE, 0.5f));
DrawRectangleLines(30, 400, 310, 30, Fade(DARKBLUE, 0.5f));
DrawText("MOUSE LEFT BUTTON to CYCLE VOX MODELS", 40, 410, 10, BLUE);
DrawText(GetFileName(szVoxFiles[currentModel]), 100, 10, 20, DARKBLUE);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// Unload models data (GPU VRAM)
for (int i = 0; i < NUM_VOX_FILES; i++) UnloadModel(models[i]);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@ -1,543 +0,0 @@
/*******************************************************************************************
*
* raylib [models] example - PBR material
*
* NOTE: This example requires raylib OpenGL 3.3 for shaders support and only #version 330
* is currently supported. OpenGL ES 2.0 platforms are not supported at the moment.
*
* This example has been created using raylib 1.8 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2017 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
#include "rlgl.h"
#include <stdio.h>
#define RLIGHTS_IMPLEMENTATION
#include "rlights.h"
#if defined(PLATFORM_DESKTOP)
#define GLSL_VERSION 330
#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
#define GLSL_VERSION 100
#endif
#define CUBEMAP_SIZE 1024 // Cubemap texture size
#define IRRADIANCE_SIZE 32 // Irradiance texture size
#define PREFILTERED_SIZE 256 // Prefiltered HDR environment texture size
#define BRDF_SIZE 512 // BRDF LUT texture size
#define LIGHT_DISTANCE 1000.0f
#define LIGHT_HEIGHT 1.0f
// PBR texture maps generation
static TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, int format); // Generate cubemap (6 faces) from equirectangular (panorama) texture
static TextureCubemap GenTextureIrradiance(Shader shader, TextureCubemap cubemap, int size); // Generate irradiance cubemap using cubemap texture
static TextureCubemap GenTexturePrefilter(Shader shader, TextureCubemap cubemap, int size); // Generate prefilter cubemap using cubemap texture
static Texture2D GenTextureBRDF(Shader shader, int size); // Generate a generic BRDF texture
// PBR material loading
static Material LoadMaterialPBR(Color albedo, float metalness, float roughness);
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
SetConfigFlags(FLAG_MSAA_4X_HINT); // Enable Multi Sampling Anti Aliasing 4x (if available)
InitWindow(screenWidth, screenHeight, "raylib [models] example - pbr material");
// Define the camera to look into our 3d world
Camera camera = { 0 };
camera.position = (Vector3){ 4.0f, 4.0f, 4.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 mode type
// Load model and PBR material
Model model = LoadModel("resources/pbr/trooper.obj");
// Mesh tangents are generated... and uploaded to GPU
// NOTE: New VBO for tangents is generated at default location and also binded to mesh VAO
//MeshTangents(&model.meshes[0]);
model.materials[0] = LoadMaterialPBR((Color){ 255, 255, 255, 255 }, 1.0f, 1.0f);
// Create lights
// NOTE: Lights are added to an internal lights pool automatically
CreateLight(LIGHT_POINT, (Vector3){ LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 0, 255 }, model.materials[0].shader);
CreateLight(LIGHT_POINT, (Vector3){ 0.0f, LIGHT_HEIGHT, LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 255, 0, 255 }, model.materials[0].shader);
CreateLight(LIGHT_POINT, (Vector3){ -LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 0, 255, 255 }, model.materials[0].shader);
CreateLight(LIGHT_DIRECTIONAL, (Vector3){ 0.0f, LIGHT_HEIGHT*2.0f, -LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 255, 255 }, model.materials[0].shader);
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
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); // Update camera
// Send to material PBR shader camera view position
float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z };
SetShaderValue(model.materials[0].shader, model.materials[0].shader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
BeginMode3D(camera);
DrawModel(model, Vector3Zero(), 1.0f, WHITE);
DrawGrid(10, 1.0f);
EndMode3D();
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadMaterial(model.materials[0]); // Unload material: shader and textures
UnloadModel(model); // Unload model
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
// Load PBR material (Supports: ALBEDO, NORMAL, METALNESS, ROUGHNESS, AO, EMMISIVE, HEIGHT maps)
// NOTE: PBR shader is loaded inside this function
static Material LoadMaterialPBR(Color albedo, float metalness, float roughness)
{
Material mat = LoadMaterialDefault(); // Initialize material to default
// Load PBR shader (requires several maps)
mat.shader = LoadShader(TextFormat("resources/shaders/glsl%i/pbr.vs", GLSL_VERSION),
TextFormat("resources/shaders/glsl%i/pbr.fs", GLSL_VERSION));
// Get required locations points for PBR material
// NOTE: Those location names must be available and used in the shader code
mat.shader.locs[SHADER_LOC_MAP_ALBEDO] = GetShaderLocation(mat.shader, "albedo.sampler");
mat.shader.locs[SHADER_LOC_MAP_METALNESS] = GetShaderLocation(mat.shader, "metalness.sampler");
mat.shader.locs[SHADER_LOC_MAP_NORMAL] = GetShaderLocation(mat.shader, "normals.sampler");
mat.shader.locs[SHADER_LOC_MAP_ROUGHNESS] = GetShaderLocation(mat.shader, "roughness.sampler");
mat.shader.locs[SHADER_LOC_MAP_OCCLUSION] = GetShaderLocation(mat.shader, "occlusion.sampler");
//mat.shader.locs[SHADER_LOC_MAP_EMISSION] = GetShaderLocation(mat.shader, "emission.sampler");
//mat.shader.locs[SHADER_LOC_MAP_HEIGHT] = GetShaderLocation(mat.shader, "height.sampler");
mat.shader.locs[SHADER_LOC_MAP_IRRADIANCE] = GetShaderLocation(mat.shader, "irradianceMap");
mat.shader.locs[SHADER_LOC_MAP_PREFILTER] = GetShaderLocation(mat.shader, "prefilterMap");
mat.shader.locs[SHADER_LOC_MAP_BRDF] = GetShaderLocation(mat.shader, "brdfLUT");
// Set view matrix location
mat.shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(mat.shader, "matModel");
//mat.shader.locs[SHADER_LOC_MATRIX_VIEW] = GetShaderLocation(mat.shader, "view");
mat.shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(mat.shader, "viewPos");
// Set PBR standard maps
mat.maps[MATERIAL_MAP_ALBEDO].texture = LoadTexture("resources/pbr/trooper_albedo.png");
mat.maps[MATERIAL_MAP_NORMAL].texture = LoadTexture("resources/pbr/trooper_normals.png");
mat.maps[MATERIAL_MAP_METALNESS].texture = LoadTexture("resources/pbr/trooper_metalness.png");
mat.maps[MATERIAL_MAP_ROUGHNESS].texture = LoadTexture("resources/pbr/trooper_roughness.png");
mat.maps[MATERIAL_MAP_OCCLUSION].texture = LoadTexture("resources/pbr/trooper_ao.png");
// Set textures filtering for better quality
SetTextureFilter(mat.maps[MATERIAL_MAP_ALBEDO].texture, TEXTURE_FILTER_BILINEAR);
SetTextureFilter(mat.maps[MATERIAL_MAP_NORMAL].texture, TEXTURE_FILTER_BILINEAR);
SetTextureFilter(mat.maps[MATERIAL_MAP_METALNESS].texture, TEXTURE_FILTER_BILINEAR);
SetTextureFilter(mat.maps[MATERIAL_MAP_ROUGHNESS].texture, TEXTURE_FILTER_BILINEAR);
SetTextureFilter(mat.maps[MATERIAL_MAP_OCCLUSION].texture, TEXTURE_FILTER_BILINEAR);
// Enable sample usage in shader for assigned textures
SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "albedo.useSampler"), (int[1]){ 1 }, SHADER_UNIFORM_INT);
SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "normals.useSampler"), (int[1]){ 1 }, SHADER_UNIFORM_INT);
SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "metalness.useSampler"), (int[1]){ 1 }, SHADER_UNIFORM_INT);
SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "roughness.useSampler"), (int[1]){ 1 }, SHADER_UNIFORM_INT);
SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "occlusion.useSampler"), (int[1]){ 1 }, SHADER_UNIFORM_INT);
int renderModeLoc = GetShaderLocation(mat.shader, "renderMode");
SetShaderValue(mat.shader, renderModeLoc, (int[1]){ 0 }, SHADER_UNIFORM_INT);
// Set up material properties color
mat.maps[MATERIAL_MAP_ALBEDO].color = albedo;
mat.maps[MATERIAL_MAP_NORMAL].color = (Color){ 128, 128, 255, 255 };
mat.maps[MATERIAL_MAP_METALNESS].value = metalness;
mat.maps[MATERIAL_MAP_ROUGHNESS].value = roughness;
mat.maps[MATERIAL_MAP_OCCLUSION].value = 1.0f;
mat.maps[MATERIAL_MAP_EMISSION].value = 0.5f;
mat.maps[MATERIAL_MAP_HEIGHT].value = 0.5f;
// Generate cubemap from panorama texture
//--------------------------------------------------------------------------------------------------------
Texture2D panorama = LoadTexture("resources/dresden_square_2k.hdr");
// Load equirectangular to cubemap shader
Shader shdrCubemap = LoadShader(TextFormat("resources/shaders/glsl%i/pbr.vs", GLSL_VERSION),
TextFormat("resources/shaders/glsl%i/pbr.fs", GLSL_VERSION));
SetShaderValue(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, SHADER_UNIFORM_INT);
TextureCubemap cubemap = GenTextureCubemap(shdrCubemap, panorama, CUBEMAP_SIZE, PIXELFORMAT_UNCOMPRESSED_R32G32B32);
UnloadTexture(panorama);
UnloadShader(shdrCubemap);
//--------------------------------------------------------------------------------------------------------
// Generate irradiance map from cubemap texture
//--------------------------------------------------------------------------------------------------------
// Load irradiance (GI) calculation shader
Shader shdrIrradiance = LoadShader(TextFormat("resources/shaders/glsl%i/skybox.vs", GLSL_VERSION),
TextFormat("resources/shaders/glsl%i/irradiance.fs", GLSL_VERSION));
SetShaderValue(shdrIrradiance, GetShaderLocation(shdrIrradiance, "environmentMap"), (int[1]){ 0 }, SHADER_UNIFORM_INT);
mat.maps[MATERIAL_MAP_IRRADIANCE].texture = GenTextureIrradiance(shdrIrradiance, cubemap, IRRADIANCE_SIZE);
UnloadShader(shdrIrradiance);
//--------------------------------------------------------------------------------------------------------
// Generate prefilter map from cubemap texture
//--------------------------------------------------------------------------------------------------------
// Load reflection prefilter calculation shader
Shader shdrPrefilter = LoadShader(TextFormat("resources/shaders/glsl%i/skybox.vs", GLSL_VERSION),
TextFormat("resources/shaders/glsl%i/prefilter.fs", GLSL_VERSION));
SetShaderValue(shdrPrefilter, GetShaderLocation(shdrPrefilter, "environmentMap"), (int[1]){ 0 }, SHADER_UNIFORM_INT);
mat.maps[MATERIAL_MAP_PREFILTER].texture = GenTexturePrefilter(shdrPrefilter, cubemap, PREFILTERED_SIZE);
UnloadTexture(cubemap);
UnloadShader(shdrPrefilter);
//--------------------------------------------------------------------------------------------------------
// Generate BRDF (bidirectional reflectance distribution function) texture (using shader)
//--------------------------------------------------------------------------------------------------------
Shader shdrBRDF = LoadShader(TextFormat("resources/shaders/glsl%i/brdf.vs", GLSL_VERSION),
TextFormat("resources/shaders/glsl%i/brdf.fs", GLSL_VERSION));
mat.maps[MATERIAL_MAP_BRDF].texture = GenTextureBRDF(shdrBRDF, BRDF_SIZE);
UnloadShader(shdrBRDF);
//--------------------------------------------------------------------------------------------------------
return mat;
}
// Texture maps generation (PBR)
//-------------------------------------------------------------------------------------------
// Generate cubemap texture from HDR texture
static TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, int format)
{
TextureCubemap cubemap = { 0 };
rlDisableBackfaceCulling(); // Disable backface culling to render inside the cube
// STEP 1: Setup framebuffer
//------------------------------------------------------------------------------------------
unsigned int rbo = rlLoadTextureDepth(size, size, true);
cubemap.id = rlLoadTextureCubemap(NULL, size, format);
unsigned int fbo = rlLoadFramebuffer(size, size);
rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0);
rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X, 0);
// Check if framebuffer is complete with attachments (valid)
if (rlFramebufferComplete(fbo)) TraceLog(LOG_INFO, "FBO: [ID %i] Framebuffer object created successfully", fbo);
//------------------------------------------------------------------------------------------
// STEP 2: Draw to framebuffer
//------------------------------------------------------------------------------------------
// NOTE: Shader is used to convert HDR equirectangular environment map to cubemap equivalent (6 faces)
rlEnableShader(shader.id);
// Define projection matrix and send it to shader
Matrix matFboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR);
rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_PROJECTION], matFboProjection);
// Define view matrix for every side of the cubemap
Matrix fboViews[6] = {
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ -1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f })
};
rlViewport(0, 0, size, size); // Set viewport to current fbo dimensions
// Activate and enable texture for drawing to cubemap faces
rlActiveTextureSlot(0);
rlEnableTexture(panorama.id);
for (int i = 0; i < 6; i++)
{
// Set the view matrix for the current cube face
rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_VIEW], fboViews[i]);
// Select the current cubemap face attachment for the fbo
// WARNING: This function by default enables->attach->disables fbo!!!
rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X + i, 0);
rlEnableFramebuffer(fbo);
// Load and draw a cube, it uses the current enabled texture
rlClearScreenBuffers();
rlLoadDrawCube();
// ALTERNATIVE: Try to use internal batch system to draw the cube instead of rlLoadDrawCube
// for some reason this method does not work, maybe due to cube triangles definition? normals pointing out?
// TODO: Investigate this issue...
//rlSetTexture(panorama.id); // WARNING: It must be called after enabling current framebuffer if using internal batch system!
//rlClearScreenBuffers();
//DrawCubeV(Vector3Zero(), Vector3One(), WHITE);
//rlDrawRenderBatchActive();
}
//------------------------------------------------------------------------------------------
// STEP 3: Unload framebuffer and reset state
//------------------------------------------------------------------------------------------
rlDisableShader(); // Unbind shader
rlDisableTexture(); // Unbind texture
rlDisableFramebuffer(); // Unbind framebuffer
rlUnloadFramebuffer(fbo); // Unload framebuffer (and automatically attached depth texture/renderbuffer)
// Reset viewport dimensions to default
rlViewport(0, 0, rlGetFramebufferWidth(), rlGetFramebufferHeight());
rlEnableBackfaceCulling();
//------------------------------------------------------------------------------------------
cubemap.width = size;
cubemap.height = size;
cubemap.mipmaps = 1;
cubemap.format = PIXELFORMAT_UNCOMPRESSED_R32G32B32;
return cubemap;
}
// Generate irradiance texture using cubemap data
static TextureCubemap GenTextureIrradiance(Shader shader, TextureCubemap cubemap, int size)
{
TextureCubemap irradiance = { 0 };
rlDisableBackfaceCulling(); // Disable backface culling to render inside the cube
// STEP 1: Setup framebuffer
//------------------------------------------------------------------------------------------
unsigned int rbo = rlLoadTextureDepth(size, size, true);
irradiance.id = rlLoadTextureCubemap(NULL, size, PIXELFORMAT_UNCOMPRESSED_R32G32B32);
unsigned int fbo = rlLoadFramebuffer(size, size);
rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0);
rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X, 0);
//------------------------------------------------------------------------------------------
// STEP 2: Draw to framebuffer
//------------------------------------------------------------------------------------------
// NOTE: Shader is used to solve diffuse integral by convolution to create an irradiance cubemap
rlEnableShader(shader.id);
// Define projection matrix and send it to shader
Matrix matFboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR);
rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_PROJECTION], matFboProjection);
// Define view matrix for every side of the cubemap
Matrix fboViews[6] = {
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ -1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f })
};
rlActiveTextureSlot(0);
rlEnableTextureCubemap(cubemap.id);
rlViewport(0, 0, size, size); // Set viewport to current fbo dimensions
for (int i = 0; i < 6; i++)
{
rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_VIEW], fboViews[i]);
rlFramebufferAttach(fbo, irradiance.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X + i, 0);
rlEnableFramebuffer(fbo);
rlClearScreenBuffers();
rlLoadDrawCube();
}
//------------------------------------------------------------------------------------------
// STEP 3: Unload framebuffer and reset state
//------------------------------------------------------------------------------------------
rlDisableShader(); // Unbind shader
rlDisableTexture(); // Unbind texture
rlDisableFramebuffer(); // Unbind framebuffer
rlUnloadFramebuffer(fbo); // Unload framebuffer (and automatically attached depth texture/renderbuffer)
// Reset viewport dimensions to default
rlViewport(0, 0, rlGetFramebufferWidth(), rlGetFramebufferHeight());
rlEnableBackfaceCulling();
//------------------------------------------------------------------------------------------
irradiance.width = size;
irradiance.height = size;
irradiance.mipmaps = 1;
irradiance.format = PIXELFORMAT_UNCOMPRESSED_R32G32B32;
return irradiance;
}
// Generate prefilter texture using cubemap data
static TextureCubemap GenTexturePrefilter(Shader shader, TextureCubemap cubemap, int size)
{
TextureCubemap prefilter = { 0 };
rlDisableBackfaceCulling(); // Disable backface culling to render inside the cube
// STEP 1: Setup framebuffer
//------------------------------------------------------------------------------------------
unsigned int rbo = rlLoadTextureDepth(size, size, true);
prefilter.id = rlLoadTextureCubemap(NULL, size, PIXELFORMAT_UNCOMPRESSED_R32G32B32);
rlTextureParameters(prefilter.id, RL_TEXTURE_MIN_FILTER, RL_TEXTURE_FILTER_MIP_LINEAR);
unsigned int fbo = rlLoadFramebuffer(size, size);
rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0);
rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X, 0);
//------------------------------------------------------------------------------------------
// Generate mipmaps for the prefiltered HDR texture
//glGenerateMipmap(GL_TEXTURE_CUBE_MAP); // TODO!
// STEP 2: Draw to framebuffer
//------------------------------------------------------------------------------------------
// NOTE: Shader is used to prefilter HDR and store data into mipmap levels
// Define projection matrix and send it to shader
Matrix fboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR);
rlEnableShader(shader.id);
rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_PROJECTION], fboProjection);
// Define view matrix for every side of the cubemap
Matrix fboViews[6] = {
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ -1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f })
};
rlActiveTextureSlot(0);
rlEnableTextureCubemap(cubemap.id);
// TODO: Locations should be taken out of this function... too shader dependant...
int roughnessLoc = rlGetLocationUniform(shader.id, "roughness");
rlEnableFramebuffer(fbo);
#define MAX_MIPMAP_LEVELS 5 // Max number of prefilter texture mipmaps
for (int mip = 0; mip < MAX_MIPMAP_LEVELS; mip++)
{
// Resize framebuffer according to mip-level size.
unsigned int mipWidth = size*(int)powf(0.5f, (float)mip);
unsigned int mipHeight = size*(int)powf(0.5f, (float)mip);
rlViewport(0, 0, mipWidth, mipHeight);
//glBindRenderbuffer(GL_RENDERBUFFER, rbo);
//glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mipWidth, mipHeight);
float roughness = (float)mip/(float)(MAX_MIPMAP_LEVELS - 1);
rlSetUniform(roughnessLoc, &roughness, SHADER_UNIFORM_FLOAT, 1);
for (int i = 0; i < 6; i++)
{
rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_VIEW], fboViews[i]);
rlFramebufferAttach(fbo, prefilter.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X + i, mip);
rlClearScreenBuffers();
rlLoadDrawCube();
}
}
//------------------------------------------------------------------------------------------
// STEP 3: Unload framebuffer and reset state
//------------------------------------------------------------------------------------------
rlDisableShader(); // Unbind shader
rlDisableTexture(); // Unbind texture
rlDisableFramebuffer(); // Unbind framebuffer
rlUnloadFramebuffer(fbo); // Unload framebuffer (and automatically attached depth texture/renderbuffer)
// Reset viewport dimensions to default
rlViewport(0, 0, rlGetFramebufferWidth(), rlGetFramebufferHeight());
rlEnableBackfaceCulling();
//------------------------------------------------------------------------------------------
prefilter.width = size;
prefilter.height = size;
prefilter.mipmaps = MAX_MIPMAP_LEVELS;
prefilter.format = PIXELFORMAT_UNCOMPRESSED_R32G32B32;
return prefilter;
}
// Generate BRDF texture using cubemap data
// TODO: Review implementation: https://github.com/HectorMF/BRDFGenerator
static Texture2D GenTextureBRDF(Shader shader, int size)
{
Texture2D brdf = { 0 };
// STEP 1: Setup framebuffer
//------------------------------------------------------------------------------------------
unsigned int rbo = rlLoadTextureDepth(size, size, true);
brdf.id = rlLoadTexture(NULL, size, size, PIXELFORMAT_UNCOMPRESSED_R32G32B32, 1);
unsigned int fbo = rlLoadFramebuffer(size, size);
rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER, 0);
rlFramebufferAttach(fbo, brdf.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_TEXTURE2D, 0);
//------------------------------------------------------------------------------------------
// STEP 2: Draw to framebuffer
//------------------------------------------------------------------------------------------
// NOTE: Render BRDF LUT into a quad using FBO
rlEnableShader(shader.id);
rlViewport(0, 0, size, size);
rlEnableFramebuffer(fbo);
rlClearScreenBuffers();
rlLoadDrawQuad();
//------------------------------------------------------------------------------------------
// STEP 3: Unload framebuffer and reset state
//------------------------------------------------------------------------------------------
rlDisableShader(); // Unbind shader
rlDisableTexture(); // Unbind texture
rlDisableFramebuffer(); // Unbind framebuffer
rlUnloadFramebuffer(fbo); // Unload framebuffer (and automatically attached depth texture/renderbuffer)
// Reset viewport dimensions to default
rlViewport(0, 0, rlGetFramebufferWidth(), rlGetFramebufferHeight());
//------------------------------------------------------------------------------------------
brdf.width = size;
brdf.height = size;
brdf.mipmaps = 1;
brdf.format = PIXELFORMAT_UNCOMPRESSED_R32G32B32;
return brdf;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

View File

@ -31,16 +31,16 @@ int main(void)
camera.target = (Vector3){ 0.0f, 8.0f, 0.0f }; // Camera looking at point
camera.up = (Vector3){ 0.0f, 1.6f, 0.0f }; // Camera up vector (rotation towards target)
camera.fovy = 45.0f; // Camera field-of-view Y
camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
Ray ray = { 0 }; // Picking ray
Model tower = LoadModel("resources/models/turret.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/models/turret_diffuse.png"); // Load model texture
tower.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set model diffuse texture
Model tower = LoadModel("resources/models/obj/turret.obj"); // Load OBJ model
Texture2D texture = LoadTexture("resources/models/obj/turret_diffuse.png"); // Load model texture
tower.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set model diffuse texture
Vector3 towerPos = { 0.0f, 0.0f, 0.0f }; // Set model position
BoundingBox towerBBox = GetMeshBoundingBox(tower.meshes[0]); // Get mesh bounding box
Vector3 towerPos = { 0.0f, 0.0f, 0.0f }; // Set model position
BoundingBox towerBBox = GetMeshBoundingBox(tower.meshes[0]); // Get mesh bounding box
// Ground quad
Vector3 g0 = (Vector3){ -50.0f, 0.0f, -50.0f };

View File

@ -10,8 +10,9 @@
********************************************************************************************/
#include "raylib.h"
#include "rlgl.h"
#include "raymath.h"
#include "raymath.h" // Required for: MatrixPerspective(), MatrixLookAt()
#if defined(PLATFORM_DESKTOP)
#define GLSL_VERSION 330

View File

@ -7,12 +7,13 @@
*
* Example contributed by Berni (@Berni8k) and reviewed by Ramon Santamaria (@raysan5)
*
* Copyright (c) 2017 Berni (@Berni8k) and Ramon Santamaria (@raysan5)
* Copyright (c) 2017-2021 Berni (@Berni8k) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
#include "raymath.h" // Required for: MatrixRotateXYZ()
int main(void)
{
@ -33,7 +34,7 @@ int main(void)
// Model loading
// NOTE: Diffuse map loaded automatically
Model model = LoadModel("resources/plane/plane.gltf");
Model model = LoadModel("resources/models/gltf/plane/plane.gltf");
float pitch = 0.0f;
float roll = 0.0f;
@ -78,7 +79,6 @@ int main(void)
model.transform = MatrixRotateXYZ((Vector3){ DEG2RAD*pitch, DEG2RAD*yaw, DEG2RAD*roll });
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();

View File

@ -1,13 +1,19 @@
| resource | author | licence | notes |
| :------------------- | :---------: | :------ | :---- |
| models/castle.obj,<br> models/castle_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
| models/bridge.obj,<br> models/bridge_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
| models/house.obj,<br> models/house_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
| models/market.obj,<br> models/market_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
| models/turret.obj,<br> models/turret_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
| models/well.obj,<br> models/well_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
| models/cube.obj,<br> models/cube_diffuse.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
| models/vertex_colored_object.iqm | ❔ | ❔ | - |
| models/obj/castle.obj,<br>models/castle_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
| models/obj/bridge.obj,<br>models/bridge_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
| models/obj/house.obj,<br>models/house_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
| models/obj/market.obj,<br>models/market_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
| models/obj/turret.obj,<br>models/turret_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
| models/obj/well.obj,<br>models/well_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
| models/obj/cube.obj,<br>models/cube_diffuse.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
| models/iqm/guy.iqm,<br>models/iqm/guyanim.iqm,<br>models/iqm/guytex.png,<br>models/iqm/guy.blend | [@culacant](https://github.com/culacant) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
| models/iqm/vertex_colored_object.iqm | ❔ | ❔ | - |
| models/gltf/plane/plane.gltf,<br>models/gltf/plane/plane.bin,<br>models/gltf/plane/plane_diffuse.png | [GiaHanLam](https://sketchfab.com/GiaHanLam) | [CC-BY](https://creativecommons.org/licenses/by/4.0/) | Used by: [`models_yaw_pitch_roll.c`](https://github.com/raysan5/raylib/blob/master/examples/models/models_yaw_pitch_roll.c)
| models/gltf/... | _various_ | Check [LICENSE](https://github.com/raysan5/raylib/blob/master/examples/models/resources/models/gltf/LICENSE) | - |
| models/vox/chr_knight.vox | ❔ | ❔ | - |
| models/vox/chr_sword.vox | ❔ | ❔ | - |
| models/vox/monu9.vox | ❔ | ❔ | - |
| billboard.png | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
| cubicmap.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
| cubicmap_atlas.png | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
@ -15,6 +21,3 @@
| dresden_square_1k.hdr | [HDRIHaven](https://hdrihaven.com/hdri/?h=dresden_square) | [CC0](https://hdrihaven.com/p/license.php) | - |
| dresden_square_2k.hdr | [HDRIHaven](https://hdrihaven.com/hdri/?h=dresden_square) | [CC0](https://hdrihaven.com/p/license.php) | - |
| skybox.png | ❔ | ❔ | - |
| **guy/...** | [@culacant](https://github.com/culacant) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) |
| **plane/...** | [GiaHanLam](https://sketchfab.com/GiaHanLam) | [CC-BY](https://creativecommons.org/licenses/by/4.0/) | Used by: [`models_yaw_pitch_roll.c`](https://github.com/raysan5/raylib/blob/master/examples/models/models_yaw_pitch_roll.c)
| **gltf/...** | _various_ | [LICENSE](https://github.com/raysan5/raylib/blob/master/examples/models/resources/gltf/LICENSE) | - |

View File

Before

Width:  |  Height:  |  Size: 804 KiB

After

Width:  |  Height:  |  Size: 804 KiB

View File

Before

Width:  |  Height:  |  Size: 295 KiB

After

Width:  |  Height:  |  Size: 295 KiB

View File

Before

Width:  |  Height:  |  Size: 311 KiB

After

Width:  |  Height:  |  Size: 311 KiB

View File

Before

Width:  |  Height:  |  Size: 434 KiB

After

Width:  |  Height:  |  Size: 434 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 383 KiB

After

Width:  |  Height:  |  Size: 383 KiB

View File

Before

Width:  |  Height:  |  Size: 380 KiB

After

Width:  |  Height:  |  Size: 380 KiB

View File

Before

Width:  |  Height:  |  Size: 371 KiB

After

Width:  |  Height:  |  Size: 371 KiB

View File

Before

Width:  |  Height:  |  Size: 334 KiB

After

Width:  |  Height:  |  Size: 334 KiB

View File

@ -0,0 +1,9 @@
The following models are provided by the official github repo of voxel-model format by MagikaVoxel developer @ephtracy
GitHub official repo: https://github.com/ephtracy/voxel-model
- chr_knight.vox - https://github.com/ephtracy/voxel-model/blob/master/vox/character/chr_knight.vox
- chr_sword.vox - https://github.com/ephtracy/voxel-model/blob/master/vox/character/chr_sword.vox
- monu9.vox - https://github.com/ephtracy/voxel-model/blob/master/vox/monument/monu9.vox
Worth mentioning there is no license specified for the models yet: https://github.com/ephtracy/voxel-model/issues/22

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 547 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 717 KiB

View File

@ -1,124 +0,0 @@
#version 330
// Input vertex attributes (from vertex shader)
in vec2 fragTexCoord;
// Constant values
const float PI = 3.14159265359;
const uint MAX_SAMPLES = 1024u;
// Output fragment color
out vec4 finalColor;
vec2 Hammersley(uint i, uint N);
float RadicalInverseVdC(uint bits);
float GeometrySchlickGGX(float NdotV, float roughness);
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness);
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness);
vec2 IntegrateBRDF(float NdotV, float roughness);
float RadicalInverseVdC(uint bits)
{
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
}
// Compute Hammersley coordinates
vec2 Hammersley(uint i, uint N)
{
return vec2(float(i)/float(N), RadicalInverseVdC(i));
}
// Integrate number of importance samples for (roughness and NoV)
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
{
float a = roughness*roughness;
float phi = 2.0 * PI * Xi.x;
float cosTheta = sqrt((1.0 - Xi.y)/(1.0 + (a*a - 1.0)*Xi.y));
float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
// Transform from spherical coordinates to cartesian coordinates (halfway vector)
vec3 H = vec3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta);
// Transform from tangent space H vector to world space sample vector
vec3 up = ((abs(N.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0));
vec3 tangent = normalize(cross(up, N));
vec3 bitangent = cross(N, tangent);
vec3 sampleVec = tangent*H.x + bitangent*H.y + N*H.z;
return normalize(sampleVec);
}
float GeometrySchlickGGX(float NdotV, float roughness)
{
// For IBL k is calculated different
float k = (roughness*roughness)/2.0;
float nom = NdotV;
float denom = NdotV*(1.0 - k) + k;
return nom/denom;
}
// Compute the geometry term for the BRDF given roughness squared, NoV, NoL
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
{
float NdotV = max(dot(N, V), 0.0);
float NdotL = max(dot(N, L), 0.0);
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
return ggx1*ggx2;
}
// Bidirectional reflectance distribution function
// Ref: https://github.com/HectorMF/BRDFGenerator
vec2 IntegrateBRDF(float NdotV, float roughness)
{
float A = 0.0;
float B = 0.0;
vec3 V = vec3(sqrt(1.0 - NdotV*NdotV), 0.0, NdotV);
vec3 N = vec3(0.0, 0.0, 1.0);
for (uint i = 0u; i < MAX_SAMPLES; i++)
{
// Generate a sample vector that's biased towards the preferred alignment direction (importance sampling)
vec2 Xi = Hammersley(i, MAX_SAMPLES); // Compute a Hammersely coordinate
vec3 H = ImportanceSampleGGX(Xi, N, roughness); // Integrate number of importance samples for (roughness and NoV)
vec3 L = normalize(2.0*dot(V, H)*H - V); // Compute reflection vector L
float NdotL = max(L.z, 0.0); // Compute normal dot light
float NdotH = max(H.z, 0.0); // Compute normal dot half
float VdotH = max(dot(V, H), 0.0); // Compute view dot half
if (NdotL > 0.0)
{
float G = GeometrySmith(N, V, L, roughness); // Compute the geometry term for the BRDF given roughness squared, NoV, NoL
float GVis = (G*VdotH)/(NdotH*NdotV); // Compute the visibility term given G, VoH, NoH, NoV, NoL
float Fc = pow(1.0 - VdotH, 5.0); // Compute the fresnel term given VoH
A += (1.0 - Fc)*GVis; // Sum the result given fresnel, geometry, visibility
B += Fc*GVis;
}
}
// Calculate brdf average sample
A /= float(MAX_SAMPLES);
B /= float(MAX_SAMPLES);
return vec2(A, B);
}
void main()
{
// Calculate brdf based on texture coordinates
vec2 brdf = IntegrateBRDF(fragTexCoord.x, fragTexCoord.y);
// Calculate final fragment color
finalColor = vec4(brdf.r, brdf.g, 0.0, 1.0);
}

View File

@ -1,17 +0,0 @@
#version 330
// Input vertex attributes
in vec3 vertexPosition;
in vec2 vertexTexCoord;
// Output vertex attributes (to fragment shader)
out vec2 fragTexCoord;
void main()
{
// Calculate fragment position based on model transformations
fragTexCoord = vertexTexCoord;
// Calculate final vertex position
gl_Position = vec4(vertexPosition, 1.0);
}

View File

@ -1,50 +0,0 @@
#version 330
// Input vertex attributes (from vertex shader)
in vec3 fragPosition;
// Input uniform values
uniform samplerCube environmentMap;
// Constant values
const float PI = 3.14159265359;
// Output fragment color
out vec4 finalColor;
void main()
{
// The sample direction equals the hemisphere's orientation
vec3 normal = normalize(fragPosition);
vec3 irradiance = vec3(0.0);
vec3 up = vec3(0.0, 1.0, 0.0);
vec3 right = cross(up, normal);
up = cross(normal, right);
float sampleDelta = 0.025;
float nrSamples = 0.0;
for (float phi = 0.0; phi < 2.0*PI; phi += sampleDelta)
{
for (float theta = 0.0; theta < 0.5*PI; theta += sampleDelta)
{
// Spherical to cartesian (in tangent space)
vec3 tangentSample = vec3(sin(theta)*cos(phi), sin(theta)*sin(phi), cos(theta));
// tangent space to world
vec3 sampleVec = tangentSample.x*right + tangentSample.y*up + tangentSample.z*normal;
// Fetch color from environment cubemap
irradiance += texture(environmentMap, sampleVec).rgb*cos(theta)*sin(theta);
nrSamples++;
}
}
// Calculate irradiance average value from samples
irradiance = PI*irradiance*(1.0/float(nrSamples));
// Calculate final fragment color
finalColor = vec4(irradiance, 1.0);
}

View File

@ -1,292 +0,0 @@
#version 330
#define MAX_REFLECTION_LOD 4.0
#define MAX_DEPTH_LAYER 20
#define MIN_DEPTH_LAYER 10
#define MAX_LIGHTS 4
#define LIGHT_DIRECTIONAL 0
#define LIGHT_POINT 1
struct MaterialProperty {
vec3 color;
int useSampler;
sampler2D sampler;
};
struct Light {
int enabled;
int type;
vec3 position;
vec3 target;
vec4 color;
};
// Input vertex attributes (from vertex shader)
in vec3 fragPosition;
in vec2 fragTexCoord;
in vec3 fragNormal;
in vec3 fragTangent;
in vec3 fragBinormal;
// Input material values
uniform MaterialProperty albedo;
uniform MaterialProperty normals;
uniform MaterialProperty metalness;
uniform MaterialProperty roughness;
uniform MaterialProperty occlusion;
uniform MaterialProperty emission;
uniform MaterialProperty height;
// Input uniform values
uniform samplerCube irradianceMap;
uniform samplerCube prefilterMap;
uniform sampler2D brdfLUT;
// Input lighting values
uniform Light lights[MAX_LIGHTS];
// Other uniform values
uniform int renderMode;
uniform vec3 viewPos;
vec2 texCoord;
// Constant values
const float PI = 3.14159265359;
// Output fragment color
out vec4 finalColor;
vec3 ComputeMaterialProperty(MaterialProperty property);
float DistributionGGX(vec3 N, vec3 H, float roughness);
float GeometrySchlickGGX(float NdotV, float roughness);
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness);
vec3 fresnelSchlick(float cosTheta, vec3 F0);
vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness);
vec2 ParallaxMapping(vec2 texCoords, vec3 viewDir);
// WARNING: There is some weird behaviour with this function, always returns black!
// Yes, I even tried: return texture(property.sampler, texCoord).rgb;
vec3 ComputeMaterialProperty(MaterialProperty property)
{
vec3 result = vec3(0.0, 0.0, 0.0);
if (property.useSampler == 1) result = texture(property.sampler, texCoord).rgb;
else result = property.color;
return result;
}
float DistributionGGX(vec3 N, vec3 H, float roughness)
{
float a = roughness*roughness;
float a2 = a*a;
float NdotH = max(dot(N, H), 0.0);
float NdotH2 = NdotH*NdotH;
float nom = a2;
float denom = (NdotH2*(a2 - 1.0) + 1.0);
denom = PI*denom*denom;
return nom/denom;
}
float GeometrySchlickGGX(float NdotV, float roughness)
{
float r = (roughness + 1.0);
float k = r*r/8.0;
float nom = NdotV;
float denom = NdotV*(1.0 - k) + k;
return nom/denom;
}
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
{
float NdotV = max(dot(N, V), 0.0);
float NdotL = max(dot(N, L), 0.0);
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
return ggx1*ggx2;
}
vec3 fresnelSchlick(float cosTheta, vec3 F0)
{
return F0 + (1.0 - F0)*pow(1.0 - cosTheta, 5.0);
}
vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
{
return F0 + (max(vec3(1.0 - roughness), F0) - F0)*pow(1.0 - cosTheta, 5.0);
}
vec2 ParallaxMapping(vec2 texCoords, vec3 viewDir)
{
// Calculate the number of depth layers and calculate the size of each layer
float numLayers = mix(MAX_DEPTH_LAYER, MIN_DEPTH_LAYER, abs(dot(vec3(0.0, 0.0, 1.0), viewDir)));
float layerDepth = 1.0/numLayers;
// Calculate depth of current layer
float currentLayerDepth = 0.0;
// Calculate the amount to shift the texture coordinates per layer (from vector P)
// Note: height amount is stored in height material attribute color R channel (sampler use is independent)
vec2 P = viewDir.xy*height.color.r;
vec2 deltaTexCoords = P/numLayers;
// Store initial texture coordinates and depth values
vec2 currentTexCoords = texCoords;
float currentDepthMapValue = texture(height.sampler, currentTexCoords).r;
while (currentLayerDepth < currentDepthMapValue)
{
// Shift texture coordinates along direction of P
currentTexCoords -= deltaTexCoords;
// Get depth map value at current texture coordinates
currentDepthMapValue = texture(height.sampler, currentTexCoords).r;
// Get depth of next layer
currentLayerDepth += layerDepth;
}
// Get texture coordinates before collision (reverse operations)
vec2 prevTexCoords = currentTexCoords + deltaTexCoords;
// Get depth after and before collision for linear interpolation
float afterDepth = currentDepthMapValue - currentLayerDepth;
float beforeDepth = texture(height.sampler, prevTexCoords).r - currentLayerDepth + layerDepth;
// Interpolation of texture coordinates
float weight = afterDepth/(afterDepth - beforeDepth);
vec2 finalTexCoords = prevTexCoords*weight + currentTexCoords*(1.0 - weight);
return finalTexCoords;
}
void main()
{
// Calculate TBN and RM matrices
mat3 TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal));
// Calculate lighting required attributes
vec3 normal = normalize(fragNormal);
vec3 view = normalize(viewPos - fragPosition);
vec3 refl = reflect(-view, normal);
// Check if parallax mapping is enabled and calculate texture coordinates to use based on height map
// NOTE: remember that 'texCoord' variable must be assigned before calling any ComputeMaterialProperty() function
if (height.useSampler == 1) texCoord = ParallaxMapping(fragTexCoord, view);
else texCoord = fragTexCoord; // Use default texture coordinates
// Fetch material values from texture sampler or color attributes
vec3 color = texture(albedo.sampler, texCoord).rgb; //ComputeMaterialProperty(albedo);
vec3 metal = texture(metalness.sampler, texCoord).rgb; //ComputeMaterialProperty(metalness);
vec3 rough = texture(roughness.sampler, texCoord).rgb; //ComputeMaterialProperty(roughness);
vec3 emiss = texture(emission.sampler, texCoord).rgb; //ComputeMaterialProperty(emission);
vec3 ao = texture(occlusion.sampler, texCoord).rgb; //ComputeMaterialProperty(occlusion);
// Check if normal mapping is enabled
if (normals.useSampler == 1)
{
// Fetch normal map color and transform lighting values to tangent space
normal = texture(normals.sampler, texCoord).rgb; //ComputeMaterialProperty(normals);
normal = normalize(normal*2.0 - 1.0);
normal = normalize(normal*TBN);
// Convert tangent space normal to world space due to cubemap reflection calculations
refl = normalize(reflect(-view, normal));
}
// Calculate reflectance at normal incidence
vec3 F0 = vec3(0.04);
F0 = mix(F0, color, metal.r);
// Calculate lighting for all lights
vec3 Lo = vec3(0.0);
vec3 lightDot = vec3(0.0);
for (int i = 0; i < MAX_LIGHTS; i++)
{
if (lights[i].enabled == 1)
{
// Calculate per-light radiance
vec3 light = vec3(0.0);
vec3 radiance = lights[i].color.rgb;
if (lights[i].type == LIGHT_DIRECTIONAL) light = -normalize(lights[i].target - lights[i].position);
else if (lights[i].type == LIGHT_POINT)
{
light = normalize(lights[i].position - fragPosition);
float distance = length(lights[i].position - fragPosition);
float attenuation = 1.0/(distance*distance);
radiance *= attenuation;
}
// Cook-torrance BRDF
vec3 high = normalize(view + light);
float NDF = DistributionGGX(normal, high, rough.r);
float G = GeometrySmith(normal, view, light, rough.r);
vec3 F = fresnelSchlick(max(dot(high, view), 0.0), F0);
vec3 nominator = NDF*G*F;
float denominator = 4*max(dot(normal, view), 0.0)*max(dot(normal, light), 0.0) + 0.001;
vec3 brdf = nominator/denominator;
// Store to kS the fresnel value and calculate energy conservation
vec3 kS = F;
vec3 kD = vec3(1.0) - kS;
// Multiply kD by the inverse metalness such that only non-metals have diffuse lighting
kD *= 1.0 - metal.r;
// Scale light by dot product between normal and light direction
float NdotL = max(dot(normal, light), 0.0);
// Add to outgoing radiance Lo
// Note: BRDF is already multiplied by the Fresnel so it doesn't need to be multiplied again
Lo += (kD*color/PI + brdf)*radiance*NdotL*lights[i].color.a;
lightDot += radiance*NdotL + brdf*lights[i].color.a;
}
}
// Calculate ambient lighting using IBL
vec3 F = fresnelSchlickRoughness(max(dot(normal, view), 0.0), F0, rough.r);
vec3 kS = F;
vec3 kD = 1.0 - kS;
kD *= 1.0 - metal.r;
// Calculate indirect diffuse
vec3 irradiance = texture(irradianceMap, fragNormal).rgb;
vec3 diffuse = color*irradiance;
// Sample both the prefilter map and the BRDF lut and combine them together as per the Split-Sum approximation
vec3 prefilterColor = textureLod(prefilterMap, refl, rough.r*MAX_REFLECTION_LOD).rgb;
vec2 brdf = texture(brdfLUT, vec2(max(dot(normal, view), 0.0), rough.r)).rg;
vec3 reflection = prefilterColor*(F*brdf.x + brdf.y);
// Calculate final lighting
vec3 ambient = (kD*diffuse + reflection)*ao;
// Calculate fragment color based on render mode
vec3 fragmentColor = ambient + Lo + emiss; // Physically Based Rendering
if (renderMode == 1) fragmentColor = color; // Albedo
else if (renderMode == 2) fragmentColor = normal; // Normals
else if (renderMode == 3) fragmentColor = metal; // Metalness
else if (renderMode == 4) fragmentColor = rough; // Roughness
else if (renderMode == 5) fragmentColor = ao; // Ambient Occlusion
else if (renderMode == 6) fragmentColor = emiss; // Emission
else if (renderMode == 7) fragmentColor = lightDot; // Lighting
else if (renderMode == 8) fragmentColor = kS; // Fresnel
else if (renderMode == 9) fragmentColor = irradiance; // Irradiance
else if (renderMode == 10) fragmentColor = reflection; // Reflection
// Apply HDR tonemapping
fragmentColor = fragmentColor/(fragmentColor + vec3(1.0));
// Apply gamma correction
fragmentColor = pow(fragmentColor, vec3(1.0/2.2));
// Calculate final fragment color
finalColor = vec4(fragmentColor, 1.0);
}

View File

@ -1,41 +0,0 @@
#version 330
// Input vertex attributes
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec3 vertexNormal;
in vec4 vertexTangent;
// Input uniform values
uniform mat4 mvp;
uniform mat4 matModel;
// Output vertex attributes (to fragment shader)
out vec3 fragPosition;
out vec2 fragTexCoord;
out vec3 fragNormal;
out vec3 fragTangent;
out vec3 fragBinormal;
void main()
{
// Calculate binormal from vertex normal and tangent
vec3 vertexBinormal = cross(vertexNormal, vec3(vertexTangent));
// Calculate fragment normal based on normal transformations
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
// Calculate fragment position based on model transformations
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
// Send vertex attributes to fragment shader
fragTexCoord = vertexTexCoord;
fragNormal = normalize(normalMatrix*vertexNormal);
fragTangent = normalize(normalMatrix*vec3(vertexTangent));
fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal);
fragBinormal = normalize(normalMatrix*vertexBinormal);
fragBinormal = cross(fragNormal, fragTangent);
// Calculate final vertex position
gl_Position = mvp*vec4(vertexPosition, 1.0);
}

View File

@ -1,113 +0,0 @@
#version 330
#define MAX_SAMPLES 1024u
#define CUBEMAP_RESOLUTION 1024.0
// Input vertex attributes (from vertex shader)
in vec3 fragPosition;
// Input uniform values
uniform samplerCube environmentMap;
uniform float roughness;
// Constant values
const float PI = 3.14159265359;
// Output fragment color
out vec4 finalColor;
float DistributionGGX(vec3 N, vec3 H, float roughness);
float RadicalInverse_VdC(uint bits);
vec2 Hammersley(uint i, uint N);
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness);
float DistributionGGX(vec3 N, vec3 H, float roughness)
{
float a = roughness*roughness;
float a2 = a*a;
float NdotH = max(dot(N, H), 0.0);
float NdotH2 = NdotH*NdotH;
float nom = a2;
float denom = (NdotH2*(a2 - 1.0) + 1.0);
denom = PI*denom*denom;
return nom/denom;
}
float RadicalInverse_VdC(uint bits)
{
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return float(bits)*2.3283064365386963e-10; // / 0x100000000
}
vec2 Hammersley(uint i, uint N)
{
return vec2(float(i)/float(N), RadicalInverse_VdC(i));
}
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
{
float a = roughness*roughness;
float phi = 2.0*PI*Xi.x;
float cosTheta = sqrt((1.0 - Xi.y)/(1.0 + (a*a - 1.0)*Xi.y));
float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
// Transform from spherical coordinates to cartesian coordinates (halfway vector)
vec3 H = vec3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta);
// Transform from tangent space H vector to world space sample vector
vec3 up = ((abs(N.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0));
vec3 tangent = normalize(cross(up, N));
vec3 bitangent = cross(N, tangent);
vec3 sampleVec = tangent*H.x + bitangent*H.y + N*H.z;
return normalize(sampleVec);
}
void main()
{
// Make the simplyfying assumption that V equals R equals the normal
vec3 N = normalize(fragPosition);
vec3 R = N;
vec3 V = R;
vec3 prefilteredColor = vec3(0.0);
float totalWeight = 0.0;
for (uint i = 0u; i < MAX_SAMPLES; i++)
{
// Generate a sample vector that's biased towards the preferred alignment direction (importance sampling)
vec2 Xi = Hammersley(i, MAX_SAMPLES);
vec3 H = ImportanceSampleGGX(Xi, N, roughness);
vec3 L = normalize(2.0*dot(V, H)*H - V);
float NdotL = max(dot(N, L), 0.0);
if(NdotL > 0.0)
{
// Sample from the environment's mip level based on roughness/pdf
float D = DistributionGGX(N, H, roughness);
float NdotH = max(dot(N, H), 0.0);
float HdotV = max(dot(H, V), 0.0);
float pdf = D*NdotH/(4.0*HdotV) + 0.0001;
float resolution = CUBEMAP_RESOLUTION;
float saTexel = 4.0*PI/(6.0*resolution*resolution);
float saSample = 1.0/(float(MAX_SAMPLES)*pdf + 0.0001);
float mipLevel = ((roughness == 0.0) ? 0.0 : 0.5*log2(saSample/saTexel));
prefilteredColor += textureLod(environmentMap, L, mipLevel).rgb*NdotL;
totalWeight += NdotL;
}
}
// Calculate prefilter average color
prefilteredColor = prefilteredColor/totalWeight;
// Calculate final fragment color
finalColor = vec4(prefilteredColor, 1.0);
}

View File

@ -24,8 +24,14 @@
********************************************************************************************/
#include "raylib.h"
#include "rlgl.h" // Required for: rlDrawRenderBatchActive(), rlGetMatrixModelview(), rlGetMatrixProjection()
#include "glad.h" // Required for: OpenGL functionality
#if defined(__APPLE__)
#include <OpenGL/gl3.h> // OpenGL 3 library for OSX
#include <OpenGL/gl3ext.h> // OpenGL 3 extensions library for OSX
#else
#include "glad.h" // Required for: OpenGL functionality
#endif
#include "raymath.h" // Required for: MatrixMultiply(), MatrixToFloat()
#if defined(PLATFORM_DESKTOP)

View File

@ -9,5 +9,3 @@
| raysan.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
| space.png | ❔ | ❔ | - |
| texel_checker.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [UV Checker Map Maker](http://uvchecker.byvalle.com/) |
| egg.png | [@GoldenThumbs](https://github.com/GoldenThumbs) |
| torus.png | [@GoldenThumbs](https://github.com/GoldenThumbs) |

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 B

View File

@ -9,27 +9,29 @@ varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
uniform vec2 texScale;
// Function for drawing outlines on alpha-blended textures
vec4 DrawOutline(sampler2D tex, vec2 uv, vec2 lineScale, vec3 lineCol)
{
vec2 texelScale = 1.0 / lineScale;
vec4 center = texture2D(tex, uv); // We sample the center texel, (with all color data)
// Next we sample four corner texels, but only for the alpha channel (this is for the outline)
vec4 corners;
corners.x = texture2D(tex, uv+vec2( texelScale.x, texelScale.y)).a;
corners.y = texture2D(tex, uv+vec2( texelScale.x,-texelScale.y)).a;
corners.z = texture2D(tex, uv+vec2(-texelScale.x, texelScale.y)).a;
corners.w = texture2D(tex, uv+vec2(-texelScale.x,-texelScale.y)).a;
uniform vec2 textureSize;
uniform float outlineSize;
uniform vec4 outlineColor;
float outline = min(dot(corners, vec4(1.0)), 1.0);
vec4 col = mix(vec4(0.0), vec4(lineCol, 1.0), outline);
col = mix(col, center, center.a);
return col;
}
// Output fragment color
out vec4 finalColor;
void main()
{
gl_FragColor = DrawOutline(texture0, fragTexCoord, texScale, vec3(0.0));
vec4 texel = texture2D(texture0, fragTexCoord); // Get texel color
vec2 texelScale = vec2(0.0);
texelScale.x = outlineSize/textureSize.x;
texelScale.y = outlineSize/textureSize.y;
// We sample four corner texels, but only for the alpha channel (this is for the outline)
vec4 corners = vec4(0.0);
corners.x = texture2D(texture0, fragTexCoord + vec2(texelScale.x, texelScale.y)).a;
corners.y = texture2D(texture0, fragTexCoord + vec2(texelScale.x, -texelScale.y)).a;
corners.z = texture2D(texture0, fragTexCoord + vec2(-texelScale.x, texelScale.y)).a;
corners.w = texture2D(texture0, fragTexCoord + vec2(-texelScale.x, -texelScale.y)).a;
float outline = min(dot(corners, vec4(1.0)), 1.0);
vec4 color = mix(vec4(0.0), outlineColor, outline);
gl_FragColor = mix(color, texel, texel.a);
}

View File

@ -7,30 +7,29 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
uniform vec2 texScale;
uniform vec2 textureSize;
uniform float outlineSize;
uniform vec4 outlineColor;
// Output fragment color
out vec4 finalColor;
// Function for drawing outlines on alpha-blended textures
vec4 DrawOutline(sampler2D tex, vec2 uv, vec2 lineScale, vec3 lineCol)
{
vec2 texelScale = 1.0 / lineScale;
vec4 center = texture(tex, uv); // We sample the center texel, (with all color data)
// Next we sample four corner texels, but only for the alpha channel (this is for the outline)
vec4 corners;
corners.x = texture(tex, uv+vec2( texelScale.x, texelScale.y)).a;
corners.y = texture(tex, uv+vec2( texelScale.x,-texelScale.y)).a;
corners.z = texture(tex, uv+vec2(-texelScale.x, texelScale.y)).a;
corners.w = texture(tex, uv+vec2(-texelScale.x,-texelScale.y)).a;
float outline = min(dot(corners, vec4(1.0)), 1.0);
vec4 col = mix(vec4(0.0), vec4(lineCol, 1.0), outline);
col = mix(col, center, center.a);
return col;
}
void main()
{
finalColor = DrawOutline(texture0, fragTexCoord, texScale, vec3(0.0));
vec4 texel = texture(texture0, fragTexCoord); // Get texel color
vec2 texelScale = vec2(0.0);
texelScale.x = outlineSize/textureSize.x;
texelScale.y = outlineSize/textureSize.y;
// We sample four corner texels, but only for the alpha channel (this is for the outline)
vec4 corners = vec4(0.0);
corners.x = texture(texture0, fragTexCoord + vec2(texelScale.x, texelScale.y)).a;
corners.y = texture(texture0, fragTexCoord + vec2(texelScale.x, -texelScale.y)).a;
corners.z = texture(texture0, fragTexCoord + vec2(-texelScale.x, texelScale.y)).a;
corners.w = texture(texture0, fragTexCoord + vec2(-texelScale.x, -texelScale.y)).a;
float outline = min(dot(corners, vec4(1.0)), 1.0);
vec4 color = mix(vec4(0.0), outlineColor, outline);
finalColor = mix(color, texel, texel.a);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 132 KiB

View File

@ -5,12 +5,10 @@
* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
*
* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3).
*
* This example has been created using raylib 3.8 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Example contributed by Samuel Skiff (@GoldenThumbs)
* Example contributed by Samuel Skiff (@GoldenThumbs) and reviewed by Ramon Santamaria (@raysan5)
*
* Copyright (c) 2021 Samuel SKiff (@GoldenThumbs) and Ramon Santamaria (@raysan5)
*
@ -33,13 +31,23 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - Apply an outline to a texture");
Texture2D egg = LoadTexture("resources/egg.png");
Texture2D torus = LoadTexture("resources/torus.png");
Texture2D texture = LoadTexture("resources/fudesumi.png");
Shader shdrOutline = LoadShader(0, TextFormat("resources/shaders/glsl%i/outline.fs", GLSL_VERSION));
float outlineScale = 16.0f;
float textureScale[2] = { 16.0f*4, 16.0f*4 };
SetShaderValue(shdrOutline, GetShaderLocation(shdrOutline, "texScale"), textureScale, SHADER_UNIFORM_VEC2);
float outlineSize = 2.0f;
float outlineColor[4] = { 1.0f, 0.0f, 0.0f, 1.0f }; // Normalized RED color
float textureSize[2] = { (float)texture.width, (float)texture.height };
// Get shader locations
int outlineSizeLoc = GetShaderLocation(shdrOutline, "outlineSize");
int outlineColorLoc = GetShaderLocation(shdrOutline, "outlineColor");
int textureSizeLoc = GetShaderLocation(shdrOutline, "textureSize");
// Set shader values (they can be changed later)
SetShaderValue(shdrOutline, outlineSizeLoc, &outlineSize, SHADER_UNIFORM_FLOAT);
SetShaderValue(shdrOutline, outlineColorLoc, outlineColor, SHADER_UNIFORM_VEC4);
SetShaderValue(shdrOutline, textureSizeLoc, textureSize, SHADER_UNIFORM_VEC2);
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@ -49,7 +57,10 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
outlineSize += GetMouseWheelMove();
if (outlineSize < 1.0f) outlineSize = 1.0f;
SetShaderValue(shdrOutline, outlineSizeLoc, &outlineSize, SHADER_UNIFORM_FLOAT);
//----------------------------------------------------------------------------------
// Draw
@ -59,11 +70,14 @@ int main(void)
ClearBackground(RAYWHITE);
BeginShaderMode(shdrOutline);
DrawTextureEx(egg, (Vector2){ 0, 230 }, 0.0, outlineScale, WHITE);
DrawTextureEx(torus, (Vector2){ 544, 230 }, 0.0, outlineScale, WHITE);
DrawTexture(texture, GetScreenWidth()/2 - texture.width/2, -30, WHITE);
EndShaderMode();
DrawText("Shader-based outlines for textures", 190, 200, 20, LIGHTGRAY);
DrawText("Shader-based\ntexture\noutline", 10, 10, 20, GRAY);
DrawText(TextFormat("Outline size: %i px", (int)outlineSize), 10, 120, 20, MAROON);
DrawFPS(710, 10);
@ -73,8 +87,7 @@ int main(void)
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(egg);
UnloadTexture(torus);
UnloadTexture(texture);
UnloadShader(shdrOutline);
CloseWindow(); // Close window and OpenGL context

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

View File

@ -0,0 +1,20 @@
#version 100
precision mediump float;
// Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord;
varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
void main()
{
vec4 texelColor = texture2D(texture0, fragTexCoord);
if (texelColor.a == 0.0) discard;
gl_FragColor = texelColor*fragColor*colDiffuse;
}

View File

@ -1,5 +1,7 @@
#version 100
precision mediump float;
// Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord;
varying vec4 fragColor;

View File

@ -15,7 +15,7 @@
#include "raylib.h"
#include "raymath.h"
#define MAX_POINTS 11 // 10 points and back to the start
#define MAX_POINTS 11 // 10 points and back to the start
int main(void)
{
@ -24,6 +24,9 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - textured polygon");
// Define texture coordinates to map our texture to poly
Vector2 texcoords[MAX_POINTS] = {
(Vector2){ 0.75f, 0.0f },
(Vector2){ 0.25f, 0.0f },
@ -38,22 +41,24 @@ int main(void)
(Vector2){ 0.75f, 0.0f} // Close the poly
};
// Define the base poly vertices from the UV's
// NOTE: They can be specified in any other way
Vector2 points[MAX_POINTS] = { 0 };
// Create the poly coords from the UV's
// you don't have to do this you can specify
// them however you want
for (int i = 0; i < MAX_POINTS; i++)
{
points[i].x = (texcoords[i].x - 0.5f)*256.0f;
points[i].y = (texcoords[i].y - 0.5f)*256.0f;
}
InitWindow(screenWidth, screenHeight, "raylib [textures] example - textured polygon");
// Define the vertices drawing position
// NOTE: Initially same as points but updated every frame
Vector2 positions[MAX_POINTS] = { 0 };
for (int i = 0; i < MAX_POINTS; i++) positions[i] = points[i];
// Load texture to be mapped to poly
Texture texture = LoadTexture("resources/cat.png");
float angle = 0.0f;
float angle = 0.0f; // Rotation angle (in degrees)
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@ -63,10 +68,9 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
// Update points rotation with an angle transform
// NOTE: Base points position are not modified
angle++;
Vector2 positions[MAX_POINTS] = { 0 };
for (int i = 0; i < MAX_POINTS; i++) positions[i] = Vector2Rotate(points[i], angle*DEG2RAD);
//----------------------------------------------------------------------------------

View File

Before

Width:  |  Height:  |  Size: 190 KiB

After

Width:  |  Height:  |  Size: 190 KiB

View File

@ -39,7 +39,7 @@
<Keyword>Win32Proj</Keyword>
<RootNamespace>models_mesh_magicavoxel_loading</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>models_mesh_magicavoxel_loading</ProjectName>
<ProjectName>models_loading_vox</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -379,7 +379,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\examples\models\models_magicavoxel_loading.c" />
<ClCompile Include="..\..\..\examples\models\models_loading_vox.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@ -93,16 +93,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_first_person_maze",
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_geometric_shapes", "examples\models_geometric_shapes.vcxproj", "{14BA7F98-02CC-4648-9236-676BFF9458AF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_gltf_animation", "examples\models_gltf_animation.vcxproj", "{FADC31C3-09AA-4DB4-A289-153482D10C09}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_gltf_model", "examples\models_gltf_model.vcxproj", "{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_heightmap", "examples\models_heightmap.vcxproj", "{0859A973-E4FE-4688-8D16-0253163FDE24}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_loading", "examples\models_loading.vcxproj", "{F3412853-2B6A-4334-8CF2-B796CDAE0850}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_material_pbr", "examples\models_material_pbr.vcxproj", "{3A6C48C6-80AB-456F-A3A5-969930958971}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_mesh_generation", "examples\models_mesh_generation.vcxproj", "{BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_mesh_picking", "examples\models_mesh_picking.vcxproj", "{D03F2C82-9553-4AFA-8F49-9234009122B6}"
@ -275,7 +269,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rlgl_standalone", "examples
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_split_screen", "examples\core_split_screen.vcxproj", "{946A1700-C7AA-46F0-AEF2-67C98B5722AC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_mesh_magicavoxel_loading", "examples\models_mesh_magicavoxel_loading.vcxproj", "{2F1B955B-275E-4D8E-8864-06FEC44D7912}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_loading_vox", "examples\models_loading_vox.vcxproj", "{2F1B955B-275E-4D8E-8864-06FEC44D7912}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -895,38 +889,6 @@ Global
{14BA7F98-02CC-4648-9236-676BFF9458AF}.Release|x64.Build.0 = Release|x64
{14BA7F98-02CC-4648-9236-676BFF9458AF}.Release|x86.ActiveCfg = Release|Win32
{14BA7F98-02CC-4648-9236-676BFF9458AF}.Release|x86.Build.0 = Release|Win32
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Debug|x64.ActiveCfg = Debug|x64
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Debug|x64.Build.0 = Debug|x64
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Debug|x86.ActiveCfg = Debug|Win32
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Debug|x86.Build.0 = Debug|Win32
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Release.DLL|x64.Build.0 = Release.DLL|x64
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Release.DLL|x86.Build.0 = Release.DLL|Win32
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Release|x64.ActiveCfg = Release|x64
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Release|x64.Build.0 = Release|x64
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Release|x86.ActiveCfg = Release|Win32
{FADC31C3-09AA-4DB4-A289-153482D10C09}.Release|x86.Build.0 = Release|Win32
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|x64.ActiveCfg = Debug|x64
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|x64.Build.0 = Debug|x64
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|x86.ActiveCfg = Debug|Win32
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Debug|x86.Build.0 = Debug|Win32
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|x64.Build.0 = Release.DLL|x64
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release.DLL|x86.Build.0 = Release.DLL|Win32
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|x64.ActiveCfg = Release|x64
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|x64.Build.0 = Release|x64
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|x86.ActiveCfg = Release|Win32
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71}.Release|x86.Build.0 = Release|Win32
{0859A973-E4FE-4688-8D16-0253163FDE24}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
{0859A973-E4FE-4688-8D16-0253163FDE24}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
{0859A973-E4FE-4688-8D16-0253163FDE24}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
@ -959,22 +921,6 @@ Global
{F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release|x64.Build.0 = Release|x64
{F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release|x86.ActiveCfg = Release|Win32
{F3412853-2B6A-4334-8CF2-B796CDAE0850}.Release|x86.Build.0 = Release|Win32
{3A6C48C6-80AB-456F-A3A5-969930958971}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
{3A6C48C6-80AB-456F-A3A5-969930958971}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
{3A6C48C6-80AB-456F-A3A5-969930958971}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
{3A6C48C6-80AB-456F-A3A5-969930958971}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
{3A6C48C6-80AB-456F-A3A5-969930958971}.Debug|x64.ActiveCfg = Debug|x64
{3A6C48C6-80AB-456F-A3A5-969930958971}.Debug|x64.Build.0 = Debug|x64
{3A6C48C6-80AB-456F-A3A5-969930958971}.Debug|x86.ActiveCfg = Debug|Win32
{3A6C48C6-80AB-456F-A3A5-969930958971}.Debug|x86.Build.0 = Debug|Win32
{3A6C48C6-80AB-456F-A3A5-969930958971}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
{3A6C48C6-80AB-456F-A3A5-969930958971}.Release.DLL|x64.Build.0 = Release.DLL|x64
{3A6C48C6-80AB-456F-A3A5-969930958971}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
{3A6C48C6-80AB-456F-A3A5-969930958971}.Release.DLL|x86.Build.0 = Release.DLL|Win32
{3A6C48C6-80AB-456F-A3A5-969930958971}.Release|x64.ActiveCfg = Release|x64
{3A6C48C6-80AB-456F-A3A5-969930958971}.Release|x64.Build.0 = Release|x64
{3A6C48C6-80AB-456F-A3A5-969930958971}.Release|x86.ActiveCfg = Release|Win32
{3A6C48C6-80AB-456F-A3A5-969930958971}.Release|x86.Build.0 = Release|Win32
{BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
{BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
{BE097E8F-B6F3-45DC-8A27-E0EBC31AB912}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
@ -2349,11 +2295,8 @@ Global
{5317807F-61D4-4E0F-B6DC-2D9F12621ED9} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}
{CBD6C0F8-8200-4E9A-9D7C-6505A2AA4A62} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
{14BA7F98-02CC-4648-9236-676BFF9458AF} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
{FADC31C3-09AA-4DB4-A289-153482D10C09} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
{F5FC9279-DE63-4EF3-B31F-CFCEF9B11F71} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
{0859A973-E4FE-4688-8D16-0253163FDE24} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
{F3412853-2B6A-4334-8CF2-B796CDAE0850} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
{3A6C48C6-80AB-456F-A3A5-969930958971} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
{BE097E8F-B6F3-45DC-8A27-E0EBC31AB912} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
{D03F2C82-9553-4AFA-8F49-9234009122B6} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
{FE232CA5-6C0D-4ADF-9A21-775D4DC048D3} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}

View File

@ -9,7 +9,9 @@
"command": "make",
"args": [
"PLATFORM=PLATFORM_DESKTOP",
"BUILD_MODE=DEBUG"
"BUILD_MODE=DEBUG",
"PROJECT_NAME=${fileBasenameNoExtension}",
"OBJS=${fileBasenameNoExtension}.c"
],
"windows": {
"command": "C:/raylib/mingw/bin/mingw32-make.exe",
@ -42,6 +44,8 @@
"command": "make",
"args": [
"PLATFORM=PLATFORM_DESKTOP",
"PROJECT_NAME=${fileBasenameNoExtension}",
"OBJS=${fileBasenameNoExtension}.c"
],
"windows": {
"command": "C:/raylib/mingw/bin/mingw32-make.exe",

View File

@ -43,8 +43,8 @@
.PHONY: all clean install uninstall
# Define required raylib variables
RAYLIB_VERSION = 3.8.1
RAYLIB_API_VERSION = 381
RAYLIB_VERSION = 4.0.0
RAYLIB_API_VERSION = 400
# Define raylib source code path
RAYLIB_SRC_PATH ?= ../src

View File

@ -25,14 +25,16 @@ pub fn build(b: *std.build.Builder) void {
raylib.addIncludeDir("external/glfw/include");
raylib.addCSourceFile("rcore.c", raylib_flags);
raylib.addCSourceFile("rmodels.c", raylib_flags);
raylib.addCSourceFile("raudio.c", raylib_flags);
raylib.addCSourceFile("rshapes.c", raylib_flags);
raylib.addCSourceFile("rtext.c", raylib_flags);
raylib.addCSourceFile("rtextures.c", raylib_flags);
raylib.addCSourceFile("utils.c", raylib_flags);
raylib.addCSourceFile("rglfw.c", raylib_flags);
raylib.addCSourceFiles(&.{
"raudio.c",
"rcore.c",
"rglfw.c",
"rmodels.c",
"rshapes.c",
"rtext.c",
"rtextures.c",
"utils.c",
}, raylib_flags);
switch (raylib.target.toTarget().os.tag) {
.windows => {

View File

@ -84,8 +84,12 @@
//------------------------------------------------------------------------------------
// Module: rlgl - Configuration values
//------------------------------------------------------------------------------------
// Enable OpenGL Debug Context (only available on OpenGL 4.3)
//#define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT 1
// Show OpenGL extensions and capabilities detailed logs on init
//#define RLGL_SHOW_GL_DETAILS_INFO 1
//#define RLGL_SHOW_GL_DETAILS_INFO 1
//#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 4096 // Default internal render batch elements limits
#define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering)

13718
src/external/glad.h vendored

File diff suppressed because it is too large Load Diff

View File

@ -43,27 +43,25 @@ revision history:
Changed Vox_LoadFileName to Vox_LoadFromMemory
1.02 (2021-09-10) @raysan5: Reviewed some formating
1.03 (2021-10-02) @catmanl: Reduce warnings on gcc
1.04 (2021-10-17) @warzes: Fixing the error of loading VOX models
*/
#ifndef VOX_LOADER_H
#define VOX_LOADER_H
#include <string.h>
#include <stdlib.h>
// Allow custom memory allocators
#ifndef VOX_MALLOC
#define VOX_MALLOC RL_MALLOC
#define VOX_MALLOC(sz) malloc(sz)
#endif
#ifndef VOX_CALLOC
#define VOX_CALLOC RL_CALLOC
#define VOX_CALLOC(n,sz) calloc(n,sz)
#endif
#ifndef VOX_REALLOC
#define VOX_REALLOC RL_REALLOC
#define VOX_REALLOC(n,sz) realloc(n,sz)
#endif
#ifndef VOX_FREE
#define VOX_FREE RL_FREE
#define VOX_FREE(p) free(p)
#endif
#define VOX_SUCCESS (0)
@ -157,6 +155,9 @@ void Vox_FreeArrays(VoxArray3D* voxarray);
#ifdef VOX_LOADER_IMPLEMENTATION
#include <string.h>
#include <stdlib.h>
/////////////////////////////////////////////////////////////////////////////////////////////
// ArrayUShort helper
/////////////////////////////////////////////////////////////////////////////////////////////
@ -585,6 +586,9 @@ int Vox_LoadFromMemory(unsigned char* pvoxData, unsigned int voxDataSize, VoxArr
unsigned long chunkSize = *((unsigned long*)fileDataPtr);
fileDataPtr += sizeof(unsigned long);
//unsigned long chunkTotalChildSize = *((unsigned long*)fileDataPtr);
fileDataPtr += sizeof(unsigned long);
if (strcmp(szChunkName, "SIZE") == 0)
{
//(4 bytes x 3 : x, y, z )

View File

@ -193,7 +193,7 @@ typedef struct tagBITMAPINFOHEADER {
#endif
#if defined(SUPPORT_FILEFORMAT_OGG)
// TODO: Remap malloc()/free() calls to RL_MALLOC/RL_FREE
// TODO: Remap stb_vorbis malloc()/free() calls to RL_MALLOC/RL_FREE
#define STB_VORBIS_IMPLEMENTATION
#include "external/stb_vorbis.h" // OGG loading functions
@ -405,8 +405,6 @@ void UntrackAudioBuffer(AudioBuffer *buffer);
// Initialize audio device
void InitAudioDevice(void)
{
// TODO: Load AUDIO context memory dynamically?
// Init audio context
ma_context_config ctxConfig = ma_context_config_init();
ctxConfig.logCallback = OnLog;

View File

@ -5,7 +5,7 @@
* FEATURES:
* - NO external dependencies, all required libraries included with raylib
* - Multiplatform: Windows, Linux, FreeBSD, OpenBSD, NetBSD, DragonFly,
* MacOS, Haiku, UWP, Android, Raspberry Pi, HTML5.
* MacOS, Haiku, Android, Raspberry Pi, DRM native, HTML5.
* - Written in plain C code (C99) in PascalCase/camelCase notation
* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3 or ES2 - choose at compile)
* - Unique OpenGL abstraction layer (usable as standalone module): [rlgl]
@ -21,29 +21,28 @@
* - Bindings to multiple programming languages available!
*
* NOTES:
* One default Font is loaded on InitWindow()->LoadFontDefault() [core, text]
* One default Texture2D is loaded on rlglInit(), 1x1 white pixel R8G8B8A8 [rlgl] (OpenGL 3.3 or ES2)
* One default Shader is loaded on rlglInit()->rlLoadShaderDefault() [rlgl] (OpenGL 3.3 or ES2)
* One default RenderBatch is loaded on rlglInit()->rlLoadRenderBatch() [rlgl] (OpenGL 3.3 or ES2)
* - One default Font is loaded on InitWindow()->LoadFontDefault() [core, text]
* - One default Texture2D is loaded on rlglInit(), 1x1 white pixel R8G8B8A8 [rlgl] (OpenGL 3.3 or ES2)
* - One default Shader is loaded on rlglInit()->rlLoadShaderDefault() [rlgl] (OpenGL 3.3 or ES2)
* - One default RenderBatch is loaded on rlglInit()->rlLoadRenderBatch() [rlgl] (OpenGL 3.3 or ES2)
*
* DEPENDENCIES (included):
* [core] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input (PLATFORM_DESKTOP)
* [rcore] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input (PLATFORM_DESKTOP)
* [rlgl] glad (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading (PLATFORM_DESKTOP)
* [raudio] miniaudio (David Reid - github.com/mackron/miniaudio) for audio device/context management
*
* OPTIONAL DEPENDENCIES (included):
* [core] msf_gif (Miles Fogle) for GIF recording
* [core] sinfl (Micha Mettke) for DEFLATE decompression algorythm
* [core] sdefl (Micha Mettke) for DEFLATE compression algorythm
* [textures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...)
* [textures] stb_image_write (Sean Barret) for image writting (BMP, TGA, PNG, JPG)
* [textures] stb_image_resize (Sean Barret) for image resizing algorithms
* [textures] stb_perlin (Sean Barret) for Perlin noise image generation
* [text] stb_truetype (Sean Barret) for ttf fonts loading
* [text] stb_rect_pack (Sean Barret) for rectangles packing
* [models] par_shapes (Philip Rideout) for parametric 3d shapes generation
* [models] tinyobj_loader_c (Syoyo Fujita) for models loading (OBJ, MTL)
* [models] cgltf (Johannes Kuhlmann) for models loading (glTF)
* [rcore] msf_gif (Miles Fogle) for GIF recording
* [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorythm
* [rcore] sdefl (Micha Mettke) for DEFLATE compression algorythm
* [rtextures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...)
* [rtextures] stb_image_write (Sean Barret) for image writting (BMP, TGA, PNG, JPG)
* [rtextures] stb_image_resize (Sean Barret) for image resizing algorithms
* [rtext] stb_truetype (Sean Barret) for ttf fonts loading
* [rtext] stb_rect_pack (Sean Barret) for rectangles packing
* [rmodels] par_shapes (Philip Rideout) for parametric 3d shapes generation
* [rmodels] tinyobj_loader_c (Syoyo Fujita) for models loading (OBJ, MTL)
* [rmodels] cgltf (Johannes Kuhlmann) for models loading (glTF)
* [raudio] dr_wav (David Reid) for WAV audio file loading
* [raudio] dr_flac (David Reid) for FLAC audio file loading
* [raudio] dr_mp3 (David Reid) for MP3 audio file loading
@ -1053,8 +1052,11 @@ RLAPI char **GetDroppedFiles(int *count); // Get dropped
RLAPI void ClearDroppedFiles(void); // Clear dropped files paths buffer (free memory)
RLAPI long GetFileModTime(const char *fileName); // Get file modification time (last write time)
// Compression/Encoding functionality
RLAPI unsigned char *CompressData(unsigned char *data, int dataLength, int *compDataLength); // Compress data (DEFLATE algorithm)
RLAPI unsigned char *DecompressData(unsigned char *compData, int compDataLength, int *dataLength); // Decompress data (DEFLATE algorithm)
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataLength, int *outputLength); // Encode data to Base64 string
RLAPI unsigned char *DecodeDataBase64(unsigned char *data, int *outputLength); // Decode Base64 string data
// Persistent storage management
RLAPI bool SaveStorageValue(unsigned int position, int value); // Save integer value to storage file (to defined position), returns true on success
@ -1109,7 +1111,6 @@ RLAPI int GetTouchY(void); // Get touch posit
RLAPI Vector2 GetTouchPosition(int index); // Get touch position XY for a touch point index (relative to screen size)
RLAPI int GetTouchPointId(int index); // Get touch point identifier for given index
RLAPI int GetTouchPointCount(void); // Get number of touch points
RLAPI int GetTouchEvent(void); // Get last touch event registered
//------------------------------------------------------------------------------------
// Gestures and Touch Handling Functions (Module: rgestures)
@ -1189,6 +1190,7 @@ RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec);
RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
RLAPI bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint); // Check the collision between two lines defined by two points each, returns collision point by reference
RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]
RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
//------------------------------------------------------------------------------------
@ -1383,7 +1385,9 @@ RLAPI void DrawSphere(Vector3 centerPos, float radius, Color color);
RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
RLAPI void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
RLAPI void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
RLAPI void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder with base at startPos and top at endPos
RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
RLAPI void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder wires with base at startPos and top at endPos
RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ
RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line
RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))

Some files were not shown because too many files have changed in this diff Show More