C_Sharp 板


LINE

又研究出一些心得分享 https://dl.dropboxusercontent.com/u/61164954/project/RenderingTest/index.html C#一般开发模式风格并不像是C++开发视窗程式需要动到很多底层的WIN32 API, 或是太过於复杂跟系统有关的观念,但发展到一个需求,如果一些怪怪的需求多了, C#一定会有无法胜任的地方,不然就是靠wrapper.不然就是靠pinvoke, 去存取C/CC++ dll或是win32 api. 特别提到一块是高速rendering需求,C#用的GDI+是无法胜任的... 尤其在画面开始慢慢变得大张後. 这时候很多人也许就开始会想借重opengl或是directx去处理, 但还有一个东西叫GDI,这东西一定得靠WIN32 API去做,用pinvoke, 如果你的需求是2d影像,快速播放,而不像是开发游戏还需要用到一些功能特性, 後来我觉得gdi比opengl或是directx好用,只是看你的用法. 不过像这种native api的使用其实跟c#没有真正的直接关系就是, 反来会是mfc之类的开发比较需要. 这边说到gdi(不是c#原来用的gdi+),一般c#用gdi,首先就是一个BitMap物件, 建立Graphics , 建立GDI物件, 到最後显示 public static void DrawImage(ref Graphics grDest, ref Bitmap grSrcBitmap) { grSrc = Graphics.FromImage(grSrcBitmap); hdcDest = grDest.GetHdc(); hdcSrc = grSrc.GetHdc(); hBitmap = grSrcBitmap.GetHbitmap(); hOldObject = SelectObject(hdcSrc, hBitmap); BitBlt(hdcDest, 0, 0, grSrcBitmap.Width, grSrcBitmap.Height, hdcSrc, 0, 0, 0x00CC0020U); if (hOldObject != IntPtr.Zero) SelectObject(hdcSrc, hOldObject); if (hBitmap != IntPtr.Zero) DeleteObject(hBitmap); if (hdcDest != IntPtr.Zero) grDest.ReleaseHdc(hdcDest); if (hdcSrc != IntPtr.Zero) grSrc.ReleaseHdc(hdcSrc); } 这中间有好几步骤虚要新的记忆体,产生物件,到释放..... 步骤多又慢 (但即使如此还是比gdi+强...) 一直觉得这种复制建立的过程不太合理....BitMap也慢... 所以就直接把 bitmap 资料写入到 BitMap的记忆体中, 少了好几个步骤 public unsafe static void DrawImageHighSpeed() { SetDIBits(hdcDest, hBitmap, 0, (uint)h, data_ptr, ref info, DIB_RGB_COLORS); BitBlt(hdcDest, 0, 0, w , h , hdcSrc, 0, 0, 0x00CC0020U); } 但要用这方式虚要先做一个初始化,当确定不再坐rendering工作後, 也得自己释放一下记忆体(c#管不到它自己以外的部分...) public unsafe static void initHighSpeed(ref Graphics _grDest, int width, int height, uint[] data) { w = width; h = height; _Bitmap = new Bitmap(width, height); grSrc = Graphics.FromImage(_Bitmap); grDest = _grDest; hdcDest = grDest.GetHdc(); hdcSrc = grSrc.GetHdc(); hBitmap = _Bitmap.GetHbitmap(); hOldObject = SelectObject(hdcSrc, hBitmap); info = new BITMAPINFO(); info.bmiHeader = new BITMAPINFOHEADER(); info.bmiHeader.biSize = (uint)Marshal.SizeOf(info.bmiHeader); info.bmiHeader.biWidth = w; info.bmiHeader.biHeight = h; info.bmiHeader.biPlanes = 1; info.bmiHeader.biBitCount = 32; info.bmiHeader.biCompression = BitmapCompressionMode.BI_RGB; info.bmiHeader.biSizeImage = (uint)(w * h * 4); fixed (uint* dptr = data) { data_ptr = (IntPtr)dptr;} } public unsafe static void freeHighSpeed() { if (hOldObject != IntPtr.Zero) SelectObject(hdcSrc, hOldObject); if (hBitmap != IntPtr.Zero) DeleteObject(hBitmap); if (hdcDest != IntPtr.Zero) grDest.ReleaseHdc(hdcDest); if (hdcSrc != IntPtr.Zero) grSrc.ReleaseHdc(hdcSrc); try { _Bitmap.Dispose(); } catch { } } 最後再进化一次.... 有没有办法直接把自己的data array写入到图型装置记忆体? 有的...而且是最快的方式 public unsafe static void DrawImageHighSpeedtoDevice() { SetDIBitsToDevice(hdcDest, 0, 0, (uint)w, (uint)h, 0, 0, 0, (uint)h, data_ptr, ref info, DIB_RGB_COLORS); } 一个步骤不拖泥带水...(不过这种方式开始得做一点初始化工作,但只有第一次需要 要更新画面读写一下自己的data arry call SetDIBitsToDevice 重刷一下就好.... 这rendering的模式破1000fps以上....(data array已经准备号,单纯刷画面的速度) 800*600画面下可以刷的速度 100内 GDI+ 200~300fps 从c#BitMap物件 900~1000fps data array刷到bitmap记忆体中然後rendering 1500~1600fps 直接把data array刷到装置记忆体 1024*768状况下 gdi+剩下 40多fps ... 直接把data array刷到装置记忆体可达到近900fps 最慢的从c#BitMap物件 有150fps左右 data array刷到bitmap记忆体中然後rendering 550fps左右 如果你的需要只是一次又一次产生简单的2d影像画面刷上去, 没牵涉到像是sprite的控制游戏需求,这就够好用了.... 重点是省包directx相关wrapper,精简扼要... (directx使用非常麻烦...而且如果单这种状况来说directx占不到便宜) --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 60.248.56.181
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_Sharp/M.1445504557.A.837.html ※ 编辑: erspicu (60.248.56.181), 10/22/2015 17:13:41
1F:推 stu87616: 推 10/23 12:51
2F:推 Litfal: 有种回到VB6时代的感觉ww 10/23 12:51
3F:→ Litfal: 主要还是简单影像GDI+足矣,复杂影像:需要绘制多个物件/ 10/23 12:54
4F:推 Litfal: 坐标系转换/遮罩(这个我记得GDI有)/一些resize算法(虽然 10/23 12:58
5F:→ Litfal: GDI+也不强)回去用GDI重新写过,应该会搞死人XD 10/23 12:58
6F:推 zel: 推 10/23 21:29
7F:推 dreamnook: 推 10/24 10:44
8F:推 name2name2: 推 10/25 21:07
9F:推 Harper34: 现在还有其他选择WPF 10/25 21:59
10F:推 KanoLoa: 大推 10/25 22:53
11F:推 frank6780: 推 10/29 03:09
12F:推 sunneo: great 10/13 13:23







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:BabyMother站内搜寻

TOP