Merge branch 'master' into master
This commit is contained in:
commit
8d6254b352
39 changed files with 22175 additions and 5774 deletions
|
|
@ -115,6 +115,12 @@ elseif ("${PLATFORM}" STREQUAL "DRM")
|
|||
|
||||
endif ()
|
||||
|
||||
# The rlgl_standalone example only targets desktop, without shared libraries.
|
||||
if (BUILD_SHARED_LIBS OR NOT ${PLATFORM} MATCHES "Desktop")
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
||||
|
||||
endif()
|
||||
|
||||
include_directories(BEFORE SYSTEM others/external/include)
|
||||
|
||||
if (NOT TARGET raylib)
|
||||
|
|
@ -131,6 +137,9 @@ foreach (example_source ${example_sources})
|
|||
add_executable(${example_name} ${example_source})
|
||||
|
||||
target_link_libraries(${example_name} raylib)
|
||||
if (NOT WIN32)
|
||||
target_link_libraries(${example_name} m)
|
||||
endif()
|
||||
|
||||
string(REGEX MATCH ".*/.*/" resources_dir ${example_source})
|
||||
string(APPEND resources_dir "resources")
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@
|
|||
# - Windows (Win32, Win64)
|
||||
# - Linux (X11/Wayland desktop mode)
|
||||
# - Others (not tested)
|
||||
# > PLATFORM_DESKTOP_RGFW (RGFW backend):
|
||||
# - Windows (Win32, Win64)
|
||||
# - Linux (X11 desktop mode)
|
||||
# - macOS/OSX (x64, arm64 (not tested))
|
||||
# - Others (not tested)
|
||||
# > PLATFORM_WEB:
|
||||
# - HTML5 (WebAssembly)
|
||||
# > PLATFORM_DRM:
|
||||
|
|
@ -86,7 +91,7 @@ BUILD_WEB_RESOURCES ?= TRUE
|
|||
BUILD_WEB_RESOURCES_PATH ?= $(dir $<)resources@resources
|
||||
|
||||
# Determine PLATFORM_OS when required
|
||||
ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_DESKTOP_SDL PLATFORM_WEB))
|
||||
ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_DESKTOP_SDL PLATFORM_WEB PLATFORM_DESKTOP_RGFW))
|
||||
# No uname.exe on MinGW!, but OS=Windows_NT on Windows!
|
||||
# ifeq ($(UNAME),Msys) -> Windows
|
||||
ifeq ($(OS),Windows_NT)
|
||||
|
|
@ -416,6 +421,31 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP_SDL)
|
|||
LDLIBS += -latomic
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP_RGFW)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# Libraries for Windows desktop compilation
|
||||
LDLIBS = ..\src\libraylib.a -lgdi32 -lwinmm -lopengl32
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# Libraries for Debian GNU/Linux desktop compipling
|
||||
# NOTE: Required packages: libegl1-mesa-dev
|
||||
LDLIBS = ../src/libraylib.a -lGL -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lm -lpthread -ldl -lrt
|
||||
|
||||
# Explicit link to libc
|
||||
ifeq ($(RAYLIB_LIBTYPE),SHARED)
|
||||
LDLIBS += -lc
|
||||
endif
|
||||
|
||||
# NOTE: On ARM 32bit arch, miniaudio requires atomics library
|
||||
LDLIBS += -latomic
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# Libraries for Debian GNU/Linux desktop compiling
|
||||
# NOTE: Required packages: libegl1-mesa-dev
|
||||
LDLIBS = ../src/libraylib.a -lm
|
||||
LDLIBS += -framework Foundation -framework AppKit -framework OpenGL -framework CoreVideo
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_DRM)
|
||||
# Libraries for DRM compiling
|
||||
# NOTE: Required packages: libasound2-dev (ALSA)
|
||||
|
|
@ -453,6 +483,7 @@ CORE = \
|
|||
core/core_input_mouse_wheel \
|
||||
core/core_input_multitouch \
|
||||
core/core_loading_thread \
|
||||
core/core_random_sequence \
|
||||
core/core_random_values \
|
||||
core/core_scissor_test \
|
||||
core/core_smooth_pixelperfect \
|
||||
|
|
|
|||
|
|
@ -158,7 +158,8 @@ LDLIBS = -lm -lc -lraylib -llog -landroid -lEGL -lGLESv2 -lOpenSLES -ldl
|
|||
OBJS = $(patsubst %.c, $(PROJECT_BUILD_PATH)/obj/%.o, $(PROJECT_SOURCE_FILES))
|
||||
|
||||
# Android APK building process... some steps required...
|
||||
# NOTE: typing 'make' will invoke the default target entry called 'all',
|
||||
# NOTE: typing 'make' will invoke the default target entry called 'all'
|
||||
# TODO: Use apksigner for APK signing, jarsigner is not recommended
|
||||
all: create_temp_project_dirs \
|
||||
copy_project_required_libs \
|
||||
copy_project_resources \
|
||||
|
|
@ -170,8 +171,14 @@ all: create_temp_project_dirs \
|
|||
compile_project_class \
|
||||
compile_project_class_dex \
|
||||
create_project_apk_package \
|
||||
zipalign_project_apk_package \
|
||||
sign_project_apk_package
|
||||
sign_project_apk_package \
|
||||
zipalign_project_apk_package
|
||||
|
||||
# WARNING: About build signing process:
|
||||
# - If using apksigner, zipalign must be used before the APK file has been signed.
|
||||
# - If using jarsigner (not recommended), zipalign must be used after the APK file has been signed.
|
||||
# REF: https://developer.android.com/tools/zipalign
|
||||
# REF: https://developer.android.com/tools/apksigner
|
||||
|
||||
# Create required temp directories for APK building
|
||||
create_temp_project_dirs:
|
||||
|
|
|
|||
|
|
@ -359,6 +359,7 @@ CORE = \
|
|||
core/core_input_mouse_wheel \
|
||||
core/core_input_multitouch \
|
||||
core/core_loading_thread \
|
||||
core/core_random_sequence \
|
||||
core/core_random_values \
|
||||
core/core_scissor_test \
|
||||
core/core_smooth_pixelperfect \
|
||||
|
|
@ -588,6 +589,9 @@ core/core_input_multitouch: core/core_input_multitouch.c
|
|||
core/core_loading_thread: core/core_loading_thread.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -sUSE_PTHREADS=1
|
||||
|
||||
core/core_random_sequence: core/core_random_sequence.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
core/core_random_values: core/core_random_values.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ Examples using raylib core platform functionality like window creation, inputs,
|
|||
| 29 | [core_custom_frame_control](core/core_custom_frame_control.c) | <img src="core/core_custom_frame_control.png" alt="core_custom_frame_control" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) |
|
||||
| 30 | [core_smooth_pixelperfect](core/core_smooth_pixelperfect.c) | <img src="core/core_smooth_pixelperfect.png" alt="core_smooth_pixelperfect" width="80"> | ⭐️⭐️⭐️☆ | 3.7 | **4.0** | [Giancamillo Alessandroni](https://github.com/NotManyIdeasDev) |
|
||||
| 31 | [core_window_should_close](core/core_window_should_close.c) | <img src="core/core_window_should_close.png" alt="core_window_should_close" width="80"> | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
|
||||
| 32 | [core_random_sequence](core/core_random_sequence.c) | <img src="core/core_random_sequence.png" alt="core_random_sequence" width="80"> | ⭐️☆☆☆ | **5.0** | **5.0** | [REDl3east](https://github.com/REDl3east) |
|
||||
|
||||
### category: shapes
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,24 +1,14 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
// This has been tested to work with zig 0.11.0 (67709b6, Aug 4 2023) and zig 0.12.0-dev.2075+f5978181e (Jan 8 2024)
|
||||
//
|
||||
// anytype is used here to preserve compatibility, in 0.12.0dev the std.zig.CrossTarget type
|
||||
// was reworked into std.Target.Query and std.Build.ResolvedTarget. Using anytype allows
|
||||
// us to accept both CrossTarget and ResolvedTarget and act accordingly in getOsTagVersioned.
|
||||
fn add_module(comptime module: []const u8, b: *std.Build, target: anytype, optimize: std.builtin.OptimizeMode) !*std.Build.Step {
|
||||
if (comptime builtin.zig_version.minor >= 12 and @TypeOf(target) != std.Build.ResolvedTarget) {
|
||||
@compileError("Expected 'std.Build.ResolvedTarget' for argument 2 'target' in 'add_module', found '" ++ @typeName(@TypeOf(target)) ++ "'");
|
||||
} else if (comptime builtin.zig_version.minor == 11 and @TypeOf(target) != std.zig.CrossTarget) {
|
||||
@compileError("Expected 'std.zig.CrossTarget' for argument 2 'target' in 'add_module', found '" ++ @typeName(@TypeOf(target)) ++ "'");
|
||||
}
|
||||
|
||||
if (getOsTagVersioned(target) == .emscripten) {
|
||||
// This has been tested to work with zig 0.12.0
|
||||
fn add_module(comptime module: []const u8, b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) !*std.Build.Step {
|
||||
if (target.result.os.tag == .emscripten) {
|
||||
@panic("Emscripten building via Zig unsupported");
|
||||
}
|
||||
|
||||
const all = b.step(module, "All " ++ module ++ " examples");
|
||||
var dir = try openIterableDirVersioned(std.fs.cwd(), module);
|
||||
var dir = try std.fs.cwd().openDir(module, .{ .iterate = true });
|
||||
defer if (comptime builtin.zig_version.minor >= 12) dir.close();
|
||||
|
||||
var iter = dir.iterate();
|
||||
|
|
@ -29,28 +19,28 @@ fn add_module(comptime module: []const u8, b: *std.Build, target: anytype, optim
|
|||
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 getOsTagVersioned(target) == .windows) continue;
|
||||
if (std.mem.eql(u8, "core_loading_thread", name) and target.result.os.tag == .windows) continue;
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = name,
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
exe.addCSourceFile(.{ .file = .{ .path = path }, .flags = &.{} });
|
||||
exe.addCSourceFile(.{ .file = b.path(path), .flags = &.{} });
|
||||
exe.linkLibC();
|
||||
exe.addObjectFile(switch (getOsTagVersioned(target)) {
|
||||
.windows => .{ .path = "../zig-out/lib/raylib.lib" },
|
||||
.linux => .{ .path = "../zig-out/lib/libraylib.a" },
|
||||
.macos => .{ .path = "../zig-out/lib/libraylib.a" },
|
||||
.emscripten => .{ .path = "../zig-out/lib/libraylib.a" },
|
||||
exe.addObjectFile(switch (target.result.os.tag) {
|
||||
.windows => b.path("../zig-out/lib/raylib.lib"),
|
||||
.linux => b.path("../zig-out/lib/libraylib.a"),
|
||||
.macos => b.path("../zig-out/lib/libraylib.a"),
|
||||
.emscripten => b.path("../zig-out/lib/libraylib.a"),
|
||||
else => @panic("Unsupported OS"),
|
||||
});
|
||||
|
||||
exe.addIncludePath(.{ .path = "../src" });
|
||||
exe.addIncludePath(.{ .path = "../src/external" });
|
||||
exe.addIncludePath(.{ .path = "../src/external/glfw/include" });
|
||||
exe.addIncludePath(b.path("../src"));
|
||||
exe.addIncludePath(b.path("../src/external"));
|
||||
exe.addIncludePath(b.path("../src/external/glfw/include"));
|
||||
|
||||
switch (getOsTagVersioned(target)) {
|
||||
switch (target.result.os.tag) {
|
||||
.windows => {
|
||||
exe.linkSystemLibrary("winmm");
|
||||
exe.linkSystemLibrary("gdi32");
|
||||
|
|
@ -117,19 +107,3 @@ pub fn build(b: *std.Build) !void {
|
|||
all.dependOn(try add_module("text", b, target, optimize));
|
||||
all.dependOn(try add_module("textures", b, target, optimize));
|
||||
}
|
||||
|
||||
fn getOsTagVersioned(target: anytype) std.Target.Os.Tag {
|
||||
if (comptime builtin.zig_version.minor >= 12) {
|
||||
return target.result.os.tag;
|
||||
} else {
|
||||
return target.getOsTag();
|
||||
}
|
||||
}
|
||||
|
||||
fn openIterableDirVersioned(dir: std.fs.Dir, path: []const u8) !(if (builtin.zig_version.minor >= 12) std.fs.Dir else std.fs.IterableDir) {
|
||||
if (comptime builtin.zig_version.minor >= 12) {
|
||||
return dir.openDir(path, .{ .iterate = true });
|
||||
} else {
|
||||
return dir.openIterableDir(path, .{});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ int main(void)
|
|||
{
|
||||
if (!collision.hit)
|
||||
{
|
||||
ray = GetMouseRay(GetMousePosition(), camera);
|
||||
ray = GetScreenToWorldRay(GetMousePosition(), camera);
|
||||
|
||||
// Check collision between ray and box
|
||||
collision = GetRayCollisionBox(ray,
|
||||
|
|
|
|||
176
examples/core/core_random_sequence.c
Normal file
176
examples/core/core_random_sequence.c
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Generates a random sequence
|
||||
*
|
||||
* Example originally created with raylib 5.0, last time updated with raylib 5.0
|
||||
*
|
||||
* Example contributed by Dalton Overmyer (@REDl3east) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2023 Dalton Overmyer (@REDl3east)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
|
||||
#include <stdlib.h> // Required for: malloc() and free()
|
||||
|
||||
typedef struct ColorRect{
|
||||
Color c;
|
||||
Rectangle r;
|
||||
} ColorRect;
|
||||
|
||||
static Color GenerateRandomColor();
|
||||
static ColorRect* GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight);
|
||||
static void ShuffleColorRectSequence(ColorRect* rectangles, int rectCount);
|
||||
static void DrawTextCenterKeyHelp(const char* key, const char* text, int posX, int posY, int fontSize, Color color);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void) {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - Generates a random sequence");
|
||||
|
||||
int rectCount = 20;
|
||||
float rectSize = (float)screenWidth/rectCount;
|
||||
ColorRect* rectangles = GenerateRandomColorRectSequence(rectCount, rectSize, screenWidth, 0.75f * screenHeight);
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
if(IsKeyPressed(KEY_SPACE))
|
||||
{
|
||||
ShuffleColorRectSequence(rectangles, rectCount);
|
||||
}
|
||||
|
||||
if(IsKeyPressed(KEY_UP))
|
||||
{
|
||||
rectCount++;
|
||||
rectSize = (float)screenWidth/rectCount;
|
||||
free(rectangles);
|
||||
rectangles = GenerateRandomColorRectSequence(rectCount, rectSize, screenWidth, 0.75f * screenHeight);
|
||||
}
|
||||
|
||||
if(IsKeyPressed(KEY_DOWN))
|
||||
{
|
||||
if(rectCount >= 4){
|
||||
rectCount--;
|
||||
rectSize = (float)screenWidth/rectCount;
|
||||
free(rectangles);
|
||||
rectangles = GenerateRandomColorRectSequence(rectCount, rectSize, screenWidth, 0.75f * screenHeight);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
int fontSize = 20;
|
||||
for(int x=0;x<rectCount;x++)
|
||||
{
|
||||
DrawRectangleRec(rectangles[x].r, rectangles[x].c);
|
||||
DrawTextCenterKeyHelp("SPACE", "to shuffle the sequence.", 10, screenHeight - 96, fontSize, BLACK);
|
||||
DrawTextCenterKeyHelp("UP", "to add a rectangle and generate a new sequence.", 10, screenHeight - 64, fontSize, BLACK);
|
||||
DrawTextCenterKeyHelp("DOWN", "to remove a rectangle and generate a new sequence.", 10, screenHeight - 32, fontSize, BLACK);
|
||||
}
|
||||
|
||||
const char* rectCountText = TextFormat("%d rectangles", rectCount);
|
||||
int rectCountTextSize = MeasureText(rectCountText, fontSize);
|
||||
DrawText(rectCountText, screenWidth - rectCountTextSize - 10, 10, fontSize, BLACK);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
free(rectangles);
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Color GenerateRandomColor()
|
||||
{
|
||||
return CLITERAL(Color){
|
||||
GetRandomValue(0, 255),
|
||||
GetRandomValue(0, 255),
|
||||
GetRandomValue(0, 255),
|
||||
255,
|
||||
};
|
||||
}
|
||||
|
||||
static ColorRect* GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight){
|
||||
int *seq = LoadRandomSequence(rectCount, 0, rectCount-1);
|
||||
ColorRect* rectangles = (ColorRect *)malloc(rectCount*sizeof(ColorRect));
|
||||
|
||||
float rectSeqWidth = rectCount * rectWidth;
|
||||
int startX = (screenWidth - rectSeqWidth) * 0.5f;
|
||||
|
||||
for(int x=0;x<rectCount;x++){
|
||||
int rectHeight = Remap(seq[x], 0, rectCount-1, 0, screenHeight);
|
||||
rectangles[x].c = GenerateRandomColor();
|
||||
rectangles[x].r = CLITERAL(Rectangle){
|
||||
startX + x * rectWidth, screenHeight - rectHeight, rectWidth, rectHeight
|
||||
};
|
||||
}
|
||||
UnloadRandomSequence(seq);
|
||||
return rectangles;
|
||||
}
|
||||
|
||||
static void ShuffleColorRectSequence(ColorRect* rectangles, int rectCount)
|
||||
{
|
||||
int *seq = LoadRandomSequence(rectCount, 0, rectCount-1);
|
||||
for(int i1=0;i1<rectCount;i1++){
|
||||
ColorRect* r1 = &rectangles[i1];
|
||||
ColorRect* r2 = &rectangles[seq[i1]];
|
||||
|
||||
// swap only the color and height
|
||||
ColorRect tmp = *r1;
|
||||
r1->c = r2->c;
|
||||
r1->r.height = r2->r.height;
|
||||
r1->r.y = r2->r.y;
|
||||
r2->c = tmp.c;
|
||||
r2->r.height = tmp.r.height;
|
||||
r2->r.y = tmp.r.y;
|
||||
|
||||
}
|
||||
UnloadRandomSequence(seq);
|
||||
}
|
||||
|
||||
static void DrawTextCenterKeyHelp(const char* key, const char* text, int posX, int posY, int fontSize, Color color)
|
||||
{
|
||||
int spaceSize = MeasureText(" ", fontSize);
|
||||
int pressSize = MeasureText("Press", fontSize);
|
||||
int keySize = MeasureText(key, fontSize);
|
||||
int textSize = MeasureText(text, fontSize);
|
||||
int totalSize = pressSize + 2 * spaceSize + keySize + 2 * spaceSize + textSize;
|
||||
int textSizeCurrent = 0;
|
||||
|
||||
DrawText("Press", posX, posY, fontSize, color);
|
||||
textSizeCurrent += pressSize + 2 * spaceSize;
|
||||
DrawText(key, posX + textSizeCurrent, posY, fontSize, RED);
|
||||
DrawRectangle(posX + textSizeCurrent, posY + fontSize, keySize, 3, RED);
|
||||
textSizeCurrent += keySize + 2 * spaceSize;
|
||||
DrawText(text, posX + textSizeCurrent, posY, fontSize, color);
|
||||
}
|
||||
BIN
examples/core/core_random_sequence.png
Normal file
BIN
examples/core/core_random_sequence.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
177
examples/models/models_bone_socket.c
Normal file
177
examples/models/models_bone_socket.c
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Using bones as socket for calculating the positioning of something
|
||||
*
|
||||
* Example originally created with raylib 4.5, last time updated with raylib 4.5
|
||||
*
|
||||
* Example contributed by iP (@ipzaur) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2024 iP (@ipzaur)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "raymath.h"
|
||||
|
||||
#define BONE_SOCKETS 3
|
||||
#define BONE_SOCKET_HAT 0
|
||||
#define BONE_SOCKET_HAND_R 1
|
||||
#define BONE_SOCKET_HAND_L 2
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - bone socket");
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = { 0 };
|
||||
camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position
|
||||
camera.target = (Vector3){ 0.0f, 2.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 projection type
|
||||
|
||||
// Load gltf model
|
||||
Model characterModel = LoadModel("resources/models/gltf/greenman.glb"); // Load character model
|
||||
Model equipModel[BONE_SOCKETS] = {
|
||||
LoadModel("resources/models/gltf/greenman_hat.glb"), // Index for the hat model is the same as BONE_SOCKET_HAT
|
||||
LoadModel("resources/models/gltf/greenman_sword.glb"), // Index for the sword model is the same as BONE_SOCKET_HAND_R
|
||||
LoadModel("resources/models/gltf/greenman_shield.glb") // Index for the shield model is the same as BONE_SOCKET_HAND_L
|
||||
};
|
||||
|
||||
bool showEquip[3] = { true, true, true }; // Toggle on/off equip
|
||||
|
||||
// Load gltf model animations
|
||||
int animsCount = 0;
|
||||
unsigned int animIndex = 0;
|
||||
unsigned int animCurrentFrame = 0;
|
||||
ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/greenman.glb", &animsCount);
|
||||
|
||||
// indices of bones for sockets
|
||||
int boneSocketIndex[BONE_SOCKETS] = { -1, -1, -1 };
|
||||
|
||||
// search bones for sockets
|
||||
for (int i = 0; i < characterModel.boneCount; i++)
|
||||
{
|
||||
if (TextIsEqual(characterModel.bones[i].name, "socket_hat"))
|
||||
{
|
||||
boneSocketIndex[BONE_SOCKET_HAT] = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TextIsEqual(characterModel.bones[i].name, "socket_hand_R"))
|
||||
{
|
||||
boneSocketIndex[BONE_SOCKET_HAND_R] = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TextIsEqual(characterModel.bones[i].name, "socket_hand_L"))
|
||||
{
|
||||
boneSocketIndex[BONE_SOCKET_HAND_L] = i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||
unsigned short angle = 0; // Set angle for rotate character
|
||||
|
||||
DisableCursor(); // Limit cursor to relative movement inside the window
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_THIRD_PERSON);
|
||||
|
||||
// Rotate character
|
||||
if (IsKeyDown(KEY_F)) angle = (angle + 1)%360;
|
||||
else if (IsKeyDown(KEY_H)) angle = (360 + angle - 1)%360;
|
||||
|
||||
// Select current animation
|
||||
if (IsKeyPressed(KEY_T)) animIndex = (animIndex + 1)%animsCount;
|
||||
else if (IsKeyPressed(KEY_G)) animIndex = (animIndex + animsCount - 1)%animsCount;
|
||||
|
||||
// Toggle shown of equip
|
||||
if (IsKeyPressed(KEY_ONE)) showEquip[BONE_SOCKET_HAT] = !showEquip[BONE_SOCKET_HAT];
|
||||
if (IsKeyPressed(KEY_TWO)) showEquip[BONE_SOCKET_HAND_R] = !showEquip[BONE_SOCKET_HAND_R];
|
||||
if (IsKeyPressed(KEY_THREE)) showEquip[BONE_SOCKET_HAND_L] = !showEquip[BONE_SOCKET_HAND_L];
|
||||
|
||||
// Update model animation
|
||||
ModelAnimation anim = modelAnimations[animIndex];
|
||||
animCurrentFrame = (animCurrentFrame + 1)%anim.frameCount;
|
||||
UpdateModelAnimation(characterModel, anim, animCurrentFrame);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
// Draw character
|
||||
Quaternion characterRotate = QuaternionFromAxisAngle((Vector3){ 0.0f, 1.0f, 0.0f }, angle*DEG2RAD);
|
||||
characterModel.transform = MatrixMultiply(QuaternionToMatrix(characterRotate), MatrixTranslate(position.x, position.y, position.z));
|
||||
UpdateModelAnimation(characterModel, anim, animCurrentFrame);
|
||||
DrawMesh(characterModel.meshes[0], characterModel.materials[1], characterModel.transform);
|
||||
|
||||
// Draw equipments (hat, sword, shield)
|
||||
for (int i = 0; i < BONE_SOCKETS; i++)
|
||||
{
|
||||
if (!showEquip[i]) continue;
|
||||
|
||||
Transform *transform = &anim.framePoses[animCurrentFrame][boneSocketIndex[i]];
|
||||
Quaternion inRotation = characterModel.bindPose[boneSocketIndex[i]].rotation;
|
||||
Quaternion outRotation = transform->rotation;
|
||||
|
||||
// Calculate socket rotation (angle between bone in initial pose and same bone in current animation frame)
|
||||
Quaternion rotate = QuaternionMultiply(outRotation, QuaternionInvert(inRotation));
|
||||
Matrix matrixTransform = QuaternionToMatrix(rotate);
|
||||
// Translate socket to its position in the current animation
|
||||
matrixTransform = MatrixMultiply(matrixTransform, MatrixTranslate(transform->translation.x, transform->translation.y, transform->translation.z));
|
||||
// Transform the socket using the transform of the character (angle and translate)
|
||||
matrixTransform = MatrixMultiply(matrixTransform, characterModel.transform);
|
||||
|
||||
// Draw mesh at socket position with socket angle rotation
|
||||
DrawMesh(equipModel[i].meshes[0], equipModel[i].materials[1], matrixTransform);
|
||||
}
|
||||
|
||||
DrawGrid(10, 1.0f);
|
||||
EndMode3D();
|
||||
|
||||
DrawText("Use the T/G to switch animation", 10, 10, 20, GRAY);
|
||||
DrawText("Use the F/H to rotate character left/right", 10, 35, 20, GRAY);
|
||||
DrawText("Use the 1,2,3 to toggle shown of hat, sword and shield", 10, 60, 20, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadModelAnimations(modelAnimations, animsCount);
|
||||
UnloadModel(characterModel); // Unload character model and meshes/material
|
||||
|
||||
// Unload equipment model and meshes/material
|
||||
for (int i = 0; i < BONE_SOCKETS; i++) UnloadModel(equipModel[i]);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
examples/models/models_bone_socket.png
Normal file
BIN
examples/models/models_bone_socket.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
|
|
@ -47,6 +47,8 @@ int main(void)
|
|||
|
||||
UnloadImage(image); // Unload cubesmap image from RAM, already uploaded to VRAM
|
||||
|
||||
bool pause = false; // Pause camera orbital rotation (and zoom)
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -55,7 +57,9 @@ int main(void)
|
|||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||
if (IsKeyPressed(KEY_P)) pause = !pause;
|
||||
|
||||
if (!pause) UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ int main(void)
|
|||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||
|
||||
Image imMap = LoadImage("resources/cubicmap.png"); // Load cubicmap image (RAM)
|
||||
Texture2D cubicmap = LoadTextureFromImage(imMap); // Convert image to texture to display (VRAM)
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ int main(void)
|
|||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
// Check collision between ray and box
|
||||
if (GetRayCollisionBox(GetMouseRay(GetMousePosition(), camera), bounds).hit) selected = !selected;
|
||||
if (GetRayCollisionBox(GetScreenToWorldRay(GetMousePosition(), camera), bounds).hit) selected = !selected;
|
||||
else selected = false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -17,117 +17,189 @@
|
|||
|
||||
#include "raymath.h" // Required for: MatrixTranslate()
|
||||
|
||||
#define MAX_VOX_FILES 3
|
||||
#define MAX_VOX_FILES 4
|
||||
|
||||
#define RLIGHTS_IMPLEMENTATION
|
||||
#include "rlights.h"
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#define GLSL_VERSION 330
|
||||
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||
#define GLSL_VERSION 100
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
// 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"
|
||||
};
|
||||
const char* voxFileNames[] = {
|
||||
"resources/models/vox/chr_knight.vox",
|
||||
"resources/models/vox/chr_sword.vox",
|
||||
"resources/models/vox/monu9.vox",
|
||||
"resources/models/vox/fez.vox"
|
||||
};
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - magicavoxel loading");
|
||||
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 projection type
|
||||
// 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 projection type
|
||||
|
||||
// Load MagicaVoxel files
|
||||
Model models[MAX_VOX_FILES] = { 0 };
|
||||
//--------------------------------------------------------------------------------------
|
||||
// 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;
|
||||
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));
|
||||
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));
|
||||
// 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;
|
||||
}
|
||||
Matrix matTranslate = MatrixTranslate(-center.x, 0, -center.z);
|
||||
models[i].transform = matTranslate;
|
||||
}
|
||||
|
||||
int currentModel = 0;
|
||||
int currentModel = 0;
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Load voxel shader
|
||||
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/voxel_lighting.vs", GLSL_VERSION),
|
||||
TextFormat("resources/shaders/glsl%i/voxel_lighting.fs", GLSL_VERSION));
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||
// Get some required shader locations
|
||||
shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
|
||||
// NOTE: "matModel" location name is automatically assigned on shader loading,
|
||||
// no need to get the location again if using that uniform name
|
||||
//shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel");
|
||||
|
||||
// Cycle between models on mouse click
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1)%MAX_VOX_FILES;
|
||||
// Ambient light level (some basic lighting)
|
||||
int ambientLoc = GetShaderLocation(shader, "ambient");
|
||||
SetShaderValue(shader, ambientLoc, (float[4]) { 0.1f, 0.1f, 0.1f, 1.0f }, SHADER_UNIFORM_VEC4);
|
||||
|
||||
// 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;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
// Assign out lighting shader to model
|
||||
for (int i = 0; i < MAX_VOX_FILES; i++)
|
||||
{
|
||||
Model m = models[i];
|
||||
for (int j = 0; j < m.materialCount; j++)
|
||||
{
|
||||
m.materials[j].shader = shader;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
// Create lights
|
||||
Light lights[MAX_LIGHTS] = { 0 };
|
||||
lights[0] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, -20 }, Vector3Zero(), GRAY, shader);
|
||||
lights[1] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, 20 }, Vector3Zero(), GRAY, shader);
|
||||
lights[2] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, 20 }, Vector3Zero(), GRAY, shader);
|
||||
lights[3] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, -20 }, Vector3Zero(), GRAY, shader);
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
// Draw 3D model
|
||||
BeginMode3D(camera);
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
|
||||
DrawModel(models[currentModel], (Vector3){ 0, 0, 0 }, 1.0f, WHITE);
|
||||
DrawGrid(10, 1.0);
|
||||
//--------------------------------------------------------------------------------------
|
||||
Vector3 modelpos = { 0 };
|
||||
Vector3 camerarot = { 0 };
|
||||
|
||||
EndMode3D();
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE))
|
||||
{
|
||||
const Vector2 mouseDelta = GetMouseDelta();
|
||||
camerarot.x = mouseDelta.x * 0.05f;
|
||||
camerarot.y = mouseDelta.y * 0.05f;
|
||||
}
|
||||
else
|
||||
{
|
||||
camerarot.x = 0;
|
||||
camerarot.y = 0;
|
||||
}
|
||||
|
||||
// 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);
|
||||
UpdateCameraPro(&camera,
|
||||
(Vector3) {
|
||||
(IsKeyDown(KEY_W) || IsKeyDown(KEY_UP)) * 0.1f - // Move forward-backward
|
||||
(IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN)) * 0.1f,
|
||||
(IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT)) * 0.1f - // Move right-left
|
||||
(IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT)) * 0.1f,
|
||||
0.0f // Move up-down
|
||||
},
|
||||
camerarot,
|
||||
GetMouseWheelMove() * -2.0f); // Move to target (zoom)
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
// Cycle between models on mouse click
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1) % MAX_VOX_FILES;
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Unload models data (GPU VRAM)
|
||||
for (int i = 0; i < MAX_VOX_FILES; i++) UnloadModel(models[i]);
|
||||
// Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f })
|
||||
float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z };
|
||||
SetShaderValue(shader, shader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Update light values (actually, only enable/disable them)
|
||||
for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(shader, lights[i]);
|
||||
|
||||
return 0;
|
||||
//----------------------------------------------------------------------------------
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
// Draw 3D model
|
||||
BeginMode3D(camera);
|
||||
|
||||
DrawModel(models[currentModel], modelpos, 1.0f, WHITE);
|
||||
DrawGrid(10, 1.0);
|
||||
|
||||
// Draw spheres to show where the lights are
|
||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||
{
|
||||
if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lights[i].color);
|
||||
else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lights[i].color, 0.3f));
|
||||
}
|
||||
|
||||
EndMode3D();
|
||||
|
||||
// Display info
|
||||
DrawRectangle(10, 400, 340, 60, Fade(SKYBLUE, 0.5f));
|
||||
DrawRectangleLines(10, 400, 340, 60, Fade(DARKBLUE, 0.5f));
|
||||
DrawText("MOUSE LEFT BUTTON to CYCLE VOX MODELS", 40, 410, 10, BLUE);
|
||||
DrawText("MOUSE MIDDLE BUTTON to ZOOM OR ROTATE CAMERA", 40, 420, 10, BLUE);
|
||||
DrawText("UP-DOWN-LEFT-RIGHT KEYS to MOVE CAMERA", 40, 430, 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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ int main(void)
|
|||
Color cursorColor = WHITE;
|
||||
|
||||
// Get ray and test against objects
|
||||
ray = GetMouseRay(GetMousePosition(), camera);
|
||||
ray = GetScreenToWorldRay(GetMousePosition(), camera);
|
||||
|
||||
// Check ray collision against ground quad
|
||||
RayCollision groundHitInfo = GetRayCollisionQuad(ray, g0, g1, g2, g3);
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ static TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int s
|
|||
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);
|
||||
Matrix matFboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, rlGetCullDistanceNear(), rlGetCullDistanceFar());
|
||||
rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_PROJECTION], matFboProjection);
|
||||
|
||||
// Define view matrix for every side of the cubemap
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue