Skip to content

Commit

Permalink
rendering: Adds SDL_gpu based rendering.
Browse files Browse the repository at this point in the history
  • Loading branch information
abaire committed Oct 7, 2021
1 parent c936b6d commit eccba7a
Show file tree
Hide file tree
Showing 13 changed files with 400 additions and 25 deletions.
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,9 @@
[submodule "3rdparty/NaturalSort"]
path = 3rdparty/NaturalSort
url = https://github.com/scopeInfinity/NaturalSort.git
[submodule "3rdparty/pbgl"]
path = 3rdparty/pbgl
url = https://github.com/abaire/pbgl.git
[submodule "3rdparty/sdl-gpu"]
path = 3rdparty/sdl-gpu
url = https://github.com/abaire/sdl-gpu.git
1 change: 1 addition & 0 deletions 3rdparty/pbgl
Submodule pbgl added at f47dd3
1 change: 1 addition & 0 deletions 3rdparty/sdl-gpu
Submodule sdl-gpu added at c1c333
8 changes: 6 additions & 2 deletions Includes/font.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
#include "font.h"
#include <cassert>
#include "3rdparty/SDL_FontCache/SDL_FontCache.h"
#include "infoLog.h"


Font::Font(Renderer& renderer, const char* path) : renderer(renderer) {
fcFont = FC_CreateFont();
assert(fcFont);
#ifdef FC_USE_SDL_GPU
bool load_success = FC_LoadFont(fcFont, path, 20, FC_MakeColor(250, 250, 250, 255),
TTF_STYLE_NORMAL);
#else
bool load_success = FC_LoadFont(fcFont, renderer.getRenderer(), path, 20,
FC_MakeColor(250, 250, 250, 255), TTF_STYLE_NORMAL);
#endif
assert(load_success);
}

Expand Down
8 changes: 7 additions & 1 deletion Includes/font.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@
#include <string>
#include <utility>
#include <vector>
#include "3rdparty/SDL_FontCache/SDL_FontCache.h"
#include "renderer.h"

// clang-format off
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
#include "3rdparty/SDL_FontCache/SDL_FontCache.h"
#pragma clang diagnostic pop
// clang-format on

class Font {
private:
FC_Font* fcFont;
Expand Down
17 changes: 17 additions & 0 deletions Includes/menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
#include "settingsMenu.hpp"
#include "xbeLauncher.h"
#include "xbeScanner.h"
#ifdef NXDK
// clang-format off
#ifdef FC_USE_SDL_GPU
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
#include "SDL_gpu.h"
#pragma clang diagnostic pop
#endif
// clang-format on
#endif

// Character used in the config.json to separate multiple path entries.
#define PATH_DELIMITER ','
Expand Down Expand Up @@ -384,13 +394,20 @@ void Menu::render(Font& font) {
dimensions = font.draw(menutext, coordinates);

if (i == this->currentMenu->getSelected()) {
#ifdef FC_USE_SDL_GPU
GPU_Rect rect = { std::get<0>(coordinates) - 10, std::get<1>(coordinates),
std::get<0>(dimensions) + 20, std::get<1>(dimensions) };
SDL_Color color = { 0xFF, 0xFF, 0xFF, 0xFF };
GPU_Rectangle2(renderer.getRenderer(), rect, color);
#else
SDL_Rect rect;
rect.w = std::get<0>(dimensions) + 20;
rect.h = std::get<1>(dimensions);
rect.x = std::get<0>(coordinates) - 10;
rect.y = std::get<1>(coordinates);
renderer.setDrawColor(0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderDrawRect(renderer.getRenderer(), &rect);
#endif
}

coordinates = std::pair<float, float>(
Expand Down
98 changes: 90 additions & 8 deletions Includes/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#ifdef NXDK
#include <hal/video.h>
#include "nxdk-sdl-gpu/nxdkSDLGPU.h"
#endif

// One line of text with the default font is 31 pixels high.
Expand All @@ -18,6 +19,9 @@ Renderer::Renderer() {
height = xmode.height;
width = xmode.width;
windowFlags = SDL_WINDOW_SHOWN;
#ifdef FC_USE_SDL_GPU
windowFlags |= SDL_WINDOW_OPENGL;
#endif
#else
height = 480;
width = 640;
Expand All @@ -33,14 +37,24 @@ Renderer::Renderer() {

Renderer::~Renderer() {
if (background != nullptr) {
#ifdef FC_USE_SDL_GPU
GPU_FreeImage(background);
#else
SDL_DestroyTexture(background);
#endif
}
if (renderer != nullptr) {
#ifdef FC_USE_SDL_GPU
GPU_FreeTarget(renderer);
#else
SDL_DestroyRenderer(renderer);
#endif
}
#ifndef FC_USE_SDL_GPU
if (window != nullptr) {
SDL_DestroyWindow(window);
}
#endif
}

int Renderer::init() {
Expand All @@ -49,11 +63,24 @@ int Renderer::init() {
if (window == nullptr) {
return 1;
}

#ifdef FC_USE_SDL_GPU
GPU_SetInitWindow(SDL_GetWindowID(window));
renderer = GPU_Init(width, height, GPU_DEFAULT_INIT_FLAGS);
if (!renderer) {
return 1;
}
#else
renderer = SDL_CreateRenderer(window, -1, renderFlags);
#endif
if (renderer == nullptr) {
return 2;
}
SDL_SetRenderDrawBlendMode(getRenderer(), SDL_BLENDMODE_BLEND);
#ifdef FC_USE_SDL_GPU
GPU_SetShapeBlendMode(GPU_BLEND_NORMAL);
#else
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
#endif
setDrawColor();
clear();
return 0;
Expand All @@ -72,7 +99,26 @@ int Renderer::init(const char* bgpath) {
InfoLog::outputLine(InfoLog::ERROR, "Creating background surface failed.\n");
return 3;
}
#ifdef FC_USE_SDL_GPU
// OpenGL wants the surface in BGR format, but pbgl does not currently implement a
// conversion. Since IMG_Load is only used in this one place, it is converted here
// manually.
auto srcFormat = static_cast<SDL_PixelFormatEnum>(bgsurf->format->format);
switch (srcFormat) {
case SDL_PIXELFORMAT_RGB24:
case SDL_PIXELFORMAT_RGB888:
case SDL_PIXELFORMAT_RGBA32:
case SDL_PIXELFORMAT_RGBA8888:
bgsurf = convertRGBToBGR(bgsurf);
break;
default:
// Ignore surfaces that may already be BGR.
break;
}
background = GPU_CopyImageFromSurface(bgsurf);
#else
background = SDL_CreateTextureFromSurface(renderer, bgsurf);
#endif
SDL_FreeSurface(bgsurf);
if (background == nullptr) {
InfoLog::outputLine(InfoLog::ERROR, "Creating background texture failed.\n");
Expand All @@ -82,44 +128,80 @@ int Renderer::init(const char* bgpath) {
}

int Renderer::clear() {
#ifdef FC_USE_SDL_GPU
GPU_ClearColor(renderer, drawColor);
return 0;
#else
int ret = SDL_RenderClear(renderer);
return ret;
#endif
}

void Renderer::flip() {
#ifdef FC_USE_SDL_GPU
GPU_Flip(renderer);
#else
setDrawColor(0, 0, 0, 0xFF);
SDL_RenderDrawRect(renderer, nullptr);
setDrawColor();
SDL_RenderPresent(renderer);
#ifdef NXDK
XVideoWaitForVBlank();
#endif
}

int Renderer::setDrawColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
#ifdef FC_USE_SDL_GPU
drawColor.r = r;
drawColor.g = g;
drawColor.b = b;
drawColor.a = a;
return 0;
#else
return SDL_SetRenderDrawColor(renderer, r, g, b, a);
#endif
}

void Renderer::drawTexture(SDL_Texture* tex, SDL_Rect& src, SDL_Rect& dst) {
void Renderer::drawTexture(NX_Texture* tex, NX_Rect& src, NX_Rect& dst) {
#ifdef FC_USE_SDL_GPU
GPU_BlitRect(tex, &src, renderer, &dst);
#else
SDL_RenderCopy(renderer, tex, &src, &dst);
#endif
}

void Renderer::drawTexture(SDL_Texture* tex, SDL_Rect& dst) {
void Renderer::drawTexture(NX_Texture* tex, NX_Rect& dst) {
#ifdef FC_USE_SDL_GPU
GPU_BlitRect(tex, nullptr, renderer, &dst);
#else
SDL_RenderCopy(renderer, tex, nullptr, &dst);
#endif
}

void Renderer::drawTexture(SDL_Texture* tex, int x, int y) {
SDL_Rect dst = { x, y, 0, 0 };
void Renderer::drawTexture(NX_Texture* tex, int x, int y) {
#ifdef FC_USE_SDL_GPU
NX_Rect dst = { static_cast<float>(x), static_cast<float>(y), static_cast<float>(tex->w),
static_cast<float>(tex->h) };
#else
NX_Rect dst = { x, y, 0, 0 };
SDL_QueryTexture(tex, nullptr, nullptr, &dst.w, &dst.h);
#endif
drawTexture(tex, dst);
}

void Renderer::fillRectangle(const SDL_Rect& dst) {
void Renderer::fillRectangle(const NX_Rect& dst) {
#ifdef FC_USE_SDL_GPU
GPU_RectangleFilled2(renderer, dst, drawColor);
#else
SDL_RenderFillRect(renderer, &dst);
#endif
}

void Renderer::fillRectangle(const SDL_FRect& dst) {
#ifdef FC_USE_SDL_GPU
GPU_Rect rect = { dst.x, dst.y, dst.w, dst.h };
GPU_RectangleFilled2(renderer, rect, drawColor);
#else
SDL_RenderFillRectF(renderer, &dst);
#endif
}

void Renderer::blitSurface(SDL_Surface* bg, SDL_Surface* fg, int offset) {
Expand Down
43 changes: 35 additions & 8 deletions Includes/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,24 @@
#include <SDL.h>
#include <vector>

int min(int lhs, int rhs);
int max(int lhs, int rhs);
// clang-format off
#ifdef FC_USE_SDL_GPU
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
#include "SDL_gpu.h"
#pragma clang diagnostic pop
#endif
// clang-format on

#ifdef FC_USE_SDL_GPU
typedef GPU_Image NX_Texture;
typedef GPU_Rect NX_Rect;
typedef GPU_Target NX_Target;
#else
typedef SDL_Texture NX_Texture;
typedef SDL_Rect NX_Rect;
typedef SDL_Renderer NX_Target;
#endif

class Renderer {
public:
Expand All @@ -17,28 +33,35 @@ class Renderer {
int clear();
void flip();

#ifdef FC_USE_SDL_GPU
GPU_Target* getRenderer() { return renderer; }
#else
SDL_Renderer* getRenderer() { return renderer; }
#endif
int getWidth() const { return width; }
int getHeight() const { return height; }

int setDrawColor(uint8_t r = 0x40, uint8_t g = 0x40, uint8_t b = 0xE0, uint8_t a = 0x00);

void drawTexture(SDL_Texture* tex, SDL_Rect& src, SDL_Rect& dst);
void drawTexture(SDL_Texture* tex, SDL_Rect& dst);
void drawTexture(SDL_Texture* tex, int x, int y);
void drawTexture(NX_Texture* tex, NX_Rect& src, NX_Rect& dst);
void drawTexture(NX_Texture* tex, NX_Rect& dst);
void drawTexture(NX_Texture* tex, int x, int y);

void fillRectangle(const SDL_Rect& dst);
void fillRectangle(const NX_Rect& dst);
void fillRectangle(const SDL_FRect& dst);

void blitSurface(SDL_Surface* bg, SDL_Surface* fg, int offset);

void drawBackground();

private:
SDL_Renderer* renderer = nullptr;
NX_Target* renderer = nullptr;
NX_Texture* background = nullptr;

SDL_Window* window = nullptr;
SDL_Texture* background = nullptr;
#ifndef FC_USE_SDL_GPU
Uint32 renderFlags = 0;
#endif
Uint32 windowFlags = 0;

int height = 0;
Expand All @@ -48,6 +71,10 @@ class Renderer {
size_t menuItemCount = 0;
size_t lowerHalf = 0;
size_t upperHalf = 0;

#ifdef FC_USE_SDL_GPU
SDL_Color drawColor;
#endif
};

#endif
Loading

0 comments on commit eccba7a

Please sign in to comment.