RAMSES Documentation  27.0.130
Information for RAMSES users and developers
ramses-example-local-datalink/src/main.cpp

Local Data Link Example

// -------------------------------------------------------------------------
// Copyright (C) 2014 BMW Car IT GmbH
// -------------------------------------------------------------------------
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
// -------------------------------------------------------------------------
#include "ramses-client.h"
#include "ramses-utils.h"
#include <unordered_set>
#include <cmath>
#include <chrono>
#include <memory>
#include <thread>
#include <unordered_set>
{
public:
void windowClosed(ramses::displayId_t /*displayId*/) override
{
m_windowClosed = true;
}
bool isWindowClosed() const
{
return m_windowClosed;
}
private:
bool m_windowClosed = false;
};
{
public:
: m_sceneControlApi(sceneControlApi)
, m_renderer(renderer)
{
}
{
scenesWithCreatedProviderOrConsumer.insert(sceneId);
}
{
scenesWithCreatedProviderOrConsumer.insert(sceneId);
}
{
while (scenesWithCreatedProviderOrConsumer.find(sceneId) == scenesWithCreatedProviderOrConsumer.end())
{
m_renderer.doOneLoop();
m_sceneControlApi.dispatchEvents(*this);
}
}
private:
ramses::RendererSceneControl& m_sceneControlApi;
std::unordered_set<ramses::sceneId_t> scenesWithCreatedProviderOrConsumer;
};
// Helper struct for triangle scene
struct TriangleSceneInfo
{
public:
// Node that will be used as transformation provider
ramses::Node* translateNode;
// Textures that will be used as texture provider
ramses::Texture2D* textures[2];
// Data object that will be used as data consumer
// Provider scene
ramses::Scene* scene;
};
// Helper struct for quad scene
struct QuadSceneInfo
{
// Consumer node that will use transformation from provider node
ramses::Node* consumerNode;
// Consumer texture sampler, that will use texture from provider
ramses::TextureSampler* textureSampler;
// Additional rotation chained after consumed transformation
ramses::Node* rotateNode;
// Data object that will be used as data provider
// Consumer scene
ramses::Scene* scene;
};
std::unique_ptr<TriangleSceneInfo> createTriangleSceneContent(ramses::RamsesClient& client, ramses::sceneId_t sceneId)
{
auto sceneInfo = std::make_unique<TriangleSceneInfo>();
sceneInfo->scene = client.createScene(sceneId, ramses::SceneConfig(), "triangle scene");
// every scene needs a render pass with camera
auto* camera = sceneInfo->scene->createPerspectiveCamera("my camera");
camera->setViewport(0, 0, 1280u, 480u);
camera->setFrustum(19.f, 1280.f / 480.f, 0.1f, 1500.f);
ramses::RenderPass* renderPass = sceneInfo->scene->createRenderPass("my render pass");
renderPass->setCamera(*camera);
ramses::RenderGroup* renderGroup = sceneInfo->scene->createRenderGroup();
renderPass->addRenderGroup(*renderGroup);
// prepare triangle geometry: vertex position array and index array
float vertexPositionsArray[] = { -0.25f, -0.125f, 0.f, 0.25f, -0.125f, 0.f, 0.f, 0.125f, 0.f };
ramses::ArrayResource* vertexPositions = sceneInfo->scene->createArrayResource(ramses::EDataType::Vector3F, 3, vertexPositionsArray);
uint16_t indicesArray[] = { 0, 1, 2 };
ramses::ArrayResource* indices = sceneInfo->scene->createArrayResource(ramses::EDataType::UInt16, 3, indicesArray);
// create an appearance for red triangle
effectDesc.setVertexShaderFromFile("res/ramses-example-local-datalink.vert");
effectDesc.setFragmentShaderFromFile("res/ramses-example-local-datalink.frag");
ramses::Effect* effect = sceneInfo->scene->createEffect(effectDesc, ramses::ResourceCacheFlag_DoNotCache, "glsl shader");
ramses::Appearance* appearance = sceneInfo->scene->createAppearance(*effect, "triangle appearance");
ramses::GeometryBinding* geometry = sceneInfo->scene->createGeometryBinding(*effect, "triangle geometry");
geometry->setIndices(*indices);
ramses::AttributeInput positionsInput;
effect->findAttributeInput("a_position", positionsInput);
geometry->setInputBuffer(positionsInput, *vertexPositions);
effect->findUniformInput("color", colorInput);
appearance->setInputValueVector4f(colorInput, 1.0f, 0.0f, 0.3f, 1.0f);
//bind input to data object
sceneInfo->colorData = sceneInfo->scene->createDataVector4f("colorData");
sceneInfo->colorData->setValue(1.0f, 0.0f, 0.3f, 1.0f);
appearance->bindInput(colorInput, *sceneInfo->colorData);
ramses::Node* rootTranslation = sceneInfo->scene->createNode("root scene translation node");
rootTranslation->setTranslation(0.0f, 0.0f, -1.0f);
sceneInfo->translateNode = sceneInfo->scene->createNode("triangle translation node");
sceneInfo->translateNode->setParent(*rootTranslation);
// create a mesh node to define the triangle with chosen appearance
ramses::MeshNode* meshNode = sceneInfo->scene->createMeshNode("triangle mesh node");
meshNode->setAppearance(*appearance);
meshNode->setGeometryBinding(*geometry);
meshNode->setParent(*sceneInfo->translateNode);
// mesh needs to be added to a render group that belongs to a render pass with camera in order to be rendered
renderGroup->addMeshNode(*meshNode);
// Create provided texture
sceneInfo->textures[0] = ramses::RamsesUtils::CreateTextureResourceFromPng("res/ramses-example-local-datalink-texture.png", *sceneInfo->scene);
sceneInfo->textures[1] = ramses::RamsesUtils::CreateTextureResourceFromPng("res/ramses-example-local-datalink-texture2.png", *sceneInfo->scene);
return sceneInfo;
}
std::unique_ptr<QuadSceneInfo> createQuadSceneContent(ramses::RamsesClient& client, ramses::sceneId_t sceneId)
{
auto sceneInfo = std::make_unique<QuadSceneInfo>();
sceneInfo->scene = client.createScene(sceneId, ramses::SceneConfig(), "quad scene");
// every scene needs a render pass with camera
auto* camera = sceneInfo->scene->createPerspectiveCamera("my camera");
camera->setViewport(0, 0, 1280u, 480u);
camera->setFrustum(19.f, 1280.f / 480.f, 0.1f, 1500.f);
ramses::RenderPass* renderPass = sceneInfo->scene->createRenderPass("my render pass");
renderPass->setCamera(*camera);
ramses::RenderGroup* renderGroup = sceneInfo->scene->createRenderGroup();
renderPass->addRenderGroup(*renderGroup);
// prepare triangle geometry: vertex position array and index array
float vertexPositionsArray[] = { -0.1f, -0.1f, 0.0f,
0.1f, -0.1f, 0.0f,
0.1f, 0.1f, 0.0f,
-0.1f, 0.1f, 0.0f };
ramses::ArrayResource* vertexPositions = sceneInfo->scene->createArrayResource(ramses::EDataType::Vector3F, 4, vertexPositionsArray);
float texCoordsArray[] = { 1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f };
ramses::ArrayResource* texCoords = sceneInfo->scene->createArrayResource(ramses::EDataType::Vector2F, 4, texCoordsArray);
uint16_t indicesArray[] = { 0, 1, 2, 2, 3, 0 };
ramses::ArrayResource* indices = sceneInfo->scene->createArrayResource(ramses::EDataType::UInt16, 6, indicesArray);
// create an appearance for red triangle
effectDesc.setVertexShaderFromFile("res/ramses-example-local-datalink-texturing.vert");
effectDesc.setFragmentShaderFromFile("res/ramses-example-local-datalink-texturing.frag");
ramses::Effect* effect = sceneInfo->scene->createEffect(effectDesc, ramses::ResourceCacheFlag_DoNotCache, "glsl shader");
ramses::Appearance* appearance = sceneInfo->scene->createAppearance(*effect, "quad appearance");
ramses::GeometryBinding* geometry = sceneInfo->scene->createGeometryBinding(*effect, "quad geometry");
geometry->setIndices(*indices);
ramses::AttributeInput positionsInput;
effect->findAttributeInput("a_position", positionsInput);
geometry->setInputBuffer(positionsInput, *vertexPositions);
ramses::AttributeInput texCoordsInput;
effect->findAttributeInput("a_texcoord", texCoordsInput);
geometry->setInputBuffer(texCoordsInput, *texCoords);
effect->findUniformInput("color", colorInput);
appearance->setInputValueVector4f(colorInput, 1.0f, 1.0f, 1.0f, 1.0f);
ramses::UniformInput textureInput;
effect->findUniformInput("textureSampler", textureInput);
ramses::Texture2D* fallbackTexture = ramses::RamsesUtils::CreateTextureResourceFromPng("res/ramses-example-local-datalink-texture-fallback.png", *sceneInfo->scene);
sceneInfo->textureSampler = sceneInfo->scene->createTextureSampler(ramses::ETextureAddressMode_Clamp, ramses::ETextureAddressMode_Clamp,
appearance->setInputTexture(textureInput, *sceneInfo->textureSampler);
sceneInfo->consumerNode = sceneInfo->scene->createNode("quad root node");
sceneInfo->rotateNode = sceneInfo->scene->createNode("");
// create a mesh node to define the triangle with chosen appearance
ramses::MeshNode* meshNode = sceneInfo->scene->createMeshNode("quad mesh node");
meshNode->setAppearance(*appearance);
meshNode->setGeometryBinding(*geometry);
meshNode->setParent(*sceneInfo->rotateNode);
// mesh needs to be added to a render group that belongs to a render pass with camera in order to be rendered
renderGroup->addMeshNode(*meshNode);
sceneInfo->rotateNode->setParent(*sceneInfo->consumerNode);
//create data object for providing color info (not used by any appearance)
sceneInfo->colorData = sceneInfo->scene->createDataVector4f("colorData");
sceneInfo->colorData->setValue(1.0f, 1.0f, 1.0f, 1.0f);
return sceneInfo;
}
int main(int argc, char* argv[])
{
//Ramses client
ramses::RamsesFrameworkConfig config(argc, argv);
config.setRequestedRamsesShellType(ramses::ERamsesShellType_Console); //needed for automated test of examples
ramses::RamsesFramework framework(config);
ramses::RamsesClient& client(*framework.createClient("ramses-local-datalink-example"));
ramses::RendererConfig rendererConfig(argc, argv);
ramses::RamsesRenderer& renderer(*framework.createRenderer(rendererConfig));
ramses::DisplayConfig displayConfig(argc, argv);
const ramses::displayId_t display = renderer.createDisplay(displayConfig);
renderer.flush();
auto& sceneControlAPI = *renderer.getSceneControlAPI();
const ramses::sceneId_t triangleSceneId{1u};
const ramses::sceneId_t quadSceneId{2u};
const ramses::sceneId_t quadSceneId2{3u};
std::unique_ptr<TriangleSceneInfo> triangleInfo = createTriangleSceneContent(client, triangleSceneId);
std::unique_ptr<QuadSceneInfo> quadInfo = createQuadSceneContent(client, quadSceneId);
std::unique_ptr<QuadSceneInfo> quadInfo2 = createQuadSceneContent(client, quadSceneId2);
ramses::Scene* triangleScene = triangleInfo->scene;
ramses::Scene* quadScene = quadInfo->scene;
ramses::Scene* quadScene2 = quadInfo2->scene;
ramses::Node* providerNode = triangleInfo->translateNode;
ramses::Node* consumerNode = quadInfo->consumerNode;
ramses::Node* consumerNode2 = quadInfo2->consumerNode;
// IMPORTANT NOTE: For simplicity and readability the example code does not check return values from API calls.
// This should not be the case for real applications.
// Transformation links
ramses::dataProviderId_t transformationProviderId(14u);
ramses::dataConsumerId_t transformationConsumerId(12u);
ramses::dataConsumerId_t transformationConsumerId2(87u);
triangleScene->createTransformationDataProvider(*providerNode, transformationProviderId);
quadScene->createTransformationDataConsumer(*consumerNode, transformationConsumerId);
quadScene2->createTransformationDataConsumer(*consumerNode2, transformationConsumerId2);
//Data links
ramses::dataProviderId_t dataProviderId(100u);
ramses::dataConsumerId_t dataConsumerId(101u);
triangleScene->createDataConsumer(*triangleInfo->colorData, dataConsumerId);
quadScene->createDataProvider(*quadInfo->colorData, dataProviderId);
//Texture links
ramses::dataProviderId_t textureProviderId(200u);
ramses::dataConsumerId_t textureConsumerId(201u);
triangleScene->createTextureProvider(*triangleInfo->textures[0], textureProviderId);
quadScene2->createTextureConsumer(*quadInfo2->textureSampler, textureConsumerId);
triangleScene->flush();
quadScene->flush();
quadScene2->flush();
framework.connect();
triangleScene->publish();
quadScene->publish();
quadScene2->publish();
const auto fbId = renderer.getDisplayFramebuffer(display);
sceneControlAPI.setSceneMapping(triangleSceneId, display);
sceneControlAPI.setSceneMapping(quadSceneId, display);
sceneControlAPI.setSceneMapping(quadSceneId2, display);
sceneControlAPI.flush();
sceneControlAPI.setSceneDisplayBufferAssignment(triangleSceneId, fbId, 0);
sceneControlAPI.setSceneDisplayBufferAssignment(quadSceneId, fbId, 1);
sceneControlAPI.setSceneDisplayBufferAssignment(quadSceneId2, fbId, 2);
sceneControlAPI.setSceneState(triangleSceneId, ramses::RendererSceneState::Rendered);
sceneControlAPI.setSceneState(quadSceneId, ramses::RendererSceneState::Rendered);
sceneControlAPI.setSceneState(quadSceneId2, ramses::RendererSceneState::Rendered);
sceneControlAPI.flush();
SceneStateEventHandler eventHandler(sceneControlAPI, renderer);
eventHandler.waitForDataProviderOrConsumerCreated(triangleSceneId);
eventHandler.waitForDataProviderOrConsumerCreated(quadSceneId);
eventHandler.waitForDataProviderOrConsumerCreated(quadSceneId2);
// link transformation
sceneControlAPI.linkData(triangleSceneId, transformationProviderId, quadSceneId, transformationConsumerId);
sceneControlAPI.linkData(triangleSceneId, transformationProviderId, quadSceneId2, transformationConsumerId2);
// link data
sceneControlAPI.linkData(quadSceneId, dataProviderId, triangleSceneId, dataConsumerId);
// link texture
sceneControlAPI.linkData(triangleSceneId, textureProviderId, quadSceneId2, textureConsumerId);
sceneControlAPI.flush();
// run animation
uint32_t textureId = 0;
uint64_t timeStamp = 0u;
RendererEventHandler rendererEventHandler;
while (!rendererEventHandler.isWindowClosed())
{
renderer.dispatchEvents(rendererEventHandler);
if (timeStamp % 100 == 0)
{
textureId = (1 - textureId);
triangleInfo->scene->updateTextureProvider(*triangleInfo->textures[textureId], textureProviderId);
}
triangleInfo->translateNode->setTranslation(std::sin(timeStamp * 0.05f) * 0.2f, 0.0f, 0.0f);
triangleInfo->scene->flush();
quadInfo->rotateNode->rotate(0.0f, 0.0f, 1.0f);
quadInfo->scene->flush();
quadInfo2->rotateNode->rotate(0.0f, 1.0f, 0.0f);
quadInfo2->scene->flush();
quadInfo->colorData->setValue(std::sin(timeStamp * 0.1f), 0.0f, 0.5f, 1.0f);
renderer.doOneLoop();
timeStamp++;
std::this_thread::sleep_for(std::chrono::milliseconds{ 15u });
}
}
Definition: main.cpp:24
void windowClosed(ramses::displayId_t) override
This method will be called when a display's window has been closed.
Definition: main.cpp:26
bool isWindowClosed() const
Definition: main.cpp:31
Definition: main.cpp:48
void waitForDataProviderOrConsumerCreated(ramses::sceneId_t sceneId)
Definition: main.cpp:66
SceneStateEventHandler(ramses::RendererSceneControl &sceneControlApi, ramses::RamsesRenderer &renderer)
Definition: main.cpp:50
void dataConsumerCreated(ramses::sceneId_t sceneId, ramses::dataConsumerId_t) override
This method will be called whenever a data consumer is created.
Definition: main.cpp:61
void dataProviderCreated(ramses::sceneId_t sceneId, ramses::dataProviderId_t) override
This method will be called whenever a data provider is created.
Definition: main.cpp:56
The Appearance describes how an object should look like. This includes GLSL uniform values,...
Definition: Appearance.h:34
status_t setInputValueVector4f(const UniformInput &input, float x, float y, float z, float w)
Sets value of the input.
status_t setCullingMode(ECullMode mode)
Sets the culling mode indicating which side of mesh will be removed before rasterization....
status_t setDepthFunction(EDepthFunc func)
Sets depth comparison function. Depth writing has to be enabled in order for this to have any effect....
status_t setInputTexture(const UniformInput &input, const TextureSampler &textureSampler)
Sets texture sampler to the input.
status_t bindInput(const UniformInput &input, const DataObject &dataObject)
Bind a DataObject to the Appearance's uniform input. The value from the DataObject will be used and a...
The ArrayResource stores a data array of a given type. The data is immutable. The resource can be use...
Definition: ArrayResource.h:26
The AttributeInput is a description of an attribute effect input.
Definition: AttributeInput.h:22
status_t setViewport(int32_t x, int32_t y, uint32_t width, uint32_t height)
Sets the viewport to be used when rendering with this camera.
The DataVector4f data object stores a vector with 4 float components within a scene.
Definition: DataVector4f.h:22
The DisplayConfig holds a set of parameters to be used to initialize a display.
Definition: DisplayConfig.h:22
An effect description holds all necessary information for an effect to be created.
Definition: EffectDescription.h:21
status_t setVertexShaderFromFile(const char *shaderSourceFileName)
Reads and sets vertex shader source from file.
status_t setUniformSemantic(const char *inputName, EEffectUniformSemantic semanticType)
Sets an uniform semantic. Used for uniforms which are not locally available on the client,...
status_t setFragmentShaderFromFile(const char *shaderSourceFileName)
Reads and sets fragment shader source from file.
An effect describes how an object will be rendered to the screen.
Definition: Effect.h:26
status_t findUniformInput(const char *inputName, UniformInput &uniformInput) const
Finds uniform input by input name.
status_t findAttributeInput(const char *inputName, AttributeInput &attributeInput) const
Finds attribute input by input name.
A geometry binding together with an appearance describe how an object will be rendered to the screen.
Definition: GeometryBinding.h:25
status_t setIndices(const ArrayResource &indicesResource)
Assign a data array with data type UInt16 or UInt32 to be used when accessing vertex data.
status_t setInputBuffer(const AttributeInput &attributeInput, const ArrayResource &arrayResource, uint32_t instancingDivisor=0)
Assign a data array resource to a given effect attribute input.
The MeshNode holds all information which is needed to render an object to the screen.
Definition: MeshNode.h:25
status_t setAppearance(Appearance &appearance)
Sets the Appearance of the MeshNode.
status_t setGeometryBinding(GeometryBinding &geometry)
Sets the GeometryBinding of the MeshNode.
The Node is the base class of all nodes and provides scene graph functionality which propagates to it...
Definition: Node.h:23
status_t setParent(Node &node)
Sets parent Node for this node.
status_t setTranslation(float x, float y, float z)
Sets the absolute translation the absolute values.
Entry point of RAMSES client API.
Definition: RamsesClient.h:34
Scene * createScene(sceneId_t sceneId, const SceneConfig &sceneConfig=SceneConfig(), const char *name=nullptr)
Create a new empty Scene.
The RamsesFrameworkConfig holds a set of parameters to be used to initialize ramses.
Definition: RamsesFrameworkConfig.h:23
Class representing ramses framework components that are needed to initialize an instance of ramses cl...
Definition: RamsesFramework.h:35
RamsesRenderer is the main renderer component which provides API to configure and control the way con...
Definition: RamsesRenderer.h:37
status_t doOneLoop()
Prepare content to be rendered in next frame and render next frame.
static Texture2D * CreateTextureResourceFromPng(const char *pngFilePath, Scene &scene, const TextureSwizzle &swizzle={}, const char *name=nullptr)
Creates a Texture from the given png file.
The RenderGroup is a container used to collect renderables which are supposed to be rendered together...
Definition: RenderGroup.h:31
status_t addMeshNode(const MeshNode &mesh, int32_t orderWithinGroup=0)
Add a mesh to this RenderGroup. If a mesh is already contained in this RenderGroup only its render or...
The RenderPass is a container used to collect meshes which are supposed to be rendered together.
Definition: RenderPass.h:31
status_t setCamera(const Camera &camera)
Set the camera to use for rendering the objects of this renderpass.
status_t setClearFlags(uint32_t clearFlags)
Set the clear flags which enable/disable the clearing of the render target assigned to this RenderPas...
status_t addRenderGroup(const RenderGroup &renderGroup, int32_t orderWithinPass=0)
Add a RenderGroup to this RenderPass for rendering.
The RendererConfig holds a set of parameters to be used to initialize a renderer.
Definition: RendererConfig.h:26
Convenience empty implementation of IRendererEventHandler that can be used to derive from when only s...
Definition: IRendererEventHandler.h:194
Convenience empty implementation of IRendererSceneControlEventHandler that can be used to derive from...
Definition: IRendererSceneControlEventHandler.h:214
Control states of scenes.
Definition: RendererSceneControl.h:33
status_t dispatchEvents(IRendererSceneControlEventHandler &eventHandler)
RendererSceneControl methods push commands to an internal queue which is submitted when calling flush...
The SceneConfig holds a set of parameters to be used when creating a scene.
Definition: SceneConfig.h:22
The Scene holds a scene graph. It is the essential class for distributing content to the ramses syste...
Definition: Scene.h:83
status_t publish(EScenePublicationMode publicationMode=EScenePublicationMode_LocalAndRemote)
Publishes the scene to the ramses system.
status_t createTextureProvider(const Texture2D &texture, dataProviderId_t dataId)
Annotates a Texture2D as a content provider. Texture provider and texture consumer can be linked on R...
PerspectiveCamera * createPerspectiveCamera(const char *name=nullptr)
Creates a Perspective Camera in this Scene.
status_t createDataConsumer(const DataObject &dataObject, dataConsumerId_t dataId)
Annotates a DataObject as a data consumer. Data provider and data consumer can be linked on Ramses Re...
status_t createDataProvider(const DataObject &dataObject, dataProviderId_t dataId)
Annotates a DataObject as a data provider. Data provider and data consumer can be linked on Ramses Re...
status_t createTransformationDataConsumer(const Node &node, dataConsumerId_t dataId)
Annotates a Node as a transformation data consumer. Data provider and data consumer can be linked on ...
status_t createTransformationDataProvider(const Node &node, dataProviderId_t dataId)
Annotates a Node as a transformation data provider. Data provider and data consumer can be linked on ...
status_t flush(sceneVersionTag_t sceneVersionTag=InvalidSceneVersionTag)
Commits all changes done to the scene since the last flush or since scene creation....
status_t createTextureConsumer(const TextureSampler &sampler, dataConsumerId_t dataId)
Annotates a ramses::TextureSampler as a content consumer. Texture provider and texture consumer can b...
Texture represents a 2-D texture resource.
Definition: Texture2D.h:24
The TextureSampler holds a texture and its sampling parameters.
Definition: TextureSampler.h:29
The UniformInput is a description of an uniform effect input.
Definition: UniformInput.h:22
@ EDepthFunc_Always
Definition: AppearanceEnums.h:133
@ ETextureSamplingMethod_Linear
Definition: TextureEnums.h:21
@ ETextureAddressMode_Clamp
Definition: TextureEnums.h:32
@ EClearFlags_None
Definition: RamsesFrameworkTypes.h:257
@ ModelViewProjectionMatrix
Model-view-projection matrix 4x4.
@ Vector2F
two components of type float per data element
@ UInt16
one component of type uint16_t per data element
@ Vector3F
three components of type float per data element
@ ERamsesShellType_Console
Definition: RamsesFrameworkTypes.h:169
@ Rendered
Scene is being rendered.
constexpr const resourceCacheFlag_t ResourceCacheFlag_DoNotCache
Requests the render to not cache a resource. This is the default value.
Definition: RamsesFrameworkTypes.h:212
@ ECullMode_Disabled
Definition: AppearanceEnums.h:94
int main(int argc, char *argv[])
Definition: main.cpp:21