如何扭曲桌面屏幕

我想改变桌面屏幕的形状,所以桌面上显示的内容会同时失真。 用户仍然可以在失真的桌面上用鼠标操作电脑(运行应用程序,打开“我的电脑”等)。 我想我必须先得到屏幕坐标的投影matrix。 然后转换matrix,并将桌面缓冲图像映射到扭曲的网格。 是否有任何可以修改OpenGL或DirectX桌面屏幕的界面? 请给我一些小费。 非常感谢你提前。

请参考http://img.zgserver.com/windows/404.gif的图片

BR,海​​丰

Addition1:

对不起! 也许我没有明确expression我想要实现的东西。 我想要实现的是修改屏幕的形状。 所以我们可以同时扭曲在Windows上运行的所有应用程序的形状。 例如,“我的电脑”窗口会随着桌面屏幕的扭曲而变形。 而且我们仍然可以使用鼠标从扭曲的桌面上操作PC(点击快捷方式运行一个程序)。

加2:投影matrix只是我的假设。 没有任何桌面投影matrix将桌面投影到屏幕上。 我想要实现的是改变桌面的形状,就像将桌面映射到3D网格一样。 但用户仍然可以在扭曲的桌面上操作操作系统(点击快捷方式运行程序,打开即可上网)。

另外3:操作系统上运行的所有程序的形状都随着屏幕的变形而改变。 这是实时的。 用户仍然可以像往常一样在失真的屏幕上操作操作系统。

也许我们可以拦截或者重写GPU本身来实现这个效果。

我正在调查GDI,我想我可以find一些线索。 第一步是find如何在屏幕上显示桌面。

由于使用Aero的Window Seven使用Direct3D API呈现桌面,因此可能会钩住dwm.exe进程(通过使用弯路?)并更改桌面表面投影到屏幕的方式。 据我所知,没有DWM API可以用来做到这一点。

OK,首先,你发布的链接使用了一些复杂的形状,而不是一个简单的四边形,所以一个投影矩阵来获得这种效果是不够的。 您需要将当前桌面图像作为纹理,并将该纹理映射到网格上。 请注意,你仍然可以用一个简单的四元组来做到这一点,但它会给出一个更简单的效果(我仍然建议你先试试这个来调试你的设置)。

如何捕获桌面内容:

基本上有两种方法(API)来做到这一点。 第一个是老派,只会给你一个快照(很难更新它,所以你仍然使用你的桌面,即使效果开始)。 第二个会给你更多的交互支持,但在Windows XP上不起作用。

  1. 使用Windows GDI函数(可能使用GDI +或.NET)来捕获桌面内容并使用BitBlt()将其保存到DIB位图 – 这就是桌面上的“打印屏幕”按钮,只有它图像到剪贴板。 然后,将其映射到OpenGL / DirectX纹理,然后继续处理。
  2. 使用新的Windows DWM缩略图功能代理桌面。 有一些关于如何使用这个合成效果的文档 。

如何使用桌面内容:

这涉及到几个步骤,并且代码将根据您选择的DirectX或OpenGL而有所不同。

  1. 创建一个支持3D渲染的全屏窗口(例如为该窗口设置OpenGL或DirectX,或者使用一个或两个内置支持的框架)。
  2. 捕获桌面内容(方法1:在启动时一次,方法2:在事件循环中重复)
  3. 将桌面内容从位图转移到纹理。
  4. 创建曲面(四边形或网格)并映射纹理。
  5. 更新你的窗口。

更多细节:

实施这个需要良好的知识:

  1. 使用DirectX或OpenGL的3D动画
  2. Windows中的高级UI编程

您可能没有掌握所有这些知识,所以我建议您花一些时间研究所需的API,并计划应用程序中的数据流。

另外,这个帖子是故意模糊的。 当您需要更多关于使用特定API所涉及的不同步骤的详细信息时,请随时就其他更专注的问题提出疑问。

我不知道在Windows中如何做到这一点,但是如果在X11上使用AIGLX合成,创建这些效果相当简单。 这样一个排序的例子是Compiz 。 所以看看那个可能是值得的。

我知道你想在Windows上完成,但是也可以通过已经运行的系统来熟悉这些必要的任务,这可能是一个好主意。

这里的问题9.100和9.110如下

9.100如何找到给定对象空间坐标的屏幕坐标?

如果您只需要为几个顶点找到它,则可以使用GLU库gluProject()实用程序。 对于大量的坐标,使用反馈机制会更有效率。

要使用gluProject() ,您需要提供gluProject()矩阵,投影矩阵,视口和输入对象空间坐标。 屏幕空间坐标返回X,Y和Z,Z被归一化(0 <= Z <= 1)。

9.110如何找到屏幕像素的对象空间坐标?

GLU库gluUnProject()提供了gluUnProject()函数。

您需要读取深度缓冲区,以获取感兴趣的X,Y位置处的输入屏幕坐标Z值。 这可以编码如下:

 GLdouble z; glReadPixels (x, y, 1, 1, GL_DEPTH_COMPONENT, GL_DOUBLE, &z); 

请注意,x和y是以(0,0)左下角为中心的以OpenGL为中心的。

您将需要提供屏幕空间X,Y和Z值作为输入到gluUnProject()的输入到模型视图矩阵,投影矩阵和视口,这些视图在呈现特定像素时是当前的。


这个OpenGl教程说明了如何使用以下方法重置投影矩阵

 glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glLoadIdentity(); // Reset The Projection Matrix // Calculate The Aspect Ratio Of The Window gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glLoadIdentity(); // Reset The Modelview Matrix 

不,您不想“修改桌面投影到屏幕的投影矩阵”。

桌面不投影到屏幕上。 它是2D的,所以它是两个数组之间的一个简单的memcpy()(其中一个恰好在图形卡上)

基本思路是:

  • 你让你的操作系统渲染桌面纹理,而不是一个标准的帧缓冲区。
  • 你清除屏幕
  • 你显示一些三角形,并用“桌面”

这应该可以在Linux上用Compiz来完成,就像datenwolf所说的那样,在Vista上非常困难,用tibur的想法,在XP上几乎是不可能的。

你给的截图是在XP下,但。 我怀疑这实际上是第二个屏幕,甚至第二台电脑。 桌面以标准方式渲染,截取屏幕,并在另一个屏幕上的一个摇摆物体上呈现。