从窗口系统的显示角度上看,这可以给我们带来很大的方便,帮助实现更高质量的视觉效果,比如:
1、访问窗口:现在所有的窗口都显示到离屏表面,这些离屏表面就可以用于其他的地方了。例如前面提到的Alt-Tab组合键所看到的缩略图,用户还可以据此实现一些其他需求。
2、窗口 *** 作中不再涉及到背景应用程序:在Vista之前,如果隐藏的窗口变得重新可见,这部分区域只有在应用程序醒来后并响应了WM_PAINT才能被重画,这就引起了很多难看的效果。在Vista中,背景窗口不会收到WM_PAINT,也不会被要求提交,因为他们的内容已经在离屏表面当中了,可以被直接拿来进行重新合成。
3、更炫的用户体验,这个不用多说了,大家可以有自己的体验感受。
4、高分辨率支持:大部分应用程序不知道它所运行的显示器的分辨率。随着高分辨率显示器的普及,这会使应用程序在物理空间看起来越来越小,效果很差。由于DWM访问了窗口的离屏表面,其特殊的位置可以调整应用程序的显示分辨率,使它在高分辨率显示器上有更好的效果。
在DWM中,我们的每个窗口都用一个Surface表示,都可以看到为是3D的网格。虽然每个窗口还是一个矩形,但它们都位于一个3D空间之中。窗口的 *** 作,比如最大化,还原等等,都发生了变化,它们都是对网格进行3D变换实现的。与以往有了很大的区别。
在Windows Vista或Windows7中窗口的毛玻璃效果非常绚丽。在窗口的边界,我们可以看到窗口下面的内容。这其中同时具有一个的透明和模糊效果。但是,在实现毛玻璃时,为了不让下面的窗口内容过于清晰影响上面的窗口,DWM组还对下面的窗口实现了模糊效果。 1、模糊下面的内容,这是由自定义的象素Shader实现,这个Shader是一个完全运行在GPU的小程序,它可以并行处理多个象素。
2、模糊只是针对窗口边界下的部分内容。这些内容需要从不同的缓冲提取出来。
3、摸索的方法类似于平均值处理:一个象素的值等于其邻居象素的平局值。
众所周知,Direct3D支持多个Surface,最后显示不同Surface时是通过Flip(翻转)实现的,DWM也是如此。这样实现的结果就是不会在出现以前的Tearing。使得桌面变得更平滑。
现在,我们的桌面虽然称得上是一个全屏幕的Direct3D应用程序。不管是老式只支持帖图加速的图形处理器还是新型的高速图形处理器,我们都需要 *** 作图形处理器的存储系统。这就出现了两个重要的问题:
1、在窗口很多时,运行DWM需要的内存将是一个问题,它随着用户的窗口数增加而增加。
2、DWM会与其它的应用程序共享内存资源。比如DirectX应用程序、视频回放和WPF应用程序等等。
解决这些问题,微软提出了Windows显示驱动模型(Display Driver Model)。WDDM是Vista及以后 *** 作系统的新的DirectX驱动模型。WDDM主要提供三项功能:1、虚拟化视频内存。2、允许与GPU的交互。3、允许DirectX表面可以跨进程共享。
在WDDM中,显示内容是虚拟化的。这就表示显示内容与系统内存一样。我们知道,在系统内存中如果内存分配完毕,此时还有新的分配要求,就会产生第二存储页面,然后由系统管理存储页面和主存储的页面算法和机制。现在,主存储是显示内存,而第二存储页面是系统内存。在显示存储和系统内存都分配完后,将使用磁盘作为视频内存表面。当然,这种情况比较少见。但是这样的设计使得WDDM足够的健壮,应用程序的可靠性也得到增强。在WDDM而言,它将实现非常关键的功能:执行内存的分配、实现分配内存和真正的显示内存的控制。WDDM本身也在不断的改进中。
既然WDDM已经实现了显示内存的虚拟化,那么这就意味着WDDM具有调整应用程序的GPU命令优先级的功能。这种功能通常是由WDDM调度程序实现。因此WDDM必须能中断GPU的某些 *** 作,并保存 *** 作的上下文,以备在必要时恢复 *** 作继续运行。基于这项功能,WDDM提供了两种级别的调度支持:
1、基本调度。它是基于DirectX9的WDDM驱动和硬件所支持的调度粒度。也就是说单独的Primitive和Shader程序不能被中断,上下文交换必须在它们完成后进行。
2、高级调度。它是基于DirectX10的WDDM驱动和硬件所支持的调度粒度。这种调用支持比Primitive和Shader更细粒度的中断。注意,虽然DirectX10支持高级调度,但是它并不是DirecX10所必须的。也就是说,只有部分硬件支持高级调度。桌面窗口管理器使用DirectX9,因此它是支持基本调度。
前面曾经提到过,通过WDDM可以支持Surface的跨进程共享。共享DirectX表面对于重定向DirectX应用程序非常重要。因为Vista必须要和以前的应用程序兼容,就必须支持以前用GDI、、DirectX编写的应用程序。WDM必须把这些应用程序的窗口重定向到Surface,然后由WDM统一合成、最后显示一个单一的Surface。
需要注意的一点是:WDM只重定向Top-level的窗口。而对于MDI应用程序,它的所有Top-level窗口、子窗口会被合成为单独的一个Surface,然后交给DWM合成。根据以前的Windows图形系统。重定向主要分为以下三类:
1、只用GDI显示的窗口
毫无疑问,GDI应用程序在当今任是主流。WDM在重定向基于GDI的应用程序时,基本过程如下:
A、在系统内存中分配一个和窗口大小一样的内存块,然后和窗口关联。
B、显示内存中也分配一个同样大小、指定象素格式的显存块。
C、然后,当应用程序获得窗口的DC时,因为这个窗口还没有参与到WDM的合成,所以现在,它活动的DC不在是主视频内存中,而且前面在系统内存中分配的内存块。
D、经过GDI的 *** 作后,在系统内存形成一个Surface。
E、系统会根据窗口的各种参数、适当的从系统内存复制显示内容到视频内存中。
F、这样,视频内存的数据就和窗口保持一致,剩下的工作就由WDM完成:合成各个Surface,形成最终的桌面。
自己看吧:
>
李萨如图形成过程研究
在学习《大学物理》关于波动的那一章时第一次接触到了李萨如图,当时就对它变幻的图形产生了兴趣,于是就想是否能够自己来模拟绘制李萨如图。本学期,我自学了Visual Basic,尽管还不是很精通,但已经可以用它来编写绘制李萨如图,所以编写了这个小程序,作为一个研究李萨如图和振动的辅助工具。上网查寻是否已有先例,所得结果是:在各大搜索引擎中只得到了对于李萨如图的介绍,而搜索不到绘制李萨如图的程序。这就更加坚定了我一定要编出这个程序的决心。
——题记
在实际问题中,经常会遇到同一个质点同时参与两个不同方向的振动。这时质点的合位移是两个分振动的矢量和。其中,相互垂直的两个简谐振动的合成,就是我准备讨论的李萨如图的基础本质。
我认为编辑程序的前提,就是要将所用到的量和公式进行变量式处理,也可以说是数字化处理。所以,在进行程序说明以前,先对李萨如图合成原理进行分析。
李萨如图上的每一个点都可以用以下的公式进行表示:
X=A1Cos(ω1t+ψ1) Y=A2Cos(ω2t+ψ2)
从这里可以看出,李萨如图实际上是一个质点同时在X轴和Y轴上振动形成的。但是,如果这两个相互垂直的振动的频率为任意值,那么它们的合成运动就会比较复杂,而且轨迹是不稳定的。然而,如果两个振动的频率成简单的整数比,这样就能合成一个稳定、封闭的曲线图形,这就是李萨如图。
下面我介绍一下我是如何在程序中实现这一目的的。在程序中,我将公式稍加改动,成为:
X = Sin (at) Y = - Sin (bt+ψ)
其中,a和b是变量,用于获取外界输入的数值,为了保证频率成简单的整数比,所以a和b只能取个位整数。ψ是用来获取外界输入的初始相差的值,ψ=ψ2-ψ1。先前公式中的A1和A2,只关系到绘制出的图形的最高最低点和最左最右点的位置,对图形的实质没有影响,所以我将其简化为1∶1。
以上这些就是我所制作的程序的理论基础。如果将t作为可以不断自动变化一个微小量的变量,再依靠VB提供的功能就能将点(X,Y)逐一绘制在屏幕上,这样就形成了一个绘制李萨如图的过程。如果将ψ作为一个不断自动变化的变量,那么就可以使李萨如图“动”起来,即绘制出频率比相同,但初始相差不同各个图形。当这些图形一幅接着一幅出现在眼前时,就有了动的效果,这也可以模拟示波器上得到的李萨如图形。
在对李萨如图合成原理进行分析,并且对VB程序相关内容的做了仔细研究之后,终于编出了名为“李萨如图绘制程序”的应用程序。下面我就来简单介绍一下这个程序所具有的特点,也可以说是我制作得比较得意的地方。
一、可以变换绘制图线的颜色。这样的好处就是可以看清李萨如图绘制的全过程。因为李萨如图在绘制过程中会有和原图线重合的时候,这时换一种颜色,就可以知道图线仍然在绘制只不过是和原图线重合而已,并不是已停止绘制。
二、可以自定初始相差。本程序提供了八种初始相差值,这样便可以更清楚地了解李萨如图在不同初始相差下的不同形式了。
三、可以手动控制绘图速度。在一个水平滚动轴上,左右移动滑块便可以实现对绘图速度的控制。
制作这个程序,要先对李萨如图进行研究,了解其形成原理,然后再要对VB进行研究,想方设法把对李萨如图的理解用计算机语言表达出来。这个过程不仅让我对李萨如图有了更深的理解,而且也帮助我更快地掌握VB这门语言,从中还是收获不少的。如果已知一个振动的周期,就可以根据李萨如图求出另一个振动的周期,这是一种比较方便也是比较常用的测定频率的方法。因此,李萨如图有着较为广泛的应用。也希望这个程序能对李萨如图的研究有所帮助。
问题的提出:我们已经证明及拓宽了命题,现在我想更深入研究振动,比如说,如何实现互相垂直的两简谐振动的合成?(可以先由学生讨论,教师必要的提示引导,学生猜想,电脑验证。)(ppt)实际上我们刚才得到的是物理学中非常有名的李萨如图的特例,下面我们通过电脑来简单认识一下李萨如图。(由学生发现、猜想、总结)
垂直振动的叠加
命题拓宽:李萨如图。(抛砖引玉,点到为止)
在互相垂直的分振动的频率不同时,和振动的轨迹不能形成稳定的图案,但如果频率比为整数比时,和振动的轨迹为稳定曲线。
命题应用:由于图形的花样与分振动的频率比有关,因此可以通过李萨如图的花样来判断二分振动的频率比,通过频率比可以由已知频率来测量未知频率,这在电学的测量中占有重要的地位,可以达很高的精确度。
通过以上的研究我们发现,不管是简谐振动还是振动的叠加,我们都可以通过圆周运动来实现,下面我们尝试用同样的思路来探讨有关波的问题。
FC2001型李萨如图激光演示仪
价格: 面议 产地:清华大学
获取资料 咨询价格 收藏此产品
详细说明:
FC2001型激光李萨如图演示仪是清华大学物理系根据教学实验大纲研制的一款演示仪器,该实验仪设计巧妙、 *** 作简单、演示效果直观形象。
一.概述
垂直方向同频率简谐振动的合运动轨迹一般情况下是椭圆。垂直方向不同频率(ω1:ω2=m:n;m、n为整数)简谐振动的合运动轨迹是李萨如图。
垂直方向振动合成的教学一直是普物教学的难点,难就难在学生对合运动的轨迹缺乏真实、直观的认识。为了解决这个难点,不少人在这方面下了功夫,也研制出不少垂直振动合成仪,但画出的李萨如图普遍较小,大课上学生不易看清楚。
清华大学物理系研制的这种垂直振动合成仪,用激光演示李萨如图,因激光光源亮度高,演示的李萨如图图形大,在有270个座位的大教室中演示,坐在任何位置的学生都看得十分清楚.
二.仪器结构
激光李萨如图演示仪由激光电源、He-Ne激光管(腔长250mm,功率2mW)和机械部分三部分组成,如图
1.激光管; 2,4 钢尺; 3.平面镜
He-Ne激光管、两振动部件均固定在底座上。底座为长约100cm、宽10cm、高2cm的铝型材,整个机械装置重约2kg。振动部件为一钢尺,一端固定,另一端连接平面境。调节钢尺的长短可改变振动的频率,拨动钢尺,平面镜即作简谐振动。两平面镜分别运动时,可分别演示水平振动、垂直振动;两平面镜同时动作时,可演示垂直振动的合成。当两振动的频率成简单整数比时,合运动的轨迹即为李萨如图,
三.演示方法
1) 开启激光电源,在两平面镜中可分别看到两个光点。
2) 轻轻拨动一钢尺,可观察到一个方向的振动;同时拨动两钢尺,则可观察到合运动的轨迹。一般以教室的墙面作屏,当演示仪离墙面距离为5—6m时,李萨如图形的大小在米的量级,仪器离屏越远,演示的李萨如图形越大,效果也越好。
3) 参考数据如表1.
表1
频率比ωx:ωy 水平尺长x/cm 垂直尺长y/cm
1:1 22 21
2:1 16 21
3:1 12 25
四.注意事项
1) 为保证平面镜具有较高的反射率(一般要求反射率大于85%),平面镜需镀
2)为保证振动频较高,据ω= ,平面镜质量需小,一般选超薄玻璃(δ=1mm)。
3) 不许用手触摸平面镜的反射面。
4) 接通电源的情况下,不许用手直接接触激光管的接线端。
图文:李萨如图形
用砂摆演示振动图线时,要匀速地拉动摆锤下面的纸片,振动的摆漏下的细砂就形成正弦曲线。演示垂直振动的合成时,摆线为Y形(附图3),砂摆D一方面可绕AB轴摆动,另一方面在套环C点以下部分又可在任何竖直平面内摆动。振动的频率由悬线的长度决定。以AB为轴沿对方向前后摆动的摆长为 ,频率为;以C为定点沿y方向左右摆动的摆长为,频率为。如果将砂摆沿任意方向拉开,则摆的振动是上述两个垂直振动的合成,当两垂直方向振动的频率成简单整数比时,可得到各种闭合的合成运动轨迹。从砂迹图形的峰点(极值)可以得出垂直方向振动频率的比值。也就是说,沿着这种闭合曲线环绕一周后,在x方向和y方向往返的次数与两个方向频率成正比。
import javautil;
import javaawt;
import javaapplet;
import javatext;
import javaawtevent;
public class Alarm extends Applet implements Runnable
{
Thread timer=null; //创建线程timer
Image gif1; //clockp:闹钟的外壳,闹铃和报时物
boolean setflag=false,stopflag=false,cancelflag=false;
Panel setpanel;
//获取声音文件
AudioClip ring=getAudioClip(getCodeBase(), "1mid");
Button setbutton=new Button("SET");
Button cancelbutton=new Button("CANCEL");
Button stopbutton=new Button("STOP");
//响应按钮事件
private ActionListener setli=new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
setflag=true;
}
};
private ActionListener cancelli=new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
setflag=true;
}
};
private ActionListener stopli=new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
ringstop();
//清除的方法
//gclearRect(83,280,20,30);
}
};
Label note1=new Label("Alarm clock:");
//GregorianCalendar提供的是一个日历式的东东,上面又多了很多的参数,是方便 *** 作了不少。而Date类的功能远不及其,求个和日期有联系的还要自己计算。
GregorianCalendar cal=new GregorianCalendar();
GregorianCalendar cal2=new GregorianCalendar();
SimpleDateFormat df=new SimpleDateFormat("yyyy MM dd HH:mm:ss");//设置时间格式
Date dummy=new Date(); //生成Data对象
String lastdate=dfformat(dummy);
Font F=new Font("TimesRoman",FontPLAIN,14);//设置字体格式
Date dat=null;
Date timeNow;
Color fgcol=Colorblue;
Color fgcol2=ColordarkGray;
Color backcolor=Colorblue;
Label hlabel2,mlabel2,slabel2;//显示时间单位时所用的标签(时、分、秒)
int i;
int s,m,h;
TextField sethour,setmin,setsec;//显示当前时间文本框和定时文本框
//在Applet程序中,首先自动调用初始化完成必要的初始化工作,紧接着自动调用start,在进入执行程序和返回到该页面时被调用,而从该页面转到别的页面时,stop被调用,关闭浏览器时,执行destroy。
public void init()//初始化方法
{
int fieldx=50,fieldy1=120,fieldy2=220,fieldw=30,fieldh=20,space=50;//显示时间和定时文本框的定位参数
setLayout(null); //将布局管理器初始化为null
setpanel=new Panel();
setpanelsetLayout(null);
setpaneladd(note1);
note1setBounds(30,100,60,20);
note1setBackground(backcolor);
note1setForeground(Colorblack);
//定时用的文本框(时、分、秒)
sethour=new TextField("00",5);
setmin=new TextField("00",5);
setsec=new TextField("00",5);
hlabel2=new Label();
mlabel2=new Label();
slabel2=new Label();
//定时的小时文本框的位置、大小
setpaneladd(sethour);
sethoursetBounds(fieldx,fieldy2,fieldw,fieldh);
sethoursetBackground(Colorwhite);
//在文本框后加入单位“时”
setpaneladd(hlabel2);
hlabel2setText("h");
hlabel2setBackground(backcolor);
hlabel2setForeground(Colorblack);
hlabel2setBounds(fieldx+fieldw+3,fieldy2,14,20);
fieldx=fieldx+space;
//定时的分钟文本框的位置、大小
setpaneladd(setmin);
setminsetBounds(fieldx,fieldy2,fieldw,fieldh);
setminsetBackground(Colorwhite);
//在文本框后加入单位“分”
setpaneladd(mlabel2);
mlabel2setText("m");
mlabel2setBackground(backcolor);
mlabel2setForeground(Colorblack);
mlabel2setBounds(fieldx+fieldw+3,fieldy2,14,20);
fieldx=fieldx+space;
//定时的秒文本框的位置、大小
setpaneladd(setsec);
setsecsetBounds(fieldx,fieldy2,fieldw,fieldh);
setsecsetBackground(Colorwhite);
//在文本框后加入单位“秒”
setpaneladd(slabel2);
slabel2setText("s");
slabel2setBackground(backcolor);
slabel2setForeground(Colorblack);
slabel2setBounds(fieldx+fieldw+3,fieldy2,14,20);
//设置闹钟控制按钮(on,off)
setpaneladd(cancelbutton);
setpaneladd(setbutton);
setpaneladd(stopbutton);
cancelbuttonsetBounds(90,180,40,20);
setbuttonsetBounds(140,180,40,20);
stopbuttonsetBounds(522,180,40,20);
setbuttonaddActionListener(setli);
cancelbuttonaddActionListener(cancelli);
stopbuttonaddActionListener(stopli);
stopbuttonsetVisible(false);
//将面板加入当前容器中,并设置面板的大小和背景色
add(setpanel);
setpanelsetBounds(300,1,250,420);
setpanelsetBackground(backcolor);
/int xcenter,ycenter,s,m,h;
//闹钟中心点所在位置
xcenter=145;
ycenter=162;
s=(int)calget(CalendarSECOND);
m=(int)calget(CalendarMINUTE);
h=(int)calget(CalendarHOUR_OF_DAY);
//初始化指针位置
lastxs=(int)(Mathcos(s314f/30-314f/2)30+xcenter);
lastys=(int)(Mathsin(s314f/30-314f/2)30+ycenter);
lastxm=(int)(Mathcos(m314f/30-314f/2)25+xcenter);
lastym=(int)(Mathsin(m314f/30-314f/2)25+ycenter);
lastxh=(int)(Mathcos((h30+m/2)314f/180-314f/2)18+xcenter);
lastyh=(int)(Mathsin((h30+m/2)314f/180-314f/2)18+ycenter);
lasts=s; /
MediaTracker mt=new MediaTracker(this);//为给定组件创建一个跟踪媒体的MediaTracker对象,把添加到被跟踪的组
//Java允SappletHTML所在的位置(decument base)下dY料,也允Sapplet钠涑淌酱a所在的位置(code base)下dY料。藉由呼叫getDocumentBase()cgotCodeBase()可得到URL物件。@些函湍阏业侥阆胂螺d的n案的位置
//clockp=getImage(getDocumentBase(),"11png");
gif1=getImage(getCodeBase(),"2gif");
//i为id号
mtaddImage(gif1,i++);
try
{
mtwaitForAll();
}
catch(InterruptedException e)
{};//等待加载结束
resize(600,420);//设置窗口大小
}
//窗口显示有改变的时候调用paint
public void paint(Graphics g)
{//重写paint()方法
int xh,yh,xm,ym,xs,ys,strike_times;
int xcenter,ycenter;
String today;
xcenter=148;
ycenter=186;
dat=new Date();
//用当前时间初始化日历时间
calsetTime(dat);
//读取当前时间
s=(int)calget(CalendarSECOND);
m=(int)calget(CalendarMINUTE);
h=(int)calget(CalendarHOUR_OF_DAY);
//换一种时间表达形式
today=dfformat(dat);
//指针位置
xs=(int)(Mathcos(s314f/30-314f/2)30+xcenter);
ys=(int)(Mathsin(s314f/30-314f/2)30+ycenter);
xm=(int)(Mathcos(m314f/30-314f/2)25+xcenter);
ym=(int)(Mathsin(m314f/30-314f/2)25+ycenter);
xh=(int)(Mathcos((h30+m/2)314f/180-314f/2)12+xcenter);
yh=(int)(Mathsin((h30+m/2)314f/180-314f/2)12+ycenter);
//设置字体和颜色
gsetFont(F);
//前景色
gsetColor(getBackground()); //取背景色的
gdrawImage(gif1,75,110,this);
//以数字方式显示年、月、日和时间
gdrawString(today,55,415);
//画指针
gdrawLine(xcenter,ycenter,xs,ys);
gdrawLine(xcenter,ycenter-1,xm,ym); //(x1,y1,x2,y2)
gdrawLine(xcenter-1,ycenter,xm,ym);
gdrawLine(xcenter,ycenter-1,xh,yh);
gdrawLine(xcenter-1,ycenter,xh,yh);
int timedelta;//记录当前时间与闹铃定时的时差
Integer currh,currm,currs;//分别记录当前的时、分、秒
Date dat2=new Date();
cal2setTime(dat2);
//读取当前时间
currh=(int)cal2get(CalendarSECOND);
currm=(int)cal2get(CalendarMINUTE);
currs=(int)cal2get(CalendarHOUR_OF_DAY);
//这样做的话说我API已过时
//timeNow=new Date();
//currh=new Integer(timeNowgetHours());
//currm=new Integer(timeNowgetMinutes());
//currs=new Integer(timeNowgetSeconds());
if(setflag)
{ //判断是否设置了闹钟
//判断当前时间是否为闹钟所定的时间
if((currhintValue()==IntegervalueOf(sethourgetText())intValue())&&(currmintValue()==IntegervalueOf(setmingetText())intValue())&&(currsintValue()==IntegervalueOf(setsecgetText())intValue()))
{
ringplay();
gdrawImage(gif1,83,280,this);
stopbuttonsetVisible(true);
}
timedelta=currmintValue()60+currsintValue()-IntegervalueOf(setmingetText())intValue()60-IntegervalueOf(setsecgetText())intValue();
if((timedelta>=30))
{
//若当前时间与闹钟相差时间超过30秒,闹钟自动停
ringstop();
//清除的方法
gclearRect(83,280,20,30);
}
}
dat=null;
}
public void start()
{
if(timer==null)
{
timer=new Thread(this);//将timer实例化
timerstart();
}
}
public void stop()
{
timer=null;
}
//给创建线程后start之后自动执行的函数
public void run()
{
//在run()方法中,调用repaint()方法,以重绘小程序区,进行时钟显示的更新。接着调用sleep方法让当前线程(也就是我们创建的线程clockthread)睡眠1000毫秒,因为我们每秒钟要更新一下显示,所以让它睡眠1秒
while(timer!=null)
{
try
{
timersleep(1000);
}
catch(InterruptedException e)
{}
//调用repaint时,会首先清除掉paint方法之前的画的内容,再调用paint方法
repaint();//刷新画面
}
timer=null;
}
//当AWT接收到一个applet的重绘请求时,它就调用applet的 update(),默认地,update() 清除applet的背景,然后调用 paint()。重载 update(),将以前在paint()中的绘图代码包含在update()中,从而避免每次重绘时将整个区域清除
//有两种方法可以明显地减弱闪烁:重载 update()或使用双缓冲。
//使用双缓冲技术:另一种减小帧之间闪烁的方法是使用双缓冲,它在许多动画Applet中被使用。其主要原理是创建一个后台图像,将需要绘制的一帧画入图像,然后调用DrawImage()将整个图像一次画到屏幕上去;好处是大部分绘制是离屏的,将离屏图像一次绘至屏幕上比直接在屏幕上绘制要有效得多,大大提高做图的性能。
// 双缓冲可以使动画平滑,但有一个缺点,要分配一张后台图像,如果图像相当大,这将需要很大一块内存;当你使用双缓冲技术时,应重载 update()。
public void update(Graphics g)
{
Image offscreen_buf=null;
//采用双缓冲技术的update()方法
if(offscreen_buf==null)
offscreen_buf=createImage(600,420);
Graphics offg=offscreen_bufgetGraphics();
offgclipRect(1,1,599,419);
paint(offg);
Graphics ong=getGraphics();
ongclipRect(1,1,599,419);
ongdrawImage(offscreen_buf,0,0,this);
}
/ Creates a new instance of AlarmClock /
}
以上就是关于桌面窗口管理器的优点全部的内容,包括:桌面窗口管理器的优点、求李萨如图形的资料。、李萨如图的特点是什么等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)