void _al_draw_bitmap_region_memory(ALLEGRO_BITMAP *src, ALLEGRO_COLOR tint, int sx, int sy, int sw, int sh, int dx, int dy, int flags) { int op, src_mode, dst_mode; int op_alpha, src_alpha, dst_alpha; float xtrans, ytrans; ASSERT(src->parent == NULL); al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); if (_AL_DEST_IS_ZERO && _AL_SRC_NOT_MODIFIED_TINT_WHITE && _al_transform_is_translation(al_get_current_transform(), &xtrans, &ytrans)) { _al_draw_bitmap_region_memory_fast(src, sx, sy, sw, sh, dx + xtrans, dy + ytrans, flags); return; } /* We used to have special cases for translation/scaling only, but the * general version received much more optimisation and ended up being * faster. */ _al_draw_transformed_scaled_bitmap_memory(src, tint, sx, sy, sw, sh, dx, dy, sw, sh, flags); }
static bool set_opengl_blending(ALLEGRO_DISPLAY *d) { const int blend_modes[4] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA }; const int blend_equations[3] = { GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT }; int op, src_color, dst_color, op_alpha, src_alpha, dst_alpha; (void)d; al_get_separate_blender(&op, &src_color, &dst_color, &op_alpha, &src_alpha, &dst_alpha); #if defined ALLEGRO_IPHONE || defined ALLEGRO_GP2XWIZ if (al_get_opengl_version() >= _ALLEGRO_OPENGL_VERSION_2_0) { glEnable(GL_BLEND); glBlendFuncSeparate(blend_modes[src_color], blend_modes[dst_color], blend_modes[src_alpha], blend_modes[dst_alpha]); glBlendEquationSeparate( blend_equations[op], blend_equations[op_alpha]); return true; } else { glEnable(GL_BLEND); glBlendFunc(blend_modes[src_color], blend_modes[dst_color]); glBlendEquation(blend_equations[op]); return true; } #else if (d->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_1_4) { glEnable(GL_BLEND); glBlendFuncSeparate(blend_modes[src_color], blend_modes[dst_color], blend_modes[src_alpha], blend_modes[dst_alpha]); if (d->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) { glBlendEquationSeparate( blend_equations[op], blend_equations[op_alpha]); } else glBlendEquation(blend_equations[op]); return true; } else { if (src_color == src_alpha && dst_color == dst_alpha) { glEnable(GL_BLEND); glBlendFunc(blend_modes[src_color], blend_modes[dst_color]); glBlendEquation(blend_equations[op]); return true; } } #endif return false; }
void _al_point_2d(ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v) { int shade = 1; int op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha; ALLEGRO_COLOR vc; int clip_min_x, clip_min_y, clip_max_x, clip_max_y; int x = (int)floorf(v->x); int y = (int)floorf(v->x); al_get_clipping_rectangle(&clip_min_x, &clip_min_y, &clip_max_x, &clip_max_y); clip_max_x += clip_min_x; clip_max_y += clip_min_y; if(x < clip_min_x || x >= clip_max_x || y < clip_min_y || y >= clip_max_y) return; vc = v->color; al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); if (_AL_DEST_IS_ZERO && _AL_SRC_NOT_MODIFIED) { shade = 0; } if (texture) { float U = fix_var(v->u, al_get_bitmap_width(texture)); float V = fix_var(v->v, al_get_bitmap_height(texture)); ALLEGRO_COLOR color = al_get_pixel(texture, U, V); if(vc.r != 1 || vc.g != 1 || vc.b != 1 || vc.a != 1) { color.r *= vc.r; color.g *= vc.g; color.b *= vc.b; color.a *= vc.a; } if (shade) { al_put_blended_pixel(v->x, v->y, color); } else { al_put_pixel(v->x, v->y, color); } } else { ALLEGRO_COLOR color = al_map_rgba_f(vc.r, vc.g, vc.b, vc.a); if (shade) { al_put_blended_pixel(v->x, v->y, color); } else { al_put_pixel(v->x, v->y, color); } } }
static mrb_value separate_blender_getter(mrb_state *mrb, mrb_value self) { int op; int src; int dst; int alpha_op; int alpha_src; int alpha_dst; mrb_value a; al_get_separate_blender(&op, &src, &dst, &alpha_op, &alpha_src, &alpha_dst); a = mrb_ary_new_capa(mrb, 6); mrb_ary_push(mrb, a, mrb_fixnum_value(op)); mrb_ary_push(mrb, a, mrb_fixnum_value(src)); mrb_ary_push(mrb, a, mrb_fixnum_value(dst)); mrb_ary_push(mrb, a, mrb_fixnum_value(alpha_op)); mrb_ary_push(mrb, a, mrb_fixnum_value(alpha_src)); mrb_ary_push(mrb, a, mrb_fixnum_value(alpha_dst)); return a; }
static void set_blender(ALLEGRO_DISPLAY *display) { int op, src, dst, alpha_op, alpha_src, alpha_dst; ALLEGRO_COLOR color; LPDIRECT3DDEVICE9 device = al_d3d_get_device(display); al_get_separate_blender(&op, &src, &dst, &alpha_op, &alpha_src, &alpha_dst, &color); src = al_blender_to_d3d(src); dst = al_blender_to_d3d(dst); alpha_src = al_blender_to_d3d(alpha_src); alpha_dst = al_blender_to_d3d(alpha_dst); IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, src); IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, dst); IDirect3DDevice9_SetRenderState(device, D3DRS_SEPARATEALPHABLENDENABLE, true); IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLENDALPHA, alpha_src); IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLENDALPHA, alpha_dst); IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); }
bool _al_opengl_set_blender(ALLEGRO_DISPLAY *ogl_disp) { int op, src_color, dst_color, op_alpha, src_alpha, dst_alpha; const int blend_modes[8] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_ONE_MINUS_DST_COLOR }; const int blend_equations[3] = { GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT }; (void)ogl_disp; al_get_separate_blender(&op, &src_color, &dst_color, &op_alpha, &src_alpha, &dst_alpha); /* glBlendFuncSeparate was only included with OpenGL 1.4 */ /* (And not in OpenGL ES) */ #if !defined ALLEGRO_GP2XWIZ #if !defined ALLEGRO_IPHONE && !defined ALLEGRO_ANDROID if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_1_4) { #else if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) { #endif glEnable(GL_BLEND); glBlendFuncSeparate(blend_modes[src_color], blend_modes[dst_color], blend_modes[src_alpha], blend_modes[dst_alpha]); if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) { glBlendEquationSeparate( blend_equations[op], blend_equations[op_alpha]); } else { glBlendEquation(blend_equations[op]); } } else { if (src_color == src_alpha && dst_color == dst_alpha) { glEnable(GL_BLEND); glBlendFunc(blend_modes[src_color], blend_modes[dst_color]); } else { ALLEGRO_ERROR("Blender unsupported with this OpenGL version (%d %d %d %d %d %d)\n", op, src_color, dst_color, op_alpha, src_alpha, dst_alpha); return false; } } #else glEnable(GL_BLEND); glBlendFunc(blend_modes[src_color], blend_modes[dst_color]); #endif return true; } /* These functions make drawing calls use shaders or the fixed pipeline * based on what the user has set up. FIXME: OpenGL only right now. */ static void vert_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v) { /* Only use this shader stuff with GLES2+ or equivalent */ if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) { #ifndef ALLEGRO_CFG_NO_GLES2 if (display->ogl_extras->pos_loc >= 0) { glVertexAttribPointer(display->ogl_extras->pos_loc, n, t, false, stride, v); glEnableVertexAttribArray(display->ogl_extras->pos_loc); } #endif } else { glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(n, t, stride, v); } } static void vert_ptr_off(ALLEGRO_DISPLAY *display) { if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) { #ifndef ALLEGRO_CFG_NO_GLES2 if (display->ogl_extras->pos_loc >= 0) { glDisableVertexAttribArray(display->ogl_extras->pos_loc); } #endif } else { glDisableClientState(GL_VERTEX_ARRAY); } } static void color_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v) { if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) { #ifndef ALLEGRO_CFG_NO_GLES2 if (display->ogl_extras->color_loc >= 0) { glVertexAttribPointer(display->ogl_extras->color_loc, n, t, false, stride, v); glEnableVertexAttribArray(display->ogl_extras->color_loc); } #endif } else { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(n, t, stride, v); } } static void color_ptr_off(ALLEGRO_DISPLAY *display) { if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) { #ifndef ALLEGRO_CFG_NO_GLES2 if (display->ogl_extras->color_loc >= 0) { glDisableVertexAttribArray(display->ogl_extras->color_loc); } #endif } else { glDisableClientState(GL_COLOR_ARRAY); } } static void tex_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v) { if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) { #ifndef ALLEGRO_CFG_NO_GLES2 if (display->ogl_extras->texcoord_loc >= 0) { glVertexAttribPointer(display->ogl_extras->texcoord_loc, n, t, false, stride, v); glEnableVertexAttribArray(display->ogl_extras->texcoord_loc); } #endif } else { glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(n, t, stride, v); } } static void tex_ptr_off(ALLEGRO_DISPLAY *display) { if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) { #ifndef ALLEGRO_CFG_NO_GLES2 if (display->ogl_extras->texcoord_loc >= 0) { glDisableVertexAttribArray(display->ogl_extras->texcoord_loc); } #endif } else { glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } /* Dummy implementation of clear. */ static void ogl_clear(ALLEGRO_DISPLAY *d, ALLEGRO_COLOR *color) { ALLEGRO_DISPLAY *ogl_disp = (void *)d; ALLEGRO_BITMAP *target = al_get_target_bitmap(); ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_target; float r, g, b, a; if (target->parent) target = target->parent; ogl_target = target->extra; if ((!ogl_target->is_backbuffer && ogl_disp->ogl_extras->opengl_target != target) || target->locked) { _al_clear_memory(color); return; } al_unmap_rgba_f(*color, &r, &g, &b, &a); /* There's a very nasty bug in Android 2.1 that makes glClear cause * screen flicker (appears to me it's swapping buffers.) Work around * by drawing two triangles instead on that OS. */ #ifdef ALLEGRO_ANDROID if (ogl_target->is_backbuffer && _al_android_is_os_2_1()) { GLfloat v[8] = { 0, d->h, 0, 0, d->w, d->h, d->w, 0 }; GLfloat c[16] = { r, g, b, a, r, g, b, a, r, g, b, a, r, g, b, a }; ALLEGRO_TRANSFORM bak1, bak2, t; al_copy_transform(&bak1, &d->proj_transform); al_copy_transform(&bak2, al_get_current_transform()); al_identity_transform(&t); al_ortho_transform(&t, 0, d->w, d->h, 0, -1, 1); al_set_projection_transform(d, &t); al_identity_transform(&t); al_use_transform(&t); _al_opengl_set_blender(d); vert_ptr_on(d, 2, GL_FLOAT, 2*sizeof(float), v); color_ptr_on(d, 4, GL_FLOAT, 4*sizeof(float), c); if (!(d->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE)) { glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); vert_ptr_off(d); color_ptr_off(d); al_set_projection_transform(d, &bak1); al_use_transform(&bak2); return; } #endif glClearColor(r, g, b, a); glClear(GL_COLOR_BUFFER_BIT); }
bool _al_opengl_set_blender(ALLEGRO_DISPLAY *ogl_disp) { int op, src_color, dst_color, op_alpha, src_alpha, dst_alpha; ALLEGRO_COLOR const_color; const int blend_modes[10] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_ONE_MINUS_DST_COLOR, #if defined(ALLEGRO_CFG_OPENGLES2) || !defined(ALLEGRO_CFG_OPENGLES) GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR #else GL_ONE, GL_ONE #endif }; const int blend_equations[3] = { GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT }; (void)ogl_disp; al_get_separate_blender(&op, &src_color, &dst_color, &op_alpha, &src_alpha, &dst_alpha); const_color = al_get_blend_color(); /* glBlendFuncSeparate was only included with OpenGL 1.4 */ #if !defined ALLEGRO_CFG_OPENGLES if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_1_4) { #else /* FIXME: At this time (09/2014) there are a lot of Android phones that * don't support glBlendFuncSeparate even though they claim OpenGL ES 2.0 * support. Rather than not work on 20-25% of phones, we just don't support * separate blending on Android for now. */ #ifdef ALLEGRO_ANDROID if (false) { #else if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) { #endif #endif glEnable(GL_BLEND); #if defined(ALLEGRO_CFG_OPENGLES2) || !defined(ALLEGRO_CFG_OPENGLES) #ifndef ALLEGRO_ANDROID_HACK_X86_64 glBlendColor(const_color.r, const_color.g, const_color.b, const_color.a); #endif #endif glBlendFuncSeparate(blend_modes[src_color], blend_modes[dst_color], blend_modes[src_alpha], blend_modes[dst_alpha]); if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) { glBlendEquationSeparate( blend_equations[op], blend_equations[op_alpha]); } else { glBlendEquation(blend_equations[op]); } } else { if (src_color == src_alpha && dst_color == dst_alpha) { glEnable(GL_BLEND); #if defined(ALLEGRO_CFG_OPENGLES2) || !defined(ALLEGRO_CFG_OPENGLES) #ifndef ALLEGRO_ANDROID_HACK_X86_64 glBlendColor(const_color.r, const_color.g, const_color.b, const_color.a); #endif #endif glBlendFunc(blend_modes[src_color], blend_modes[dst_color]); } else { ALLEGRO_ERROR("Blender unsupported with this OpenGL version (%d %d %d %d %d %d)\n", op, src_color, dst_color, op_alpha, src_alpha, dst_alpha); return false; } } return true; } /* These functions make drawing calls use shaders or the fixed pipeline * based on what the user has set up. FIXME: OpenGL only right now. */ static void vert_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v) { /* Only use this shader stuff with GLES2+ or equivalent */ if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { #ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE if (display->ogl_extras->varlocs.pos_loc >= 0) { glVertexAttribPointer(display->ogl_extras->varlocs.pos_loc, n, t, false, stride, v); glEnableVertexAttribArray(display->ogl_extras->varlocs.pos_loc); } #endif } else { glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(n, t, stride, v); } } static void vert_ptr_off(ALLEGRO_DISPLAY *display) { if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { #ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE if (display->ogl_extras->varlocs.pos_loc >= 0) { glDisableVertexAttribArray(display->ogl_extras->varlocs.pos_loc); } #endif } else { glDisableClientState(GL_VERTEX_ARRAY); } } static void color_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v) { if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { #ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE if (display->ogl_extras->varlocs.color_loc >= 0) { glVertexAttribPointer(display->ogl_extras->varlocs.color_loc, n, t, false, stride, v); glEnableVertexAttribArray(display->ogl_extras->varlocs.color_loc); } #endif } else { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(n, t, stride, v); } } static void color_ptr_off(ALLEGRO_DISPLAY *display) { if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { #ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE if (display->ogl_extras->varlocs.color_loc >= 0) { glDisableVertexAttribArray(display->ogl_extras->varlocs.color_loc); } #endif } else { glDisableClientState(GL_COLOR_ARRAY); } } static void tex_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v) { if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { #ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE if (display->ogl_extras->varlocs.texcoord_loc >= 0) { glVertexAttribPointer(display->ogl_extras->varlocs.texcoord_loc, n, t, false, stride, v); glEnableVertexAttribArray(display->ogl_extras->varlocs.texcoord_loc); } #endif } else { glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(n, t, stride, v); } } static void tex_ptr_off(ALLEGRO_DISPLAY *display) { if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) { #ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE if (display->ogl_extras->varlocs.texcoord_loc >= 0) { glDisableVertexAttribArray(display->ogl_extras->varlocs.texcoord_loc); } #endif } else { glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } /* There's a very nasty bug in Android 2.1 that makes glClear cause * screen flicker (appears to me it's swapping buffers.) Work around * by drawing two triangles instead on that OS. */ static void ogl_clear_android_2_1_workaround(ALLEGRO_DISPLAY *d, float r, float g, float b, float a) { GLfloat v[8] = { 0, d->h, 0, 0, d->w, d->h, d->w, 0 }; GLfloat c[16] = { r, g, b, a, r, g, b, a, r, g, b, a, r, g, b, a }; ALLEGRO_TRANSFORM bak1, bak2, t; al_copy_transform(&bak1, al_get_current_projection_transform()); al_copy_transform(&bak2, al_get_current_transform()); al_identity_transform(&t); al_orthographic_transform(&t, 0, 0, -1, d->w, d->h, 1); al_use_projection_transform(&t); al_identity_transform(&t); al_use_transform(&t); _al_opengl_set_blender(d); vert_ptr_on(d, 2, GL_FLOAT, 2*sizeof(float), v); color_ptr_on(d, 4, GL_FLOAT, 4*sizeof(float), c); if (!(d->flags & ALLEGRO_PROGRAMMABLE_PIPELINE)) { glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); vert_ptr_off(d); color_ptr_off(d); al_use_projection_transform(&bak1); al_use_transform(&bak2); } static void ogl_clear(ALLEGRO_DISPLAY *d, ALLEGRO_COLOR *color) { ALLEGRO_DISPLAY *ogl_disp = (void *)d; ALLEGRO_BITMAP *target = al_get_target_bitmap(); ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_target; float r, g, b, a; if (target->parent) target = target->parent; ogl_target = target->extra; if ((!ogl_target->is_backbuffer && ogl_disp->ogl_extras->opengl_target != target) || target->locked) { _al_clear_bitmap_by_locking(target, color); return; } al_unmap_rgba_f(*color, &r, &g, &b, &a); if (ogl_target->is_backbuffer && IS_ANDROID_AND(_al_android_is_os_2_1())) { ogl_clear_android_2_1_workaround(d, r, g, b, a); return; } glClearColor(r, g, b, a); glClear(GL_COLOR_BUFFER_BIT); }
/* This one will check to see what exactly we need to draw... I.e. this will call all of the actual renderers and set the appropriate callbacks */ void _al_triangle_2d(ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3) { int shade = 1; int grad = 1; int op, src_mode, dst_mode, op_alpha, src_alpha, dst_alpha; ALLEGRO_COLOR v1c, v2c, v3c; v1c = v1->color; v2c = v2->color; v3c = v3->color; al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha); if (_AL_DEST_IS_ZERO && _AL_SRC_NOT_MODIFIED) { shade = 0; } if ((v1c.r == v2c.r && v2c.r == v3c.r) && (v1c.g == v2c.g && v2c.g == v3c.g) && (v1c.b == v2c.b && v2c.b == v3c.b) && (v1c.a == v2c.a && v2c.a == v3c.a)) { grad = 0; } if (texture) { if (grad) { state_texture_grad_any_2d state; state.solid.texture = texture; if (shade) { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_grad_any_init, shader_texture_grad_any_first, shader_texture_grad_any_step, shader_texture_grad_any_draw_shade); } else { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_grad_any_init, shader_texture_grad_any_first, shader_texture_grad_any_step, shader_texture_grad_any_draw_opaque); } } else { int white = 0; state_texture_solid_any_2d state; if (v1c.r == 1 && v1c.g == 1 && v1c.b == 1 && v1c.a == 1) { white = 1; } state.texture = texture; if (shade) { if (white) { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_solid_any_init, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_shade_white); } else { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_solid_any_init, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_shade); } } else { if (white) { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_solid_any_init, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_opaque_white); } else { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_texture_solid_any_init, shader_texture_solid_any_first, shader_texture_solid_any_step, shader_texture_solid_any_draw_opaque); } } } } else { if (grad) { state_grad_any_2d state; if (shade) { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_grad_any_init, shader_grad_any_first, shader_grad_any_step, shader_grad_any_draw_shade); } else { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_grad_any_init, shader_grad_any_first, shader_grad_any_step, shader_grad_any_draw_opaque); } } else { state_solid_any_2d state; if (shade) { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_solid_any_init, shader_solid_any_first, shader_solid_any_step, shader_solid_any_draw_shade); } else { _al_draw_soft_triangle(v1, v2, v3, (uintptr_t)&state, shader_solid_any_init, shader_solid_any_first, shader_solid_any_step, shader_solid_any_draw_opaque); } } } }
/* ---------------------------------------------------------------------------- * 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 ); } }
/* Function: al_get_blender */ void al_get_blender(int *op, int *src, int *dst) { al_get_separate_blender(op, src, dst, NULL, NULL, NULL); }