1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
#pragma once #ifndef TEXTURE_H #define TEXTURE_H
#include "utilities.h" #include "perlin.h" #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h"
...
class image_texture : public texture { public: const static int bytes_per_pixel = 3;
image_texture() : data(nullptr), width(0), height(0), bytes_per_scanline(0) {}
image_texture(const char* filename) { auto components_per_pixel = bytes_per_pixel;
data = stbi_load( filename, &width, &height, &components_per_pixel, components_per_pixel);
if (!data) { std::cerr << "ERROR: Could not load texture image file '" << filename << "'.\n"; width = height = 0; }
bytes_per_scanline = bytes_per_pixel * width; }
~image_texture() { delete data; }
virtual color value(double u, double v, const vec3& p) const override { if (data == nullptr) return color(0, 1, 1);
u = clamp(u, 0.0, 1.0); v = 1.0 - clamp(v, 0.0, 1.0); auto i = static_cast<int>(u * width); auto j = static_cast<int>(v * height); if (i >= width) i = width - 1; if (j >= height) j = height - 1; const auto color_scale = 1.0 / 255.0; auto pixel = data + j * bytes_per_scanline + i * bytes_per_pixel;
return color(color_scale * pixel[0], color_scale * pixel[1], color_scale * pixel[2]); }
private: unsigned char* data; int width, height; int bytes_per_scanline; };
#endif
|