Browse Source

Starting our C++ Project: Initial project files

Godzil 1 year ago
parent
commit
c20407a063

BIN
assets/basketball.png


BIN
assets/bowlingball.png


BIN
assets/crate.png


BIN
assets/metal.png


BIN
assets/pico8.ttf


+ 61 - 0
source/app.cpp

@@ -0,0 +1,61 @@
+/*
+ * 2D Physic Engine
+ * app.cpp: basic application handling.
+ * Based on pikuma.com Learn Game Physics Engine Programming course.
+ * Copyright (c) 2022 986-Studio. All rights reserved.
+ *
+ * Created by Manoël Trapier on 07/06/2022.
+ */
+#include <app.h>
+#include <graphics.h>
+
+void application::parseParameters(int argc, char *argv[])
+{
+    // Nothing to do for now
+}
+
+void application::setup()
+{
+    running = graphics::openWindow();
+}
+
+void application::input()
+{
+    SDL_Event event;
+    while(SDL_PollEvent(&event))
+    {
+        switch(event.type)
+        {
+        case SDL_QUIT:
+            running = false;
+            break;
+
+        case SDL_KEYDOWN:
+            if (event.key.keysym.sym == SDLK_ESCAPE)
+            {
+                running = false;
+            }
+            break;
+        }
+    }
+}
+
+void application::update()
+{
+    // Nothing for now.
+}
+
+void application::render()
+{
+    graphics::clearScreen(0xFF056263);
+    graphics::draw::fillCircle(200, 200, 40, 0xFFFFFFFF);
+    graphics::draw::text(10, 10, graphics::makeColour(255, 12, 98), "Hello world!");
+    graphics::renderFrame();
+}
+
+void application::destroy()
+{
+    // Nothing for now.
+
+    graphics::closeWindow();
+}

+ 225 - 0
source/graphics.cpp

@@ -0,0 +1,225 @@
+/*
+ * 2D Physic Engine
+ * graphics.cpp: utilities to display stuff.
+ * Based on pikuma.com Learn Game Physics Engine Programming course.
+ * Copyright (c) 2022 986-Studio. All rights reserved.
+ *
+ * Created by Manoël Trapier on 07/06/2022.
+ */
+
+#include <cstdarg>
+
+#include <SDL.h>
+#include <SDL_image.h>
+#include <SDL_ttf.h>
+#include <SDL2_gfxPrimitives.h>
+
+#include <logger.h>
+
+#include <graphics.h>
+
+SDL_Window* graphics::window = nullptr;
+SDL_Renderer* graphics::renderer = nullptr;
+int graphics::windowWidth = 0;
+int graphics::windowHeight = 0;
+TTF_Font *graphics::font = nullptr;
+
+bool graphics::openWindow()
+{
+    if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
+    {
+        logger::critical("Error initializing SDL: %s", SDL_GetError());
+        return false;
+    }
+
+    if (TTF_Init())
+    {
+        logger::critical("SDL_ttf Initialisation error: %s", SDL_GetError());
+        return false;
+    }
+
+    SDL_DisplayMode display_mode;
+    SDL_GetCurrentDisplayMode(0, &display_mode);
+
+    graphics::windowWidth = display_mode.w;
+    graphics::windowHeight = display_mode.h;
+
+    graphics::window = SDL_CreateWindow(nullptr, 0, 0,
+                                        windowWidth, windowHeight, SDL_WINDOW_BORDERLESS);
+    if (!graphics::window)
+    {
+        logger::critical("Error creating SDL window: %s", SDL_GetError());
+        return false;
+    }
+    graphics::renderer = SDL_CreateRenderer(window, -1,
+                                            SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+    if (!graphics::renderer)
+    {
+        logger::critical("Error creating SDL renderer: %s", SDL_GetError());
+        return false;
+    }
+
+    graphics::font = TTF_OpenFont("assets/pico8.ttf", 8);
+    if (graphics::font == nullptr)
+    {
+        logger::critical("Cannot open the font for printing...: %s", SDL_GetError());
+        return false;
+    }
+
+    SDL_SetWindowFullscreen(graphics::window, SDL_WINDOW_FULLSCREEN);
+
+    return true;
+}
+
+void graphics::closeWindow()
+{
+    SDL_DestroyRenderer(graphics::renderer);
+    SDL_DestroyWindow(graphics::window);
+    SDL_Quit();
+}
+
+SDL_Texture *graphics::loadTexture(const char *filename)
+{
+    SDL_Surface *surface = IMG_Load(filename);
+    if (!surface)
+    {
+        logger::error("Error opening texture file '%s'!", filename);
+        return nullptr;
+    }
+
+    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
+    SDL_FreeSurface(surface);
+
+    logger::info("Loaded texture %s", filename);
+
+    return texture;
+}
+
+void graphics::renderFrame()
+{
+    SDL_RenderPresent(graphics::renderer);
+}
+
+void graphics::clearScreen(uint32_t color)
+{
+    SDL_SetRenderDrawColor(graphics::renderer, color >> 16, color >> 8, color, 255);
+    SDL_RenderClear(graphics::renderer);
+}
+
+void graphics::draw::line(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint32_t color)
+{
+    lineColor(graphics::renderer, x0, y0, x1, y1, color);
+}
+
+void graphics::draw::circle(int16_t x, int16_t y, int16_t radius, double angle, uint32_t color)
+{
+    circleColor(graphics::renderer, x, y, radius, color);
+    lineColor(graphics::renderer,
+              x, y,
+              floor(x + cos(angle) * radius), floor(y + sin(angle) * radius),
+              color);
+}
+
+void graphics::draw::fillCircle(int16_t x, int16_t y, int16_t radius, uint32_t color)
+{
+    filledCircleColor(graphics::renderer, x, y, radius, color);
+}
+
+void graphics::draw::rect(int16_t x, int16_t y, int16_t width, int16_t height, uint32_t color)
+{
+    lineColor(graphics::renderer,
+              floor(x - width / 2.0), floor(y - height / 2.0),
+              floor(x + width / 2.0), floor(y - height / 2.0), color);
+    lineColor(graphics::renderer,
+              floor(x + width / 2.0), floor(y - height / 2.0),
+              floor(x + width / 2.0), floor(y + height / 2.0), color);
+    lineColor(graphics::renderer,
+              floor(x + width / 2.0), floor(y + height / 2.0),
+              floor(x - width / 2.0), floor(y + height / 2.0), color);
+    lineColor(graphics::renderer,
+              floor(x - width / 2.0), floor(y + height / 2.0),
+              floor(x - width / 2.0), floor(y - height / 2.0), color);
+}
+
+void graphics::draw::fillRect(int16_t x, int16_t y, int16_t width, int16_t height, uint32_t color)
+{
+    boxColor(graphics::renderer,
+             floor(x - width / 2.0), floor(y - height / 2.0),
+             floor(x + width / 2.0), floor(y + height / 2.0), color);
+}
+
+void graphics::draw::polygon(int16_t x, int16_t y, const std::vector<vec2> &vertices, uint32_t color)
+{
+    for (uint32_t i = 0; i < vertices.size(); i++)
+    {
+        uint32_t currIndex = i;
+        uint32_t nextIndex = (i + 1) % vertices.size();
+
+        lineColor(graphics::renderer,
+                  floor(vertices[currIndex].x), floor(vertices[currIndex].y),
+                  floor(vertices[nextIndex].x), floor(vertices[nextIndex].y),
+                  color);
+    }
+    filledCircleColor(graphics::renderer, x, y, 1, color);
+}
+
+void graphics::draw::fillPolygon(int16_t x, int16_t y, const std::vector<vec2> &vertices, uint32_t color)
+{
+    std::vector<short> vx;
+    std::vector<short> vy;
+
+    for (const auto & vertice : vertices)
+    {
+        vx.push_back(static_cast<short>(vertice.x));
+    }
+
+    for (const auto & vertice : vertices)
+    {
+        vy.push_back(static_cast<short>(vertice.y));
+    }
+
+    filledPolygonColor(graphics::renderer, &vx[0], &vy[0], vertices.size(), color);
+    filledCircleColor(graphics::renderer, x, y, 1, 0xFF000000);
+}
+
+void graphics::draw::texture(int16_t x, int16_t y, int16_t width, int16_t height,
+                             double rotation, SDL_Texture *texture)
+{
+    SDL_Rect dstRect = {x - (width / 2), y - (height / 2), width, height};
+
+    double rotationDeg = rotation * 57.2958;
+
+    SDL_RenderCopyEx(graphics::renderer, texture, nullptr, &dstRect, rotationDeg,
+                     nullptr, SDL_FLIP_NONE);
+}
+
+void graphics::draw::text(int16_t x, int16_t y, uint32_t colour, const char *format, ...)
+{
+    va_list va;
+    uint8_t r = ((colour >> 16) & 0xFF);
+    uint8_t g = ((colour >>  8) & 0xFF);
+    uint8_t b = ((colour      ) & 0xFF);
+    SDL_Color c = { r, g, b , 255};
+    char buffer[512];
+
+    va_start(va, format);
+    vsnprintf(buffer, 512, format, va);
+    va_end(va);
+
+    SDL_Surface *surface = TTF_RenderText_Blended(font, buffer, c);
+    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
+
+    int labelWidth, labelHeight;
+
+    SDL_QueryTexture(texture, nullptr, nullptr, &labelWidth, &labelHeight);
+
+    SDL_Rect destRect =
+    {
+        x, y, labelWidth, labelHeight
+    };
+    SDL_RenderCopyEx(renderer, texture, nullptr, &destRect,0,
+                     nullptr, SDL_FLIP_NONE);
+
+    SDL_FreeSurface(surface);
+    SDL_DestroyTexture(texture);
+}

+ 32 - 0
source/include/app.h

@@ -0,0 +1,32 @@
+/*
+ * 2D Physic Engine
+ * app.h: 
+ * Based on pikuma.com Learn Game Physics Engine Programming course.
+ * Copyright (c) 2022 986-Studio. All rights reserved.
+ *
+ * Created by Manoël Trapier on 07/06/2022.
+ */
+
+#ifndef PHYSICENGINE_APP_H
+#define PHYSICENGINE_APP_H
+
+class application
+{
+private:
+    bool running;
+
+public:
+    application() : running(false) {};
+    ~application() = default;
+
+    void parseParameters(int argc, char *argv[]);
+    bool isRunning() { return this->running; }
+
+    void setup();
+    void input();
+    void update();
+    void render();
+    void destroy();
+};
+
+#endif /* PHYSICENGINE_APP_H */

+ 61 - 0
source/include/graphics.h

@@ -0,0 +1,61 @@
+/*
+ * 2D Physic Engine
+ * graphics.h: header for the utilities to display stuff.
+ * Based on pikuma.com Learn Game Physics Engine Programming course.
+ * Copyright (c) 2022 986-Studio. All rights reserved.
+ *
+ * Created by Manoël Trapier on 07/06/2022.
+ */
+
+#ifndef PHYSICENGINE_GRAPHICS_H
+#define PHYSICENGINE_GRAPHICS_H
+
+#include <cstdint>
+#include <vector>
+
+#include <SDL.h>
+#include <SDL_ttf.h>
+#include <physics/vec2.h>
+
+class graphics {
+private:
+    static int windowWidth;
+    static int windowHeight;
+    static SDL_Window* window;
+    static SDL_Renderer* renderer;
+    static TTF_Font *font;
+
+public:
+    static int width() { return graphics::windowWidth; }
+    static int height() { return graphics::windowHeight; }
+    static bool openWindow();
+    static void closeWindow();
+    static void clearScreen(uint32_t color);
+    static void renderFrame();
+    static SDL_Texture *loadTexture(const char *filename);
+
+    static uint32_t makeColour(uint8_t r, uint8_t g, uint8_t b)
+    {
+        return 0xFF000000 | (r << 16) | (g << 8) | (b << 0);
+    }
+
+    static uint32_t makeColour(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
+    {
+        return (a << 24) | (r << 16) | (g << 8) | (b << 0);
+    }
+
+    struct draw
+    {
+        static void line(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint32_t color);
+        static void circle(int16_t x, int16_t y, int16_t radius, double angle, uint32_t color);
+        static void fillCircle(int16_t x, int16_t y, int16_t radius, uint32_t color);
+        static void rect(int16_t x, int16_t y, int16_t width, int16_t height, uint32_t color);
+        static void fillRect(int16_t x, int16_t y, int16_t width, int16_t height, uint32_t color);
+        static void polygon(int16_t x, int16_t y, const std::vector<vec2>& vertices, uint32_t color);
+        static void fillPolygon(int16_t x, int16_t y, const std::vector<vec2> &vertices, uint32_t color);
+        static void texture(int16_t x, int16_t y, int16_t width, int16_t height, double rotation, SDL_Texture *texture);
+        static void text(int16_t x, int16_t y, uint32_t colour, const char *format, ...);
+    };
+};
+
+#endif /* PHYSICENGINE_GRAPHICS_H */

+ 15 - 0
source/include/physics/particle.h

@@ -0,0 +1,15 @@
+/*
+ * 2D Physic Engine
+ * particle.h:
+ * Based on pikuma.com Learn Game Physics Engine Programming course.
+ * Copyright (c) 2022 986-Studio. All rights reserved.
+ *
+ * Created by Manoël Trapier on 07/06/2022.
+ */
+
+#ifndef PHYSICENGINE_PHYSICS_PARTICLE_H
+#define PHYSICENGINE_PHYSICS_PARTICLE_H
+
+// TODO
+
+#endif /* PHYSICENGINE_PHYSICS_PARTICLE_H */

+ 3 - 3
source/include/vec2.h → source/include/physics/vec2.h

@@ -7,8 +7,8 @@
  * Created by Manoël Trapier on 07/06/2022.
  */
 
-#ifndef PHYSICENGINE_VEC2_H
-#define PHYSICENGINE_VEC2_H
+#ifndef PHYSICENGINE_PHYSICS_VEC2_H
+#define PHYSICENGINE_PHYSICS_VEC2_H
 
 #include <cmath>
 
@@ -156,4 +156,4 @@ struct vec2
 
 };
 
-#endif /* PHYSICENGINE_VEC2_H */
+#endif /* PHYSICENGINE_PHYSICS_VEC2_H */

+ 15 - 1
source/main.cpp

@@ -8,12 +8,26 @@
  */
 
 #include <logger.h>
+#include <app.h>
 
 int main(int argc, char *argv[])
 {
+    application app;
     logger::info("Booting up Physic Engine version %s", VERSION);
 
-    logger::info("Hello World!");
+    app.parseParameters(argc, argv);
+    app.setup();
+
+    logger::info("Ready to go!");
+
+    while(app.isRunning())
+    {
+        app.input();
+        app.update();
+        app.render();
+    }
+
+    app.destroy();
 
     return 0;
 }

+ 10 - 0
source/physics/particle.cpp

@@ -0,0 +1,10 @@
+/*
+ * 2D Physic Engine
+ * particules.cpp: 
+ * Based on pikuma.com Learn Game Physics Engine Programming course.
+ * Copyright (c) 2022 986-Studio. All rights reserved.
+ *
+ * Created by Manoël Trapier on 07/06/2022.
+ */
+
+// TODO