123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- /*
- * 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 <imgui.h>
- #include <imgui_sdl.h>
- #include <imgui_impl_sdl.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);
- ImGui::CreateContext();
- ImGuiSDL::Initialize(graphics::renderer, graphics::windowWidth, graphics::windowHeight);
- 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);
- }
|