canvas教程

云风的个人空间 : 脏矩形 demo

字号+ 作者:H5之家 来源:H5之家 2017-04-15 11:04 我要评论( )

FAQ Q: 这是什么? A: 这是一个脏矩形技术演示的 demo source code 。 Q: 如何编译? A: 在 windows 平台选一款 C 编译器,将包内所有的 .c 文件编译链接在一起即可。 Q: 这个 demo 实现了什么? A: 实现了一个支持分区域以脏矩形方式更新的画布,并以绘制矩

FAQ

Q: 这是什么?
A: 这是一个脏矩形技术演示的 demo source code 。

Q: 如何编译?
A: 在 windows 平台选一款 C 编译器,将包内所有的 .c 文件编译链接在一起即可。

Q: 这个 demo 实现了什么?
A: 实现了一个支持分区域以脏矩形方式更新的画布,并以绘制矩形为实例作为演示。

Q: demo 表现出来的东西是什么?
A: 可以说,这个 demo 什么都没有表现,仅仅是一个正方形从窗口飘过。

Q: 这些 source code 有实用价值吗?
A: 价值要看你怎么看待它,如果你不了解脏矩形技术,那么读懂它就是有价值的。如果你想在此基础上发展这些代码,它们或许也有价值。如果你想直接用来做项目,很抱歉,那它太简陋了。

Q: 代码中为什么没有注释?
A: 因为云风已经尽可能的将代码写的简洁清晰,过于详尽的代码注释不是我的风格。

Q: 为什么是 C 写的?
A: 因为这并非一个很复杂的技术,也不需要过于复杂的结构,C 更纯净一些,不需要用 C++ 。而不用汇编,可以让代码更好的被理解,如果真正需要效率的时候,我们可以做汇编优化。

Q: 有哪些地方可以被改进?
A: 代码结构设计的并不理想,函数和变量命名都太过随意。但我已经在我能够掌握的时间内(周末的整整一个晚上)把它写到让自己比较满意了。有些地方设计的并不一定合理,比如,每次刷新 canvas 的时候强制用黑色清屏(见 canvas.c 中的 drawfunc_clear 函数)。test.c 是用一个默认的机器向导生成的 win32 程序框架,并且随便添加了几行代码,显得很不严谨,鉴于这个 demo 只是演示脏举行技术,而非 windows 程序框架,时间有限的情况下一个简陋的 test 代码应当是可以接受的。

Q: 为什么发布这样的 source code?
A: 风魂已经几年没有公开的版本发布,已经流传的版本从现在的眼光看已经非常糟糕。代码组织混乱、C++ 的不正确使用、结构设计不合理等等。云风个人认为,其中还有点价值的只是脏矩形技术的思想,但这些已经混杂在体积臃肿的代码堆里。在《游戏之旅——我的编程感悟》一书第八章,我本来想用出版文字的方式把这部分技术记录下来。但直到今天才有些许空暇编写 demo 演示。

Q: 脏矩形技术在 3d 游戏为主流的今天是否已经毫无用武之地?
A: 即使在 3d 游戏中,我们依然可以用这个技术做 UI 模块,如果设计合理,可以带来极大的便利甚至更高的效率。而制作 2d 休闲游戏更加有用。

Q: source code 中 gdi 部分是可以被替换的吗?
A: 设计上就考虑了将显示部分分离,整个 demo 的代码篇幅已经被压缩到很短,读懂代码后,应该很容易把 gdi 部分替换成 directx 或是其它。比如将 canvas 提交到一个带 alpha 通道的贴图中,以制作 3d 游戏的 UI 用。同样的道理,这个 demo 中使用 16bit 色彩深度,你也可以方便的修改为 32bit 。

Q: 脏矩形技术可以进一步优化吗?
A: 可以。对于经常滚动的情况可以做滚动优化(即让 canvas 跟随场景滚动)。对于大面积的遮挡物,比如不透明的对话框时,可以做覆盖优化,让被覆盖的对象不进入渲染管道。在这个 demo 里都没有实现。或许以后再有时间,我会丰富 demo 的内容。

Q: 发现了 Bug ?
A: 如何你想使用这些代码,请关注最新版本。最新版本在云风的个人空间中能够找到。 链接如果失效,请使用搜索引擎。bug fix 的信息通常不会显著标出,但是在相关的页面的版本信息页上会表现出来,同时也有 RSS 可以订阅。如果发现了最新版本仍然存在的 Bug ,非常欢迎提交给作者云风。

Q: 如何联系作者?
A: 作者的主页是 在那里可以找到云风最新的联系方式,而且主页上有留言本,blog 和个人 wiki 也都可以留言。如果主页有一天不能访问,请用 google 搜索“云风”

Q: 这些 source code 有版权吗?
A: 作者云风保留版权,但是你可以自由的使用它,免费用在你想用的任何项目中。如果你在使用之前通知一下我,我将感到高兴,但你不这样做,也不会被指责。不过,云风保留修改和散发这些代码的权利,任何人不允许自己在公开的场合,如你的个人主页,blog,或是公开的 论坛,maillist 等地方散发这些代码。这样做,是为了代码中的 bug 可以得到及时修改,请谅解。如果你对代码做出了大规模的修改增删,那么欢迎你当成你自己的作品发布。


云风,于二○○六年五月廿一日


  • 下载 dirtyrectdemo.rar
  • canvas.h
    #ifndef _DIRTYRECT_CANVAS_H #define _DIRTYRECT_CANVAS_H     pixeldraw_funcpitchobjectycanvas;   #define COMMON_HEADER \ unsigned dirty; \ int width; \ int height; \ int kx; \ int ky;   hflip_objectcanvas_releasecanvas_drawobjectycanvas_updatecanvas_redraw  #endif
    canvas.c
      #define CANVAS_PIPELINE_EXPAND 32   struct pipe_node { draw_func funcobjecty  struct canvas_block { pixel total_objectcapability_pipeline  heightblock_wcanvas_block block  pitchobjectyiiiptrCANVAS_BLOCK_WIDTHpixelptrptr  canvas_block sizenewsizepipe_node); blk->capability_pipeline=size; blkpipe_nodeblk  canvas flip_objectpitchwh=c->height; pixel iijj<w;j+=CANVAS_BLOCK_WIDTH) { block->ptr=line+j; blockblockcanvas_block_resize(block); blockblockblock.func=flip; block.object=flip_object; block.x=j; block.block; } lineline  hflip_objectnwCANVAS_BLOCK_WIDTHnhCANVAS_BLOCK_HEIGHTcanvas canvascanvas_blockcanvas_blocknw  c->width=w; c->height=h; c->block_w=nw; c->block_h=nh; c->pitch=pitch; canvas_initc; }   iwhiijjblockblockc  struct object_2d { COMMON_HEADER } ;   objectyobject_2d object_2d leftobjobjobjlefttoprightbottom  leftleftlefttoptoptoprightrightrightbottombottombottom  ihfrom_yijcanvas_block pipe_node blk->total_object==blk->capability_pipeline) { canvas_block_resizenodenode->func=func; node->object=object; node->x=x-j*CANVAS_BLOCK_WIDTH; node->y=y-i*CANVAS_BLOCK_HEIGHT; blk->total_last|=dirty; } block  ipitchiiblk->total_object!=blk->total_last) { pixel *ptr=blk->ptr; drawfunc_clearjjjpipe_node *node=&blk->pipeline[j]; nodeblk->total_last=blk->total_object; } blk  ipitchii,++blk) { blk
    box.h
    #ifndef _DIRTYRECT_BOX_H #define _DIRTYRECT_BOX_H   #include "canvas.h"   struct box { COMMON_HEADER pixel color  box y);   #endif
    box.c
    #include "box.h"   pitchobjectybox boxwi,j; pixel *buffer=ptr; pixel coloryh+=y; ybufferbufferxw+=x; xbufferw+x>CANVAS_BLOCK_WIDTH) { wh+y>CANVAS_BLOCK_HEIGHT) { hiijjbufferbufferbuffer  box y) { canvas_draw
    gdi.h
    #ifndef _DIRTYRECT_FLIPGDI_H #define _DIRTYRECT_FLIPGDI_H   #include "canvas.h"   struct gdi { draw_func flipobject; pixel height  wndhgdi_release  #endif
    gdi.c
      struct gdi_object { HWND wnd; HDC dc; BITMAPINFO bi; RGBQUAD pal  pitchobjectygdi_object gdi_object *)object; SetDIBitsToDevice(obj->dc, x,y,CANVAS_BLOCK_WIDTH,CANVAS_BLOCK_HEIGHT, xCANVAS_BLOCK_HEIGHT, ptrDIB_RGB_COLORS   wndhgdi_object *obj; BITMAPINFOHEADER *bh; gpixel~g->flip=gdi_flip; gh*g->pitch); ggdi_object gdi_objectg->width=w; g->height=h; obj->wnd=(HWND)wnd; obj->dc=GetDC(obj->wnd); bhbhbhbhbh); bhpixel); bh->biHeight=-CANVAS_BLOCK_HEIGHT; bhbhpixelbhobjobjobj  gdi_object gdi_object *)g->object; ReleaseDCgg
    test.c
      #define WIDTH 640 #define HEIGHT 480   struct gdi g_gdi; struct canvas *g_canvas;   HINSTANCE hInst; // current instance   ATOM MyRegisterClassBOOL InitInstanceLRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);   i; MSG msg; struct box b; hInst MyRegisterClass  InitInstance FALSE; } b.b.b.b.b.b.dirty=DIRTY;   // Main message loop: iPeekMessagePM_NOREMOVEGetMessageTranslateMessageDispatchMessageb.dirty=DIRTY; box_draw(g_canvas,&b,i,i); canvas_updatei; Sleep    gdi_releasecanvas_release(g_canvas);     ATOM MyRegisterClassWNDCLASS wc;   wc.style= CS_HREDRAW|CS_VREDRAW; wc.WNDPROC)WndProc; wc.wc.wc.hInstance= hInst; wc.hIcon= NULL; wc.wc.hbrBackground= NULL; wc.lpszMenuName= NULL; wc.    BOOL InitInstanceHWND hWnd; DWORD style=WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_MAXIMIZEBOX; RECT rectWIDTH,HEIGHT}; AdjustWindowRect  hWndstylerect.rect.hInst    hWndFALSE; }   gdi_createg_canvasg_gdi.g_gdi.  ShowWindow(hWnd, SW_SHOWDEFAULT); UpdateWindow(hWnd);   return TRUE; }   LRESULT CALLBACK WndProcmessageWM_PAINT: canvas_redrawWM_DESTROY: PostQuitMessageDefWindowProc

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • HTML5 Canvas雨滴下落动画DEMO演示2

      HTML5 Canvas雨滴下落动画DEMO演示2

      2017-02-24 13:03

    • Android中圆角矩形和圆形的多种实现方式

      Android中圆角矩形和圆形的多种实现方式

      2017-02-24 12:03

    • Canvas系列教程二:矩形和线条的绘制

      Canvas系列教程二:矩形和线条的绘制

      2017-01-26 14:00

    • 雷达图demo啦!各位水友支持一下啦。。。

      雷达图demo啦!各位水友支持一下啦。。。

      2017-01-04 17:00

    网友点评