void ddImage_compositeTempBuffer(ddImage* image, ddColor* buffer, int y, int left, int right) { ddColor* p = (ddColor*)(image->data + y * image->rowstride); int x; p += left; // XXX - use vimage on OS X for ( x = left; x < right; ++x ) { //if ( *p != 0 ) // printf("not zero!"); *p = alpha_blend(*p, buffer[x]); ++p; } }
void draw_sprite_scaled_alpha(gfx_context_t * ctx, sprite_t * sprite, int32_t x, int32_t y, uint16_t width, uint16_t height, float alpha) { int32_t _left = max(x, 0); int32_t _top = max(y, 0); int32_t _right = min(x + width, ctx->width - 1); int32_t _bottom = min(y + height, ctx->height - 1); for (uint16_t _y = 0; _y < height; ++_y) { for (uint16_t _x = 0; _x < width; ++_x) { if (x + _x < _left || x + _x > _right || y + _y < _top || y + _y > _bottom) continue; uint32_t n_color = getBilinearFilteredPixelColor(sprite, (double)_x / (double)width, (double)_y/(double)height); uint32_t f_color = rgb(_ALP(n_color) * alpha, 0, 0); GFX(ctx, x + _x, y + _y) = alpha_blend(GFX(ctx, x + _x, y + _y), n_color, f_color); } } }
void draw_sprite_alpha(gfx_context_t * ctx, sprite_t * sprite, int32_t x, int32_t y, float alpha) { int32_t _left = max(x, 0); int32_t _top = max(y, 0); int32_t _right = min(x + sprite->width, ctx->width - 1); int32_t _bottom = min(y + sprite->height, ctx->height - 1); for (uint16_t _y = 0; _y < sprite->height; ++_y) { for (uint16_t _x = 0; _x < sprite->width; ++_x) { if (x + _x < _left || x + _x > _right || y + _y < _top || y + _y > _bottom) continue; uint32_t n_color = SPRITE(sprite, _x, _y); uint32_t f_color = rgb(_ALP(n_color) * alpha, 0, 0); GFX(ctx, x + _x, y + _y) = alpha_blend(GFX(ctx, x + _x, y + _y), n_color, f_color); } } }
static void alpha_blend_transition( uint8_t *Y, uint8_t *Cb, uint8_t *Cr, uint8_t *a0, const uint8_t *Y2, const uint8_t *Cb2, const uint8_t *Cr2, const uint8_t *a1, const size_t len, const size_t w, unsigned int time_index, const unsigned int dur, const int alpha_select ) { uint8_t lookup[256]; const uint8_t *T = (const uint8_t*) lookup; const uint8_t *aA = (alpha_select == 0 ? a0 : a1); size_t i; /* precalc lookup table for vectorization */ for( i = 0; i < 256; i ++ ) { if( time_index < aA[i] ) lookup[i] = 0; else if ( time_index >= (aA[i] + dur) ) lookup[i] = 0xff; else lookup[i] = 0xff * ( (double) (time_index - i ) / dur ); } uint8_t AA[ RUP8(w) ]; for( i = 0; i < len; i += w ) { /* unroll the lookup table so we can vectorize */ expand_lookup_table( AA, T, aA + i, w ); alpha_blend( Y + i, Y2 + i, AA, w ); alpha_blend( Cb+ i, Cb2+ i, AA, w ); alpha_blend( Cr+ i, Cr2+ i, AA, w ); } }
/* * Draw a character to a context. */ static void draw_char(FT_Bitmap * bitmap, int x, int y, uint32_t fg, gfx_context_t * ctx) { int i, j, p, q; int x_max = x + bitmap->width; int y_max = y + bitmap->rows; for (j = y, q = 0; j < y_max; j++, q++) { for ( i = x, p = 0; i < x_max; i++, p++) { SGFX(ctx->backbuffer,i,j,ctx->width) = alpha_blend(SGFX(ctx->backbuffer,i,j,ctx->width),fg,rgb(bitmap->buffer[q * bitmap->width + p],0,0)); } } }
void ddImage_blendRect(ddImage* image, ddRect rect, ddColor color) { int x, y; if ( !RECT_VALID(rect) ) return; // XXX - use vImage on OS X for ( y = INT_F(rect.top); y < INT_F(rect.bottom); ++y ) { for ( x = INT_F(rect.left); x < INT_F(rect.right); ++x ) { ddColor *p = (ddColor*)(image->data + y * image->rowstride + x * sizeof(ddColor)); *p = alpha_blend(*p, color); } } }
void Dds::copy_alpha_blend(const Point& point, const Size& size, unsigned* vram) const { Point top_left = Point(0, 0); Point bottom_right = Point(size_->width() - 1, size_->height() - 1); Iterator::Image source_iterator(top_left, bottom_right, *size_); Iterator::Image destination_iterator(top_left + point, bottom_right + point, size); while (source_iterator.has_next()) { if (size.is_iterator_in(destination_iterator)) { vram[destination_iterator] = alpha_blend( data_[source_iterator], vram[destination_iterator]); } ++source_iterator; ++destination_iterator; } }
void draw_sprite(gfx_context_t * ctx, sprite_t * sprite, int32_t x, int32_t y) { int32_t _left = max(x, 0); int32_t _top = max(y, 0); int32_t _right = min(x + sprite->width, ctx->width - 1); int32_t _bottom = min(y + sprite->height, ctx->height - 1); for (uint16_t _y = 0; _y < sprite->height; ++_y) { for (uint16_t _x = 0; _x < sprite->width; ++_x) { if (x + _x < _left || x + _x > _right || y + _y < _top || y + _y > _bottom) continue; if (sprite->alpha == ALPHA_MASK) { GFX(ctx, x + _x, y + _y) = alpha_blend(GFX(ctx, x + _x, y + _y), SPRITE(sprite, _x, _y), SMASKS(sprite, _x, _y)); } else if (sprite->alpha == ALPHA_EMBEDDED) { GFX(ctx, x + _x, y + _y) = alpha_blend_rgba(GFX(ctx, x + _x, y + _y), SPRITE(sprite, _x, _y)); } else if (sprite->alpha == ALPHA_INDEXED) { if (SPRITE(sprite, _x, _y) != sprite->blank) { GFX(ctx, x + _x, y + _y) = SPRITE(sprite, _x, _y) | 0xFF000000; } } else { GFX(ctx, x + _x, y + _y) = SPRITE(sprite, _x, _y) | 0xFF000000; } } } }
glm::vec3 CTracer::TraceRay(SRay ray) { int max_iter = 400; int straight_iters_num = 7; double time_step = 4; // in seconds double eps = 1e-5; double ztol = 1e-7; glm::vec4 disk_color(-1, -1, -1, -1); bool crossed_disk = false; bool crossed_other = false; glm::vec3 color(0, 0, 1); glm::vec4 other_color; glm::dvec3 cur_pos(m_camera.m_pos), cur_speed(ray.m_dir / glm::length(ray.m_dir) * light_speed); int iter = 0; glm::dvec3 cur_dir(0.0, 0.0, 0.0); glm::dvec3 prev_dir(0.0, 0.0, 0.0); Segment segm; SRay changed; double cam_to_bh = glm::length(m_camera.m_pos - black_hole.center); glm::dvec3 accel; int last_iter_straight = -1; double cur_pos_abs_sq; //while (iter < max_iter) { while (true) { // simple: //cur_pos += ray.m_dir * light_speed * time_step; //cur_speed = ray.m_dir / glm::length(ray.m_dir) * light_speed; // with acceleration: cur_pos_abs_sq = glm::dot(cur_pos, cur_pos); accel = -(cur_pos / glm::length(cur_pos)) * grav_const * black_hole.mass / cur_pos_abs_sq; // assuming coordinates center is in center of black hole. //fout << "accel: " << accel.x << ' ' << accel.y << ' ' << accel.z << ", module: " << glm::length(accel) << std::endl; segm.start = cur_pos; //changed.m_start = cur_pos; cur_pos += (cur_speed + accel * time_step / 2.0) * time_step; cur_speed += accel * time_step; cur_speed *= light_speed / glm::length(cur_speed); // choosing non-uniform time step //time_step = 2 / glm::length(accel); // Checking intersection for segment. segm.end = cur_pos; auto intersn = intersection(segm); if (intersn.first == SPHERE_INTERSN) { other_color = intersn.second; crossed_other = true; if (!alpha_blending_enable) { return rgb_cut(other_color); } break; } else if (intersn.first == DISK_INTERSN && intersn.second.w > ztol) { if (!crossed_disk) { disk_color = intersn.second; crossed_disk = true; if (!alpha_blending_enable) { return rgb_cut(disk_color); } } else { // encountered disk previously. // It is impossible to come to this point if alpha blending is disabled. disk_color = alpha_blend(disk_color, intersn.second); } } // another way is to compute cross product //if (glm::dot(cur_pos, cur_pos) > 3 * (cam_to_bh + black_hole.radius) * (cam_to_bh + black_hole.radius) || //if (glm::dot(cur_speed, prev_dir) < (1 - eps) * light_speed * light_speed) { // speeds must be of length light_speed // has put light_speed^2 in the right side of equation if (glm::length(glm::cross(cur_speed, prev_dir)) < eps * light_speed * light_speed && glm::dot(cur_pos, cur_pos) > 2 * (cam_to_bh + black_hole.radius) * (cam_to_bh + black_hole.radius)) { if (last_iter_straight == -1) { last_iter_straight = iter; } else if (iter - last_iter_straight > straight_iters_num) { glm::dvec2 spher(0, 0); glm::dvec3 dir_normd = cur_speed / glm::length(cur_speed); spher.x = atan2(dir_normd.x, dir_normd.y) + PI; // (at least in MS library) atan2 returns value in [-pi, pi] spher.y = asin(dir_normd.z); //fout << "final iter no: " << iter << std::endl; //fout << "spher coords: " << spher.y << ' ' << spher.x << std::endl; std::pair<unsigned, unsigned> stars_shape = img_shape(1); double H = stars_shape.second; spher.x *= H / PI; // transforming [0, 2pi) to [0, 2H) spher.y = (spher.y + PI / 2.0) * H / PI; // transforming [-pi/2, pi/2] to [0, H] spher.x = glm::clamp(spher.x, 0.0, 2 * H - 1); spher.y = glm::clamp(spher.y, 0.0, H - 1); //fout << "ray start: " << ray.m_start.x << ' ' << ray.m_start.y << ' ' << ray.m_start.z << std::endl; //fout << "ray dir: " << ray.m_dir.x << ' ' << ray.m_dir.y << ' ' << ray.m_dir.z << std::endl; //fout << "spher coords: " << spher.y << ' ' << spher.x << std::endl; other_color = img_get_pxl_rgba(1, int(spher.x), int(spher.y)); other_color.w = 1; crossed_other = true; break; } } prev_dir = cur_speed; iter++; } //fout << "min dist to black hole: " << *min_element(dist_to_bh.begin(), dist_to_bh.end()) << std::endl; //std::cout << alpha_blending_enable << std::endl; if (!alpha_blending_enable) { color = rgb_cut(other_color); } else { if (crossed_disk) { if (!crossed_other) { color = rgb_cut(disk_color); } else { // Alpha-blending color = rgb_cut(alpha_blend(disk_color, other_color)); } } else { color = rgb_cut(other_color); } } return color; }