您的位置:首页 > 产品设计 > UI/UE

最简单的Ogre系列之三——添加鼠标(不使用任何GUI)

2011-05-11 00:34 411 查看
本节在上节画矩形框的基础上添加了一个鼠标箭头,以更形象展示鼠标位置。显示鼠标我们可以用CEGUI之类的组件,但对于我的实验程序来说过于庞大,我只需要鼠标来显示点击位置即可。所以我利用OGRE中的Overlay面板和PanelOverlayElement组件来实现鼠标效果。下面简单介绍一下Overlay。

基本概念

Overlay是那些将在主场景被渲染之后才渲染的可视组件(2D和3D)的容器。这些可视组件将构成HUD(Heads-Up-Display)、菜单或其它在主场景内容之上的任何东西。Overlay将被渲染在“普通”场景内容之上的层。一个Overlay总是占满整个Viewport,即使它包含的组件并没有那么大。Overlay只是可视组件的容器,本身并不代表任何可视组件。Overlay可以通过调用OverlayManager::Create函数来创建,或者将其定义在特定的脚本文件(.overlay文件)。你可以定义无限多的Overlay;Overlay被创建后是隐藏的,即你必须调用“show”函数才能看到它。这样你可以预先定义很多Overlay(如菜单),仅在需要它们的时候才将它们显示出来。在同一时刻可以存在和显示多个Overlay,Overlay的“zorder”参数决定了谁在上谁在下。缺省情况下,Overlay会被渲染到全部的Viewport。当你只有一个全屏Overlay的时候这非常好用,但当你在程序中用几个Viewport构成“画中画”的时候,你可能就不想让它显示在小画面中了。你可以通过调用Viewport::setDisplayOverlays方法将某些Viewport的Overlay关闭。

PanelOverlayElement表示一个平面,单一材质(或透明)的面板,它可以包含其他元素。与其他类一样,如果它隐藏,它包含的内容也跟着隐藏,如果移动了它包含的内容也跟着移动等等。这个面板本身是一个2D矩形,它要么完全透明,要么用单一材质渲染。面板上的纹理可以根据你的需要平铺(tile)。这个组件适合作为背景及将其他元素分组。注意,因为它只有单一重复的材质,它的边界不能是离散的(除非纹理只有一个且只铺了一次)。

动手实践

因为我们使用了材质,故需要修改resources_d.cfg,在其后添加FileSystem=../../media,将其指向我们放材质和纹理的文件夹。../表示上级目录。新建一个txt文件,将其命名为Cursor,并将其后缀名改为material,即Cursor.material。添加如下代码:

material Cursor/default
{
technique
{
pass
{
scene_blend alpha_blend
texture_unit
{
texture cursor.png
tex_address_mode clamp
}
}
}
}


其中cursor.png即为我们所需要的鼠标纹理文件,如下所示:



在程序中,我们需要定义Overlay容器和PanelOverlayElement组件。

//Cursor
Overlay* OverCursor;
PanelOverlayElement* mCursor;


并将其初始化

//create cursor
void createCursor(String name, String material, RenderWindow* win)
{
OverCursor = OverlayManager::getSingleton().create(name);
mCursor = new PanelOverlayElement(name);
mCursor->initialise();
mCursor->setMaterialName(material);
MaterialPtr m = MaterialManager::getSingleton().getByName(material);
m->getTechnique(0)->getPass(0)->setAlphaRejectValue(150);
mCursor->setDimensions(32.0/win->getWidth(), 32.0/win->getHeight());
OverCursor->add2D(mCursor);
OverCursor->show();
mCursor->show();
}


这样做以后鼠标会显示在窗口的左上角,但不会动。我们需要在mouseMoved事件中添加相应的语句,以使鼠标在窗口范围内移动。如下所示:

bool mouseMoved (const OIS::MouseEvent& e)
{
const Real clickX = static_cast <Real> (e.state.X.abs) / mWindow->getWidth();
const Real clickY = static_cast <Real> (e.state.Y.abs) / mWindow->getHeight();
mCursor->setLeft(clickX);
mCursor->setTop (clickY);
return true;
}


这样我们就可以看到活动的鼠标了。完整的代码可以从如下网址下载(我是用VS2008编译的)。



Author : Zhu Xiaoyang (cgnerds@gmail.com)

Creation Date : May 10 2011
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐