D3D游戏关于窗口中如何精确确定鼠标位置的相关讨论

在开发D3D游戏时,如何正确获取窗口内鼠标位置是关键。常见错误是忽略窗口边框和标题栏导致的坐标偏差。通过使用`AdjustWindowRect`函数调整窗口大小,确保客户端区域与后台缓存匹配,可以解决这个问题。调整后,窗口将适应后台缓冲区大小,从而提供准确的鼠标坐标。在创建窗口时应用适当的风格,如`WS_OVERLAPPEDWINDOW`,并结合`CreateWindow`函数,可以确保在窗口和全屏模式下都能正确获取坐标。
部署运行你感兴趣的模型镜像

在GameDev中的相关贴子:

(1)http://www.gamedev.net/topic/623813-getting-mouse-position/

里面有几句很重要的话:

<1>How do you create your application window?
A common mistake is to choose some backbuffer resolution (for example 1024x768), create a backbuffer with this resolution and also create a window with this size - while forgetting, that if window is 1024x768 then its client area is smaller (because of the title bar and borders) and DirectX rendering will be stretched. 

<2>//一般我们取得坐标后,就可以横坐标加8/2,纵坐标加28/2即可获取真实的坐标,不过不同创建窗口的风格会导致不同的差异,所以请依据真实情况调整即可

 it's 8 pixels for borders and 28 pixels for the title bar (on my Vista, this depends on your OS and your settings, you can change the title bar size somewhere). 

(2)关于DInput取不了屏幕坐标的思考,及Windows Proc取坐标有问题的解决方案

http://www.gamedev.net/topic/423799-direct-input-mouse-position-wrong--fixed-/

<1>有一句话契合上面

Looks to me like you haven't used AdjustWindowRect() to get a 1:1 mapping of client area to backbuffer space. Your backbuffer may be 640x400 or something, but your entire window is also 640x400, meaning that the client area is around 632x380 or something. That means that a point on your client area won't map to the same place on the backbuffer.
AdjustWindowRect() will give you the dimensions to pass to CreateWindow[Ex]() if you give it the size of client area you want. 

 

小计:

     在我们获取鼠标的位置时,假如没有处理好创建窗口的步骤,很有可能取的是错误的坐标,像在龙书中就没有指出这种情况,以至于在Pick一节中鼠标及射线不是很准确,甚至可以说简直就是偏差的,那么如何来实现获取准确的鼠标坐标的位置呢,首先建立窗口之前就应该调用一个函数AdjustWindowRect,这个函数可以调整窗口的大小,为什么要调大小,在上面的两个帖子中讲的很明白,因为窗口含有标题栏及左右上下边框,使得我们的窗口小于我们创建的后台缓存,这就会出现很大的问题,主要是鼠标往右下角走时,鼠标的位置会越来越不精确,正是由于前台和后台的大小的区别(前台比后台小),造成这么大的麻烦。而AdjustWindowRect这个函数可以在创建窗口前调整窗口大小,使现在的客户区和后台缓存一样大,所以我们的整个窗口变大了点。这样处理之后就可以正确获取坐标了,样例代码如下:

RECT rc;
  SetRect( &rc, 0, 0, WIDTH, HEIGHT );
  AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, false );//注意这里好像只能用WS_OVERLAPPEDWINDOW,我测试了几个其它的好象不行,下面的创建风格也要是WS_OVERLAPPEDWINDOW
//   char szBuf[128];
//   sprintf(szBuf,"(%d,%d),(%d,%d)",rc.left,rc.right,rc.top,rc.bottom);//这里查看调整后的窗口大小
//   MessageBox(NULL,szBuf,"",MB_OK);

  hwnd=::CreateWindow(WNDCLASSNAME,WNDCAPTION,WS_OVERLAPPEDWINDOW,0,0,( rc.right - rc.left ),rc.bottom - rc.top,0,0,hInstance,0);

 

当然,一定还有其他方案解决此类问题,因为这里对窗口风格有点限定(也有可能我不会搭配风格使得有问题),不过在Dx SDK中是基于此来解决此问题的,这个方案可以使在窗口和全屏下都可以正确获取坐标位置。还有一个就是在《DirectX+游戏开发终极指南》中GUI开发部分中,它的Demo在窗口模式下可以正常使用,但在全屏时却不行,那里面很可能是在初始化d3dpp时有问题,所以那个也不是最终的解决方案。

您可能感兴趣的与本文相关的镜像

ComfyUI

ComfyUI

AI应用
ComfyUI

ComfyUI是一款易于上手的工作流设计工具,具有以下特点:基于工作流节点设计,可视化工作流搭建,快速切换工作流,对显存占用小,速度快,支持多种插件,如ADetailer、Controlnet和AnimateDIFF等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值