diff --git a/examples/simple_demo_qml/CMakeLists.txt b/examples/simple_demo_qml/CMakeLists.txt index 90dface6f..0a4b2c49b 100644 --- a/examples/simple_demo_qml/CMakeLists.txt +++ b/examples/simple_demo_qml/CMakeLists.txt @@ -58,9 +58,9 @@ set(CMAKE_AUTOUIC ON) # Build add_executable(simple_demo_qml - Main.cpp - IgnitionRenderer.h - IgnitionRenderer.cpp + Main.cc + IgnitionRenderer.hh + IgnitionRenderer.cc ThreadRenderer.h ThreadRenderer.cpp ${QT_RESOURCES} diff --git a/examples/simple_demo_qml/IgnitionRenderer.cc b/examples/simple_demo_qml/IgnitionRenderer.cc new file mode 100644 index 000000000..5b25f3dfb --- /dev/null +++ b/examples/simple_demo_qml/IgnitionRenderer.cc @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2021 Rhys Mainwaring + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// The functions BuildScene and createCamera are copied from the simple_demo +// example. + +#include "IgnitionRenderer.hh" + +#include +#include + +#include + +#include + +using namespace ignition; +using namespace rendering; + +////////////////////////////////////////////////// +void BuildScene(ignition::rendering::ScenePtr _scene) +{ + // initialize _scene + _scene->SetAmbientLight(0.3, 0.3, 0.3); + VisualPtr root = _scene->RootVisual(); + + // create directional light + DirectionalLightPtr light0 = _scene->CreateDirectionalLight(); + light0->SetDirection(-0.5, 0.5, -1); + light0->SetDiffuseColor(0.5, 0.5, 0.5); + light0->SetSpecularColor(0.5, 0.5, 0.5); + root->AddChild(light0); + + // create point light + PointLightPtr light2 = _scene->CreatePointLight(); + light2->SetDiffuseColor(0.5, 0.5, 0.5); + light2->SetSpecularColor(0.5, 0.5, 0.5); + light2->SetLocalPosition(3, 5, 5); + root->AddChild(light2); + + // create green material + MaterialPtr green = _scene->CreateMaterial(); + green->SetAmbient(0.0, 0.5, 0.0); + green->SetDiffuse(0.0, 0.7, 0.0); + green->SetSpecular(0.5, 0.5, 0.5); + green->SetShininess(50); + green->SetReflectivity(0); + + // create center visual + VisualPtr center = _scene->CreateVisual(); + center->AddGeometry(_scene->CreateSphere()); + center->SetLocalPosition(3, 0, 0); + center->SetLocalScale(0.1, 0.1, 0.1); + center->SetMaterial(green); + root->AddChild(center); + + // create red material + MaterialPtr red = _scene->CreateMaterial(); + red->SetAmbient(0.5, 0.0, 0.0); + red->SetDiffuse(1.0, 0.0, 0.0); + red->SetSpecular(0.5, 0.5, 0.5); + red->SetShininess(50); + red->SetReflectivity(0); + red->SetRenderOrder(3); + + // create sphere visual + VisualPtr sphere = _scene->CreateVisual(); + sphere->AddGeometry(_scene->CreateSphere()); + sphere->SetOrigin(0.0, -0.5, 0.0); + sphere->SetLocalPosition(3, 0, 0); + sphere->SetLocalRotation(0, 0, 0); + sphere->SetLocalScale(1, 1, 1); + sphere->SetMaterial(red); + root->AddChild(sphere); + + // create blue material + MaterialPtr blue = _scene->CreateMaterial(); + blue->SetAmbient(0.0, 0.0, 0.3); + blue->SetDiffuse(0.0, 0.0, 0.8); + blue->SetSpecular(0.5, 0.5, 0.5); + blue->SetShininess(50); + blue->SetReflectivity(0); + + // create box visual + VisualPtr box = _scene->CreateVisual(); + box->AddGeometry(_scene->CreateBox()); + box->SetOrigin(0.0, 0.5, 0.0); + box->SetLocalPosition(3, 0, 0); + box->SetLocalRotation(IGN_PI / 4, 0, IGN_PI / 3); + box->SetLocalScale(1, 2.5, 1); + box->SetMaterial(blue); + root->AddChild(box); + + // create ellipsoid visual + VisualPtr ellipsoidVisual = _scene->CreateVisual(); + auto ellipsoid = _scene->CreateSphere(); + ellipsoidVisual->SetLocalScale(1.2, 0.7, 0.5); + ellipsoidVisual->AddGeometry(ellipsoid); + ellipsoidVisual->SetLocalPosition(3, -1, 0); + ellipsoidVisual->SetMaterial(green); + root->AddChild(ellipsoidVisual); + + // create white material + MaterialPtr white = _scene->CreateMaterial(); + white->SetAmbient(0.5, 0.5, 0.5); + white->SetDiffuse(0.8, 0.8, 0.8); + white->SetReceiveShadows(true); + white->SetReflectivity(0); + white->SetRenderOrder(0); + + VisualPtr capsuleVisual = _scene->CreateVisual(); + CapsulePtr capsule = _scene->CreateCapsule(); + capsule->SetLength(0.2); + capsule->SetRadius(0.2); + capsuleVisual->AddGeometry(capsule); + capsuleVisual->SetOrigin(0.0, 0.0, 0.0); + capsuleVisual->SetLocalPosition(4, 2, 0); + capsuleVisual->SetLocalScale(1, 1, 1); + capsuleVisual->SetMaterial(red); + root->AddChild(capsuleVisual); + + // create plane visual + VisualPtr plane = _scene->CreateVisual(); + plane->AddGeometry(_scene->CreatePlane()); + plane->SetLocalScale(5, 8, 1); + plane->SetLocalPosition(3, 0, -0.5); + plane->SetMaterial(white); + root->AddChild(plane); + + // create plane visual + VisualPtr plane2 = _scene->CreateVisual(); + plane2->AddGeometry(_scene->CreatePlane()); + plane2->SetLocalScale(5, 8, 1); + plane2->SetLocalPosition(4, 0.5, -0.5); + plane2->Scale(0.1, 0.1, 1); + plane2->SetMaterial(red); + root->AddChild(plane2); + + // create axis visual + VisualPtr axis = _scene->CreateAxisVisual(); + axis->SetLocalPosition(4.0, 0.5, -0.4); + root->AddChild(axis); + + // create camera + CameraPtr camera = _scene->CreateCamera("camera"); + camera->SetLocalPosition(0.0, 0.0, 0.0); + camera->SetLocalRotation(0.0, 0.0, 0.0); + camera->SetImageWidth(800); + camera->SetImageHeight(600); + camera->SetAntiAliasing(2); + camera->SetAspectRatio(800.0/600.0); + camera->SetHFOV(IGN_PI / 2); + root->AddChild(camera); + + // track target + camera->SetTrackTarget(box); +} + +////////////////////////////////////////////////// +ignition::rendering::CameraPtr CreateCamera(const std::string &_engineName) +{ + // create and populate scene + std::map params; + + // ensure that the QML application and Ignition / Ogre2 share an OpenGL + // context + params["useCurrentGLContext"] = "1"; + RenderEngine *engine = rendering::engine(_engineName, params); + if (!engine) + { + std::cout << "Engine '" << _engineName + << "' is not supported" << std::endl; + return CameraPtr(); + } + ScenePtr scene = engine->CreateScene("scene"); + BuildScene(scene); + + // return camera sensor + SensorPtr sensor = scene->SensorByName("camera"); + return std::dynamic_pointer_cast(sensor); +} + +////////////////////////////////////////////////// +IgnitionRenderer::~IgnitionRenderer() +{ +} + +////////////////////////////////////////////////// +IgnitionRenderer::IgnitionRenderer() +{ +} + +////////////////////////////////////////////////// +void IgnitionRenderer::Initialise() +{ + // no-op - all initialised on the main thread +} + +////////////////////////////////////////////////// +void IgnitionRenderer::InitialiseOnMainThread() +{ + if (!this->initialised) + { + this->InitEngine(); + this->initialised = true; + } +} + +////////////////////////////////////////////////// +void IgnitionRenderer::Render() +{ + // pre-render may regenerate textureId if the size changes + this->camera->PreRender(); + this->textureId = this->camera->RenderTextureGLId(); + + // render to texture + this->camera->Update(); + + // Move camera + this->UpdateCamera(); +} + +////////////////////////////////////////////////// +bool IgnitionRenderer::Initialised() const +{ + return this->initialised; +} + +////////////////////////////////////////////////// +unsigned int IgnitionRenderer::TextureId() const +{ + return this->textureId; +} + +////////////////////////////////////////////////// +QSize IgnitionRenderer::TextureSize() const +{ + return this->textureSize; +} + +////////////////////////////////////////////////// +void IgnitionRenderer::InitEngine() +{ + std::string engineName("ogre2"); + + common::Console::SetVerbosity(4); + + try + { + this->camera = CreateCamera(engineName); + } + catch (...) + { + std::cerr << "Error starting up: " << engineName << std::endl; + } + + if (!this->camera) + { + ignerr << "No cameras found. Scene will not be rendered" << std::endl; + return; + } + + // quick check on sizing... + ignmsg << "imageW: " << this->camera->ImageWidth() << "\n"; + ignmsg << "imageH: " << this->camera->ImageHeight() << "\n"; + + // pre-render will force texture creation and may update texture id + this->camera->PreRender(); + this->textureId = this->camera->RenderTextureGLId(); +} + +////////////////////////////////////////////////// +void IgnitionRenderer::UpdateCamera() +{ + double angle = this->cameraOffset / 2 * M_PI; + double x = sin(angle) * 3.0 + 3.0; + double y = cos(angle) * 3.0; + this->camera->SetLocalPosition(x, y, 0.0); + + this->cameraOffset += 0.0005; +} diff --git a/examples/simple_demo_qml/IgnitionRenderer.cpp b/examples/simple_demo_qml/IgnitionRenderer.cpp deleted file mode 100644 index a12668c29..000000000 --- a/examples/simple_demo_qml/IgnitionRenderer.cpp +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) 2021 Rhys Mainwaring - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// The functions buildScene and createCamera are copied from the simple_demo example. - -#include "IgnitionRenderer.h" - -#include -#include - -#include - -#include - -using namespace ignition; -using namespace rendering; - -//----------------------------------------------------------------------- -void BuildScene(ignition::rendering::ScenePtr _scene) -{ - - // initialize _scene - _scene->SetAmbientLight(0.3, 0.3, 0.3); - VisualPtr root = _scene->RootVisual(); - - // create directional light - DirectionalLightPtr light0 = _scene->CreateDirectionalLight(); - light0->SetDirection(-0.5, 0.5, -1); - light0->SetDiffuseColor(0.5, 0.5, 0.5); - light0->SetSpecularColor(0.5, 0.5, 0.5); - root->AddChild(light0); - - // create point light - PointLightPtr light2 = _scene->CreatePointLight(); - light2->SetDiffuseColor(0.5, 0.5, 0.5); - light2->SetSpecularColor(0.5, 0.5, 0.5); - light2->SetLocalPosition(3, 5, 5); - root->AddChild(light2); - - // create green material - MaterialPtr green = _scene->CreateMaterial(); - green->SetAmbient(0.0, 0.5, 0.0); - green->SetDiffuse(0.0, 0.7, 0.0); - green->SetSpecular(0.5, 0.5, 0.5); - green->SetShininess(50); - green->SetReflectivity(0); - - // create center visual - VisualPtr center = _scene->CreateVisual(); - center->AddGeometry(_scene->CreateSphere()); - center->SetLocalPosition(3, 0, 0); - center->SetLocalScale(0.1, 0.1, 0.1); - center->SetMaterial(green); - root->AddChild(center); - - // create red material - MaterialPtr red = _scene->CreateMaterial(); - red->SetAmbient(0.5, 0.0, 0.0); - red->SetDiffuse(1.0, 0.0, 0.0); - red->SetSpecular(0.5, 0.5, 0.5); - red->SetShininess(50); - red->SetReflectivity(0); - red->SetRenderOrder(3); - - // create sphere visual - VisualPtr sphere = _scene->CreateVisual(); - sphere->AddGeometry(_scene->CreateSphere()); - sphere->SetOrigin(0.0, -0.5, 0.0); - sphere->SetLocalPosition(3, 0, 0); - sphere->SetLocalRotation(0, 0, 0); - sphere->SetLocalScale(1, 1, 1); - sphere->SetMaterial(red); - root->AddChild(sphere); - - // create blue material - MaterialPtr blue = _scene->CreateMaterial(); - blue->SetAmbient(0.0, 0.0, 0.3); - blue->SetDiffuse(0.0, 0.0, 0.8); - blue->SetSpecular(0.5, 0.5, 0.5); - blue->SetShininess(50); - blue->SetReflectivity(0); - - // create box visual - VisualPtr box = _scene->CreateVisual(); - box->AddGeometry(_scene->CreateBox()); - box->SetOrigin(0.0, 0.5, 0.0); - box->SetLocalPosition(3, 0, 0); - box->SetLocalRotation(IGN_PI / 4, 0, IGN_PI / 3); - box->SetLocalScale(1, 2.5, 1); - box->SetMaterial(blue); - root->AddChild(box); - - // create ellipsoid visual - VisualPtr ellipsoidVisual = _scene->CreateVisual(); - auto ellipsoid = _scene->CreateSphere(); - ellipsoidVisual->SetLocalScale(1.2, 0.7, 0.5); - ellipsoidVisual->AddGeometry(ellipsoid); - ellipsoidVisual->SetLocalPosition(3, -1, 0); - ellipsoidVisual->SetMaterial(green); - root->AddChild(ellipsoidVisual); - - // create white material - MaterialPtr white = _scene->CreateMaterial(); - white->SetAmbient(0.5, 0.5, 0.5); - white->SetDiffuse(0.8, 0.8, 0.8); - white->SetReceiveShadows(true); - white->SetReflectivity(0); - white->SetRenderOrder(0); - - VisualPtr capsuleVisual = _scene->CreateVisual(); - CapsulePtr capsule = _scene->CreateCapsule(); - capsule->SetLength(0.2); - capsule->SetRadius(0.2); - capsuleVisual->AddGeometry(capsule); - capsuleVisual->SetOrigin(0.0, 0.0, 0.0); - capsuleVisual->SetLocalPosition(4, 2, 0); - capsuleVisual->SetLocalScale(1, 1, 1); - capsuleVisual->SetMaterial(red); - root->AddChild(capsuleVisual); - - // create plane visual - VisualPtr plane = _scene->CreateVisual(); - plane->AddGeometry(_scene->CreatePlane()); - plane->SetLocalScale(5, 8, 1); - plane->SetLocalPosition(3, 0, -0.5); - plane->SetMaterial(white); - root->AddChild(plane); - - // create plane visual - VisualPtr plane2 = _scene->CreateVisual(); - plane2->AddGeometry(_scene->CreatePlane()); - plane2->SetLocalScale(5, 8, 1); - plane2->SetLocalPosition(4, 0.5, -0.5); - plane2->Scale(0.1, 0.1, 1); - plane2->SetMaterial(red); - root->AddChild(plane2); - - // create axis visual - VisualPtr axis = _scene->CreateAxisVisual(); - axis->SetLocalPosition(4.0, 0.5, -0.4); - root->AddChild(axis); - - // create camera - CameraPtr camera = _scene->CreateCamera("camera"); - camera->SetLocalPosition(0.0, 0.0, 0.0); - camera->SetLocalRotation(0.0, 0.0, 0.0); - camera->SetImageWidth(800); - camera->SetImageHeight(600); - camera->SetAntiAliasing(2); - camera->SetAspectRatio(800.0/600.0); - camera->SetHFOV(IGN_PI / 2); - root->AddChild(camera); - - // track target - camera->SetTrackTarget(box); -} - -//----------------------------------------------------------------------- -ignition::rendering::CameraPtr CreateCamera(const std::string &_engineName) -{ - // create and populate scene - std::map params; - - // ensure that the QML application and Ignition / Ogre2 share an OpenGL context - params["useCurrentGLContext"] = "1"; - RenderEngine *engine = rendering::engine(_engineName, params); - if (!engine) - { - std::cout << "Engine '" << _engineName - << "' is not supported" << std::endl; - return CameraPtr(); - } - ScenePtr scene = engine->CreateScene("scene"); - BuildScene(scene); - - // return camera sensor - SensorPtr sensor = scene->SensorByName("camera"); - return std::dynamic_pointer_cast(sensor); -} - -//----------------------------------------------------------------------- -IgnitionRenderer::~IgnitionRenderer() -{ -} - -//----------------------------------------------------------------------- -IgnitionRenderer::IgnitionRenderer() -{ -} - -//----------------------------------------------------------------------- -void IgnitionRenderer::Initialise() -{ - // no-op - all initialised on the main thread -} - -//----------------------------------------------------------------------- -void IgnitionRenderer::InitialiseOnMainThread() -{ - if (!this->initialised) - { - this->InitEngine(); - this->initialised = true; - } -} - -//----------------------------------------------------------------------- -void IgnitionRenderer::Render() -{ - // pre-render may regenerate textureId if the size changes - this->camera->PreRender(); - this->textureId = this->camera->RenderTextureGLId(); - - // render to texture - this->camera->Update(); - - // Move camera - this->UpdateCamera(); -} - -//----------------------------------------------------------------------- -bool IgnitionRenderer::Initialised() const -{ - return this->initialised; -} - -//----------------------------------------------------------------------- -unsigned int IgnitionRenderer::TextureId() const -{ - return this->textureId; -} - -//----------------------------------------------------------------------- -QSize IgnitionRenderer::TextureSize() const -{ - return this->textureSize; -} - -//----------------------------------------------------------------------- -void IgnitionRenderer::InitEngine() -{ - std::string engineName("ogre2"); - - common::Console::SetVerbosity(4); - - try - { - this->camera = CreateCamera(engineName); - } - catch (...) - { - std::cerr << "Error starting up: " << engineName << std::endl; - } - - if (!this->camera) - { - ignerr << "No cameras found. Scene will not be rendered" << std::endl; - return; - } - - // quick check on sizing... - ignmsg << "imageW: " << this->camera->ImageWidth() << "\n"; - ignmsg << "imageH: " << this->camera->ImageHeight() << "\n"; - - // pre-render will force texture creation and may update texture id - this->camera->PreRender(); - this->textureId = this->camera->RenderTextureGLId(); -} - -//----------------------------------------------------------------------- -void IgnitionRenderer::UpdateCamera() -{ - double angle = this->cameraOffset / 2 * M_PI; - double x = sin(angle) * 3.0 + 3.0; - double y = cos(angle) * 3.0; - this->camera->SetLocalPosition(x, y, 0.0); - - this->cameraOffset += 0.0005; -} - -//----------------------------------------------------------------------- diff --git a/examples/simple_demo_qml/IgnitionRenderer.h b/examples/simple_demo_qml/IgnitionRenderer.h deleted file mode 100644 index eddf81fca..000000000 --- a/examples/simple_demo_qml/IgnitionRenderer.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2021 Rhys Mainwaring - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef IGNITION_RENDERING_EXAMPLES_SIMPLE_DEMO_IGNITION_RENDERER_HH_ -#define IGNITION_RENDERING_EXAMPLES_SIMPLE_DEMO_IGNITION_RENDERER_HH_ - -#include - -#include - -/// \brief Ignition renderer class. This manages the initialisation -/// and update of an Ignition rendering engine instance and makes the -/// rendered texture available in a shared context for an application -/// to apply to a render surface. -class IgnitionRenderer -{ -public: - /// \brief Destructor - virtual ~IgnitionRenderer(); - - /// \brief Constructor - IgnitionRenderer(); - - /// \brief Render the next frame. May be called on a render thread. - void Render(); - - /// \brief Initialise the render engine and scene. May be called on a render thread. - void Initialise(); - - /// \brief Initialise the render engine and scene. Must be called on the main thread. - void InitialiseOnMainThread(); - - /// \brief Return a boolean: true if the renderer is initialised. - bool Initialised() const; - - /// \brief Return the ID of the OpenGL texture. - unsigned int TextureId() const; - - /// \brief Return the size of the texture - QSize TextureSize() const; - -private: - /// \brief Initialise the render engine. Must be called on the main thread. - void InitEngine(); - - /// \brief Move the camera position one step in its orbit. - void UpdateCamera(); - - /// \brief The OpenGL texture ID - unsigned int textureId = 0; - - /// \brief The sise of the texture being rendered - QSize textureSize = QSize(800, 600); - - /// \brief A flag to mark if the renderer has been initialised - bool initialised = false; - - /// \brief The current camera offset in its orbit - double cameraOffset = 0.0; - - /// \brief The camera for the example scene - ignition::rendering::CameraPtr camera; -}; - -#endif // IGNITION_RENDERING_EXAMPLES_SIMPLE_DEMO_IGNITION_RENDERER_HH_ diff --git a/examples/simple_demo_qml/IgnitionRenderer.hh b/examples/simple_demo_qml/IgnitionRenderer.hh new file mode 100644 index 000000000..6edd9172d --- /dev/null +++ b/examples/simple_demo_qml/IgnitionRenderer.hh @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2021 Rhys Mainwaring + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef IGNITION_RENDERING_EXAMPLES_SIMPLE_DEMO_QML_IGNITION_RENDERER_HH_ +#define IGNITION_RENDERING_EXAMPLES_SIMPLE_DEMO_QML_IGNITION_RENDERER_HH_ + +#include + +#include + +/// \brief Ignition renderer class. This manages the initialisation +/// and update of an Ignition rendering engine instance and makes the +/// rendered texture available in a shared context for an application +/// to apply to a render surface. +class IgnitionRenderer +{ + /// \brief Destructor + public: virtual ~IgnitionRenderer(); + + /// \brief Constructor + public: IgnitionRenderer(); + + /// \brief Render the next frame. May be called on a render thread. + public: void Render(); + + /// \brief Initialise the render engine and scene. May be called on a render + /// thread. + public: void Initialise(); + + /// \brief Initialise the render engine and scene. Must be called on the main + /// thread. + public: void InitialiseOnMainThread(); + + /// \brief Return a boolean: true if the renderer is initialised. + public: bool Initialised() const; + + /// \brief Return the ID of the OpenGL texture. + public: unsigned int TextureId() const; + + /// \brief Return the size of the texture + public: QSize TextureSize() const; + + /// \brief Initialise the render engine. Must be called on the main thread. + private: void InitEngine(); + + /// \brief Move the camera position one step in its orbit. + private: void UpdateCamera(); + + /// \brief The OpenGL texture ID + private: unsigned int textureId = 0; + + /// \brief The sise of the texture being rendered + private: QSize textureSize = QSize(800, 600); + + /// \brief A flag to mark if the renderer has been initialised + private: bool initialised = false; + + /// \brief The current camera offset in its orbit + private: double cameraOffset = 0.0; + + /// \brief The camera for the example scene + private: ignition::rendering::CameraPtr camera; +}; + +#endif // IGNITION_RENDERING_EXAMPLES_SIMPLE_DEMO_QML_IGNITION_RENDERER_HH_ diff --git a/examples/simple_demo_qml/Main.cc b/examples/simple_demo_qml/Main.cc new file mode 100644 index 000000000..512b260da --- /dev/null +++ b/examples/simple_demo_qml/Main.cc @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2021 Rhys Mainwaring + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "ThreadRenderer.h" + +#include +#include +#include + +#include +#include + +int main(int _argc, char** _argv) +{ + try + { + // use single-threaded scene graph rendering + qputenv("QSG_RENDER_LOOP", "basic"); + + // requested surface format + QSurfaceFormat format = RenderThread::CreateSurfaceFormat(); + QSurfaceFormat::setDefaultFormat(format); + RenderThread::Print(format); + + qmlRegisterType("IgnitionRendering", 1, 0, + "ThreadRenderer"); + + QGuiApplication app(_argc, _argv); + + int execReturn = 0; + { + QQuickView view; + + // Rendering in a thread introduces a slightly more complicated cleanup + // so we ensure that no cleanup of graphics resources happen until the + // application is shutting down. + view.setPersistentOpenGLContext(true); + view.setPersistentSceneGraph(true); + + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.setSource(QUrl("qrc:/Main.qml")); + view.show(); + + execReturn = app.exec(); + } + + // As the render threads make use of our QGuiApplication object + // to clean up gracefully, wait for them to finish before + // QGuiApp is taken off the heap. + for (QThread *t : qAsConst(ThreadRenderer::threads)) + { + t->wait(); + delete t; + t = nullptr; + } + + return execReturn; + } + catch (const std::exception& e) + { + std::cerr << e.what() << '\n'; + } + catch (...) + { + std::cerr << "Unknown exception" << '\n'; + } + return -1; +} diff --git a/examples/simple_demo_qml/Main.cpp b/examples/simple_demo_qml/Main.cpp deleted file mode 100644 index c749f2c97..000000000 --- a/examples/simple_demo_qml/Main.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2021 Rhys Mainwaring - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "ThreadRenderer.h" - -#include -#include -#include - -#include -#include - -int main(int _argc, char** _argv) -{ - try - { - // requested surface format - QSurfaceFormat format = RenderThread::CreateSurfaceFormat(); - QSurfaceFormat::setDefaultFormat(format); - RenderThread::Print(format); - - qmlRegisterType("IgnitionRendering", 1, 0, "ThreadRenderer"); - - QGuiApplication app(_argc, _argv); - - int execReturn = 0; - { - QQuickView view; - - // Rendering in a thread introduces a slightly more complicated cleanup - // so we ensure that no cleanup of graphics resources happen until the - // application is shutting down. - view.setPersistentOpenGLContext(true); - view.setPersistentSceneGraph(true); - - view.setResizeMode(QQuickView::SizeRootObjectToView); - view.setSource(QUrl("qrc:/Main.qml")); - view.show(); - - execReturn = app.exec(); - } - - // As the render threads make use of our QGuiApplication object - // to clean up gracefully, wait for them to finish before - // QGuiApp is taken off the heap. - for (QThread *t : qAsConst(ThreadRenderer::threads)) - { - t->wait(); - delete t; - t = nullptr; - } - - return execReturn; - } - catch (const std::exception& e) - { - std::cerr << e.what() << '\n'; - } - catch (...) - { - std::cerr << "Unknown exception" << '\n'; - } - return -1; -} diff --git a/examples/simple_demo_qml/Main.qml b/examples/simple_demo_qml/Main.qml index 5fd7bcbe4..6ffc0e995 100644 --- a/examples/simple_demo_qml/Main.qml +++ b/examples/simple_demo_qml/Main.qml @@ -2,34 +2,34 @@ import QtQuick 2.0 import IgnitionRendering 1.0 Item { - width: 800 - height: 600 + width: 800 + height: 600 - ThreadRenderer { - id: renderer - anchors.fill: parent - anchors.margins: 10 - opacity: 0 - Component.onCompleted: renderer.opacity = 1; - } + ThreadRenderer { + id: renderer + anchors.fill: parent + anchors.margins: 10 + opacity: 0 + Component.onCompleted: renderer.opacity = 1; + } - Rectangle { - id: labelFrame - anchors.margins: -10 - radius: 5 - color: "white" - border.color: "black" - opacity: 0.8 - anchors.fill: label - } + Rectangle { + id: labelFrame + anchors.margins: -10 + radius: 5 + color: "white" + border.color: "black" + opacity: 0.8 + anchors.fill: label + } - Text { - id: label - anchors.bottom: renderer.bottom - anchors.left: renderer.left - anchors.right: renderer.right - anchors.margins: 20 - wrapMode: Text.WordWrap - text: "simple_demo_qml : the `simple_demo` example using ignition-rendering and QML." - } + Text { + id: label + anchors.bottom: renderer.bottom + anchors.left: renderer.left + anchors.right: renderer.right + anchors.margins: 20 + wrapMode: Text.WordWrap + text: "simple_demo_qml : the `simple_demo` example using ignition-rendering and QML." + } } diff --git a/examples/simple_demo_qml/ThreadRenderer.cpp b/examples/simple_demo_qml/ThreadRenderer.cpp index 5f1fa3c66..36e4343fa 100644 --- a/examples/simple_demo_qml/ThreadRenderer.cpp +++ b/examples/simple_demo_qml/ThreadRenderer.cpp @@ -69,7 +69,7 @@ ****************************************************************************/ #include "ThreadRenderer.h" -#include "IgnitionRenderer.h" +#include "IgnitionRenderer.hh" #include #include diff --git a/examples/simple_demo_qml/ThreadRenderer.h b/examples/simple_demo_qml/ThreadRenderer.h index ffea96d83..798fe6de4 100644 --- a/examples/simple_demo_qml/ThreadRenderer.h +++ b/examples/simple_demo_qml/ThreadRenderer.h @@ -68,10 +68,10 @@ ** ****************************************************************************/ -#ifndef IGNITION_RENDERING_EXAMPLES_SIMPLE_DEMO_THREAD_RENDERER_HH_ -#define IGNITION_RENDERING_EXAMPLES_SIMPLE_DEMO_THREAD_RENDERER_HH_ +#ifndef IGNITION_RENDERING_EXAMPLES_SIMPLE_DEMO_QML_THREAD_RENDERER_HH_ +#define IGNITION_RENDERING_EXAMPLES_SIMPLE_DEMO_QML_THREAD_RENDERER_HH_ -#include "IgnitionRenderer.h" +#include "IgnitionRenderer.hh" #include #include