OpenTTD Source 20260711-master-g3fb3006dff
sdl2_opengl_v.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10/* XXX -- Temporary hack for Windows compile */
11#define WINGDIAPI
12#define APIENTRY
13
14#include "../stdafx.h"
15#include "../openttd.h"
16#include "../gfx_func.h"
17#include "../rev.h"
19#include "../network/network.h"
20#include "../thread.h"
21#include "../progress.h"
22#include "../fileio_func.h"
23#include "../framerate_type.h"
24#include "../window_func.h"
25#include "sdl2_opengl_v.h"
26#include <SDL.h>
27#include <mutex>
28#include <condition_variable>
29#include <GL/gl.h>
30#include "../3rdparty/opengl/glext.h"
31#include "opengl.h"
32#ifdef __EMSCRIPTEN__
33# include <emscripten.h>
34# include <emscripten/html5.h>
35#endif
36
37#include "../safeguards.h"
38
40
46static OGLProc GetOGLProcAddressCallback(const char *proc)
47{
48 return reinterpret_cast<OGLProc>(SDL_GL_GetProcAddress(proc));
49}
50
51bool VideoDriver_SDL_OpenGL::CreateMainWindow(uint w, uint h, uint flags)
52{
53 return this->VideoDriver_SDL_Base::CreateMainWindow(w, h, flags | SDL_WINDOW_OPENGL);
54}
55
56std::optional<std::string_view> VideoDriver_SDL_OpenGL::Start(const StringList &param)
57{
58 auto error = VideoDriver_SDL_Base::Start(param);
59 if (error) return error;
60
61 error = this->AllocateContext();
62 if (error) {
63 this->Stop();
64 return error;
65 }
66
67 this->driver_info += " (";
68 this->driver_info += OpenGLBackend::Get()->GetDriverName();
69 this->driver_info += ")";
70
71 /* Now we have a OpenGL context, force a client-size-changed event,
72 * so all buffers are allocated correctly. */
73 int w, h;
74 SDL_GetWindowSize(this->sdl_window, &w, &h);
75 this->ClientSizeChanged(w, h, true);
76 /* We should have a valid screen buffer now. If not, something went wrong and we should abort. */
77 if (_screen.dst_ptr == nullptr) {
78 this->Stop();
79 return "Can't get pointer to screen buffer";
80 }
81 /* Main loop expects to start with the buffer unmapped. */
82 this->ReleaseVideoPointer();
83
84 return std::nullopt;
85}
86
92
97{
99
100 if (this->gl_context != nullptr) {
101 SDL_GL_DeleteContext(this->gl_context);
102 this->gl_context = nullptr;
103 }
104}
105
107{
108 SDL_GL_SetSwapInterval(vsync);
109}
110
115std::optional<std::string_view> VideoDriver_SDL_OpenGL::AllocateContext()
116{
117 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
118 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
119 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
120 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
121 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
122 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
123
124 if (_debug_driver_level >= 8) {
125 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
126 }
127
128 this->gl_context = SDL_GL_CreateContext(this->sdl_window);
129 if (this->gl_context == nullptr) return "SDL2: Can't activate GL context";
130
132
134}
135
137{
138 OpenGLBackend::Get()->PopulateCursorCache();
139}
140
145
147{
148 if (this->gl_context == nullptr) return false;
149
150 if (_screen.dst_ptr != nullptr) this->ReleaseVideoPointer();
151
152 w = std::max(w, 64);
153 h = std::max(h, 64);
154 this->dirty_rect = {};
155
156 bool res = OpenGLBackend::Get()->Resize(w, h, force);
157 SDL_GL_SwapWindow(this->sdl_window);
158 _screen.dst_ptr = this->GetVideoPointer();
159
160 CopyPalette(this->local_palette, true);
161
162 return res;
163}
164
166{
167 if (BlitterFactory::GetCurrentBlitter()->NeedsAnimationBuffer()) {
169 }
171}
172
174{
175 if (this->anim_buffer != nullptr) OpenGLBackend::Get()->ReleaseAnimBuffer(this->dirty_rect);
177 this->dirty_rect = {};
178 this->anim_buffer = nullptr;
179}
180
182{
184
185 if (this->local_palette.count_dirty != 0) {
187
188 /* Always push a changed palette to OpenGL. */
189 OpenGLBackend::Get()->UpdatePalette(this->local_palette.palette, this->local_palette.first_dirty, this->local_palette.count_dirty);
191 blitter->PaletteAnimate(this->local_palette);
192 }
193
194 this->local_palette.count_dirty = 0;
195 }
196
199
200 SDL_GL_SwapWindow(this->sdl_window);
201}
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
Definition factory.hpp:139
How all blitters should look like.
Definition base.hpp:29
virtual Blitter::PaletteAnimation UsePaletteAnimation()=0
Check if the blitter uses palette animation at all.
virtual void PaletteAnimate(const Palette &palette)=0
Called when the 8bpp palette is changed; you should redraw all pixels on the screen that are equal to...
@ Blitter
The blitter takes care of the palette animation.
Definition base.hpp:53
The factory for SDL' OpenGL video driver.
void Paint()
Render video buffer to the screen.
Definition opengl.cpp:1065
uint8_t * GetAnimBuffer()
Get a pointer to the memory for the separate animation buffer.
Definition opengl.cpp:1196
void * GetVideoBuffer()
Get a pointer to the memory for the video driver to draw to.
Definition opengl.cpp:1174
bool Resize(int w, int h, bool force=false)
Change the size of the drawing window and allocate matching resources.
Definition opengl.cpp:939
static std::optional< std::string_view > Create(GetOGLProcAddressProc get_proc, const Dimension &screen_res)
Create and initialize the singleton back-end class.
Definition opengl.cpp:490
void UpdatePalette(const Colour *pal, uint first, uint length)
Update the stored palette.
Definition opengl.cpp:1051
void ReleaseAnimBuffer(const Rect &update_rect)
Update animation buffer texture after the animation buffer was filled.
Definition opengl.cpp:1257
void ClearCursorCache()
Queue a request for cursor cache clear.
Definition opengl.cpp:1161
static OpenGLBackend * Get()
Get singleton instance of this class.
Definition opengl.h:86
void DrawMouseCursor()
Draw mouse cursor on screen.
Definition opengl.cpp:1097
void ReleaseVideoBuffer(const Rect &update_rect)
Update video buffer texture after the video buffer was filled.
Definition opengl.cpp:1219
static void Destroy()
Free resources and destroy singleton back-end class.
Definition opengl.cpp:503
RAII class for measuring simple elements of performance.
std::optional< std::string_view > Start(const StringList &param) override
Start this driver.
Definition sdl2_v.cpp:603
Dimension GetScreenSize() const override
Get the resolution of the main screen.
Definition sdl2_v.cpp:774
Palette local_palette
Current palette to use for drawing.
Definition sdl2_v.h:54
std::string driver_info
Information string about selected driver.
Definition sdl2_v.h:57
void ClientSizeChanged(int w, int h, bool force)
Indicate to the driver the client-size might have changed.
Definition sdl2_v.cpp:141
virtual bool CreateMainWindow(uint w, uint h, uint flags=0)
Create the main window.
Definition sdl2_v.cpp:153
void Stop() override
Stop this driver.
Definition sdl2_v.cpp:647
Rect dirty_rect
Rectangle encompassing the dirty area of the video buffer.
Definition sdl2_v.h:56
struct SDL_Window * sdl_window
Main SDL window.
Definition sdl2_v.h:53
void Paint() override
Paint the window.
void ReleaseVideoPointer() override
Hand video buffer back to the painting backend.
void * gl_context
OpenGL context.
void DestroyContext()
Destroy and release the OpenGL context.
void ToggleVsync(bool vsync) override
Change the vsync setting.
bool CreateMainWindow(uint w, uint h, uint flags) override
Create the main window.
void * GetVideoPointer() override
Get a pointer to the video buffer.
void Stop() override
Stop this driver.
std::optional< std::string_view > AllocateContext()
Allocate the OpenGL context.
void ClearSystemSprites() override
Clear all cached sprites.
bool AllocateBackingStore(int w, int h, bool force=false) override
(Re-)create the backing store.
std::optional< std::string_view > Start(const StringList &param) override
Start this driver.
void PopulateSystemSprites() override
Populate all sprites in cache.
uint8_t * anim_buffer
Animation buffer from OpenGL back-end.
static OGLProc GetOGLProcAddressCallback(const char *proc)
Platform-specific callback to get an OpenGL function pointer.
Definition cocoa_ogl.mm:49
Factory to 'query' all available blitters.
Functions for standard in/out file operations.
Types for recording game performance data.
@ Video
Speed of painting drawn video buffer.
Functions related to the gfx engine.
Basic functions/variables used all over the place.
OpenGL video driver support.
Some generic types.
bool CopyPalette(Palette &local_palette, bool force_copy)
Copy the current palette if the palette was updated.
Definition palette.cpp:230
Functions related to modal progress.
Declaration of OTTD revision dependent variables.
A number of safeguards to prevent using unsafe methods.
static OGLProc GetOGLProcAddressCallback(const char *proc)
Platform-specific callback to get an OpenGL function pointer.
static FVideoDriver_SDL_OpenGL iFVideoDriver_SDL_OpenGL
The OpenGL SDL video driver.
OpenGL backend of the SDL2 video driver.
Definition of base types and functions in a cross-platform compatible way.
std::vector< std::string > StringList
Type for a list of strings.
Definition string_type.h:61
Base of all threads.
bool _video_vsync
Whether we should use vsync (only if active video driver supports HW acceleration).
Window functions not directly related to making/drawing windows.