/* virtual */ void sphere::do_changed(field::base& f) { TRACE("hugh::scene::object::geometry::do_changed"); if (&f == &subdivision) { attribute_list_.clear(); index_list_ .clear(); octahedron const oct; for (auto const& a : oct.attributes.get()) { // why doesn't '*oct.attributes' work here? add_point(a.position, attribute_list_); } unsigned running_idx(unsigned((*oct.attributes).size())); for (unsigned i(0); i < (*oct.indices).size(); i += 3) { subdivide_triangle((*oct.indices)[i+0], (*oct.indices)[i+1], (*oct.indices)[i+2], *subdivision, attribute_list_, index_list_, running_idx); } compute_bounds(); compute_tangents(); } else { base::do_changed(f); } }
//--------------------------------------------------------------------------------------- void GmoShapeSlurTie::on_handler_dragged(int iHandler, UPoint newPos) { m_points[iHandler] = newPos; compute_vertices(); compute_bounds(); make_points_and_vertices_relative_to_origin(); }
Overlap compute_overlap(Polygon* p1, Polygon* p2) { Bounds b1 = compute_bounds(p1); Bounds b2 = compute_bounds(p2); int x = MIN(b1.left, b2.left); int y = MIN(b1.top, b2.top); int width = MAX(b1.right, b2.right) - x; int height = MAX(b1.bottom, b2.bottom) - y; char* mask1 = new char[width * height]; char* mask2 = new char[width * height]; Polygon* op1 = offset_polygon(p1, -x, -y); Polygon* op2 = offset_polygon(p2, -x, -y); /* print_polygon(p1);print_polygon(p2); print_polygon(op1);print_polygon(op2); */ rasterize_polygon(op1, mask1, width, height); rasterize_polygon(op2, mask2, width, height); int mask_1 = 0, mask_2 = 0, mask_intersect = 0; for (int i = 0; i < width * height; i++) { if (mask1[i] && mask2[i]) mask_intersect++; else if (mask1[i]) mask_1++; else if (mask2[i]) mask_2++; } free_polygon(op1); free_polygon(op2); delete[] mask1; delete[] mask2; Overlap overlap; overlap.overlap = (float) mask_intersect / (float) (mask_1 + mask_2 + mask_intersect); overlap.only1 = (float) mask_1 / (float) (mask_1 + mask_2 + mask_intersect); overlap.only2 = (float) mask_2 / (float) (mask_1 + mask_2 + mask_intersect); return overlap; }
bool SkLayerRasterizer::onRasterize(const SkPath& path, const SkMatrix& matrix, const SkIRect* clipBounds, SkMask* mask, SkMask::CreateMode mode) const { SkASSERT(fLayers); if (fLayers->empty()) { return false; } if (SkMask::kJustRenderImage_CreateMode != mode) { if (!compute_bounds(*fLayers, path, matrix, clipBounds, &mask->fBounds)) return false; } if (SkMask::kComputeBoundsAndRenderImage_CreateMode == mode) { mask->fFormat = SkMask::kA8_Format; mask->fRowBytes = mask->fBounds.width(); size_t size = mask->computeImageSize(); if (0 == size) { return false; // too big to allocate, abort } mask->fImage = SkMask::AllocImage(size); memset(mask->fImage, 0, size); } if (SkMask::kJustComputeBounds_CreateMode != mode) { SkBitmap device; SkRasterClip rectClip; SkDraw draw; SkMatrix translatedMatrix; // this translates us to our local pixels SkMatrix drawMatrix; // this translates the path by each layer's offset rectClip.setRect(SkIRect::MakeWH(mask->fBounds.width(), mask->fBounds.height())); translatedMatrix = matrix; translatedMatrix.postTranslate(-SkIntToScalar(mask->fBounds.fLeft), -SkIntToScalar(mask->fBounds.fTop)); device.installMaskPixels(*mask); draw.fBitmap = &device; draw.fMatrix = &drawMatrix; draw.fRC = &rectClip; draw.fClip = &rectClip.bwRgn(); // we set the matrixproc in the loop, as the matrix changes each time (potentially) SkDeque::F2BIter iter(*fLayers); SkLayerRasterizer_Rec* rec; while ((rec = (SkLayerRasterizer_Rec*)iter.next()) != NULL) { drawMatrix = translatedMatrix; drawMatrix.preTranslate(rec->fOffset.fX, rec->fOffset.fY); draw.drawPath(path, rec->fPaint); } } return true; }
/* explicit */ octahedron::octahedron() : node::geometry() { TRACE("scene::primitive::octahedron::octahedron"); make_octahedron(attribute_list_, index_list_); compute_bounds(); compute_tangents(); }
bool SkLayerRasterizer::onRasterize(const SkPath& path, const SkMatrix& matrix, const SkIRect* clipBounds, SkMask* mask, SkMask::CreateMode mode) { if (fLayers.empty()) return false; if (SkMask::kJustRenderImage_CreateMode != mode) { if (!compute_bounds(fLayers, path, matrix, clipBounds, &mask->fBounds)) return false; } if (SkMask::kComputeBoundsAndRenderImage_CreateMode == mode) { mask->fFormat = SkMask::kA8_Format; mask->fRowBytes = SkToU16(mask->fBounds.width()); mask->fImage = SkMask::AllocImage(mask->computeImageSize()); memset(mask->fImage, 0, mask->computeImageSize()); } if (SkMask::kJustComputeBounds_CreateMode != mode) { SkBitmap device; SkDraw draw; SkMatrix translatedMatrix; // this translates us to our local pixels SkMatrix drawMatrix; // this translates the path by each layer's offset SkRegion rectClip; rectClip.setRect(0, 0, mask->fBounds.width(), mask->fBounds.height()); translatedMatrix = matrix; translatedMatrix.postTranslate(-SkIntToScalar(mask->fBounds.fLeft), -SkIntToScalar(mask->fBounds.fTop)); device.setConfig(SkBitmap::kA8_Config, mask->fBounds.width(), mask->fBounds.height(), mask->fRowBytes); device.setPixels(mask->fImage); draw.fBitmap = &device; draw.fMatrix = &drawMatrix; draw.fClip = &rectClip; // we set the matrixproc in the loop, as the matrix changes each time (potentially) draw.fBounder = NULL; SkDeque::Iter iter(fLayers); SkLayerRasterizer_Rec* rec; while ((rec = (SkLayerRasterizer_Rec*)iter.next()) != NULL) { drawMatrix = translatedMatrix; drawMatrix.preTranslate(rec->fOffset.fX, rec->fOffset.fY); draw.drawPath(path, rec->fPaint); } } return true; }
//======================================================================================= // GmoShapeSlurTie implementation //======================================================================================= GmoShapeSlurTie::GmoShapeSlurTie(ImoObj* pCreatorImo, int objtype, ShapeId idx, UPoint* points, LUnits thickness, Color color) : GmoSimpleShape(pCreatorImo, objtype, idx, color) , VertexSource() , m_thickness(thickness) { save_points(points); compute_vertices(); compute_bounds(); make_points_and_vertices_relative_to_origin(); }
/* explicit */ tetrahedron::tetrahedron() : base() { TRACE("hugh::scene::object::geometry::tetrahedron::tetrahedron"); attribute_list_.clear(); index_list_ .clear(); make_tetrahedron(attribute_list_, index_list_); compute_bounds(); compute_tangents(); }
/* explicit */ cube::cube() : base() { TRACE("hugh::scene::object::geometry::cube::cube"); attribute_list_.clear(); index_list_ .clear(); make_cube(attribute_list_, index_list_); compute_bounds(); compute_tangents(); }
/* virtual */ void cylinder::do_changed(field::base& f) { TRACE("scene::primitive::cylinder::do_changed"); if (&f == &sides) { make_cylinder(*sides, attribute_list_, index_list_); compute_bounds(); compute_tangents(); } else { node::geometry::do_changed(f); } }
ExperimentalApp() : GLFWApp(1280, 720, "Shadow App") { glfwSwapInterval(0); gen = std::mt19937(rd()); igm.reset(new gui::ImGuiManager(window)); gui::make_dark_theme(); int width, height; glfwGetWindowSize(window, &width, &height); glViewport(0, 0, width, height); cameraController.set_camera(&camera); camera.farClip = 55.f; camera.look_at({0, 0, +15}, {0, 0, 0}); // Debugging views uiSurface.bounds = {0, 0, (float) width, (float) height}; uiSurface.add_child( {{0.0000f, +10},{0, +10},{0.1667f, -10},{0.133f, +10}}); uiSurface.add_child( {{0.1667f, +10},{0, +10},{0.3334f, -10},{0.133f, +10}}); uiSurface.add_child( {{0.3334f, +10},{0, +10},{0.5009f, -10},{0.133f, +10}}); uiSurface.add_child( {{0.5000f, +10},{0, +10},{0.6668f, -10},{0.133f, +10}}); uiSurface.add_child( {{0.6668f, +10},{0, +10},{0.8335f, -10},{0.133f, +10}}); uiSurface.add_child( {{0.8335f, +10},{0, +10},{1.0000f, -10},{0.133f, +10}}); uiSurface.layout(); fullscreen_post_quad = make_fullscreen_quad(); sceneShader = make_watched_shader(shaderMonitor, "assets/shaders/shadow/scene_vert.glsl", "assets/shaders/shadow/scene_frag.glsl"); shadowmapShader = make_watched_shader(shaderMonitor, "assets/shaders/shadow/shadowmap_vert.glsl", "assets/shaders/shadow/shadowmap_frag.glsl"); pointLightShader = make_watched_shader(shaderMonitor, "assets/shaders/shadow/point_light_vert.glsl", "assets/shaders/shadow/point_light_frag.glsl"); gaussianBlurShader = make_watched_shader(shaderMonitor, "assets/shaders/gaussian_blur_vert.glsl", "assets/shaders/gaussian_blur_frag.glsl"); skydome.recompute(2, 10.f, 1.15f); auto lightDir = skydome.get_light_direction(); sunLight = std::make_shared<DirectionalLight>(lightDir, float3(.50f, .75f, .825f), 64.f); // todo spotLightB shadowDepthTexture.load_data(shadowmapResolution, shadowmapResolution, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); shadowFramebuffer.attach(GL_DEPTH_ATTACHMENT, shadowDepthTexture); if (!shadowFramebuffer.check_complete()) throw std::runtime_error("incomplete shadow framebuffer"); shadowBlurTexture.load_data(shadowmapResolution, shadowmapResolution, GL_R32F, GL_RGBA, GL_FLOAT, nullptr); shadowBlurFramebuffer.attach(GL_COLOR_ATTACHMENT0, shadowBlurTexture); if (!shadowBlurFramebuffer.check_complete()) throw std::runtime_error("incomplete blur framebuffer"); auto spotLightA = std::make_shared<SpotLight>(float3(0.f, 10.f, 0.f), float3(0.f, -1.f, 0.f), float3(0.766f, 0.766f, 0.005f), 30.0f, float3(1.0f, 0.0f, 0.0001f)); spotLights.push_back(spotLightA); // Single spotlight fbo for (int i = 0; i < 1; ++i) { auto buffer = std::make_shared<SpotLightFramebuffer>(); buffer->create(shadowmapResolution); spotLightFramebuffers.push_back(buffer); } // Point light init { pointLight.reset(new PointLight(float3(0.f, 0.f, 0.f), float3(0, 1, 1), float3(1.0f, 0.05f, 0.0002f))); pointLightFramebuffer.reset(new PointLightFramebuffer()); pointLightFramebuffer->create(float2(shadowmapResolution)); pointLightSphere = std::make_shared<Renderable>(make_sphere(0.5f)); sceneObjects.push_back(pointLightSphere); } viewA.reset(new GLTextureView(shadowDepthTexture.get_gl_handle())); viewB.reset(new GLTextureView(shadowBlurTexture.get_gl_handle())); viewC.reset(new GLTextureView(spotLightFramebuffers[0]->shadowDepthTexture.get_gl_handle())); viewD.reset(new GLTextureView(pointLightFramebuffer->depthBuffer.get_gl_handle())); auto lucy = load_geometry_from_ply("assets/models/stanford/lucy.ply"); rescale_geometry(lucy, 8.0f); auto lucyBounds = lucy.compute_bounds(); auto statue = std::make_shared<Renderable>(lucy); statue->pose.position = {0, 0, 0}; //sceneObjects.push_back(statue); auto hollowCube = load_geometry_from_ply("assets/models/geometry/CubeHollowOpen.ply"); for (auto & v : hollowCube.vertices) v *= 0.20f; auto hCube = std::make_shared<Renderable>(hollowCube); hCube->pose.position = float3(0, 0, 0); hCube->pose.orientation = make_rotation_quat_around_x(ANVIL_PI / 2); //sceneObjects.push_back(hCube); auto curvedMesh = make_curved_plane(2, 1, 8, 8); sceneObjects.push_back(std::make_shared<Renderable>(curvedMesh)); //floor = std::make_shared<Renderable>(make_plane(32.f, 32.f, 64, 64), false); //floor->pose.orientation = make_rotation_quat_axis_angle({1, 0, 0}, -ANVIL_PI / 2); //floor->pose.position = {0, lucyBounds.min().y, 0}; //sceneObjects.push_back(floor); gl_check_error(__FILE__, __LINE__); }