void PrintGeometricObject::PrintObject(GeometricObject& g) { // Todo cout << "GeometricObject\n"; cout << " circumference: " << g.Circumference() << " " << g.measurementUnit_ << "\n"; cout << " area: " << g.Area() << " " << g.measurementUnit_ << "^2\n\n"; }
int main() { GeometricObject shape; shape.setColor("red"); shape.setFilled(true); cout << shape.toString() << endl << endl; Circle circle(5); circle.setColor("black"); circle.setFilled(false); cout << circle.toString() << endl; cout << " Circle radius: " << circle.getRadius() << " area: " << circle.getArea() << " perimeter: " << circle.getPerimeter() << " \n" << endl; Rectangle rectangle(2, 3); rectangle.setColor("orange"); rectangle.setFilled(true); cout << rectangle.toString() << endl; cout << " Rectangle width: " << rectangle.getWidth() << " height: " << rectangle.getHeight() << " area: " << rectangle.getArea() << " perimeter: " << rectangle.getPerimeter() << " \n" << endl; return 0; }
void Window::notify() { Vector v_right = v_up->cross_product(*v_vpn); /* Parallel orthogonal projection matrix */ double _ft[][4] = { {v_right.x(), v_right.y(), v_right.z(), .0}, {v_up->x(), v_up->y(), v_up->z(), .0}, {v_vpn->x(), v_vpn->y(), v_vpn->z(), .0}, {v_translation->x(), v_translation->y(), v_translation->z(), 1.0} }; Matrix* translate_and_rotate = new Matrix(_ft); /* ---------- */ /* Perspective projection matrix */ double d = 10.0; double _p[][4] = { {1.0, .0, .0, .0 }, { .0, 1.0, .0, .0 }, { .0, .0, 1.0, -1.0 / d}, { .0, .0, .0, .0 } }; Matrix* perspective = new Matrix(_p); Matrix* all_perspective = Transformations::multiply(translate_and_rotate, perspective); /* ---------- */ // This fake display file MUST NOT have a window attached! DisplayFile* fakeDisplay = new DisplayFile(); for(GeometricObjectIterator it = displayFile->begin(); it < displayFile->end(); ++it) { GeometricObject* fakeObject = (*it)->clone(); if(projection == "orthogonal") { fakeObject->transform(translate_and_rotate); } if(projection == "perspective") { fakeObject->transform(all_perspective); fakeObject->planeW0(); } fakeDisplay->add_object(fakeObject); } // Send the fake objects to the ViewPort for(std::vector<ViewPort*>::iterator it = view_ports.begin(); it < view_ports.end(); ++it) { (*it)->notify(fakeDisplay->begin(), fakeDisplay->end()); } delete translate_and_rotate; delete all_perspective; delete perspective; }
bool hit(Point3d& impact, Rgb64f& reflection, const Point3d& camera_pos, const Vector3d& ray, const Point3d& light_pos) const { auto impact1 = Point3d{}; auto impact2 = Point3d{}; auto ref1 = Rgb64f{}; auto ref2 = Rgb64f{}; auto hit1 = _o1->hit(impact1, ref1, camera_pos, ray, light_pos); auto hit2 = _o2->hit(impact2, ref2, camera_pos, ray, light_pos); impact = impact1; reflection = ref1; return hit1 && hit2; }
// A function for displaying a geometric object void displayGeometricObject(GeometricObject &object) { cout << "The area is " << object.getArea() << endl; cout << "The perimeter is " << object.getPerimeter() << endl; GeometricObject *p = &object; Circle *p1 = dynamic_cast<Circle*>(p); Rectangle *p2 = dynamic_cast<Rectangle*>(p); if (p1 != 0) { cout << "The radius is " << p1->getRadius() << endl; cout << "The diameter is " << p1->getDiameter() << endl; } if (p2 != 0) { cout << "The width is " << p2->getWidth() << endl; cout << "The height is " << p2->getHeight() << endl; } }
RGBAPixel GeometricObject::rayTrace(PointLight& lightSrc, Point3D& pt, Ray& viewRay, vector<GeometricObject*>& shapes){ RGBAPixel color = material.color; if(texture != NULL) color = *mapToTexture(pt); Vector3D dir(lightSrc.o,pt); dir.normalize(); Point3D tempPt(pt+dir.reflect()*0.01); Ray backtraceRay(tempPt,dir.reflect(), "shadow"); //from hit point on shape to light source double tHitLight = lightSrc.o.distance(pt); bool shadow = false; Point3D trash(0,0,0); for(int i = 0; i < shapes.size(); i++){ if(shapes[i]->isLightSrc) continue; double tHitAnotherShape = shapes[i]->hit(backtraceRay,trash); if(tHitAnotherShape < tHitLight && tHitAnotherShape > 0){ shadow = true; break; } } //pt's intersection with viewRay and geometry Vector3D n(this->getNormal(pt)); n.normalize(); double r = 0.0; double g = 0.0; double b = 0.0; //Ambient Lighting r += 0.04 * 30; g += 0.04 * 30; b += 0.04 * 30; RGBAPixel temp(r*color.red, g*color.green ,b*color.blue); if(shadow){ return temp; } //Diffuse Lighting Vector3D reflectRay = (dir.reflect()).hat(); double product = reflectRay.dot(n); if (product > 0){ r += color.red*product * material.kd; g += color.green*product * material.kd; b += color.blue*product * material.kd; } //Specular Lighting double epsilon = 10.0; Vector3D rVec(dir - (n*dir.dot(n)*2.0)); double spec = rVec.dot(viewRay.d.reflect()); double rw0e; if(spec > 0) rw0e = pow(spec,epsilon); else rw0e = 0; if(product > 0){ r += color.red*rw0e * material.ks * 0.5; g += color.green*rw0e * material.ks * 0.5; b += color.blue*rw0e * material.ks * 0.5; } r = r*material.directScale; g = g*material.directScale; b = b*material.directScale; //Reflections double minTime = 100000.0; double tHitAnotherShape = 0.0; Vector3D recViewDir(viewRay.d - (2*viewRay.d*n)*n); //direction of mirror reflection recViewDir.normalize(); Ray recViewRay(pt,recViewDir, "view"); recViewRay.recurseLevel = viewRay.recurseLevel+1; Point3D recPt; RGBAPixel recColor; //Mirror Reflection if(material.reflectProperty == "mirror" && viewRay.recurseLevel < 3){ GeometricObject* nextShape = NULL; for(int k = 0; k < shapes.size(); k++){ if(shapes[k] == this) continue; tHitAnotherShape = shapes[k]->hit(recViewRay,recPt); if(tHitAnotherShape > 0.0 && tHitAnotherShape < minTime){ nextShape = shapes[k]; minTime = tHitAnotherShape; } } if(nextShape != NULL){ recColor = nextShape->rayTrace(lightSrc, recPt, recViewRay, shapes); r += (recColor.red); //* (1-material.directScale); g += (recColor.green);// * (1-material.directScale); b += (recColor.blue);// * (1-material.directScale); } } if(material.reflectProperty == "glossy" && viewRay.recurseLevel < 3){ double tempR = 0.0; double tempG = 0.0; double tempB = 0.0; Vector3D axisA = Vector3D(1,0,0).cross(recViewDir).hat() * 1; Vector3D axisB = axisA.cross(recViewDir).hat() * 1; Point3D tempPt = pt + recViewDir - 0.5*axisA - 0.5*axisB; Rectangle rect(tempPt, axisA, axisB); vector<Point3D> samplepts = rect.generatePoints(100); for(int i = 0; i < samplepts.size(); i++){ Vector3D indirectDir(pt,samplepts[i]); Ray indirectRay(pt,indirectDir); indirectRay.recurseLevel = viewRay.recurseLevel + 1; GeometricObject* nextShape = NULL; double minTime = 100000.0; double tHitAnotherShape = 0.0; for(int k = 0; k < shapes.size(); k++){ if(shapes[k] == this) continue; tHitAnotherShape = shapes[k]->hit(indirectRay,recPt); if(tHitAnotherShape > 0.0 && tHitAnotherShape < minTime){ nextShape = shapes[k]; minTime = tHitAnotherShape; } if(nextShape != NULL && nextShape->material.transparency == 0){ recColor = nextShape->rayTrace(lightSrc, recPt, recViewRay, shapes); tempR += (recColor.red); tempG += (recColor.green); tempB += (recColor.blue); } } } r += tempR / samplepts.size(); g += tempG / samplepts.size(); b += tempB / samplepts.size(); } if(material.transparency > 0 && viewRay.recurseLevel == 0){ double tempR = 255; double tempG = 255; double tempB = 255; Vector3D invNormal = n.reflect(); Ray inverseRay(pt,invNormal); inverseRay.recurseLevel = viewRay.recurseLevel + 1; GeometricObject* nextShape = NULL; double minTime = 100000.0; double tHitAnotherShape = 0.0; for(int k = 0; k < shapes.size(); k++){ if(shapes[k] == this) continue; tHitAnotherShape = shapes[k]->hit(inverseRay,recPt); if(tHitAnotherShape > 0.0 && tHitAnotherShape < minTime){ nextShape = shapes[k]; minTime = tHitAnotherShape; } if(nextShape != NULL && nextShape != this){ recColor = nextShape->rayTrace(lightSrc, recPt, inverseRay, shapes); tempR = (recColor.red); tempG = (recColor.green); tempB = (recColor.blue); } } r = tempR * material.transparency + (r*(1-material.transparency)); g = tempG * material.transparency + (g*(1-material.transparency)); b = tempB * material.transparency + (b*(1-material.transparency)); } //cap off maximum color values r =std::min((int)r,255); g =std::min((int)g,255); b =std::min((int)b,255); temp(r,g,b); return temp; }
RGBAPixel GeometricObject::rayTrace(AreaLight& lightSrc, Point3D& pt, Ray& viewRay, vector<GeometricObject*>& shapes){ double r = 0.0; double g = 0.0; double b = 0.0; int dim = 6; //6 for testing purposes. 25 for production purposes. int total_rays = dim*dim; vector<Point3D> lightPts = lightSrc.shape.generatePoints(total_rays); for(int i = 0; i < dim; i++){ for(int j = 0; j < dim; j++){ Point3D samplePt(lightPts[i*dim+j]); Vector3D dir(pt, samplePt); //direction from shape hit point to light source dir.normalize(); Point3D rayPt(pt+(dir*0.01)); Ray backtraceRay(rayPt,dir, "shadow"); //ray from hit point on shape to light source double tHitLight = samplePt.distance(rayPt); bool hitShape = false; Point3D trash(0,0,0); for(int k = 0; k < shapes.size(); k++){ if(shapes[k] == this) continue; double tHitAnotherShape = shapes[k]->hit(backtraceRay,trash); if(tHitAnotherShape > 0 && tHitAnotherShape < tHitLight){ hitShape = true; break; } } if(!hitShape){ PointLight ptLt(samplePt, 1, material.kd, material.ks); RGBAPixel tempPixel = rayTrace(ptLt, pt, viewRay, shapes); r += tempPixel.red; g += tempPixel.green; b += tempPixel.blue; } r = r*material.directScale; g = g*material.directScale; b = b*material.directScale; //Mirror Reflection if(viewRay.recurseLevel < 3){ Vector3D n(this->getNormal(pt)); Vector3D recViewDir(viewRay.d - (2*viewRay.d*n)*n); recViewDir.normalize(); Ray recViewRay(pt,recViewDir, "view"); recViewRay.recurseLevel = viewRay.recurseLevel+1; Point3D recPt; RGBAPixel recColor; GeometricObject* nextShape = NULL; double minTime = 100000.0; double tHitAnotherShape = 0.0; for(int k = 0; k < shapes.size(); k++){ if(shapes[k] == this) continue; tHitAnotherShape = shapes[k]->hit(recViewRay,recPt); if(tHitAnotherShape > 0.0 && tHitAnotherShape < minTime){ nextShape = shapes[k]; minTime = tHitAnotherShape; } } if(nextShape != NULL){ recColor = nextShape->rayTrace(lightSrc, recPt, recViewRay, shapes); r += (recColor.red); g += (recColor.green); b += (recColor.blue); } } } } r = r / total_rays * 1.5; g = g / total_rays * 1.5; b = b / total_rays * 1.5; r =std::min((int)r,255); g =std::min((int)g,255); b =std::min((int)b,255); RGBAPixel pixel(r,g,b); return pixel; }
// A function for computing the areas of two geometric objects bool equalArea(GeometricObject &object1, GeometricObject &object2) { return object1.getArea() == object2.getArea(); }
// A function for displaying a geometric object void displayGeometricObject(GeometricObject &object) { cout << "The area is " << object.getArea() << endl; cout << "The parimeter is " << object.getPerimeter() << endl; }
bool contains(const Point3d& p) const { return _o1->contains(p) && !_o2->contains(p); }
void draw_frame(Device *device) { SR_CHECK_ERROR("Begin RenderFrame"); RenderState &render_state = device->render_state(); vec4ub color(77, 77, 77, 255); render_state.ClearBuffer(true, true, false, color); //3d device->render_state().Set3D(); depth_fbo.Bind(); //fbo로 그리기. deferred같은거 구현하기 위해서 임시로 시도함 device->render_state().Set3D(); render_state.ClearBuffer(true, true, false, color); VertexList vert_list; vert_list.push_back(CreateVertex(vec3(-0.5, -0.5, 0), vec2(0, 0))); vert_list.push_back(CreateVertex(vec3(0.5, -0.5, 0), vec2(1, 0))); vert_list.push_back(CreateVertex(vec3(0, 0.5, 0), vec2(0.5, 1))); //vbo, ibo 적절히 만들기 if(vbo.Loaded() == false) { vbo.Init(vert_list); } if(wire_ibo.Loaded() == false) { IndexList index_list; index_list.push_back(0); index_list.push_back(1); index_list.push_back(1); index_list.push_back(2); index_list.push_back(2); index_list.push_back(0); wire_ibo.Init(index_list); } { //shader사용 선언이 가장 먼저 device->render_state().UseShader(color_shader); SR_CHECK_ERROR("UseShader"); mat4 mvp(1.0f); ShaderVariable mvp_var = color_shader.uniform_var(kMVPHandleName); SetUniformMatrix(mvp_var, mvp); vec4 color(1.0f); ShaderVariable const_color_var = color_shader.uniform_var(kConstColorHandleName); SetUniformVector(const_color_var, color); SR_CHECK_ERROR("SetVector"); color_shader.SetVertexList(vert_list); color_shader.DrawArrays(kDrawTriangles, vert_list.size()); color_shader.DrawArrays(kDrawTriangles, vbo); color_shader.DrawElements(kDrawLines, vbo, wire_ibo); } { //shader사용 선언이 가장 먼저 device->render_state().UseShader(simple_shader); TexturePtr tex = device->tex_mgr()->Get("sora"); device->render_state().UseTexture(*tex, 0); SR_CHECK_ERROR("UseShader"); mat4 mvp(1.0f); mvp = glm::rotate(mvp, 10.0f, vec3(0, 0, 1)); ShaderVariable mvp_var = simple_shader.uniform_var(kMVPHandleName); SetUniformMatrix(mvp_var, mvp); SR_CHECK_ERROR("SetMatrix"); simple_shader.SetVertexList(vert_list); simple_shader.DrawArrays(kDrawTriangles, vert_list.size()); } //일반 3d객체 그리기+카메라 회전 장착 { //set camera + projection float win_width = (float)device->render_state().win_width(); float win_height = (float)device->render_state().win_height(); glm::mat4 projection = glm::perspective(45.0f, win_width / win_height, 0.1f, 100.0f); float radius = 4; float cam_x = radius * cos(SR_DEG_2_RAD(aptitude)) * sin(SR_DEG_2_RAD(latitude)); float cam_y = radius * sin(SR_DEG_2_RAD(aptitude)); float cam_z = radius * cos(SR_DEG_2_RAD(aptitude)) * cos(SR_DEG_2_RAD(latitude)); vec3 eye(cam_x, cam_y, cam_z); vec3 center(0); vec3 up(0, 1, 0); glm::mat4 view = glm::lookAt(eye, center, up); glm::mat4 mvp(1.0f); mvp = projection * view; ShaderVariable mvp_var = simple_shader.uniform_var(kMVPHandleName); SetUniformMatrix(mvp_var, mvp); SR_CHECK_ERROR("SetMatrix"); GeometricObject<Vertex> mesh; //mesh.PointTeapot(0.05f); //mesh.WireTeapot(0.05f); //mesh.SolidTeapot(0.05f); //mesh.WireShpere(1, 16, 16); //mesh.PointShpere(1, 16, 16); //mesh.SolidSphere(1, 16, 16); //mesh.SolidCube(1, 1, 1); //mesh.WireCube(1, 1, 1); mesh.PointCube(1, 1, 1); //mesh.PointCylinder(1, 1, 2, 8, 8); //mesh.WireCylinder(1, 1, 2, 8, 8); mesh.SolidCylinder(1, 1, 2, 8, 8); //mesh.WireAxis(5); //mesh.SolidPlane(3); //mesh.WirePlane(3, 0.1f); //mesh.SolidTorus(1, 0.1); //mesh.SolidCone(2, 2); auto it = mesh.Begin(); auto endit = mesh.End(); for( ; it != endit ; ++it) { const DrawCmdData<Vertex> &cmd = *it; //앞면 뒷면 그리기를 허용/불가능 정보까지 내장해야 //뚜껑없는 원통 그리기가 편하다 if(cmd.disable_cull_face == true) { glDisable(GL_CULL_FACE); } simple_shader.SetVertexList(cmd.vertex_list); if(cmd.index_list.empty()) { simple_shader.DrawArrays(cmd.draw_mode, cmd.vertex_list.size()); } else { simple_shader.DrawElements(cmd.draw_mode, cmd.index_list); } if(cmd.disable_cull_face == true) { glEnable(GL_CULL_FACE); } } } depth_fbo.Unbind(); /* //fbo에 있는 내용을 적절히 그리기 { device->render_state().Set2D(); device->render_state().UseShader(simple_shader); ShaderVariable mvp_var = simple_shader.uniform_var(kMVPHandleName); mat4 world_mat(1.0f); SetUniformMatrix(mvp_var, world_mat); //device->render_state().UseTexture(depth_fbo.color_tex()); device->render_state().UseTexture(depth_fbo.depth_tex()); Vertex2DList vert_list; vert_list.push_back(CreateVertex2D(-1, -1, 0, 0)); vert_list.push_back(CreateVertex2D(1, -1, 1, 0)); vert_list.push_back(CreateVertex2D(1, 1, 1, 1)); vert_list.push_back(CreateVertex2D(-1, 1, 0, 1)); simple_shader.SetVertexList(vert_list); simple_shader.DrawArrays(kDrawTriangleFan, vert_list.size()); } */ null_post_effect.DrawScissor(depth_fbo.color_tex(), 0, 0, 320, 480); grayscale_post_effect.DrawScissor(depth_fbo.color_tex(), 320, 0, 320, 480); grayscale_post_effect.Draw(depth_fbo.color_tex(), 100, 100, 100, 100); SR_CHECK_ERROR("End RenderFrame"); }