diff options
| author | 3gg <3gg@shellblade.net> | 2026-02-05 19:06:44 -0800 |
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2026-02-05 19:06:44 -0800 |
| commit | 85a5ad70b7fa4844e37fe06463ea82d8e6f1abaf (patch) | |
| tree | 3b2cea07437cd8d239cac5c843a7e67f7d8d0480 /src | |
| parent | d44df852bbdcb58d634413d69eaa288a7b4573f3 (diff) | |
Expose functions for gamma correction
Diffstat (limited to 'src')
| -rw-r--r-- | src/swgfx.c | 34 |
1 files changed, 33 insertions, 1 deletions
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}; } | |||
| 78 | static inline sgVec3 sub3(sgVec3 a, sgVec3 b) { return (sgVec3){a.x - b.x, a.y - b.y, a.z - b.z}; } | 78 | static inline sgVec3 sub3(sgVec3 a, sgVec3 b) { return (sgVec3){a.x - b.x, a.y - b.y, a.z - b.z}; } |
| 79 | static inline sgVec3 div3(sgVec3 a, sgVec3 b) { return (sgVec3){a.x / b.x, a.y / b.y, a.z / b.z}; } | 79 | static inline sgVec3 div3(sgVec3 a, sgVec3 b) { return (sgVec3){a.x / b.x, a.y / b.y, a.z / b.z}; } |
| 80 | static inline sgVec3 scale3(sgVec3 v, R s) { return (sgVec3){v.x * s, v.y * s, v.z * s}; } | 80 | static inline sgVec3 scale3(sgVec3 v, R s) { return (sgVec3){v.x * s, v.y * s, v.z * s}; } |
| 81 | static inline sgVec3 exp3(sgVec3 v, R exp) { return (sgVec3){powf(v.x, exp), powf(v.y, exp), powf(v.z, exp)};} | ||
| 81 | static inline R dot3(sgVec3 a, sgVec3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; } | 82 | static inline R dot3(sgVec3 a, sgVec3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; } |
| 82 | static inline R normsq3(sgVec3 v) { return v.x * v.x + v.y * v.y + v.z * v.z; } | 83 | static inline R normsq3(sgVec3 v) { return v.x * v.x + v.y * v.y + v.z * v.z; } |
| 83 | static inline R norm3 (sgVec3 v) { return (R)sqrt(normsq3(v)); } | 84 | 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) { | |||
| 268 | 0, 0, -1, 0); | 269 | 0, 0, -1, 0); |
| 269 | } | 270 | } |
| 270 | 271 | ||
| 272 | static inline sgVec3 PixelToVec3(sgPixel p) { | ||
| 273 | return (sgVec3){(R)p.r / 255.f, (R)p.g / 255.f, (R)p.b / 255.f}; | ||
| 274 | } | ||
| 275 | static inline sgPixel Vec3ToPixel(sgVec3 p, R a) { | ||
| 276 | 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)}; | ||
| 277 | } | ||
| 271 | static inline sgVec4 PixelToVec4(sgPixel p) { | 278 | static inline sgVec4 PixelToVec4(sgPixel p) { |
| 272 | return (sgVec4){(R)p.r / 255.f, (R)p.g / 255.f, (R)p.b / 255.f, (R)p.a / 255.f}; | 279 | return (sgVec4){(R)p.r / 255.f, (R)p.g / 255.f, (R)p.b / 255.f, (R)p.a / 255.f}; |
| 273 | } | 280 | } |
| 274 | static inline sgPixel Vec4ToPixel(sgVec4 p) { | 281 | static inline sgPixel Vec4ToPixel(sgVec4 p) { |
| 275 | return (sgPixel){(int)(p.x * 255.f), (int)(p.y * 255.f), (int)(p.z * 255.f), (int)(p.w * 255.f)}; | 282 | 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)}; |
| 276 | } | 283 | } |
| 277 | 284 | ||
| 278 | #ifndef _NDEBUG | 285 | #ifndef _NDEBUG |
| @@ -729,6 +736,11 @@ void sgDel(swgfx** ppSwgfx) { | |||
| 729 | } | 736 | } |
| 730 | } | 737 | } |
| 731 | 738 | ||
| 739 | sgPixel* sgColourBuffer(swgfx* gfx) { | ||
| 740 | assert(gfx); | ||
| 741 | return gfx->colour; | ||
| 742 | } | ||
| 743 | |||
| 732 | void sgPresent(swgfx* gfx, sgVec2i dimensions, sgScreenPixel* screen) { | 744 | void sgPresent(swgfx* gfx, sgVec2i dimensions, sgScreenPixel* screen) { |
| 733 | assert(gfx); | 745 | assert(gfx); |
| 734 | assert(screen); | 746 | assert(screen); |
| @@ -891,6 +903,26 @@ void sgTrianglesIndexedNonUniform(swgfx* gfx, size_t numTris, const sgTriIdx* tr | |||
| 891 | } | 903 | } |
| 892 | } | 904 | } |
| 893 | 905 | ||
| 906 | static void ImageExp(sgPixel* pixels, int width, int height, R exp) { | ||
| 907 | assert(pixels); | ||
| 908 | for (int i = 0; i < width * height; ++i) { | ||
| 909 | sgPixel* p = &pixels[i]; | ||
| 910 | *p = Vec3ToPixel(exp3(PixelToVec3(*p), exp), p->a); | ||
| 911 | } | ||
| 912 | } | ||
| 913 | |||
| 914 | void sgGamma(swgfx* gfx, sgPixel* pixels, int width, int height) { | ||
| 915 | assert(gfx); | ||
| 916 | assert(pixels); | ||
| 917 | ImageExp(pixels, width, height, 2.2f); | ||
| 918 | } | ||
| 919 | |||
| 920 | void sgGammaInv(swgfx* gfx, sgPixel* pixels, int width, int height) { | ||
| 921 | assert(gfx); | ||
| 922 | assert(pixels); | ||
| 923 | ImageExp(pixels, width, height, 1.0f/2.2f); | ||
| 924 | } | ||
| 925 | |||
| 894 | static bool ViewportWithinBuffer(swgfx* gfx) { | 926 | static bool ViewportWithinBuffer(swgfx* gfx) { |
| 895 | assert(gfx); | 927 | assert(gfx); |
| 896 | const sgViewport_t vp = gfx->viewport; | 928 | const sgViewport_t vp = gfx->viewport; |
