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

DCSM Provider Example

// -------------------------------------------------------------------------
// Copyright (C) 2019 BMW AG
// -------------------------------------------------------------------------
// 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 <thread>
#include <iostream>
#include <algorithm>
#include <fstream>
class DCSMProviderExample : ramses::IDcsmProviderEventHandler
{
public:
DCSMProviderExample(int argc, char* argv[])
: m_framework(argc, argv)
, m_ramses(*m_framework.createClient("ramses-example-dcsm-provider"))
, m_dcsm(*m_framework.createDcsmProvider())
, m_alphaInput()
{
for (int i = 1; i < argc; ++i)
{
std::string arg = argv[i];
if (arg == "-offer")
{
if (argc <= i + 3)
{
std::cerr << "'-offer' argument error: too few arguments" << std::endl;
continue;
}
int sceneid = atoi(argv[++i]);
int content = atoi(argv[++i]);
int category = atoi(argv[++i]);
if (sceneid > 0)
m_sceneToOffer = ramses::sceneId_t(sceneid);
else
std::cerr << "'-offer' argument error: invalid scene, using default" << std::endl;
if (content > 0)
m_contentID = ramses::ContentID(content);
else
std::cerr << "'-offer' argument error: invalid content, using default" << std::endl;
if (category > 0)
m_categoryID = ramses::Category(category);
else
std::cerr << "'-offer' argument error: invalid category, using default" << std::endl;
}
}
m_framework.connect();
}
~DCSMProviderExample() override
{
// shutdown: stop distribution, free resources, unregister
if (m_scene)
{
m_scene->unpublish();
m_ramses.destroy(*m_scene);
}
m_framework.disconnect();
}
void createScene()
{
// create a scene for distributing content
m_scene = m_ramses.createScene(m_sceneToOffer, ramses::SceneConfig(), "dcsm example scene");
m_camera = m_scene->createOrthographicCamera("my camera");
m_camera->setFrustum(-1, 1, -1, 1, 0.1f, 100.0f);
m_camera->setViewport(0u, 0u, 100u, 100u);
ramses::RenderPass* renderPass = m_scene->createRenderPass("my render pass");
renderPass->setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
renderPass->setCamera(*m_camera);
ramses::RenderGroup* renderGroup = m_scene->createRenderGroup();
renderPass->addRenderGroup(*renderGroup);
const float vertexPositionsArray[] = { -1.0f, -1.0f, -1.f, 1.0f, -1.0f, -1.f, -1.0f, 1.0f, -1.f, 1.0f, 1.0f, -1.f };
ramses::ArrayResource* vertexPositions = m_scene->createArrayResource(ramses::EDataType::Vector3F, 4, vertexPositionsArray);
const float textureCoordsArray[] = { 0.f, 1.f, 1.f, 1.f, 0.f, 0.f, 1.f, 0.f };
ramses::ArrayResource* textureCoords = m_scene->createArrayResource(ramses::EDataType::Vector2F, 4, textureCoordsArray);
const uint16_t indicesArray[] = { 0, 1, 2, 2, 1, 3 };
ramses::ArrayResource* indices = m_scene->createArrayResource(ramses::EDataType::UInt16, 6, indicesArray);
const ramses::Texture2D* texture = ramses::RamsesUtils::CreateTextureResourceFromPng("res/ramses-example-dcsm-provider-texture.png", *m_scene);
const ramses::TextureSampler* sampler = m_scene->createTextureSampler(
*texture);
effectDesc.setVertexShaderFromFile("res/ramses-example-dcsm-provider.vert");
effectDesc.setFragmentShaderFromFile("res/ramses-example-dcsm-provider.frag");
ramses::EffectDescription effectDescOutline;
effectDescOutline.setVertexShaderFromFile("res/ramses-example-dcsm-provider-outline.vert");
effectDescOutline.setFragmentShaderFromFile("res/ramses-example-dcsm-provider-outline.frag");
const ramses::Effect* effectTex = m_scene->createEffect(effectDesc, ramses::ResourceCacheFlag_DoNotCache, "glsl shader");
m_appearance = m_scene->createAppearance(*effectTex, "triangle appearance");
const ramses::Effect* effectOutline = m_scene->createEffect(effectDescOutline, ramses::ResourceCacheFlag_DoNotCache, "glsl shader");
ramses::Appearance* appearanceOutline = m_scene->createAppearance(*effectOutline, "outline appearance");
ramses::GeometryBinding* geometry = m_scene->createGeometryBinding(*effectTex, "triangle geometry");
ramses::GeometryBinding* geometryOutline = m_scene->createGeometryBinding(*effectOutline, "triangle geometry");
geometry->setIndices(*indices);
geometryOutline->setIndices(*indices);
ramses::AttributeInput positionsInput;
ramses::AttributeInput texcoordsInput;
effectTex->findAttributeInput("a_position", positionsInput);
effectTex->findAttributeInput("a_texcoord", texcoordsInput);
geometry->setInputBuffer(positionsInput, *vertexPositions);
geometry->setInputBuffer(texcoordsInput, *textureCoords);
effectOutline->findAttributeInput("a_position", positionsInput);
effectOutline->findAttributeInput("a_texcoord", texcoordsInput);
geometryOutline->setInputBuffer(positionsInput, *vertexPositions);
geometryOutline->setInputBuffer(texcoordsInput, *textureCoords);
ramses::UniformInput textureInput;
effectTex->findUniformInput("textureSampler", textureInput);
effectTex->findUniformInput("transparency", m_alphaInput);
m_appearance->setInputTexture(textureInput, *sampler);
m_appearance->setInputValueFloat(m_alphaInput, 1.0f);
m_appearance->setBlendingOperations(ramses::EBlendOperation_Add, ramses::EBlendOperation_Add);
ramses::MeshNode* meshNode = m_scene->createMeshNode("textured triangle mesh node");
ramses::MeshNode* meshSizeOutline = m_scene->createMeshNode("size outline");
meshSizeOutline->setAppearance(*appearanceOutline);
meshSizeOutline->setGeometryBinding(*geometryOutline);
meshNode->setAppearance(*m_appearance);
meshNode->setGeometryBinding(*geometry);
renderGroup->addMeshNode(*meshNode, 1);
renderGroup->addMeshNode(*meshSizeOutline, 2);
m_scene->flush();
m_scene->publish();
}
std::vector<uint8_t> loadPreviewImageFile()
{
// load preview image
std::ifstream file;
file.open("res/ramses-example-dcsm-provider-texture.png", std::fstream::binary | std::fstream::in);
if (!file.good())
{
printf("Could not open preview image file!\n");
exit(1);
}
file.seekg(0, std::ios::end);
const auto numberOfBytes = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<uint8_t> fileContents(static_cast<unsigned int>(numberOfBytes));
file.read(reinterpret_cast<char*>(fileContents.data()), static_cast<std::streamsize>(numberOfBytes));
file.close();
return fileContents;
}
void runLoopForOneLifecycle()
{
m_sizeReceived = false;
m_released = false;
// first is to offer the content to a consumer listening
metadata.setPreviewDescription(std::u32string(U"example/пример/例"));
const auto& fileContents = loadPreviewImageFile();
metadata.setPreviewImagePng(fileContents.data(), fileContents.size());
m_dcsm.offerContentWithMetadata(m_contentID, m_categoryID, m_sceneToOffer, ramses::EDcsmOfferingMode::LocalAndRemote, metadata);
// wait for the consumer accepting the offer and sending the initial size
while (!m_sizeReceived)
{
m_dcsm.dispatchEvents(*this);
std::this_thread::sleep_for(std::chrono::milliseconds(16u));
}
bool currShowing = false;
ramses::SizeInfo currSize = m_newSize;
m_camera->setViewport(0u, 0u, currSize.width, currSize.height);
while (!m_released)
{
std::this_thread::sleep_for(std::chrono::milliseconds(16u));
// dispatch the events coming in via DCSM from the consumer
m_dcsm.dispatchEvents(*this);
const auto now = uint64_t(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
if (currSize != m_newSize)
{
const auto sizeStart = !m_sizeAnim.startTime ? now : m_sizeAnim.startTime;
const auto sizeEnd = !m_sizeAnim.finishTime ? now : m_sizeAnim.finishTime;
if (sizeStart <= now)
{
const auto currFraction = sizeEnd == sizeStart ? 1.0f : float(now - sizeStart) / (sizeEnd - sizeStart);
auto resultSize = m_newSize;
if (currFraction >= 0.999f)
currSize = m_newSize;
else
{
resultSize.width = static_cast<uint32_t>(currSize.width * (1.f - currFraction) + m_newSize.width * currFraction);
resultSize.height = static_cast<uint32_t>(currSize.height * (1.f - currFraction) + m_newSize.height * currFraction);
}
m_camera->setViewport(0u, 0u, resultSize.width, resultSize.height);
m_scene->flush();
}
}
if (currShowing != m_showing)
{
const auto showStart = !m_showHideAnim.startTime ? now : m_showHideAnim.startTime;
const auto showEnd = !m_showHideAnim.finishTime ? now : m_showHideAnim.finishTime;
if (showStart <= now)
{
const auto currFraction = showEnd == showStart ? 1.0f : float(now - showStart) / (showEnd - showStart);
m_appearance->setInputValueFloat(m_alphaInput, m_showing ? std::min(currFraction, 1.f) : 1 - std::min(currFraction, 1.f));
if (currFraction >= 0.999f)
currShowing = m_showing;
m_scene->flush();
}
}
}
}
// DCSM Provider event handler interface implementation
virtual void contentHide(ramses::ContentID /*contentID*/, ramses::AnimationInformation animInfo) override
{
// save the hide parameters, which are then used within our logic loop
m_showing = false;
m_showHideAnim = animInfo;
}
// DCSM Provider event handler interface implementation
virtual void contentShow(ramses::ContentID /*contentID*/, ramses::AnimationInformation animInfo) override
{
// save the show parameters, which are then used within our logic loop
m_showing = true;
m_showHideAnim = animInfo;
}
// DCSM Provider event handler interface implementation
virtual void stopOfferAccepted(ramses::ContentID /*contentID*/, ramses::AnimationInformation /*animInfo*/) override
{
// we will never request the content to be not offered anymore in this example, so this is not needed
}
// DCSM Provider event handler interface implementation
virtual void contentSizeChange(ramses::ContentID /*contentID*/, const ramses::CategoryInfoUpdate& categoryInfo, ramses::AnimationInformation animInfo) override
{
// save the resize parameters, which are then used within our logic loop
m_newSize = ramses::SizeInfo{ categoryInfo.getCategoryRect().width, categoryInfo.getCategoryRect().height };
m_sizeAnim = animInfo;
m_sizeReceived = true;
}
// DCSM Provider event handler interface implementation
virtual void contentReadyRequested(ramses::ContentID contentID) override
{
// we have our content ready before we offer it, so we automatically reply with ready here
m_dcsm.markContentReady(contentID);
}
// DCSM Provider event handler interface implementation
virtual void contentRelease(ramses::ContentID /*contentID*/, ramses::AnimationInformation /*animInfo*/) override
{
// if the consumer requests the content to be gone, we will leave our logic loop
m_released = true;
m_showing = false;
}
private:
bool m_released = false;
bool m_showing = false;
bool m_sizeReceived = false;
ramses::sceneId_t m_sceneToOffer{123};
ramses::SizeInfo m_newSize = ramses::SizeInfo{ 0, 0 };
ramses::Scene* m_scene = nullptr;
ramses::OrthographicCamera* m_camera = nullptr;
ramses::Appearance* m_appearance = nullptr;
ramses::UniformInput m_alphaInput;
};
int main(int argc, char* argv[])
{
DCSMProviderExample example(argc, argv);
example.createScene();
example.runLoopForOneLifecycle();
return 0;
}
The Appearance describes how an object should look like. This includes GLSL uniform values,...
Definition: Appearance.h:34
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
Update of information about a DCSM category. Contains information like changes in size....
Definition: CategoryInfoUpdate.h:29
Rect getCategoryRect() const
Get new category rect. Only valid when hasCategoryRectUpdate().
Class to create DCSM metadata object to be used in DcsmProvider.
Definition: DcsmMetadataCreator.h:30
status_t setPreviewImagePng(const void *data, size_t dataLength)
Set preview image metadata entry. Data must point to a valid in memory representation of a PNG file f...
status_t setPreviewDescription(std::u32string previewDescription)
Set preview description metadata entry. Must be a valid utf32 string.
Class used to offer ramses content and meta infos to a consumer and synchronize actions between clien...
Definition: DcsmProvider.h:28
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.
An Interface for a class, whose functions are called as reaction to DcsmConsumer communication after ...
Definition: IDcsmProviderEventHandler.h:24
virtual void contentShow(ContentID contentID, AnimationInformation animInfo)=0
Called if a content will be switched to shown.
virtual void contentSizeChange(ContentID contentID, const CategoryInfoUpdate &categoryInfo, AnimationInformation animInfo)=0
Called after the rendering viewport for the content has been changed. Will be called once after a Dcs...
virtual void stopOfferAccepted(ContentID contentID, AnimationInformation animInfo)=0
Called after a content was requested to no longer be offered. After this function returns,...
virtual void contentRelease(ContentID contentID, AnimationInformation animInfo)=0
Called after an assigned DcsmConsumer is no longer interested in the content or the scene associated ...
virtual void contentHide(ContentID contentID, AnimationInformation animInfo)=0
Called if a content will be switched to be hidden.
virtual void contentReadyRequested(ContentID contentID)=0
Called after a DcsmConsumer requested the content and it has not been marked ready yet....
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 OrthographicCamera is a local camera which defines an orthographic view into the scene.
Definition: OrthographicCamera.h:22
Entry point of RAMSES client API.
Definition: RamsesClient.h:34
Class representing ramses framework components that are needed to initialize an instance of ramses cl...
Definition: RamsesFramework.h:35
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.
status_t setClearColor(float r, float g, float b, float a)
Set the clear color for the RenderPass (default: [0,0,0,0])
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
Helper class to create strongly typed values out of various types.
Definition: StronglyTypedValue.h:23
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
@ ETextureSamplingMethod_Linear
Definition: TextureEnums.h:21
@ ETextureAddressMode_Repeat
Definition: TextureEnums.h:33
StronglyTypedValue< uint64_t, 0, struct SceneIdTag > sceneId_t
Scene identifier used to refer to scenes created using client API and then manage their mapping using...
Definition: RamsesFrameworkTypes.h:43
StronglyTypedValue< uint64_t, 0, ContentIDTag > ContentID
Identifier for DCSM content. Must be globally unique.
Definition: DcsmApiTypes.h:25
@ EClearFlags_Color
Definition: RamsesFrameworkTypes.h:259
@ 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
constexpr const resourceCacheFlag_t ResourceCacheFlag_DoNotCache
Requests the render to not cache a resource. This is the default value.
Definition: RamsesFrameworkTypes.h:212
StronglyTypedValue< uint64_t, 0, CategoryTag > Category
Category descriptor for DCSM.
Definition: DcsmApiTypes.h:33
@ EBlendFactor_OneMinusSrcAlpha
Definition: AppearanceEnums.h:74
@ EBlendFactor_One
Definition: AppearanceEnums.h:72
@ EBlendFactor_SrcAlpha
Definition: AppearanceEnums.h:73
@ EBlendOperation_Add
Definition: AppearanceEnums.h:58
int main(int argc, char *argv[])
Definition: main.cpp:21
Definition: DcsmApiTypes.h:152
uint32_t width
width of rectangle
Definition: DcsmApiTypes.h:79
uint32_t height
height of rectangle
Definition: DcsmApiTypes.h:82
Size information for DCSM canvas size change.
Definition: DcsmApiTypes.h:109
uint32_t width
canvas width in pixels
Definition: DcsmApiTypes.h:122
uint32_t height
canvas height in pixels
Definition: DcsmApiTypes.h:125