Removes SetViewport from CRenderer.
[0ad.git] / source / tools / atlas / GameInterface / Handlers / GraphicsSetupHandlers.cpp
blobcd849413c107072939186f03849cb28fc156b126
1 /* Copyright (C) 2022 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
18 #include "precompiled.h"
20 #include "MessageHandler.h"
21 #include "../GameLoop.h"
22 #include "../CommandProc.h"
23 #include "../ActorViewer.h"
24 #include "../View.h"
25 #include "../InputProcessor.h"
27 #include "graphics/GameView.h"
28 #include "graphics/ObjectManager.h"
29 #include "gui/GUIManager.h"
30 #include "lib/external_libraries/libsdl.h"
31 #include "lib/timer.h"
32 #include "maths/MathUtil.h"
33 #include "ps/CConsole.h"
34 #include "ps/CLogger.h"
35 #include "ps/Filesystem.h"
36 #include "ps/Profile.h"
37 #include "ps/Profiler2.h"
38 #include "ps/Game.h"
39 #include "ps/VideoMode.h"
40 #include "ps/GameSetup/Config.h"
41 #include "ps/GameSetup/GameSetup.h"
42 #include "renderer/backend/IDevice.h"
43 #include "renderer/Renderer.h"
44 #include "renderer/SceneRenderer.h"
46 #if OS_WIN
47 // We don't include wutil header directly to prevent including Windows headers.
48 extern void wutil_SetAppWindow(void* hwnd);
49 #endif
51 namespace AtlasMessage
54 InputProcessor g_Input;
56 // This keeps track of the last in-game user input.
57 // It is used to throttle FPS to save CPU & GPU.
58 double last_user_activity;
60 // see comment in GameLoop.cpp about ah_display_error before using INIT_HAVE_DISPLAY_ERROR
61 const int g_InitFlags = INIT_HAVE_VMODE | INIT_NO_GUI;
63 MESSAGEHANDLER(Init)
65 UNUSED2(msg);
67 g_Quickstart = true;
69 // Mount mods if there are any specified as command line parameters
70 if (!Init(g_AtlasGameLoop->args, g_InitFlags | INIT_MODS| INIT_MODS_PUBLIC))
72 // There are no mods specified on the command line,
73 // but there are in the config file, so mount those.
74 Shutdown(SHUTDOWN_FROM_CONFIG);
75 ENSURE(Init(g_AtlasGameLoop->args, g_InitFlags));
78 // Initialise some graphics state for Atlas.
79 // (This must be done after Init loads the config DB,
80 // but before the UI constructs its GL canvases.)
81 g_VideoMode.InitNonSDL();
84 MESSAGEHANDLER(InitAppWindow)
86 #if OS_WIN
87 wutil_SetAppWindow(msg->handle);
88 #else
89 UNUSED2(msg);
90 #endif
93 MESSAGEHANDLER(InitSDL)
95 UNUSED2(msg);
97 // When using GLX (Linux), SDL has to load the GL library to find
98 // glXGetProcAddressARB before it can load any extensions.
99 // When running in Atlas, we skip the SDL video initialisation code
100 // which loads the library, and so SDL_GL_GetProcAddress fails (in
101 // ogl.cpp importExtensionFunctions).
102 // So, make sure it's loaded:
103 SDL_InitSubSystem(SDL_INIT_VIDEO);
104 // wxWidgets doesn't use a proper approach to dynamically load functions and
105 // doesn't provide GetProcAddr-like function. Technically we need to call
106 // SDL_GL_LoadLibrary inside GL device creation, but that might lead to a
107 // crash on Windows because of a wrong order of initialization between SDL
108 // and wxWidgets context management. So leave the call as is while it works.
109 // Refs:
110 // http://trac.wxwidgets.org/ticket/9213
111 // http://trac.wxwidgets.org/ticket/9215
112 if (SDL_GL_LoadLibrary(nullptr) && g_Logger)
113 LOGERROR("SDL failed to load GL library: '%s'", SDL_GetError());
116 MESSAGEHANDLER(InitGraphics)
118 UNUSED2(msg);
120 g_VideoMode.CreateBackendDevice(false);
122 g_VideoMode.GetBackendDevice()->OnWindowResize(g_xres, g_yres);
124 InitGraphics(g_AtlasGameLoop->args, g_InitFlags, {});
128 MESSAGEHANDLER(Shutdown)
130 UNUSED2(msg);
132 // Empty the CommandProc, to get rid of its references to entities before
133 // we kill the EntityManager
134 GetCommandProc().Destroy();
136 AtlasView::DestroyViews();
137 g_AtlasGameLoop->view = AtlasView::GetView_None();
139 int flags = 0;
140 Shutdown(flags);
144 QUERYHANDLER(Exit)
146 UNUSED2(msg);
147 g_AtlasGameLoop->running = false;
151 MESSAGEHANDLER(RenderEnable)
153 g_AtlasGameLoop->view->SetEnabled(false);
154 g_AtlasGameLoop->view = AtlasView::GetView(msg->view);
155 g_AtlasGameLoop->view->SetEnabled(true);
158 MESSAGEHANDLER(SetViewParamB)
160 AtlasView* view = AtlasView::GetView(msg->view);
161 view->SetParam(*msg->name, msg->value);
164 MESSAGEHANDLER(SetViewParamI)
166 AtlasView* view = AtlasView::GetView(msg->view);
167 view->SetParam(*msg->name, msg->value);
170 MESSAGEHANDLER(SetViewParamC)
172 AtlasView* view = AtlasView::GetView(msg->view);
173 view->SetParam(*msg->name, msg->value);
176 MESSAGEHANDLER(SetViewParamS)
178 AtlasView* view = AtlasView::GetView(msg->view);
179 view->SetParam(*msg->name, *msg->value);
182 MESSAGEHANDLER(SetActorViewer)
184 if (msg->flushcache)
186 // TODO EXTREME DANGER: this'll break horribly if any units remain
187 // in existence and use their actors after we've deleted all the actors.
188 // (The actor viewer currently only has one unit at a time, so it's
189 // alright.)
190 // Should replace this with proper actor hot-loading system, or something.
192 AtlasView::GetView_Actor()->GetActorViewer().SetActor(L"", "", -1);
193 AtlasView::GetView_Actor()->GetActorViewer().UnloadObjects();
194 // vfs_reload_changed_files();
196 AtlasView::GetView_Actor()->SetSpeedMultiplier(msg->speed);
197 AtlasView::GetView_Actor()->GetActorViewer().SetActor(*msg->id, *msg->animation, msg->playerID);
200 //////////////////////////////////////////////////////////////////////////
202 MESSAGEHANDLER(SetCanvas)
204 // Need to set the canvas size before possibly doing any rendering,
205 // else we'll get GL errors when trying to render to 0x0
206 CVideoMode::UpdateRenderer(msg->width, msg->height);
208 g_AtlasGameLoop->glCanvas = msg->canvas;
209 Atlas_GLSetCurrent(const_cast<void*>(g_AtlasGameLoop->glCanvas));
213 MESSAGEHANDLER(ResizeScreen)
215 CVideoMode::UpdateRenderer(msg->width, msg->height);
217 #if OS_MACOSX
218 // OS X seems to require this to update the GL canvas
219 Atlas_GLSetCurrent(const_cast<void*>(g_AtlasGameLoop->glCanvas));
220 #endif
223 QUERYHANDLER(RenderLoop)
226 const double time = timer_Time();
227 static double last_time = time;
228 const double realFrameLength = time-last_time;
229 last_time = time;
230 ENSURE(realFrameLength >= 0.0);
231 // TODO: filter out big jumps, e.g. when having done a lot of slow
232 // processing in the last frame
233 g_AtlasGameLoop->realFrameLength = realFrameLength;
236 if (g_Input.ProcessInput(g_AtlasGameLoop))
237 last_user_activity = timer_Time();
239 msg->timeSinceActivity = timer_Time() - last_user_activity;
241 ReloadChangedFiles();
243 RendererIncrementalLoad();
245 // Pump SDL events (e.g. hotkeys)
246 SDL_Event_ ev;
247 while (in_poll_priority_event(&ev))
248 in_dispatch_event(&ev);
250 if (g_GUI)
251 g_GUI->TickObjects();
253 g_AtlasGameLoop->view->Update(g_AtlasGameLoop->realFrameLength);
255 g_AtlasGameLoop->view->Render();
257 if (CProfileManager::IsInitialised())
258 g_Profiler.Frame();
260 msg->wantHighFPS = g_AtlasGameLoop->view->WantsHighFramerate();
263 //////////////////////////////////////////////////////////////////////////
265 MESSAGEHANDLER(RenderStyle)
267 g_Renderer.GetSceneRenderer().SetTerrainRenderMode(msg->wireframe ? EDGED_FACES : SOLID);
268 g_Renderer.GetSceneRenderer().SetWaterRenderMode(msg->wireframe ? EDGED_FACES : SOLID);
269 g_Renderer.GetSceneRenderer().SetModelRenderMode(msg->wireframe ? EDGED_FACES : SOLID);
270 g_Renderer.GetSceneRenderer().SetOverlayRenderMode(msg->wireframe ? EDGED_FACES : SOLID);
273 } // namespace AtlasMessage