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