2005年03月04日



处世哲学:如何快速看透一个人

时间:2005-03-03 23:16:10 阅读数:4891 
作者:无心戒烟  会员级别: 给作者留言




看一个国家的国民教育,要看他的公共厕所。

看一个男人的品味,要看他的袜子。

看一个女人是否养尊处优,要看她的手。

看一个人的气血,要看他的头发。

看一个人的心术,要看他的眼神。

看一个人的身价,要看他的对手。

看一个人的底牌.要看他身边的好友。

看一个人的性格,要看他的字写得怎样。

看一个人是否快乐,不要看笑容,要看清晨梦醒时的一刹那表情。

看一个人的胸襟,要看他如何面对失败及被人出卖。

看两个人的关系,要看发生意外时,另一方的紧张程度。

看你重不重视我的贴子,就要看你有没有看到此处了。

出处:http://club.china.alibaba.com/club/post/view/40_3491203.html

此文未经作者无心戒烟 同意就转贴了。如认为属于侵权,请跟我联系,我会立刻撤销本页面。

2005年03月02日

基本概念:
函数依赖的定义:
 设R(A1,A2,…,AN)是一个关系模式,X和Y是(A1,A2,…,AN)的子集,若只要关系r是关系模式R的可能
取值,则r中不可能有两个元组在X中的属性值相等,而在Y中属性值不等,则称“X函数决定Y”,或
“Y函数依赖于X”,记作X->Y。
非平凡的函数依赖:
 若X->Y,但Y≮X,称为非平凡的函数依赖。

第一范式(1NF):
 元组的每个分量必须是不可分的数据项。
第二范式(2NF):
 若关系模式R∈1NF,且每一个非主属性完全函数依赖于码,则R∈2NF。
第三范式(3NF):
 若关系模式R∈2NF,且每一个非主属性都不传递依赖于码,则R∈3NF。
Boyce-Codd 范式(BCNF):
 若关系模式R∈1NF,且对于每一个非平凡的函数依赖X->Y,都有X包含码,则R∈BCNF。

2004年11月07日

      我的个人电脑,给我的感觉,就像我自己的家,但又不全是。我了解它吗?作为一个程序员,想到这个问题,我不禁惭愧。虽然我能胜任我现在的工作,但是却不了解自己的电脑。

       系统中有多少内存?多少页面文件?使用情况是怎么样的?某一时刻,系统中有多少进程在运行?是什么进程?他们的具体情况是怎么样的?在这个网络时代,自己的电脑中到底有没有别人在访问自己?自己的电脑中到底有没有进程跟外界通讯?如同作家主一样,我要控制自己电脑的所有大门,谁进来了,我都要清楚进来这个家的到底是什么东西!

        为了解决以上问题,我决定亲历亲为。现在的情况是,对于系统的内存的使用情况,基本上,我可以解决了。解决之道是:利用windows操作系统提供给我的API函数和结构:
        

typedef struct _MEMORYSTATUS { DWORD dwLength;//这个结构的大小,in bytes; DWORD dwMemoryLoad;//使用中的物理内存的百分比; SIZE_T dwTotalPhys;//所有物理内存的大小,in bytes SIZE_T dwAvailPhys;//所有可用物理内存的大小,in bytes SIZE_T dwTotalPageFile;//已提交内存的大小,in bytes SIZE_T dwAvailPageFile;//可提交内存的大小,in bytes SIZE_T dwTotalVirtual;// 调用进程的用户方式的虚拟内存的空间大小,in bytes SIZE_T dwAvailVirtual;//调用进程的用户方式的可用(未保留、未提交)虚拟内存的空间大小,in bytes } MEMORYSTATUS, *LPMEMORYSTATUS;
这个法宝怎么使用呢?嘿嘿,有另一个法宝:GlobalMemoryStatus() function 。我知道这些东西,无非就是看了msdn。为了将来回忆往事而有所凭依,才写下来。万一将来不会英文了呢,现在正好先翻译过来。要使用这两个法宝,只需要我们#include ,凡是windows下的sdk编程,这个需要是必要的需要了。也就是说,用这两个法宝没有增加原来程序的什么东西。可是知道这些信息对我好像没有什么帮助,因为这些信息只是描述目前系统的内存的使用梗概。好,继续去发现。。。
 如果有个变态的人偏偏要为难你,说,“我要向某个地址空间写一段代码”。也许我该叫上帝来应付这个超级难侍候的主,可是我是男子汉啊,有什么困难不能解决呢?自己扛吧!!
 其实我很同情内存的。好好一块内存,竟然给这么多好事的人瓜分一块块的。呜呜,有点像当年的八国联军,瓜分中国没商量。中国当年给瓜分,(不清楚是什么年代了,我是不称职的龙的传人,哎),有什么好处呢?好处当然有的啦,当然,这种好处主要也是对那八个国家来说的。他们可以在自己分得的那块地盘上,尽情掠夺,别人来的话,不行,俺不同意。这样别人就不敢来了。为什么不敢来?大家都在玩这个瓜分游戏,当然要遵守游戏规则。要是你能抢别人的话,弄不好也会被别人抢的。幸好,咱们这个内存没有落得这样的命运,毕竟人们都变得斯文了。
 要了解内存,需要怎么做呢?当然要了解关于内存的术语了,在www.baidu.com就可以能找到答案,尽情飞舞吧。咱用操作系统是Windows xp professional,嘿嘿,昨天才知道的。上司问我,你的操作系统是什么?靠,这么弱智的问题都有人提出来。而我就是愣在那里,我不知道。世上真是无奇不有啊,眼前这个陪伴了我快两年的好伙伴叫什么名字,我竟然想不起来。自从我给她起了个名字“MyWife"以来,我忘了她的真名。既然她是windows家族的,好,要想了解她的内存分配、管理的方式,就研究windows的内存管理系统就好了。 老是翻书,十足的读书人了。这次我就不再查书。赫赫。内存是。。。?你知道吗?要说出答案来,多么的困难啊。就好像你站在广场的中央,我远远的看,靠近来看,站在左边看,站在右边看,都会看到你,但你的形象各不相同啊。内存其实是个俗名,老外管它Memory,一个存储器而已。在存储器系统里面,还有很长串的族谱呢。有兴趣的话,就去看看吧。我可是怕了他。在存储器系统里,有Registers,Memory,Disk。跟Cpu打交道的呢就是Registers和Memory。咱么(程序员阿,很拽的)平时的工作就是要让Cpu按人们的安排做事情。cpu做事情的时候,就从Memory和Registers中获取我给她最高指示,接受我给她的可利用的数据(赫赫,只能处理数据)。为了让cpu接收到我的最高order的时候,能做无奇不有事情,我就要把“指令”首先存储到Memory当中,如果Memory的容量能够足够大,我就可以让cpu做更多的事情,哈哈。我们去市场买回来的内存条——就是这个Memory,你知道这个不起眼的家伙身价多高了吧?不用慌,别人替你想好了,虽然这个Memory容量比较小,你可以用虚拟内存的概念,把disk这个游手好闲的家伙拉进来,嘿嘿,Disk的肚子可大了,咱们还可以把指令存储到Disk的肚子里,你觉得麻烦?看起来是很麻烦的,你看,把指令存储到三个地方,每个地方的关卡口令都不一样,很麻烦的!!不着急嘛,我不是说了虚拟内存吗?你就别管这么多了,反正对你来说,世界照样转cpu在出厂的时候已经被教化的很好了,他知道怎么处理disk和Memory。哎,自己想吧。我说的这些东西啊,不是你看到的,你看到只是操作系统给你的API。怎么回事?cpu做好之后,他就能辨别一套指令系统了。可是这套指令系统太枯燥了,要用这套指令系统来指令cpu工作,那就是白受罪了。所以人们又搞了一个叫操作系统的家伙来使用。现在的操作系统啊,他一出生就充满力量,厉害吧?对,他能放首歌,上网。。可是,人们的需要是千奇百怪的,有个特殊的需要怎么办呢?当当当,轮到我们程序员出场了,在这个时候,我挺身而出,我用操作系统能听懂的语言沟通沟通,他就能解决你的问题了。哇,兜了好大圈子啊。终于清算出我们研究的对象了吧?就是操作系统!我们只跟操作系统沟通,无论我怎么给她人性化,始终她是个机器。她的一切都定下来了,我只能熟悉她的一切,才能跟她沟通。首先要知道的,就是我们存放指令的地方发生了什么变化。恩,最大的变化就是实现了区块分块管理了。简称“内存空间分区”。嘿嘿,现在不说内存了,咱说内存空间了。 Windows的内存空间是怎么分区的?每个系列都不同的。win98,win2k,winXP,都不相同,但是大体一致的。
 
2004年10月06日

 

Geometry Independent Interactive Lighting with

Orthogonal Illumination Maps

Cass Everitt

Abstract

One shortcoming of the OpenGL lighting model is that lighting calculations are only performed per vertex. This typically requires that applications oversample the geometry to produce many more vertices than would otherwise be required. In the same way that traditional texture mapping is used to enhance the complexity of a scene without additional geometry, orthogonal illumination maps can be used to enhance the complexity of the lighting in a geometry independent fashion. The technique of orthogonal illumination mapping is a multipass technique designed to shift the computational burden of lighting calculations from the geometry processing portion of the OpenGL pipeline to the fragment processing portion. This is appropriate since much of the recent work in OpenGL hardware has been to extend and enhance fragment processing capabilities.

Note

I will use the term multipass when referring to rendering techniques that take advantage of any of accumulation buffering, blending, or multitexturing to achieve their effects.

History

This section will need to discuss a lot, probably. There is a lot to be said for where texture mapping came from, what bump mapping is and where it came from. Robert, I will need some help from you on outlining what’s important to cover here.

Here is a first shot at what might be useful:

  • What is texture mapping?
  • What is the basic technique?
  • Who invented it?
  • Why?
  • What is bump mapping?
  • What is the basic technique?
  • Who invented it?
  • Why?
  • How does it compare to texture mapping?
  • Texture mapping techniques to improve interactive illumination
  • Bump mapping (multipass)
  • Projective textures (for spotlight textures)
  • Environment maps
    • Specular illumination (multipass)
    • Gloss maps (multipass)

 

Orthogonal Illumination Maps

The texture-based bump mapping technique [Peercy, Cabral] describe requires computing texture coordinate biases per vertex that are somewhat expensive, but then amortizes that cost over the polygon interior. Orthogonal illumination maps require only a per frame calculation. The trade off is that this technique only applies to diffuse illumination by directional (or infinite) light sources.

The basics of the process are simply a reorganization of the diffuse illumination equation such that the operations can occur in the fragment processing stage of the OpenGL pipeline. Diffuse illumination is given by

C = (L . N) Cl * Cd (Equation 1)

Where Cl is the color of the light source and Cd is the diffuse color of the material. Typically what happens in an OpenGL application is that Cl, Cd, N and the light position (or direction) are specified and OpenGL evaluates the equation at each vertex.

First, we need to decompose the dot product in order to move the evaluation of this equation out of the geometry processing.

L . N = Lx * Nx + Ly * Ny + Lz * Nz (Equation 2)

Equation 2 begins to look like something that could be implemented with a multipass technique, except that the components are signed and our fragment processing is generally clamped to the range [0,1]. To deal with this, we will split each normal component as follows:

Nxp = clamp(Nx, 0, 1)

Nxn = clamp(-Nx, 0, 1)

Nyp = clamp(Ny, 0, 1)

Nyn = clamp(-Ny, 0, 1)

Nzp = clamp(Nz, 0, 1)

Nzn = clamp(-Nz, 0, 1) (Equation 3)

Now we can rewrite Equation 2 as:

L . N = Lx * Nxp + Ly * Nyp + Lz * Nzp – Lx * Nxn – Ly * Nyn – Lz * Nzn (Equation 4)

If we make each of Nxp, Nyp, Nzp, Nxn, Nyn, Nzn become a luminance texture and we use the GL_TEX_ENV of GL_MODULATE, we can factor the Lx, Ly, and Lz terms into the object’s color in separate rendering passes. Since half of the terms are negative, three of the passes will require subtractive blending. To avoid clamping problems, all the additive passes should occur first.

The following algorithm demonstrates the sequence of operations assuming Lx, Ly, and Lz are non-negative.

  1. Disable blend, enable polygon offset
  2. Set polygon offset
  3. Set blendfunc to ONE, ONE
  4. Set blendEquation to FUNC_ADD
  5. Ctemp = Lx(Cd * Cl)
  6. Call glColor3fv(Ctemp)
  7. Bind Nxp texture
  8. Render the geometry
  9. Enable blend
  10. Adjust polygon offset
  11. Ctemp = Ly(Cd * Cl)
  12. Call glColor3fv(Ctemp)
  13. Bind the Nyp texture
  14. Render the geometry
  15. Adjust polygon offset
  16. Ctemp = Lz(Cd * Cl)
  17. Call glColor3fv(Ctemp)
  18. Bind Nzp texture
  19. Render the geometry
  20. Set blendEquation to FUNC_REVERSE_SUBTRACT
  21. Adjust polygon offset
  22. Ctemp = Lx(Cd * Cl)
  23. Call glColor3f(Ctemp)
  24. Bind the Nxn texture
  25. Render the geometry
  26. Adjust polygon offset
  27. Ctemp = Ly(Cd * Cl)
  28. Call glColor3f(Ctemp)
  29. Bind the Nyn texture
  30. Render the geometry
  31. Adjust polygon offset
  32. Ctemp = Lz(Cd * Cl)
  33. Call glColor3f(Ctemp)
  34. Bind the Nzn texture
  35. Render the geometry

Simple conditionals on the sign of Lx, Ly, or Lz can be used at each of the 6 passes to determine which texture to load and to possibly flip the sign of Ctemp (in the case of negative components).

Ok – I’m done for now. I will pick it back up when I regain my cognitive skills.

 

出处:

http://www.r3.nu/~cass/thesis/thesis.html

2004年10月02日

这三方面涉及到的函数:

void   glColor(red,   green,   blue,   alpha);
void   glShadeMode(   GLenum   mode);//GL_SMOOTH ,   GL_FLAT .
void   glEnable(   GLenum   cap)   ; // GL_LIGHTING

//设置光照模型:光线的类型及光线的亮度。
void glLightModelf(
  GLenum
pname,  
  GLfloat param  
);

void glLightModeli(
  GLenum pname,  
  GLint param    
);
 

void glLightModelfv( GLenum pname,  const GLfloat *params ); void glLightModeliv(  GLenum pname,  const GLint *params ); 

//设置材质属性:
void glMaterialf(
  GLenum
face,  
  GLenum pname, 
  GLfloat param 
);

void glMateriali(
  GLenum face,  
  GLenum pname, 
  GLint param   
);

void glMaterialfv( GLenum face,  GLenum pname,  const GLfloat *params ); void glMaterialiv(  GLenum face,  GLenum pname,  const GLint *params ); 
void glColorMaterial(GLenum face, Glenum mode);//使face的mode 跟踪下面的glColor()的颜色。

glEnable(GL_XXXX)这个函数主要是开启OPENGL的功能,好歹算是个控制枢纽。原型:glEnable(GLenum cap  );

cap :

GL_TEXTURE_2D :开启2D纹理贴图功能。把bmp文件贴到多边形时   要用到这个功能。
GL_TEXTURE_1D:开启1D纹理贴图功能。未体验过。
GL_LIGHTING:       开启光照功能。使OPENGL按照光照理论,可以利用材质属性和光照参数为某一个定点决定最终的“颜色”(视觉效果)。计算方法:图元的每个顶点都被赋予了一个RGB值,该值是根据环境、散射和镜面三种光照值与材质对该三种光的反射率相乘之后的“净”效果来决定。
GL_COLOR_MATERIAL:   开启颜色跟踪法,If enabled, have one or more material parameters track the current color

2004年09月30日

1.Translate 和 Rotate 的作用都是叠加的。
      Translate每一次操作都把当前所在的位置作为原点。Rotate每一次操作都是相对于当前原点的(而不是屏幕的中央)。所以下面两段代码的效果不一样的:
      Exp1能带来好像月球围绕地球旋转的同时还有自转的效果。
      Exp2带来的则是两个独立的自转的系统。

Exp1:
       glLoadIdentity();
       glTranslatef(-1.5f,0.0f,-20.0f); 
       glRotatef(rtri,0.0f,1.0f,0.0f);
       glTranslatef(3.0f,0.0f,0.0f);
       glRotatef(rquad,1.0f,0.0f,0.0f); 和

Exp2:
        glLoadIdentity();
        glTranslatef(-1.5f,0.0f,-20.0f); 
        glRotatef(rtri,0.0f,1.0f,0.0f);
        glLoadIdentity();
        glTranslatef(-1.5f,0.0f,-20.0f);
       glTranslatef(3.0f,0.0f,0.0f);
       glRotatef(rquad,1.0f,0.0f,0.0f);
 
2.Texture(纹理贴图)  ———————————— by  10月1日凌晨

      初始化:
       1) 读取bmp文件。需要获得的信息有,位图的width 和 height ,最后就是数据指针(UNSIGNED BYTE TYPE)。
       2) 产生Texture Names (调用glGenTexture(n,&texturenames[0])),通过glBindTexture()绑定之后,就可以用texturenames来选择所操作的texture了。glBindTexture()的主要功能是给texture data 分配texture name。
           The glBindTexture function enables you to create a named texture。Texture names are unsigned integers with the value zero reserved to represent the default texture for each texture target. Texture names and the corresponding texture contents are local to the shared display-list space of the current OpenGL rendering context; two rendering contexts share texture names only if they also share display lists. You can generate a set of new texture names using glGenTextures. (以上e文摘自msdn)。

        (大概意思:glBindTexture 能产生命名texture,Texture names 是无符号整数,0 表示每个texture target 的默认texture。Texture names 和 相应的texture contents 所占用的空间来自于当前OpenGL 的rendering context的  共享的 显示列表。)例子:
             glBindTexture(GL_TEXTURE_2D, texture[0]);

      3) 定义生成何种纹理。调用glTexImage2D()来定义2D纹理。调用glTexParameteri()设置滤镜。

 完成以上几个步骤后,剩下来的就是要根据名字Texture names来选择Texture,接下来设置纹理坐标。

选择Texture:
         调用glBindTexture(GLenum target,     GLuint texture )来选择所要操作的内容。texture 就是上面的Texture names。例子:
         glBindTexture(GL_TEXTURE_2D, texture[0]); texture[0]已经有上面的步骤准备好了。由于上面texture[]可以有多个命名,所以在这里要选择你所要操作的texture了。

设置纹理坐标:
        纹理有两个方向的坐标:s(横坐标)(0.0,纹理图像最左侧的像素的坐标,1.0,最右侧的像素的坐标),t(纵坐标)(0.0,纹理图像的底部;1.0,顶部)。主要目标就是——将纹理图像的一个特殊的位置与多边形的顶点相关联)。例子:
glBegin(GL_QUADS)

…..
// 纹理图像最左下角与多边形顶点(-1.0f, -1.0f,  1.0f)相对应,即显示图像时,这个像素显示在顶点(-1.0f, -1.0f,  1.0f)的位置上。
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f); 
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f); 
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f); 

…..

glEnd();

ps::
关于纹理坐标,可以这样子理解:想象一张很大grid,每个cell的长,宽为1.0f。这个grid的bottomleft为[0,0],y轴向上增长,X轴向右增长。由glTexImage2D产生纹理时指定的bmp图填充一个cell。则调用glTexCoord(X,Y)时,X,Y就在这样的grid下取值,点(x,y)所对应的bmp图上的坐标应该为:
x’ = x 减去小于x的最大整数,y’ = y 减去小于y的最大整数。如下面的序列:

 glBindTexture(GL_TEXTURE_2D, texture[0]); // Select Our Logo Texture glBegin(GL_QUADS); // Start Drawing A Textured Quad glTexCoord2f(0.0f, -roll+0.0f); glVertex3f(-1.1f, -1.1f, 0.0f); // Bottom Left glTexCoord2f(3.0f, -roll+0.0f); glVertex3f( 1.1f, -1.1f, 0.0f); // Bottom Right glTexCoord2f(3.0f, -roll+3.0f); glVertex3f( 1.1f, 1.1f, 0.0f); // Top Right glTexCoord2f(0.0f, -roll+3.0f); glVertex3f(-1.1f, 1.1f, 0.0f); // Top Left glEnd(); // Done Drawing The Quad
这个纹理贴图的效果则是:   在{[-1.1,-1.1],[1.1,-1.1],[1.1,1.1],[-1.1,1.1]}这个方框里填充了(3*3= 9)张bmp图texture[0]。//copyright by 2004-10-03 

//–by 2004.10.1

3.雾化。glFog()选择雾化类型。

      OPENGL支持三种雾化效果:GL_LINEAR产生深度感。GL_EXP为大雾或云的效果。GL_EXP2为烟和薄雾效果。
       

 

 

 

2004年09月23日

C语言动画技术的实现方法

陈  福

在利用C语言进行工程开发、游戏设计以及计算机辅助教学软件研制中,都要采用动画技术。动画具有突出并强化事物特征、实现工作模拟、进行图形变换等多种功能,使所开发的软件科学合理、生动形象。我们在多年计算机辅助教学软件的开发研制实践中,探索出C语言动画技术的几种实现方法,现介绍如下:

一、利用目标移动技术实现画

动画的形式是多种多样的,目标移动是其中之一,即将被移动的目标由屏幕的一个位置移动到另一个位置。如果直接一步到位移动,没有中间过程,会使人有生硬或突然感,动感不强,为了实现良好的动感,必须根据目标的大小及移动距离的长短分成苦干步来实现,每动一步先用底色覆盖原来的目标,再将移动目标复现在政一位置,这样依次到目的地,由于人眼具有视觉暂留的生理现象,人的肉眼见此移动过程具有真实感。很多资料中又将这种动画设计方法叫做中间化。用此法还可以进行平移、变形、旋转等动画设计。如下程序中的MOVE-1( )函数便是利用目标移动覆盖的方法在屏幕上左右往返移动一个圆和一个长形的子程序。

二、利用存取位图像函数产生动画

上一种方法每移动一步都要在中间点上重新绘制移动目标,移动目标小,且绘制简单的内容较容易实现,而当被移动目标大且绘制较复杂时,采用这样的方法就不理想,C语言图形库中有将指定区域的一个位图像存到主存储区中的函数getimage( )和在屏幕指定位置上显示一个图像分配图像函数putimage( ),两个函数为存储图像分配存储空间,(x1,y1),(x2,y2)图像时,首先通过inagesize(x1,y1,x2,y2)函数为存储图像分配存储空间(x1,y1),(x2,y2)分别为图像的左上角和右下角的坐标,然后调用malice[imagesize(x1,y1,x2,y2)]得到新分配块的指针,如果没有足够的空间分配给新块就返回NUL,最后用  getimage(x1,y1,x2,y2,viod  far *buffer)将屏幕矩形区域内容保存到主存储区,前四个参数为图像左上、右下角坐标,buffer为指向主存储区中存放位图像区域的指针,至此,移动目标存储完毕。调用 putimage(x1,y1,void  far *buffer,ops)将以前用getimage保存的图像重新送回屏幕,图像的左上角坐标为(X1,Y2),buffer为指向保存源图像的主存储区域的指针。参数ops指明了一个组合算子,它用于颜色,该颜色是由显示区域已在屏幕的和保存源图像的像素来计算的。其取值有拷贝(COPY-PUT)、异或(XOR-PUT)、或(AND-PUT)和拷贝源图像的非(NOT-PUT)等几种,取COPY-PUT时,将源位图像拷贝到屏幕上,取XOR-PUT时,将源位图像同显示区域已在屏幕上的图像“异或”等等。巧妙使用这两个函数,可以产生多种动画形式,在下例程序中,MOVE-2子程序就是应用此法使一昆虫在屏幕的任一位置随机飞舞。

三、利用活动动页产生动画

一些计算机的图形硬件提供了两个以上独立的存储区或存储页,用户可以在这些区或页中进行绘图、显示,这种方法只适用于几种图形适配器,如VGA有两个屏幕页,EGA有四个屏幕页。利用这种方法产生动画的基本思想是将各页预先绘好显示内容,然后在它们之间互相切换,或屏幕页的交替显示,便可产生动画。

在C语言图形库中有一函数setactivepage(nit  page),通过对该函数的调用可以使用page成为活动页,该句后面的所有图形输出都针对page 图形页,此时在本页各种图形绘制的过程在屏幕上看不到,当调用setvisualpage(nit  page)时,就使得page成为可见图形页。有了多个图形页,程序就可以将图形输出到一个关闭的屏幕页,呆以理解为先在屏幕的后台工作,然后,通过调用setvisualpage改变可见页来快速显示后台屏幕图像,从而产生动画。如下例中的move-3子程序就是利用两页屏幕来实现单摆的往复运动,方法是在活动页上绘制单摆的下一位置图形后,再将此活动页变成可见页,另一页变成活动页画下一个单摆面……这样单摆便运动起来。

四、利用调色板产生动画

以上所介绍的移动、复制、交替出现的动画生成方法,都是使目标运动。有时可以利用调色板改变颜色产生动画。设计基本思想有二:一是各目标按所设计的颜色用调色板变色产生闪动感,如星空、灯光等;二是用不同的颜色(有一定的规律)在屏幕的一系列位置上绘制出目标,当改变调色板中的颜色时,所有的目标都将改变颜色,颜色的有序变化,就可以产生动画,如高山流水,便可用此法实现。

C语言图形库中有关调色板的函数有:getpalette(struct  palettetype  far* palette)函数,它将有关当前调色板尺寸和颜色信息填入到由palette所指的palettetype的结构中;setallpalette(struct  palettetype  far*palette)函数把当前调色板置为由palette所指的palettetype结构中给出的值;setpalette(int  inco  ,  int  blco)函数将调色板中的入口颜色inco改变为颜色blco。如:setpalette(0,4)便将当前调色板中的第一种颜色(即背景颜色)改变为实际颜色数4,屏幕上的其它颜色也随之改变。下例中的MOVE-4( )子程序就是利用调色板产生动画的实例,内容为一个晴朗的夜晚,天上皓月当空,群星闪烁,地下灯光闪闪,灿烂耀眼,好一幅月夜美景图。

五、利用掩模技术产生动画

所谓掩模,就是对于被移动的目标,使用两个稍有不同的图像,这两个特殊的图模互相混合,从而使移动的目标在经过背景时,不改变颜色,它是对getmage和putimage函数的深层应用。实现的方法是,对移动的目标事先做好AND图和XOR图,这两上特殊的图制作方法是不同的,AND图要求目标轮廓内容点的像素值为0,而XOR图则按实际颜色去制,并将这两个图用getimage保存于存储区中,当移动该目标时,先将要移动位置的屏幕保存,然后第一个模与屏幕相“与”,第二个模与第一个模相“异或”,最后,复制回保存的屏幕,两个模组合后目标将以正常的颜色出现在屏幕上,并且背景也保持不变。子程序move-5就是应用此法简单模拟地球围绕太阳转的实例。用此技术还可以使多个目标在屏幕上同时运动,如太阳系的九大行星的公转等。

六、利用移动背景法产生动画

有些动画内容只移动目标是不能产生很好的动画效果的,如汽车的长时间行驶、飞机的航行等,由于受到屏幕所限,只能是稍纵即逝。但可以用背景移动法来实现动画,基本思想是目标不动,通过移动背景,使视觉产生相对运动,从而形成动画,移动背景要采用以上几种方法。限于片幅,不再举例。

动画实现的方法是多种多样的,只要我们在实际应用中,科学设计,灵活应用,定会使您的动画达到理想的效果。

 

2004年09月22日

我想开发一个2D图形界面程序。在VC下,我尝试用一个console程序做程序的入口,在文本模式下,为了显示图形,我用了一个比较笨的方法:找到本窗口的handle,然后在这个基础上利用在sdk上的知识来画图,如用到GDI。但是这个方法反应太慢了。所以我改用TC30来做。因为在TC中提供了一个Graphics.h让我们在console中由文本模式切换到图形模式,而且这方面的资料比较多。在VC中还找不到这么简单的方法来画图。

1。首先下载完整的borlandc Turbo C++3.0

2。设置Options–>Linker—->Library  ,选择Graphic Library.

如果不进行这个设置修改,会出现连接错误的。嘿嘿。

至于Graphics.h提供的函数怎么使用,以后再补上吧。哈哈

2004年08月30日

那条江,
静静的,安详的,
缓缓的流过我的家乡;
那座山,
默默的,平和的,
稳稳的怀抱我的家乡;
那条江,还有我和儿伴追逐的影子;
那座山,还有我和同窗快乐的笑声;
我那遥远的家乡啊!
虽然我离开了你,
虽然我不在你身边,
我的心已属于你!

每次我悄悄回去,
每次我得到你的消息,
心,澎湃着,
血,翻腾着,
家乡啊,你是我唯一的骄傲!
家乡啊,你是我唯一的动力!

 

(我离开家乡多年,脑海中经常出现家乡的山啊水啊,能够平静我在喧闹生活里的烦躁。我很希望能够为家乡的建设,为家乡的人民做些什么。我希望在外面历练的年月里,能够获得足够的能力回到家乡,改善人们的生活。今年已经26岁了,还是一事无成,但是想到家乡,我像听到他的呼唤,于是我能够继续挣扎在这个人间炼狱。)