#include "common/texture.h" #include #include #include #include Texture::Texture(int width, int height) { this->resize(width, height); } Texture::Texture(char const *fileName) { this->load(fileName); } bool Texture::load(char const *fileName) { CImg img_char(fileName); if (img_char.is_empty()) { std::cerr << "(Image): Could not open file " << fileName << std::endl; return false; } this->image_ = CImg(img_char.width(), img_char.height(), img_char.depth(), 3, 0); for (int c = 0; c < 3; c++) cimg_forXYZ(img_char, x, y, z) { this->image_(x, y, z, c) = img_char(x, y, z, std::min(c, img_char.spectrum() - 1)) / 255.0f; } return true; } bool Texture::save(char const *fileName) const { CImg img_char; img_char = 255 * this->image_; img_char.save(fileName); return true; } Color Texture::getPixelAt(int x, int y) const { if ((x %= this->width()) < 0) x += this->width(); if ((y %= this->height()) < 0) y += this->height(); return Color(this->image_.atXY(x, y, 0), this->image_.atXY(x, y, 1), this->image_.atXY(x, y, 2)); } void Texture::setPixelAt(int x, int y, Color const &color) { if ((x %= this->width()) < 0) x += this->width(); if ((y %= this->height()) < 0) y += this->height(); this->image_(x, y, 0) = color.r; this->image_(x, y, 1) = color.g; this->image_(x, y, 2) = color.b; } Color Texture::color(float u, float v, bool interpolate) const { Color color; if (!interpolate) { color = this->getPixelAt(int(roundf(u * this->width())), int(roundf(v * this->height()))); } else { // IMPLEMENT bilinear interpolation float x = u * this->width(); float x1 = std::floor(x); float x2 = std::ceil(x); float y = v * this->height(); float y1 = std::floor(y); float y2 = std::ceil(y); Color x1y1 = this->getPixelAt(static_cast(x1), static_cast(y1)); Color x2y1 = this->getPixelAt(static_cast(x2), static_cast(y1)); Color x1y2 = this->getPixelAt(static_cast(x1), static_cast(y2)); Color x2y2 = this->getPixelAt(static_cast(x2), static_cast(y2)); Color fxy1 = (x2 - x) * x1y1 + (x - x1) * x2y1; Color fxy2 = (x2 - x) * x1y2 + (x - x1) * x2y2; color = (y2 - y) * fxy1 + (y - y1) * fxy2; } return color; } Color Texture::color(Vector2d const &surfacePosition, bool interpolate) const { return color(surfacePosition.u, surfacePosition.v, interpolate); }