Easyx图形库应用(直接显存操作)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
有过屏幕驱动经验的同学都知道,所谓的屏幕驱动,那就是把内存的数据,一次又一次通过vga、mipi、rgb888、hdmi这样的接口送出去。一秒之内,可以送出去多少次,那就代表了当前帧率是多少。这里面,如果我们希望及时更新图象,一般有两种方法。一种就是系统api操作,一种就是直接显存操作。

1、更新单个像素
在easyx库下面,就有这样的函数putpixel。如果我们希望操作某一个像素的时候,就可以通过putpixel函数来操作具体的像素值。这里,我们可以写一个小的demo程序,
#undef UNICODE
#include <graphics.h>
#include <math.h>
#include <conio.h>int main(int argc, char* argv[])
{int w = 640;int h = 480;DWORD* buf = NULL;initgraph(w, h);BeginBatchDraw();buf = GetImageBuffer(); // get basic address of image bufferdouble t = 0.0;while (!_kbhit()){for (int y = 0; y < h; y++){for (int x = 0; x < w; x++){double dx = x - w / 2.0;double dy = y - h / 2.0;double r = sqrt(dx * dx + dy * dy);double v = sin(r / 10.0 - t) * 0.5 + 0.5;int R = (int)(v * 255);int G = (int)((1 - v) * 255);int B = (int)(128 + 127 * sin(t + r / 20.0));putpixel(x, y, RGB(B, G, R));}}FlushBatchDraw();Sleep(20);t += 0.2;}EndBatchDraw();closegraph();return 0;
}2、效果分析
但是等程序写好后,我们却发现程序运行起来的时候,非常卡顿。经过分析,终于找到了原因。原因就是这里的putpixel。分析发现,如果是调用putpixel函数,那么相当于每次都需要经过system call,最终调用os api才能刷新像素值。这样做,虽然比较简单,但是非常浪费时间。
3、直接操作缓存
和putpixel相比较,另外一种更高效的办法,就是操作缓存。所谓的操作缓存,就是直接修改内存里面的数值。这个内存,就是下一次系统要swap过来,刷新的内存。修改以后呢,并不着急调用系统api,刷新界面,而是等所有的数据都ok之后,再一起刷新界面。这样刷新的效率,无疑会高很多。
#undef UNICODE
#include <graphics.h>
#include <math.h>
#include <conio.h>int main(int argc, char* argv[])
{int w = 640;int h = 480;DWORD* buf = NULL;initgraph(w, h);BeginBatchDraw();buf = GetImageBuffer(); // get basic address of image bufferdouble t = 0.0;while (!_kbhit()){for (int y = 0; y < h; y++){for (int x = 0; x < w; x++){double dx = x - w / 2.0;double dy = y - h / 2.0;double r = sqrt(dx * dx + dy * dy);double v = sin(r / 10.0 - t) * 0.5 + 0.5;int R = (int)(v * 255);int G = (int)((1 - v) * 255);int B = (int)(128 + 127 * sin(t + r / 20.0));buf[y * w + x] = RGB(R, G, B);}}FlushBatchDraw();Sleep(20);t += 0.2;}EndBatchDraw();closegraph();return 0;
}所以,这里通过GetImageBuffer获取显存首地址,直接操作像素的方法,其实是非常重要的一个措施。大家可以好好练习一下。
