/* SImage::maskFromColour * Changes the mask/alpha channel so that pixels that match [colour] * are fully transparent, and all other pixels fully opaque *******************************************************************/ bool SImage::maskFromColour(rgba_t colour, Palette8bit* pal) { if (type == PALMASK) { // Get palette to use if (has_palette || !pal) pal = &palette; // Palette+Mask type, go through the mask for (int a = 0; a < width * height; a++) { if (pal->colour(data[a]).equals(colour)) mask[a] = 0; else mask[a] = 255; } } else if (type == RGBA) { // RGBA type, go through alpha channel uint32_t c = 0; for (int a = 0; a < width * height; a++) { rgba_t pix_col(data[c], data[c + 1], data[c + 2], 255); if (pix_col.equals(colour)) data[c + 3] = 0; else data[c + 3] = 255; // Skip to next pixel c += 4; } } else return false; // Announce change announce("image_changed"); return true; }
Color Scene::ray_to_raster(const Ray& r, unsigned int depth) { float raymin; ShadeHint hitsh; int ox = 0; int oy = 0; SceneObject *curobj = getClosestObject(r, &raymin, &hitsh); if (curobj == nullptr) { return BG_COLOR; } else { Color pix_col(ambient_light); // we've intesected an object #ifdef SOFT_SHADOW for (int i = 0; i < 4; i++) { for (ox = 0; ox < 2; ox++) { for (oy = 0; oy < 2; oy++) { #endif for (auto &light : lights) { const Ray& shadowRay = r.createShadowRay(ox*0.2, oy*0.2, raymin, light); if (hasNoObjectIntersections(curobj, shadowRay)) { switch (curobj->type()) { case SceneObject::TYPE::SPHERE: case SceneObject::TYPE::TRIANGLE: pix_col += curobj->calc_color(this, shadowRay, light, &hitsh, depth + 1); break; } } } #ifdef SOFT_SHADOW } } } pix_col.r /= 15.0; pix_col.g /= 15.0; pix_col.b /= 15.0; #endif return pix_col; } }