aboutsummaryrefslogtreecommitdiff
path: root/Client/Source/Phy2DLite/Tests/test.cpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2021-12-01 19:30:25 +0800
committerchai <chaifix@163.com>2021-12-01 19:30:25 +0800
commitbcc11176480f403ab294de24d61bab993ce2fdfd (patch)
tree0863baca5d29dc58b3555cf38bfeecbeecbec624 /Client/Source/Phy2DLite/Tests/test.cpp
parent1308cb4e2db1eb117b53372bc4fe964cf2d96813 (diff)
*misc
Diffstat (limited to 'Client/Source/Phy2DLite/Tests/test.cpp')
-rw-r--r--Client/Source/Phy2DLite/Tests/test.cpp644
1 files changed, 644 insertions, 0 deletions
diff --git a/Client/Source/Phy2DLite/Tests/test.cpp b/Client/Source/Phy2DLite/Tests/test.cpp
new file mode 100644
index 0000000..6456b75
--- /dev/null
+++ b/Client/Source/Phy2DLite/Tests/test.cpp
@@ -0,0 +1,644 @@
+#include "test.h"
+#if TEST == TEST_P2D
+
+#include "libfixmath/libfixmath/fixmath.h"
+#include <iostream>
+#include <time.h>
+#include <math.h>
+#include "SDL2/SDL.h"
+#include "imgui/imgui.h"
+#include "imgui/backends/imgui_impl_opengl2.h"
+#include "imgui/backends/imgui_impl_sdl.h"
+
+#include "../Phy2D.h"
+#include "glad/glad.h"
+
+using namespace std;
+using namespace Phy2D;
+
+namespace
+{
+ Body bodies[200];
+ Joint joints[100];
+
+ Body* bomb = NULL;
+
+ float timeStep = 1.0f / 60.0f;
+ int iterations = 10;
+ Vec2 gravity(0.0f, -10.0f);
+
+ int numBodies = 0;
+ int numJoints = 0;
+
+ int demoIndex = 0;
+
+ int width = 1280;
+ int height = 720;
+ float zoom = 10.0f;
+ float pan_y = 8.0f;
+
+ World world(gravity, iterations);
+}
+
+static void DrawBody(Body* body)
+{
+ Mat22 R(body->rotation);
+ Vec2 x = body->position;
+ Vec2 h = 0.5f * body->width;
+
+ Vec2 v1 = x + R * Vec2(-h.x, -h.y);
+ Vec2 v2 = x + R * Vec2(h.x, -h.y);
+ Vec2 v3 = x + R * Vec2(h.x, h.y);
+ Vec2 v4 = x + R * Vec2(-h.x, h.y);
+
+ if (body == bomb)
+ glColor3f(0.4f, 0.9f, 0.4f);
+ else
+ glColor3f(0.8f, 0.8f, 0.9f);
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(v1.x, v1.y);
+ glVertex2f(v2.x, v2.y);
+ glVertex2f(v3.x, v3.y);
+ glVertex2f(v4.x, v4.y);
+ glEnd();
+}
+
+static void DrawJoint(Joint* joint)
+{
+ Body* b1 = joint->body1;
+ Body* b2 = joint->body2;
+
+ Mat22 R1(b1->rotation);
+ Mat22 R2(b2->rotation);
+
+ Vec2 x1 = b1->position;
+ Vec2 p1 = x1 + R1 * joint->localAnchor1;
+
+ Vec2 x2 = b2->position;
+ Vec2 p2 = x2 + R2 * joint->localAnchor2;
+
+ glColor3f(0.5f, 0.5f, 0.8f);
+ glBegin(GL_LINES);
+ glVertex2f(x1.x, x1.y);
+ glVertex2f(p1.x, p1.y);
+ glVertex2f(x2.x, x2.y);
+ glVertex2f(p2.x, p2.y);
+ glEnd();
+}
+
+static void Demo1(Body* b, Joint* j)
+{
+ float x, y;
+
+ b->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
+ b->position.Set(0.0f, (number)-0.5f * b->width.y);
+ world.Add(b);
+ ++b; ++numBodies;
+
+ b->Set(Vec2(1.0f, 1.0f), 200.0f);
+ b->position.Set(0.0f, 4.0f);
+ world.Add(b);
+ ++b; ++numBodies;
+}
+
+// A simple pendulum
+static void Demo2(Body* b, Joint* j)
+{
+ Body* b1 = b + 0;
+ b1->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
+ b1->friction = 0.2f;
+ b1->position.Set(0.0f, (number)-0.5f * b1->width.y);
+ b1->rotation = 0.0f;
+ world.Add(b1);
+
+ Body* b2 = b + 1;
+ b2->Set(Vec2(1.0f, 1.0f), 100.0f);
+ b2->friction = 0.2f;
+ b2->position.Set(9.0f, 11.0f);
+ b2->rotation = 0.0f;
+ world.Add(b2);
+
+ numBodies += 2;
+
+ j->Set(b1, b2, Vec2(0.0f, 11.0f));
+ world.Add(j);
+
+ numJoints += 1;
+}
+
+// Varying friction coefficients
+static void Demo3(Body* b, Joint* j)
+{
+ b->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
+ b->position.Set(0.0f, (number)-0.5f * b->width.y);
+ world.Add(b);
+ ++b; ++numBodies;
+
+ b->Set(Vec2(13.0f, 0.25f), NUMBER_MAX);
+ b->position.Set(-2.0f, 11.0f);
+ b->rotation = -0.25f;
+ world.Add(b);
+ ++b; ++numBodies;
+
+ b->Set(Vec2(0.25f, 1.0f), NUMBER_MAX);
+ b->position.Set(5.25f, 9.5f);
+ world.Add(b);
+ ++b; ++numBodies;
+
+ b->Set(Vec2(13.0f, 0.25f), NUMBER_MAX);
+ b->position.Set(2.0f, 7.0f);
+ b->rotation = 0.25f;
+ world.Add(b);
+ ++b; ++numBodies;
+
+ b->Set(Vec2(0.25f, 1.0f), NUMBER_MAX);
+ b->position.Set(-5.25f, 5.5f);
+ world.Add(b);
+ ++b; ++numBodies;
+
+ b->Set(Vec2(13.0f, 0.25f), NUMBER_MAX);
+ b->position.Set(-2.0f, 3.0f);
+ b->rotation = -0.25f;
+ world.Add(b);
+ ++b; ++numBodies;
+
+ float friction[5] = { 0.75f, 0.5f, 0.35f, 0.1f, 0.0f };
+ for (int i = 0; i < 5; ++i)
+ {
+ b->Set(Vec2(0.5f, 0.5f), 25.0f);
+ b->friction = friction[i];
+ b->position.Set(-7.5f + 2.0f * i, 14.0f);
+ world.Add(b);
+ ++b; ++numBodies;
+ }
+}
+
+// A vertical stack
+static void Demo4(Body* b, Joint* j)
+{
+ b->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
+ b->friction = 0.2f;
+ b->position.Set(0.0f, (number)-0.5f * b->width.y);
+ b->rotation = 0.0f;
+ world.Add(b);
+ ++b; ++numBodies;
+
+ for (int i = 0; i < 10; ++i)
+ {
+ b->Set(Vec2(1.0f, 1.0f), 1.0f);
+ b->friction = 0.2f;
+ //float x = Random(-0.1f, 0.1f);
+ float x = 0;
+ b->position.Set(x, 0.51f + 1.05f * i);
+ world.Add(b);
+ ++b; ++numBodies;
+ }
+}
+
+// A pyramid
+static void Demo5(Body* b, Joint* j)
+{
+ b->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
+ b->friction = 0.2f;
+ b->position.Set(0.0f, (number)-0.5f * b->width.y);
+ b->rotation = 0.0f;
+ world.Add(b);
+ ++b; ++numBodies;
+
+ Vec2 x(-6.0f, 0.75f);
+ Vec2 y;
+
+ for (int i = 0; i < 12; ++i)
+ {
+ y = x;
+
+ for (int j = i; j < 12; ++j)
+ {
+ b->Set(Vec2(1.0f, 1.0f), 10.0f);
+ b->friction = 0.2f;
+ b->position = y;
+ world.Add(b);
+ ++b; ++numBodies;
+
+ y += Vec2(1.125f, 0.0f);
+ }
+
+ //x += Vec2(0.5625f, 1.125f);
+ x += Vec2(0.5625f, 2.0f);
+ }
+}
+
+// A teeter
+static void Demo6(Body* b, Joint* j)
+{
+ Body* b1 = b + 0;
+ b1->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
+ b1->position.Set(0.0f, (number)-0.5f * b1->width.y);
+ world.Add(b1);
+
+ Body* b2 = b + 1;
+ b2->Set(Vec2(12.0f, 0.25f), 100.0f);
+ b2->position.Set(0.0f, 1.0f);
+ world.Add(b2);
+
+ Body* b3 = b + 2;
+ b3->Set(Vec2(0.5f, 0.5f), 25.0f);
+ b3->position.Set(-5.0f, 2.0f);
+ world.Add(b3);
+
+ Body* b4 = b + 3;
+ b4->Set(Vec2(0.5f, 0.5f), 25.0f);
+ b4->position.Set(-5.5f, 2.0f);
+ world.Add(b4);
+
+ Body* b5 = b + 4;
+ b5->Set(Vec2(1.0f, 1.0f), 100.0f);
+ b5->position.Set(5.5f, 15.0f);
+ world.Add(b5);
+
+ numBodies += 5;
+
+ j->Set(b1, b2, Vec2(0.0f, 1.0f));
+ world.Add(j);
+
+ numJoints += 1;
+}
+
+// A suspension bridge
+static void Demo7(Body* b, Joint* j)
+{
+ b->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
+ b->friction = 0.2f;
+ b->position.Set(0.0f, (number)-0.5f * b->width.y);
+ b->rotation = 0.0f;
+ world.Add(b);
+ ++b; ++numBodies;
+
+ const int numPlanks = 15;
+ float mass = 50.0f;
+
+ for (int i = 0; i < numPlanks; ++i)
+ {
+ b->Set(Vec2(1.0f, 0.25f), mass);
+ b->friction = 0.2f;
+ b->position.Set(-8.5f + 1.25f * i, 5.0f);
+ world.Add(b);
+ ++b; ++numBodies;
+ }
+
+ // Tuning
+ float frequencyHz = 2.0f;
+ float dampingRatio = 0.7f;
+
+ // frequency in radians
+ float omega = (number)2.0f * PI * frequencyHz;
+
+ // damping coefficient
+ float d = 2.0f * mass * dampingRatio * omega;
+
+ // spring stifness
+ float k = mass * omega * omega;
+
+ // magic formulas
+ float softness = 1.0f / (d + timeStep * k);
+ float biasFactor = timeStep * k / (d + timeStep * k);
+
+ for (int i = 0; i < numPlanks; ++i)
+ {
+ j->Set(bodies + i, bodies + i + 1, Vec2(-9.125f + 1.25f * i, 5.0f));
+ j->softness = softness;
+ j->biasFactor = biasFactor;
+
+ world.Add(j);
+ ++j; ++numJoints;
+ }
+
+ j->Set(bodies + numPlanks, bodies, Vec2(-9.125f + 1.25f * numPlanks, 5.0f));
+ j->softness = softness;
+ j->biasFactor = biasFactor;
+ world.Add(j);
+ ++j; ++numJoints;
+}
+
+// Dominos
+static void Demo8(Body* b, Joint* j)
+{
+ Body* b1 = b;
+ b->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
+ b->position.Set(0.0f, (number)-0.5f * b->width.y);
+ world.Add(b);
+ ++b; ++numBodies;
+
+ b->Set(Vec2(12.0f, 0.5f), NUMBER_MAX);
+ b->position.Set(-1.5f, 10.0f);
+ world.Add(b);
+ ++b; ++numBodies;
+
+ for (int i = 0; i < 10; ++i)
+ {
+ b->Set(Vec2(0.2f, 2.0f), 10.0f);
+ b->position.Set(-6.0f + 1.0f * i, 11.125f);
+ b->friction = 0.1f;
+ world.Add(b);
+ ++b; ++numBodies;
+ }
+
+ b->Set(Vec2(14.0f, 0.5f), NUMBER_MAX);
+ b->position.Set(1.0f, 6.0f);
+ b->rotation = 0.3f;
+ world.Add(b);
+ ++b; ++numBodies;
+
+ Body* b2 = b;
+ b->Set(Vec2(0.5f, 3.0f), NUMBER_MAX);
+ b->position.Set(-7.0f, 4.0f);
+ world.Add(b);
+ ++b; ++numBodies;
+
+ Body* b3 = b;
+ b->Set(Vec2(12.0f, 0.25f), 20.0f);
+ b->position.Set(-0.9f, 1.0f);
+ world.Add(b);
+ ++b; ++numBodies;
+
+ j->Set(b1, b3, Vec2(-2.0f, 1.0f));
+ world.Add(j);
+ ++j; ++numJoints;
+
+ Body* b4 = b;
+ b->Set(Vec2(0.5f, 0.5f), 10.0f);
+ b->position.Set(-10.0f, 15.0f);
+ world.Add(b);
+ ++b; ++numBodies;
+
+ j->Set(b2, b4, Vec2(-7.0f, 15.0f));
+ world.Add(j);
+ ++j; ++numJoints;
+
+ Body* b5 = b;
+ b->Set(Vec2(2.0f, 2.0f), 20.0f);
+ b->position.Set(6.0f, 2.5f);
+ b->friction = 0.1f;
+ world.Add(b);
+ ++b; ++numBodies;
+
+ j->Set(b1, b5, Vec2(6.0f, 2.6f));
+ world.Add(j);
+ ++j; ++numJoints;
+
+ Body* b6 = b;
+ b->Set(Vec2(2.0f, 0.2f), 10.0f);
+ b->position.Set(6.0f, 3.6f);
+ world.Add(b);
+ ++b; ++numBodies;
+
+ j->Set(b5, b6, Vec2(7.0f, 3.5f));
+ world.Add(j);
+ ++j; ++numJoints;
+}
+
+// A multi-pendulum
+static void Demo9(Body* b, Joint* j)
+{
+ b->Set(Vec2(100.0f, 20.0f), NUMBER_MAX);
+ b->friction = 0.2f;
+ b->position.Set(0.0f, (number)-0.5f * b->width.y);
+ b->rotation = 0.0f;
+ world.Add(b);
+
+ Body * b1 = b;
+ ++b;
+ ++numBodies;
+
+ float mass = 10.0f;
+
+ // Tuning
+ float frequencyHz = 4.0f;
+ float dampingRatio = 0.7f;
+
+ // frequency in radians
+ float omega = (number) 2.0f * PI * frequencyHz;
+
+ // damping coefficient
+ float d = 2.0f * mass * dampingRatio * omega;
+
+ // spring stiffness
+ float k = mass * omega * omega;
+
+ // magic formulas
+ float softness = 1.0f / (d + timeStep * k);
+ float biasFactor = timeStep * k / (d + timeStep * k);
+
+ const float y = 12.0f;
+
+ for (int i = 0; i < 15; ++i)
+ {
+ Vec2 x(0.5f + i, y);
+ b->Set(Vec2(0.75f, 0.25f), mass);
+ b->friction = 0.2f;
+ b->position = x;
+ b->rotation = 0.0f;
+ world.Add(b);
+
+ j->Set(b1, b, Vec2(float(i), y));
+ j->softness = softness;
+ j->biasFactor = biasFactor;
+ world.Add(j);
+
+ b1 = b;
+ ++b;
+ ++numBodies;
+ ++j;
+ ++numJoints;
+ }
+}
+
+void(*demos[])(Body* b, Joint* j) = { Demo1, Demo2, Demo3, Demo4, Demo5, Demo6, Demo7, Demo8, Demo9 };
+
+static void InitDemo(int index)
+{
+ world.Clear();
+ numBodies = 0;
+ numJoints = 0;
+ bomb = NULL;
+
+ demoIndex = index;
+ demos[index](bodies, joints);
+}
+
+int main(int argc, char **argv) {
+
+ // Setup SDL
+ // (Some versions of SDL before <2.0.10 appears to have performance/stalling issues on a minority of Windows systems,
+ // depending on whether SDL_INIT_GAMECONTROLLER is enabled or disabled.. updating to latest version of SDL is recommended!)
+ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
+ {
+ printf("Error: %s\n", SDL_GetError());
+ return -1;
+ }
+
+ // Setup window
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
+ SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
+ SDL_Window* window = SDL_CreateWindow("Phy2D lite", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, window_flags);
+ SDL_GLContext gl_context = SDL_GL_CreateContext(window);
+
+ if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) {
+ std::cerr << "Failed to initialize the OpenGL context." << std::endl;
+ exit(1);
+ }
+
+ SDL_GL_MakeCurrent(window, gl_context);
+ SDL_GL_SetSwapInterval(1); // Enable vsync
+
+ // Setup Dear ImGui context
+ IMGUI_CHECKVERSION();
+ ImGui::CreateContext();
+ ImGuiIO& io = ImGui::GetIO(); (void)io;
+ //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
+ //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
+
+ // Setup Dear ImGui style
+ ImGui::StyleColorsDark();
+ //ImGui::StyleColorsClassic();
+
+ // Setup Platform/Renderer backends
+ ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
+ ImGui_ImplOpenGL2_Init();
+
+ // Load Fonts
+ // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
+ // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
+ // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
+ // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
+ // - Read 'docs/FONTS.md' for more instructions and details.
+ // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
+ //io.Fonts->AddFontDefault();
+ //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
+ //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
+ //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
+ //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f);
+ //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
+ //IM_ASSERT(font != NULL);
+
+ // Our state
+ bool show_demo_window = true;
+ bool show_another_window = false;
+ ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
+
+ glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ float aspect = float(width) / float(height);
+ if (width >= height)
+ {
+ // aspect >= 1, set the height from -1 to 1, with larger width
+ glOrtho(-zoom * aspect, zoom * aspect, -zoom + pan_y, zoom + pan_y, -1.0, 1.0);
+ }
+ else
+ {
+ // aspect < 1, set the width to -1 to 1, with larger height
+ glOrtho(-zoom, zoom, -zoom / aspect + pan_y, zoom / aspect + pan_y, -1.0, 1.0);
+ }
+
+ InitDemo(5);
+
+ // Main loop
+ bool done = false;
+ while (!done)
+ {
+ //glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ // Poll and handle events (inputs, window resize, etc.)
+ // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
+ // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
+ // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
+ // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
+ SDL_Event event;
+ while (SDL_PollEvent(&event))
+ {
+ ImGui_ImplSDL2_ProcessEvent(&event);
+ if (event.type == SDL_QUIT)
+ done = true;
+ if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
+ done = true;
+ if (event.type == SDL_KEYDOWN)
+ {
+ switch (event.key.keysym.sym)
+ {
+ case SDLK_1:
+ case SDLK_2:
+ case SDLK_3:
+ case SDLK_4:
+ case SDLK_5:
+ case SDLK_6:
+ case SDLK_7:
+ case SDLK_8:
+ case SDLK_9:
+ InitDemo(event.key.keysym.sym - SDLK_1);
+ break;
+ }
+ }
+ }
+
+ // Start the Dear ImGui frame
+ ImGui_ImplOpenGL2_NewFrame();
+ ImGui_ImplSDL2_NewFrame();
+ ImGui::NewFrame();
+
+ // Rendering
+ ImGui::Render();
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ world.Step(timeStep);
+
+ for (int i = 0; i < numBodies; ++i)
+ DrawBody(bodies + i);
+
+ for (int i = 0; i < numJoints; ++i)
+ DrawJoint(joints + i);
+
+ glPointSize(4.0f);
+ glColor3f(1.0f, 0.0f, 0.0f);
+ glBegin(GL_POINTS);
+ std::map<ArbiterKey, Arbiter>::const_iterator iter;
+ for (iter = world.arbiters.begin(); iter != world.arbiters.end(); ++iter)
+ {
+ const Arbiter& arbiter = iter->second;
+ for (int i = 0; i < arbiter.numContacts; ++i)
+ {
+ Vec2 p = arbiter.contacts[i].position;
+ glVertex2f(p.x, p.y);
+ }
+ }
+ glEnd();
+ glPointSize(1.0f);
+
+ //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound
+ ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
+ SDL_GL_SwapWindow(window);
+ }
+
+ // Cleanup
+ ImGui_ImplOpenGL2_Shutdown();
+ ImGui_ImplSDL2_Shutdown();
+ ImGui::DestroyContext();
+
+ SDL_GL_DeleteContext(gl_context);
+ SDL_DestroyWindow(window);
+ SDL_Quit();
+
+ return 0;
+}
+
+#endif \ No newline at end of file