//------------------------------------------------------------------------------- /// /// \file texture.cpp /// \author Cem Yuksel (www.cemyuksel.com) /// \version 1.0 /// \date August 21, 2019 /// /// \brief Example source for CS 6620 - University of Utah. /// //------------------------------------------------------------------------------- #include "texture.h" #include "lodepng.h" //------------------------------------------------------------------------------- int ReadLine( FILE *fp, int size, char *buffer ) { int i; for ( i=0; i<size; i++ ) { buffer[i] = fgetc(fp); if ( feof(fp) || buffer[i] == '\n' || buffer[i] == '\r' ) { buffer[i] = '\0'; return i+1; } } return i; } //------------------------------------------------------------------------------- bool LoadPPM( FILE *fp, int &width, int &height, std::vector<Color24> &data ) { const int bufferSize = 1024; char buffer[bufferSize]; ReadLine(fp,bufferSize,buffer); if ( buffer[0] != 'P' && buffer[1] != '6' ) return false; ReadLine(fp,bufferSize,buffer); while ( buffer[0] == '#' ) ReadLine(fp,bufferSize,buffer); // skip comments sscanf(buffer,"%d %d",&width,&height); ReadLine(fp,bufferSize,buffer); while ( buffer[0] == '#' ) ReadLine(fp,bufferSize,buffer); // skip comments // last read line should be "255\n" data.resize(width*height); fread( data.data(), sizeof(Color24), width*height, fp ); return true; } //------------------------------------------------------------------------------- bool TextureFile::Load() { data.clear(); width = 0; height = 0; char const *name = GetName(); if ( name[0] == '\0' ) return false; int len = (int) strlen(name); if ( len < 3 ) return false; bool success = false; char ext[3] = { (char)tolower(name[len-3]), (char)tolower(name[len-2]), (char)tolower(name[len-1]) }; if ( strncmp(ext,"png",3) == 0 ) { std::vector<unsigned char> d; unsigned int w, h; unsigned int error = lodepng::decode(d,w,h,name,LCT_RGB); if ( error == 0 ) { width = w; height = h; data.resize(width*height); memcpy( data.data(), d.data(), width*height*3 ); } success = (error == 0); } else if ( strncmp(ext,"ppm",3) == 0 ) { FILE *fp = fopen( name, "rb" ); if ( ! fp ) return false; success = LoadPPM(fp,width,height,data); fclose(fp); } return success; } //------------------------------------------------------------------------------- Color TextureFile::Sample(Vec3f const &uvw) const { if ( width + height == 0 ) return Color(0,0,0); Vec3f u = TileClamp(uvw); float x = width * u.x; float y = height * u.y; int ix = (int)x; int iy = (int)y; float fx = x - ix; float fy = y - iy; if ( ix < 0 ) ix -= (ix/width - 1)*width; if ( ix >= width ) ix -= (ix/width)*width; int ixp = ix+1; if ( ixp >= width ) ixp -= width; if ( iy < 0 ) iy -= (iy/height - 1)*height; if ( iy >= height ) iy -= (iy/height)*height; int iyp = iy+1; if ( iyp >= height ) iyp -= height; return data[iy *width+ix ].ToColor() * ((1-fx)*(1-fy)) + data[iy *width+ixp].ToColor() * ( fx *(1-fy)) + data[iyp*width+ix ].ToColor() * ((1-fx)* fy ) + data[iyp*width+ixp].ToColor() * ( fx * fy ); } //------------------------------------------------------------------------------- Color TextureChecker::Sample(Vec3f const &uvw) const { Vec3f u = TileClamp(uvw); if ( u.x <= 0.5f ) { return u.y <= 0.5f ? color1 : color2; } else { return u.y <= 0.5f ? color2 : color1; } } //-------------------------------------------------------------------------------