void fillMandelbrot( const RGB& c1, const RGB& c2, const RGB& c3, int iters ) { int centerX = img.width() / 2; int centerY = img.height() / 2; const int THRES = 1e6; for(int y = 0; y < img.height() ; y++) { for(int x = 0; x < img.width(); x++) { complex<float> z((x-centerX)/(float)img.width() * 3.0 - 0.25, (y-centerY)/(float)img.height() * 3.0); complex<float> c = z; float val = std::abs(z); int i=0; while( i++ < iters && val < THRES ) { z = z * z + c; val = std::abs(z); } float t = i / (float)iters; t = powf(t, 0.25); RGB color; if( t >= 1.0 ) color = c1; else color = interpolate(c2, c3, t); img.setPixel(x, y, color); } } }
void fillCircle_jitter( const RGB& c, const RGB& cb, int centerX, int centerY, int radius ) { const int N = 4; float h = 1.0f / N; int radius2 = radius * radius; for(int y = 0; y < img.height() ; y++) { for(int x = 0; x < img.width(); x++) { // for this pixel, sample N^2 times int cnt = 0; float dy = y - centerY + 0.5 * h; for(int i=0;i<N;i++) { float dx = x - centerX + 0.5 * h; for(int j=0;j<N;j++) { float rr = dx * dx + dy * dy; if( rr <= radius2 ) cnt++; dx += h; } dy += h; } float t = cnt / (float)(N * N); img.setPixel(x, y, interpolate(c, cb, t)); } } }
void createMasks(const RGBImage& img) { cout << "creating masks ..." << endl; int w = img.width(), h = img.height(); GrayScaleImagef I(w, h); for(int i=0;i<h;i++) { for(int j=0;j<w;j++) { RGBImage::pixel_t pix = img.getPixel(j, i); if( pix.r > 0 ) { I.setPixel(j, i, 1.0); //cout << (int)pix.r << endl; } else { //cout << (int)pix.r << endl; I.setPixel(j, i, 0.0); } } } float invSamples = 1.0 / (samples * samples); float step = 1.0 / samples; // create a set of masks for(int i=0;i<256;i++) { cout << "level " << i << endl; float maskSize = i+1; float topY = 0.5 * (h - maskSize); float bottomY = topY + maskSize; float leftX = topY; float rightX = bottomY; GrayScaleImagef m(w, h); for(int i=0;i<w;i++) { int y = i; for(int j=0;j<h;j++) { int x = j; //cout << i << "," << j << endl; int cnt = 0; for(int ny=0;ny<samples;ny++) { float yy = ny * step + y; float yyy =(yy-topY) / maskSize; for(int nx=0;nx<samples;nx++) { float xx = nx * step + x; float xxx = (xx-leftX) / maskSize; if( xxx >= 0 && xxx < 1.0 && yyy >= 0 && yyy < 1.0 ) { GrayScaleImage::pixel_t pix = I.sample(xxx*(w-1), yyy*(h-1)); cnt += pix; } } } m.setPixel(j, i, cnt * invSamples); } } masks.push_back(m); } cout << "masks created!" << endl; }
static void windowDisplay(void) { glClear(GL_COLOR_BUFFER_BIT); glRasterPos2i(0,0); glPixelStorei(GL_UNPACK_ALIGNMENT,1); glDrawPixels(img.width(), img.height(), GL_RGB, GL_UNSIGNED_BYTE, img.raw_data()); glFlush(); }
void fillCircle( const RGB& c, int centerX, int centerY, int radius ) { int radius2 = radius * radius; for(int y = 0; y < img.height() ; y++) { for(int x = 0; x < img.width(); x++) { int dx = x - centerX; int dy = y - centerY; int rr = dx * dx + dy * dy; if( rr > radius2 ) continue; img.setPixel(x, y, c); } } }
void saveImage(const RGBImage& img, const string& filename) { int w = img.width(); int h = img.height(); QImage I(w, h, QImage::Format_ARGB32); for(int y=0;y<h;y++) { for(int x=0;x<w;x++) { RGBImage::pixel_t pix = img.getPixel(x, y); I.setPixel(x, y, qRgb(pix.r, pix.g, pix.b)); } } I.save(filename.c_str()); }
void SimpleRayTracer::traceScene(const Scene& SceneModel, RGBImage& Image) { //TODO Camera eye(-8.0f, 1.0f, 1.0f, 0.75f, 640.0f, 480.0f); Color pColor; Vector ray; for (unsigned int y = 0; y < Image.height(); y++) { for (unsigned int x = 0; x < Image.width(); x++) { ray = eye.generateRay(x, y); pColor = trace(SceneModel, eye.Position(), ray, m_MaxDepth); Image.setPixelColor(x, y, pColor); } } }
RGBImage loadImage(const string& filename) { cout << "loading image " << filename << endl; QImage img(filename.c_str()); int w = img.width(); int h = img.height(); RGBImage I(w, h); for(int y=0;y<h;y++) { for(int x=0;x<w;x++) { QRgb pix = img.pixel(x, y); RGBPixel c(qRed(pix), qGreen(pix), qBlue(pix)); I.setPixel(x, y, c); } } cout << "done." << endl; return I; }
RGBImage halftone(const RGBImage& img, int blockSize) { int w = img.width(), h = img.height(); RGBImage I(w, h); int yBlocks = ceil(h / (float)blockSize); int xBlocks = ceil(w / (float)blockSize); cout << "blocks: " << yBlocks << "x" << xBlocks << endl; for(int i=0;i<yBlocks;i++) { int y0 = i * blockSize; int y1 = Utils::clamp((i+1) * blockSize, 0, h); for(int j=0;j<xBlocks;j++) { int x0 = j * blockSize; int x1 = Utils::clamp((j+1) * blockSize, 0, w); fillBlock(x0, y0, x1, y1, img, I); } } return I; }
void setPixels( const string& option ) { if( option == "red" ) img.fill(RGB::red); else if( option == "green" ) img.fill(RGB::green); else if( option == "blue" ) img.fill(RGB::blue); else if( option == "all" ) { int halfW = img.width() / 2; int halfH = img.height() / 2; img.fill( 0, 0, halfW, halfH, RGB::blue ); img.fill( halfW, 0, halfW, halfH, RGB::yellow ); img.fill( 0, halfH, halfW, halfH, RGB::red ); img.fill( halfW, halfH, halfW, halfH, RGB::green ); } else if( option == "circle" ) { img.fill(RGB::blue); fillCircle( RGB::yellow, img.width()/2, img.height()/2, img.height()*0.375); } else if( option == "circle_smooth") { fillCircle_jitter( RGB::yellow, RGB::blue, img.width()/2, img.height()/2, img.height()*0.375); } else if( option == "man" ) { fillMandelbrot( RGB::black, RGB::blue, RGB::green, 256); } else { // invalid command int halfW = img.width() / 2; int halfH = img.height() / 2; img.fill( 0, 0, halfW, halfH, RGB::blue ); img.fill( halfW, 0, halfW, halfH, RGB::yellow ); img.fill( 0, halfH, halfW, halfH, RGB::red ); img.fill( halfW, halfH, halfW, halfH, RGB::green ); } }
void animation() { char filename[1024]; int totalPic = 120; float blkSize = 2; int pid = 0; RGBImage sImg = imgs[0]; RGBImage fadeInImg = halftone(imgs[0], 2); RGBImage fadeOutImg = halftone(imgs[1], 2); float fadeInL = 10.0f, fadeOutL = 10.0f; for(int i=0;i<fadeInL;i++,pid++) { float ratio = 1.0 - i / (fadeInL-1.0); sImg = ImageUtils::blend(imgs[0], fadeInImg, ratio); img = ImageUtils::flip(sImg); sprintf(filename, "img%d.png", pid); saveImage(sImg, filename); glClear(GL_COLOR_BUFFER_BIT); glRasterPos2i(0,0); glPixelStorei(GL_UNPACK_ALIGNMENT,1); glDrawPixels(img.width(), img.height(), GL_RGB, GL_UNSIGNED_BYTE, img.raw_data()); glFlush(); } float transitionL = 10.0f; int tstartId = (totalPic-transitionL)/2; float ratio=1.0; for(int i=0;i<totalPic/2;i++, pid++) { blkSize += 2; currentBlkSize = Utils::clamp<int>(blkSize, 2, 1280); ratio = 1.0 - Utils::clamp((pid - tstartId) / transitionL, 0.0f, 1.0f); sImg = ImageUtils::blend(imgs[0], imgs[1], ratio); RGBImage hImg = halftone(sImg, currentBlkSize); img = ImageUtils::flip(hImg); sprintf(filename, "img%d.png", pid); saveImage(hImg, filename); glClear(GL_COLOR_BUFFER_BIT); glRasterPos2i(0,0); glPixelStorei(GL_UNPACK_ALIGNMENT,1); glDrawPixels(img.width(), img.height(), GL_RGB, GL_UNSIGNED_BYTE, img.raw_data()); glFlush(); } for(int i=0;i<totalPic/2;i++, pid++) { blkSize -= 2; currentBlkSize = Utils::clamp<int>(blkSize, 2, 1280); ratio = 1.0 - Utils::clamp((pid - tstartId) / transitionL, 0.0f, 1.0f); sImg = ImageUtils::blend(imgs[0], imgs[1], ratio); RGBImage hImg = halftone(sImg, currentBlkSize); img = ImageUtils::flip(hImg); sprintf(filename, "img%d.png", pid); saveImage(hImg, filename); glClear(GL_COLOR_BUFFER_BIT); glRasterPos2i(0,0); glPixelStorei(GL_UNPACK_ALIGNMENT,1); glDrawPixels(img.width(), img.height(), GL_RGB, GL_UNSIGNED_BYTE, img.raw_data()); glFlush(); } for(int i=0;i<fadeOutL;i++,pid++) { float ratio = i / (fadeOutL-1.0); sImg = ImageUtils::blend(imgs[1], fadeOutImg, ratio); img = ImageUtils::flip(sImg); sprintf(filename, "img%d.png", pid); saveImage(sImg, filename); glClear(GL_COLOR_BUFFER_BIT); glRasterPos2i(0,0); glPixelStorei(GL_UNPACK_ALIGNMENT,1); glDrawPixels(img.width(), img.height(), GL_RGB, GL_UNSIGNED_BYTE, img.raw_data()); glFlush(); } }