void RenderImage( double time, const Mat4f& torus_matrix, const Mat4f& light_proj_matrix ) { // this is going into the on-screen framebuffer DefaultFramebuffer().Bind(Framebuffer::Target::Draw); gl.ClearColor(1.0f, 0.9f, 0.8f, 0.0f); gl.Viewport(width, height); gl.Clear().ColorBuffer().DepthBuffer(); gl.CullFace(Face::Back); // transf_prog.light_proj_matrix.Set(light_proj_matrix); Mat4f perspective = CamMatrixf::PerspectiveX( Degrees(60), float(width)/height, 1, 60 ); // setup the camera Vec3f camera_target(0.0f, 0.8f, 0.0f); auto camera = CamMatrixf::Orbiting( camera_target, GLfloat(7.0 - SineWave(time / 14.0)*3.0), FullCircles(time / 26.0), Degrees(45 + SineWave(time / 17.0) * 40) ); Vec3f camera_position = camera.Position(); transf_prog.camera_matrix.Set(perspective*camera); transf_prog.camera_position.Set(camera_position); // render into the depth buffer shadow_pp.Bind(); gl.Enable(Capability::PolygonOffsetFill); gl.ColorMask(false, false, false, false); transf_prog.model_matrix = ModelMatrixf(); plane.Draw(); transf_prog.model_matrix.Set(torus_matrix); torus.Draw(); gl.ColorMask(true, true, true, true); gl.Disable(Capability::PolygonOffsetFill); gl.Enable(Capability::Blend); gl.Disable(Capability::Blend); // render into the color buffer sketch_pp.Bind(); gl.Enable(Capability::Blend); transf_prog.model_matrix = ModelMatrixf(); transf_prog.texture_matrix.Set(Mat2f(Vec2f(3.0, 0.0), Vec2f(0.0, 3.0))); plane.Draw(); transf_prog.model_matrix.Set(torus_matrix); transf_prog.texture_matrix.Set(Mat2f(Vec2f(8.0, 0.0), Vec2f(0.0, 2.0))); torus.Draw([](GLuint phase) -> bool { return phase < 4; }); transf_prog.texture_matrix.Set(Mat2f(Vec2f(0.0, 2.0), Vec2f(8.0, 0.0))); torus.Draw([](GLuint phase) -> bool { return phase >= 4; }); // render the edges line_pp.Bind(); transf_prog.model_matrix = ModelMatrixf(); plane.DrawEdges(); transf_prog.model_matrix.Set(torus_matrix); torus.DrawEdges(); gl.Disable(Capability::Blend); }
void RenderImage( double time, const Vec3f& torus_center, const Mat4f& torus_matrix, const Mat4f& light_proj_matrix ) { // this is going into the on-screen framebuffer DefaultFramebuffer().Bind(Framebuffer::Target::Draw); gl.ClearColor(0.6f, 0.6f, 0.5f, 0.0f); gl.Viewport(width, height); gl.Clear().ColorBuffer().DepthBuffer(); gl.CullFace(Face::Back); // transf_prog.light_proj_matrix.Set(light_proj_matrix); Mat4f perspective = CamMatrixf::PerspectiveX( Degrees(60), float(width)/height, 1, 60 ); // setup the camera Vec3f camera_target(0.0f, 0.8f, 0.0f); auto camera = CamMatrixf::Orbiting( camera_target, GLfloat(8.0 - SineWave(time / 15.0)*3.0), FullCircles(time / 24.0), Degrees(45 + SineWave(time / 20.0) * 40) ); Vec3f camera_position = camera.Position(); transf_prog.camera_matrix.Set(perspective*camera); transf_prog.camera_position.Set(camera_position); // setup the view clipping plane Planef clip_plane = Planef::FromPointAndNormal( torus_center, Normalized(camera_position-torus_center) ); metal_pp.Bind(); // Render the plane transf_prog.model_matrix = ModelMatrixf(); transf_prog.texture_matrix.Set(Mat2f(Vec2f(9.0f,0.0f), Vec2f(0.0f,9.0f))); metal_prog.color_1 = Vec3f(1.0f, 0.9f, 0.8f); metal_prog.color_2 = Vec3f(0.9f, 0.8f, 0.6f); metal_prog.with_glass_shadow = 1; plane.Draw([](GLuint) -> bool {return true;}); // Render the torus transf_prog.model_matrix.Set(torus_matrix); transf_prog.texture_matrix.Set(Mat2f(Vec2f(16.0f,0.0f), Vec2f(0.0f, 4.0f))); metal_prog.metal_tex.Set(0); metal_prog.color_1 = Vec3f(0.9f, 0.9f, 0.9f); metal_prog.color_2 = Vec3f(0.3f, 0.3f, 0.3f); metal_prog.with_glass_shadow = 0; // the metal-part torus.Draw( [](GLuint phase) -> bool { return (phase <= 3); } ); // now the glass part glass_pp.Bind(); glass_prog.color = Vec3f(0.6f, 0.4f, 0.1f); gl.Enable(Functionality::ClipDistance, 0); gl.Enable(Capability::Blend); transf_prog.clip_plane.Set(clip_plane.Equation()); for(int c=0; c!=2; ++c) { transf_prog.clip_direction.Set((c == 0)?-1:1); for(int p=0; p!=4; ++p) { if(p % 2 == 0) gl.CullFace(Face::Front); else gl.CullFace(Face::Back); torus.Draw( [&p](GLuint phase) -> bool { if(p == 0 || p == 3) return (phase == 4); else return (phase > 4); } ); } } gl.Disable(Capability::Blend); gl.Disable(Functionality::ClipDistance, 0); }
void wmonkey_scene_2() { printf("WOODEN MONKEY SCENE : 2 (path tracing) ----------------------------------\n\n"); Raytracer rt; int width = 16 * 20 * 2; int height = 12 * 20 * 2; // room dimensions double wDiameter = 20; double wRadius = wDiameter / 2; double wallSize[] = {wDiameter + DBL_EPSILON, wDiameter + DBL_EPSILON, wDiameter + DBL_EPSILON}; // Camera parameters. Point3D camera_pos(0, 0, 1); Vector3D camera_target(0, 0, -1); Vector3D up(0, 1, 0); double fov = 65; double l0c = .9; PointLight * light0 = new PointLight( // Point3D(-wDiameter - roomRad + (roomRad / 2), 50 * 2, 50 * 2), Point3D(0, wRadius - 5, 0), Colour(l0c, l0c, l0c), 0.2); rt.addLightSource(light0); // http://en.wikipedia.org/wiki/Cornell_Box // http://www.kevinbeason.com/smallpt/#moreinfo Material matLight( Colour(1, 1, 1) // ambient , Colour(1, 1, 1) // diffuse , Colour(1, 1, 1) // spec , 0, 0, 0, 0 ); Material matMirror( Colour(0.3, 0.3, 0.3) // ambient , Colour(0.1, 0.1, 0.1) // diffuse , Colour(0.628281, 0.555802, 0.366065) // spec , 51.2, 1.0 ); Material matGlass( Colour(0, 0, 0) // ambient , Colour(0.1, 0.1, 0.1) // diffuse , Colour(1.0, 1.0, 1.0) // spec , 100, 0.0, 1.01, 0.9 ); Material matBeige( Colour(0.607843, 0.549019, 0.372549) // ambient , Colour(0.741176, 0.686274, 0.525490) // diffuse , Colour(0.933333, 0.901960, 0.807843) // spec , 12.8 ); Material matReddishWall( Colour(.25, .25, .25) // ambient , Colour(.75, .25, .25) // diffuse , Colour(.3, .3, .3) // spec , 2, 0, 0, 0 ); Material matBluishWall( Colour(.25, .25, .25) // ambient , Colour(.25, .25, .75) // diffuse , Colour(.3, .3, .3) // spec , 2, 0, 0, 0 ); Material matGreenishWall( Colour(.25, .25, .25) // ambient , Colour(.25, .75, .25) // diffuse , Colour(.3, .3, .3) // spec , 2, 0, 0, 0 ); Material matBaseWall( Colour(.25, .25, .25) // ambient , Colour(.25, .25, .25) // diffuse , Colour(.6, .6, .6) // spec , 2, 0, 0, 0 ); // create and position the box SceneDagNode* wallLeft = rt.addObject( new UnitSquare(), &matReddishWall ); SceneDagNode* wallRight = rt.addObject( new UnitSquare(), &matBluishWall ); SceneDagNode* wallFront = rt.addObject( new UnitSquare(), &matBaseWall ); SceneDagNode* wallTop = rt.addObject( new UnitSquare(), &matLight ); SceneDagNode* wallBot = rt.addObject( new UnitSquare(), &matGreenishWall ); rt.translate(wallFront, Vector3D(0, 0, -wDiameter - wRadius + DBL_EPSILON)); rt.scale(wallFront, Point3D(0, 0, 0), wallSize); rt.translate(wallRight, Vector3D(wRadius, 0, -wDiameter + DBL_EPSILON)); rt.rotate(wallRight, 'y', -90); rt.scale(wallRight, Point3D(0, 0, 0), wallSize); rt.translate(wallLeft, Vector3D(-wRadius, 0, -wDiameter + DBL_EPSILON)); rt.rotate(wallLeft, 'y', 90); rt.scale(wallLeft, Point3D(0, 0, 0), wallSize); rt.translate(wallTop, Vector3D(0, wRadius, -wDiameter + DBL_EPSILON)); rt.rotate(wallTop, 'x', 90); rt.scale(wallTop, Point3D(0, 0, 0), wallSize); rt.translate(wallBot, Vector3D(0, -wRadius, -wDiameter + DBL_EPSILON)); rt.rotate(wallBot, 'x', -90); rt.scale(wallBot, Point3D(0, 0, 0), wallSize); // create some objects within the box... SceneDagNode* sphere_chrome = rt.addObject( new UnitSphere(), &matGlass ); double _sChrome_size = 2; double _sChrome[] = {_sChrome_size, _sChrome_size, _sChrome_size}; rt.translate(sphere_chrome, Vector3D(wRadius / 3 * 2, -wRadius + (_sChrome_size), -wDiameter + (wRadius / 3))); rt.scale(sphere_chrome, Point3D(0, 0, 0), _sChrome); SceneDagNode* sphere_glass = rt.addObject( new UnitSphere(), &matMirror ); double _sGlass_size = 2.5; double _sGlass[] = {_sGlass_size, _sGlass_size, _sGlass_size}; rt.translate(sphere_glass, Vector3D(-wRadius / 3 * 2, -wRadius + (_sGlass_size), -wDiameter - (wRadius / 3))); rt.scale(sphere_glass, Point3D(0, 0, 0), _sGlass); SceneDagNode* sphere_beige = rt.addObject( new UnitSphere(), &matBeige ); double _sBeige_size = 3.5; double _sBeige[] = {_sBeige_size, _sBeige_size, _sBeige_size}; rt.translate(sphere_beige, Vector3D(wRadius / 3 * 2, -wRadius + (_sGlass_size * 2), -wDiameter - (wRadius / 3))); rt.scale(sphere_beige, Point3D(0, 0, 0), _sBeige); rt.setAAMode(Raytracer::AA_SUPER_SAMPLING); rt.setAAMode(Raytracer::NONE); rt.setShadingMode(Raytracer::SCENE_MODE_DIFFUSE); rt.setShadows(Raytracer::SHADOW_CAST); rt.setEnvMapMode(Raytracer::ENV_MAP_CUBE_SKYBOX); // rt.setColorSpaceMode(Raytracer::COLOR_ENC_SRGB_GAMMA_CORRECT); rt.setReflDepth(4); // refraction if it's turned on if (REFRACTION_FLAG) { rt.setRefractionMode(REFRACTION_FLAG); } if ( rt.getEnvMapMode() != Raytracer::NONE ) { // load images EnvMap env; if ( _DEBUG ) { env = EnvMap( "EnvMaps/DebugMaps/posx.bmp", "EnvMaps/DebugMaps/posy.bmp", "EnvMaps/DebugMaps/posz.bmp", "EnvMaps/DebugMaps/negx.bmp", "EnvMaps/DebugMaps/negy.bmp", "EnvMaps/DebugMaps/negz.bmp" ); } else { env = EnvMap( "EnvMaps/SaintLazarusChurch/posx.bmp", "EnvMaps/SaintLazarusChurch/posy.bmp", "EnvMaps/SaintLazarusChurch/posz.bmp", "EnvMaps/SaintLazarusChurch/negx.bmp", "EnvMaps/SaintLazarusChurch/negy.bmp", "EnvMaps/SaintLazarusChurch/negz.bmp" ); } rt.setEnvMap(env); } printf("WOODEN MONKEY SCENE : 2 :: Rendering...\n"); rt.render(width, height, camera_pos, camera_target, up, fov, "wmonkey_2.bmp"); printf("WOODEN MONKEY SCENE : 2 :: Done!\n"); }