void ClCmdQueue::enqueueMapImage(cl::Image2D& img, cl_mem_flags flags, bool blocking) { // Set origin to 0,0,0 offset within the image to copy from cl::size_t<3> origin = makeCoords(0, 0, 0); // Set the region to be copied based on the width and height of image size_t width = 0, height = 0; img.getImageInfo<size_t>(CL_IMAGE_WIDTH, &width); img.getImageInfo<size_t>(CL_IMAGE_HEIGHT, &height); cl::size_t<3> region = makeCoords(width, height, 1); // The following two variables are not really used by are needed for the // API call. size_t rowPitch = 0, slicePitch = 0; queue.enqueueMapImage(img, blocking, flags, origin, region, &rowPitch, &slicePitch); }
int renCalcVisibility(S_Renderer *pRenderer, const S_Coords *point, const S_Coords *normal) { S_Coords cvec; IZG_ASSERT(pRenderer && point && normal); /* vektor od kamery k plosce, pozice kamery je (0, 0, -camera_dist) */ cvec = makeCoords(point->x, point->y, point->z + pRenderer->camera_dist); coordsNormalize(&cvec); /* test zda je normala privracena * skalarni soucin vektoru od kamery a normaly */ return (normal->x * cvec.x + normal->y * cvec.y + normal->z * cvec.z > 0) ? 0 : 1; }
void renInit(S_Renderer *pRenderer) { IZG_ASSERT(pRenderer); /* frame buffer prozatim neni */ pRenderer->frame_buffer = NULL; pRenderer->frame_w = 0; pRenderer->frame_h = 0; /* podobne take depth buffer */ pRenderer->depth_buffer = NULL; pRenderer->max_depth = 1000.0; /* nastaveni pozice kamery */ pRenderer->camera_dist = 1000; /* pocatecni nastaveni trackballu (natoceni a zoom sceny) */ pRenderer->scene_rot_x = 0; pRenderer->scene_rot_y = 0; pRenderer->scene_move_z = -980; pRenderer->scene_move_x = 0; pRenderer->scene_move_y = 0; /* default material */ pRenderer->mat_ambient = makeMaterial(0.8, 0.8, 0.8); pRenderer->mat_diffuse = makeMaterial(0.8, 0.8, 0.8); pRenderer->mat_specular = makeMaterial(0.8, 0.8, 0.8); /* default zdroj svetla */ pRenderer->light_position = makeCoords(3.0, -3.0, -pRenderer->camera_dist); pRenderer->light_ambient = makeLight(0.2, 0.2, 0.2); pRenderer->light_diffuse = makeLight(0.7, 0.7, 0.7); pRenderer->light_specular = makeLight(0.7, 0.7, 0.7); /* nastaveni ukazatelu na fce */ pRenderer->releaseFunc = renRelease; pRenderer->createBuffersFunc = renCreateBuffers; pRenderer->clearBuffersFunc = renClearBuffers; pRenderer->projectTriangleFunc = renProjectTriangle; pRenderer->calcReflectanceFunc = renLambertianReflectance; }
S_RGBA renLambertianReflectance(S_Renderer *pRenderer, const S_Coords *point, const S_Coords *normal) { S_Coords lvec; double diffuse, r, g, b; S_RGBA color; IZG_ASSERT(pRenderer && point && normal); /* vektor ke zdroji svetla */ lvec = makeCoords(pRenderer->light_position.x - point->x, pRenderer->light_position.y - point->y, pRenderer->light_position.z - point->z); coordsNormalize(&lvec); /* ambientni cast */ r = pRenderer->light_ambient.red * pRenderer->mat_ambient.red; g = pRenderer->light_ambient.green * pRenderer->mat_ambient.green; b = pRenderer->light_ambient.blue * pRenderer->mat_ambient.blue; /* difuzni cast */ diffuse = lvec.x * normal->x + lvec.y * normal->y + lvec.z * normal->z; if( diffuse > 0 ) { r += diffuse * pRenderer->light_diffuse.red * pRenderer->mat_diffuse.red; g += diffuse * pRenderer->light_diffuse.green * pRenderer->mat_diffuse.green; b += diffuse * pRenderer->light_diffuse.blue * pRenderer->mat_diffuse.blue; } /* saturace osvetleni*/ r = MIN(1, r); g = MIN(1, g); b = MIN(1, b); /* kreslici barva */ color.red = ROUND2BYTE(255 * r); color.green = ROUND2BYTE(255 * g); color.blue = ROUND2BYTE(255 * b); return color; }
S_Coords curvePoint(S_Curve *pCurve, double t) { S_Coords point = makeCoords(0.0, 0.0, 0.0); double A, denom = 0.0; int i, size; IZG_ASSERT(pCurve); /* velikost krivky */ size = curveSize(pCurve); /* kontrola hodnoty parametru t <0, 1> */ if( t < 0.0 ) t = 0.0; else if( t >= 1.0 ) t = 1.0; /* vypocet bodu krivky pomoci Bernsteinovych polynomu */ for( i = 0; i < size; ++i ) { A = dvecGet(pCurve->weights, i) * splineFunc(i, pCurve->degree, pCurve->knots, t); point.x += cvecGet(pCurve->points, i).x * A; point.y += cvecGet(pCurve->points, i).y * A; point.z += cvecGet(pCurve->points, i).z * A; denom += A; } /* podeleni jmenovatelem */ if( !IS_ZERO(denom) ) { denom = 1.0 / denom; } point.x *= denom; point.y *= denom; point.z *= denom; return point; }
void curveResize(S_Curve *pCurve, int size, int k) { int i, n; IZG_ASSERT(pCurve && size >= 0 && k >= 2); /* stupen krivky */ pCurve->degree = k; /* zmena velikosti vektoru */ n = cvecSize(pCurve->points); cvecResize(pCurve->points, size); dvecResize(pCurve->weights, size); /* inicializace novych dat */ for( i = n; i < size; ++i ) { cvecGet(pCurve->points, i) = makeCoords(0.0, 0.0, 0.0); dvecGet(pCurve->weights, i) = 1.0; } /* inicializace uzloveho vektoru */ curveInitKnotVector(pCurve); }
//=========================================================================== void CellDivision::constructCells() //=========================================================================== { // @@@ NOTE // // This implementation depends upon using bounding boxes that are // aligned with the principal axis and box-shaped. // First we check if big_box_ is valid. @jbt if (!big_box_.valid()) { MESSAGE("Big box is invalid - returning empty cell vector."); cells_.clear(); return; } if (dim_ < 1) { MESSAGE("Incorrect number of space dimensions."); cells_.clear(); return; } // We partition space into cells. makeCoords(); double tol = 1.0e-9; // VSK, 082017. To avoid loosing surfaces in // planar cases int ncells = ncells_[0]; for (int i = 1; i < dim_; ++i) ncells *= ncells_[i]; cells_.resize(ncells); Point low = big_box_.low(); Point len = big_box_.high() - low; cell_delta_.resize(dim_); for (int i = 0; i < dim_; ++i) cell_delta_[i] = len[i] / ncells_[i]; Point corner; corner.resize(dim_); for (int i = 0; i < ncells; ++i) { for (int dd = 0; dd < dim_; ++dd) { corner[dd] = low[dd] + coords_[i][dd] * cell_delta_[dd]; } cells_[i].setBox(BoundingBox(corner, corner + cell_delta_)); } // Now that we have the cells, we check every face, and add its pointer // to every cell overlapping its bounding box. for (size_t f=0; f<faces_.size(); ++f) { BoundingBox b = faces_[f]->boundingBox(); for (int i = 0; i < ncells; ++i) { if (b.overlaps(cells_[i].box(), tol)) { cells_[i].addFace(faces_[f]); cells_[i].addFaceBox(b); } } } // // The following code depends on dimensionality 3 - commenting out. @jbt // int i, j, k; // // // We partition space into cells. // cells_.resize(ncellsx_*ncellsy_*ncellsz_); // Point low = big_box_.low(); // Point len = big_box_.high() - low; // cell_delta_ = Point(len[0]/ncellsx_, len[1]/ncellsy_, len[2]/ncellsz_); // const Point& delta = cell_delta_; // // double x = low[0]; // double y = low[1]; // double z = low[2]; // Point corner; // // for (i=0; i<ncellsx_; ++i) { // y = low[1]; // for (j=0; j<ncellsy_; ++j) { // z = low[2]; // for (k=0; k<ncellsz_; ++k) { // corner.setValue(x, y, z); // cells_[i + j*ncellsx_ + k*ncellsx_*ncellsy_] // .setBox(BoundingBox(corner, corner + delta)); // z += delta[2]; // } // y += delta[1]; // } // x += delta[0]; // } // // int x1, x2, y1, y2, z1, z2; // Point lo, hi; // // Now that we have the cells, we check every face, and add its pointer // // to every cell overlapping its bounding box. // for (size_t f=0; f<faces_.size(); ++f) { // BoundingBox b = faces_[f]->boundingBox(); // lo = b.low(); // hi = b.high(); // cellContaining(lo, x1, y1, z1); // cellContaining(hi, x2, y2, z2); // for (i=x1; i<=x2; ++i) // for (j=y1; j<=y2; ++j) // for (k=z1; k<=z2; ++k) // { // cells_[i + j*ncellsx_ + k*ncellsx_*ncellsy_].addFace(faces_[f]); // cells_[i + j*ncellsx_ + k*ncellsx_*ncellsy_].addFaceBox(b); // } // } // //#ifdef DEBUG_CELLS // for (i=0; i<ncellsx_*ncellsy_*ncellsz_; ++i) { // cout << "Cell " << i << " has " // << cells_[i].num_faces() << " faces "; // for (j=0; j<cells_[i].num_faces(); ++j) // cout << cells_[i].face(j)->GetId() << " "; // cout << endl; // } //#endif }
S_RGBA studrenPhongReflectance(S_Renderer *pRenderer, const S_Coords *point, const S_Coords *normal) { S_Coords lvec, eyevec, reflect; double diffuse, specular, reflect_scalar; double r, g, b; /* If = Ia + Id + Is */ S_RGBA color; IZG_ASSERT(pRenderer && point && normal); /* vektor ke zdroji svetla */ lvec = makeCoords(pRenderer->light_position.x - point->x, pRenderer->light_position.y - point->y, pRenderer->light_position.z - point->z); coordsNormalize(&lvec); /* vektor ke kamere */ eyevec = makeCoords(-point->x, -point->y, -pRenderer->camera_dist - point->z); coordsNormalize(&eyevec); /* ambientni cast -- Ia = (Al * Am) + (As * Am) */ /* As je barva sceny, muzeme zanedbat */ r = pRenderer->light_ambient.red * pRenderer->mat_ambient.red; g = pRenderer->light_ambient.green * pRenderer->mat_ambient.green; b = pRenderer->light_ambient.blue * pRenderer->mat_ambient.blue; /* difuzni cast -- Id = Dl * Dm * LambertTerm */ /* LambertTerm = dot(N, L) */ diffuse = lvec.x * normal->x + lvec.y * normal->y + lvec.z * normal->z; if( diffuse > 0 ) { r += diffuse * pRenderer->light_diffuse.red * pRenderer->mat_diffuse.red; g += diffuse * pRenderer->light_diffuse.green * pRenderer->mat_diffuse.green; b += diffuse * pRenderer->light_diffuse.blue * pRenderer->mat_diffuse.blue; } /* odraziva cast -- Is = Sm * Sl * pow( max( dot(R, E), 0.0), f ) */ /* R = reflect(-L, N) = 2 * dot(N, L) * N - L */ reflect_scalar = 2 * (normal->x * lvec.x + normal->y * lvec.y + normal->z * lvec.z); reflect.x = reflect_scalar * normal->x - lvec.x; reflect.y = reflect_scalar * normal->y - lvec.y; reflect.z = reflect_scalar * normal->z - lvec.z; specular = pow( MAX(reflect.x * eyevec.x + reflect.y * eyevec.y + reflect.z * eyevec.z, 0.0f), ((S_StudentRenderer*)pRenderer)->mat_shininess); r += specular * pRenderer->light_specular.red * pRenderer->mat_specular.red; g += specular * pRenderer->light_specular.green * pRenderer->mat_specular.green; b += specular * pRenderer->light_specular.blue * pRenderer->mat_specular.blue; /* saturace osvetleni*/ r = MIN(1, r); g = MIN(1, g); b = MIN(1, b); /* kreslici barva */ color.red = ROUND2BYTE(255 * r); color.green = ROUND2BYTE(255 * g); color.blue = ROUND2BYTE(255 * b); return color; }
void studrenDrawTriangle(S_Renderer *pRenderer, S_Coords *v1, S_Coords *v2, S_Coords *v3, S_Coords *n1, S_Coords *n2, S_Coords *n3, int x1, int y1, int x2, int y2, int x3, int y3 ) { // oblast trojuhelniku int min[2] = { MIN(x1, MIN(x2, x3)), MIN(y1, MIN(y2, y3)) }; int max[2] = { MAX(x1, MAX(x2, x3)), MAX(y1, MAX(y2, y3)) }; // oriznuti rozmerem okna min[0] = MAX(min[0], 0); min[1] = MAX(min[1], 0); max[0] = MIN(max[0], pRenderer->frame_w - 1); max[1] = MIN(max[1], pRenderer->frame_h - 1); // pro urceni hranic trojuhelnika pouzijeme pineduv algoritmus // hranova funkce je rovnice Ax + By + C = 0 // A,B je normalovy vektor primky, tzn. (-dy, dx) // C vyjadrime jako x1y2 - x2y1 int A[3] = { { y1 - y2 }, { y2 - y3 }, { y3 - y1 } }; int B[3] = { { x2 - x1 }, { x3 - x2 }, { x1 - x3 } }; int C[3] = { { x1 * y2 - x2 * y1 }, { x2 * y3 - x3 * y2 }, { x3 * y1 - x1 * y3 } }; // do hranove funkce dosadime protejsi vrcholy // provedeme normalizaci, aby kladna strana byla uvnitr oblasti int s0 = A[0] * x3 + B[0] * y3 + C[0]; int s1 = A[1] * x1 + B[1] * y1 + C[1]; int s2 = A[2] * x2 + B[2] * y2 + C[2]; if (s0 < 0) { A[0] *= -1; B[0] *= -1; C[0] *= -1; s0 *= -1; } if (s1 < 0) { A[1] *= -1; B[1] *= -1; C[1] *= -1; s1 *= -1; } if (s2 < 0) { A[2] *= -1; B[2] *= -1; C[2] *= -1; s2 *= -1; } double _s0 = 1.0f / (double)s0; double _s1 = 1.0f / (double)s1; double _s2 = 1.0f / (double)s2; /* gourandovo stinovani */ //S_RGBA color, b1, b2, b3; //b1 = pRenderer->calcReflectanceFunc(pRenderer, v1, n1); //b2 = pRenderer->calcReflectanceFunc(pRenderer, v2, n2); //b3 = pRenderer->calcReflectanceFunc(pRenderer, v3, n3); // vyplnovani pinedovim algoritmem for (int y = min[1]; y <= max[1]; ++y) { int e[3] = { A[0] * min[0] + B[0] * y + C[0], A[1] * min[0] + B[1] * y + C[1], A[2] * min[0] + B[2] * y + C[2] }; for (int x = min[0]; x <= max[0]; ++x) { // uvnitr trojuhelniku jsou cisla kladna if (e[0] >= 0 && e[1] >= 0 && e[2] >= 0) { // spocitame barycentricke koeficienty u,v,w double u = e[1] * _s1; double v = e[2] * _s2; double w = e[0] * _s0; // nemelo by nastat, protoze jsme uvnitr trojuhelniku //if (u < 0.0f || u > 1.0f) continue; //if (v < 0.0f || v > 1.0f) continue; //if (w < 0.0f || w > 1.0f) continue; // bod v trojuhelniku pred projekci ve 3D S_Coords pt = makeCoords( u * v1->x + v * v2->x + w * v3->x, u * v1->y + v * v2->y + w * v3->y, u * v1->z + v * v2->z + w * v3->z); /* gourandovo stinovani */ //double r = u * b1.red + v * b2.red + w * b3.red; //double g = u * b1.green + v * b2.green + w * b3.green; //double b = u * b1.blue + v * b2.blue + w * b3.blue; //double a = u * b1.alpha + v * b2.alpha + w * b3.alpha; //r = MIN(255.0f, MAX(r, 0.0f)); //g = MIN(255.0f, MAX(g, 0.0f)); //b = MIN(255.0f, MAX(b, 0.0f)); //a = MIN(255.0f, MAX(a, 0.0f)); //color.red = ROUND2BYTE(r); //color.green = ROUND2BYTE(g); //color.blue = ROUND2BYTE(b); //color.alpha = ROUND2BYTE(a); // vektor smerujici od bodu ke kamere S_Coords P_Cam = makeCoords( -pt.x, -pt.y, -pRenderer->camera_dist - pt.z); // vykreslime jen blizsi body double depth = sqrt(P_Cam.x * P_Cam.x + P_Cam.y * P_Cam.y + P_Cam.z * P_Cam.z); if (depth <= DEPTH(pRenderer, x, y)) { // normala bodu S_Coords n = makeCoords( u * n1->x + v * n2->x + w * n3->x, u * n1->y + v * n2->y + w * n3->y, u * n1->z + v * n2->z + w * n3->z); coordsNormalize(&n); S_RGBA color; color = pRenderer->calcReflectanceFunc(pRenderer, &pt, &n); /* vybarvi objekt normalou */ //color.red = ROUND2BYTE(255.0f * (n.x / 2.0f + 0.5f)); //color.green = ROUND2BYTE(255.0f * (n.y / 2.0f + 0.5f)); //color.blue = ROUND2BYTE(255.0f * (-n.z / 2.0f + 0.5f)); //color.alpha = 255; DEPTH(pRenderer, x, y) = depth; PIXEL(pRenderer, x, y) = color; } } // Ei(x+1,y) = Ei(x,y) + dy e[0] += A[0]; e[1] += A[1]; e[2] += A[2]; } } }