1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
/* $Id$ */
/*
* This file is part of OpenTTD.
* 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.
* 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.
* 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 <http://www.gnu.org/licenses/>.
*/
/** @file opengl.h OpenGL video driver support. */
#ifndef VIDEO_OPENGL_H
#define VIDEO_OPENGL_H
#include "../core/alloc_type.hpp"
#include "../core/geometry_type.hpp"
#include "../gfx_type.h"
#include "../spriteloader/spriteloader.hpp"
#include "../misc/lrucache.hpp"
typedef void (*OGLProc)();
typedef OGLProc (*GetOGLProcAddressProc)(const char *proc);
bool IsOpenGLVersionAtLeast(byte major, byte minor);
const char *FindStringInExtensionList(const char *string, const char *substring);
class OpenGLSprite;
/** Platform-independent back-end class for OpenGL video drivers. */
class OpenGLBackend : public ZeroedMemoryAllocator, SpriteEncoder {
private:
static OpenGLBackend *instance; ///< Singleton instance pointer.
bool persistent_mapping_supported; ///< Persistent pixel buffer mapping supported.
GLsync sync_vid_mapping; ///< Sync object for the persistently mapped video buffer.
GLsync sync_anim_mapping; ///< Sync object for the persistently mapped animation buffer.
void *vid_buffer; ///< Pointer to the mapped video buffer.
GLuint vid_pbo; ///< Pixel buffer object storing the memory used for the video driver to draw to.
GLuint vid_texture; ///< Texture handle for the video buffer texture.
GLuint vid_program; ///< Shader program for rendering a RGBA video buffer.
GLuint pal_program; ///< Shader program for rendering a paletted video buffer.
GLuint vao_quad; ///< Vertex array object storing the rendering state for the fullscreen quad.
GLuint vbo_quad; ///< Vertex buffer with a fullscreen quad.
GLuint pal_texture; ///< Palette lookup texture.
void *anim_buffer; ///< Pointer to the mapped animation buffer.
GLuint anim_pbo; ///< Pixel buffer object storing the memory used for the animation buffer.
GLuint anim_texture; ///< Texture handle for the animation buffer texture.
GLuint remap_program; ///< Shader program for blending and rendering a RGBA + remap texture.
GLint remap_sprite_loc; ///< Uniform location for sprite parameters.
GLint remap_screen_loc; ///< Uniform location for screen size;
GLint remap_zoom_loc; ///< Uniform location for sprite zoom;
GLint remap_rgb_loc; ///< Uniform location for RGB mode flag;
LRUCache<SpriteID, Sprite> cursor_cache; ///< Cache of encoded cursor sprites.
OpenGLBackend();
~OpenGLBackend();
const char *Init();
bool InitShaders();
void RenderOglSprite(OpenGLSprite *gl_sprite, uint x, uint y, ZoomLevel zoom);
public:
/** Get singleton instance of this class. */
static inline OpenGLBackend *Get()
{
return OpenGLBackend::instance;
}
static const char *Create(GetOGLProcAddressProc get_proc);
static void Destroy();
void UpdatePalette(const Colour *pal, uint first, uint length);
bool Resize(int w, int h, bool force = false);
void Paint();
void DrawMouseCursor();
void ClearCursorCache();
void *GetVideoBuffer();
uint8 *GetAnimBuffer();
void ReleaseVideoBuffer(const Rect &update_rect);
void ReleaseAnimBuffer(const Rect &update_rect);
/* SpriteEncoder */
bool Is32BppSupported() override { return true; }
uint GetSpriteAlignment() override { return 1u << (ZOOM_LVL_COUNT - 1); }
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
};
/** Class that encapsulates a RGBA texture together with a paletted remap texture. */
class OpenGLSprite {
private:
/** Enum of all used OpenGL texture objects. */
enum Texture {
TEX_RGBA, ///< RGBA texture part.
TEX_REMAP, ///< Remap texture part.
NUM_TEX
};
Dimension dim;
GLuint tex[NUM_TEX]; ///< The texture objects.
static GLuint dummy_tex[NUM_TEX]; ///< 1x1 dummy textures to substitute for unused sprite components.
static bool Create();
static void Destroy();
bool BindTextures();
public:
OpenGLSprite(uint width, uint height, uint levels, SpriteColourComponent components);
~OpenGLSprite();
void Update(uint width, uint height, uint level, const SpriteLoader::CommonPixel *data);
Dimension GetSize(ZoomLevel level) const;
friend class OpenGLBackend;
};
#endif /* VIDEO_OPENGL_H */
|