diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 0f4b7c88..dd02215e 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -22,8 +22,8 @@ jobs: platform: # - { name: Windows VS2019, os: windows-2019 } # - { name: Windows VS2022, os: windows-2022 } - - { name: Linux GCC, os: ubuntu-20.04, flags: -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_STANDARD=17 } - - { name: Linux Clang, os: ubuntu-20.04, flags: -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_STANDARD=17 } + - { name: Linux GCC, os: ubuntu-22.04, flags: -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_STANDARD=17 } + - { name: Linux Clang, os: ubuntu-22.04, flags: -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_STANDARD=17 } #- { name: Linux GCC, os: ubuntu-18.04, flags: -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_STANDARD=14 } #- { name: Linux Clang, os: ubuntu-18.04, flags: -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_STANDARD=14 } # - { name: MacOS XCode, os: macos-latest } @@ -35,15 +35,15 @@ jobs: - { name: Debug, flags: -DCMAKE_BUILD_TYPE=Debug } steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: recursive - name: Install Linux Dependencies if: runner.os == 'Linux' - run: sudo apt-get install libasound2-dev libx11-dev libxrandr-dev libxi-dev libgl1-mesa-dev libglu1-mesa-dev libxcursor-dev libxinerama-dev -y + run: sudo apt-get update && sudo apt-get install -y libasound2-dev libx11-dev libxrandr-dev libxi-dev libgl1-mesa-dev libglu1-mesa-dev libxcursor-dev libxinerama-dev - name: Configure - run: cmake -B build -S . -DBUILD_TESTING=ON -DCMAKE_CXX_FLAGS="-Wall -Wextra -Wpedantic" ${{ matrix.platform.flags }} ${{ matrix.type.flags }} ${{ matrix.config.flags }} + run: cmake -B build -S . -DGLFW_BUILD_WAYLAND=OFF -DBUILD_TESTING=ON -DCMAKE_CXX_FLAGS="-Wall -Wextra -Wpedantic" ${{ matrix.platform.flags }} ${{ matrix.type.flags }} ${{ matrix.config.flags }} - name: Build run: cmake --build build diff --git a/CMakeLists.txt b/CMakeLists.txt index 619e3bc7..b4340f70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.11) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") project (raylib_cpp - VERSION 5.0.1 + VERSION 5.0.2 DESCRIPTION "raylib-cpp C++ Object Oriented Wrapper for raylib" HOMEPAGE_URL "https://github.com/robloach/raylib-cpp" LANGUAGES C CXX diff --git a/clib.json b/clib.json index 5a5fafba..bbdd1cc9 100644 --- a/clib.json +++ b/clib.json @@ -32,6 +32,7 @@ "include/Functions.hpp", "include/Gamepad.hpp", "include/Image.hpp", + "include/Keyboard.hpp", "include/Material.hpp", "include/Matrix.hpp", "include/Mesh.hpp", diff --git a/examples/models/models_first_person_maze.cpp b/examples/models/models_first_person_maze.cpp index 32d1a175..4910aa79 100644 --- a/examples/models/models_first_person_maze.cpp +++ b/examples/models/models_first_person_maze.cpp @@ -25,7 +25,7 @@ int main(void) raylib::Image imMap("resources/cubicmap.png"); // Load cubicmap image (RAM) raylib::Texture cubicmap(imMap); // Convert image to texture to display (VRAM) - Mesh mesh = raylib::Mesh::Cubicmap(imMap, Vector3{ 1.0f, 1.0f, 1.0f }); + raylib::MeshUnmanaged mesh = raylib::MeshUnmanaged::Cubicmap(imMap, Vector3{ 1.0f, 1.0f, 1.0f }); // Use MeshUnmanaged, Mesh will be handled by Model raylib::Model model(mesh); // NOTE: By default each cube is mapped to one part of texture atlas diff --git a/include/AudioStream.hpp b/include/AudioStream.hpp index 8edde003..0f3d685a 100644 --- a/include/AudioStream.hpp +++ b/include/AudioStream.hpp @@ -48,11 +48,11 @@ class AudioStream : public ::AudioStream { Unload(); } - GETTERSETTER(rAudioBuffer *, Buffer, buffer) - GETTERSETTER(rAudioProcessor *, Processor, processor) - GETTERSETTER(unsigned int, SampleRate, sampleRate) - GETTERSETTER(unsigned int, SampleSize, sampleSize) - GETTERSETTER(unsigned int, Channels, channels) + GETTER(rAudioBuffer *, Buffer, buffer) + GETTER(rAudioProcessor *, Processor, processor) + GETTER(unsigned int, SampleRate, sampleRate) + GETTER(unsigned int, SampleSize, sampleSize) + GETTER(unsigned int, Channels, channels) AudioStream& operator=(const ::AudioStream& stream) { set(stream); @@ -90,7 +90,9 @@ class AudioStream : public ::AudioStream { * Unload audio stream and free memory */ void Unload() { - ::UnloadAudioStream(*this); + if (IsReady()) { + ::UnloadAudioStream(*this); + } } /** @@ -159,7 +161,7 @@ class AudioStream : public ::AudioStream { * Set pan for audio stream (0.5 is centered) */ AudioStream& SetPan(float pan = 0.5f) { - ::SetAudioStreamPitch(*this, pan); + ::SetAudioStreamPan(*this, pan); return *this; } @@ -181,14 +183,14 @@ class AudioStream : public ::AudioStream { * Attach audio stream processor to stream */ void AttachProcessor(::AudioCallback processor) { - ::SetAudioStreamCallback(*this, processor); + ::AttachAudioStreamProcessor(*this, processor); } /** * Detach audio stream processor from stream */ void DetachProcessor(::AudioCallback processor) { - ::SetAudioStreamCallback(*this, processor); + ::DetachAudioStreamProcessor(*this, processor); } /** diff --git a/include/AutomationEventList.hpp b/include/AutomationEventList.hpp index 77001989..3271aec9 100644 --- a/include/AutomationEventList.hpp +++ b/include/AutomationEventList.hpp @@ -15,12 +15,18 @@ class AutomationEventList : public ::AutomationEventList { set(automationEventList); } - AutomationEventList(unsigned int capacity = 16384, - unsigned int count = 0, - AutomationEvent *events = nullptr) : ::AutomationEventList{capacity, count, events} { - // Nothing. + /** + * Load an empty automation events list. + */ + AutomationEventList() { + set(::LoadAutomationEventList(0)); } + /** + * Load automation events list from file. + * + * @param fileName The file path to load the automation events list from. + */ AutomationEventList(const char* fileName) { Load(fileName); } @@ -39,9 +45,9 @@ class AutomationEventList : public ::AutomationEventList { Unload(); } - GETTERSETTER(unsigned int, Capacity, capacity) - GETTERSETTER(unsigned int, Count, count) - GETTERSETTER(AutomationEvent*, Events, events) + GETTER(unsigned int, Capacity, capacity) + GETTER(unsigned int, Count, count) + GETTER(AutomationEvent*, Events, events) AutomationEventList& operator=(const ::AutomationEventList& other) { set(other); @@ -81,9 +87,21 @@ class AutomationEventList : public ::AutomationEventList { /** * Update audio stream buffers with data */ - AutomationEventList& Unload() { - ::UnloadAutomationEventList(this); - return *this; + void Unload() { + if (!IsReady()) { + return; + } + + // The function signature of UnloadAutomationEventList() changes from raylib 5.0. + #if RAYLIB_VERSION_MAJOR == 5 + #if RAYLIB_VERSION_MINOR == 0 + ::UnloadAutomationEventList(this); + #elif RAYLIB_VERSION_MINOR >= 1 + ::UnloadAutomationEventList(*this); + #endif + #else + ::UnloadAutomationEventList(*this); + #endif } bool IsReady() { @@ -114,7 +132,7 @@ class AutomationEventList : public ::AutomationEventList { } void Play(int index) { - if (index < 0 || index >= this->count) { + if (index < 0 || static_cast(index) >= this->count) { return; } diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 07be5c7a..83a1951a 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,48 +1,56 @@ add_library(raylib_cpp INTERFACE) +set(RAYLIB_CPP_HEADERS + AudioDevice.hpp + AudioStream.hpp + AutomationEventList.hpp + BoundingBox.hpp + Camera2D.hpp + Camera3D.hpp + Color.hpp + FileData.hpp + FileText.hpp + Font.hpp + Functions.hpp + Gamepad.hpp + Image.hpp + Keyboard.hpp + Material.hpp + Matrix.hpp + Mesh.hpp + MeshUnmanaged.hpp + Model.hpp + ModelAnimation.hpp + Mouse.hpp + Music.hpp + Ray.hpp + RayCollision.hpp + RaylibException.hpp + raylib-cpp-utils.hpp + raylib-cpp.hpp + raylib.hpp + raymath.hpp + Rectangle.hpp + RenderTexture.hpp + Shader.hpp + Sound.hpp + Text.hpp + Texture.hpp + TextureUnmanaged.hpp + Touch.hpp + Vector2.hpp + Vector3.hpp + Vector4.hpp + VrStereoConfig.hpp + Wave.hpp + Window.hpp +) + # Include Directory target_include_directories(raylib_cpp INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/) # Set the header files as install files. install(FILES - AudioDevice.hpp - AudioStream.hpp - AutomationEventList.hpp - BoundingBox.hpp - Camera2D.hpp - Camera3D.hpp - Color.hpp - Font.hpp - Functions.hpp - Gamepad.hpp - Image.hpp - Material.hpp - Matrix.hpp - Mesh.hpp - Model.hpp - ModelAnimation.hpp - Mouse.hpp - Music.hpp - Ray.hpp - RayCollision.hpp - RaylibException.hpp - raylib-cpp-utils.hpp - raylib-cpp.hpp - raylib.hpp - raymath.hpp - Rectangle.hpp - RenderTexture.hpp - Shader.hpp - Sound.hpp - Text.hpp - Texture.hpp - TextureUnmanaged.hpp - Touch.hpp - Vector2.hpp - Vector3.hpp - Vector4.hpp - VrStereoConfig.hpp - Wave.hpp - Window.hpp - DESTINATION include + ${RAYLIB_CPP_HEADERS} + DESTINATION include ) diff --git a/include/Camera3D.hpp b/include/Camera3D.hpp index 67cd19f6..641b5158 100644 --- a/include/Camera3D.hpp +++ b/include/Camera3D.hpp @@ -129,7 +129,7 @@ class Camera3D : public ::Camera3D { } }; -typedef Camera3D Camera; +using Camera = Camera3D; } // namespace raylib diff --git a/include/Color.hpp b/include/Color.hpp index edf6b200..fdb25f7a 100644 --- a/include/Color.hpp +++ b/include/Color.hpp @@ -159,15 +159,35 @@ class Color : public ::Color { ::DrawLineStrip(points, numPoints, *this); } + void DrawText(const char* text, int posX = 0, int posY = 0, int fontSize = 10.0f) const { + ::DrawText(text, posX, posY, fontSize, *this); + } + void DrawText(const std::string& text, int posX = 0, int posY = 0, int fontSize = 10.0f) const { ::DrawText(text.c_str(), posX, posY, fontSize, *this); } + void DrawText(const ::Font& font, const char* text, ::Vector2 position, + float fontSize, float spacing) const { + ::DrawTextEx(font, text, position, fontSize, spacing, *this); + } + void DrawText(const ::Font& font, const std::string& text, ::Vector2 position, float fontSize, float spacing) const { ::DrawTextEx(font, text.c_str(), position, fontSize, spacing, *this); } + void DrawText( + const ::Font& font, + const char* text, + ::Vector2 position, + ::Vector2 origin, + float rotation, + float fontSize, + float spacing) const { + ::DrawTextPro(font, text, position, origin, rotation, fontSize, spacing, *this); + } + void DrawText( const ::Font& font, const std::string& text, diff --git a/include/FileData.hpp b/include/FileData.hpp new file mode 100644 index 00000000..664d4c24 --- /dev/null +++ b/include/FileData.hpp @@ -0,0 +1,56 @@ +#ifndef RAYLIB_CPP_INCLUDE_FILEDATA_HPP_ +#define RAYLIB_CPP_INCLUDE_FILEDATA_HPP_ + +#include +#include + +#include "./raylib.hpp" +#include "./raylib-cpp-utils.hpp" + +namespace raylib { + +class FileData { + public: + FileData() = default; + FileData(const FileData&) = delete; + FileData(FileData&& other) noexcept : data(other.data), bytesRead(other.bytesRead) { + other.data = nullptr; + other.bytesRead = 0; + } + FileData& operator=(const FileData&) = delete; + FileData& operator=(FileData&& other) noexcept { + std::swap(data, other.data); + std::swap(bytesRead, other.bytesRead); + return *this; + } + ~FileData() { Unload(); } + + explicit FileData(const std::string& fileName) { + Load(fileName); + } + + GETTER(const unsigned char*, Data, data) + GETTER(int, BytesRead, bytesRead) + + void Load(const std::string& fileName) { Load(fileName.c_str()); } + void Load(const char* fileName) { + data = ::LoadFileData(fileName, &bytesRead); + } + + void Unload() { + if (data != nullptr) { + ::UnloadFileData(data); + data = nullptr; + } + } + + private: + unsigned char* data{nullptr}; + int bytesRead{0}; +}; + +} // namespace raylib + +using RFileData = raylib::FileData; + +#endif // RAYLIB_CPP_INCLUDE_FILEDATA_HPP_ diff --git a/include/FileText.hpp b/include/FileText.hpp new file mode 100644 index 00000000..2b411614 --- /dev/null +++ b/include/FileText.hpp @@ -0,0 +1,65 @@ +#ifndef RAYLIB_CPP_INCLUDE_FILETEXT_HPP_ +#define RAYLIB_CPP_INCLUDE_FILETEXT_HPP_ + +#include +#include + +#include "./raylib.hpp" +#include "./raylib-cpp-utils.hpp" + +namespace raylib { + +class FileText { + public: + FileText() = default; + FileText(const FileText&) = delete; + FileText(FileText&& other) noexcept : data(other.data), length(other.length) { + other.data = nullptr; + other.length = 0; + } + FileText& operator=(const FileText&) = delete; + FileText& operator=(FileText&& other) noexcept { + std::swap(data, other.data); + std::swap(length, other.length); + return *this; + } + ~FileText() { Unload(); } + + explicit FileText(const std::string& fileName) { + Load(fileName); + } + + GETTER(const char*, Data, data) + GETTER(unsigned int, Length, length) + + [[nodiscard]] const char* c_str() const { return data; } + + [[nodiscard]] std::string ToString() const { return data; } + explicit operator std::string() const { + return data; + } + + void Load(const std::string& fileName) { Load(fileName.c_str()); } + void Load(const char* fileName) { + data = ::LoadFileText(fileName); + length = ::TextLength(data); + } + + void Unload() { + if (data != nullptr) { + ::UnloadFileText(data); + data = nullptr; + length = 0; + } + } + + private: + char* data{nullptr}; + unsigned int length{0}; +}; + +} // namespace raylib + +using RFileText = raylib::FileText; + +#endif // RAYLIB_CPP_INCLUDE_FILETEXT_HPP_ diff --git a/include/Font.hpp b/include/Font.hpp index 7ac33dd0..a77e56ce 100644 --- a/include/Font.hpp +++ b/include/Font.hpp @@ -108,11 +108,11 @@ class Font : public ::Font { } } - GETTERSETTER(int, BaseSize, baseSize) - GETTERSETTER(int, GlyphCount, glyphCount) - GETTERSETTER(int, GlyphPadding, glyphPadding) - GETTERSETTER(::Rectangle*, Recs, recs) - GETTERSETTER(::GlyphInfo*, Glyphs, glyphs) + GETTER(int, BaseSize, baseSize) + GETTER(int, GlyphCount, glyphCount) + GETTER(int, GlyphPadding, glyphPadding) + GETTER(::Rectangle*, Recs, recs) + GETTER(::GlyphInfo*, Glyphs, glyphs) /** * Get the texture atlas containing the glyphs. @@ -166,7 +166,7 @@ class Font : public ::Font { void Load(const std::string& fileName) { set(::LoadFont(fileName.c_str())); if (!IsReady()) { - throw new RaylibException("Failed to load Font with from file: " + fileName); + throw RaylibException("Failed to load Font with from file: " + fileName); } } @@ -183,14 +183,14 @@ class Font : public ::Font { void Load(const std::string& fileName, int fontSize, int* fontChars, int charCount) { set(::LoadFontEx(fileName.c_str(), fontSize, fontChars, charCount)); if (!IsReady()) { - throw new RaylibException("Failed to load Font with from file with font size: " + fileName); + throw RaylibException("Failed to load Font with from file with font size: " + fileName); } } void Load(const ::Image& image, ::Color key, int firstChar) { set(::LoadFontFromImage(image, key, firstChar)); if (!IsReady()) { - throw new RaylibException("Failed to load Font with from image"); + throw RaylibException("Failed to load Font with from image"); } } @@ -199,7 +199,7 @@ class Font : public ::Font { set(::LoadFontFromMemory(fileType.c_str(), fileData, dataSize, fontSize, fontChars, charsCount)); if (!IsReady()) { - throw new RaylibException("Failed to load Font " + fileType + " with from file data"); + throw RaylibException("Failed to load Font " + fileType + " with from file data"); } } @@ -210,6 +210,14 @@ class Font : public ::Font { return ::IsFontReady(*this); } + /** + * Draw text using font and additional parameters. + */ + void DrawText(const char* text, ::Vector2 position, float fontSize, + float spacing, ::Color tint = WHITE) const { + ::DrawTextEx(*this, text, position, fontSize, spacing, tint); + } + /** * Draw text using font and additional parameters. */ @@ -218,6 +226,16 @@ class Font : public ::Font { ::DrawTextEx(*this, text.c_str(), position, fontSize, spacing, tint); } + /** + * Draw text using font and additional parameters. + */ + void DrawText(const char* text, int posX, int posY, float fontSize, + float spacing, ::Color tint = WHITE) const { + ::DrawTextEx(*this, text, + { static_cast(posX), static_cast(posY) }, + fontSize, spacing, tint); + } + /** * Draw text using font and additional parameters. */ @@ -228,6 +246,20 @@ class Font : public ::Font { fontSize, spacing, tint); } + void DrawText( + const char* text, + ::Vector2 position, + ::Vector2 origin, + float rotation, + float fontSize, + float spacing, + ::Color tint = WHITE) const { + ::DrawTextPro(*this, text, + position, origin, + rotation, fontSize, + spacing, tint); + } + void DrawText( const std::string& text, ::Vector2 position, @@ -265,6 +297,13 @@ class Font : public ::Font { spacing, tint); } + /** + * Measure string size for Font + */ + Vector2 MeasureText(const char* text, float fontSize, float spacing) const { + return ::MeasureTextEx(*this, text, fontSize, spacing); + } + /** * Measure string size for Font */ @@ -279,6 +318,14 @@ class Font : public ::Font { return ::GetGlyphIndex(*this, character); } + /** + * Create an image from text (custom sprite font) + */ + ::Image ImageText(const char* text, float fontSize, + float spacing, ::Color tint) const { + return ::ImageTextEx(*this, text, fontSize, spacing, tint); + } + /** * Create an image from text (custom sprite font) */ diff --git a/include/Functions.hpp b/include/Functions.hpp index ac309d97..d79e0f05 100644 --- a/include/Functions.hpp +++ b/include/Functions.hpp @@ -21,56 +21,56 @@ namespace raylib { /** * Initialize window and OpenGL context */ -RLCPPAPI inline void InitWindow(int width, int height, const std::string& title = "raylib") { +[[maybe_unused]] RLCPPAPI inline void InitWindow(int width, int height, const std::string& title = "raylib") { ::InitWindow(width, height, title.c_str()); } /** * Set title for window */ -RLCPPAPI inline void SetWindowTitle(const std::string& title) { +[[maybe_unused]] RLCPPAPI inline void SetWindowTitle(const std::string& title) { ::SetWindowTitle(title.c_str()); } /** * Get the human-readable, UTF-8 encoded name of the primary monitor */ -RLCPPAPI inline std::string GetMonitorName(int monitor = 0) { +[[maybe_unused]] RLCPPAPI inline std::string GetMonitorName(int monitor = 0) { return ::GetMonitorName(monitor); } /** * Set clipboard text content */ -RLCPPAPI inline void SetClipboardText(const std::string& text) { +[[maybe_unused]] RLCPPAPI inline void SetClipboardText(const std::string& text) { ::SetClipboardText(text.c_str()); } /** * Get clipboard text content */ -RLCPPAPI inline std::string GetClipboardText() { +[[maybe_unused]] RLCPPAPI inline std::string GetClipboardText() { return ::GetClipboardText(); } /** * Takes a screenshot of current screen (saved a .png) */ -RLCPPAPI inline void TakeScreenshot(const std::string& fileName) { +[[maybe_unused]] RLCPPAPI inline void TakeScreenshot(const std::string& fileName) { ::TakeScreenshot(fileName.c_str()); } /** * Get gamepad internal name id */ -RLCPPAPI inline std::string GetGamepadName(int gamepad) { +[[maybe_unused]] RLCPPAPI inline std::string GetGamepadName(int gamepad) { return ::GetGamepadName(gamepad); } /** * Load text data from file (read) */ -RLCPPAPI std::string LoadFileText(const std::string& fileName) { +[[maybe_unused]] RLCPPAPI std::string LoadFileText(const std::string& fileName) { char* text = ::LoadFileText(fileName.c_str()); std::string output(text); ::UnloadFileText(text); @@ -80,77 +80,77 @@ RLCPPAPI std::string LoadFileText(const std::string& fileName) { /** * Save text data to file (write) */ -RLCPPAPI inline bool SaveFileText(const std::string& fileName, const std::string& text) { +[[maybe_unused]] RLCPPAPI inline bool SaveFileText(const std::string& fileName, const std::string& text) { return ::SaveFileText(fileName.c_str(), const_cast(text.c_str())); } /** * Check if file exists */ -RLCPPAPI inline bool FileExists(const std::string& fileName) { +[[maybe_unused]] RLCPPAPI inline bool FileExists(const std::string& fileName) { return ::FileExists(fileName.c_str()); } /** * Check if directory path exists */ -RLCPPAPI inline bool DirectoryExists(const std::string& dirPath) { +[[maybe_unused]] RLCPPAPI inline bool DirectoryExists(const std::string& dirPath) { return ::DirectoryExists(dirPath.c_str()); } /** * Check file extension (including point: .png, .wav) */ -RLCPPAPI inline bool IsFileExtension(const std::string& fileName, const std::string& ext) { +[[maybe_unused]] RLCPPAPI inline bool IsFileExtension(const std::string& fileName, const std::string& ext) { return ::IsFileExtension(fileName.c_str(), ext.c_str()); } /** * Get pointer to extension for a filename string (including point: ".png") */ -RLCPPAPI inline std::string GetFileExtension(const std::string& fileName) { +[[maybe_unused]] RLCPPAPI inline std::string GetFileExtension(const std::string& fileName) { return ::GetFileExtension(fileName.c_str()); } /** * Get pointer to filename for a path string */ -RLCPPAPI inline std::string GetFileName(const std::string& filePath) { +[[maybe_unused]] RLCPPAPI inline std::string GetFileName(const std::string& filePath) { return ::GetFileName(filePath.c_str()); } /** * Get filename string without extension */ -RLCPPAPI inline std::string GetFileNameWithoutExt(const std::string& filePath) { +[[maybe_unused]] RLCPPAPI inline std::string GetFileNameWithoutExt(const std::string& filePath) { return ::GetFileNameWithoutExt(filePath.c_str()); } /** * Get full path for a given fileName with path */ -RLCPPAPI inline std::string GetDirectoryPath(const std::string& filePath) { +[[maybe_unused]] RLCPPAPI inline std::string GetDirectoryPath(const std::string& filePath) { return ::GetDirectoryPath(filePath.c_str()); } /** * Get previous directory path for a given path */ -RLCPPAPI inline std::string GetPrevDirectoryPath(const std::string& dirPath) { +[[maybe_unused]] RLCPPAPI inline std::string GetPrevDirectoryPath(const std::string& dirPath) { return ::GetPrevDirectoryPath(dirPath.c_str()); } /** * Get current working directory */ -RLCPPAPI inline std::string GetWorkingDirectory() { +[[maybe_unused]] RLCPPAPI inline std::string GetWorkingDirectory() { return ::GetWorkingDirectory(); } /** * Get filenames in a directory path */ -RLCPPAPI std::vector LoadDirectoryFiles(const std::string& dirPath) { +[[maybe_unused]] RLCPPAPI std::vector LoadDirectoryFiles(const std::string& dirPath) { FilePathList files = ::LoadDirectoryFiles(dirPath.c_str()); std::vector output(files.paths, files.paths + files.count); ::UnloadDirectoryFiles(files); @@ -160,14 +160,14 @@ RLCPPAPI std::vector LoadDirectoryFiles(const std::string& dirPath) /** * Change working directory, return true on success */ -RLCPPAPI inline bool ChangeDirectory(const std::string& dir) { +[[maybe_unused]] RLCPPAPI inline bool ChangeDirectory(const std::string& dir) { return ::ChangeDirectory(dir.c_str()); } /** * Get dropped files names */ -RLCPPAPI std::vector LoadDroppedFiles() { +[[maybe_unused]] RLCPPAPI std::vector LoadDroppedFiles() { if (!::IsFileDropped()) { return std::vector(); } @@ -180,28 +180,28 @@ RLCPPAPI std::vector LoadDroppedFiles() { /** * Get file modification time (last write time) */ -RLCPPAPI inline long GetFileModTime(const std::string& fileName) { // NOLINT +[[maybe_unused]] RLCPPAPI inline long GetFileModTime(const std::string& fileName) { // NOLINT return ::GetFileModTime(fileName.c_str()); } /** * Open URL with default system browser (if available) */ -RLCPPAPI inline void OpenURL(const std::string& url) { +[[maybe_unused]] RLCPPAPI inline void OpenURL(const std::string& url) { return ::OpenURL(url.c_str()); } /** * Load an image. */ -RLCPPAPI inline ::Image LoadImage(const std::string& fileName) { +[[maybe_unused]] RLCPPAPI inline ::Image LoadImage(const std::string& fileName) { return ::LoadImage(fileName.c_str()); } /** * Load an image from RAW file data */ -RLCPPAPI inline ::Image LoadImageRaw(const std::string& fileName, +[[maybe_unused]] RLCPPAPI inline ::Image LoadImageRaw(const std::string& fileName, int width, int height, int format, int headerSize) { return ::LoadImageRaw(fileName.c_str(), width, height, format, headerSize); @@ -210,14 +210,14 @@ RLCPPAPI inline ::Image LoadImageRaw(const std::string& fileName, /** * Load animated image data */ -RLCPPAPI inline ::Image LoadImageAnim(const std::string& fileName, int *frames) { +[[maybe_unused]] RLCPPAPI inline ::Image LoadImageAnim(const std::string& fileName, int *frames) { return ::LoadImageAnim(fileName.c_str(), frames); } /** * Load image from memory buffer, fileType refers to extension like "png" */ -RLCPPAPI inline ::Image LoadImageFromMemory(const std::string& fileType, +[[maybe_unused]] RLCPPAPI inline ::Image LoadImageFromMemory(const std::string& fileType, const unsigned char *fileData, int dataSize) { return ::LoadImageFromMemory(fileType.c_str(), fileData, dataSize); @@ -226,28 +226,47 @@ RLCPPAPI inline ::Image LoadImageFromMemory(const std::string& fileType, /** * Export image data to file */ -RLCPPAPI inline bool ExportImage(const Image& image, const std::string& fileName) { +[[maybe_unused]] RLCPPAPI inline bool ExportImage(const Image& image, const std::string& fileName) { return ::ExportImage(image, fileName.c_str()); } /** * Export image as code file (.h) defining an array of bytes */ -RLCPPAPI inline bool ExportImageAsCode(const Image& image, const std::string& fileName) { +[[maybe_unused]] RLCPPAPI inline bool ExportImageAsCode(const Image& image, const std::string& fileName) { return ::ExportImageAsCode(image, fileName.c_str()); } /** * Draw text (using default font) */ -RLCPPAPI inline void DrawText(const std::string& text, int posX, int posY, int fontSize, ::Color color) { +[[maybe_unused]] RLCPPAPI inline void DrawText(const char* text, int posX, int posY, int fontSize, ::Color color) { + ::DrawText(text, posX, posY, fontSize, color); +} + +/** + * Draw text (using default font) + */ +[[maybe_unused]] RLCPPAPI inline void DrawText( + const std::string& text, + int posX, int posY, + int fontSize, + ::Color color) { ::DrawText(text.c_str(), posX, posY, fontSize, color); } /** * Draw text using font and additional parameters */ -RLCPPAPI inline void DrawTextEx(const Font& font, const std::string& text, Vector2 position, +[[maybe_unused]] RLCPPAPI inline void DrawTextEx(const Font& font, char* text, Vector2 position, + float fontSize, float spacing, ::Color tint) { + ::DrawTextEx(font, text, position, fontSize, spacing, tint); +} + +/** + * Draw text using font and additional parameters + */ +[[maybe_unused]] RLCPPAPI inline void DrawTextEx(const Font& font, const std::string& text, Vector2 position, float fontSize, float spacing, ::Color tint) { ::DrawTextEx(font, text.c_str(), position, fontSize, spacing, tint); } @@ -255,7 +274,15 @@ RLCPPAPI inline void DrawTextEx(const Font& font, const std::string& text, Vecto /** * Draw text using Font and pro parameters (rotation) */ -RLCPPAPI inline void DrawTextPro(const Font& font, const std::string& text, Vector2 position, +[[maybe_unused]] RLCPPAPI inline void DrawTextPro(const Font& font, const char* text, Vector2 position, + Vector2 origin, float rotation, float fontSize, float spacing, ::Color tint) { + ::DrawTextPro(font, text, position, origin, rotation, fontSize, spacing, tint); +} + +/** + * Draw text using Font and pro parameters (rotation) + */ +[[maybe_unused]] RLCPPAPI inline void DrawTextPro(const Font& font, const std::string& text, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, ::Color tint) { ::DrawTextPro(font, text.c_str(), position, origin, rotation, fontSize, spacing, tint); } @@ -263,49 +290,75 @@ RLCPPAPI inline void DrawTextPro(const Font& font, const std::string& text, Vect /** * Load font from file (filename must include file extension) */ -RLCPPAPI inline ::Font LoadFont(const std::string& fileName) { +[[maybe_unused]] RLCPPAPI inline ::Font LoadFont(const std::string& fileName) { return ::LoadFont(fileName.c_str()); } /** * Load font from file (filename must include file extension) */ -RLCPPAPI inline ::Font LoadFontEx(const std::string& fileName, int fontSize, int *fontChars, int charsCount) { +[[maybe_unused]] RLCPPAPI inline ::Font LoadFontEx( + const std::string& fileName, + int fontSize, int *fontChars, + int charsCount) { return ::LoadFontEx(fileName.c_str(), fontSize, fontChars, charsCount); } /** * Measure string width for default font */ -RLCPPAPI inline int MeasureText(const std::string& text, int fontSize) { +[[maybe_unused]] RLCPPAPI inline int MeasureText(const char* text, int fontSize) { + return ::MeasureText(text, fontSize); +} + +/** + * Measure string width for default font + */ +[[maybe_unused]] RLCPPAPI inline int MeasureText(const std::string& text, int fontSize) { return ::MeasureText(text.c_str(), fontSize); } /** * Check if two text string are equal */ -RLCPPAPI inline bool TextIsEqual(const std::string& text1, const std::string& text2) { +[[maybe_unused]] RLCPPAPI inline bool TextIsEqual(const char* text1, const char* text2) { + return ::TextIsEqual(text1, text2); +} + +/** + * Check if two text string are equal + */ +[[maybe_unused]] RLCPPAPI inline bool TextIsEqual(const std::string& text1, const std::string& text2) { return ::TextIsEqual(text1.c_str(), text2.c_str()); } /** * Check if two text string are equal */ -RLCPPAPI inline unsigned int TextLength(const std::string& text) { +[[maybe_unused]] RLCPPAPI inline unsigned int TextLength(const char* text) { + return ::TextLength(text); +} + +/** + * Check if two text string are equal + */ +[[maybe_unused]] RLCPPAPI inline unsigned int TextLength(const std::string& text) { return ::TextLength(text.c_str()); } /** * Get text length, checks for '\0' ending */ -RLAPI inline std::string TextSubtext(const std::string& text, int position, int length) { +[[maybe_unused]] RLCPPAPI inline std::string TextSubtext(const std::string& text, int position, int length) { return ::TextSubtext(text.c_str(), position, length); } /** * Replace text string */ -RLAPI inline std::string TextReplace(const std::string& text, const std::string& replace, const std::string& by) { +[[maybe_unused]] RLCPPAPI std::string TextReplace( + const std::string& text, const std::string& replace, + const std::string& by) { const char* input = text.c_str(); char* output = ::TextReplace(const_cast(input), replace.c_str(), by.c_str()); if (output != NULL) { @@ -319,7 +372,7 @@ RLAPI inline std::string TextReplace(const std::string& text, const std::string& /** * Insert text in a position */ -RLAPI inline std::string TextInsert(const std::string& text, const std::string& insert, int position) { +[[maybe_unused]] RLCPPAPI std::string TextInsert(const std::string& text, const std::string& insert, int position) { char* output = ::TextInsert(text.c_str(), insert.c_str(), position); if (output != NULL) { std::string stringOutput(output); @@ -332,7 +385,7 @@ RLAPI inline std::string TextInsert(const std::string& text, const std::string& /** * Split text into multiple strings */ -RLAPI inline std::vector TextSplit(const std::string& text, char delimiter) { +[[maybe_unused]] RLCPPAPI std::vector TextSplit(const std::string& text, char delimiter) { int count; const char** split = ::TextSplit(text.c_str(), delimiter, &count); return std::vector(split, split + count); @@ -341,35 +394,35 @@ RLAPI inline std::vector TextSplit(const std::string& text, char de /** * Find first text occurrence within a string */ -RLAPI inline int TextFindIndex(const std::string& text, const std::string& find) { +[[maybe_unused]] RLCPPAPI inline int TextFindIndex(const std::string& text, const std::string& find) { return ::TextFindIndex(text.c_str(), find.c_str()); } /** * Get upper case version of provided string */ -RLAPI inline std::string TextToUpper(const std::string& text) { +[[maybe_unused]] RLCPPAPI inline std::string TextToUpper(const std::string& text) { return ::TextToUpper(text.c_str()); } /** * Get lower case version of provided string */ -RLAPI inline std::string TextToLower(const std::string& text) { +[[maybe_unused]] RLCPPAPI inline std::string TextToLower(const std::string& text) { return ::TextToLower(text.c_str()); } /** * Get Pascal case notation version of provided string */ -RLAPI inline std::string TextToPascal(const std::string& text) { +[[maybe_unused]] RLCPPAPI inline std::string TextToPascal(const std::string& text) { return ::TextToPascal(text.c_str()); } /** * Get integer value from text (negative values not supported) */ -RLAPI inline int TextToInteger(const std::string& text) { +[[maybe_unused]] RLCPPAPI inline int TextToInteger(const std::string& text) { return ::TextToInteger(text.c_str()); } diff --git a/include/Image.hpp b/include/Image.hpp index a000c730..4564b869 100644 --- a/include/Image.hpp +++ b/include/Image.hpp @@ -316,11 +316,29 @@ class Image : public ::Image { } } - GETTERSETTER(void*, Data, data) - GETTERSETTER(int, Width, width) - GETTERSETTER(int, Height, height) - GETTERSETTER(int, Mipmaps, mipmaps) - GETTERSETTER(int, Format, format) + GETTER(void*, Data, data) + GETTER(int, Width, width) + GETTER(int, Height, height) + GETTER(int, Mipmaps, mipmaps) + GETTER(int, Format, format) + + /** + * Set the width of the image canvas. + * + * @see ResizeCanvas + */ + void SetWidth(int width, int offsetX = 0, int offsetY = 0, ::Color fill = {255, 255, 255, 255}) { + ResizeCanvas(width, height, offsetX, offsetY, fill); + } + + /** + * Set the height of the image canvas. + * + * @see ResizeCanvas + */ + void SetHeight(int height, int offsetX = 0, int offsetY = 0, ::Color fill = {255, 255, 255, 255}) { + ResizeCanvas(width, height, offsetX, offsetY, fill); + } /** * Retrieve the width and height of the image. @@ -645,6 +663,16 @@ class Image : public ::Image { ::ImageDraw(this, src, srcRec, dstRec, tint); } + void DrawText(const char* text, ::Vector2 position, int fontSize, + ::Color color = {255, 255, 255, 255}) { + ::ImageDrawText(this, + text, + static_cast(position.x), + static_cast(position.y), + fontSize, + color); + } + void DrawText(const std::string& text, ::Vector2 position, int fontSize, ::Color color = {255, 255, 255, 255}) { ::ImageDrawText(this, @@ -660,11 +688,21 @@ class Image : public ::Image { ::ImageDrawText(this, text.c_str(), x, y, fontSize, color); } + void DrawText(const char* text, int x, int y, int fontSize, + ::Color color = {255, 255, 255, 255}) { + ::ImageDrawText(this, text, x, y, fontSize, color); + } + void DrawText(const ::Font& font, const std::string& text, ::Vector2 position, float fontSize, float spacing, ::Color tint = {255, 255, 255, 255}) { ::ImageDrawTextEx(this, font, text.c_str(), position, fontSize, spacing, tint); } + void DrawText(const ::Font& font, const char* text, ::Vector2 position, + float fontSize, float spacing, ::Color tint = {255, 255, 255, 255}) { + ::ImageDrawTextEx(this, font, text, position, fontSize, spacing, tint); + } + /** * Load color data from image as a Color array (RGBA - 32bit) */ diff --git a/include/Keyboard.hpp b/include/Keyboard.hpp new file mode 100644 index 00000000..055257b3 --- /dev/null +++ b/include/Keyboard.hpp @@ -0,0 +1,64 @@ +#ifndef RAYLIB_CPP_INCLUDE_KEYBOARD_HPP_ +#define RAYLIB_CPP_INCLUDE_KEYBOARD_HPP_ + +#include "./raylib.hpp" + +namespace raylib { +/** + * Input-related functions: keyboard + */ +namespace Keyboard { + /** + * Detect if a key has been pressed once + */ + [[maybe_unused]] RLCPPAPI inline bool IsKeyPressed(int key) { + return ::IsKeyPressed(key); + } + + /** + * Detect if a key has been pressed again (Only PLATFORM_DESKTOP) + */ + [[maybe_unused]] RLCPPAPI inline bool IsKeyPressedRepeat(int key) { + return ::IsKeyPressedRepeat(key); + } + + /** + * Detect if a key is being pressed + */ + [[maybe_unused]] RLCPPAPI inline bool IsKeyDown(int key) { + return ::IsKeyDown(key); + } + + /** + * Detect if a key has been released once + */ + [[maybe_unused]] RLCPPAPI inline bool IsKeyReleased(int key) { + return ::IsKeyReleased(key); + } + + /** + * Detect if a key is NOT being pressed + */ + [[maybe_unused]] RLCPPAPI inline bool IsKeyUp(int key) { + return ::IsKeyUp(key); + } + + /** + * Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty + */ + [[maybe_unused]] RLCPPAPI inline bool GetKeyPressed() { + return ::GetKeyPressed(); + } + + /** + * Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty + */ + [[maybe_unused]] RLCPPAPI inline bool GetCharPressed() { + return ::GetCharPressed(); + } +} // namespace Keyboard +} // namespace raylib + +namespace RKeyboard = raylib::Keyboard; + +#endif // RAYLIB_CPP_INCLUDE_KEYBOARD_HPP_ diff --git a/include/Mesh.hpp b/include/Mesh.hpp index 7b6d6cbf..60bd11fa 100644 --- a/include/Mesh.hpp +++ b/include/Mesh.hpp @@ -8,28 +8,33 @@ #include "./raylib-cpp-utils.hpp" #include "./BoundingBox.hpp" #include "./Model.hpp" +#include "./MeshUnmanaged.hpp" namespace raylib { /** - * Vertex data definning a mesh + * Vertex data defining a mesh + * + * The Mesh will be unloaded on object destruction. + * + * @see raylib::MeshUnmanaged */ -class Mesh : public ::Mesh { +class Mesh : public MeshUnmanaged { public: - Mesh(const ::Mesh& mesh) { - set(mesh); - } + using MeshUnmanaged::MeshUnmanaged; /** - * Load meshes from model file + * Explicitly forbid the copy constructor. */ - // static std::vector Load(const std::string& fileName) { - // int count = 0; - // ::Mesh* meshes = LoadMeshes(fileName.c_str(), &count); - // return std::vector(meshes, meshes + count); - // } - Mesh(const Mesh&) = delete; + /** + * Explicitly forbid copy assignment. + */ + Mesh& operator=(const Mesh&) = delete; + + /** + * Move constructor. + */ Mesh(Mesh&& other) { set(other); @@ -50,106 +55,6 @@ class Mesh : public ::Mesh { other.vboId = nullptr; } - /** - * Generate polygonal mesh - */ - static ::Mesh Poly(int sides, float radius) { - return ::GenMeshPoly(sides, radius); - } - - /** - * Generate plane mesh (with subdivisions) - */ - static ::Mesh Plane(float width, float length, int resX, int resZ) { - return ::GenMeshPlane(width, length, resX, resZ); - } - - /** - * Generate cuboid mesh - */ - static ::Mesh Cube(float width, float height, float length) { - return ::GenMeshCube(width, height, length); - } - - /** - * Generate sphere mesh (standard sphere) - */ - static ::Mesh Sphere(float radius, int rings, int slices) { - return ::GenMeshSphere(radius, rings, slices); - } - - /** - * Generate half-sphere mesh (no bottom cap) - */ - static ::Mesh HemiSphere(float radius, int rings, int slices) { - return ::GenMeshHemiSphere(radius, rings, slices); - } - - /** - * Generate cylinder mesh - */ - static ::Mesh Cylinder(float radius, float height, int slices) { - return ::GenMeshCylinder(radius, height, slices); - } - - /** - * Generate cone/pyramid mesh - */ - static ::Mesh Cone(float radius, float height, int slices) { - return ::GenMeshCone(radius, height, slices); - } - - /** - * Generate torus mesh - */ - static ::Mesh Torus(float radius, float size, int radSeg, int sides) { - return ::GenMeshTorus(radius, size, radSeg, sides); - } - - /** - * Generate trefoil knot mesh - */ - static ::Mesh Knot(float radius, float size, int radSeg, int sides) { - return ::GenMeshKnot(radius, size, radSeg, sides); - } - - /** - * Generate heightmap mesh from image data - */ - static ::Mesh Heightmap(const ::Image& heightmap, ::Vector3 size) { - return ::GenMeshHeightmap(heightmap, size); - } - - /** - * Generate cubes-based map mesh from image data - */ - static ::Mesh Cubicmap(const ::Image& cubicmap, ::Vector3 cubeSize) { - return ::GenMeshCubicmap(cubicmap, cubeSize); - } - - GETTERSETTER(int, VertexCount, vertexCount) - GETTERSETTER(int, TriangleCount, triangleCount) - GETTERSETTER(float*, Vertices, vertices) - GETTERSETTER(float *, TexCoords, texcoords) - GETTERSETTER(float *, TexCoords2, texcoords2) - GETTERSETTER(float *, Normals, normals) - GETTERSETTER(float *, Tangents, tangents) - GETTERSETTER(unsigned char *, Colors, colors) - GETTERSETTER(unsigned short *, Indices, indices) // NOLINT - GETTERSETTER(float *, AnimVertices, animVertices) - GETTERSETTER(float *, AnimNormals, animNormals) - GETTERSETTER(unsigned char *, BoneIds, boneIds) - GETTERSETTER(float *, BoneWeights, boneWeights) - GETTERSETTER(unsigned int, VaoId, vaoId) - GETTERSETTER(unsigned int *, VboId, vboId) - - Mesh& operator=(const ::Mesh& mesh) { - set(mesh); - return *this; - } - - Mesh& operator=(const Mesh&) = delete; - Mesh& operator=(Mesh&& other) noexcept { if (this == &other) { return *this; @@ -180,110 +85,6 @@ class Mesh : public ::Mesh { ~Mesh() { Unload(); } - - /** - * Upload mesh vertex data to GPU (VRAM) - */ - void Upload(bool dynamic = false) { - ::UploadMesh(this, dynamic); - } - - /** - * Upload mesh vertex data to GPU (VRAM) - */ - void UpdateBuffer(int index, void *data, int dataSize, int offset = 0) { - ::UpdateMeshBuffer(*this, index, data, dataSize, offset); - } - - /** - * Draw a 3d mesh with material and transform - */ - void Draw(const ::Material& material, const ::Matrix& transform) const { - ::DrawMesh(*this, material, transform); - } - - /** - * Draw multiple mesh instances with material and different transforms - */ - void Draw(const ::Material& material, ::Matrix* transforms, int instances) const { - ::DrawMeshInstanced(*this, material, transforms, instances); - } - - /** - * Export mesh data to file - * - * @throws raylib::RaylibException Throws if failed to export the Mesh. - */ - void Export(const std::string& fileName) { - if (!::ExportMesh(*this, fileName.c_str())) { - throw new RaylibException("Failed to export the Mesh"); - } - } - - /** - * Unload mesh from memory (RAM and/or VRAM) - */ - void Unload() { - if (vboId != nullptr) { - ::UnloadMesh(*this); - vboId = nullptr; - } - } - - /** - * Compute mesh bounding box limits - */ - raylib::BoundingBox BoundingBox() const { - return ::GetMeshBoundingBox(*this); - } - - /** - * Compute mesh bounding box limits - */ - operator raylib::BoundingBox() { - return BoundingBox(); - } - - /** - * Compute mesh tangents - */ - Mesh& GenTangents() { - ::GenMeshTangents(this); - return *this; - } - - /** - * Load model from generated mesh - */ - raylib::Model LoadModelFrom() const { - return ::LoadModelFromMesh(*this); - } - - /** - * Load model from generated mesh - */ - operator raylib::Model() { - return ::LoadModelFromMesh(*this); - } - - protected: - void set(const ::Mesh& mesh) { - vertexCount = mesh.vertexCount; - triangleCount = mesh.triangleCount; - vertices = mesh.vertices; - texcoords = mesh.texcoords; - texcoords2 = mesh.texcoords2; - normals = mesh.normals; - tangents = mesh.tangents; - colors = mesh.colors; - indices = mesh.indices; - animVertices = mesh.animVertices; - animNormals = mesh.animNormals; - boneIds = mesh.boneIds; - boneWeights = mesh.boneWeights; - vaoId = mesh.vaoId; - vboId = mesh.vboId; - } }; } // namespace raylib diff --git a/include/MeshUnmanaged.hpp b/include/MeshUnmanaged.hpp new file mode 100644 index 00000000..6ecbd181 --- /dev/null +++ b/include/MeshUnmanaged.hpp @@ -0,0 +1,267 @@ +#ifndef RAYLIB_CPP_INCLUDE_MESHUNMANAGED_HPP_ +#define RAYLIB_CPP_INCLUDE_MESHUNMANAGED_HPP_ + +#include +#include + +#include "./raylib.hpp" +#include "./raylib-cpp-utils.hpp" +#include "./BoundingBox.hpp" +#include "./Model.hpp" + +namespace raylib { + +/** + * Vertex data defining a mesh, not managed by C++ RAII. + * + * Make sure to Unload() this if needed, otherwise use raylib::Mesh. + * + * @see raylib::Mesh + */ +class MeshUnmanaged : public ::Mesh { + public: + /** + * Default texture constructor. + */ + MeshUnmanaged() { + vertexCount = 0; + triangleCount = 0; + vertices = nullptr; + texcoords = nullptr; + texcoords2 = nullptr; + normals = nullptr; + tangents = nullptr; + colors = nullptr; + indices = nullptr; + animVertices = nullptr; + animNormals = nullptr; + boneIds = nullptr; + boneWeights = nullptr; + vaoId = 0; + vboId = nullptr; + } + + MeshUnmanaged(const ::Mesh& mesh) { + set(mesh); + } + + MeshUnmanaged(::Mesh&& mesh) { + set(mesh); + } + + /** + * Load meshes from model file + */ + // static std::vector Load(const std::string& fileName) { + // int count = 0; + // ::Mesh* meshes = LoadMeshes(fileName.c_str(), &count); + // return std::vector(meshes, meshes + count); + // } + + /** + * Generate polygonal mesh + */ + static ::Mesh Poly(int sides, float radius) { + return ::GenMeshPoly(sides, radius); + } + + /** + * Generate plane mesh (with subdivisions) + */ + static ::Mesh Plane(float width, float length, int resX, int resZ) { + return ::GenMeshPlane(width, length, resX, resZ); + } + + /** + * Generate cuboid mesh + */ + static ::Mesh Cube(float width, float height, float length) { + return ::GenMeshCube(width, height, length); + } + + /** + * Generate sphere mesh (standard sphere) + */ + static ::Mesh Sphere(float radius, int rings, int slices) { + return ::GenMeshSphere(radius, rings, slices); + } + + /** + * Generate half-sphere mesh (no bottom cap) + */ + static ::Mesh HemiSphere(float radius, int rings, int slices) { + return ::GenMeshHemiSphere(radius, rings, slices); + } + + /** + * Generate cylinder mesh + */ + static ::Mesh Cylinder(float radius, float height, int slices) { + return ::GenMeshCylinder(radius, height, slices); + } + + /** + * Generate cone/pyramid mesh + */ + static ::Mesh Cone(float radius, float height, int slices) { + return ::GenMeshCone(radius, height, slices); + } + + /** + * Generate torus mesh + */ + static ::Mesh Torus(float radius, float size, int radSeg, int sides) { + return ::GenMeshTorus(radius, size, radSeg, sides); + } + + /** + * Generate trefoil knot mesh + */ + static ::Mesh Knot(float radius, float size, int radSeg, int sides) { + return ::GenMeshKnot(radius, size, radSeg, sides); + } + + /** + * Generate heightmap mesh from image data + */ + static ::Mesh Heightmap(const ::Image& heightmap, ::Vector3 size) { + return ::GenMeshHeightmap(heightmap, size); + } + + /** + * Generate cubes-based map mesh from image data + */ + static ::Mesh Cubicmap(const ::Image& cubicmap, ::Vector3 cubeSize) { + return ::GenMeshCubicmap(cubicmap, cubeSize); + } + + GETTERSETTER(int, VertexCount, vertexCount) + GETTERSETTER(int, TriangleCount, triangleCount) + GETTERSETTER(float*, Vertices, vertices) + GETTERSETTER(float *, TexCoords, texcoords) + GETTERSETTER(float *, TexCoords2, texcoords2) + GETTERSETTER(float *, Normals, normals) + GETTERSETTER(float *, Tangents, tangents) + GETTERSETTER(unsigned char *, Colors, colors) + GETTERSETTER(unsigned short *, Indices, indices) // NOLINT + GETTERSETTER(float *, AnimVertices, animVertices) + GETTERSETTER(float *, AnimNormals, animNormals) + GETTERSETTER(unsigned char *, BoneIds, boneIds) + GETTERSETTER(float *, BoneWeights, boneWeights) + GETTERSETTER(unsigned int, VaoId, vaoId) + GETTERSETTER(unsigned int *, VboId, vboId) + + MeshUnmanaged& operator=(const ::Mesh& mesh) { + set(mesh); + return *this; + } + + /** + * Unload mesh from memory (RAM and/or VRAM) + */ + void Unload() { + if (vboId != nullptr) { + ::UnloadMesh(*this); + vboId = nullptr; + } + } + + /** + * Upload mesh vertex data to GPU (VRAM) + */ + void Upload(bool dynamic = false) { + ::UploadMesh(this, dynamic); + } + + /** + * Upload mesh vertex data to GPU (VRAM) + */ + void UpdateBuffer(int index, void *data, int dataSize, int offset = 0) { + ::UpdateMeshBuffer(*this, index, data, dataSize, offset); + } + + /** + * Draw a 3d mesh with material and transform + */ + void Draw(const ::Material& material, const ::Matrix& transform) const { + ::DrawMesh(*this, material, transform); + } + + /** + * Draw multiple mesh instances with material and different transforms + */ + void Draw(const ::Material& material, ::Matrix* transforms, int instances) const { + ::DrawMeshInstanced(*this, material, transforms, instances); + } + + /** + * Export mesh data to file + * + * @throws raylib::RaylibException Throws if failed to export the Mesh. + */ + void Export(const std::string& fileName) { + if (!::ExportMesh(*this, fileName.c_str())) { + throw RaylibException("Failed to export the Mesh"); + } + } + + /** + * Compute mesh bounding box limits + */ + raylib::BoundingBox BoundingBox() const { + return ::GetMeshBoundingBox(*this); + } + + /** + * Compute mesh bounding box limits + */ + operator raylib::BoundingBox() { + return BoundingBox(); + } + + /** + * Compute mesh tangents + */ + Mesh& GenTangents() { + ::GenMeshTangents(this); + return *this; + } + + /** + * Load model from generated mesh + */ + raylib::Model LoadModelFrom() const { + return ::LoadModelFromMesh(*this); + } + + /** + * Load model from generated mesh + */ + operator raylib::Model() { + return ::LoadModelFromMesh(*this); + } + + protected: + void set(const ::Mesh& mesh) { + vertexCount = mesh.vertexCount; + triangleCount = mesh.triangleCount; + vertices = mesh.vertices; + texcoords = mesh.texcoords; + texcoords2 = mesh.texcoords2; + normals = mesh.normals; + tangents = mesh.tangents; + colors = mesh.colors; + indices = mesh.indices; + animVertices = mesh.animVertices; + animNormals = mesh.animNormals; + boneIds = mesh.boneIds; + boneWeights = mesh.boneWeights; + vaoId = mesh.vaoId; + vboId = mesh.vboId; + } +}; +} // namespace raylib + +using RMeshUnmanaged = raylib::MeshUnmanaged; + +#endif // RAYLIB_CPP_INCLUDE_MESHUNMANAGED_HPP_ diff --git a/include/Model.hpp b/include/Model.hpp index a2e1cf97..d9b7c158 100644 --- a/include/Model.hpp +++ b/include/Model.hpp @@ -43,6 +43,15 @@ class Model : public ::Model { Load(mesh); } + /** + * The Model constructor with a Mesh() is removed. + * + * Use `raylib::MeshUnmanaged` or `::Mesh` instead, as raylib will take ownership of the data. + * + * @see raylib::MeshUnmanaged + */ + Model(const raylib::Mesh& mesh) = delete; + ~Model() { Unload(); } diff --git a/include/ModelAnimation.hpp b/include/ModelAnimation.hpp index 9440df5a..13f90910 100644 --- a/include/ModelAnimation.hpp +++ b/include/ModelAnimation.hpp @@ -102,6 +102,11 @@ class ModelAnimation : public ::ModelAnimation { frameCount = model.frameCount; bones = model.bones; framePoses = model.framePoses; + + // Duplicate the name. TextCopy() uses the null terminator, which we ignore here. + for (int i = 0; i < 32; i++) { + name[i] = model.name[i]; + } } }; } // namespace raylib diff --git a/include/Mouse.hpp b/include/Mouse.hpp index 4416497a..5dc9a018 100644 --- a/include/Mouse.hpp +++ b/include/Mouse.hpp @@ -8,88 +8,87 @@ namespace raylib { /** * Input-related functions: mouse */ -class Mouse { - public: +namespace Mouse { /** * Detect if a mouse button has been pressed once */ - static bool IsButtonPressed(int button) { + [[maybe_unused]] RLCPPAPI inline bool IsButtonPressed(int button) { return ::IsMouseButtonPressed(button); } /** * Detect if a mouse button is being pressed */ - static bool IsButtonDown(int button) { + [[maybe_unused]] RLCPPAPI inline bool IsButtonDown(int button) { return ::IsMouseButtonDown(button); } /** * Detect if a mouse button has been released once */ - static bool IsButtonReleased(int button) { + [[maybe_unused]] RLCPPAPI inline bool IsButtonReleased(int button) { return ::IsMouseButtonReleased(button); } - static bool IsButtonUp(int button) { + [[maybe_unused]] RLCPPAPI inline bool IsButtonUp(int button) { return ::IsMouseButtonUp(button); } - static int GetX() { + [[maybe_unused]] RLCPPAPI inline int GetX() { return ::GetMouseX(); } - static int GetY() { + [[maybe_unused]] RLCPPAPI inline int GetY() { return ::GetMouseY(); } - static void SetX(int x) { + [[maybe_unused]] RLCPPAPI inline void SetX(int x) { ::SetMousePosition(x, GetY()); } - static void SetY(int y) { + [[maybe_unused]] RLCPPAPI inline void SetY(int y) { ::SetMousePosition(GetX(), y); } - static Vector2 GetPosition() { + [[maybe_unused]] RLCPPAPI inline Vector2 GetPosition() { return ::GetMousePosition(); } - static void SetPosition(int x, int y) { + [[maybe_unused]] RLCPPAPI inline void SetPosition(int x, int y) { ::SetMousePosition(x, y); } - static void SetPosition(::Vector2 position) { + [[maybe_unused]] RLCPPAPI inline void SetPosition(::Vector2 position) { ::SetMousePosition(static_cast(position.x), static_cast(position.y)); } /** * Get mouse delta between frames */ - static Vector2 GetDelta() { + [[maybe_unused]] RLCPPAPI inline Vector2 GetDelta() { return ::GetMouseDelta(); } - static void SetOffset(int offsetX = 0, int offsetY = 0) { + [[maybe_unused]] RLCPPAPI inline void SetOffset(int offsetX = 0, int offsetY = 0) { ::SetMouseOffset(offsetX, offsetY); } - static void SetOffset(::Vector2 offset) { + [[maybe_unused]] RLCPPAPI inline void SetOffset(::Vector2 offset) { ::SetMouseOffset(static_cast(offset.x), static_cast(offset.y)); } - static void SetScale(float scaleX = 1.0f, float scaleY = 1.0f) { + [[maybe_unused]] RLCPPAPI inline void SetScale(float scaleX = 1.0f, float scaleY = 1.0f) { ::SetMouseScale(scaleX, scaleY); } - static void SetScale(::Vector2 scale) { + [[maybe_unused]] RLCPPAPI inline void SetScale(::Vector2 scale) { ::SetMouseScale(scale.x, scale.y); } /** * Get mouse wheel movement for X or Y, whichever is larger */ - static float GetWheelMove() { + [[maybe_unused]] RLCPPAPI inline float GetWheelMove() { return ::GetMouseWheelMove(); } @@ -98,7 +97,7 @@ class Mouse { * * @see ::GetMouseWheelMoveV() */ - static Vector2 GetWheelMoveV() { + [[maybe_unused]] RLCPPAPI inline Vector2 GetWheelMoveV() { return GetMouseWheelMoveV(); } @@ -107,47 +106,47 @@ class Mouse { * * @see ::MouseCursor */ - static void SetCursor(int cursor = MOUSE_CURSOR_DEFAULT) { + [[maybe_unused]] RLCPPAPI inline void SetCursor(int cursor = MOUSE_CURSOR_DEFAULT) { ::SetMouseCursor(cursor); } /** * Get touch position X for touch point 0 (relative to screen size) */ - static int GetTouchX() { + [[maybe_unused]] RLCPPAPI inline int GetTouchX() { return ::GetTouchX(); } /** * Get touch position Y for touch point 0 (relative to screen size) */ - static int GetTouchY() { + [[maybe_unused]] RLCPPAPI inline int GetTouchY() { return ::GetTouchY(); } /** * Get touch position XY for a touch point index (relative to screen size) */ - static Vector2 GetTouchPosition(int index) { + [[maybe_unused]] RLCPPAPI inline Vector2 GetTouchPosition(int index) { return ::GetTouchPosition(index); } /** * Get a ray trace from mouse position */ - static Ray GetRay(::Vector2 mousePosition, const ::Camera& camera) { + [[maybe_unused]] RLCPPAPI inline Ray GetRay(::Vector2 mousePosition, const ::Camera& camera) { return ::GetMouseRay(mousePosition, camera); } /** * Get a ray trace from mouse position */ - static Ray GetRay(const ::Camera& camera) { + [[maybe_unused]] RLCPPAPI inline Ray GetRay(const ::Camera& camera) { return ::GetMouseRay(::GetMousePosition(), camera); } -}; +} // namespace Mouse } // namespace raylib -using RMouse = raylib::Mouse; +namespace RMouse = raylib::Mouse; #endif // RAYLIB_CPP_INCLUDE_MOUSE_HPP_ diff --git a/include/Music.hpp b/include/Music.hpp index 2e6fa903..2b43dcc3 100644 --- a/include/Music.hpp +++ b/include/Music.hpp @@ -60,11 +60,11 @@ class Music : public ::Music { Unload(); } - GETTERSETTER(::AudioStream, Stream, stream) - GETTERSETTER(unsigned int, FrameCount, frameCount) + GETTER(::AudioStream, Stream, stream) + GETTER(unsigned int, FrameCount, frameCount) GETTERSETTER(bool, Looping, looping) - GETTERSETTER(int, CtxType, ctxType) - GETTERSETTER(void*, CtxData, ctxData) + GETTER(int, CtxType, ctxType) + GETTER(void*, CtxData, ctxData) Music& operator=(const ::Music& music) { set(music); diff --git a/include/Rectangle.hpp b/include/Rectangle.hpp index c234538d..df7d4598 100644 --- a/include/Rectangle.hpp +++ b/include/Rectangle.hpp @@ -80,9 +80,21 @@ class Rectangle : public ::Rectangle { ::DrawRectangleRounded(*this, roundness, segments, color); } + void DrawRoundedLines(float roundness, int segments, ::Color color) const { + #if RAYLIB_VERSION_MAJOR == 5 && RAYLIB_VERSION_MINOR == 0 + ::DrawRectangleRoundedLines(*this, roundness, segments, 1.0f, color); + #else + ::DrawRectangleRoundedLines(*this, roundness, segments, color); + #endif + } + void DrawRoundedLines(float roundness, int segments, float lineThick, ::Color color) const { - ::DrawRectangleRoundedLines(*this, roundness, segments, lineThick, color); + #if RAYLIB_VERSION_MAJOR == 5 && RAYLIB_VERSION_MINOR == 0 + ::DrawRectangleRoundedLines(*this, roundness, segments, lineThick, color); + #else + DrawRectangleRoundedLinesEx(*this, roundness, segments, lineThick, color); + #endif } /** diff --git a/include/RenderTexture.hpp b/include/RenderTexture.hpp index 706650d5..b8b0b4d9 100644 --- a/include/RenderTexture.hpp +++ b/include/RenderTexture.hpp @@ -43,7 +43,7 @@ class RenderTexture : public ::RenderTexture { other.depth = {}; } - GETTERSETTER(unsigned int, Id, id) + GETTER(unsigned int, Id, id) /** * Get the color buffer attachment texture. @@ -134,7 +134,9 @@ class RenderTexture : public ::RenderTexture { depth = renderTexture.depth; } }; -typedef RenderTexture RenderTexture2D; + +using RenderTexture2D = RenderTexture; + } // namespace raylib using RRenderTexture = raylib::RenderTexture; diff --git a/include/Shader.hpp b/include/Shader.hpp index ccbb7ac0..2dfb45fe 100644 --- a/include/Shader.hpp +++ b/include/Shader.hpp @@ -62,8 +62,8 @@ class Shader : public ::Shader { return ::LoadShaderFromMemory(vsCode, fsCode); } - GETTERSETTER(unsigned int, Id, id) - GETTERSETTER(int*, Locs, locs) + GETTER(unsigned int, Id, id) + GETTER(int*, Locs, locs) Shader& operator=(const ::Shader& shader) { set(shader); diff --git a/include/Sound.hpp b/include/Sound.hpp index fce156c9..76b5ae1b 100644 --- a/include/Sound.hpp +++ b/include/Sound.hpp @@ -59,8 +59,8 @@ class Sound : public ::Sound { Unload(); } - GETTERSETTER(unsigned int, FrameCount, frameCount) - GETTERSETTER(::AudioStream, Stream, stream) + GETTER(unsigned int, FrameCount, frameCount) + GETTER(::AudioStream, Stream, stream) Sound& operator=(Sound&& other) noexcept { if (this == &other) { @@ -173,7 +173,7 @@ class Sound : public ::Sound { void Load(const std::string& fileName) { set(::LoadSound(fileName.c_str())); if (!IsReady()) { - throw new RaylibException("Failed to load Sound from file"); + throw RaylibException("Failed to load Sound from file"); } } @@ -185,7 +185,7 @@ class Sound : public ::Sound { void Load(const ::Wave& wave) { set(::LoadSoundFromWave(wave)); if (!IsReady()) { - throw new RaylibException("Failed to load Wave"); + throw RaylibException("Failed to load Wave"); } } diff --git a/include/Texture.hpp b/include/Texture.hpp index ab9db518..8d665be0 100644 --- a/include/Texture.hpp +++ b/include/Texture.hpp @@ -67,8 +67,8 @@ class Texture : public TextureUnmanaged { }; // Create the Texture aliases. -typedef Texture Texture2D; -typedef Texture TextureCubemap; +using Texture2D = Texture; +using TextureCubemap = Texture; } // namespace raylib diff --git a/include/TextureUnmanaged.hpp b/include/TextureUnmanaged.hpp index 523f8a21..d32818ba 100644 --- a/include/TextureUnmanaged.hpp +++ b/include/TextureUnmanaged.hpp @@ -12,7 +12,7 @@ namespace raylib { /** - * A Texture that is not managed by the C++ garbage collector. + * A Texture that is not managed by C++ RAII. * * Make sure to Unload() this if needed, otherwise use raylib::Texture. * @@ -80,11 +80,11 @@ class TextureUnmanaged : public ::Texture { // Nothing. } - GETTERSETTER(unsigned int, Id, id) - GETTERSETTER(int, Width, width) - GETTERSETTER(int, Height, height) - GETTERSETTER(int, Mipmaps, mipmaps) - GETTERSETTER(int, Format, format) + GETTER(unsigned int, Id, id) + GETTER(int, Width, width) + GETTER(int, Height, height) + GETTER(int, Mipmaps, mipmaps) + GETTER(int, Format, format) TextureUnmanaged& operator=(const ::Texture& texture) { set(texture); @@ -334,8 +334,8 @@ class TextureUnmanaged : public ::Texture { }; // Create the TextureUnmanaged aliases. -typedef TextureUnmanaged Texture2DUnmanaged; -typedef TextureUnmanaged TextureCubemapUnmanaged; +using Texture2DUnmanaged = TextureUnmanaged; +using TextureCubemapUnmanaged = TextureUnmanaged; } // namespace raylib diff --git a/include/Touch.hpp b/include/Touch.hpp index ec5a5749..091f847c 100644 --- a/include/Touch.hpp +++ b/include/Touch.hpp @@ -7,45 +7,44 @@ namespace raylib { /** * Input-related functions: touch */ -class Touch { - public: +namespace Touch { /** * Get touch position X for touch point 0 (relative to screen size) */ - static int GetX() { + [[maybe_unused]] RLCPPAPI inline int GetX() { return ::GetTouchX(); } /** * Get touch position Y for touch point 0 (relative to screen size) */ - static int GetY() { + [[maybe_unused]] RLCPPAPI inline int GetY() { return ::GetTouchY(); } /** * Get touch position XY for a touch point index (relative to screen size) */ - static Vector2 GetPosition(int index) { + [[maybe_unused]] RLCPPAPI inline Vector2 GetPosition(int index) { return ::GetTouchPosition(index); } /** * Get touch point identifier for given index */ - static int GetPointId(int index) { + [[maybe_unused]] RLCPPAPI inline int GetPointId(int index) { return ::GetTouchPointId(index); } /** * Get number of touch points */ - static int GetPointCount() { + [[maybe_unused]] RLCPPAPI inline int GetPointCount() { return ::GetTouchPointCount(); } -}; +} // namespace Touch } // namespace raylib -using RTouch = raylib::Touch; +namespace RTouch = raylib::Touch; #endif // RAYLIB_CPP_INCLUDE_TOUCH_HPP_ diff --git a/include/Vector2.hpp b/include/Vector2.hpp index 5cb605aa..d1438783 100644 --- a/include/Vector2.hpp +++ b/include/Vector2.hpp @@ -96,7 +96,7 @@ class Vector2 : public ::Vector2 { } /** - * Add two vectors (v1 + v2) + * Subtract two vectors (v1 - v2) */ Vector2& operator-=(const ::Vector2& vector2) { set(Vector2Subtract(*this, vector2)); diff --git a/include/Vector3.hpp b/include/Vector3.hpp index 2492d85e..a0a93dc5 100644 --- a/include/Vector3.hpp +++ b/include/Vector3.hpp @@ -213,6 +213,13 @@ class Vector3 : public ::Vector3 { return Vector3Length(*this); } + /** + * Calculate vector square length + */ + float LengthSqr() const { + return Vector3LengthSqr(*this); + } + Vector3 Normalize() const { return Vector3Normalize(*this); } @@ -237,6 +244,14 @@ class Vector3 : public ::Vector3 { return Vector3Perpendicular(*this); } + Vector3 Project(const ::Vector3& vector3) const { + return Vector3Project(*this, vector3); + } + + Vector3 Reject(const ::Vector3& vector3) const { + return Vector3Reject(*this, vector3); + } + void OrthoNormalize(::Vector3* vector3) { Vector3OrthoNormalize(this, vector3); } diff --git a/include/Vector4.hpp b/include/Vector4.hpp index 6f12640f..39236ff8 100644 --- a/include/Vector4.hpp +++ b/include/Vector4.hpp @@ -171,7 +171,8 @@ class Vector4 : public ::Vector4 { }; // Alias the Vector4 as Quaternion. -typedef Vector4 Quaternion; +using Quaternion = Vector4; + } // namespace raylib using RVector4 = raylib::Vector4; diff --git a/include/Wave.hpp b/include/Wave.hpp index 757589be..7e248ee1 100644 --- a/include/Wave.hpp +++ b/include/Wave.hpp @@ -65,11 +65,11 @@ class Wave : public ::Wave { Unload(); } - GETTERSETTER(unsigned int, FrameCount, frameCount) - GETTERSETTER(unsigned int, SampleRate, sampleRate) - GETTERSETTER(unsigned int, SampleSize, sampleSize) - GETTERSETTER(unsigned int, Channels, channels) - GETTERSETTER(void *, Data, data) + GETTER(unsigned int, FrameCount, frameCount) + GETTER(unsigned int, SampleRate, sampleRate) + GETTER(unsigned int, SampleSize, sampleSize) + GETTER(unsigned int, Channels, channels) + GETTER(void *, Data, data) Wave& operator=(const ::Wave& wave) { set(wave); diff --git a/include/Window.hpp b/include/Window.hpp index dfa9d7c4..dc096103 100644 --- a/include/Window.hpp +++ b/include/Window.hpp @@ -76,6 +76,13 @@ class Window { return ::WindowShouldClose(); } + /** + * Set a custom key to exit program (default is ESC) + */ + void SetExitKey(int key) { + ::SetExitKey(key); + } + /** * Close window and unload OpenGL context */ diff --git a/include/raylib-cpp-utils.hpp b/include/raylib-cpp-utils.hpp index 4eee8329..9dbd260d 100644 --- a/include/raylib-cpp-utils.hpp +++ b/include/raylib-cpp-utils.hpp @@ -4,6 +4,19 @@ #ifndef RAYLIB_CPP_INCLUDE_RAYLIB_CPP_UTILS_HPP_ #define RAYLIB_CPP_INCLUDE_RAYLIB_CPP_UTILS_HPP_ +#ifndef GETTER +/** + * A utility to build a get method on top of a property. + * + * @param type The type of the property. + * @param method The human-readable name for the method. + * @param name The machine-readable name of the property. + */ +#define GETTER(type, method, name) \ + /** Retrieves the name value for the object. @return The name value of the object. */ \ + type Get##method() const { return name; } +#endif + #ifndef GETTERSETTER /** * A utility to build get and set methods on top of a property. @@ -13,8 +26,7 @@ * @param name The machine-readable name of the property. */ #define GETTERSETTER(type, method, name) \ - /** Retrieves the name value for the object. @return The name value of the object. */ \ - type Get##method() const { return name; } \ + GETTER(type, method, name) \ /** Sets the name value for the object. @param value The value of which to set name to. */ \ void Set##method(type value) { name = value; } #endif diff --git a/include/raylib-cpp.hpp b/include/raylib-cpp.hpp index 88cd6ef9..1f45d66d 100644 --- a/include/raylib-cpp.hpp +++ b/include/raylib-cpp.hpp @@ -38,10 +38,13 @@ #include "./Camera2D.hpp" #include "./Camera3D.hpp" #include "./Color.hpp" +#include "./FileData.hpp" +#include "./FileText.hpp" #include "./Font.hpp" #include "./Functions.hpp" #include "./Gamepad.hpp" #include "./Image.hpp" +#include "./Keyboard.hpp" #include "./Material.hpp" #include "./Matrix.hpp" #include "./Mesh.hpp" diff --git a/include/raylib.hpp b/include/raylib.hpp index 1fd071ca..f6d08ff7 100644 --- a/include/raylib.hpp +++ b/include/raylib.hpp @@ -15,13 +15,15 @@ extern "C" { #include RAYLIB_H_FILE // NOLINT #if !defined(RAYLIB_VERSION_MAJOR) || !defined(RAYLIB_VERSION_MINOR) -#if RAYLIB_VERSION_MAJOR < 5 -#error "raylib-cpp requires at least raylib 5.0.0" + #error "raylib-cpp requires raylib >= 5" #endif + +#if RAYLIB_VERSION_MAJOR < 5 + #error "raylib-cpp requires raylib >= 5" #endif #if RAYLIB_VERSION_MAJOR > 5 -#error "raylib-cpp targets raylib 5. Use the `next` branch for the next version of raylib." + #error "raylib-cpp requires raylib ~5.0. Use the `next` branch for the next version of raylib." #endif #ifdef __cplusplus diff --git a/package.json b/package.json index c58eedf2..3f9b0d75 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "raylib-cpp", - "version": "5.0.1", + "version": "5.0.2", "description": "raylib-cpp: C++ Object-Oriented Wrapper for raylib", "main": "index.js", "private": true, @@ -30,6 +30,6 @@ }, "homepage": "https://github.com/RobLoach/raylib-cpp#readme", "devDependencies": { - "gh-pages": "^4.0.0" + "gh-pages": "^6.1.1" } } diff --git a/projects/CMake/CMakeLists.txt b/projects/CMake/CMakeLists.txt index 6a530377..a02607b4 100644 --- a/projects/CMake/CMakeLists.txt +++ b/projects/CMake/CMakeLists.txt @@ -17,11 +17,14 @@ endif() # raylib-cpp find_package(raylib_cpp QUIET) if (NOT raylib_cpp_FOUND) + if (NOT DEFINED RAYLIB_CPP_VERSION) + set(RAYLIB_CPP_VERSION v5.0.2) + endif() include(FetchContent) FetchContent_Declare( raylib_cpp GIT_REPOSITORY https://github.com/RobLoach/raylib-cpp.git - GIT_TAG v5.0.1 + GIT_TAG ${RAYLIB_CPP_VERSION} ) FetchContent_MakeAvailable(raylib_cpp) endif() diff --git a/projects/Doxygen/doxygen-awesome-css b/projects/Doxygen/doxygen-awesome-css index 4cd62308..40e9b25b 160000 --- a/projects/Doxygen/doxygen-awesome-css +++ b/projects/Doxygen/doxygen-awesome-css @@ -1 +1 @@ -Subproject commit 4cd62308d825fe0396d2f66ffbab45d0e247724c +Subproject commit 40e9b25b6174dd3b472d8868f63323a870dfeeb8 diff --git a/projects/VSCode/.vscode/launch.json b/projects/VSCode/.vscode/launch.json index afb54b7f..b65aa1c1 100644 --- a/projects/VSCode/.vscode/launch.json +++ b/projects/VSCode/.vscode/launch.json @@ -8,7 +8,7 @@ "name": "Debug", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/${fileBasenameNoExtension}", + "program": "${workspaceFolder}/game", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", @@ -42,10 +42,10 @@ "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, - "program": "${workspaceFolder}/${fileBasenameNoExtension}", + "program": "${workspaceFolder}/game", "MIMode": "gdb", "windows": { - "program": "${workspaceFolder}/${fileBasenameNoExtension}.exe", + "program": "${workspaceFolder}/game.exe", "miDebuggerPath": "C:/raylib/mingw/bin/gdb.exe" }, "osx": { diff --git a/projects/VSCode/.vscode/settings.json b/projects/VSCode/.vscode/settings.json index e98318a0..161cf881 100644 --- a/projects/VSCode/.vscode/settings.json +++ b/projects/VSCode/.vscode/settings.json @@ -7,5 +7,49 @@ "**/.DS_Store": true, "**/*.o": true, "**/*.exe": true, + }, + "files.associations": { + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "random": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "limits": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "typeinfo": "cpp" } } \ No newline at end of file diff --git a/projects/VSCode/FirstPerson.cpp b/projects/VSCode/FirstPerson.cpp index 39b9865d..2f41b280 100644 --- a/projects/VSCode/FirstPerson.cpp +++ b/projects/VSCode/FirstPerson.cpp @@ -1,191 +1,51 @@ -#include "raylib.h" -#include -#include "raymath.h" -#include "camera.h" -#include "include/raylib-cpp.hpp" -#include - -#define MAX_COLUMNS 100 -#define CollisionDetectionThreshold 15 -const int screenWidth = 1280; -const int screenHeight = 720; -bool debug = false; -bool cameraCollided = false; -bool closeToCollider = false; - -// TODO: WRITE CUSTOM MOVEMENT CODE -// TODO: NEED TO CHECK Y AXIS COLLISIONS -// TODO: NEED TO IMPELEMENT PHYSICS -struct BoxCollider -{ - BoundingBox BBox; - Vector3 *center; - Vector3 extents; - - BoxCollider() {} - - BoxCollider(Vector3 ¢er, raylib::Vector3 extents) - { - this->center = ¢er; - this->extents = extents; - UpdateBoundingBox(); - } - void UpdateBoundingBox() - { - BBox.max.x = center->x + extents.x / 2; - BBox.max.y = center->y + extents.y / 2; - BBox.max.z = center->z + extents.z / 2; - - BBox.min.x = center->x - extents.x / 2; - BBox.min.y = center->y - extents.y / 2; - BBox.min.z = center->z - extents.z / 2; - } -}; - -struct Player -{ - raylib::Camera camera; - BoxCollider collider; - - Player() - { - camera = raylib::Camera(raylib::Vector3(4, 2, 4), raylib::Vector3(0.0f, 1.8f, 0.0f), - raylib::Vector3(0, 1, 0), 90.0f, CAMERA_PERSPECTIVE); - SetCameraMode(camera, CAMERA_FIRST_PERSON); - - collider = BoxCollider(camera.position, raylib::Vector3(1, 1, 1)); - } -}; - -float DistanceSquared(Vector3 *A, Vector3 *B) -{ - float dx = A->x - B->x; - float dy = A->y - B->y; - float dz = A->z - B->z; - return (dx * dx + dy * dy + dz * dz); -} - -void GetInput() -{ - if (IsKeyPressed(KEY_Q)) - debug = !debug; -} - -void Draw3D(Player player, Vector3 positions[], float heights[], Color colors[], BoxCollider BBoxes[]) -{ - BeginMode3D(player.camera); - DrawPlane((Vector3){0.0f, 0.0f, 0.0f}, (Vector2){32.0f, 32.0f}, LIGHTGRAY); - DrawCube((Vector3){-16.0f, 2.5f, 0.0f}, 1.0f, 5.0f, 32.0f, BLUE); - DrawCube((Vector3){16.0f, 2.5f, 0.0f}, 1.0f, 5.0f, 32.0f, LIME); - DrawCube((Vector3){0.0f, 2.5f, 16.0f}, 32.0f, 5.0f, 1.0f, GOLD); - - if (!debug) - { - for (int i = 0; i < MAX_COLUMNS; i++) - { - DrawCube(positions[i], 2.0f, heights[i], 2.0f, colors[i]); - DrawCubeWires(positions[i], 2.0f, heights[i], 2.0f, BLUE); - } - } - else - { - for (int i = 0; i < MAX_COLUMNS; i++) - { - DrawBoundingBox(BBoxes[i].BBox, GREEN); - } - DrawBoundingBox(player.collider.BBox, BLUE); - } - - EndMode3D(); -} - -void Draw2D() -{ - DrawText("First person camera default controls:", 20, 20, 10, BLACK); - DrawText("- Move with keys: W, A, S, D", 40, 40, 10, DARKGRAY); - DrawText("- Mouse move to look around", 40, 60, 10, DARKGRAY); - if(closeToCollider) - { - DrawText("CHECKING COLLISIONS", 40, 100, 20, BLUE); - closeToCollider = false; - } - if (cameraCollided) - DrawText("Colliding", 40, 80, 20, GREEN); -} - -void GenerateLevel(float heights[], BoxCollider BBoxes[], Vector3 positions[], Color colors[]) -{ - for (int i = 0; i < MAX_COLUMNS; i++) - { - heights[i] = (float)GetRandomValue(1, 12); - positions[i] = (Vector3){GetRandomValue(-15, 15), heights[i] / 2, GetRandomValue(-15, 15)}; - BBoxes[i].extents = (Vector3){2.0f, heights[i], 2.0f}; - BBoxes[i].center = &positions[i]; - BBoxes[i].UpdateBoundingBox(); - colors[i] = (Color){GetRandomValue(20, 255), GetRandomValue(10, 55), 30, 255}; - } -} - -void CheckPlayerCollisions(Player *player, BoxCollider BBoxes[]) -{ - for (int i = 0; i < MAX_COLUMNS; i++) - { - if (DistanceSquared(player->collider.center, BBoxes[i].center) < CollisionDetectionThreshold) - { - closeToCollider = true; - if (CheckCollisionBoxes(player->collider.BBox, BBoxes[i].BBox)) - { - cameraCollided = true; - return; - } - } - } - cameraCollided = false; +#include + + +void UpdateFrame(raylib::Window& window, raylib::Camera3D& cam) { + static raylib::Vector3 position; + + window.BeginDrawing(); + + cam.Update(CAMERA_ORBITAL); + + window.ClearBackground(raylib::Color::RayWhite()); + + cam.BeginMode(); + + position.DrawCube({2.0f, 2.0f, 2.0f}, raylib::Color::Red()); + position.DrawCubeWires({2.0f, 2.0f, 2.0f}, raylib::Color::Maroon()); + DrawGrid(10, 1.0f); + + cam.EndMode(); + + raylib::Vector2 textPosition{10, 40}; + raylib::Text sampleText( GetFontDefault(),"This is a raylib-cpp example", 20.0f, 20.0f /10.0f, raylib::Color::DarkGray()); + sampleText.Draw(textPosition); + window.EndDrawing(); + } -void Abbas() -{ - for (int i = 0; i < screenWidth; i++) - { - DrawPixel(i,screenHeight/2,BLACK); - } - for (int i = 0; i < screenHeight; i++) - { - DrawPixel(screenWidth/2,i,BLACK); - } -} +int main() { -int main() -{ - InitWindow(screenWidth, screenHeight, "LET ME HELP YOU SEE, SLAYER"); + const int screenWidth = 800; + const int screenHeight = 450; - Player player; - float heights[MAX_COLUMNS] = {0}; - Vector3 positions[MAX_COLUMNS] = {0}; - Color colors[MAX_COLUMNS] = {0}; - BoxCollider BBoxes[MAX_COLUMNS]; - GenerateLevel(heights, BBoxes, positions, colors); + raylib::Window window(screenWidth, screenHeight); - SetTargetFPS(60); - while (!WindowShouldClose()) - { - BeginDrawing(); - ClearBackground(WHITE); - CheckPlayerCollisions(&player, BBoxes); - Draw3D(player, positions, heights, colors, BBoxes); - Draw2D(); + raylib::Vector3 position(10.0f, 10.0f, 8.0f); + raylib::Vector3 target(0.0f, 0.0f, 0.0f); + raylib::Vector3 up (0.0f, 1.0f, 0.0f); - Abbas(); + float fovy = 60.0f; + raylib::Camera3D cam(position, target, up, fovy, CAMERA_PERSPECTIVE); - GetInput(); - UpdateCamera(&player.camera); - player.collider.UpdateBoundingBox(); + window.SetTargetFPS(60); - EndDrawing(); + while (!window.ShouldClose()) { + UpdateFrame(window, cam); } - CloseWindow(); - - return 0; + window.Close(); + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/projects/VSCode/Makefile b/projects/VSCode/Makefile index 2ca0ead0..3e61f626 100644 --- a/projects/VSCode/Makefile +++ b/projects/VSCode/Makefile @@ -356,9 +356,9 @@ SRC_DIR = src OBJ_DIR = obj # Define all object files from source files -SRC = $(call rwildcard, *.c, *.h) +SRC = $(call rwildcard, *.cpp, *.h) #OBJS = $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) -OBJS ?= main.c +OBJS ?= FirstPerson.cpp # For Android platform we call a custom Makefile.Android ifeq ($(PLATFORM),PLATFORM_ANDROID) diff --git a/tests/raylib_cpp_test.cpp b/tests/raylib_cpp_test.cpp index 6d188c61..58c358ff 100644 --- a/tests/raylib_cpp_test.cpp +++ b/tests/raylib_cpp_test.cpp @@ -69,6 +69,11 @@ int main(int argc, char *argv[]) { AssertEqual(image.GetHeight(), 50); } + // Keyboard + { + AssertNot(raylib::Keyboard::IsKeyPressed(KEY_MINUS)); + } + // raylib::LoadDirectoryFiles() { std::vector files = raylib::LoadDirectoryFiles(::GetWorkingDirectory()); @@ -122,6 +127,19 @@ int main(int argc, char *argv[]) { Assert(passed, "Expected to have a RaylibException to be thrown"); } + // Load FileData + { + raylib::FileData file(path + "/resources/weird.wav"); + Assert(file.GetBytesRead() > 0, "Expected file to be loaded correctly"); + } + + // Load FileText + { + raylib::FileText text(path + "/resources/lorem.txt"); + Assert(text.GetLength() > 0, "Expected file to be loaded correctly"); + AssertEqual(text.ToString().substr(0, 5), "Lorem"); + } + TraceLog(LOG_INFO, "TEST: raylib-cpp test"); TraceLog(LOG_INFO, "---------------------"); return 0; diff --git a/tests/resources/lorem.txt b/tests/resources/lorem.txt new file mode 100644 index 00000000..4c738ee8 --- /dev/null +++ b/tests/resources/lorem.txt @@ -0,0 +1,4 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. +Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. +Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. \ No newline at end of file pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy