Skip to content

v0_2 First Button

PolyWCube edited this page May 22, 2025 · 1 revision

Log

So this is it~. We finally have a renderer, I mean by an actual renderer that can draw stuff in the following procedure.

Draw Datas (Primitive Shapes, buffers) --> Draw Buffer --> Renderer --> Call Window Function --> Final image

I tried to mimic the interface of the graphic flow of some typical graphic libraries with my own implementation to suit my system. For example, I have things like this.

// Window and renderer setup
Object::Object* object->AddProperty<Object::Window>();
Object::Window* windowProperty = object->GetProperty<Object::Window>();
windowProperty->Create();
Graphic::Window::Window* window = windowProperty->Get(); // This is actually unsafe but I will fix in the future

object->AddProperty<Object::Renderer>();
Object::Renderer* rendererProperty = object->GetProperty<Object::Renderer>();

if (window) {
	window->SetVisible(true);
	window->SetEventCallback(BIND_EVENT_CALLBACK(Event)); // Bind event callback

	rendererProperty->Create(window->GetWindowHandle());
}

// Call per frame
rendererProperty->BeginFrame();
rendererProperty->SetBuffer(buffer.GetDatas(), WINDOW_WIDTH, WINDOW_HEIGHT);
rendererProperty->SwapBuffer();
rendererProperty->EndFrame();

In this example, we can see it is pretty neat and simple, as most of the stuff is hidden and automated in the abstract class. Another thing that has changed in this update is that the CRTP implementation of the previous version has been changed to the this deduction implementation. They are quite the same, but the this deduction is more like the CRTP, remove the CR, just the TP. This makes the derived class not really need to pass any specific information about itself to the base class.

// Before
template <class Derived>
class Base {
public :
	void DoSmt() { static_cast<Derived*>(this)->DoSmtImpl(); }
protected :
	Base() = default;
};
class Derived : public Base<Derived> { void DoSmtImpl() { /* Implementation */ } };

// After
class Base {
public :
	template <typename Self>
	void DoSmt(this Self self) { self.DoSmtImpl(); }
protected :
	Base() = default;
};
class Derived : public Base { void DoSmtImpl() { /* Implementation */ } };

The second big change is the UI system. Currently, the UI system is still in the prototype, only implements the button just yet, a lot of things could be expanded and improved, but compared to the target of the system, it is a full success.

AddLayer(new UI::Layer(uiManager)); // Create the new UI layer, taking the uiManager as the interface

std::unique_ptr<UI::Button> closeButton = std::make_unique<UI::Button>("closeButton", 0, Math::Vector3<int16_t>(10, 10, 0), Math::Vector2<uint16_t>(40, 40));

closeButton->SetDefaultColor({150, 0, 0, 255});
closeButton->SetHoverColor({250, 0, 0, 255});
closeButton->SetPressColor({50, 0, 0, 255});
closeButton->SetDisableColor({50, 0, 0, 255});

closeButton->SetClickCallback([this]() { Shutdown(); }); // The callback takes a lambda to a function of this pointer- Application class in this example - with a function

uiManager.AddElement(std::move(closeButton)); // Bind the button to the UI manager

uiManager.UpdateBuffer(buffer, { WINDOW_WIDTH, WINDOW_HEIGHT }); // Update this every frame

Here are some benchmarking results that I made with the renderer during my development process

// No optimization
[Thu-May-25|51:46:21] Debug: Render Size: 500, 500
[Thu-May-25|51:46:21] Debug: Benchmark of Render() for 60 iterations:
[Thu-May-25|51:46:21] Debug: Total duration: 136429414 microseconds (2.27 minutes)
FPS: 0.44

// Optimization 1 (Optimize the buffer-to-bytes conversion function), this is a huge improvement! 
[Thu-May-25|19:58:21] Debug: Render Size: 500, 500
[Thu-May-25|19:58:21] Debug: Benchmark of Render() for 60 iterations:
[Thu-May-25|19:58:21] Debug: Total duration: 2171907 microseconds (0.03 minutes)
FPS: 27.6

// Optimization 2 (Optimize the buffer internal function and the rendering method)
[Thu-May-25|52:04:22] Debug: Render Size: 1920, 1080 // Increased rendering size
[Thu-May-25|52:04:22] Debug: Benchmark of Render() for 60 iterations:
[Sat-May-25|19:10:20] Debug: Total duration: 1163452 microseconds
FPS: 51.57

// Optimization 2 + Rotate Line (Draw function)
[Sat-May-25|19:10:20] Debug: Render Size: 1920, 1080
[Sat-May-25|19:10:20] Debug: Benchmark of Render() for 60 iterations:
[Thu-May-25|52:04:22] Debug: Total duration: 1391978 microseconds
FPS: 43.10 // Kinda needed to concern the implementation of the drawing function

Roadmap

I will keep expanding the UI system as the rendering pipeline thing (maybe I will try some GPU-accelerating things in the future), also developing a new interface or something easier to use, maybe a visual scripting feature, who knows, maybe one day I'll create a new programming language. Additionally, maybe the next update will be about 3D graphics, if I'm capable of doing so. Anyways, I don't have a big feature to do in the next update just yet, for now, I'll just keep doing my study and improving my code.

Update

  • Add renderer, buffer, and most of the necessary graphics stuff
  • Create an abstract UI system

Logo - BG

Clone this wiki locally