From 85a5ad70b7fa4844e37fe06463ea82d8e6f1abaf Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Thu, 5 Feb 2026 19:06:44 -0800 Subject: Expose functions for gamma correction --- src/swgfx.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'src/swgfx.c') diff --git a/src/swgfx.c b/src/swgfx.c index 153a5f4..bbf9a5b 100644 --- a/src/swgfx.c +++ b/src/swgfx.c @@ -78,6 +78,7 @@ static inline sgVec3 neg3(sgVec3 v) { return (sgVec3){-v.x, -v.y, -v.z}; } static inline sgVec3 sub3(sgVec3 a, sgVec3 b) { return (sgVec3){a.x - b.x, a.y - b.y, a.z - b.z}; } static inline sgVec3 div3(sgVec3 a, sgVec3 b) { return (sgVec3){a.x / b.x, a.y / b.y, a.z / b.z}; } static inline sgVec3 scale3(sgVec3 v, R s) { return (sgVec3){v.x * s, v.y * s, v.z * s}; } +static inline sgVec3 exp3(sgVec3 v, R exp) { return (sgVec3){powf(v.x, exp), powf(v.y, exp), powf(v.z, exp)};} static inline R dot3(sgVec3 a, sgVec3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; } static inline R normsq3(sgVec3 v) { return v.x * v.x + v.y * v.y + v.z * v.z; } static inline R norm3 (sgVec3 v) { return (R)sqrt(normsq3(v)); } @@ -268,11 +269,17 @@ static inline sgMat4 Mat4Perspective(R fovy, R aspect, R near, R far) { 0, 0, -1, 0); } +static inline sgVec3 PixelToVec3(sgPixel p) { + return (sgVec3){(R)p.r / 255.f, (R)p.g / 255.f, (R)p.b / 255.f}; +} +static inline sgPixel Vec3ToPixel(sgVec3 p, R a) { + return (sgPixel){(uint8_t)(p.x * 255.f), (uint8_t)(p.y * 255.f), (uint8_t)(p.z * 255.f), (uint8_t)(a * 255.f)}; +} static inline sgVec4 PixelToVec4(sgPixel p) { return (sgVec4){(R)p.r / 255.f, (R)p.g / 255.f, (R)p.b / 255.f, (R)p.a / 255.f}; } static inline sgPixel Vec4ToPixel(sgVec4 p) { - return (sgPixel){(int)(p.x * 255.f), (int)(p.y * 255.f), (int)(p.z * 255.f), (int)(p.w * 255.f)}; + return (sgPixel){(uint8_t)(p.x * 255.f), (uint8_t)(p.y * 255.f), (uint8_t)(p.z * 255.f), (uint8_t)(p.w * 255.f)}; } #ifndef _NDEBUG @@ -729,6 +736,11 @@ void sgDel(swgfx** ppSwgfx) { } } +sgPixel* sgColourBuffer(swgfx* gfx) { + assert(gfx); + return gfx->colour; +} + void sgPresent(swgfx* gfx, sgVec2i dimensions, sgScreenPixel* screen) { assert(gfx); assert(screen); @@ -891,6 +903,26 @@ void sgTrianglesIndexedNonUniform(swgfx* gfx, size_t numTris, const sgTriIdx* tr } } +static void ImageExp(sgPixel* pixels, int width, int height, R exp) { + assert(pixels); + for (int i = 0; i < width * height; ++i) { + sgPixel* p = &pixels[i]; + *p = Vec3ToPixel(exp3(PixelToVec3(*p), exp), p->a); + } +} + +void sgGamma(swgfx* gfx, sgPixel* pixels, int width, int height) { + assert(gfx); + assert(pixels); + ImageExp(pixels, width, height, 2.2f); +} + +void sgGammaInv(swgfx* gfx, sgPixel* pixels, int width, int height) { + assert(gfx); + assert(pixels); + ImageExp(pixels, width, height, 1.0f/2.2f); +} + static bool ViewportWithinBuffer(swgfx* gfx) { assert(gfx); const sgViewport_t vp = gfx->viewport; -- cgit v1.2.3