Your First Project: Cube Workshop
Create a standalone C++ application that displays a textured cube with a camera and lighting. You will integrate Rhea with CMake, provide the application's assets, and change the scene in your own source tree.
Start by completing Getting Started. This tutorial uses the same BasicApp implementation so that your first project builds on an example you have already explored.
Documentation draft: this external-project configuration is based on the current engine sources. A clean build and visual verification are still required before publication. Use the same engine revision as your working BasicApp checkout.
1. Create the project directory
Create a directory named CubeWorkshop, with src, Assets, and external subdirectories. Place a complete Rhea checkout in external/rhea. A local copy or Git submodule is suitable; use the engine repository root, containing Rhea, Poseidon, and the top-level CMakeLists.txt.
Copy these two files from that engine checkout:
| Source | Destination |
|---|---|
Rhea/Samples/01_BasicApp/BasicApp.cpp | src/main.cpp |
Rhea/Samples/01_BasicApp/Assets/kies.png | Assets/kies.png |
Your directory structure should now be:
CubeWorkshop/
Assets/
kies.png
external/
rhea/
CMakeLists.txt
Rhea/
Poseidon/
...
src/
main.cpp
CMakeLists.txt
Copy the source and texture, rather than the sample's CMake file. We will define the build for your independent application below.
2. Define the build
Create CMakeLists.txt in the CubeWorkshop directory:
cmake_minimum_required(VERSION 3.24)
project(CubeWorkshop LANGUAGES C CXX)
set(RHEA_SDK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/rhea")
# Build the engine libraries without its applications and sample executables.
set(RHEA_BUILD_APPS OFF CACHE BOOL "" FORCE)
set(RHEA_BUILD_SAMPLES OFF CACHE BOOL "" FORCE)
set(POSEIDON_BUILD_SAMPLES OFF CACHE BOOL "" FORCE)
set(RHEA_BUILD_TESTS OFF CACHE BOOL "" FORCE)
include("${RHEA_SDK_DIR}/Rhea/cmake/rhea_project.cmake")
add_subdirectory("${RHEA_SDK_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/rhea")
add_executable(CubeWorkshop src/main.cpp)
target_compile_features(CubeWorkshop PRIVATE cxx_std_17)
target_link_libraries(CubeWorkshop PRIVATE
Rhea::Core
Rhea::Client
RheaFabrics
)
set_target_properties(CubeWorkshop PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin/$<CONFIG>"
)
rhea_copy_assets(CubeWorkshop "${CMAKE_CURRENT_SOURCE_DIR}/Assets" "basic_app")
rhea_copy_assets(CubeWorkshop "${RHEA_ASSETS_DIR}" "rhea")
rhea_project_end()
The engine is built from the local checkout through add_subdirectory; neither mwpkg nor a FetchContent declaration is needed in your project.
The project helper collects Fabric registrations. rhea_project_end() finalizes those registrations after the engine has been added. This project uses the default selection of registered Fabrics; it does not need a custom enabled.json yet.
The two asset-copy calls provide different resources:
Data/basic_appcontains your texture. The copied sample refers to it as//basic_app/kies.png.Data/rheacontains the engine assets, including the standard shader.
Keep the basic_app resource name for now. It is the resource namespace used by the copied source, and is independent of the executable name.
3. Build and run
Open a terminal in CubeWorkshop. On Windows with MSVC, use a developer terminal. You need the compiler, CMake 3.24 or newer, Python 3, and the backend dependencies described in Getting Started.
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build --config Debug --target CubeWorkshop
CMake may download missing engine dependencies according to the engine's configuration.
The project places the executable and its assets in build/bin/Debug. On Windows PowerShell:
cd build/bin/Debug
.\CubeWorkshop.exe
On Linux:
cd build/bin/Debug
./CubeWorkshop
The expected result is a window with a lit, textured cube. Press Escape to exit. The Data directory must remain next to the executable.
4. Make the scene your own
Open your project's src/main.cpp. You are now editing your application's copy of the code.
Change the application name in main():
app.setAppname("CubeWorkshop");
In createScene(), move the camera farther from the cube and to one side:
camera->setLocalPosition(math::Vector3(2, 2, -8));
Keep the existing setLookAt call so that the camera continues looking at the origin.
Next, find the diffuse material color:
material->setColor(shader->getInputSlotId("DIFFUSE"), math::Color(1.0f, 1.0f, 1.0f, 1.0f));
Replace it with a blue tint:
material->setColor(shader->getInputSlotId("DIFFUSE"), math::Color(0.1f, 0.3f, 0.9f, 1.0f));
Return to the project root, rebuild, and run again. The expected result is a different viewpoint and a blue-tinted cube. The texture, lighting, and other material values also affect the final appearance. For a stronger tint, apply the same blue color to the named AMBIENT slot as well. Material colors multiply the texture; white preserves its original colors. Use the named slots rather than hard-coded indices.
You can replace Assets/kies.png with your own PNG under the same filename. Rebuild to stage the changed asset beside the executable, then restart the application.
5. Understand what you built
Your application now has its own source, build target, and assets. The engine remains a separate checkout that your CMake project includes.
In the copied source:
main()initializes the application, callssetup(), and enters the runtime loop.setup()waits for the shader and texture to load, then callscreateScene()to create the scene, camera, lighting, mesh, and material.onInput()handles Escape to request an exit.onFrameEnd()returns the exit flag to the runtime.
No editor is required for this workflow. Scene construction happens in C++, with ordinary edit-build-run iterations.
Troubleshooting
| Symptom | What to check |
|---|---|
| CMake cannot find Python | Set Python3_EXECUTABLE to your Python 3 interpreter when configuring. |
| A compiler or dependency is missing | Review the configure output and the requirements in Getting Started. |
| The executable is missing | Build the CubeWorkshop target with the Debug configuration and inspect the build output. |
| Textures or shaders cannot be loaded | Run from the executable directory and check that Data/basic_app/kies.png and Data/rhea are present. |
| The window opens but the scene renders incorrectly | Record the operating system, graphics backend, engine revision, and application output for a bug report. |
Next steps
Read Architecture to understand engine composition. Continue with Runtime Scene Instancing when you want to move from scene construction in C++ to reusable scene resources.