Initial Cross Platform Work
This commit is contained in:
		| @@ -1,382 +1,79 @@ | ||||
| #pragma once | ||||
|  | ||||
| /* | ||||
| MIT License | ||||
|  | ||||
| Copyright (c) 2024 - 2025 tobid7 | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| #include <pd/core/common.hpp> | ||||
| #include <pd/core/vec.hpp> | ||||
| #include <pd/lib3ds/memory.hpp> | ||||
| #include <pd/lithium/command.hpp> | ||||
| #include <pd/lithium/flags.hpp> | ||||
| #include <pd/lithium/font.hpp> | ||||
| #include <pd/lithium/objects.hpp> | ||||
| #include <pd/lithium/screen.hpp> | ||||
| #include <pd/lithium/texture.hpp> | ||||
| #include <pd/lithium/vertex.hpp> | ||||
|  | ||||
| namespace PD { | ||||
| namespace LI { | ||||
| /** | ||||
|  * Lithium base renderer Class. | ||||
|  */ | ||||
| class Renderer : public SmartCtor<Renderer> { | ||||
|  public: | ||||
|   /** | ||||
|    * Constructor setting up the 2d Rendering Engine | ||||
|    * @param flags Flags to use [can be changed at runtime]. | ||||
|    */ | ||||
|   Renderer(LIRenderFlags flags = LIRenderFlags_Default); | ||||
|   /** | ||||
|    * Deconstructor that unloads all the renderer data | ||||
|    */ | ||||
|   ~Renderer(); | ||||
|  | ||||
|   /** | ||||
|    * Prepare render stage for rendering. | ||||
|    */ | ||||
|   void PrepareRender(); | ||||
|   /** | ||||
|    * Render a screens Command list. | ||||
|    * @param s Screen to Draw its list on. | ||||
|    */ | ||||
|   void Render(Screen::Ref s); | ||||
|   /** | ||||
|    * Finalize rendering stage. | ||||
|    */ | ||||
|   void FinalizeRender(); | ||||
|  | ||||
|   /** | ||||
|    * Register Screens (For UI7, probably move this). | ||||
|    * @param bottom set if you register bottom ot top screen. | ||||
|    * @param s Screen to register. | ||||
|    */ | ||||
|   void RegisterScreen(bool bottom, Screen::Ref s) { screens[bottom] = s; } | ||||
|   /** | ||||
|    * Set the Screen next commands will be add to | ||||
|    * @param s Screen of choice | ||||
|    */ | ||||
|   void OnScreen(Screen::Ref s) { | ||||
|     if (!s) { | ||||
|       return; | ||||
|     } | ||||
|     this->screen = s; | ||||
|     area_size = screen->GetSize(); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Get cobst reference to active screen. | ||||
|    * @return current screen. | ||||
|    */ | ||||
|   Screen::Ref CurrentScreen() const { return screen; } | ||||
|   /** | ||||
|    * Get Screen of screen regestry. | ||||
|    * @param bottom bottom ot top screen. | ||||
|    * @return screen reference | ||||
|    */ | ||||
|   Screen::Ref GetScreen(bool bottom) { | ||||
|     auto res = screens[bottom]; | ||||
|     Assert(res.get(), "Screen is not registered!"); | ||||
|     return res; | ||||
|   } | ||||
|  | ||||
|   void Rotation(float v) { rot = v; } | ||||
|   float Rotation() const { return rot; } | ||||
|   void TextScale(float v) { text_size = v; } | ||||
|   void DefaultTextScale() { text_size = default_text_size; } | ||||
|   float TextScale() const { return text_size; } | ||||
|   void Layer(int v) { current_layer = v; } | ||||
|   int Layer() const { return current_layer; } | ||||
|   LIRenderFlags& GetFlags() { return flags; } | ||||
|   void Font(Font::Ref v) { | ||||
|     font = v; | ||||
|     font_update = true; | ||||
|   } | ||||
|   Font::Ref Font() const { return font; } | ||||
|  | ||||
|   /** | ||||
|    * Use a specific Texture for Next Rectangle. | ||||
|    * @param v texture reference to use. | ||||
|    */ | ||||
|   void UseTex(Texture::Ref v = nullptr) { | ||||
|     if (v == nullptr) { | ||||
|       current_tex = white; | ||||
|       return; | ||||
|     } | ||||
|     current_tex = v; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Draws a Rect based on current Texture | ||||
|    * @param pos Position of the Rect | ||||
|    * @param size Size of the Rect | ||||
|    * @param color Color of the Rect [0xffffffff] | ||||
|    * for full visible texture | ||||
|    * @param uv UV Map (if texture needs a custom uv) | ||||
|    * @note This function is part of Simple Draw API. | ||||
|    */ | ||||
|   void DrawRect(const vec2& pos, const vec2& size, u32 color, | ||||
|                 const Rect& uv = vec4(0.f, 1.f, 1.f, 0.f)); | ||||
|   /** | ||||
|    *  Draw a Solid Rect (uses white tex) | ||||
|    * @note | ||||
|    * - acts as a simplified Draw rect Wrapper | ||||
|    * - This function is part of Simple Draw API. | ||||
|    * @param pos Position of the rect | ||||
|    * @param size Size of the rect | ||||
|    * @param color Color of the rect | ||||
|    */ | ||||
|   void DrawRectSolid(const vec2& pos, const vec2& size, u32 color); | ||||
|   /** | ||||
|    *  Render a Triangle | ||||
|    * @param a Position A | ||||
|    * @param b Position B | ||||
|    * @param c Position C | ||||
|    * @param color Color of the triangle | ||||
|    * @note | ||||
|    * - Uses Solid color [white tex] | ||||
|    * - This function is part of Simple Draw API. | ||||
|    */ | ||||
|   void DrawTriangle(const vec2& a, const vec2& b, const vec2& c, u32 color); | ||||
|   /** | ||||
|    *  Draw a Circle (Supports Textures) | ||||
|    * @param center_pos Center Position | ||||
|    * @param r Radius of the circle | ||||
|    * @param color Color of the circle | ||||
|    * @param segments Segments to use | ||||
|    * @note | ||||
|    * - Textures could look a bit janky due to uv mapping | ||||
|    * - This function is part of Simple Draw API. | ||||
|    */ | ||||
|   void DrawCircle(const vec2& center_pos, float r, u32 color, int segments); | ||||
|   /** | ||||
|    * Draw a Line between to Positions | ||||
|    * @param a Position A | ||||
|    * @param b Position B | ||||
|    * @param color Color of the line | ||||
|    * @param t Thickness | ||||
|    * @note This function is part of Simple Draw API. | ||||
|    */ | ||||
|   void DrawLine(const vec2& a, const vec2& b, u32 color, int t); | ||||
|   /** | ||||
|    * Render a Text | ||||
|    * @param pos Position of the text | ||||
|    * @param color Color of the Text | ||||
|    * @param text Text to Render | ||||
|    * @param flags flags to use | ||||
|    * @param ap optional size for specific flags | ||||
|    * @note This function is part of Simple Draw API. | ||||
|    */ | ||||
|   void DrawText(const vec2& pos, u32 color, const std::string& text, | ||||
|                 u32 flags = 0, const vec2& ap = vec2()); | ||||
|   /** | ||||
|    * Draw a Texture as 2D Image | ||||
|    * @param pos Position | ||||
|    * @param tex Texture reference | ||||
|    * @param scale Scale (cause maybe wants to be resized) | ||||
|    * @note | ||||
|    * - Acts as a Simplified wrapper to DrawRect | ||||
|    * - This function is part of Simple Draw API. | ||||
|    */ | ||||
|   void DrawImage(const vec2& pos, Texture::Ref tex, | ||||
|                  const vec2& scale = vec2(1.f)); | ||||
|  | ||||
|   // Debug STUFF | ||||
|  | ||||
|   /** DEBUG Get the Number of Vertices of last Frame */ | ||||
|   u32 Vertices() const { return vertices; } | ||||
|   /** DEBUG Get the Number of Indices of last frame */ | ||||
|   u32 Indices() const { return indices; } | ||||
|   /** DEBUG Get the Number of Commands of last frame */ | ||||
|   u32 Commands() const { return commands; } | ||||
|   /** DEBUG Get the Number of Drawcalls of last frame */ | ||||
|   u32 DrawCalls() const { return drawcalls; } | ||||
|   /** Auto Static Text Number of Texts */ | ||||
|   u32 AstUsage() const { return ast.size(); } | ||||
|   /** Text Map System number of texts */ | ||||
|   u32 TmsUsage() const { return tms.size(); } | ||||
|  | ||||
|   // TOOLS | ||||
|  | ||||
|   /** Rotate a rect corner position by sine and cosine value */ | ||||
|   static void RotateCorner(vec2& v, float s, float c); | ||||
|   /** Create a Rect by Position, Size and rotation angle */ | ||||
|   static Rect CreateRect(const vec2& pos, const vec2& size, float angle); | ||||
|   /** Create a Line Rect by 2 Position and a thickness value */ | ||||
|   static Rect CreateLine(const vec2& a, const vec2& b, int t); | ||||
|   /** Check if a pos and size are inside a vec4 rect */ | ||||
|   static bool InBox(const vec2& pos, const vec2& size, const vec4& rect); | ||||
|   /** Check if a pos is inside a vec4 rect */ | ||||
|   static bool InBox(const vec2& pos, const vec4& rect); | ||||
|   /** Check if one or all of three positions are somehow inside a vec4 rect */ | ||||
|   static bool InBox(const vec2& alpha, const vec2& bravo, const vec2& charlie, | ||||
|                     const vec4& rect); | ||||
|   /** | ||||
|    * Get The Address of a Screen | ||||
|    * @note **IMPORTANT** THIS IS FOR 32Bit System | ||||
|    * | ||||
|    * Should find a better way to do this for porting this lib | ||||
|    */ | ||||
|   static u32 Screen32(Screen::Ref s) { return (u32)s.get(); } | ||||
|   /** Function to optimize command order for rendering */ | ||||
|   static void OptiCommandList(std::vector<Command::Ref>& list); | ||||
|   /** Returns Viewport with xy */ | ||||
|   vec4 GetViewport(); | ||||
|   /** Push a Self Created command */ | ||||
|   void PushCommand(Command::Ref cmd) { | ||||
|     cmd->Index(cmd_idx++);  // Indexing | ||||
|     draw_list[Screen32(screen)].push_back(cmd); | ||||
|   } | ||||
|   /** Automatically sets up a command */ | ||||
|   void SetupCommand(Command::Ref cmd); | ||||
|   /** Creates a default Quad Render Command */ | ||||
|   void QuadCommand(Command::Ref cmd, const Rect& quad, const Rect& uv, u32 col); | ||||
|   /** Create a Default Triangle */ | ||||
|   void TriangleCommand(Command::Ref cmd, const vec2& a, const vec2& b, | ||||
|                        const vec2& c, u32 col); | ||||
|   /** | ||||
|    * Create List of a Text Commands | ||||
|    * @param cmds Link to a command List | ||||
|    * @param pos Position | ||||
|    * @param color Color | ||||
|    * @param text Text | ||||
|    * @param flags Flags | ||||
|    * @param box (Size for wrapping / Offset for Centered Text) | ||||
|    */ | ||||
|   void TextCommand(std::vector<Command::Ref>& cmds, const vec2& pos, u32 color, | ||||
|                    const std::string& text, LITextFlags flags, const vec2& box); | ||||
|   vec2 GetTextDimensions(const std::string& text); | ||||
|   /** | ||||
|    * Function to short a text and replace the rest by ... | ||||
|    * @param text Text to short | ||||
|    * @param maxlen Maximum width | ||||
|    * @param newsize New Textbox size | ||||
|    * @return shorted text | ||||
|    */ | ||||
|   std::string ShortText(const std::string& text, int maxlen, vec2& newsize); | ||||
|   /** | ||||
|    * Function to Wrap Text by specific width | ||||
|    * | ||||
|    * **NOT IMPLEMENTED YET** | ||||
|    * @param text text to wrap | ||||
|    * @param maxlen maximum width per line | ||||
|    * @param newsize new textbox size | ||||
|    * @return wrapped text | ||||
|    */ | ||||
|   std::string WrapText(const std::string& text, int maxlen, vec2& newsize); | ||||
|  | ||||
|  private: | ||||
|   // Helper Funcitons | ||||
|  | ||||
|   /** | ||||
|    * Update the 3DS citro3d texenv for specific RenderMode | ||||
|    * @param mode RenderMode to use. | ||||
|    */ | ||||
|   void UpdateRenderMode(const RenderMode& mode); | ||||
|  | ||||
|   /** Current Screen */ | ||||
|   Screen::Ref screen; | ||||
|   /** Screen Regestry */ | ||||
|   Screen::Ref screens[2]; | ||||
|  | ||||
|   // Context Related | ||||
|  | ||||
|   /** Renderer flags */ | ||||
|   LIRenderFlags flags = LIRenderFlags_Default; | ||||
|   /** Area Size */ | ||||
|   vec2 area_size; | ||||
|   /** Current Layer */ | ||||
|   int current_layer = 0; | ||||
|   /** Current Texture */ | ||||
|   Texture::Ref current_tex = nullptr; | ||||
|   /** Single Color Texture (for solid color objs) */ | ||||
|   Texture::Ref white = nullptr; | ||||
|   /** Current Font Reference */ | ||||
|   Font::Ref font = nullptr; | ||||
|   /** Font updated */ | ||||
|   bool font_update; | ||||
|   /** Current Rendermode */ | ||||
|   RenderMode mode = RenderMode_RGBA; | ||||
|   /** Text Map System */ | ||||
|   std::map<std::string, TextBox> tms; | ||||
|   /** (Auto) Static Text */ | ||||
|   std::unordered_map<u32, StaticText::Ref> ast; | ||||
|  | ||||
|   // Text Rendering | ||||
|  | ||||
|   /** Default FOnt height */ | ||||
|   const float default_font_h = 24.f; | ||||
|   /** Default Text Scale */ | ||||
|   const float default_text_size = 0.7f; | ||||
|   /** Current Text Scale */ | ||||
|   float text_size = 0.7f; | ||||
|   // Special | ||||
|  | ||||
|   /** Current Rotation (RECTS) */ | ||||
|   float rot = 0.f; | ||||
|   // Rendering | ||||
|  | ||||
|   /** Map of drawlist by 32Bit memory Address of their Screen */ | ||||
|   std::unordered_map<u32, std::vector<Command::Ref>> draw_list; | ||||
|   /** Vertex Buffer in linear Ram */ | ||||
|   std::vector<Vertex, LinearAllocator<Vertex>> vertex_buf; | ||||
|   /** 16Bit index buffer in linear Ram */ | ||||
|   std::vector<u16, LinearAllocator<u16>> index_buf; | ||||
|   /** vertex index (render stage) */ | ||||
|   u32 vertex_idx = 0; | ||||
|   /** index buf index (render stage) */ | ||||
|   u32 index_idx = 0; | ||||
|   /** command index (used for debug count) */ | ||||
|   u32 cmd_idx = 0; | ||||
|  | ||||
|   // Debug | ||||
|  | ||||
|   /** Num of Vertices */ | ||||
|   u32 vertices = 0; | ||||
|   /** Num of indices */ | ||||
|   u32 indices = 0; | ||||
|   /** Num of Commands */ | ||||
|   u32 commands = 0; | ||||
|   /** Num of Drawcalls */ | ||||
|   u32 drawcalls = 0; | ||||
|  | ||||
|   // Shader | ||||
|  | ||||
|   /** Shader code */ | ||||
|   DVLB_s* dvlb = nullptr; | ||||
|   /** Shader program */ | ||||
|   shaderProgram_s shader; | ||||
|   /** Shader Attribute info */ | ||||
|   C3D_AttrInfo attr; | ||||
|   /** projection matrix location */ | ||||
|   int uLoc_projection = 0; | ||||
|  | ||||
|   // Matrix | ||||
|  | ||||
|   /** Precalculated Projectrion Matrix for top screen */ | ||||
|   C3D_Mtx top_proj; | ||||
|   /** Precalculated Projectrion Matrix for bottom screen */ | ||||
|   C3D_Mtx bot_proj; | ||||
| }; | ||||
| }  // namespace LI | ||||
| #pragma once | ||||
|  | ||||
| /* | ||||
| MIT License | ||||
|  | ||||
| Copyright (c) 2024 - 2025 tobid7 | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| #include <pd/lithium/backend.hpp> | ||||
| #include <pd/lithium/drawlist.hpp> | ||||
| #include <pd/lithium/font.hpp> | ||||
| #include <pd/lithium/pd_p_api.hpp> | ||||
|  | ||||
| namespace PD { | ||||
| namespace LI { | ||||
| class PD_LITHIUM_API Renderer : public SmartCtor<Renderer> { | ||||
|  public: | ||||
|   Renderer(Backend::Ref backend); | ||||
|   ~Renderer() = default; | ||||
|  | ||||
|   void Render(); | ||||
|  | ||||
|   // SECTION: ADVANCED API | ||||
|  | ||||
|   void AddCommand(Command::Ref v) { DrawList.Add(v); } | ||||
|   void RegisterDrawList(DrawList::Ref list) { pDrawLists.Add(list); } | ||||
|   Command::Ref PreGenerateCmd(); | ||||
|  | ||||
|   // SECTION: Open Command and Object creation API | ||||
|   static void RotateCorner(fvec2& pos, float sinus, float cosinus); | ||||
|   static Rect PrimRect(const fvec2& pos, const fvec2& size, float angle = 0.f); | ||||
|   static Rect PrimLine(const fvec2& a, const fvec2& b, int thickness = 1); | ||||
|   static void CmdQuad(Command::Ref cmd, const Rect& quad, const Rect& uv, | ||||
|                       u32 color); | ||||
|   static void CmdTriangle(Command::Ref cmd, const fvec2 a, const fvec2 b, | ||||
|                           const fvec2 c, u32 clr); | ||||
|   static void CmdPolyLine(const Vec<fvec2>& points, u32 clr, u32 flags = 0, | ||||
|                           int thickness = 1); | ||||
|   static void CmdConvexPolyFilled(Command::Ref cmd, const Vec<fvec2>& points, | ||||
|                                   u32 clr, Texture::Ref tex); | ||||
|  | ||||
|   // SECTION: InBounds Checks | ||||
|  | ||||
|   static bool InBox(const fvec2& pos, const fvec2& size, const fvec4& area); | ||||
|   static bool InBox(const fvec2& pos, const fvec4& area); | ||||
|   static bool InBox(const fvec2& a, const fvec2& b, const fvec2& c, | ||||
|                     const fvec4& area); | ||||
|  | ||||
|   // SECTION: Data // | ||||
|  | ||||
|   Texture::Ref WhitePixel = nullptr; | ||||
|   Backend::Ref pBackend = nullptr; | ||||
|   Texture::Ref CurrentTex = nullptr; | ||||
|   int Layer = 0; | ||||
|  | ||||
|  private: | ||||
|   PD::Vec<Command::Ref> DrawList; | ||||
|   PD::Vec<DrawList::Ref> pDrawLists; | ||||
| }; | ||||
| }  // namespace LI | ||||
| }  // namespace PD | ||||
		Reference in New Issue
	
	Block a user