boost::shared_ptr<cv::Mat> RemoveLonePixels::apply( boost::shared_ptr<cv::Mat> input ) const { boost::shared_ptr<cv::Mat> result( new cv::Mat( input->clone() ) ); for( int row = 0; row < input->rows; ++row ) { for( int col = 0; col < input->cols; ++col ) { cv::Vec3b& pixel = result->at<cv::Vec3b>( row, col ); if ( !isImageBorder( row, col, input->rows, input->cols ) ) { if( isWhite( pixel ) ) { if ( shouldBeColored( row, col, result ) ) { colorPixel( pixel, row, col, result ); } } else { if( isLonely( row, col, result ) ) { whitenPixel( pixel ); } } } } } return result; }
/** * @brief Calculates every pixel in a rectangle. * @param calcLocation A rectangle in the complex-plane that is to be calculated. * @param m Settings for the visualization. */ void calculateRectangle(rectangle calcLocation, mandelData * m) //added m-> to location.w & h { //the rectangle calcLocation is located in the complex-plane //the size and location of this rectangle must be translated into screen-coordinates int xScreen = (int)((calcLocation.x - m->location.x)/m->location.w * (double) m->width); int yScreen = (int)((calcLocation.y - m->location.y)/m->location.h * (double) m->height); int rectScreenWidth = (int)(calcLocation.w/m->location.w*(double)m->width); int rectScreenHeight = (int)(calcLocation.h/m->location.h*(double)m->height); //when calcLocation has been mapped to screen-coordinates, each of the pixels in calcLocation is calculated for(int x = xScreen; x <= xScreen + rectScreenWidth; x++) { for(int y = yScreen; y <= yScreen + rectScreenHeight; y++) { if(x >= m-> width || y >= m-> height) continue; //translate from screen-coordinates to coodrinates in the complex-plane double fx = calcLocation.x + (double)(x - xScreen)/(double)rectScreenWidth*calcLocation.w; double fy = calcLocation.y + (double)(y - yScreen)/(double)rectScreenHeight*calcLocation.h; m->image[y * m->width + x] = colorPixel(fx, fy, m); } } }
int GzPutTriangle(GzRender *render, int numParts, GzToken *nameList, GzPointer *valueList) /* numParts : how many names and values */ { /* - pass in a triangle description with tokens and values corresponding to GZ_POSITION:3 vert positions in model space - Xform positions of verts using matrix on top of stack - Clip - just discard any triangle with any vert(s) behind view plane - optional: test for triangles with all three verts off-screen (trivial frustum cull) - invoke triangle rasterizer */ if (render == NULL || nameList == NULL) return GZ_FAILURE; float *n1 = new float[3], *v1 = new float[3], *t1 = new float[2]; float *n2 = new float[3], *v2 = new float[3], *t2 = new float[2]; float *n3 = new float[3], *v3 = new float[3], *t3 = new float[2]; float color1[3]; float color2[3]; float color3[3]; for (int i = 0; i < numParts; ++i) { // iterates through number of parts if (nameList[i] == GZ_NULL_TOKEN) // do nothing ; if (nameList[i] == GZ_TEXTURE_INDEX) { GzTextureIndex *tex = (GzTextureIndex*)valueList[i]; for (int num = 0; num < 2; ++num) { t1[num] = tex[0][num]; t2[num] = tex[1][num]; t3[num] = tex[2][num]; } for (int num = 0; num < 2; ++num) { t1[num] /= ((v1[2] / ((float)MAXINT - v1[2])) + 1.0); t2[num] /= ((v2[2] / ((float)MAXINT - v2[2])) + 1.0); t3[num] /= ((v3[2] / ((float)MAXINT - v3[2])) + 1.0); } if (render->tex_fun != NULL) { // for Gourad Shading float dummy[3] = { 1, 1, 1 }; colorPixelTex(render, n1, color1, dummy, dummy, dummy); colorPixelTex(render, n2, color2, dummy, dummy, dummy); colorPixelTex(render, n3, color3, dummy, dummy, dummy); } } if (nameList[i] == GZ_NORMAL) { GzCoord *normal = (GzCoord*)valueList[i]; for (int num = 0; num < 3; ++num) { n1[num] = normal[0][num]; n2[num] = normal[1][num]; n3[num] = normal[2][num]; } float matrix[4][4]; for (int i = 0; i < 4; ++i) // get matrix based on normals for (int j = 0; j < 4; ++j) matrix[i][j] = render->Xnorm[render->matlevel - 1][i][j]; float n_v1[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; float n_v2[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; float n_v3[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; for (int y = 0; y < 4; ++y) { // does matrix multiplication for (int x = 0; x < 4; ++x) { if (x != 3) { n_v1[y] += matrix[y][x] * n1[x]; n_v2[y] += matrix[y][x] * n2[x]; n_v3[y] += matrix[y][x] * n3[x]; } else { n_v1[y] += matrix[y][x] * 1; n_v2[y] += matrix[y][x] * 1; n_v3[y] += matrix[y][x] * 1; } } } for (int x = 0; x < 3; ++x) { // converts the vertices from 4D to 3D n_v1[x] /= n_v1[3]; n_v2[x] /= n_v2[3]; n_v3[x] /= n_v3[3]; } // Reassign n1, n2, n3 for (int num = 0; num < 3; ++num) { n1[num] = n_v1[num]; n2[num] = n_v2[num]; n3[num] = n_v3[num]; } // gets the color based on vertices colorPixel(render, n1, color1); colorPixel(render, n2, color2); colorPixel(render, n3, color3); } if (nameList[i] == GZ_POSITION) { // Executes GzCoord *coord = (GzCoord*)valueList[i]; for (int num = 0; num < 3; ++num) { v1[num] = coord[0][num]; v2[num] = coord[1][num]; v3[num] = coord[2][num]; } // Transform the coords based on the current matrix float matrix[4][4]; for (int i = 0; i < 4; ++i) for (int j = 0; j < 4; ++j) matrix[i][j] = render->Ximage[render->matlevel - 1][i][j]; float n_v1[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; float n_v2[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; float n_v3[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; for (int y = 0; y < 4; ++y) { // does matrix multiplication for (int x = 0; x < 4; ++x) { if (x != 3) { n_v1[y] += matrix[y][x] * v1[x]; n_v2[y] += matrix[y][x] * v2[x]; n_v3[y] += matrix[y][x] * v3[x]; } else { n_v1[y] += matrix[y][x] * 1; n_v2[y] += matrix[y][x] * 1; n_v3[y] += matrix[y][x] * 1; } } } for (int x = 0; x < 3; ++x) { // converts the vertices from 4D to 3D n_v1[x] /= n_v1[3]; n_v2[x] /= n_v2[3]; n_v3[x] /= n_v3[3]; } // Reassign v1, v2, v3 for (int num = 0; num < 3; ++num) { v1[num] = n_v1[num]; v2[num] = n_v2[num]; v3[num] = n_v3[num]; } // Offsets for Anti-aliasing { v1[0] -= render->xOff; v1[1] -= render->yOff; v2[0] -= render->xOff; v2[1] -= render->yOff; v3[0] -= render->xOff; v3[1] -= render->yOff; } } } // GZ_FLAT -> same // GZ_COLOR -> find color first then interpolate // GZ_NORMAL -> interpolate then find normals float *v_sub; float *n_sub; float c_sub; float *t_sub; for (int v = 0; v < 2; ++v) { // selection sort vertices by y from lowest to highest if (v1[1] > v2[1]) { v_sub = v2; v2 = v1; v1 = v_sub; if (render->interp_mode == GZ_NORMALS){ n_sub = n2; n2 = n1; n1 = n_sub; } else if (render->interp_mode == GZ_COLOR) { for (int c = 0; c < 3; ++c) { c_sub = color2[c]; color2[c] = color1[c]; color1[c] = c_sub; } } if (render->tex_fun != NULL) { t_sub = t1; t1 = t2; t2 = t_sub; } } if (v2[1] > v3[1]) { v_sub = v3; v3 = v2; v2 = v_sub; if (render->interp_mode == GZ_NORMALS){ n_sub = n3; n3 = n2; n2 = n_sub; } else if (render->interp_mode == GZ_COLOR) { for (int c = 0; c < 3; ++c) { c_sub = color3[c]; color3[c] = color2[c]; color2[c] = c_sub; } } if (render->tex_fun != NULL) { t_sub = t2; t2 = t3; t3 = t_sub; } } } // vectors that are based off the y-axis from low to high float vect1[3]; float vect2[3]; float vect3[3]; int lr; // 0 = left, 1 = right, 2 = special traingle case for (int num = 0; num < 3; ++num) { // DEFAULT is set to L vect1[num] = v2[num] - v1[num]; // To v2 from v1 vect2[num] = v3[num] - v2[num]; // To v3 from v2 vect3[num] = v3[num] - v1[num]; // To v3 from v1 } // Normalize the vectors normalize(vect1); normalize(vect2); normalize(vect3); // determines if the line is left or right if (v2[1] == v3[1] || v2[1] == v1[1]) // Checks if mid-vertex has same y-coord lr = 2; else { // looks at the edge vector opposite the vertex: v1 -> v3 // based on y-intercept for v2 float time, x; time = (v2[1] - v1[1]) / vect3[1]; x = v1[0] + time * vect3[0]; // find x and compare with v2 x-coordinate if (x < v2[0]) { // if the intersection occurs on the right lr = 1; // midpoint is on R } else lr = 0; // midpoint is on L } float norm[3], d; crossProduct(vect1, vect2, norm); // Calculates the cross product for the plane // Calculates d using vertex 1 d = -((norm[0] * v1[0]) + (norm[1] * v1[1]) + (norm[2] * v1[2])); // variables for finding the bounds for coloring in triangle float x_sol; float x_begin; int y_begin; float x_end, y_end; // clamps the boundaries for y if (ceilf(v1[1]) < 0) y_begin = 0; else y_begin = ceilf(v1[1]); if (v3[1] > render->display->yres - 1) y_end = render->display->yres - 1; else y_end = v3[1]; float t; float GouraudColor1[3]; float GouraudColor2[3]; float PhongNormal1[3]; float PhongNormal2[3]; float TexPoint1[3]; float TexPoint2[3]; // Computes rasterization using scan line if (lr == 0) { // vect 1 & vect 2 are on the left for (int y = y_begin; y <= y_end; ++y) { // cycles from top vertex to bottom vertex // finds the start point and the endpoint from v1 to v3 in y-coord // computes x_begin for v1 -> v2 if (y < v2[1]) { t = ((float)y - v1[1]) / vect1[1]; x_sol = (vect1[0] * t + v1[0]); x_begin = x_sol; if (render->interp_mode == GZ_COLOR) interpolate(y, v1[1], v2[1], color1, color2, GouraudColor1); else if (render->interp_mode == GZ_NORMALS) interpolate(y, v1[1], v2[1], n1, n2, PhongNormal1); if (render->tex_fun != NULL) interpolateTex(y, v1[1], v2[1], t1, t2, TexPoint1); } else { // compute for v2 -> v3 t = ((float)y - v2[1]) / vect2[1]; x_sol = (vect2[0] * t + v2[0]); x_begin = x_sol; if (render->interp_mode == GZ_COLOR) interpolate(y, v2[1], v3[1], color2, color3, GouraudColor1); else if (render->interp_mode == GZ_NORMALS) interpolate(y, v2[1], v3[1], n2, n3, PhongNormal1); if (render->tex_fun != NULL) interpolateTex(y, v2[1], v3[1], t2, t3, TexPoint1); } // computes x_end: v1 -> v3 t = ((float)y - v1[1]) / vect3[1]; x_sol = (vect3[0] * t + v1[0]); x_end = x_sol; if (render->interp_mode == GZ_COLOR) interpolate(y, v1[1], v3[1], color1, color3, GouraudColor2); else if (render->interp_mode == GZ_NORMALS) interpolate(y, v1[1], v3[1], n1, n3, PhongNormal2); if (render->tex_fun != NULL) interpolateTex(y, v1[1], v3[1], t1, t3, TexPoint2); if (render->interp_mode == GZ_FLAT) scanLine(render, x_begin, x_end, y, norm, d); // Spans line for y_value else if (render->interp_mode == GZ_COLOR) { scanLineGouraud(render, x_begin, x_end, y, norm, d, GouraudColor1, GouraudColor2, TexPoint1, TexPoint2); // Gouraud Shading } else if (render->interp_mode == GZ_NORMALS) { scanLinePhong(render, x_begin, x_end, y, norm, d, PhongNormal1, PhongNormal2, TexPoint1, TexPoint2); // Phong Shading } else scanLine(render, x_begin, x_end, y, norm, d); // Spans line for y_value } } else if (lr == 1) { // RIGHT for (int y = y_begin; y <= y_end; ++y) { // cycles from top vertex to bottom vertex // finds the start point and the endpoint from v1 to v3 in y-coord // computes x_begin for v1 -> v3 t = ((float)y - v1[1]) / vect3[1]; x_sol = (vect3[0] * t + v1[0]); x_begin = x_sol; if (render->interp_mode == GZ_COLOR) interpolate(y, v1[1], v3[1], color1, color3, GouraudColor1); else if (render->interp_mode == GZ_NORMALS) interpolate(y, v1[1], v3[1], n1, n3, PhongNormal1); if (render->tex_fun != NULL) interpolateTex(y, v1[1], v3[1], t1, t3, TexPoint1); // computes x_end v1 -> v2 if (y < v2[1]) { t = ((float)y - v1[1]) / vect1[1]; x_sol = (vect1[0] * t + v1[0]); x_end = x_sol; if (render->interp_mode == GZ_COLOR) interpolate(y, v1[1], v2[1], color1, color2, GouraudColor2); else if (render->interp_mode == GZ_NORMALS) interpolate(y, v1[1], v2[1], n1, n2, PhongNormal2); if (render->tex_fun != NULL) interpolateTex(y, v1[1], v2[1], t1, t2, TexPoint2); } else { // compute for v2 -> v3 t = ((float)y - v2[1]) / vect2[1]; x_sol = (vect2[0] * t + v2[0]); x_end = x_sol; if (render->interp_mode == GZ_COLOR) interpolate(y, v2[1], v3[1], color2, color3, GouraudColor2); else if (render->interp_mode == GZ_NORMALS) interpolate(y, v2[1], v3[1], n2, n3, PhongNormal2); if (render->tex_fun != NULL) interpolateTex(y, v2[1], v3[1], t2, t3, TexPoint2); } if (render->interp_mode == GZ_FLAT) scanLine(render, x_begin, x_end, y, norm, d); // Spans line for y_value else if (render->interp_mode == GZ_COLOR) { scanLineGouraud(render, x_begin, x_end, y, norm, d, GouraudColor1, GouraudColor2, TexPoint1, TexPoint2); // Gouraud Shading } else if (render->interp_mode == GZ_NORMALS) { scanLinePhong(render, x_begin, x_end, y, norm, d, PhongNormal1, PhongNormal2, TexPoint1, TexPoint2); // Phong Shading } else scanLine(render, x_begin, x_end, y, norm, d); // Spans line for y_value } } // special case of horizontal triangles else if (lr == 2) { // compare x float *vleft, *vright; float *vleftend, *vrightend; float *cleft, *cright; float *cleftend, *crightend; float *nleft, *nright; float *nleftend, *nrightend; float *tleft, *tright; float *tleftend, *trightend; float* vect_l; float* vect_r; if (v2[1] == v3[1]) { // bottom line triangle vleft = v1; vright = v1; if (render->interp_mode == GZ_COLOR) { cleft = color1; cright = color1; } else if (render->interp_mode == GZ_NORMALS) { nleft = n1; nright = n1; } if (render->tex_fun != NULL) { tleft = t1; tright = t1; } if (v2[0] > v3[0]) { // v2 is on the right; v1->v2 is on left, v1->v3 is on right vect_l = vect3; vect_r = vect1; vleftend = v2; vrightend = v3; if (render->interp_mode == GZ_COLOR) { cleftend = color2; crightend = color3; } else if (render->interp_mode == GZ_NORMALS) { nleftend = n2; nrightend = n3; } if (render->tex_fun != NULL) { tleftend = t2; trightend = t3; } } else { // v2 is on the left; v1->v2 is on right, v1->v3 is on left vect_l = vect1; vect_r = vect3; vleftend = v3; vrightend = v2; if (render->interp_mode == GZ_COLOR) { cleftend = color3; crightend = color2; } else if (render->interp_mode == GZ_NORMALS) { nleftend = n3; nrightend = n2; } if (render->tex_fun != NULL) { tleftend = t3; trightend = t2; } } } else if (v1[1] == v2[1]) { // top line triangle if (y_begin == v1[1]) // if top horizontal line lies on y_coord for row of pixels ++y_begin; // prevents top and bottom triangle from overwriting same line for integer y if (v1[0] > v2[0]) { // v2 is on the left; v1 is on right vleft = v2; vright = v1; vect_l = vect2; vect_r = vect3; if (render->interp_mode == GZ_COLOR) { cleft = color2; cright = color1; } else if (render->interp_mode == GZ_NORMALS) { nleft = n2; nright = n3; } if (render->tex_fun != NULL) { tleft = t2; tright = t3; } } else { // v2 is on the right; v1 is on left vleft = v1; vright = v2; vect_l = vect3; vect_r = vect2; if (render->interp_mode == GZ_COLOR) { cleft = color1; cright = color2; } else if (render->interp_mode == GZ_NORMALS) { nleft = n1; nright = n2; } if (render->tex_fun != NULL) { tleft = t1; tright = t2; } } vleftend = v3; vrightend = v3; if (render->interp_mode == GZ_COLOR) { cleftend = color3; crightend = color3; } else if (render->interp_mode == GZ_NORMALS) { nleftend = n3; nrightend = n3; } if (render->tex_fun != NULL) { tleftend = t3; trightend = t3; } } for (int y = y_begin; y <= y_end; ++y) { // cycles from top vertex to bottom vertex // computes x_begin for left t = ((float)y - vleft[1]) / vect_l[1]; x_sol = (vect_l[0] * t + vleft[0]); x_begin = x_sol; if (render->interp_mode == GZ_COLOR) interpolate(y, vleft[1], vleftend[1], cleft, cleftend, GouraudColor1); else if (render->interp_mode == GZ_NORMALS) interpolate(y, vleft[1], vleftend[1], nleft, nleftend, PhongNormal1); if (render->tex_fun != NULL) interpolateTex(y, vleft[1], vleftend[1], tleft, tleftend, TexPoint1); // computes x_end for right t = ((float)y - vright[1]) / vect_r[1]; x_sol = (vect_r[0] * t + vright[0]); x_end = x_sol; if (render->interp_mode == GZ_COLOR) interpolate(y, vright[1], vrightend[1], cright, crightend, GouraudColor2); else if (render->interp_mode == GZ_NORMALS) interpolate(y, vright[1], vrightend[1], nright, nrightend, PhongNormal2); if (render->tex_fun != NULL) interpolateTex(y, vright[1], vrightend[1], tright, trightend, TexPoint2); if (render->interp_mode == GZ_FLAT) scanLine(render, x_begin, x_end, y, norm, d); // Spans line for y_value else if (render->interp_mode == GZ_COLOR) { scanLineGouraud(render, x_begin, x_end, y, norm, d, GouraudColor1, GouraudColor2, TexPoint1, TexPoint2); // Spans line for y_value } else if (render->interp_mode == GZ_NORMALS) { scanLinePhong(render, x_begin, x_end, y, norm, d, PhongNormal1, PhongNormal2, TexPoint1, TexPoint2); // Spans line for y_value } else scanLine(render, x_begin, x_end, y, norm, d); // Spans line for y_value } } delete t1; delete t2; delete t3; delete n1; delete n2; delete n3; delete v1; delete v2; delete v3; return GZ_SUCCESS; }
void scanLinePhong(GzRender *render, float x_begin, float x_end, int y, float* norm, float d, float* norm1, float* norm2, float* TexPoint1, float* TexPoint2) { // Span line method int index; // used to find index within triangles float z; if (!(x_begin > render->display->xres - 1 || x_end < 0)) { // checks and see if line is within the screen // prevents same line from being drawn twice for later triangles int x = ceilf(x_begin); if (x == x_begin) ++x; float x_s = x_begin; float total = x_end - x_begin; // Clamps the value between 0 and xres if (x_begin < 0) x = 0.0; if (x_end > render->display->xres - 1) x_end = render->display->xres - 1; float t; float newNormal[3]; float newColor[3]; for (x; x <= x_end; ++x) { // begins spanning line index = (render->display->xres * y) + x; // interpolates z at that point z = -((norm[0] * (float)x) + (norm[1] * (float)y) + d) / norm[2]; if (z < render->display->fbuf[index].z && z >= 0) { // if the object is in front of what's on fbuf t = (x - x_s) / total; for (int n = 0; n < 3; ++n) newNormal[n] = (norm1[n] * (1 - t) + norm2[n] * t); normalize(newNormal); colorPixel(render, newNormal, newColor); // gets color based on normal if (render->tex_fun == NULL) { render->display->fbuf[index].red = ctoi(newColor[0]); render->display->fbuf[index].green = ctoi(newColor[1]); render->display->fbuf[index].blue = ctoi(newColor[2]); } else { // look up kd and ka float newTex[2]; for (int n = 0; n < 2; ++n) // interpolate u and v newTex[n] = (TexPoint1[n] * (1 - t) + TexPoint2[n] * t); for (int n = 0; n < 2; ++n) // revert the interpolated value back to screen space newTex[n] *= ((z / ((float)MAXINT - z)) + 1); float texColor[3]; float newTexColor[3]; render->tex_fun(newTex[0], newTex[1], texColor); // grab color from texture colorPixelTex(render, newNormal, newTexColor, render->Ks, texColor, texColor); // get color for Phong render->display->fbuf[index].red = ctoi(newTexColor[0]); render->display->fbuf[index].green = ctoi(newTexColor[1]); render->display->fbuf[index].blue = ctoi(newTexColor[2]); } render->display->fbuf[index].z = z; } } } }
int main(int argc, char * argv[]) { BMP image; image.SetSize(W,H); image.SetBitDepth(32); std::vector<Camera> cameras; Scene scene; // check for proper usage if(argc == 1 || argc > 2) { fprintf(stderr, "%s: usage: %s FILENAME\n", argv[0], argv[0]); return 1; } Parser* fileParser = new Parser(); if(fileParser->parse(argv[1]) == 1) return 1; cameras = fileParser->getCameras(); scene = fileParser->getScene(); for(size_t i = 0; i < scene.planes.size(); i++) { Plane* curr_plane = &scene.planes.at(i); if(curr_plane->hastexture) { curr_plane->texture.ReadFromFile(curr_plane->textureFN.c_str()); } } // for each camera for(int i = 0; i < cameras.size(); i++) { Camera* current_camera = &cameras.at(i); // for every pixel for(int px=0; px<W; px++) { printf("printing column: %d\n", px); for(int py=0; py<H; py++) { //printf("coloring %d %d\n", px, py); Color current_pix = colorPixel(px, py, &scene, current_camera); image(px, py)->Red = (ebmpBYTE) 255 * current_pix.r; image(px, py)->Green = (ebmpBYTE) 255 * current_pix.g; image(px, py)->Blue = (ebmpBYTE) 255 * current_pix.b; image(px, py)->Alpha = 0.0; //printf("%d\t%d\n", px, py); //printf("%f\t%f\t%f\n", current_pix.r, current_pix.g, current_pix.b); } } std::string inputfileName = argv[1]; size_t pos = inputfileName.find_last_of('.'); inputfileName = inputfileName.substr(0, pos); char* camnum = new char[20]; std::string s; std::stringstream out; out << i; s = out.str(); std::string outfileName = inputfileName; outfileName.append("-"); outfileName.append(s); outfileName.append(".bmp"); image.WriteToFile(outfileName.c_str()); } //BMP texture; //texture.ReadFromFile("output.bmp"); free(fileParser); return 0; }
int main(int argc, char** argv) { printf("Initializing image.\n"); initializeImage(512, 512); printf("Configuring scene.\n"); Scene scene = configureScene(); printf("Loading camera.\n"); Camera eye = *scene.getCamera(); printf("Beginning render.\n"); /* Status message: indicate rendering mode. */ #ifdef _TRACE_MODE_INT_ONLY_ printf("Rendering in intersection-only mode.\n"); #elif defined(_TRACE_MODE_NO_AA_) printf("Rendering in shading-only mode (No AA).\n"); #else printf("Rendering in full mode (Shading + AA).\n"); printf("Using %d samples for antialiasing.\n", N_SAMPLES); #endif /************ Reduced functionality modes (part a & b) *************/ #if defined(_TRACE_MODE_INT_ONLY_) || defined(_TRACE_MODE_NO_AA_) int percentile = 0; for(int iy = 0; iy < ny; iy++){ for(int ix = 0; ix < nx; ix++){ Ray ray = eye.getRay(ix, iy); Intersection* hit = scene.intersect(ray, 0.0, HUGE); if(hit) #if defined(_TRACE_MODE_INT_ONLY_) colorPixel(image, ix, iy, Color(1.0f, 1.0f, 1.0f), 1.0f, nx, ny); #else colorPixel(image, ix, iy, scene.shade(ray, *hit, BACKGROUND), 2.2f, nx, ny); #endif } /* Rough estimate of percent progress. */ if((1.0 * iy)/(ny-1) >= 0.10*percentile && percentile <= 10){ printf("%d%%\n", percentile++ * 10); } } #else /********** Shading and anti-aliasing. (Default) (part c) ***********/ int percentile = 0; int one_dim_steps = sqrt(N_SAMPLES); float stepsize = 1.0f/one_dim_steps; for(int iy = 0; iy < ny; iy++){ for(int ix = 0; ix < nx; ix++){ Color sampleSum = BACKGROUND; /* Stratified sampling within pixel, with additional random jitter. */ for(int sy = 0; sy < one_dim_steps; sy++){ for(int sx = 0; sx < one_dim_steps; sx++){ float x, y, jx, jy; // Generate random jitter in [0, 1.0] jx = (float)rand()/(float)RAND_MAX; jy = (float)rand()/(float)RAND_MAX; // Work with a fixed stepsize, but add additional random factor in [0, 1.0] (s_ + j_) x = ix - 0.5f + (sx + jx) * stepsize; // -0.5 moves from center point to left boundary y = iy - 0.5f + (sy + jy) * stepsize; // -0.5 moves from center point to top boundary // Generate eye ray from the stratified/random position within pixel Ray r = eye.getRay(x, y); // Add to sum of sampled colors on hit, with baseline value equal to BACKGROUND Intersection *hit = scene.intersect(r, 0.0f, HUGE); if(hit) sampleSum += scene.shade(r, *hit, BACKGROUND); } } // Finally, color the pixel at (ix, iy) by the average sampled color, with gamma correction. colorPixel(image, ix, iy, sampleSum * (1.0f / (one_dim_steps*one_dim_steps)), 2.2f, nx, ny); } /* Rough estimate of percent progress. */ if((1.0 * iy)/(ny-1) >= 0.10*percentile && percentile <= 10){ printf("%d%%\n", percentile++ * 10); } } #endif // Configure GLUT for rendering via OpenGL setup_glut(argc, argv); return EXIT_SUCCESS; }