/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #ifndef __NBASERENDERER__ #define __NBASERENDERER__ #include "core/renderable.h" #include "core/material.h" #include "timing/benchmark.h" #include "data/registry.h" #include "geometry/frustum.h" #include "geometry/rect.h" #include "plugin/plugin_manager.h" #include "async/job_perf.h" namespace GS { namespace Render { class RasterFont; struct IEnvironment; /// Video mode settings. enum VideoMode { VideoWindowed = 0, VideoFullscreen, VideoWindowedQuiet, ///< Open windowed output but do not automatically show the window. VideoRaw, VideoGenericPAL, ///< Used by console systems. VideoGenericNTSC }; /// struct Window { /// Get handle. virtual void *GetHandle() const = 0; /// Get render window size. virtual void GetSize(uint &w, uint &h) = 0; virtual ~Window() {} }; /*! @short Renderer base class. This the base that has to be derived to add support for a new renderer. For example implementations see NullRenderer or GPURenderer. nNull_Renderer can be used as a starting point in implementing a new renderer. This class also implements all functions required to maintain the minimum concept of viewport used by the engine. @see S3D::Scene::SetSceneInterface(). @author Emmanuel Julien (ejulien@gsworks.fr) */ class Renderer : public RegistryListener { public: NPLACEMENT_NEW(Renderer) /// Return the plugin class. static const char *GetPluginClass() { return "Renderer"; } /*! @short Return the plugin version. @note This version number must be increased whenever a modification is made to the base interface in order to prevent incompatible plugin from being loaded. */ static uint GetPluginVersion() { return 1; } /*! @name Resource factory. @{ */ virtual Geometry *NewGeometry(const char *name = 0) = 0; virtual Material *NewMaterial(const char *name = 0) = 0; virtual Texture *NewTexture(const char *name = 0) = 0; virtual Shader *NewShader(const char *name = 0) = 0; /// @} /// Clear function enum ClearFunction { ClearColor = (1 << 0), ClearDepth = (1 << 1), ClearAll = ~0 }; /*! @short Geometry updater control word. @see UpdateGeometry(). */ enum GeoUpdate { GEOUPDATE_NONE = 0, GEOUPDATE_IDX, GEOUPDATE_VTX, GEOUPDATE_VNRM, GEOUPDATE_PNRM, GEOUPDATE_SOFTVTX, GEOUPDATE_RGB }; /// Renderer statistics. struct Statistics { String adapter, vendor; uint queue_pass, ///< Number of queue pass rendered. light_processed, ///< Number of light processed. renderable_processed, ///< Number of renderable processed. renderable_drawn, ///< Number of renderable drawn. list_drawn, ///< Number of display list drawn. triangle_drawn, ///< Number of triangles drawn. texture_memory, ///< Texture memory in use. geometry_memory; ///< Geometry memory in use. ASync::JobPerf bench_prepare_light; Benchmark bench_post_process, bench_render; /// Reset statistics. void Reset() { queue_pass = 0; light_processed = 0; renderable_processed = 0; renderable_drawn = 0; list_drawn = 0; triangle_drawn = 0; bench_post_process.Reset(); bench_prepare_light.Reset(); bench_render.Reset(); } Statistics() { texture_memory = 0; geometry_memory = 0; Reset(); } }; /// Reload managed resources on context change. virtual void OnContextChanged(ResourceFactory *) {} /// Get current adapter ideal triangle batch size. virtual uint GetTriangleIdealBatchSize() const { return 16384; } /*! @name Renderer registry. @{ */ Registry registry; virtual RegistryRValue ProcessMessage(RegistryMessage, const Registry *, const void *parm) { return RegistryReturn_Ok; } /*! @} @name Renderer queue system. @{ */ List renderable_list; /// Delete the renderable list. void DeleteRenderableList(); /// Push a renderable to the renderable list. void PushRenderable(Core::Renderable *); /*! @short Build a renderable primitive list. A separate lod view can be provided to ensure selection of the correct geometry lod when rendering derived views such as shadow maps. */ uint BuildRenderablePrimitiveList(const Core::Camera &view, const Core::Camera &lod_view, Stack &, Core::Renderable::Context = Core::Renderable::Context_Default) const; /// @} protected: String error; ///< Last error description. /// Request lights to the manager and setup lighting. void RequestAndSetupLighting(Vector4 &pos); // Renderer state. bool fullscreen; ///< Windowed or fullscreen? float output_aspect_ratio; ///< Output aspect ratio override (default: -1 for no override) float global_aspect_ratio; ///< Global aspect ratio. Core::Camera *view_item; ///< Current view item. Registry *view_registry; ///< Current view registry. Frustum frustum; ///< Current frustum. sTexture output_texture; ///< Frame buffer output texture. List windows; Window *output_window; Window *default_window; public: tVector2 dimensions; ///< Output dimensions. tVector2 ideal_render_system_vr_resolution; tVector2 saved_ideal_render_system_vr_resolution; float ipd; bool use_fix_camera; Window* GetOutputWindow(){ return output_window; } // Renderer statistics. Statistics stats; /// Set output texture. virtual void SetOutputTexture(Texture *texture) { output_texture = texture; } /// Get output dimensions. tVector2 GetOutputDimensions() const; /// Return the output aspect ratio. float GetOutputAspectRatio() const; /// Set the output aspect ratio override (0 to disable), returns the previous aspect ratio. float SetOutputAspectRatio(float k = 0) { float v = output_aspect_ratio; output_aspect_ratio = k; return v; } /// Get renderer global aspect ratio. float GetGlobalAspectRatio() const { return global_aspect_ratio; } /// Set renderer global aspect ratio, returns the previous aspect ratio. float SetGlobalAspectRatio(float k = 1.f) { float v = global_aspect_ratio; global_aspect_ratio = k; return v; } /// Is the renderer fullscreen. bool isFullscreen() const { return fullscreen; } virtual void ResetStatistics() { stats.Reset(); } /// Display on-screen statistics. virtual void DrawProfilerText(RasterFont *[2], float &x, float &y); /// Return the current camera. Core::Camera *GetCamera() const; /// Set the current viewing item. void SetCamera(Core::Camera *); /// Apply view. virtual void ApplyCamera(); /// Set view registry. void SetViewRegistry(Registry *); /*! @short Interface used by the renderer to query environment. @see SetEnvironmentInterface(). */ IEnvironment *environment_interface; /// Set the scene interface. void SetEnvironmentInterface(IEnvironment *itf) { environment_interface = itf; } /*! @name Renderer core. These are the functions to be reimplemented by a capable renderer. @{ */ /// Start a new frame. virtual bool BeginDrawList() = 0; /// End current frame, draw to back-buffer. virtual void EndDrawList() = 0; /// Returns the renderer's name as a C string. virtual const char *GetName() const = 0; /// Returns a C string describing the renderer. virtual const char *GetDescription() const = 0; /// Returns a C string containing the renderer version number. virtual const char *GetVersion() const = 0; /// Returns a C string containing the last error description. virtual const char *GetError() const { return error; } /// Open video. virtual bool Open(uint width, uint height, char bpp = 32, VideoMode = VideoWindowed, const void *sys_handle = 0) = 0; /// Free all renderer resources. virtual void Free() {} /// Close video. virtual void Close() {} /// Setup core resources. virtual bool SetupCoreResources(bool support_3d = true) { return true; } /// Explicitly resize video output. virtual bool ResizeVideo(uint width, uint height) = 0; /// Switch to/from fullscreen. virtual void SetFullscreen(bool = true) = 0; /// Refresh display output. virtual void Refresh() = 0; /// Return a pointer to the current subsystem window output. virtual void *GetCurrentSystemWindowHandle() const = 0; /// Setup an extra window to use as renderer output. virtual Window *NewOutputWindow(const void *) = 0; /// Set the output window. virtual void SetOutputWindow(Window * = 0) = 0; /// Free a rendering window. virtual void FreeOutputWindow(Window *) = 0; /// Render the display queue. virtual void RenderList() = 0; /// Request that the frame be displayed to current output window. virtual void ShowFrame() = 0; /// Clear the render target. virtual void Clear(float r, float g, float b, float a = 1.f, float z = 1.f, ClearFunction = ClearAll) = 0; /// Grab the frame buffer to a texture. virtual void GrabDisplay(Texture *) = 0; /// Grab the frame buffer to a picture. virtual void GrabDisplay(Picture &) = 0; virtual void RenderFrame() {}; /// Set a texture as render target. virtual void SetRenderTarget(Texture *) = 0; /// Draw line. virtual void DrawLine(uint count, const Vector4 *, const Color * = 0, Core::Material::BlendOperator = Core::Material::Blend_None, Core::Material::RenderWord = Core::Material::Render_None, Shader * = 0) = 0; /// Draw triangle. virtual void DrawTriangle(uint count, const Vector4 *, const ushort *idx = 0, const Color * = 0, const Vector2 * = 0, const Texture * = 0, Core::Material::BlendOperator = Core::Material::Blend_None, Core::Material::RenderWord = Core::Material::Render_None, Shader * = 0) = 0; /// Draw sprite. virtual void DrawSprite(uint count, const Vector4 *, const Color * = 0, const float *size = 0, const Texture * = 0, float global_size = 1.f, Core::Material::BlendOperator = Core::Material::Blend_None, Core::Material::RenderWord = Core::Material::Render_None, Shader * = 0) = 0; // struct WriterConfig { bool correct_ar; ///< Enforce aspect ratio. bool normalized; ///< Normalized/absolute coordinates. WriterConfig(bool normd = true, bool ar = true) : normalized(normd), correct_ar(ar) {} }; enum WriterAlignment { AlignLeft = 0, AlignMiddle, AlignRight }; /// Output string to screen. virtual void Write(const RasterFont &, const char *, float &x, float &y, const WriterConfig &, float s = 1, const Color * = 0, WriterAlignment = AlignLeft, bool mirrored = false) = 0; /// Set the view matrix. virtual void SetViewMatrix(const Matrix4 &, const Matrix4 *inverse = 0) = 0; /// Set the projection matrix. virtual void SetProjectionMatrix(const Matrix4 &) = 0; /// Set the world matrix. virtual void SetWorldMatrix(const Matrix4 &, const Matrix4 *inverse = 0) = 0; /// Clear the user clipping plane. virtual void ClearClippingPlane() = 0; /// Set the user clipping plane. virtual void SetClippingPlane(const Vector4 &p, const Vector4 &n) = 0; /// Set clipping rect. virtual void SetClippingRect(const fRect *) = 0; /// Get clipping rect. virtual fRect GetClippingRect() const = 0; /// Set viewport. virtual void SetViewport(const fRect &) = 0; /// Get viewport. virtual fRect GetViewport() const = 0; /// @} bool FromMetaTag(NML::Tag &); NML::Tag *AsMetaTag(); Renderer(); virtual ~Renderer(); }; typedef PluginManager RendererPluginManager; } // Render } // GS #endif // __NBASERENDERER__