Cogs.Core
ViewContext.cpp
1#include "ViewContext.h"
2
3#include "Components/Behavior/OrbitingCameraController.h"
4#include "Input/InputManager.h"
5#include "Platform/Gamepad.h"
6#include "Renderer/IRenderer.h"
7#include "Renderer/RenderResources.h"
8#include "Renderer/RenderTexture.h"
9#include "Services/DPIService.h"
10#include "Resources/TextureManager.h"
11#include "Systems/Core/CameraSystem.h"
12
13#include "Rendering/IGraphicsDevice.h"
14#include "Rendering/ISwapChain.h"
15
16#include "Foundation/Logging/Logger.h"
17
18#include <algorithm>
19
20namespace
21{
22 const Cogs::Logging::Log logger = Cogs::Logging::getLogger("ViewContext");
23}
24
25
27 : dpiService(std::make_unique<DPIService>())
28 , gamepadHandler(std::make_unique<Platform::GamepadHandler>())
29 , inputManager(std::make_unique<InputManager>(this))
30 , context(ctx) {
31 setWindowData(windowData);
32}
33
34Cogs::Core::ViewContext::~ViewContext() {
35 if(texture) {
36 CameraComponent* cameraComp = getCameraComponent();
37
38 if (cameraComp) {
40 }
41
42 EntityPtr cam = camera.lock();
43 if (cam) {
44 if (OrbitingCameraController* occ = cam->getComponent<OrbitingCameraController>(); occ) {
45 occ->attachToView(nullptr);
46 occ->setChanged();
47 }
48 }
49
50 RenderResource* renderTexture = texture->getAttachedResource();
51 if (renderTexture) {
52 static_cast<RenderResources*>(context->renderer->getResources())->destroyResource(renderTexture);
53 texture->attachResource(nullptr);
54 }
55 }
56 if (swapChain && (swapChain != context->device->getDefaultSwapChain())) {
57 context->device->deleteSwapChain(swapChain);
58 swapChain = nullptr;
59 }
60}
61
63 // For the default view, renderCamera is null because it will be set to the mainCamera after the scene is initialized.
64 if (!renderCamera) {
65 swapChain = context->device->getDefaultSwapChain();
66 }
67 else {
68 swapChain = context->device->createSwapChain(refWindowData());
69 if (!swapChain) {
70 LOG_WARNING(logger, "Swapchain creation failed, falling back to the default one.");
71 swapChain = context->device->getDefaultSwapChain();
72 }
73 }
74
75 texture = context->textureManager->create();
77 texture->description.format = context->device->getSettings().colorFormat;
78
79 RenderTexture* renderTexture = static_cast<RenderResources*>(context->renderer->getResources())->createRenderTexture();
80 renderTexture->setPersistent();
81 renderTexture->setOwned();
82 renderTexture->setResource(texture.resolve());
83 renderTexture->swapChain = swapChain;
84
85 texture->attachResource(renderTexture);
86
87 if (renderCamera) {
88 setCamera(renderCamera);
89 }
90
91 if(refWindowData()){
92 inputManager->initialize();
93
94 refGestures().setDisplayScale(dpiService->getScaleFactor());
95 gamepadHandler->initialize(this);
96 }
97
98 return true;
99}
100
102 if (refWindowData()) {
103 inputManager->update();
104 }
105}
106
108 if (swapChain && texture) {
109 texture->description.width = swapChain->getWidth();
110 texture->description.height = swapChain->getHeight();
111 }
112}
113
115 camera = renderCamera;
116 texture->getAttachedResource()->setName("ViewTexture (" + renderCamera->getName() + ")");
117
118 CameraComponent* cameraComp = getCameraComponent();
119 cameraComp->renderTexture = texture;
120 cameraComp->setChanged();
121
122 if (OrbitingCameraController* occ = renderCamera->getComponent<OrbitingCameraController>(); occ) {
123 occ->attachToView(this);
124 occ->setChanged();
125 }
126}
127
128void Cogs::Core::ViewContext::setSize(int newWidth, int newHeight) {
129 if (context->engine->isReady()) {
130 if (swapChain) {
131 swapChain->setSize(newWidth, newHeight);
132 }
133 else if ((context->getDefaultView() == this) && context->device) {
134 context->device->setSize(newWidth, newHeight);
135 }
136
137 glm::vec2 vpSize(newWidth, newHeight);
138 Cogs::Core::CameraComponent* cameraComp = getCameraComponent();
139
140 if (vpSize != cameraComp->viewportSize) {
141 cameraComp->viewportSize = vpSize;
142 cameraComp->setChanged();
143
144 if (texture) {
145 RenderResource* attachment = texture->getAttachedResource();
146
147 if (attachment) {
148 attachment->incrementGeneration();
149 }
150 }
151 }
152 for (ResizeCallback* cb : resizeCallbacks) {
153 cb(this, newWidth, newHeight);
154 }
155 }
156 context->engine->triggerUpdate();
157}
158
159void Cogs::Core::ViewContext::setDPI(int newDPI, float scaleFactor) {
160 dpiService->set(newDPI, scaleFactor);
161
162 context->engine->triggerUpdate();
163}
164
165glm::vec2 Cogs::Core::ViewContext::getSize() const {
166 if (swapChain) {
167 return glm::vec2(swapChain->getWidth(), swapChain->getHeight());
168 }
169 int width;
170 int height;
171
172 if (context->device->getSize(width, height)) {
173 return glm::vec2(width, height);
174 }
175 return glm::vec2(0.0f);
176}
177
179{
180 return camera.lock();
181}
182
184 EntityPtr cam = camera.lock();
185 return cam ? cam->getComponent<CameraComponent>() : context->cameraSystem->getMainCamera();
186}
187
188void Cogs::Core::ViewContext::addResizeCallback(ResizeCallback* callback) {
189 auto e = resizeCallbacks.end();
190
191 if (std::find(resizeCallbacks.begin(), e, callback) == e) {
192 resizeCallbacks.push_back(callback);
193 }
194}
195
196void Cogs::Core::ViewContext::removeResizeCallback(ResizeCallback* callback) {
197 auto e = resizeCallbacks.end();
198 auto i = std::find(resizeCallbacks.begin(), e, callback);
199
200 if (i != e) {
201 resizeCallbacks.erase(i);
202 }
203}
void setChanged()
Sets the component to the ComponentFlags::Changed state with carry.
Definition: Component.h:202
ComponentType * getComponent() const
Definition: Component.h:159
glm::vec2 viewportSize
Size of the viewport covered by this instance, given in pixels.
TextureHandle renderTexture
The render texture to output the rendered scene from the camera to.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
Input manager responsible for handling input from various devices, including mouse,...
Definition: InputManager.h:37
Component that calculates position and orientation of the entity TransformComponent.
Contains render resources used by the renderer.
CameraComponent * getCameraComponent() const
Utility to get the CameraComponent from.
void update()
Updates the components in this view. Called once per frame from the owning Context's update call.
Cogs::Core::EntityPtr getCamera() const
Gets view camera. The camera must be valid when rendering a frame in the view.
void preRender()
Called by the owning Context during its preRender call.
void setSize(int newWidth, int newHeight)
Resizes this view.
ViewContext(Context *ctx, WindowData *windowData)
Constructs a new ViewContext instance.
Definition: ViewContext.cpp:26
void setCamera(const Cogs::Core::EntityPtr &renderCamera)
Sets or updates the camera of this ViewContext instance.
bool initialize(const Cogs::Core::EntityPtr &renderCamera)
Initialises the standard components in this ViewContext instance.
Definition: ViewContext.cpp:62
Log implementation class.
Definition: LogManager.h:139
std::shared_ptr< ComponentModel::Entity > EntityPtr
Smart pointer for Entity access.
Definition: EntityPtr.h:12
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180
STL namespace.
static const ResourceHandle_t NoHandle
Handle representing a default (or none if default not present) resource.
@ RenderTarget
The texture can be used as a render target and drawn into.
Definition: Flags.h:120
@ Texture
Texture usage, see Default.
Definition: Flags.h:118