top of page
Search
Writer's pictureKelson Wysocki

What I've been doing with C++

My last post talked about one of my projects in Unreal Engine 5 and for this one, I'll be going over two projects I worked on using C++. These projects aren't directly related to game development and are built from the ground up to practice my programming skills.

The first of these projects is the Bezier Curve Graphing Calculator (BCGC). BCGC is a graphing calculator capable of graphing fourteen-point bezier curves and exporting those control values to a CSV to be used in other programs as needed. Taking inspiration from Desmos for the look and feel, I designed it to be a simple and straight-to-the-point tool for something I had found tedious using more general tools.


I used JUCE, a framework for creating GUI applications with C++, because of my prior experience with it during school. JUCE allowed me to quickly get a simple program up and running with only four control points and no visual grid. With this foundation set, I started working on getting a grid and some nicer-looking UI.


When creating the grid I chose to restrict points between zero and one because it would allow me to easily scale the curve between a min and max value after exporting the control points. Along with this, I decided to evenly space points on the x-axis, only allowing the user to change the y-axis values. For my purposes, the x-axis was the "time" axis, and restricting it to evenly spaced values allowed each control point to have only one value associated with it.


Once the grid was created I started working on a panel that would display the values of each point, allow the creation and deletion of points, and a button to export the values to a CSV. One of the most important parts of this panel was allowing the user to input values directly for each control point instead of having to click and drag, especially when trying to get a specific value.


The result is a simple program that is easy to use and performs the exact function I was missing in other programs.


My most recent project is a physics simulation built in a custom engine using OpenGL for graphics and Dear ImGui for UI. Using verlet integration to simulate particles I've been able to get up to 40,000 objects running at one time with 60+ frames per second. Collision detection between particles quickly became the limiting factor for increasing the number of objects.


The method I'm currently using to speed this up is a static octree implementation. An octree is a method of partitioning a three-dimensional space that reduces the number of collision checks done in each frame. For each update, I clear and then refill a four-dimensional array that represents the cells of the octree. Each particle then checks for collisions with other particles in the same cell or adjacent cells. To increase the speed of collision detection I implemented multithreading to go through the octree once it is constructed and perform the collision checks.


While these methods have improved performance significantly one of the major choke points is when there are a lot of particles in a small area which I have attempted to address in a few ways. The first was trying to make a dynamic octree which would attempt to center itself on the average position of objects to reduce the chance of having empty cells. In this process, I found that the increased time it took to generate the octree wasn't worth it and moved on to other solutions. The second attempt was implementing a k-d tree instead of an octree but I found that the k-d tree took significantly longer to check collisions and abandoned it.


A major optimization came from how I was doing math in the engine. Initially, I used the OpenGL Mathematics (GLM) library to handle all the math, but I wondered if there was a faster alternative. After looking at and testing alternative libraries, the main one being Eigen, I decided to try making math functions using SIMD. This change required refactoring a large amount of the project and to simplify this process I decided to continue using GLM for the main parts of the engine, only changing the verlet integration code.


After implementing the SIMD functions I benchmarked them against the corresponding GLM functions and found that SIMD was often significantly faster than GLM, at worst taking about the same amount of time. Knowing this, I tested with the simulation and found I could have around three times more particles using my SIMD implementation than I could with GLM. Currently, this is around where the project is stuck but I'm looking at different optimizations for collision detection and may revisit multithreading parts of the program.



So what next?

I will be releasing another post soon about a couple of projects in Godot that I've been working on. For C++ projects I've been playing around with the idea of creating a small game engine.

17 views0 comments

Recent Posts

See All

Commenti

Valutazione 0 stelle su 5.
Non ci sono ancora valutazioni

Aggiungi una valutazione
bottom of page