/** Sets a custom blending mode. */ void cbeSetBlendMode(CBEnchanted *cb) { bool alphaToo = cb->popValue().toBool(); int32_t type = cb->popValue().toInt(); if (alphaToo) { switch (type) { case 1: // Additive al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); break; case 2: // Erase / overwrite al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); break; default: // Reset normal, make sure that this is the same is GfxInterface::initializeGfx() al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); } } else { switch (type) { case 1: // Additive al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); break; case 2: // Erase / overwrite al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); break; default: // Reset normal, make sure that this is the same is GfxInterface::initializeGfx() al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); } } cb->pushValue(0); }
static mrb_value separate_blender_setter(mrb_state *mrb, mrb_value self) { mrb_value a; mrb_value *e; mrb_get_args(mrb, "A", &a); if (RARRAY_LEN(a) != 6) { goto invalid; } e = RARRAY_PTR(a); if (mrb_fixnum_p(e[0]) && mrb_fixnum_p(e[1]) && mrb_fixnum_p(e[2]) && mrb_fixnum_p(e[3]) && mrb_fixnum_p(e[4]) && mrb_fixnum_p(e[5])) { al_set_separate_blender(mrb_fixnum(e[0]), mrb_fixnum(e[1]), mrb_fixnum(e[2]), mrb_fixnum(e[3]), mrb_fixnum(e[4]), mrb_fixnum(e[5])); return a; } invalid: mrb_raise(mrb, E_ALLEGRO_ERROR, "invalid blending mode"); return mrb_nil_value(); // unreachable }
ALLEGRO_BITMAP *generate_brush_metal_bitmap(float w, float h, ALLEGRO_COLOR base_color) { // TODO: clean this function up // set everything up float h_stretch = 1.0; float v_stretch = 26.0; ALLEGRO_BITMAP *noise_texture = generate_noise_bitmap(w, h); // TODO: this should be greater(w, h) or something similar ALLEGRO_BITMAP *gradient_texture = generate_gradient_bitmap(w); // TODO: this should be greater(w, h) or something similar ALLEGRO_BITMAP *tex = al_create_bitmap(w, h); // store the state and set the drawing surface ALLEGRO_STATE state; al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP | ALLEGRO_STATE_BLENDER); al_set_target_bitmap(tex); // // draw the content // al_clear_to_color(base_color); al_draw_tinted_bitmap(gradient_texture, color::name("white", 0.1), 0, 0, ALLEGRO_FLAGS_EMPTY); al_set_separate_blender(ALLEGRO_DEST_MINUS_SRC, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); al_draw_tinted_scaled_bitmap(noise_texture, color::name("white", 0.3), 0, 0, al_get_bitmap_width(noise_texture), al_get_bitmap_height(noise_texture), 0, 0, al_get_bitmap_width(noise_texture)*h_stretch, al_get_bitmap_height(noise_texture)*v_stretch, ALLEGRO_FLAGS_EMPTY); al_draw_tinted_bitmap(noise_texture, color::name("white", 0.1), -200, -200, ALLEGRO_FLAGS_EMPTY); // restore the state al_restore_state(&state); al_destroy_bitmap(gradient_texture); al_destroy_bitmap(noise_texture); // return the generated image return tex; }
void Prog::blending_test(bool memory) { ALLEGRO_COLOR transparency = al_map_rgba_f(0, 0, 0, 0); int op = str_to_blend_mode(operations[4].get_selected_item_text()); int aop = str_to_blend_mode(operations[5].get_selected_item_text()); int src = str_to_blend_mode(operations[0].get_selected_item_text()); int asrc = str_to_blend_mode(operations[1].get_selected_item_text()); int dst = str_to_blend_mode(operations[2].get_selected_item_text()); int adst = str_to_blend_mode(operations[3].get_selected_item_text()); /* Initialize with destination. */ al_clear_to_color(transparency); // Just in case. al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO); draw_bitmap(destination_image.get_selected_item_text(), "original", memory, true); /* Now draw the blended source over it. */ al_set_separate_blender(op, src, dst, aop, asrc, adst); draw_bitmap(source_image.get_selected_item_text(), draw_mode.get_selected_item_text(), memory, false); }
ALLEGRO_BITMAP *generate_wood_grain_bitmap(float w, float h, ALLEGRO_COLOR base_color) { // set up everything float h_stretch = 12; ALLEGRO_BITMAP *surface = al_create_bitmap(w, h); ALLEGRO_BITMAP *noise_texture = generate_noise_bitmap(w, h, 0.5, 0.7); ALLEGRO_STATE state; al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP | ALLEGRO_STATE_BLENDER); // set the drawing surface al_set_target_bitmap(surface); // set the base color al_clear_to_color(base_color); // draw the wood grain (should clean this up a little bit) al_set_separate_blender(ALLEGRO_DEST_MINUS_SRC, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); // subtraction blender al_draw_tinted_scaled_bitmap(noise_texture, color::color("white", 1.0), -300, -300, al_get_bitmap_width(noise_texture), al_get_bitmap_height(noise_texture), 0, 0, al_get_bitmap_width(noise_texture)*h_stretch*1.736, al_get_bitmap_height(noise_texture)*2, ALLEGRO_FLAGS_EMPTY); al_draw_tinted_bitmap(noise_texture, color::color("white", 0.2), -200, -200, ALLEGRO_FLAGS_EMPTY); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); // normal blender (default blending) al_draw_tinted_scaled_bitmap(noise_texture, color::color("white", 0.3), 0, 0, al_get_bitmap_width(noise_texture), al_get_bitmap_height(noise_texture), 0, 0, al_get_bitmap_width(noise_texture)*h_stretch, al_get_bitmap_height(noise_texture), ALLEGRO_FLAGS_EMPTY); // erase the other assets al_destroy_bitmap(noise_texture); // return everything back to the way it was al_restore_state(&state); // return the generated image return surface; }
/* Generates a bitmap with transparent background and the logo text. * The bitmap will have screen size. If 'bumpmap' is not NULL, it will * contain another bitmap which is a white, blurred mask of the logo * which we use for the flash effect. */ static ALLEGRO_BITMAP *generate_logo(char const *text, char const *fontname, int font_size, float shadow_offset, float blur_radius, float blur_factor, float light_red, float light_green, float light_blue, ALLEGRO_BITMAP **bumpmap) { ALLEGRO_COLOR transparent = al_map_rgba_f(0, 0, 0, 0); int xp, yp, w, h, i, j, x, y, br, bw, dw, dh; ALLEGRO_COLOR c; ALLEGRO_FONT *logofont; ALLEGRO_STATE state; ALLEGRO_BITMAP *blur, *light, *logo; int left, right, top, bottom; float cx, cy; dw = al_get_bitmap_width(al_get_target_bitmap()); dh = al_get_bitmap_height(al_get_target_bitmap()); cx = dw * 0.5; cy = dh * 0.5; logofont = al_load_font(fontname, -font_size, 0); al_get_text_dimensions(logofont, text, &xp, &yp, &w, &h); al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP | ALLEGRO_STATE_BLENDER); /* Cheap blur effect to create a bump map. */ blur = al_create_bitmap(dw, dh); al_set_target_bitmap(blur); al_clear_to_color(transparent); br = blur_radius; bw = br * 2 + 1; c = al_map_rgba_f(1, 1, 1, 1.0 / (bw * bw * blur_factor)); al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); for (i = -br; i <= br; i++) { for (j = -br; j <= br; j++) { al_draw_text(logofont, c, cx - xp * 0.5 - w * 0.5 + i, cy - yp * 0.5 - h * 0.5 + j, 0, text); } } left = cx - xp * 0.5 - w * 0.5 - br + xp; top = cy - yp * 0.5 - h * 0.5 - br + yp; right = left + w + br * 2; bottom = top + h + br * 2; if (left < 0) left = 0; if (top < 0) top = 0; if (right > dw - 1) right = dw - 1; if (bottom > dh - 1) bottom = dh - 1; /* Cheap light effect. */ light = al_create_bitmap(dw, dh); al_set_target_bitmap(light); al_clear_to_color(transparent); al_lock_bitmap(blur, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); al_lock_bitmap_region(light, left, top, 1 + right - left, 1 + bottom - top, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY); for (y = top; y <= bottom; y++) { for (x = left; x <= right; x++) { float r1, g1, b1, a1; float r2, g2, b2, a2; float r, g, b, a; float d; ALLEGRO_COLOR c = al_get_pixel(blur, x, y); ALLEGRO_COLOR c1 = al_get_pixel(blur, x - 1, y - 1); ALLEGRO_COLOR c2 = al_get_pixel(blur, x + 1, y + 1); al_unmap_rgba_f(c, &r, &g, &b, &a); al_unmap_rgba_f(c1, &r1, &g1, &b1, &a1); al_unmap_rgba_f(c2, &r2, &g2, &b2, &a2); d = r2 - r1 + 0.5; r = clamp(d * light_red); g = clamp(d * light_green); b = clamp(d * light_blue); c = al_map_rgba_f(r, g, b, a); al_put_pixel(x, y, c); } } al_unlock_bitmap(light); al_unlock_bitmap(blur); if (bumpmap) *bumpmap = blur; else al_destroy_bitmap(blur); /* Create final logo */ logo = al_create_bitmap(dw, dh); al_set_target_bitmap(logo); al_clear_to_color(transparent); /* Draw a shadow. */ c = al_map_rgba_f(0, 0, 0, 0.5 / 9); al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); for (i = -1; i <= 1; i++) for (j = -1; j <= 1; j++) al_draw_text(logofont, c, cx - xp * 0.5 - w * 0.5 + shadow_offset + i, cy - yp * 0.5 - h * 0.5 + shadow_offset + j, 0, text); /* Then draw the lit text we made before on top. */ al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); al_draw_bitmap(light, 0, 0, 0); al_destroy_bitmap(light); al_restore_state(&state); al_destroy_font(logofont); return logo; }
/** Sets a custom blending mode in an advanced way. * Makes an error if given unsoppurted parameters. */ void cbeSetBlendModeAdvanced(CBEnchanted *cb) { int32_t cbADst = cb->popValue().toInt(); int32_t cbASrc = cb->popValue().toInt(); int32_t cbAOp = cb->popValue().toInt(); int32_t cbDst = cb->popValue().toInt(); int32_t cbSrc = cb->popValue().toInt(); int32_t cbOp = cb->popValue().toInt(); // Allegro versions int op, src, dst, aOp, aSrc, aDst; switch (cbOp) { case 1: op = ALLEGRO_ADD; break; case 2: op = ALLEGRO_DEST_MINUS_SRC; break; case 3: op = ALLEGRO_SRC_MINUS_DEST; break; default: cb->errors->createError("cbeSetAdvancedBlendMode() failed!", "First parameter was incorrect."); cb->pushValue(0); return; } switch (cbSrc) { case 1: src = ALLEGRO_ZERO; break; case 2: src = ALLEGRO_ONE; break; case 3: src = ALLEGRO_ALPHA; break; case 4: src = ALLEGRO_INVERSE_ALPHA; break; default: cb->errors->createError("cbeSetAdvancedBlendMode() failed!", "Second parameter was incorrect."); cb->pushValue(0); return; } switch (cbDst) { case 1: dst = ALLEGRO_ZERO; break; case 2: dst = ALLEGRO_ONE; break; case 3: dst = ALLEGRO_ALPHA; break; case 4: dst = ALLEGRO_INVERSE_ALPHA; break; default: cb->errors->createError("cbeSetAdvancedBlendMode() failed!", "Third parameter was incorrect."); cb->pushValue(0); return; } if (cbAOp == 0 && cbASrc == 0 && cbADst == 0) { // Alpha blending = regular blending aOp = op; aSrc = src; aDst = dst; } else { // Validate alpha parameters, too. switch (cbAOp) { case 1: aOp = ALLEGRO_ADD; break; case 2: aOp = ALLEGRO_DEST_MINUS_SRC; break; case 3: aOp = ALLEGRO_SRC_MINUS_DEST; break; default: cb->errors->createError("cbeSetAdvancedBlendMode() failed!", "4th parameter was incorrect."); cb->pushValue(0); return; } switch (cbASrc) { case 1: aSrc = ALLEGRO_ZERO; break; case 2: aSrc = ALLEGRO_ONE; break; case 3: aSrc = ALLEGRO_ALPHA; break; case 4: aSrc = ALLEGRO_INVERSE_ALPHA; break; default: cb->errors->createError("cbeSetAdvancedBlendMode() failed!", "5th parameter was incorrect."); cb->pushValue(0); return; } switch (cbADst) { case 1: aDst = ALLEGRO_ZERO; break; case 2: aDst = ALLEGRO_ONE; break; case 3: aDst = ALLEGRO_ALPHA; break; case 4: aDst = ALLEGRO_INVERSE_ALPHA; break; default: cb->errors->createError("cbeSetAdvancedBlendMode() failed!", "6th parameter was incorrect."); cb->pushValue(0); return; } } // Ok, every parameter is validated now and set properly. Set the blend mode. al_set_separate_blender(op, src, dst, aOp, aSrc, aDst); cb->pushValue(0); }
/* ---------------------------------------------------------------------------- * Draws a treasure. */ void treasure::draw() { sprite* s_ptr = anim.get_cur_sprite(); if(!s_ptr) return; float draw_x, draw_y; float draw_w, draw_h, scale; get_sprite_center(this, s_ptr, &draw_x, &draw_y); get_sprite_dimensions(this, s_ptr, &draw_w, &draw_h, &scale); float radius = type->radius * scale; bool being_delivered = false; ALLEGRO_COLOR extra_color; if(fsm.cur_state->id == TREASURE_STATE_BEING_DELIVERED) { //If it's being delivered, do some changes to the scale and coloring. being_delivered = true; if(script_timer.get_ratio_left() >= 0.5) { //First half of the sucking in process = interpolated coloring. extra_color = interpolate_color( script_timer.get_ratio_left(), 0.5, 1.0, carrying_color_move, al_map_rgb(0, 0, 0) ); } else { //Second half of the sucking in process = interpolated scaling. extra_color = carrying_color_move; radius *= (script_timer.get_ratio_left() * 2.0); } } draw_sprite( s_ptr->bitmap, draw_x, draw_y, radius * 2.0, -1, angle, map_gray(get_sprite_brightness(this)) ); if(being_delivered) { int old_op, old_src, old_dst, old_aop, old_asrc, old_adst; al_get_separate_blender( &old_op, &old_src, &old_dst, &old_aop, &old_asrc, &old_adst ); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); draw_sprite( s_ptr->bitmap, draw_x, draw_y, radius * 2.0, -1, angle, extra_color ); al_set_separate_blender( old_op, old_src, old_dst, old_aop, old_asrc, old_adst ); } }
static ALLEGRO_COLOR test(ALLEGRO_COLOR src_col, ALLEGRO_COLOR dst_col, ALLEGRO_COLOR blend, int src_format, int dst_format, int src, int dst, int src_a, int dst_a, int operation, bool verbose) { ALLEGRO_COLOR result; ALLEGRO_BITMAP *dst_bmp; al_set_new_bitmap_format(dst_format); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb_f(1, 1, 1)); dst_bmp = al_create_bitmap(1, 1); al_set_target_bitmap(dst_bmp); al_clear_to_color(dst_col); if (operation == 0) { ALLEGRO_BITMAP *src_bmp; al_set_new_bitmap_format(src_format); src_bmp = al_create_bitmap(1, 1); al_set_target_bitmap(src_bmp); al_clear_to_color(src_col); al_set_target_bitmap(dst_bmp); al_set_separate_blender(ALLEGRO_ADD, src, dst, ALLEGRO_ADD, src_a, dst_a, blend); al_draw_bitmap(src_bmp, 0, 0, 0); al_destroy_bitmap(src_bmp); } else if (operation == 1) { al_set_separate_blender(ALLEGRO_ADD, src, dst, ALLEGRO_ADD, src_a, dst_a, blend); al_draw_pixel(0, 0, src_col); } else if (operation == 2) { al_set_separate_blender(ALLEGRO_ADD, src, dst, ALLEGRO_ADD, src_a, dst_a, blend); al_draw_line(0, 0, 1, 1, src_col, 0); } result = al_get_pixel(dst_bmp, 0, 0); if (test_display) { al_set_target_bitmap(al_get_backbuffer()); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO, al_map_rgb_f(1, 1, 1)); al_draw_bitmap(dst_bmp, 0, 0, 0); } al_destroy_bitmap(dst_bmp); if (!verbose) return result; printf("---\n"); printf("test id: %d\n", test_index); printf("source : "); print_color(src_col); printf(" %s format=%d mode=%d alpha=%d\n", operation == 0 ? "bitmap" : operation == 1 ? "pixel" : "prim", src_format, src, src_a); printf("destination: "); print_color(dst_col); printf(" format=%d mode=%d alpha=%d\n", dst_format, dst, dst_a); printf("blender : "); print_color(blend); printf("\n"); printf("result : "); print_color(result); printf("\n"); return result; }
/* Function: al_set_blender */ void al_set_blender(int op, int src, int dst) { al_set_separate_blender(op, src, dst, op, src, dst); }