# Rewrite 5
- Move Libraries Source into pd directory and give them all their own CMakeLists.txt - Partial rewrite core (color, autogenerated vec), lithium (now uses UNIQUE PTR for Commands), UI7 - Use MenuV2 as new standart in UI7 - Implementz ViewPort Pre alpha to UI7 - Add Line Drawing to DrawList (not Working) - Implement a Complete new drievrs API (static Drivers) - NO SUPPORT FOR SHARED LIBRARY BUILDS IN VERSION 5 YET - Add Tools to Autogenerate Headers and Stuff
This commit is contained in:
		
							
								
								
									
										280
									
								
								pd/lithium/source/drawlist.cpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										280
									
								
								pd/lithium/source/drawlist.cpp
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,280 @@ | ||||
| /* | ||||
| 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/drawlist.hpp> | ||||
| #include <pd/lithium/renderer.hpp> | ||||
|  | ||||
| #ifndef M_PI | ||||
| #define M_PI 3.14159265358979323846 | ||||
| #endif | ||||
|  | ||||
| namespace PD { | ||||
| namespace Li { | ||||
| PD_LITHIUM_API void DrawList::DrawSolid() { CurrentTex = Gfx::GetSolidTex(); } | ||||
|  | ||||
| PD_LITHIUM_API Command::Ref DrawList::PreGenerateCmd() { | ||||
|   Command::Ref cmd = Command::New(); | ||||
|   cmd->Layer = Layer; | ||||
|   cmd->Index = pDrawList.size(); | ||||
|   cmd->Tex = CurrentTex; | ||||
|   pClipCmd(cmd.get()); | ||||
|   return std::move(cmd); | ||||
| } | ||||
|  | ||||
| PD_LITHIUM_API void DrawList::pClipCmd(Command *cmd) { | ||||
|   if (!pClipRects.IsEmpty()) { | ||||
|     cmd->ScissorOn = true; | ||||
|     cmd->ScissorRect = ivec4(pClipRects.Top()); | ||||
|   } | ||||
| } | ||||
|  | ||||
| PD_LITHIUM_API void DrawList::PathArcToN(const fvec2 &c, float radius, | ||||
|                                          float a_min, float a_max, | ||||
|                                          int segments) { | ||||
|   // Path.push_back(c); | ||||
|   PathReserve(segments + 1); | ||||
|   for (int i = 0; i < segments; i++) { | ||||
|     float a = a_min + ((float)i / (float)segments) * (a_max - a_min); | ||||
|     PathAdd(vec2(c.x + std::cos(a) * radius, c.y + std::sin(a) * radius)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| PD_LITHIUM_API void DrawList::PathFastArcToN(const fvec2 &c, float r, | ||||
|                                              float amin, float amax, int s) { | ||||
|   /** | ||||
|    * Funcion with less division overhead | ||||
|    * Usefull for stuff where a lot of calculations are required | ||||
|    */ | ||||
|   float d = (amax - amin) / s; | ||||
|   PathReserve(s + 1); | ||||
|   for (int i = 0; i <= s; i++) { | ||||
|     float a = amin + i * d; | ||||
|     PathAdd(fvec2(c.x + std::cos(a) * r, c.y + std::sin(a) * r)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| PD_LITHIUM_API void DrawList::PathRect(fvec2 a, fvec2 b, float rounding) { | ||||
|   if (rounding == 0.f) { | ||||
|     PathAdd(a); | ||||
|     PathAdd(vec2(b.x, a.y)); | ||||
|     PathAdd(b); | ||||
|     PathAdd(vec2(a.x, b.y)); | ||||
|   } else { | ||||
|     float r = std::min({rounding, (b.x - a.x) * 0.5f, (b.y - a.y) * 0.5f}); | ||||
|     /** Calculate Optimal segment count automatically */ | ||||
|     float corner = M_PI * 0.5f; | ||||
|     int segments = std::max(3, int(std::ceil(corner / (6.0f * M_PI / 180.0f)))); | ||||
|  | ||||
|     /** | ||||
|      * To Correctly render filled shapes with Paths API | ||||
|      * The Commands need to be setup clockwise | ||||
|      */ | ||||
|     /** Top Left */ | ||||
|     PathAdd(vec2(a.x + r, a.y)); | ||||
|     PathFastArcToN(vec2(b.x - r, a.y + r), r, -M_PI / 2.0f, 0.0f, segments); | ||||
|     /** Top Right */ | ||||
|     PathAdd(vec2(b.x, b.y - r)); | ||||
|     PathFastArcToN(vec2(b.x - r, b.y - r), r, 0.0f, M_PI / 2.0f, segments); | ||||
|     /** Bottom Right */ | ||||
|     PathAdd(vec2(a.x + r, b.y)); | ||||
|     PathFastArcToN(vec2(a.x + r, b.y - r), r, M_PI / 2.0f, M_PI, segments); | ||||
|     /** Bottom Left */ | ||||
|     PathAdd(vec2(a.x, a.y + r)); | ||||
|     PathFastArcToN(vec2(a.x + r, a.y + r), r, M_PI, 3.0f * M_PI / 2.0f, | ||||
|                    segments); | ||||
|   } | ||||
| } | ||||
|  | ||||
| PD_LITHIUM_API void DrawList::PathRectEx(fvec2 a, fvec2 b, float rounding, | ||||
|                                          u32 flags) { | ||||
|   if (rounding == 0.f) { | ||||
|     PathAdd(a); | ||||
|     PathAdd(vec2(b.x, a.y)); | ||||
|     PathAdd(b); | ||||
|     PathAdd(vec2(a.x, b.y)); | ||||
|   } else { | ||||
|     float r = std::min({rounding, (b.x - a.x) * 0.5f, (b.y - a.y) * 0.5f}); | ||||
|     /** Calculate Optimal segment count automatically */ | ||||
|     float corner = M_PI * 0.5f; | ||||
|     int segments = std::max(3, int(std::ceil(corner / (6.0f * M_PI / 180.0f)))); | ||||
|  | ||||
|     /** | ||||
|      * To Correctly render filled shapes with Paths API | ||||
|      * The Commands need to be setup clockwise | ||||
|      */ | ||||
|     /** Top Left */ | ||||
|     if (flags & LiPathRectFlags_KeepTopLeft) { | ||||
|       PathAdd(a); | ||||
|     } else { | ||||
|       PathAdd(vec2(a.x + r, a.y)); | ||||
|       PathFastArcToN(vec2(b.x - r, a.y + r), r, -M_PI / 2.0f, 0.0f, segments); | ||||
|     } | ||||
|  | ||||
|     /** Top Right */ | ||||
|     if (flags & LiPathRectFlags_KeepTopRight) { | ||||
|       PathAdd(vec2(b.x, a.y)); | ||||
|     } else { | ||||
|       PathAdd(vec2(b.x, b.y - r)); | ||||
|       PathFastArcToN(vec2(b.x - r, b.y - r), r, 0.0f, M_PI / 2.0f, segments); | ||||
|     } | ||||
|     /** Bottom Right */ | ||||
|     if (flags & LiPathRectFlags_KeepBotRight) { | ||||
|       PathAdd(b); | ||||
|     } else { | ||||
|       PathAdd(vec2(a.x + r, b.y)); | ||||
|       PathFastArcToN(vec2(a.x + r, b.y - r), r, M_PI / 2.0f, M_PI, segments); | ||||
|     } | ||||
|     /** Bottom Left */ | ||||
|     if (flags & LiPathRectFlags_KeepBotLeft) { | ||||
|       PathAdd(vec2(a.x, b.y)); | ||||
|     } else { | ||||
|       PathAdd(vec2(a.x, a.y + r)); | ||||
|       PathFastArcToN(vec2(a.x + r, a.y + r), r, M_PI, 3.0f * M_PI / 2.0f, | ||||
|                      segments); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| PD_LITHIUM_API void DrawList::DrawRect(const fvec2 &pos, const fvec2 &size, | ||||
|                                        u32 color, int thickness) { | ||||
|   PathRect(pos, pos + size); | ||||
|   // Flags is currently hardcoded (1 = close) | ||||
|   PathStroke(color, thickness, 1); | ||||
| } | ||||
| void DrawList::DrawRectFilled(const fvec2 &pos, const fvec2 &size, u32 color) { | ||||
|   PathRect(pos, pos + size); | ||||
|   PathFill(color); | ||||
| } | ||||
|  | ||||
| PD_LITHIUM_API void DrawList::DrawTriangle(const fvec2 &a, const fvec2 &b, | ||||
|                                            const fvec2 &c, u32 color, | ||||
|                                            int thickness) { | ||||
|   PathAdd(a); | ||||
|   PathAdd(b); | ||||
|   PathAdd(c); | ||||
|   PathStroke(color, thickness, 1); | ||||
| } | ||||
|  | ||||
| PD_LITHIUM_API void DrawList::DrawTriangleFilled(const fvec2 &a, const fvec2 &b, | ||||
|                                                  const fvec2 &c, u32 color) { | ||||
|   PathAdd(a); | ||||
|   PathAdd(b); | ||||
|   PathAdd(c); | ||||
|   PathFill(color); | ||||
| } | ||||
|  | ||||
| PD_LITHIUM_API void DrawList::DrawCircle(const fvec2 ¢er, float rad, | ||||
|                                          u32 color, int num_segments, | ||||
|                                          int thickness) { | ||||
|   if (num_segments <= 0) { | ||||
|     // Auto Segment | ||||
|   } else { | ||||
|     float am = (M_PI * 2.0f) * ((float)num_segments) / (float)num_segments; | ||||
|     PathArcToN(center, rad, 0.f, am, num_segments); | ||||
|   } | ||||
|   DrawSolid(); // Only Solid Color Supported | ||||
|   PathStroke(color, thickness, (1 << 0)); | ||||
| } | ||||
|  | ||||
| PD_LITHIUM_API void DrawList::DrawCircleFilled(const fvec2 ¢er, float rad, | ||||
|                                                u32 color, int num_segments) { | ||||
|   if (num_segments <= 0) { | ||||
|     // Auto Segment | ||||
|   } else { | ||||
|     float am = (M_PI * 2.0f) * ((float)num_segments) / (float)num_segments; | ||||
|     PathArcToN(center, rad, 0.f, am, num_segments); | ||||
|   } | ||||
|   PathFill(color); | ||||
| } | ||||
|  | ||||
| // TODO: Don't render OOS | ||||
| PD_LITHIUM_API void DrawList::DrawPolyLine(const Vec<fvec2> &points, u32 clr, | ||||
|                                            u32 flags, int thickness) { | ||||
|   if (points.Size() < 2) { | ||||
|     return; | ||||
|   } | ||||
|   DrawSolid(); | ||||
|   auto cmd = PreGenerateCmd(); | ||||
|   bool close = (flags & (1 << 0)); | ||||
|   int num_points = close ? (int)points.Size() : (int)points.Size() - 1; | ||||
|   if (flags & (1 << 1)) { | ||||
|     // TODO: Find a way to draw less garbage looking lines | ||||
|   } else { | ||||
|     // Non antialiased lines look awful when rendering with thickness != 1 | ||||
|     for (int i = 0; i < num_points; i++) { | ||||
|       int j = (i + 1) == (int)points.Size() ? 0 : (i + 1); | ||||
|       auto line = Renderer::PrimLine(points[i], points[j], thickness); | ||||
|       Renderer::CmdQuad(cmd.get(), line, vec4(0.f, 1.f, 1.f, 0.f), clr); | ||||
|     } | ||||
|   } | ||||
|   AddCommand(std::move(cmd)); | ||||
| } | ||||
|  | ||||
| PD_LITHIUM_API void DrawList::DrawConvexPolyFilled(const Vec<fvec2> &points, | ||||
|                                                    u32 clr) { | ||||
|   if (points.Size() < 3) { | ||||
|     return; // Need at least three points | ||||
|   } | ||||
|   auto cmd = PreGenerateCmd(); | ||||
|   Renderer::CmdConvexPolyFilled(cmd.get(), points, clr, CurrentTex); | ||||
|   AddCommand(std::move(cmd)); | ||||
| } | ||||
|  | ||||
| PD_LITHIUM_API void DrawList::DrawText(const fvec2 &pos, | ||||
|                                        const std::string &text, u32 color) { | ||||
|   if (!pCurrentFont) { | ||||
|     return; | ||||
|   } | ||||
|   std::vector<Command::Ref> cmds; | ||||
|   pCurrentFont->CmdTextEx(cmds, pos, color, pFontScale, text); | ||||
|   for (size_t i = 0; i < cmds.size(); i++) { | ||||
|     cmds[i]->Index = pDrawList.size(); | ||||
|     cmds[i]->Layer = Layer; | ||||
|     AddCommand(std::move(cmds[i])); | ||||
|   } | ||||
| } | ||||
|  | ||||
| PD_LITHIUM_API void DrawList::DrawTextEx(const fvec2 &p, | ||||
|                                          const std::string &text, u32 color, | ||||
|                                          LiTextFlags flags, fvec2 box) { | ||||
|   if (!pCurrentFont) { | ||||
|     return; | ||||
|   } | ||||
|   std::vector<Command::Ref> cmds; | ||||
|   pCurrentFont->CmdTextEx(cmds, p, color, pFontScale, text, flags, box); | ||||
|   for (size_t i = 0; i < cmds.size(); i++) { | ||||
|     cmds[i]->Index = pDrawList.size(); | ||||
|     cmds[i]->Layer = Layer; | ||||
|     AddCommand(std::move(cmds[i])); | ||||
|   } | ||||
| } | ||||
|  | ||||
| PD_LITHIUM_API void DrawList::DrawLine(const fvec2 &a, const fvec2 &b, | ||||
|                                        u32 color, int t) { | ||||
|   PathAdd(a); | ||||
|   PathAdd(b); | ||||
|   PathStroke(color, t); | ||||
| } | ||||
| } // namespace Li | ||||
| } // namespace PD | ||||
		Reference in New Issue
	
	Block a user