Creating an Entropy App
This guide walks you through creating a C++ application that connects to the Entropy Engine and orchestrates a 3D scene. We will use the transient_scene example as a template.
Prerequisites
Section titled “Prerequisites”- Entropy Engine compiled and running (local or remote).
- CMake 3.20+.
- C++ 20 compiler.
1. Project Setup (CMake)
Section titled “1. Project Setup (CMake)”Your application links against EntropyCanvasSDK and EntropyNetworking.
cmake_minimum_required(VERSION 3.20)project(MyEntropyApp)
find_package(EntropyCanvasSDK REQUIRED)find_package(EntropyNetworking REQUIRED)
add_executable(MyEntropyApp main.cpp)
target_link_libraries(MyEntropyApp PRIVATE EntropyCanvasSDK EntropyNetworking::Networking)
# Optional: Link USD for mesh serializationif(TARGET EntropyCanvasUSD) target_link_libraries(MyEntropyApp PRIVATE EntropyCanvasUSD)endif()2. Application Entry Point
Section titled “2. Application Entry Point”The core of an Entropy app is the CanvasClient. It connects to the engine and synchronizes state.
#include <EntropyCanvas/Network/CanvasClient.h>#include <EntropyCanvas/Scene/SceneGraph.h>
using namespace EntropyCanvas;
int main() { // 1. Create a transient SceneGraph (local ECS) SceneGraph scene;
// 2. Connect to the Engine // Connects to localhost:4433 by default, secure=true CanvasClient client("127.0.0.1", 4433, true);
if (!client.connect()) { std::cerr << "Failed to connect to Entropy Engine" << std::endl; return 1; }
// 3. Application Loop while (true) { // Process network messages client.poll();
// Push local changes to the engine // (In a real app, you would update ECS components here)
std::this_thread::sleep_for(std::chrono::milliseconds(16)); }
return 0;}3. Uploading Assets
Section titled “3. Uploading Assets”You can upload ephemeral (transient) assets programmatically. These exist only for the session duration.
Textures
Section titled “Textures”#include <EntropyCanvas/Assets/TextureLoader.h>#include <EntropyCanvas/Network/TextureClient.h>
void uploadMyTexture(CanvasClient& client) { // Load texture from disk auto texture = TextureLoader::loadFromFile("Textures/MyTexture.tga");
// Upload synchronously auto result = client.textureClient()->uploadTextureSync(texture, false /* not persistent */);
if (result.success()) { std::cout << "Texture ID: " << result.value.toShortHex() << std::endl; }}Meshes
Section titled “Meshes”Meshes are typically serialized to USD format before upload.
#include <EntropyCanvas/USD/MeshData.h>#include <EntropyCanvas/USD/UsdMeshSerializer.h>
void uploadBox(CanvasClient& client) { // Create a procedural box auto mesh = MeshData::box(1.0f);
// Serialize to USD auto serializeResult = UsdMeshSerializer::serialize(mesh);
// Upload raw bytes auto* assetClient = client.assetClient(); auto handle = assetClient->upload(serializeResult.data, ContentType::Mesh, false);
// Wait for completion...}4. Shaders and Materials
Section titled “4. Shaders and Materials”You can create custom materials with your own shaders.
Uploading a Shader
Section titled “Uploading a Shader”First, define a ShaderBundle with source code and metadata, then upload it.
#include <EntropyCanvas/Network/ShaderClient.h>
AssetId uploadCustomShader(CanvasClient& client) { std::string source = R"( // Custom Slang Shader #include "EntropyShaderLibrary/Surface.slang"
// Exposed parameters [vk::binding(0, 1)] Texture2D baseColorTexture; [vk::binding(1, 1)] SamplerState baseColorSampler;
// ... shader implementation ... )";
ShaderBundle bundle; bundle.mainSource = source; bundle.metadata.name = "MyCustomShader";
auto* shaderClient = client.shaderClient(); auto handle = shaderClient->uploadShader(bundle, false);
// Poll until complete while (!handle->isComplete()) client.poll();
return handle->result();}Creating a Material
Section titled “Creating a Material”Once you have a Shader AssetId and a Texture AssetId, you can combine them into a Material.
#include <EntropyCanvas/Assets/MaterialData.h>
AssetId createMyMaterial(CanvasClient& client, AssetId shaderId, AssetId textureId) { MaterialData mat; mat.name = "MyMaterial"; mat.shaderAssetId = shaderId;
// Set material properties mat.setVec4("baseColor", glm::vec4(1.0f)); mat.setFloat("roughness", 0.5f); mat.setFloat("metallic", 0.0f);
// Bind texture to the shader parameter "baseColorTexture" mat.setTextureRef("baseColorTexture", textureId);
// Create on server auto handle = client.createMaterial(mat); while (!handle->isComplete()) client.poll();
return handle->result();}5. Creating Entities (ECS)
Section titled “5. Creating Entities (ECS)”Finally, link everything together in the ECS.
// Create an entity in the local registryauto entity = scene.getWorld().entity("MyCube");
// Add Transform componententity.set<Transform>({ .position = {0, 0, 0}, .scale = {1, 1, 1}});
// Add Mesh component// Links the Mesh Asset ID + List of Material IDsentity.set<Mesh>({ .meshAssetId = myMeshId, .materialIds = {myMaterialId} // [0] corresponds to submesh 0});
// Sync to Engineclient.syncEntity(entity);
// Bind materials (triggers subscription on server)client.bindMeshMaterials(entity.id(), {myMaterialId});6. Lights
Section titled “6. Lights”Lights are added as components.
// Create a Point Lightauto light = scene.getWorld().entity("LightSource");light.set<Transform>({.position = {0, 5, 0}});light.set<Light>(Light::sphere(10.0f, glm::vec3(1, 0.9, 0.8)));client.syncEntity(light);Summary
Section titled “Summary”- Link
EntropyCanvasSDK. - Connect via
CanvasClient. - Upload Assets:
- Textures:
TextureClient::uploadTextureSync - Shaders:
ShaderClient::uploadShader - Meshes:
AssetClient::upload
- Textures:
- Create Materials: Define
MaterialData, set properties, bind Textures, and callclient.createMaterial. - Create Entities: Add
TransformandMeshcomponents, utilizing the uploadAssetIds. - Sync: Call
client.syncEntityto replicate to the engine.
See EntropyCanvasSDK/examples/transient_scene/main.cpp for a complete working example.