1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 //============================================================================= 24 // 25 // Implementation base for graphics driver 26 // 27 //============================================================================= 28 29 #ifndef AGS_ENGINE_GFX_GFX_DRIVER_BASE_H 30 #define AGS_ENGINE_GFX_GFX_DRIVER_BASE_H 31 32 #include "ags/lib/std/vector.h" 33 #include "ags/engine/gfx/ddb.h" 34 #include "ags/engine/gfx/graphics_driver.h" 35 #include "ags/shared/util/scaling.h" 36 37 namespace AGS3 { 38 namespace AGS { 39 namespace Engine { 40 41 using Shared::Bitmap; 42 using Shared::PlaneScaling; 43 44 // Sprite batch, defines viewport and an optional model transformation for the list of sprites 45 struct SpriteBatchDesc { 46 // View rectangle for positioning and clipping, in resolution coordinates 47 // (this may be screen or game frame resolution, depending on circumstances) 48 Rect Viewport; 49 // Optional model transformation, to be applied to each sprite 50 SpriteTransform Transform; 51 // Global node offset applied to the whole batch as the last transform 52 Point Offset; 53 // Global node flip applied to the whole batch as the last transform 54 GlobalFlipType Flip; 55 // Optional bitmap to draw sprites upon. Used exclusively by the software rendering mode. 56 PBitmap Surface; 57 SpriteBatchDescSpriteBatchDesc58 SpriteBatchDesc() : Flip(kFlip_None) { 59 } 60 SpriteBatchDesc(const Rect viewport, const SpriteTransform &transform, const Point offset = Point(), 61 GlobalFlipType flip = kFlip_None, PBitmap surface = nullptr) ViewportSpriteBatchDesc62 : Viewport(viewport) 63 , Transform(transform) 64 , Offset(offset) 65 , Flip(flip) 66 , Surface(surface) { 67 } 68 }; 69 70 typedef std::vector<SpriteBatchDesc> SpriteBatchDescs; 71 72 // The single sprite entry in the render list 73 template<class T_DDB> 74 struct SpriteDrawListEntry { 75 T_DDB *bitmap; // TODO: use shared pointer? 76 int x, y; // sprite position, in camera coordinates 77 bool skip; 78 SpriteDrawListEntrySpriteDrawListEntry79 SpriteDrawListEntry() 80 : bitmap(nullptr) 81 , x(0) 82 , y(0) 83 , skip(false) { 84 } 85 86 SpriteDrawListEntry(T_DDB *ddb, int x_ = 0, int y_ = 0) bitmapSpriteDrawListEntry87 : bitmap(ddb) 88 , x(x_) 89 , y(y_) 90 , skip(false) { 91 } 92 }; 93 94 95 // GraphicsDriverBase - is the parent class for all graphics drivers in AGS, 96 // that incapsulates the most common functionality. 97 class GraphicsDriverBase : public IGraphicsDriver { 98 public: 99 GraphicsDriverBase(); 100 101 bool IsModeSet() const override; 102 bool IsNativeSizeValid() const override; 103 bool IsRenderFrameValid() const override; 104 DisplayMode GetDisplayMode() const override; 105 Size GetNativeSize() const override; 106 Rect GetRenderDestination() const override; 107 108 void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform, 109 const Point offset = Point(), GlobalFlipType flip = kFlip_None, PBitmap surface = nullptr) override; 110 void ClearDrawLists() override; 111 SetCallbackForPolling(GFXDRV_CLIENTCALLBACK callback)112 void SetCallbackForPolling(GFXDRV_CLIENTCALLBACK callback) override { 113 _pollingCallback = callback; 114 } SetCallbackToDrawScreen(GFXDRV_CLIENTCALLBACK callback,GFXDRV_CLIENTCALLBACK post_callback)115 void SetCallbackToDrawScreen(GFXDRV_CLIENTCALLBACK callback, GFXDRV_CLIENTCALLBACK post_callback) override { 116 _drawScreenCallback = callback; 117 _drawPostScreenCallback = post_callback; 118 } SetCallbackOnInit(GFXDRV_CLIENTCALLBACKINITGFX callback)119 void SetCallbackOnInit(GFXDRV_CLIENTCALLBACKINITGFX callback) override { 120 _initGfxCallback = callback; 121 } SetCallbackForNullSprite(GFXDRV_CLIENTCALLBACKXY callback)122 void SetCallbackForNullSprite(GFXDRV_CLIENTCALLBACKXY callback) override { 123 _nullSpriteCallback = callback; 124 } 125 126 protected: 127 // Called after graphics driver was initialized for use for the first time 128 virtual void OnInit(); 129 // Called just before graphics mode is going to be uninitialized and its 130 // resources released 131 virtual void OnUnInit(); 132 // Called after new mode was successfully initialized 133 virtual void OnModeSet(const DisplayMode &mode); 134 // Called when the new native size is set 135 virtual void OnSetNativeRes(const GraphicResolution &native_res); 136 // Called before display mode is going to be released 137 virtual void OnModeReleased(); 138 // Called when new render frame is set 139 virtual void OnSetRenderFrame(const Rect &dst_rect); 140 // Called when the new filter is set 141 virtual void OnSetFilter(); 142 // Initialize sprite batch and allocate necessary resources 143 virtual void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) = 0; 144 // Clears sprite lists 145 virtual void ResetAllBatches() = 0; 146 147 void OnScalingChanged(); 148 149 DisplayMode _mode; // display mode settings 150 Rect _srcRect; // rendering source rect 151 int _srcColorDepth; // rendering source color depth (in bits per pixel) 152 Rect _dstRect; // rendering destination rect 153 Rect _filterRect; // filter scaling destination rect (before final scaling) 154 PlaneScaling _scaling; // native -> render dest coordinate transformation 155 156 // Callbacks 157 GFXDRV_CLIENTCALLBACK _pollingCallback; 158 GFXDRV_CLIENTCALLBACK _drawScreenCallback; 159 GFXDRV_CLIENTCALLBACK _drawPostScreenCallback; 160 GFXDRV_CLIENTCALLBACKXY _nullSpriteCallback; 161 GFXDRV_CLIENTCALLBACKINITGFX _initGfxCallback; 162 163 // Sprite batch parameters 164 SpriteBatchDescs _spriteBatchDesc; // sprite batches list 165 size_t _actSpriteBatch; // active batch index 166 }; 167 168 169 170 // Generic TextureTile base 171 struct TextureTile { 172 int x, y; 173 int width, height; 174 }; 175 176 // Parent class for the video memory DDBs 177 class VideoMemDDB : public IDriverDependantBitmap { 178 public: GetWidth()179 int GetWidth() override { 180 return _width; 181 } GetHeight()182 int GetHeight() override { 183 return _height; 184 } GetColorDepth()185 int GetColorDepth() override { 186 return _colDepth; 187 } 188 189 int _width, _height; 190 int _colDepth; 191 bool _opaque; // no mask color 192 }; 193 194 // VideoMemoryGraphicsDriver - is the parent class for the graphic drivers 195 // which drawing method is based on passing the sprite stack into GPU, 196 // rather than blitting to flat screen bitmap. 197 class VideoMemoryGraphicsDriver : public GraphicsDriverBase { 198 public: 199 VideoMemoryGraphicsDriver(); 200 ~VideoMemoryGraphicsDriver() override; 201 202 bool UsesMemoryBackBuffer() override; 203 Bitmap *GetMemoryBackBuffer() override; 204 void SetMemoryBackBuffer(Bitmap *backBuffer) override; 205 Bitmap *GetStageBackBuffer(bool mark_dirty) override; 206 bool GetStageMatrixes(RenderMatrixes &rm) override; 207 IDriverDependantBitmap *CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque = false) override; 208 209 protected: 210 // Creates a "raw" DDB, without pixel initialization 211 virtual IDriverDependantBitmap *CreateDDB(int width, int height, int color_depth, bool opaque = false) = 0; 212 213 // Stage screens are raw bitmap buffers meant to be sent to plugins on demand 214 // at certain drawing stages. If used at least once these buffers are then 215 // rendered as additional sprites in their respected order. 216 PBitmap CreateStageScreen(size_t index, const Size &sz); 217 PBitmap GetStageScreen(size_t index); 218 void DestroyAllStageScreens(); 219 // Use engine callback to acquire replacement for the null sprite; 220 // returns true if the sprite was provided onto the virtual screen, 221 // and false if this entry should be skipped. 222 bool DoNullSpriteCallback(int x, int y); 223 224 // Prepare and get fx item from the pool 225 IDriverDependantBitmap *MakeFx(int r, int g, int b); 226 // Resets fx pool counter 227 void ResetFxPool(); 228 // Disposes all items in the fx pool 229 void DestroyFxPool(); 230 231 // Prepares bitmap to be applied to the texture, copies pixels to the provided buffer 232 void BitmapToVideoMem(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target, 233 char *dst_ptr, const int dst_pitch, const bool usingLinearFiltering); 234 // Same but optimized for opaque source bitmaps which ignore transparent "mask color" 235 void BitmapToVideoMemOpaque(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target, 236 char *dst_ptr, const int dst_pitch); 237 238 // Stage virtual screen is used to let plugins draw custom graphics 239 // in between render stages (between room and GUI, after GUI, and so on) 240 PBitmap _stageVirtualScreen; 241 IDriverDependantBitmap *_stageVirtualScreenDDB; 242 // Stage matrixes are used to let plugins with hardware acceleration know model matrix; 243 // these matrixes are filled compatible with each given renderer 244 RenderMatrixes _stageMatrixes; 245 246 // Color component shifts in video bitmap format (set by implementations) 247 int _vmem_a_shift_32; 248 int _vmem_r_shift_32; 249 int _vmem_g_shift_32; 250 int _vmem_b_shift_32; 251 252 private: 253 // Virtual screens for rendering stages (sprite batches) 254 std::vector<PBitmap> _stageScreens; 255 // Flag which indicates whether stage screen was drawn upon during engine 256 // callback and has to be inserted into sprite stack. 257 bool _stageScreenDirty; 258 259 // Fx quads pool (for screen overlay effects) 260 struct ScreenFx { 261 Bitmap *Raw = nullptr; 262 IDriverDependantBitmap *DDB = nullptr; 263 int Red = -1; 264 int Green = -1; 265 int Blue = -1; 266 }; 267 std::vector<ScreenFx> _fxPool; 268 size_t _fxIndex; // next free pool item 269 }; 270 271 } // namespace Engine 272 } // namespace AGS 273 } // namespace AGS3 274 275 #endif 276