summaryrefslogtreecommitdiff
path: root/bitmap.h
diff options
context:
space:
mode:
authorKeuin <[email protected]>2022-04-11 22:13:57 +0800
committerKeuin <[email protected]>2022-04-11 22:13:57 +0800
commit43714bd116945573e7e4c854445462afa7f9b1b4 (patch)
tree7570dd1ab5e0feb38e504b4a49f4e8d2d0774873 /bitmap.h
parentf6661b0243cb359fb4929aee06d1247944f3d2dd (diff)
Implement ray3, timer and a simple viewport scanner.
Fix bitmap wrong pixel sequence. Remove default constructor of bitmap. Add pixel mixture method.
Diffstat (limited to 'bitmap.h')
-rw-r--r--bitmap.h41
1 files changed, 39 insertions, 2 deletions
diff --git a/bitmap.h b/bitmap.h
index b94bb25..31b9053 100644
--- a/bitmap.h
+++ b/bitmap.h
@@ -10,13 +10,48 @@
#include <ostream>
#include <cassert>
+#define COLORMIX_OVERFLOW_CHECK
+
+//// T is some unsigned integer
+//template<typename T>
+//T saturate_add(T a, T b) {
+// T c = a + b;
+// if (a > c || b > c) {
+// c = (1ULL << (sizeof(T) * 8U)) - 1ULL;
+// }
+// return c;
+//}
// T is some unsigned integer, do not use float point types!
template<typename T>
struct pixel {
T r, g, b;
+
+ /**
+ * Create a pixel with given depth, from normalized color values.
+ * For example: for 8bit pixel, with (1, 0.5, 0.25), we get: (255, 127, 63).
+ */
+ static pixel<T> from_normalized(double r, double g, double b) {
+ const auto mod = (1ULL << (sizeof(T) * 8U)) - 1ULL;
+ return pixel<T>{.r = (T) (mod * r), .g = (T) (mod * g), .b = (T) (mod * b)};
+ }
};
+// Mix two colors a and b. Returns a*u + b*v
+template<typename T>
+inline pixel<T> mix(const pixel<T> &a, const pixel<T> &b, double u, double v) {
+ assert(u >= 0);
+ assert(v >= 0);
+ assert(u <= 1);
+ assert(v <= 1);
+ assert(u + v <= 1);
+ pixel<T> c{0, 0, 0};
+ c.r = (T) (u * a.r + v * b.r);
+ c.g = (T) (u * a.g + v * b.g);
+ c.b = (T) (u * a.b + v * b.b);
+ return c;
+}
+
// 8 bit pixel
using pixel8b = pixel<uint8_t>;
@@ -28,16 +63,18 @@ class bitmap {
pixel<T> &image(unsigned x, unsigned y) {
assert(x < width);
assert(y < height);
- return content[x * width + y];
+ return content[x + y * width];
}
pixel<T> &image(unsigned x, unsigned y) const {
assert(x < width);
assert(y < height);
- return content[x * width + y];
+ return content[x + y * width];
}
public:
+ bitmap() = delete;
+
bitmap(unsigned int width, unsigned int height) : width(width), height(height) {
content.resize(width * height, pixel<T>{});
}