/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program 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, either version 3 of the License, or * (at your option) any later version. * * This program 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 this program. If not, see . * */ //============================================================================= // // Graphics driver interface // //============================================================================= #ifndef AGS_ENGINE_GFX_GRAPHICS_DRIVER_H #define AGS_ENGINE_GFX_GRAPHICS_DRIVER_H //#include "math/matrix.h" #include "common/std/memory.h" #include "ags/lib/allegro.h" // RGB, PALETTE #include "ags/shared/gfx/gfx_def.h" #include "ags/engine/gfx/gfx_defines.h" #include "ags/engine/gfx/gfx_mode_list.h" #include "ags/shared/util/geometry.h" namespace AGS3 { namespace AGS { namespace Shared { class Bitmap; typedef std::shared_ptr PBitmap; } // namespace Shared namespace Engine { // Forward declaration class IDriverDependantBitmap; class IGfxFilter; typedef std::shared_ptr PGfxFilter; using Shared::PBitmap; enum TintMethod { TintReColourise = 0, TintSpecifyMaximum = 1 }; struct SpriteColorTransform { int Alpha = 255; // alpha color value (0 - 255) SpriteColorTransform() = default; SpriteColorTransform(int alpha) : Alpha(alpha) { } }; // Sprite transformation // TODO: combine with stretch parameters in the IDriverDependantBitmap? struct SpriteTransform { // Translate int X = 0, Y = 0; float ScaleX = 1.f, ScaleY = 1.f; float Rotate = 0.f; // angle, in radians SpriteColorTransform Color; SpriteTransform() = default; SpriteTransform(int x, int y, float scalex = 1.0f, float scaley = 1.0f, float rotate = 0.0f, SpriteColorTransform color = SpriteColorTransform()) : X(x), Y(y), ScaleX(scalex), ScaleY(scaley), Rotate(rotate), Color(color) { } }; // Describes 3 render matrixes: world, view and projection struct RenderMatrixes { /* glm::mat4 World; glm::mat4 View; glm::mat4 Projection; */ }; typedef void (*GFXDRV_CLIENTCALLBACK)(); typedef bool (*GFXDRV_CLIENTCALLBACKEVT)(int evt, int data); typedef void (*GFXDRV_CLIENTCALLBACKINITGFX)(void *data); class IGraphicsDriver { public: // Gets graphic driver's identifier virtual const char *GetDriverID() = 0; // Gets graphic driver's "friendly name" virtual const char *GetDriverName() = 0; // Tells if this gfx driver has to redraw whole scene each time virtual bool RequiresFullRedrawEachFrame() = 0; // Tells if this gfx driver uses GPU to transform sprites virtual bool HasAcceleratedTransform() = 0; // Tells if this gfx driver draws on a virtual screen before rendering on real screen. virtual bool UsesMemoryBackBuffer() = 0; // Tells if this gfx driver requires releasing render targets // in case of display mode change or reset. virtual bool ShouldReleaseRenderTargets() = 0; virtual void SetTintMethod(TintMethod method) = 0; // Initialize given display mode virtual bool SetDisplayMode(const DisplayMode &mode) = 0; // Updates previously set display mode, accommodating to the new screen size virtual void UpdateDeviceScreen(const Size &screen_size) = 0; // Gets if a graphics mode was initialized virtual bool IsModeSet() const = 0; // Set the size of the native image size virtual bool SetNativeResolution(const GraphicResolution &native_res) = 0; virtual bool IsNativeSizeValid() const = 0; // Set game render frame and translation virtual bool SetRenderFrame(const Rect &dst_rect) = 0; virtual bool IsRenderFrameValid() const = 0; // Report which color depth options are best suited for the given native color depth virtual int GetDisplayDepthForNativeDepth(int native_color_depth) const = 0; virtual IGfxModeList *GetSupportedModeList(int color_depth) = 0; virtual bool IsModeSupported(const DisplayMode &mode) = 0; virtual DisplayMode GetDisplayMode() const = 0; virtual PGfxFilter GetGraphicsFilter() const = 0; virtual Size GetNativeSize() const = 0; virtual Rect GetRenderDestination() const = 0; virtual void SetCallbackForPolling(GFXDRV_CLIENTCALLBACK callback) = 0; // TODO: get rid of draw screen callback at some point when all fade functions are more or less grouped in one virtual void SetCallbackToDrawScreen(GFXDRV_CLIENTCALLBACK callback, GFXDRV_CLIENTCALLBACK post_callback) = 0; virtual void SetCallbackOnInit(GFXDRV_CLIENTCALLBACKINITGFX callback) = 0; // The event callback is called in the main render loop when a // event entry is encountered inside a sprite list. // You can use this to hook into the rendering process. virtual void SetCallbackOnSpriteEvt(GFXDRV_CLIENTCALLBACKEVT callback) = 0; // Clears the screen rectangle. The coordinates are expected in the **native game resolution**. virtual void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) = 0; // Gets closest recommended bitmap format (currently - only color depth) for the given original format. // Engine needs to have game bitmaps brought to the certain range of formats, easing conversion into the video bitmaps. virtual int GetCompatibleBitmapFormat(int color_depth) = 0; // Returns available texture memory, or 0 if this query is not supported virtual size_t GetAvailableTextureMemory() = 0; // Creates a "raw" DDB, without pixel initialization virtual IDriverDependantBitmap *CreateDDB(int width, int height, int color_depth, bool opaque = false) = 0; // Creates DDB, initializes from the given bitmap. virtual IDriverDependantBitmap *CreateDDBFromBitmap(Shared::Bitmap *bitmap, bool has_alpha, bool opaque = false) = 0; // Creates DDB intended to be used as a render target (allow render other DDBs on it). virtual IDriverDependantBitmap *CreateRenderTargetDDB(int width, int height, int color_depth, bool opaque = false) = 0; // Updates DBB using the given bitmap; bitmap must have same size and format // as the one that this DDB was initialized with. virtual void UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Shared::Bitmap *bitmap, bool has_alpha) = 0; // Destroy the DDB. virtual void DestroyDDB(IDriverDependantBitmap *bitmap) = 0; // Get shared texture from cache, or create from bitmap and assign ID // FIXME: opaque should be either texture data's flag, - in which case same sprite_id // will be either opaque or not opaque, - or DDB's flag, but in that case it cannot // be applied to the shared texture data. Currently it's possible to share same // texture data, but update it with different "opaque" values, which breaks logic. virtual IDriverDependantBitmap *GetSharedDDB(uint32_t sprite_id, Shared::Bitmap *bitmap = nullptr, bool has_alpha = true, bool opaque = false) = 0; virtual void UpdateSharedDDB(uint32_t sprite_id, Shared::Bitmap *bitmap = nullptr, bool has_alpha = true, bool opaque = false) = 0; // Removes the shared texture reference, will force the texture to recreate next time virtual void ClearSharedDDB(uint32_t sprite_id) = 0; // Prepares next sprite batch, a list of sprites with defined viewport and optional // global model transformation; all subsequent calls to DrawSprite will be adding // sprites to this batch's list. // Beginning a batch while the previous was not ended will create a sub-batch // (think of it as of a child scene node). // Optionally you can assign "filter flags" to this batch; this lets to filter certain // batches out during some operations, such as fading effects or making screenshots. virtual void BeginSpriteBatch(const Rect &viewport, const SpriteTransform &transform = SpriteTransform(), Shared::GraphicFlip flip = Shared::kFlip_None, PBitmap surface = nullptr, uint32_t filter_flags = 0) = 0; // Ends current sprite batch virtual void EndSpriteBatch() = 0; // Adds sprite to the active batch virtual void DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) = 0; // Adds fade overlay fx to the active batch virtual void SetScreenFade(int red, int green, int blue) = 0; // Adds tint overlay fx to the active batch // TODO: redesign this to allow various post-fx per sprite batch? virtual void SetScreenTint(int red, int green, int blue) = 0; // Sets stage screen parameters for the current batch. // Currently includes size and optional position offset; // the position is relative, as stage screens are using sprite batch transforms. // Stage screens are used to let plugins do raw drawing during render callbacks. // TODO: find a better term? note, it's used in several places around renderers. virtual void SetStageScreen(const Size &sz, int x = 0, int y = 0) = 0; // Clears all sprite batches, resets batch counter virtual void ClearDrawLists() = 0; virtual void RenderToBackBuffer() = 0; virtual void Render() = 0; // Renders with additional final offset and flip // TODO: leftover from old code, solely for software renderer; remove when // software mode either discarded or scene node graph properly implemented. virtual void Render(int xoff, int yoff, Shared::GraphicFlip flip) = 0; // Copies contents of the game screen into bitmap using simple blit or pixel copy. // Bitmap must be of supported size and pixel format. If it's not the method will // fail and optionally write wanted destination format into 'want_fmt' pointer. virtual bool GetCopyOfScreenIntoBitmap(Shared::Bitmap *destination, const Rect *src_rect, bool at_native_res, GraphicResolution *want_fmt = nullptr, uint32_t batch_skip_filter = 0u) = 0; // Tells if the renderer supports toggling vsync after initializing the mode. virtual bool DoesSupportVsyncToggle() = 0; // Toggles vertical sync mode, if renderer supports one; returns the *new state*. virtual bool SetVsync(bool enabled) = 0; // Tells if the renderer currently has vsync enabled. virtual bool GetVsync() const = 0; // Enables or disables rendering mode that draws sprite list directly into // the final resolution, as opposed to drawing to native-resolution buffer // and scaling to final frame. The effect may be that sprites that are // drawn with additional fractional scaling will appear more detailed than // the rest of the game. The effect is stronger for the low-res games being // rendered in the high-res mode. virtual void RenderSpritesAtScreenResolution(bool enabled) = 0; // TODO: move fade-in/out/boxout functions out of the graphics driver!! make everything render through // main drawing procedure. Since currently it does not - we need to init our own sprite batch // internally to let it set up correct viewport settings instead of relying on a chance. // Runs fade-out animation in a blocking manner. virtual void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue, uint32_t batch_skip_filter = 0u) = 0; // Runs fade-in animation in a blocking manner. virtual void FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue, uint32_t batch_skip_filter = 0u) = 0; // Runs box-out animation in a blocking manner. virtual void BoxOutEffect(bool blackingOut, int speed, int delay, uint32_t batch_skip_filter = 0u) = 0; virtual void UseSmoothScaling(bool enabled) = 0; virtual bool SupportsGammaControl() = 0; virtual void SetGamma(int newGamma) = 0; // Returns the virtual screen. Will return NULL if renderer does not support memory backbuffer. // In normal case you should use GetStageBackBuffer() instead. virtual Shared::Bitmap *GetMemoryBackBuffer() = 0; // Sets custom backbuffer bitmap to render to. // Passing NULL pointer will tell renderer to switch back to its original virtual screen. // Note that only software renderer supports this. virtual void SetMemoryBackBuffer(Shared::Bitmap *backBuffer) = 0; // Returns memory backbuffer for the current rendering stage (or base virtual screen if called outside of render pass). // All renderers should support this. virtual Shared::Bitmap *GetStageBackBuffer(bool mark_dirty = false) = 0; // Sets custom backbuffer bitmap to render current render stage to. // Passing NULL pointer will tell renderer to switch back to its original stage buffer. // Note that only software renderer supports this. virtual void SetStageBackBuffer(Shared::Bitmap *backBuffer) = 0; // Retrieves 3 transform matrixes for the current rendering stage: world (model), view and projection. // These matrixes will be filled in accordance to the renderer's compatible format; // returns false if renderer does not use matrixes (not a 3D renderer). virtual bool GetStageMatrixes(RenderMatrixes &rm) = 0; virtual ~IGraphicsDriver() {} }; } // namespace Engine } // namespace AGS } // namespace AGS3 #endif