added args and input, played around with raylib as static lib but reverted to dynamic, tried to fix objective-c runtime duplicate sumbol warning but failed, should be fine, added cmake option for raylib release
This commit is contained in:
parent
fae5d540f6
commit
80dce65014
10
README.md
10
README.md
@ -31,13 +31,15 @@ apt install libx11-dev
|
||||
apt install xorg-dev
|
||||
```
|
||||
|
||||
cmake -DBUILD_SHARED_LIBS=OFF -DUSE_EXTERNAL_GLFW=OFF ..
|
||||
|
||||
```
|
||||
cd workdir
|
||||
git clone https://github.com/raysan5/raylib.git
|
||||
cd raylib/src
|
||||
make
|
||||
cd ../examples
|
||||
make
|
||||
mkdir -p raylib/build
|
||||
cd raylib/build
|
||||
/Applications/CMake.app/Contents/bin/cmake -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release ..
|
||||
make -j4
|
||||
cd ../..
|
||||
git clone https://github.com/raysan5/raygui.git
|
||||
git clone https://github.com/oomer/poomer-raylib-bella_onimage.git
|
||||
|
||||
44
makefile
44
makefile
@ -8,6 +8,8 @@ BUILD_TYPE ?= release# Default to release build if not specified
|
||||
BELLA_SDK_PATH = ../bella_engine_sdk
|
||||
RAYGUI_PATH = ../raygui
|
||||
RAYLIB_PATH = ../raylib
|
||||
# Path to dynamic raylib library
|
||||
RAYLIB_DYLIB_PATH = ../raylib/build/raylib
|
||||
OBJ_DIR = obj/$(PLATFORM)/$(BUILD_TYPE)
|
||||
BIN_DIR = bin/$(PLATFORM)/$(BUILD_TYPE)
|
||||
OUTPUT_FILE = $(BIN_DIR)/$(EXECUTABLE_NAME)
|
||||
@ -17,6 +19,7 @@ ifeq ($(PLATFORM), Darwin)
|
||||
# macOS configuration
|
||||
SDK_LIB_EXT = dylib
|
||||
SDK_LIB_FILE = lib$(BELLA_SDK_NAME).$(SDK_LIB_EXT)
|
||||
# Dynamic raylib library
|
||||
RAYLIB_LIB_NAME = libraylib.$(SDK_LIB_EXT)
|
||||
MACOS_SDK_PATH = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
|
||||
|
||||
@ -25,7 +28,7 @@ ifeq ($(PLATFORM), Darwin)
|
||||
CXX = clang++
|
||||
|
||||
# Architecture flags
|
||||
ARCH_FLAGS = -arch x86_64 -arch arm64 -mmacosx-version-min=11.0 -isysroot $(MACOS_SDK_PATH)
|
||||
ARCH_FLAGS = -arch x86_64 -arch arm64 -mmacosx-version-min=15.0 -isysroot $(MACOS_SDK_PATH)
|
||||
|
||||
# Include paths
|
||||
INCLUDE_PATHS = -I$(BELLA_SDK_PATH)/src \
|
||||
@ -34,10 +37,12 @@ ifeq ($(PLATFORM), Darwin)
|
||||
|
||||
# Library paths
|
||||
SDK_LIB_PATH = $(BELLA_SDK_PATH)/lib
|
||||
RAYLIB_LIB_PATH = $(RAYLIB_PATH)/src
|
||||
# Updated path to dynamic raylib library
|
||||
RAYLIB_LIB_PATH = $(RAYLIB_DYLIB_PATH)
|
||||
LIB_PATHS = -L$(SDK_LIB_PATH) -L$(RAYLIB_LIB_PATH)
|
||||
|
||||
# Platform-specific libraries
|
||||
# For dynamic library, we don't need to explicitly link all of raylib's dependencies
|
||||
LIBRARIES = -l$(BELLA_SDK_NAME) \
|
||||
-lraylib \
|
||||
-lm \
|
||||
@ -47,10 +52,11 @@ ifeq ($(PLATFORM), Darwin)
|
||||
-framework AppKit \
|
||||
-framework IOKit \
|
||||
-framework CoreGraphics \
|
||||
-framework CoreVideo \
|
||||
-framework Foundation
|
||||
|
||||
# Linking flags
|
||||
LINKER_FLAGS = -mmacosx-version-min=11.0 \
|
||||
LINKER_FLAGS = -mmacosx-version-min=15.0 \
|
||||
-isysroot $(MACOS_SDK_PATH) \
|
||||
-framework Cocoa \
|
||||
-framework IOKit \
|
||||
@ -60,11 +66,13 @@ ifeq ($(PLATFORM), Darwin)
|
||||
-fvisibility=hidden \
|
||||
-O5 \
|
||||
-rpath @executable_path \
|
||||
-rpath @loader_path \
|
||||
-weak_library $(SDK_LIB_PATH)/libvulkan.dylib
|
||||
else
|
||||
# Linux configuration
|
||||
SDK_LIB_EXT = so
|
||||
SDK_LIB_FILE = lib$(BELLA_SDK_NAME).$(SDK_LIB_EXT)
|
||||
# Dynamic raylib library
|
||||
RAYLIB_LIB_NAME = libraylib.$(SDK_LIB_EXT)
|
||||
|
||||
# Compiler settings
|
||||
@ -81,11 +89,13 @@ else
|
||||
|
||||
# Library paths
|
||||
SDK_LIB_PATH = $(BELLA_SDK_PATH)/lib
|
||||
RAYLIB_LIB_PATH = $(RAYLIB_PATH)/src
|
||||
# Updated path to dynamic raylib library
|
||||
RAYLIB_LIB_PATH = $(RAYLIB_DYLIB_PATH)
|
||||
SYSTEM_LIB_PATH = /usr/lib/x86_64-linux-gnu/
|
||||
LIB_PATHS = -L$(SDK_LIB_PATH) -L$(RAYLIB_LIB_PATH)
|
||||
|
||||
# Platform-specific libraries
|
||||
# For dynamic library, we don't need to explicitly link all dependencies of raylib
|
||||
LIBRARIES = -l$(BELLA_SDK_NAME) \
|
||||
-lraylib \
|
||||
-lm \
|
||||
@ -106,16 +116,24 @@ endif
|
||||
|
||||
# Build type specific flags
|
||||
ifeq ($(BUILD_TYPE), debug)
|
||||
CPP_DEFINES = -D_DEBUG -DDL_USE_SHARED
|
||||
ifeq ($(PLATFORM), Darwin)
|
||||
CPP_DEFINES = -D_DEBUG -DDL_USE_SHARED
|
||||
else
|
||||
CPP_DEFINES = -D_DEBUG -DDL_USE_SHARED
|
||||
endif
|
||||
COMMON_FLAGS = $(ARCH_FLAGS) -fvisibility=hidden -g -O0 $(INCLUDE_PATHS)
|
||||
else
|
||||
CPP_DEFINES = -DNDEBUG=1 -DDL_USE_SHARED
|
||||
ifeq ($(PLATFORM), Darwin)
|
||||
CPP_DEFINES = -DNDEBUG=1 -DDL_USE_SHARED
|
||||
else
|
||||
CPP_DEFINES = -DNDEBUG=1 -DDL_USE_SHARED
|
||||
endif
|
||||
COMMON_FLAGS = $(ARCH_FLAGS) -fvisibility=hidden -O3 $(INCLUDE_PATHS)
|
||||
endif
|
||||
|
||||
# Language-specific flags
|
||||
C_FLAGS = $(COMMON_FLAGS) -std=c11
|
||||
CXX_FLAGS = $(COMMON_FLAGS) -std=c++11
|
||||
CXX_FLAGS = $(COMMON_FLAGS) -std=c++17
|
||||
|
||||
# Objects
|
||||
OBJECTS = $(EXECUTABLE_NAME).o
|
||||
@ -131,6 +149,14 @@ $(OUTPUT_FILE): $(OBJECT_FILES)
|
||||
$(CXX) -o $@ $^ $(LINKER_FLAGS) $(LIB_PATHS) $(LIBRARIES)
|
||||
@echo "Copying libraries to $(BIN_DIR)..."
|
||||
@cp $(SDK_LIB_PATH)/$(SDK_LIB_FILE) $(BIN_DIR)/$(SDK_LIB_FILE)
|
||||
ifeq ($(PLATFORM), Darwin)
|
||||
@# Copy raylib dylib files preserving symbolic links
|
||||
@cp -P $(RAYLIB_LIB_PATH)/libraylib.5.5.0.dylib $(BIN_DIR)/
|
||||
@cp -P $(RAYLIB_LIB_PATH)/libraylib.550.dylib $(BIN_DIR)/
|
||||
@cp -P $(RAYLIB_LIB_PATH)/libraylib.dylib $(BIN_DIR)/
|
||||
else
|
||||
@cp $(RAYLIB_LIB_PATH)/$(RAYLIB_LIB_NAME) $(BIN_DIR)/$(RAYLIB_LIB_NAME)
|
||||
endif
|
||||
@echo "Build complete: $(OUTPUT_FILE)"
|
||||
|
||||
# Add default target
|
||||
@ -141,7 +167,11 @@ clean:
|
||||
rm -f $(OBJ_DIR)/*.o
|
||||
rm -f $(OUTPUT_FILE)
|
||||
rm -f $(BIN_DIR)/$(SDK_LIB_FILE)
|
||||
ifeq ($(PLATFORM), Darwin)
|
||||
rm -f $(BIN_DIR)/libraylib*.dylib
|
||||
else
|
||||
rm -f $(BIN_DIR)/$(RAYLIB_LIB_NAME)
|
||||
endif
|
||||
rmdir $(OBJ_DIR) 2>/dev/null || true
|
||||
rmdir $(BIN_DIR) 2>/dev/null || true
|
||||
|
||||
|
||||
@ -1,3 +1,14 @@
|
||||
#ifdef __APPLE__
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
// Force the environment variable using putenv which is more reliable
|
||||
// This must be set before any Objective-C classes are loaded
|
||||
static const char* objc_disable_warning = "OBJC_DISABLE_CLASS_DUP_WARNING=YES";
|
||||
static bool _init_env = (putenv((char*)objc_disable_warning), true);
|
||||
#endif
|
||||
|
||||
#include <chrono>
|
||||
|
||||
// Add these definitions before any includes to prevent Windows API conflicts
|
||||
#define NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
@ -13,6 +24,8 @@
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
// Include our fix header first
|
||||
#include "raylib_objc_fix.h"
|
||||
// Include raylib directly but don't use its namespace
|
||||
#include <raylib.h>
|
||||
#include <mutex> // For thread synchronization
|
||||
@ -24,7 +37,8 @@
|
||||
#include "../bella_engine_sdk/src/bella_sdk/bella_engine.h" // For rendering and scene creation in Bella
|
||||
#include "../bella_engine_sdk/src/dl_core/dl_main.inl" // Core functionality from the Diffuse Logic engine
|
||||
#include "../oom/oom_license.h" // common misc code
|
||||
#include "../oom/oom_bella_long.h" // common misc code
|
||||
#include "../oom/oom_dl_misc.h" // common misc code
|
||||
#include "../oom/oom_misc.h" // common misc code
|
||||
#include "../oom/oom_bella_engine.h" // common misc code
|
||||
|
||||
// Create namespace aliases for raylib types that conflict with bella_sdk
|
||||
@ -62,6 +76,10 @@ namespace rl {
|
||||
}
|
||||
|
||||
// Define a callback type for receiving image data from the path tracer
|
||||
// This creates a type alias called 'OnImageCallback' that represents a function that:
|
||||
// 1. Takes image data (pointer to pixels), width, height, and number of color channels as parameters
|
||||
// 2. Returns void (nothing)
|
||||
// std::function is a flexible wrapper that can store any callable object (functions, lambdas, etc.)
|
||||
using OnImageCallback = std::function<void(const unsigned char* data, int width, int height, int channels)>;
|
||||
|
||||
// Structure to hold image data in the queue
|
||||
@ -95,7 +113,8 @@ private:
|
||||
// This is crucial because OpenGL operations (like texture creation) must happen on the main thread
|
||||
std::queue<ImageData> imageQueue;
|
||||
|
||||
// Callback for receiving image data
|
||||
// This member variable stores a function that will be called when new image data arrives
|
||||
// It will be set to a lambda function in the constructor
|
||||
OnImageCallback onImageCallback;
|
||||
|
||||
// Mouse interaction properties
|
||||
@ -132,8 +151,10 @@ public:
|
||||
rl::SetTargetFPS(60);
|
||||
|
||||
// THREAD SAFETY: Set up the callback that will be called by the path tracer
|
||||
// Instead of directly updating the image (which would create textures in a non-main thread),
|
||||
// we queue the image data for later processing by the main thread
|
||||
// This creates a lambda function (an anonymous function) that captures 'this' pointer
|
||||
// so it can access the current instance's methods.
|
||||
// When this callback is invoked later with image data, it will call queueImageData
|
||||
// to safely pass the data between threads.
|
||||
onImageCallback = [this](const unsigned char* data, int width, int height, int channels) {
|
||||
this->queueImageData(data, width, height, channels);
|
||||
};
|
||||
@ -163,7 +184,9 @@ public:
|
||||
rl::CloseWindow();
|
||||
}
|
||||
|
||||
// Get the callback that the path tracer should call when new image data is available
|
||||
// This method returns the callback function so other components can use it
|
||||
// The 'const' means this method doesn't modify the class state
|
||||
// It returns a copy of the callback function
|
||||
OnImageCallback getCallback() const {
|
||||
return onImageCallback;
|
||||
}
|
||||
@ -486,7 +509,9 @@ public:
|
||||
// Load an image from file - use raylib's Image type
|
||||
rl::Image image = rl::LoadImage(filename);
|
||||
if (image.data != NULL) {
|
||||
// Call our callback with the image data
|
||||
// Call our callback function with the image data to process it
|
||||
// This simulates what would happen when the path tracer produces an image
|
||||
// It determines the number of channels based on the image format
|
||||
onImageCallback(
|
||||
static_cast<const unsigned char*>(image.data),
|
||||
image.width,
|
||||
@ -503,7 +528,7 @@ public:
|
||||
// Forward declaration
|
||||
class PathTracerPreview;
|
||||
|
||||
// Custom engine observer that connects bsdk's Image to our PathTracerPreview
|
||||
// Custom override engine observer that connects bsdk's Image to our PathTracerPreview
|
||||
struct BellaEngineObserver : public dl::bella_sdk::EngineObserver {
|
||||
private:
|
||||
PathTracerPreview* preview;
|
||||
@ -512,21 +537,21 @@ public:
|
||||
BellaEngineObserver(PathTracerPreview* preview) : preview(preview) {}
|
||||
|
||||
void onStarted(dl::String pass) override {
|
||||
//logInfo("Started pass %s", pass.buf());
|
||||
dl::logInfo("Started pass %s", pass.buf());
|
||||
}
|
||||
|
||||
void onStatus(dl::String pass, dl::String status) override {
|
||||
//logInfo("%s [%s]", status.buf(), pass.buf());
|
||||
dl::logInfo("%s [%s]", status.buf(), pass.buf());
|
||||
}
|
||||
|
||||
void onProgress(dl::String pass, dl::bella_sdk::Progress progress) override {
|
||||
//logInfo("%s [%s]", progress.toString().buf(), pass.buf());
|
||||
dl::logInfo("%s [%s]", progress.toString().buf(), pass.buf());
|
||||
}
|
||||
|
||||
// This is the key method that receives images from the bella engine
|
||||
// IMPORTANT: This method is called from the bella engine's thread, NOT the main thread
|
||||
void onImage(dl::String pass, dl::bella_sdk::Image image) override {
|
||||
//logInfo("Received image from bella: %d x %d", (int)image.width(), (int)image.height());
|
||||
dl::logInfo("Received image from bella: %d x %d", (int)image.width(), (int)image.height());
|
||||
|
||||
// Get the dimensions of the image
|
||||
int width = (int)image.width();
|
||||
@ -554,11 +579,12 @@ public:
|
||||
// Direct memory copy for optimal performance
|
||||
std::memcpy(buffer, rgba_data, width * height * 4);
|
||||
|
||||
// THREAD SAFETY: Instead of directly calling updateImage (which would create textures in the wrong thread),
|
||||
// use the callback which will queue the data for processing by the main thread
|
||||
// THREAD SAFETY: Use the callback to queue data for processing by the main thread
|
||||
try {
|
||||
if (preview->getCallback()) {
|
||||
// This will queue the data for later processing in the main thread
|
||||
// Get the callback function from the preview object and invoke it
|
||||
// This passes the image data to the main thread via the callback
|
||||
// When called, this executes the lambda we defined in the constructor
|
||||
preview->getCallback()(buffer, width, height, 4);
|
||||
//std::cout << "Image data queued successfully" << std::endl;
|
||||
} else {
|
||||
@ -580,21 +606,55 @@ public:
|
||||
}
|
||||
|
||||
void onError(dl::String pass, dl::String msg) override {
|
||||
//logError("%s [%s]", msg.buf(), pass.buf());
|
||||
dl::logError("%s [%s]", msg.buf(), pass.buf());
|
||||
}
|
||||
|
||||
void onStopped(dl::String pass) override {
|
||||
//logInfo("Stopped %s", pass.buf());
|
||||
dl::logInfo("Stopped %s", pass.buf());
|
||||
}
|
||||
};
|
||||
|
||||
//#include "dl_core/dl_main.inl"
|
||||
int DL_main(dl::Args& args)
|
||||
{
|
||||
int s_oomBellaLogContext = 0;
|
||||
dl::subscribeLog(&s_oomBellaLogContext, oom::bella::log);
|
||||
dl::flushStartupMessages();
|
||||
|
||||
args.add("wd", "watchdir", "", "watch directory for changes");
|
||||
args.add("tp", "thirdparty", "", "prints third party licenses");
|
||||
args.add("li", "licenseinfo", "", "prints license info");
|
||||
args.add("i", "input", "", "prints license info");
|
||||
|
||||
if (args.helpRequested()) {
|
||||
std::cout << args.help("poomer-efsw © 2025 Harvey Fong","", "1.0") << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (args.have("--licenseinfo")) {
|
||||
std::cout << "poomer-raylib-bella_onimage © 2025 Harvey Fong" << std::endl;
|
||||
std::cout << oom::license::printLicense() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (args.have("--thirdparty")) {
|
||||
std::cout << oom::license::printBellaSDK() << "\n====\n" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
auto belPath = dl::bella_sdk::previewPath();
|
||||
|
||||
if (args.have("--input")) {
|
||||
belPath = args.value("--input");
|
||||
if (!dl::fs::exists(belPath)) {
|
||||
dl::logError("Input file %s does not exist", belPath.buf());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
SetTraceLogLevel(LOG_ERROR);
|
||||
// Set raylib configuration flags before creating the window
|
||||
rl::SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_WINDOW_RESIZABLE);
|
||||
|
||||
PathTracerPreview preview(400, 400, "poomer-raylib-bella_onimage");
|
||||
if (!rl::IsWindowReady()) {
|
||||
std::cerr << "ERROR: Window initialization failed" << std::endl;
|
||||
@ -611,6 +671,8 @@ int DL_main(dl::Args& args)
|
||||
}
|
||||
//std::cout << "OpenGL context initialized" << std::endl;
|
||||
|
||||
oom::misc::saveHDRI();
|
||||
|
||||
// Initialize the bella engine
|
||||
dl::bella_sdk::Engine engine;
|
||||
engine.scene().loadDefs();
|
||||
@ -625,20 +687,15 @@ int DL_main(dl::Args& args)
|
||||
engine.subscribe(&engineObserver);
|
||||
|
||||
// Get the preview scene with material sphere
|
||||
auto path = dl::bella_sdk::previewPath();
|
||||
if (path != "") {
|
||||
//std::cout << "Loading scene: " << path.buf() << std::endl;
|
||||
//logInfo("Loading scene: %s", path.buf());
|
||||
if (belPath != "") {
|
||||
|
||||
// Use the read method to load the scene
|
||||
if (!engine.scene().read(path)) {
|
||||
std::cerr << "ERROR: Failed to read " << path.buf() << " from " << dl::fs::currentDir().buf() << std::endl;
|
||||
dl::logError("Failed to read %s from %s", path.buf(), dl::fs::currentDir().buf());
|
||||
// Use the read method to load the scene, load left some cruft
|
||||
if (!engine.scene().read(belPath)) {
|
||||
dl::logError("Failed to read %s from %s", belPath.buf(), dl::fs::currentDir().buf());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!engine.start()) {
|
||||
std::cerr << "ERROR: Engine failed to start" << std::endl;
|
||||
dl::logError("Engine failed to start.");
|
||||
return 1;
|
||||
}
|
||||
@ -646,10 +703,9 @@ int DL_main(dl::Args& args)
|
||||
// Store the initial camera state after the scene is loaded and engine started
|
||||
//preview.storeInitialCameraTransform();
|
||||
|
||||
//std::cout << "Engine started successfully" << std::endl;
|
||||
} else {
|
||||
// For testing, load a sample image
|
||||
preview.simulateDataFromPathTracer("oomer.png");
|
||||
// For testing, load a sample image, seems to have broke
|
||||
preview.simulateDataFromPathTracer("res/DayEnvironmentHDRI019_1K-TONEMAPPED.jpg");
|
||||
}
|
||||
|
||||
// Run the preview window - this will block until the window is closed
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user