如何扭曲桌面屏幕

如何扭曲桌面屏幕

问题描述:

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

请参考图片从http://oi53.tinypic.com/bhewdx.jpg

BR, 海丰

Addition1:

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

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

加3: OS上运行的所有程序的形状都随着屏幕的变形而改变。这是实时的。通常,用户仍然可以在畸变的屏幕上操作操作系统。

也许我们可以拦截或覆盖GPU本身来实现效果。

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

+0

你的意思是,就像你可以在旧CRT屏幕和视频投影仪上找到的设置一样? – Calvin1602 2011-03-01 15:31:47

+0

是的。但我想通过软件设置来控制屏幕的形状。然后,改变屏幕的形状后,操作系统上运行的所有程序的形状将会改变,我们可以在失真的屏幕上控制操作系统。卡尔文,你能给我点小费吗?谢谢!! – HaifengWang 2011-03-02 14:56:49

+0

请注意,这些方法有专利:http://www.faqs.org/patents/app/20090102862 – 2011-03-19 16:25:58

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

+0

谢谢!我读过一些关于DWM和WDDM的资料。我认为Aero API可以渲染具有特殊形状的应用程序窗口,即使在3D坐标中。但我想要做的是修改投影矩阵,桌面表面投射到屏幕上。如果我们实现此功能,“我的电脑”窗口将随着桌面屏幕的扭曲而变形。所以我们可以扭曲在Windows上运行的所有应用程序的形状。我正在研究的一个方向是Windows的低级界面。然后显示驱动程序也应该被调查。 – HaifengWang 2011-03-01 14:28:36

+0

不错的主意,upvoted – Calvin1602 2011-03-01 15:18:48

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

我知道你想在Windows上完成它,但也许已经熟悉这个已经工作的系统的必要任务可能是一个好主意。

+0

谢谢!我看到了Compiz的视频。这个很酷!但这不是我想要实现的。我想要做的是修改桌面表面投影到屏幕的投影矩阵。如果我们实现此功能,“我的电脑”窗口将随着桌面屏幕的扭曲而变形。所以我们可以扭曲在Windows上运行的所有应用程序的形状。 – HaifengWang 2011-03-01 14:41:34

+0

@HaifengWang假设有一个用于渲染桌面的投影矩阵,只有当桌面使用3D API进行合成时才是如此。纯2D桌面不需要任何种类的投影矩阵。 – 2011-03-01 14:47:34

+0

您将截图链接到的效果无法通过简单矩阵完成。这是一个复杂的非线性效应。而且桌面通常不会被投影(好吧,Aero和Compiz确实改变了这一点)。但是你不会找到一些桌面投影矩阵来修改矩阵。 – datenwolf 2011-03-01 14:56:21

问题9.100和9.110以上here如下

9.100怎样才能找到一个给定对象的空间坐标的屏幕坐标?

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

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

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

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

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

GLdouble z; 

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

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

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


OpenGl tutorial说如何使用以下

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 
+0

谢谢!我正在学习NeHe的教程。 – HaifengWang 2011-03-01 15:12:04

+0

您的欢迎。希望能帮助到你。 – Alpine 2011-03-01 15:13:03

不,你不希望“修改通过桌面表面投射到屏幕上的投影矩阵”来重置投影矩阵。

桌面不显示在屏幕上。这是在2D,所以这是两个数组(其中一个恰好是图形卡上)

之间的简单的memcpy()的基本思想是如下:

  • 你得到你的OS呈现桌面上的纹理,而不是标准的帧缓冲区。
  • 清除
  • 你的“桌面”

这应该在Linux上有可能与Compiz的显示一些三角形和纹理它的画面,datenwolf建议,很难在Vista上,与Tibur酒店的想法,在XP上几乎不可能。

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

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

如何捕获桌面内容:

基本上有两种方式(API)来做到这一点。第一个是老派,只会给你一个快照(很难仔细更新它,以便即使在启动效果后仍能使用桌面)。第二个将为您提供更多交互支持,但在Windows XP上不起作用。

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

如何使用桌面内容:

这涉及几个步骤,并且代码将根据您选择的DirectX或OpenGL的有很大的差异。

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

更多细节:

实现这个要求的良好的知识:

  1. 使用的DirectX或OpenGL
  2. 在Windows

你可能

  • 高级UI设计3D动画没有全部的知识来实现​​这一点,因此我建议您花一些时间研究所需的API并计划应用程序中的数据流。

    此外,这篇文章故意含糊不清。如果您需要更多关于使用特定API的不同步骤的详细信息,请随时在SO上提出其他更有针对性的问题!

  • +0

    é。谢谢André给我这么多的信息!我们可以通过您的方法将桌面映射到网格。但我想在扭曲的桌面上操作操作系统。所有的程序也可以在扭曲的桌面上运行。例如,单击运行程序的快捷方式。如果打开“我的电脑”,则“我的电脑”窗口失真。如果播放视频,视频也会在失真的屏幕上播放。 – HaifengWang 2011-03-02 14:25:36