您的位置:首页 > 其它

(转)MTk屏幕切换效果的制作

2016-12-25 12:22 281 查看
学习MTK三四个月了,总要写点东西出来才行,这里简单说说,怎么制作屏幕切换效果。一些基本的概念,我就不说了,图层的原理和对图层操作的一些函数,至少要了解。

 

进入主题,说一下我的思路:首先,在进入新屏幕之前,把旧屏幕保存起来;其次,在画新屏幕之前,把屏幕锁住,不给新屏幕显示出来;再次,等到新屏幕画完,又把新屏幕保存起来。好了,现在得到了两个屏幕,就可以执行我们的切换效果了。

 

要把新旧屏幕保存起来,我们定义了两个buffer:

#pragma arm section zidata = "NONCACHEDZI", rwdata =
"NONCACHEDRW"

static U8
old_layer_buff_ptr[240*320<<1];

static U8
new_layer_buff_ptr[240*320<<1];

#pragma arm section zidata, rwdata

 

下面看一下具体步骤:

1、保存旧屏幕。在EntryNewScreen函数里添加我们的函数:

void gui_my_SSE_save(void)

{

      
gui _save_current_layer(old_layer_buff_ptr);

}

为什么要在这里添加我们的函数呢?因为没进入一个新屏幕都要调用EntryNewScreen,这里,趁新屏幕还没有画之前,就把旧屏幕保存起来。

怎么保存当前屏幕呢,看下面的函数:

void gui _save_current_layer(U8 *output_buf)

{

   
gdi_handle snap_layer;

   
gdi_handle base_layer;

   
BOOL       
src_key_enable;

gdi_color   src_key_color;

 

   
gdi_layer_create_using_outside_memory(0, 0, 240, 320,

       
&snap_layer, output_buf, 240*320*2 );

 

   
gdi_layer_get_base_handle(&base_layer);

   
gdi_layer_push_and_set_active(base_layer);

   
gdi_layer_get_source_key(&src_key_enable,
&src_key_color);

   
gdi_layer_set_source_key(FALSE, src_key_color);

 

   
gdi_layer_push_and_set_active(snap_layer);

   
gdi_layer_reset_clip();  

   
gdi_layer_flatten_with_clipping(base_layer, 0, 0, 0);

   
gdi_layer_pop_and_restore_active();

   
gdi_layer_set_source_key(src_key_enable, src_key_color);

   
gdi_layer_pop_and_restore_active();

   
gdi_layer_free(snap_layer);

}

 

2、锁住屏幕,不给新屏幕显示出来。在dm_redraw_category_screen的开始这里,添加我们的函数:

void gui_my_SSE_setup(void)

{

      
gdi_layer_lock_frame_buffer();    

}

这里把屏幕锁着,不给新屏幕显示出来,在下面执行效果的时候再把屏幕解锁,使新旧屏幕切换显示出来。

 

3、保存新屏幕,解锁屏幕,执行特效。在dm_redraw_category_screen的结束这里,添加我们的函数:

void gui_my_SSE_run(void)

{

      
GDI_HANDLE activate_layer,precious_layer, current_layer;

 

      
gui _save_current_layer (new_layer_buff_ptr);//保存新屏幕

      
gdi_layer_get_active(&activate_layer);//获得激活图层

 

 

      
gdi_layer_create_using_outside_memory(0, 0, 240, 320,

&precious_layer,  (PU8)
old_layer_buff_ptr, 240 * 320 * 2);

      
gdi_layer_create_using_outside_memory(0, 0, 240, 320,

¤t_layer,  (PU8)
new_layer_buff_ptr, 240 * 320 * 2);

      

gdi_layer_unlock_frame_buffer();//屏幕解锁

      
//执行我们的特效

      
gui_my_SSE_run_effect_type(activate_layer, current_layer,
precious_layer);

      

      
//刷新一下屏幕,恢复新屏幕

      
gdi_layer_flatten_ext(activate_layer, current_layer,
NULL,NULL,NULL,NULL);

      
UI_BLT_double_buffer(0, 0, 240, 320);

      

      
gdi_layer_free(precious_layer);//释放图层

      
gdi_layer_free(current_layer);

}

 

到这里,工作已经完成一半了,就看一下gui_my_SSE_run_effect_type要执行什么效果了。下面,我列举了两个典型的效果:

void gui_my_SSE_run_effect_type(

GDI_HANDLE handler1,

GDI_HANDLE handler2,

GDI_HANDLE handler3)

{

      
//获得自己定义的切换效果

gui_my_sse_type effect_type=gui_my_SSE_get_type();

      
switch(effect_type)

      
{

             
//一个慢慢放大的圆

             
case GUI_MY_SSE_EFFECT_CIRCLE:

                    
gui_my_SSE_effect_circle(handler1, handler2, handler3);

                    
break;

             
//慢慢展开的扇子:

             
case GUI_MY_SSE_EFFECT_ROLL:

                    
gui_my_SSE_effect_roll(handler1, handler2, handler3);

                    
break;

             
default:

                    
break;

      
}

}

先来看一下效果:

1、  慢慢放大的圆:

 

我们来说一下怎么做,如果大家学过计算机图形学的话,画圆应该是很容易的,有中点画圆算法、Bresenham画圆算法等等;我直接用的是MTK现有的算法,懒得去考究它是什么算法。

#define GUI_SSE_CIRCLE_R 25

void gui_my_SSE_effect_circle(GDI_HANDLE handler1, GDI_HANDLE
handler2, GDI_HANDLE handler3)

{

      
S32 r;

      
for(r=GUI_SSE_CIRCLE_R; r<=200;
r+=GUI_SSE_CIRCLE_R)

      
{

             
gdi_draw_solid_buffer_circle (120, 160, r, new_layer_buff_ptr,
old_layer_buff_ptr);

             
gdi_layer_flatten_ext(handler1, handler2,
handler3,NULL,NULL,NULL);

             
UI_BLT_double_buffer(0, 0, 240, 320);

      
}

}

//MTK的画圆算法,由MTK画圆函数改过来:

void gdi_draw_solid_buffer_circle(S32 x, S32 y, S32 r, U8*
input, U8* output)

{

       
float delta;

       
S32 m, n;

 

       
for (delta = 5.0 / 4 - r, m = 0, n = r; m <= n; m
++)

       
{

           
gdi_draw_line_buffer(x - m, y - n, x + m, y - n, input,
output);

           
gdi_draw_line_buffer(x - m, y + n, x +m, y + n, input, output);

           
gdi_draw_line_buffer(x - n, y - m, x + n, y - m, input,
output);

           
gdi_draw_line_buffer(x - n, y + m, x + n, y + m, input,
output);

           
if (delta >= 0)

           
{

               
delta += 2.0 * (m - n) + 5;

               
n --;

           
}

           
else

           
{

               
delta += m * 2.0 + 3;

           
}

       
}

}

 

void gdi_draw_line_buffer(S32 x1, S32 y1, S32 x2, S32 y2, U8*
input, U8* output)

{

      
U32 size, position;

      
if((y1<0) || (y2>319) ||
(x2<0) || (x1>=x2) )

             
return;

      
if(x1<0)

             
x1 = 0;

      
if(x2>240)

             
x2 = 240;

      
position = (y1*240+x1)<<1;

      
size = (x2-x1)<<1;

      
memcpy(output+position, input+position, size);

}

 

2、慢慢展开的扇子,这个用的是Bresenham画直线算法,由于代码比较长,就不贴出来了,大家知道原理就好。

 

 

 

3、还有很多效果,上下切换,左右移动,放大缩小,旋转变换,淡入淡出,飞入飞出等等特效,有兴趣的朋友可以去实现。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/menghnhhuan/archive/2010/11/21/6025019.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: