好吧,我想知道..也许其他人也是。
是否可以通过编程,尤其是 C 或 C++ 分别控制屏幕上的每个像素?
您需要对当前屏幕的驱动程序进行特殊控制吗?是否有允许您更改像素的操作系统(例如在所有内容之上绘制消息/覆盖)?
或者Windows是否支持它的WinApi?
编辑:
我问这个问题是因为我想让我的电脑在我玩游戏并且我的处理器变得太热时警告我。我主要使用 Windows,但我有一个双启动 ubuntu 发行版。
你走得越低,你遇到的麻烦就越多。
如果您想要原始像素操作,您可以查看http://www.libsdl.org/,它可以帮助您减轻创建表面/窗口等的麻烦。
如果您愿意,Linux 有一些方法可以让您变得更低(即没有“windows”或“xwindows”或任何类似的东西,只是原始屏幕),如果您对此感兴趣,请查看 Linux 帧缓冲区。
深入研究(例如使用您自己的操作系统),BIOS 将让您进入某些视频模式,这是操作系统安装程序倾向于使用的(至少他们曾经使用过,一些更高级的不再使用了) . 这不是最快的做事方式,但可以让您进入在一些汇编指令中显示像素的领域。
当然,如果你想做自己的操作系统并利用显卡(绕过 BIOS),那么你就是在谈论编写视频驱动程序之类的东西,这显然是大量的工作:)
在屏幕上重新覆盖消息之类的东西,windows 确实支持这种东西,所以我相信你可以使用 WinAPI 来做到这一点,尽管可能有一些库可以让这更容易。我知道你不需要深入研究来做那种事情。
让我们一次看一下每一位:
是否可以通过编程,尤其是 C 或 C++ 分别控制屏幕上的每个像素?
可能。这真的取决于图形架构,在许多现代系统中,实际的屏幕表面(即“出现在屏幕上的一堆像素”)并不直接受软件控制 - 至少不是来自“用户模式”(即,来自您或我可以编写的应用程序 - 您需要编写驱动程序代码,并且您需要与现有的图形驱动程序充分合作)。
人们普遍认为,将数据绘制到屏幕外缓冲区并使用 BitBlt [BitBlockTransfer] 函数将内容复制到屏幕上是执行此类操作的首选方式。
所以,在现实中,你可能无法操纵屏幕上的每个像素——但你可能会表现得像你一样。
您需要对当前屏幕的驱动程序进行特殊控制吗?
假设您可以直接访问屏幕内存,您的代码肯定必须与驱动程序合作 - 否则,谁能说您想要出现在屏幕上的内容不会被其他内容覆盖[例如,您想要完整屏幕访问,并且时钟更新器每分钟根据您绘制的内容更新屏幕上的时间,等等]。
您也许可以将驱动程序设置为具有“孔”的模式,该“孔”允许您将屏幕内存作为大的“帧缓冲区”访问。我认为在 Windows 中没有简单的方法可以做到这一点。我不记得在 2003-2005 年我以编写图形驱动程序为生时。
是否有允许您更改像素的操作系统(例如在所有内容之上绘制消息/覆盖)?
在现代显卡的硬件中创建覆盖层是绝对可能的。这通常是视频播放的工作方式 - 视频被播放到一块覆盖在其他图形之上的帧缓冲区内存中。您需要驱动程序的帮助,据我所知,这绝对可以在 Windows API 中通过 DirectX 获得。
或者Windows是否支持它的WinApi?
可能,但要准确回答,我们需要更好地了解您想要做什么。
编辑:在您的特定用例中,我会认为发出声音或弹出 CD/DVD 驱动器可能是更合适的选项。在游戏绘制的图形上叠加某些东西可能很困难,因为游戏通常会尝试尽可能多地使用可用的图形资源,而且您可能很难找到一种即使在大多数情况下都有效的方法简单的用例——不要介意那些适用于使用不同绘图/引擎/图形库的多种不同类别游戏的东西。我也不完全确定有什么可过分担心的,因为现代 CPU 对过热有很好的耐受性,所以 CPU 只会减速,可能会停止,但它不会坏——即使你取下散热器,不会出错[不,我不建议你尝试这个!]
每个平台都支持有效的原始像素块传输“又名 BitBlt()”,所以如果你真的想进入帧缓冲区级别,你可以分配一个位图并使用指针直接设置其内容,然后用一行代码有效地翻转这个内存块进入视频内存缓冲区。当然,它不如直接使用 PCI 帧缓冲区高效,但另一方面,这种方法 (BitBlt) 即使在 Win95 天也足够快,可以在不使用 WinG 的情况下将 Wolfenstein 3d 移植到 Pentium CPU 上。
但是,在创建此位图时必须小心,以使其格式(即 RGB 16 位或 32 位等)与设备所处的实际模式相匹配,否则图形子系统将进行冗长的重新编码/抖动这将完全杀死你的速度。
所以根据你的目标,如果你想要一个 3d 游戏,你的表现会很糟糕。如果您只想渲染一些形状并且不需要超过 10-15fps - 这将在不深入任何设备驱动程序级别的情况下工作。
以下是在 Windows 中叠加的一些提示:
hdc = GetDC(0);//returns hdc for the whole screen and is VERY fast
您可以将 HDC 用于屏幕并执行 BItBlt(hdc, ..... SRCCOPY) 以有效地翻转光栅块。还有用于桌面的预定义 Windows 句柄,但我不记得确切的机制,但如果您在多个显示器上,您可以为每个桌面获取 HDC,查看“GetDesktopWindow”、“GetDC”等...