几年前我开始学习Windows编程,而且我一直只使用" native"环境满足我的需求。我的意思是,我只使用Winapi编写代码,而不是DirectX \ Draw \ 2D \ etc用于图形,而不是用于音乐或其他任何外部库,只有Winapi。我上次正在进行图形渲染的下一个演变步骤。以前的算法很好,它们只重绘了应该重绘的部分窗口,它适用于不是全屏窗口。但是当我使用全屏幕时,我的fps非常小。
所以,很久以前,我已经明白,我可以制作一个全新的算法:而不是在WM_PAINT
中绘制,每次重新创建dc&#c; c,位图,我都可以运行一个并行线程,在永恒循环中重绘,dc&c; c和bitmaps只创建一次+我甚至不能使用Gdi或Gdi +函数,如Rectangle
,Graphics::FillRect
,但写我自己更快的功能。所以我做到了。我得到了什么:
62 fps,1920 \ 1080 没有任何图形负载
为什么吗
只是这个代码
void render()
{
COLORREF *matrix;
matrix = re->GetMatrix();
while (1)
{
Sleep(1000 / 120);
re->Render();
//below goes fps counter, that counts in another thread
while (!mu.try_lock())
{
}
frames++;
mu.unlock();
}
}
重新>渲染功能
inline void Card::Render()
{
//SetDIBits(hdcc, bm, 0, bi.bmiHeader.biHeight, matrix, &bi, DIB_RGB_COLORS);
//StretchBlt(hdc, 0, 0, width, height, hdcc, 0, 0, width, height, SRCCOPY);
//method above with Stretch or just BitBlt is awfull at all
SetDIBitsToDevice(hdc, 0, 0, width, height, 0, 0, 0, bi.bmiHeader.biHeight, matrix, &bi, DIB_RGB_COLORS);//hdc is a surface dc, not memory
}
所以,如果我理解得很好,那就是最大的,可以从Gdi中获取。如果我是对的,问题是 - Gdi的意义是什么?计算机游戏是在Direct 2D上开发的,然后是DirectX \ OpenGL,用户界面,在NT 8之前不是窗口更少,和(或)使用DirectDraw。我很困惑,是不是真的要编写好的软件渲染,不要使用任何库,只能自己动手?
答案 0 :(得分:1)
部分问题在于:
Sleep(1000 / 120);
出现8 ms(整数除法后)。但睡眠并不是一种非常精确的计时机制。它会在至少指定的时间内休眠。并且,使用默认时钟滴答速率,在大多数配置中它将至少休眠15.6 ms。帧持续时间为15.6 ms非常接近每秒62帧,因此这可能是根本问题。
除此之外,您将遇到GDI问题,因为图形操作主要在系统内存中执行,然后必须将其传输到图形内存。在更高的分辨率下,可能很难以高帧速率执行此操作,具体取决于所使用的硬件。
答案 1 :(得分:0)
我不确定我理解你的问题,但这是我最好的猜测。
我可以运行并行线程
GDI不是一个好主意。 WinAPI可以进行多线程处理,但使用正确很棘手,请参阅此文章:https://msdn.microsoft.com/en-us/library/ms810439.aspx
62 fps,1920 \ 1080,没有任何图形负载。为什么呢?
GDI不是为您想要的高FPS用例而设计的。它被设计用于在发生变化时重绘东西。它是在现代GPU之前设计的。
在现代硬件上,获得高FPS和/或低延迟渲染的方法是使用以GPU为中心的技术。在C ++中,这是Direct3D和Direct2D。
是不是真的要编写好的软件渲染不使用任何库
当然有可能。只是不是你试图用SetDIBitsToDevice做的方式。
在现代硬件+操作系统上,您的API调用(无论API是什么)将成为发送到3D GPU的命令。这就是为什么像D3D和D2D这样的新的以GPU为中心的API通常可以提供更好的性能。
如果您想要实现一个很好的软件渲染,请记住,您必须将结果上传到GPU纹理。在现代Windows上,WinAPI就是这样做的。
旧版Windows(即Vista之前的任何内容)并不依赖GPU。但游戏也没有使用GDI,他们使用DirectX 9,DirectDraw等......