• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Return-To-The-Roots / s25client / 5111912776

pending completion
5111912776

Pull #1592

github

web-flow
Merge aa25149c0 into 2c095fc86
Pull Request #1592: Update translations

13 of 13 new or added lines in 4 files covered. (100.0%)

21671 of 42980 relevant lines covered (50.42%)

30486.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

67.62
/libs/s25main/drivers/VideoDriverWrapper.cpp
1
// Copyright (C) 2005 - 2021 Settlers Freaks (sf-team at siedler25.org)
2
//
3
// SPDX-License-Identifier: GPL-2.0-or-later
4

5
#include "VideoDriverWrapper.h"
6
#include "FrameCounter.h"
7
#include "RTTR_Version.h"
8
#include "WindowManager.h"
9
#include "driver/VideoInterface.h"
10
#include "helpers/containerUtils.h"
11
#include "helpers/roundToNextPow2.h"
12
#include "mygettext/mygettext.h"
13
#include "ogl/DummyRenderer.h"
14
#include "ogl/OpenGLRenderer.h"
15
#include "openglCfg.hpp"
16
#include "s25util/Log.h"
17
#include "s25util/error.h"
18
#include <glad/glad.h>
19
#include <ctime>
20
#if !defined(NDEBUG) && defined(HAVE_MEMCHECK_H)
21
#    include <valgrind/memcheck.h>
22
#endif
23

24
#ifdef _WIN32
25
using SwapIntervalExt_t = BOOL APIENTRY(int);
26
#else
27
using SwapIntervalExt_t = int(int);
28
#endif
29

30
SwapIntervalExt_t* wglSwapIntervalEXT = nullptr;
31

32
VideoDriverWrapper::VideoDriverWrapper()
6✔
33
    : videodriver(nullptr, nullptr), renderer_(nullptr), enableMouseWarping(true), texture_current(0)
6✔
34
{}
6✔
35

36
VideoDriverWrapper::~VideoDriverWrapper()
6✔
37
{
38
    CleanUp();
6✔
39
    UnloadDriver();
6✔
40
}
6✔
41

42
bool VideoDriverWrapper::Initialize()
4✔
43
{
44
    if(!videodriver || !videodriver->Initialize())
4✔
45
    {
46
        UnloadDriver();
×
47
        return false;
×
48
    }
49

50
    LOG.write(_("Loaded video driver \"%1%\"\n")) % GetName();
4✔
51

52
    frameCtr_ = std::make_unique<FrameCounter>();
4✔
53
    frameLimiter_ = std::make_unique<FrameLimiter>();
4✔
54

55
    return true;
4✔
56
}
57

58
bool VideoDriverWrapper::LoadDriver(IVideoDriver* existingDriver)
3✔
59
{
60
    UnloadDriver();
3✔
61
    videodriver = Handle(existingDriver, [](IVideoDriver* p) { delete p; });
6✔
62
    return Initialize();
3✔
63
}
64

65
bool VideoDriverWrapper::LoadDriver(std::string& preference)
1✔
66
{
67
    UnloadDriver();
1✔
68
    // DLL laden
69
    if(!driver_wrapper.Load(drivers::DriverType::Video, preference))
1✔
70
        return false;
×
71

72
    auto createVideoInstance = driver_wrapper.GetFunction<CreateVideoInstance_t>("CreateVideoInstance");
1✔
73
    auto freeVideoInstance = driver_wrapper.GetFunction<FreeVideoInstance_t>("FreeVideoInstance");
1✔
74
    RTTR_Assert(createVideoInstance && freeVideoInstance);
1✔
75

76
    videodriver = Handle(createVideoInstance(&WINDOWMANAGER), freeVideoInstance);
1✔
77
    return Initialize();
1✔
78
}
79

80
void VideoDriverWrapper::UnloadDriver()
11✔
81
{
82
    videodriver.reset();
11✔
83
    driver_wrapper.Unload();
11✔
84
    renderer_.reset();
11✔
85
}
11✔
86

87
/**
88
 *  Erstellt das Fenster.
89
 *
90
 *  @param[in] width  Breite des Fensters
91
 *  @param[in] height Höhe des Fensters
92
 *
93
 *  @return Bei Erfolg @p true ansonsten @p false
94
 */
95
bool VideoDriverWrapper::CreateScreen(const VideoMode size, const bool fullscreen)
5✔
96
{
97
    if(!videodriver)
5✔
98
    {
99
        s25util::fatal_error("No video driver selected!");
×
100
        return false;
×
101
    }
102

103
    if(!videodriver->CreateScreen(rttr::version::GetTitle(), size, fullscreen))
5✔
104
    {
105
        s25util::fatal_error("Could not create window!");
×
106
        return false;
×
107
    }
108

109
    // DriverWrapper Initialisieren
110
    // Extensions laden
111
    if(!LoadAllExtensions())
5✔
112
    {
113
        s25util::fatal_error("Failed to initialize the OpenGL context!");
×
114
        return false;
×
115
    }
116

117
    RenewViewport();
5✔
118

119
    // Buffer swappen um den leeren Buffer darzustellen
120
    SwapBuffers();
5✔
121

122
    // WindowManager informieren
123
    WINDOWMANAGER.Msg_ScreenResize(GetRenderSize());
5✔
124

125
    return true;
5✔
126
}
127

128
/**
129
 *  Verändert Auflösung, Fenster/Fullscreen
130
 *
131
 *  @param[in] screenWidth neue Breite des Fensters
132
 *  @param[in] screenHeight neue Höhe des Fensters
133
 *  @param[in] fullscreen Vollbild oder nicht
134
 *
135
 *  @return Bei Erfolg @p true ansonsten @p false
136
 */
137
bool VideoDriverWrapper::ResizeScreen(const VideoMode size, const bool fullscreen)
1✔
138
{
139
    if(!videodriver)
1✔
140
    {
141
        s25util::fatal_error("No video driver selected!");
×
142
        return false;
×
143
    }
144

145
    const bool result = videodriver->ResizeScreen(size, fullscreen);
1✔
146
#ifdef _WIN32
147
    if(!videodriver->IsFullscreen())
148
    {
149
        // We cannot change the size of a maximized window. So restore it here
150
        WINDOWPLACEMENT wp;
151
        wp.length = sizeof(WINDOWPLACEMENT);
152

153
        if(GetWindowPlacement((HWND)GetMapPointer(), &wp) && ((wp.showCmd & SW_MAXIMIZE) == SW_MAXIMIZE))
154
            ShowWindow((HWND)GetMapPointer(), SW_RESTORE);
155
    }
156
#endif
157
    WINDOWMANAGER.WindowResized();
1✔
158
    return result;
1✔
159
}
160

161
/**
162
 *  Zerstört den DriverWrapper-Bildschirm.
163
 */
164
bool VideoDriverWrapper::DestroyScreen()
2✔
165
{
166
    if(!videodriver)
2✔
167
    {
168
        s25util::fatal_error("No video driver selected!");
×
169
        return false;
×
170
    }
171

172
    LOG.write("Clearing textures: ");
2✔
173
    unsigned ladezeit = GetTickCount();
2✔
174
    CleanUp();
2✔
175
    LOG.write("Finished in %dms\n") % (GetTickCount() - ladezeit);
2✔
176

177
    // Videotreiber zurücksetzen
178
    videodriver->DestroyScreen();
2✔
179

180
    return true;
2✔
181
}
182

183
void VideoDriverWrapper::setTargetFramerate(int target)
31✔
184
{
185
    frameLimiter_->setTargetFramerate(target);
31✔
186
    if(!setHwVSync(target == 0) && target == 0) // Fallback if no HW vsync but was requested
31✔
187
        frameLimiter_->setTargetFramerate(60);
31✔
188
}
31✔
189

190
unsigned VideoDriverWrapper::GetFPS() const
97✔
191
{
192
    return frameCtr_->getFrameRate();
97✔
193
}
194

195
/**
196
 *  Löscht alle herausgegebenen Texturen aus dem Speicher.
197
 */
198
void VideoDriverWrapper::CleanUp()
11✔
199
{
200
    if(!texture_list.empty())
11✔
201
    {
202
        glDeleteTextures(texture_list.size(), static_cast<const GLuint*>(texture_list.data()));
3✔
203
        texture_list.clear();
3✔
204
    }
205
}
11✔
206

207
unsigned VideoDriverWrapper::GenerateTexture()
48✔
208
{
209
    GLuint newTexture = 0;
48✔
210
    glGenTextures(1, &newTexture);
48✔
211
#if !defined(NDEBUG) && defined(HAVE_MEMCHECK_H)
212
    VALGRIND_MAKE_MEM_DEFINED(&newTexture, sizeof(newTexture));
213
#endif
214

215
    static_assert(sizeof(newTexture) == sizeof(texture_list[0]), "Unexpected texture size");
216
    if(newTexture)
48✔
217
        texture_list.push_back(newTexture);
48✔
218
    return newTexture;
48✔
219
}
220

221
void VideoDriverWrapper::BindTexture(unsigned t)
2,278✔
222
{
223
    if(t != texture_current)
2,278✔
224
    {
225
        texture_current = t;
981✔
226
        glBindTexture(GL_TEXTURE_2D, t);
981✔
227
    }
228
}
2,278✔
229

230
void VideoDriverWrapper::DeleteTexture(unsigned t)
3,989✔
231
{
232
    if(!t)
3,989✔
233
        return;
3,951✔
234
    if(t == texture_current)
38✔
235
        texture_current = 0;
4✔
236
    auto it = helpers::find(texture_list, t);
38✔
237
    if(it != texture_list.end())
38✔
238
    {
239
        glDeleteTextures(1, &t);
25✔
240
        texture_list.erase(it);
25✔
241
    }
242
}
243

244
KeyEvent VideoDriverWrapper::GetModKeyState() const
3✔
245
{
246
    if(videodriver)
3✔
247
        return videodriver->GetModKeyState();
3✔
248
    const KeyEvent ke = {KeyType::Invalid, 0, false, false, false};
×
249
    return ke;
×
250
}
251

252
void VideoDriverWrapper::SwapBuffers()
5✔
253
{
254
    if(!videodriver)
5✔
255
    {
256
        s25util::fatal_error("No video driver selected!");
×
257
        return;
×
258
    }
259
    frameLimiter_->sleepTillNextFrame(FrameCounter::clock::now());
5✔
260
    videodriver->SwapBuffers();
5✔
261
    FrameCounter::clock::time_point now = FrameCounter::clock::now();
5✔
262
    frameLimiter_->update(now);
5✔
263
    frameCtr_->update(now);
5✔
264
}
265

266
void VideoDriverWrapper::ClearScreen()
25✔
267
{
268
    glClear(GL_COLOR_BUFFER_BIT);
25✔
269
}
25✔
270

271
bool VideoDriverWrapper::Run()
×
272
{
273
    if(!videodriver)
×
274
    {
275
        s25util::fatal_error("No video driver selected!");
×
276
        return false;
×
277
    }
278

279
    return videodriver->MessageLoop();
×
280
}
281

282
Extent VideoDriverWrapper::calcPreferredTextureSize(const Extent& minSize) const
38✔
283
{
284
    return Extent(helpers::roundToNextPowerOfTwo(minSize.x), helpers::roundToNextPowerOfTwo(minSize.y));
38✔
285
}
286

287
bool VideoDriverWrapper::setHwVSync(bool enabled)
31✔
288
{
289
    if(!wglSwapIntervalEXT)
31✔
290
        return false;
31✔
291
    return wglSwapIntervalEXT(enabled ? 1 : 0) != 0;
×
292
}
293

294
/**
295
 *  Viewport (neu) setzen
296
 */
297
void VideoDriverWrapper::RenewViewport()
6✔
298
{
299
    if(!videodriver->IsOpenGL() || !renderer_)
6✔
300
        return;
6✔
301

302
    const Extent renderSize = videodriver->GetRenderSize();
×
303

304
    // Viewport mit widthxheight setzen
305
    glViewport(0, 0, renderSize.x, renderSize.y);
×
306
    glScissor(0, 0, renderSize.x, renderSize.y);
×
307

308
    // Orthogonale Matrix erstellen
309
    glMatrixMode(GL_PROJECTION);
×
310
    glLoadIdentity();
×
311

312
    // 0,0 should be top left corner
313
    glOrtho(0, renderSize.x, renderSize.y, 0, -100, 100);
×
314

315
    glMatrixMode(GL_MODELVIEW);
×
316
    glLoadIdentity();
×
317

318
    // Depthbuffer und Colorbuffer einstellen
319
    glClearColor(0.0, 0.0, 0.0, 1.0);
×
320

321
    // Smooth - Shading aktivieren
322
    glShadeModel(GL_SMOOTH);
×
323

324
    glEnable(GL_ALPHA_TEST);
×
325
    glAlphaFunc(GL_GREATER, 0.0f);
×
326

327
    // Alphablending an
328
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
×
329
    glEnable(GL_BLEND);
×
330

331
    // Depthbuffer abschalten
332
    glDisable(GL_DEPTH_TEST);
×
333
    glDepthMask(GL_FALSE);
×
334

335
    // Texturen anstellen
336
    glEnable(GL_TEXTURE_2D);
×
337

338
    // Dither abstellen
339
    glDisable(GL_DITHER);
×
340

341
    // Scissoring aktivieren
342
    glEnable(GL_SCISSOR_TEST);
×
343

344
    // Nur obere Seite von Dreiecke rendern --> Performance
345
    glEnable(GL_CULL_FACE);
×
346

347
    glEnableClientState(GL_VERTEX_ARRAY);
×
348
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
×
349

350
    ClearScreen();
×
351
}
352

353
/**
354
 *  lädt die driverwrapper-extensions.
355
 */
356
bool VideoDriverWrapper::LoadAllExtensions()
5✔
357
{
358
    if(videodriver->IsOpenGL())
5✔
359
        renderer_ = std::make_unique<OpenGLRenderer>();
×
360
    else
361
        renderer_ = std::make_unique<DummyRenderer>();
5✔
362
    if(!renderer_->initOpenGL(videodriver->GetLoaderFunction()))
5✔
363
        return false;
×
364
    LOG.write(_("OpenGL %1%.%2% supported\n")) % GLVersion.major % GLVersion.minor;
5✔
365
    if(GLVersion.major < RTTR_OGL_MAJOR || (GLVersion.major == RTTR_OGL_MAJOR && GLVersion.minor < RTTR_OGL_MINOR))
5✔
366
    {
367
        LOG.write(_("OpenGL %1% %2%.%3% is not supported. Try updating your GPU drivers or hardware!"))
×
368
          % ((RTTR_OGL_ES) ? "ES" : "") % RTTR_OGL_MAJOR % RTTR_OGL_MINOR;
×
369
        return false;
×
370
    }
371

372
// auf VSync-Extension testen
373
#ifdef _WIN32
374
    wglSwapIntervalEXT = reinterpret_cast<SwapIntervalExt_t*>(loadExtension("wglSwapIntervalEXT"));
375
#else
376
    wglSwapIntervalEXT = reinterpret_cast<SwapIntervalExt_t*>(loadExtension("glXSwapIntervalSGI"));
5✔
377
#endif
378

379
    return true;
5✔
380
}
381

382
unsigned VideoDriverWrapper::GetTickCount()
300✔
383
{
384
    if(!videodriver)
300✔
385
        return (unsigned)time(nullptr);
×
386

387
    return (unsigned)videodriver->GetTickCount();
300✔
388
}
389

390
std::string VideoDriverWrapper::GetName() const
10✔
391
{
392
    const char* name = (videodriver) ? videodriver->GetName() : nullptr;
10✔
393
    return (name) ? name : "";
10✔
394
}
395

396
/**
397
 *  lädt eine bestimmte DriverWrapper Extension-Funktion.
398
 *
399
 *  @param[in] extension Die Extension-Funktion
400
 *
401
 *  @return @p nullptr bei Fehler, Adresse der gewünschten Funktion bei Erfolg.
402
 */
403
void* VideoDriverWrapper::loadExtension(const std::string& extension)
5✔
404
{
405
    if(!videodriver)
5✔
406
    {
407
        s25util::fatal_error("No video driver selected!");
×
408
        return (nullptr);
×
409
    }
410

411
    return videodriver->GetLoaderFunction()(extension.c_str());
5✔
412
}
413

414
Position VideoDriverWrapper::GetMousePos() const
229✔
415
{
416
    if(!videodriver)
229✔
417
        return Position::Invalid();
×
418
    return videodriver->GetMousePos();
229✔
419
}
420

421
bool VideoDriverWrapper::IsLeftDown()
95✔
422
{
423
    if(!videodriver)
95✔
424
        return false;
×
425

426
    return videodriver->GetMouseStateL();
95✔
427
}
428

429
bool VideoDriverWrapper::IsRightDown()
×
430
{
431
    if(!videodriver)
×
432
        return false;
×
433

434
    return videodriver->GetMouseStateR();
×
435
}
436

437
void VideoDriverWrapper::SetMousePos(const Position& newPos)
18✔
438
{
439
    if(!videodriver || !enableMouseWarping)
18✔
440
        return;
×
441

442
    videodriver->SetMousePos(newPos);
18✔
443
}
444

445
/**
446
 *  Listet verfügbare Videomodi auf.
447
 */
448
void VideoDriverWrapper::ListVideoModes(std::vector<VideoMode>& video_modes) const
×
449
{
450
    if(!videodriver)
×
451
        return;
×
452

453
    videodriver->ListVideoModes(video_modes);
×
454
}
455

456
bool VideoDriverWrapper::HasVSync() const
×
457
{
458
    return wglSwapIntervalEXT != nullptr;
×
459
}
460

461
/**
462
 *  Gibt Pointer auf ein Fenster zurück (device-dependent!), HWND unter Windows.
463
 */
464
void* VideoDriverWrapper::GetMapPointer() const
1✔
465
{
466
    if(!videodriver)
1✔
467
        return nullptr;
1✔
468

469
    return videodriver->GetMapPointer();
×
470
}
471

472
VideoMode VideoDriverWrapper::GetWindowSize() const
8✔
473
{
474
    // Always return at least 800x600 even if real window is smaller
475
    VideoMode windowSize = videodriver->GetWindowSize();
8✔
476
    windowSize.width = std::max<unsigned>(800, windowSize.width);
8✔
477
    windowSize.height = std::max<unsigned>(600, windowSize.height);
8✔
478
    return windowSize;
8✔
479
}
480

481
Extent VideoDriverWrapper::GetRenderSize() const
296✔
482
{
483
    return videodriver->GetRenderSize();
296✔
484
}
485

486
bool VideoDriverWrapper::IsFullscreen() const
6✔
487
{
488
    return videodriver->IsFullscreen();
6✔
489
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc