diff --git a/include/PICA/regs.hpp b/include/PICA/regs.hpp index 657fb6f3..9a011cc4 100644 --- a/include/PICA/regs.hpp +++ b/include/PICA/regs.hpp @@ -131,16 +131,20 @@ namespace PICA { } enum class ColorFmt : u32 { - RGBA8 = 0, - BGR8 = 1, - RGB5A1 = 2, - RGB565 = 3, - RGBA4 = 4, - - // Technically selectable, but their function is unknown - Unknown5 = 5, - Unknown6 = 6, - Unknown7 = 7, + RGBA8 = 0x0, + RGB8 = 0x1, + RGBA5551 = 0x2, + RGB565 = 0x3, + RGBA4 = 0x4, + IA8 = 0x5, + RG8 = 0x6, + I8 = 0x7, + A8 = 0x8, + IA4 = 0x9, + I4 = 0xA, + A4 = 0xB, + ETC1 = 0xC, + ETC1A4 = 0xD, }; enum class DepthFmt : u32 { @@ -150,6 +154,27 @@ namespace PICA { Depth24Stencil8 = 3, }; + // Returns the string representation of a texture format + inline constexpr const char* textureFormatToString(ColorFmt fmt) { + switch (fmt) { + case ColorFmt::RGBA8: return "RGBA8"; + case ColorFmt::RGB8: return "RGB8"; + case ColorFmt::RGBA5551: return "RGBA5551"; + case ColorFmt::RGB565: return "RGB565"; + case ColorFmt::RGBA4: return "RGBA4"; + case ColorFmt::IA8: return "IA8"; + case ColorFmt::RG8: return "RG8"; + case ColorFmt::I8: return "I8"; + case ColorFmt::A8: return "A8"; + case ColorFmt::IA4: return "IA4"; + case ColorFmt::I4: return "I4"; + case ColorFmt::A4: return "A4"; + case ColorFmt::ETC1: return "ETC1"; + case ColorFmt::ETC1A4: return "ETC1A4"; + default: return "Unknown"; + } + } + inline constexpr bool hasStencil(DepthFmt format) { return format == PICA::DepthFmt::Depth24Stencil8; } // Size occupied by each pixel in bytes @@ -157,7 +182,7 @@ namespace PICA { // All formats are 16BPP except for RGBA8 (32BPP) and BGR8 (24BPP) inline constexpr usize sizePerPixel(ColorFmt format) { switch (format) { - case ColorFmt::BGR8: return 3; + case ColorFmt::RGB8: return 3; case ColorFmt::RGBA8: return 4; default: return 2; } diff --git a/include/renderer_gl/textures.hpp b/include/renderer_gl/textures.hpp index 3cf7871c..4e54de2d 100644 --- a/include/renderer_gl/textures.hpp +++ b/include/renderer_gl/textures.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include "PICA/regs.hpp" #include "boost/icl/interval.hpp" #include "helpers.hpp" #include "opengl.hpp" @@ -9,28 +10,9 @@ template using Interval = boost::icl::right_open_interval; struct Texture { - enum class Formats : u32 { - RGBA8 = 0, - RGB8 = 1, - RGBA5551 = 2, - RGB565 = 3, - RGBA4 = 4, - IA8 = 5, - RG8 = 6, - I8 = 7, - A8 = 8, - IA4 = 9, - I4 = 10, - A4 = 11, - ETC1 = 12, - ETC1A4 = 13, - - Trash1 = 14, Trash2 = 15 // TODO: What are these? - }; - u32 location; u32 config; // Magnification/minification filter, wrapping configs, etc - Formats format; + PICA::ColorFmt format; OpenGL::uvec2 size; bool valid; @@ -41,7 +23,7 @@ struct Texture { Texture() : valid(false) {} - Texture(u32 loc, Formats format, u32 x, u32 y, u32 config, bool valid = true) + Texture(u32 loc, PICA::ColorFmt format, u32 x, u32 y, u32 config, bool valid = true) : location(loc), format(format), size({x, y}), config(config), valid(valid) { u64 endLoc = (u64)loc + sizeInBytes(); @@ -62,7 +44,7 @@ struct Texture { void free(); u64 sizeInBytes(); - u32 decodeTexel(u32 u, u32 v, Formats fmt, const void* data); + u32 decodeTexel(u32 u, u32 v, PICA::ColorFmt fmt, const void* data); // Get the morton interleave offset of a texel based on its U and V values static u32 mortonInterleave(u32 u, u32 v); @@ -70,12 +52,9 @@ struct Texture { static u32 getSwizzledOffset(u32 u, u32 v, u32 width, u32 bytesPerPixel); static u32 getSwizzledOffset_4bpp(u32 u, u32 v, u32 width); - // Returns the string representation of a texture format - static std::string textureFormatToString(Formats fmt); - // Returns the format of this texture as a string std::string formatToString() { - return textureFormatToString(format); + return PICA::textureFormatToString(format); } // Returns the texel at coordinates (u, v) of an ETC1(A4) texture diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp index ab93af73..06748708 100644 --- a/src/core/renderer_gl/renderer_gl.cpp +++ b/src/core/renderer_gl/renderer_gl.cpp @@ -322,7 +322,7 @@ void Renderer::drawVertices(PICA::PrimType primType, std::span ver const u32 addr = (regs[0x85] & 0x0FFFFFFF) << 3; const u32 format = regs[0x8E] & 0xF; - Texture targetTex(addr, static_cast(format), width, height, config); + Texture targetTex(addr, static_cast(format), width, height, config); OpenGL::Texture tex = getTexture(targetTex); tex.bind(); } diff --git a/src/core/renderer_gl/textures.cpp b/src/core/renderer_gl/textures.cpp index f59d0779..b82653d5 100644 --- a/src/core/renderer_gl/textures.cpp +++ b/src/core/renderer_gl/textures.cpp @@ -43,34 +43,34 @@ u64 Texture::sizeInBytes() { u64 pixelCount = u64(size.x()) * u64(size.y()); switch (format) { - case Formats::RGBA8: // 4 bytes per pixel + case PICA::ColorFmt::RGBA8: // 4 bytes per pixel return pixelCount * 4; - case Formats::RGB8: // 3 bytes per pixel + case PICA::ColorFmt::RGB8: // 3 bytes per pixel return pixelCount * 3; - case Formats::RGBA5551: // 2 bytes per pixel - case Formats::RGB565: - case Formats::RGBA4: - case Formats::RG8: - case Formats::IA8: + case PICA::ColorFmt::RGBA5551: // 2 bytes per pixel + case PICA::ColorFmt::RGB565: + case PICA::ColorFmt::RGBA4: + case PICA::ColorFmt::RG8: + case PICA::ColorFmt::IA8: return pixelCount * 2; - case Formats::A8: // 1 byte per pixel - case Formats::I8: - case Formats::IA4: + case PICA::ColorFmt::A8: // 1 byte per pixel + case PICA::ColorFmt::I8: + case PICA::ColorFmt::IA4: return pixelCount; - case Formats::I4: // 4 bits per pixel - case Formats::A4: + case PICA::ColorFmt::I4: // 4 bits per pixel + case PICA::ColorFmt::A4: return pixelCount / 2; - case Formats::ETC1: // Compressed formats - case Formats::ETC1A4: { + case PICA::ColorFmt::ETC1: // Compressed formats + case PICA::ColorFmt::ETC1A4: { // Number of 4x4 tiles const u64 tileCount = pixelCount / 16; // Tiles are 8 bytes each on ETC1 and 16 bytes each on ETC1A4 - const u64 tileSize = format == Formats::ETC1 ? 8 : 16; + const u64 tileSize = format == PICA::ColorFmt::ETC1 ? 8 : 16; return tileCount * tileSize; } @@ -111,9 +111,9 @@ u32 Texture::getSwizzledOffset_4bpp(u32 u, u32 v, u32 width) { // Get the texel at position (u, v) // fmt: format of the texture // data: texture data of the texture -u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) { +u32 Texture::decodeTexel(u32 u, u32 v, PICA::ColorFmt fmt, const void* data) { switch (fmt) { - case Formats::RGBA4: { + case PICA::ColorFmt::RGBA4: { u32 offset = getSwizzledOffset(u, v, size.u(), 2); auto ptr = static_cast(data); u16 texel = u16(ptr[offset]) | (u16(ptr[offset + 1]) << 8); @@ -126,7 +126,7 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) { return (alpha << 24) | (b << 16) | (g << 8) | r; } - case Formats::RGBA5551: { + case PICA::ColorFmt::RGBA5551: { u32 offset = getSwizzledOffset(u, v, size.u(), 2); auto ptr = static_cast(data); u16 texel = u16(ptr[offset]) | (u16(ptr[offset + 1]) << 8); @@ -139,7 +139,7 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) { return (alpha << 24) | (b << 16) | (g << 8) | r; } - case Formats::RGB565: { + case PICA::ColorFmt::RGB565: { u32 offset = getSwizzledOffset(u, v, size.u(), 2); auto ptr = static_cast(data); u16 texel = u16(ptr[offset]) | (u16(ptr[offset + 1]) << 8); @@ -151,7 +151,7 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) { return (0xff << 24) | (b << 16) | (g << 8) | r; } - case Formats::RG8: { + case PICA::ColorFmt::RG8: { u32 offset = getSwizzledOffset(u, v, size.u(), 2); auto ptr = static_cast(data); @@ -162,7 +162,7 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) { return (0xff << 24) | (b << 16) | (g << 8) | r; } - case Formats::RGB8: { + case PICA::ColorFmt::RGB8: { u32 offset = getSwizzledOffset(u, v, size.u(), 3); auto ptr = static_cast(data); @@ -173,7 +173,7 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) { return (0xff << 24) | (b << 16) | (g << 8) | r; } - case Formats::RGBA8: { + case PICA::ColorFmt::RGBA8: { u32 offset = getSwizzledOffset(u, v, size.u(), 4); auto ptr = static_cast(data); @@ -185,7 +185,7 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) { return (alpha << 24) | (b << 16) | (g << 8) | r; } - case Formats::IA4: { + case PICA::ColorFmt::IA4: { u32 offset = getSwizzledOffset(u, v, size.u(), 1); auto ptr = static_cast(data); @@ -197,7 +197,7 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) { return (alpha << 24) | (intensity << 16) | (intensity << 8) | intensity; } - case Formats::A4: { + case PICA::ColorFmt::A4: { u32 offset = getSwizzledOffset_4bpp(u, v, size.u()); auto ptr = static_cast(data); @@ -209,7 +209,7 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) { return (alpha << 24) | (0 << 16) | (0 << 8) | 0; } - case Formats::A8: { + case PICA::ColorFmt::A8: { u32 offset = getSwizzledOffset(u, v, size.u(), 1); auto ptr = static_cast(data); const u8 alpha = ptr[offset]; @@ -218,7 +218,7 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) { return (alpha << 24) | (0 << 16) | (0 << 8) | 0; } - case Formats::I4: { + case PICA::ColorFmt::I4: { u32 offset = getSwizzledOffset_4bpp(u, v, size.u()); auto ptr = static_cast(data); @@ -230,7 +230,7 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) { return (0xff << 24) | (intensity << 16) | (intensity << 8) | intensity; } - case Formats::I8: { + case PICA::ColorFmt::I8: { u32 offset = getSwizzledOffset(u, v, size.u(), 1); auto ptr = static_cast(data); const u8 intensity = ptr[offset]; @@ -239,7 +239,7 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) { return (0xff << 24) | (intensity << 16) | (intensity << 8) | intensity; } - case Formats::IA8: { + case PICA::ColorFmt::IA8: { u32 offset = getSwizzledOffset(u, v, size.u(), 2); auto ptr = static_cast(data); @@ -249,8 +249,8 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) { return (alpha << 24) | (intensity << 16) | (intensity << 8) | intensity; } - case Formats::ETC1: return getTexelETC(false, u, v, size.u(), data); - case Formats::ETC1A4: return getTexelETC(true, u, v, size.u(), data); + case PICA::ColorFmt::ETC1: return getTexelETC(false, u, v, size.u(), data); + case PICA::ColorFmt::ETC1A4: return getTexelETC(true, u, v, size.u(), data); default: Helpers::panic("[Texture::DecodeTexel] Unimplemented format = %d", static_cast(fmt)); @@ -271,24 +271,4 @@ void Texture::decodeTexture(const void* data) { texture.bind(); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size.u(), size.v(), GL_RGBA, GL_UNSIGNED_BYTE, decoded.data()); -} - -std::string Texture::textureFormatToString(Texture::Formats fmt) { - switch (fmt) { - case Formats::A4: return "A4"; - case Formats::A8: return "A8"; - case Formats::ETC1: return "ETC1"; - case Formats::ETC1A4: return "ETC1A4"; - case Formats::I4: return "I4"; - case Formats::I8: return "I8"; - case Formats::IA4: return "IA4"; - case Formats::IA8: return "IA8"; - case Formats::RG8: return "RG8"; - case Formats::RGB565: return "RGB565"; - case Formats::RGB8: return "RGB8"; - case Formats::RGBA4: return "RGBA4"; - case Formats::RGBA5551: return "RGBA5551"; - case Formats::RGBA8: return "RGBA8"; - default: return "Unknown"; - } } \ No newline at end of file