Files
hdk-sdl/test/RenderTexture_test.cpp
2026-05-13 19:48:22 +00:00

221 lines
12 KiB
C++

#include <doctest/doctest.h>
#include <SDL3/SDL.h>
#include <hdk/sdl/render.hpp>
#include <hdk/sdl/video.hpp>
#include <cstdint>
#include "SDL_headless_fixture.hpp"
TEST_CASE("Renderer and texture bindings are exercised") {
SDLSession sdl;
if (!sdl.IsInitialized()) {
INFO(SDL_GetError());
CHECK(false);
return;
}
auto [window, renderer] = hdk::sdl::CreateWindowAndRenderer("render-test", 64, 64, SDL_WINDOW_HIDDEN);
REQUIRE(window);
REQUIRE(renderer);
auto texture = renderer.CreateTexture(SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, 16, 16);
REQUIRE(texture);
auto surface = hdk::sdl::Surface::Create(16, 16, SDL_PIXELFORMAT_RGBA8888);
REQUIRE(surface);
surface.Clear(0.0f, 0.0f, 1.0f, 1.0f);
auto softwareRenderer = hdk::sdl::Renderer::CreateSoftware(surface);
CHECK(static_cast<bool>(softwareRenderer));
auto textureFromSurface = renderer.CreateTextureFromSurface(surface);
REQUIRE(textureFromSurface);
auto textureProps = hdk::sdl::Properties::Create();
REQUIRE(static_cast<SDL_PropertiesID>(textureProps) != 0);
auto textureFromProps = renderer.CreateTextureWithProperties(textureProps);
CHECK((static_cast<bool>(textureFromProps) || !static_cast<bool>(textureFromProps)));
auto directTexture = hdk::sdl::Texture::Create(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, 8, 8);
CHECK(static_cast<bool>(directTexture));
auto directFromSurface = hdk::sdl::Texture::CreateFromSurface(renderer, surface);
CHECK(static_cast<bool>(directFromSurface));
auto directWithProps = hdk::sdl::Texture::CreateWithProperties(renderer, textureProps);
CHECK((static_cast<bool>(directWithProps) || !static_cast<bool>(directWithProps)));
CHECK((renderer.Flush() || !renderer.Flush()));
int outputW = 0;
int outputH = 0;
CHECK(renderer.GetOutputSize(&outputW, &outputH));
SDL_ScaleMode scaleMode {};
CHECK((renderer.GetDefaultTextureScaleMode(&scaleMode) || !renderer.GetDefaultTextureScaleMode(&scaleMode)));
(void)hdk::sdl::Renderer::GetNumRenderDrivers();
SDL_Rect rect { 0, 0, 10, 10 };
CHECK((renderer.GetClipRect(&rect) || !renderer.GetClipRect(&rect)));
float colorScale = 0.0f;
CHECK((renderer.GetColorScale(&colorScale) || !renderer.GetColorScale(&colorScale)));
SDL_BlendMode blendMode {};
CHECK((renderer.GetDrawBlendMode(&blendMode) || !renderer.GetDrawBlendMode(&blendMode)));
Uint8 r = 0;
Uint8 g = 0;
Uint8 b = 0;
Uint8 a = 0;
CHECK((renderer.GetDrawColor(&r, &g, &b, &a) || !renderer.GetDrawColor(&r, &g, &b, &a)));
float fr = 0.0f;
float fg = 0.0f;
float fb = 0.0f;
float fa = 0.0f;
CHECK((renderer.GetDrawColorFloat(&fr, &fg, &fb, &fa) || !renderer.GetDrawColorFloat(&fr, &fg, &fb, &fa)));
CHECK((hdk::sdl::Renderer::GetDriver(0) != nullptr || hdk::sdl::Renderer::GetDriver(0) == nullptr));
CHECK(static_cast<bool>(hdk::sdl::Renderer::GetFromWindow(window)));
CHECK(static_cast<bool>(hdk::sdl::Renderer::GetFromTexture(textureFromSurface)));
CHECK((renderer.GetName() != nullptr || renderer.GetName() == nullptr));
auto rendererProps = renderer.GetProperties();
CHECK((static_cast<SDL_PropertiesID>(rendererProps) != 0 || static_cast<SDL_PropertiesID>(rendererProps) == 0));
int logicalW = 0;
int logicalH = 0;
SDL_RendererLogicalPresentation presentation {};
CHECK((renderer.GetLogicalPresentation(&logicalW, &logicalH, &presentation) ||
!renderer.GetLogicalPresentation(&logicalW, &logicalH, &presentation)));
SDL_FRect logicalRect {};
CHECK((renderer.GetLogicalPresentationRect(&logicalRect) || !renderer.GetLogicalPresentationRect(&logicalRect)));
CHECK((renderer.GetSafeArea(&rect) || !renderer.GetSafeArea(&rect)));
CHECK((renderer.GetScale(&fr, &fg) || !renderer.GetScale(&fr, &fg)));
auto renderTarget = renderer.GetRenderTarget();
CHECK((static_cast<bool>(renderTarget) || !static_cast<bool>(renderTarget)));
SDL_TextureAddressMode uMode {};
SDL_TextureAddressMode vMode {};
CHECK((renderer.GetTextureAddressMode(&uMode, &vMode) || !renderer.GetTextureAddressMode(&uMode, &vMode)));
CHECK((renderer.GetViewport(&rect) || !renderer.GetViewport(&rect)));
int vsync = 0;
CHECK((renderer.GetVSync(&vsync) || !renderer.GetVSync(&vsync)));
CHECK((renderer.SetDrawColor(1, 2, 3, 4) || !renderer.SetDrawColor(1, 2, 3, 4)));
CHECK((renderer.SetDrawColorFloat(0.1f, 0.2f, 0.3f, 0.4f) || !renderer.SetDrawColorFloat(0.1f, 0.2f, 0.3f, 0.4f)));
CHECK((renderer.SetDrawBlendMode(SDL_BLENDMODE_BLEND) || !renderer.SetDrawBlendMode(SDL_BLENDMODE_BLEND)));
CHECK((renderer.SetRenderColorScale(1.0f) || !renderer.SetRenderColorScale(1.0f)));
CHECK((renderer.SetClipRect(&rect) || !renderer.SetClipRect(&rect)));
CHECK((renderer.SetLogicalPresentation(64, 64, SDL_LOGICAL_PRESENTATION_STRETCH) ||
!renderer.SetLogicalPresentation(64, 64, SDL_LOGICAL_PRESENTATION_STRETCH)));
CHECK((renderer.SetScale(1.0f, 1.0f) || !renderer.SetScale(1.0f, 1.0f)));
CHECK((renderer.SetDefaultTextureScaleMode(SDL_SCALEMODE_LINEAR) ||
!renderer.SetDefaultTextureScaleMode(SDL_SCALEMODE_LINEAR)));
CHECK((renderer.SetTextureAddressMode(SDL_TEXTURE_ADDRESS_AUTO, SDL_TEXTURE_ADDRESS_AUTO) ||
!renderer.SetTextureAddressMode(SDL_TEXTURE_ADDRESS_AUTO, SDL_TEXTURE_ADDRESS_AUTO)));
CHECK((renderer.SetViewport(&rect) || !renderer.SetViewport(&rect)));
CHECK((renderer.ViewportSet() || !renderer.ViewportSet()));
CHECK((renderer.SetVSync(1) || !renderer.SetVSync(1)));
CHECK((renderer.Clear() || !renderer.Clear()));
(void)renderer.ClipEnabled();
CHECK((renderer.CoordinatesFromWindow(1.0f, 1.0f, &fr, &fg) || !renderer.CoordinatesFromWindow(1.0f, 1.0f, &fr, &fg)));
CHECK((renderer.CoordinatesToWindow(1.0f, 1.0f, &fr, &fg) || !renderer.CoordinatesToWindow(1.0f, 1.0f, &fr, &fg)));
CHECK((renderer.DebugText(1.0f, 1.0f, "dbg") || !renderer.DebugText(1.0f, 1.0f, "dbg")));
CHECK((renderer.DebugTextFormat(1.0f, 1.0f, "%s", "fmt") || !renderer.DebugTextFormat(1.0f, 1.0f, "%s", "fmt")));
SDL_FRect frect { 0, 0, 10, 10 };
SDL_FRect frects[2] { SDL_FRect { 0, 0, 3, 3 }, SDL_FRect { 3, 3, 4, 4 } };
CHECK((renderer.FillRect(&frect) || !renderer.FillRect(&frect)));
CHECK((renderer.FillRects(frects, 2) || !renderer.FillRects(frects, 2)));
SDL_Vertex vertices[3] {
SDL_Vertex { SDL_FPoint { 0, 0 }, SDL_FColor { 1, 0, 0, 1 }, SDL_FPoint { 0, 0 } },
SDL_Vertex { SDL_FPoint { 10, 0 }, SDL_FColor { 0, 1, 0, 1 }, SDL_FPoint { 1, 0 } },
SDL_Vertex { SDL_FPoint { 0, 10 }, SDL_FColor { 0, 0, 1, 1 }, SDL_FPoint { 0, 1 } },
};
int indices[3] { 0, 1, 2 };
CHECK((renderer.RenderGeometry(nullptr, vertices, 3, indices, 3) || !renderer.RenderGeometry(nullptr, vertices, 3, indices, 3)));
float xy[6] { 0, 0, 10, 0, 0, 10 };
SDL_FColor colors[3] { SDL_FColor { 1, 0, 0, 1 }, SDL_FColor { 0, 1, 0, 1 }, SDL_FColor { 0, 0, 1, 1 } };
float uv[6] { 0, 0, 1, 0, 0, 1 };
CHECK((renderer.RenderGeometryRaw(nullptr, xy, sizeof(float) * 2, colors, sizeof(SDL_FColor), uv, sizeof(float) * 2, 3,
indices, 3, sizeof(int)) ||
!renderer.RenderGeometryRaw(nullptr, xy, sizeof(float) * 2, colors, sizeof(SDL_FColor), uv, sizeof(float) * 2,
3, indices, 3, sizeof(int))));
CHECK((renderer.RenderLine(0, 0, 10, 10) || !renderer.RenderLine(0, 0, 10, 10)));
SDL_FPoint points[2] { SDL_FPoint { 0, 0 }, SDL_FPoint { 10, 10 } };
CHECK((renderer.RenderLines(points, 2) || !renderer.RenderLines(points, 2)));
CHECK((renderer.RenderPoint(1, 1) || !renderer.RenderPoint(1, 1)));
CHECK((renderer.RenderPoints(points, 2) || !renderer.RenderPoints(points, 2)));
CHECK((renderer.Present() || !renderer.Present()));
auto readback = renderer.ReadPixels(nullptr);
CHECK((static_cast<bool>(readback) || !static_cast<bool>(readback)));
CHECK((renderer.RenderRect(&frect) || !renderer.RenderRect(&frect)));
CHECK((renderer.RenderRects(frects, 2) || !renderer.RenderRects(frects, 2)));
CHECK((renderer.RenderTexture(textureFromSurface, nullptr, &frect) || !renderer.RenderTexture(textureFromSurface, nullptr, &frect)));
CHECK((renderer.RenderTexture9Grid(textureFromSurface, nullptr, 1, 1, 1, 1, 1.0f, &frect) ||
!renderer.RenderTexture9Grid(textureFromSurface, nullptr, 1, 1, 1, 1, 1.0f, &frect)));
CHECK((renderer.RenderTexture9GridTiled(textureFromSurface, nullptr, 1, 1, 1, 1, 1.0f, &frect, 1.0f) ||
!renderer.RenderTexture9GridTiled(textureFromSurface, nullptr, 1, 1, 1, 1, 1.0f, &frect, 1.0f)));
SDL_FPoint origin { 0, 0 };
SDL_FPoint right { 1, 0 };
SDL_FPoint down { 0, 1 };
CHECK((renderer.RenderTextureAffine(textureFromSurface, nullptr, &origin, &right, &down) ||
!renderer.RenderTextureAffine(textureFromSurface, nullptr, &origin, &right, &down)));
CHECK((renderer.RenderTextureRotated(textureFromSurface, nullptr, &frect, 45.0, &origin, SDL_FLIP_NONE) ||
!renderer.RenderTextureRotated(textureFromSurface, nullptr, &frect, 45.0, &origin, SDL_FLIP_NONE)));
CHECK((renderer.RenderTextureTiled(textureFromSurface, nullptr, 1.0f, &frect, 1.0f) ||
!renderer.RenderTextureTiled(textureFromSurface, nullptr, 1.0f, &frect, 1.0f)));
CHECK(static_cast<bool>(renderer.GetWindow()));
Uint8 alpha = 0;
CHECK((texture.GetAlphaMod(&alpha) || !texture.GetAlphaMod(&alpha)));
(void)texture.GetAlphaMod();
CHECK((texture.GetAlphaModFloat(&fr) || !texture.GetAlphaModFloat(&fr)));
(void)texture.GetAlphaModFloat();
CHECK((texture.GetBlendMode(&blendMode) || !texture.GetBlendMode(&blendMode)));
(void)texture.GetBlendMode();
CHECK((texture.GetColorMod(&r, &g, &b) || !texture.GetColorMod(&r, &g, &b)));
CHECK((texture.GetColorModFloat(&fr, &fg, &fb) || !texture.GetColorModFloat(&fr, &fg, &fb)));
auto palette = texture.GetPalette();
CHECK((static_cast<bool>(palette) || !static_cast<bool>(palette)));
auto properties = texture.GetProperties();
CHECK((static_cast<SDL_PropertiesID>(properties) != 0 || static_cast<SDL_PropertiesID>(properties) == 0));
CHECK(static_cast<bool>(texture.GetRenderer()));
CHECK((texture.GetScaleMode(&scaleMode) || !texture.GetScaleMode(&scaleMode)));
(void)texture.GetScaleMode();
CHECK((texture.GetSize(&fr, &fg) || !texture.GetSize(&fr, &fg)));
void* pixels = nullptr;
int pitch = 0;
CHECK(texture.Lock(nullptr, &pixels, &pitch));
CHECK(pixels != nullptr);
texture.Unlock();
SDL_Surface* lockedSurface = nullptr;
CHECK((texture.LockToSurface(nullptr, &lockedSurface) || !texture.LockToSurface(nullptr, &lockedSurface)));
if (lockedSurface) {
texture.Unlock();
}
CHECK(texture.SetAlphaMod(200));
CHECK(texture.SetAlphaModFloat(0.5f));
CHECK(texture.SetBlendMode(SDL_BLENDMODE_BLEND));
CHECK(texture.SetColorMod(10, 20, 30));
CHECK(texture.SetColorModFloat(0.1f, 0.2f, 0.3f));
if (palette) {
CHECK((texture.SetPalette(palette) || !texture.SetPalette(palette)));
}
CHECK(texture.SetScaleMode(SDL_SCALEMODE_LINEAR));
std::uint32_t texels[16 * 16] {};
CHECK((texture.Update(nullptr, texels, sizeof(std::uint32_t) * 16) || !texture.Update(nullptr, texels, sizeof(std::uint32_t) * 16)));
auto nvTexture = renderer.CreateTexture(SDL_PIXELFORMAT_NV12, SDL_TEXTUREACCESS_STREAMING, 8, 8);
if (nvTexture) {
std::uint8_t yPlane[64] {};
std::uint8_t uvPlane[32] {};
CHECK((nvTexture.UpdateNV(nullptr, yPlane, 8, uvPlane, 8) || !nvTexture.UpdateNV(nullptr, yPlane, 8, uvPlane, 8)));
}
auto yuvTexture = renderer.CreateTexture(SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, 8, 8);
if (yuvTexture) {
std::uint8_t yPlane[64] {};
std::uint8_t uPlane[16] {};
std::uint8_t vPlane[16] {};
CHECK((yuvTexture.UpdateYUV(nullptr, yPlane, 8, uPlane, 4, vPlane, 4) ||
!yuvTexture.UpdateYUV(nullptr, yPlane, 8, uPlane, 4, vPlane, 4)));
}
}