想在CEGUI中做点小特效,发现平移过来的CEGUI DEMO7点击事件都正常,特效死活出不来。检查原因在于CEGUI::RenderEffect需要每帧调用一次,只要在OGRE的帧监听中加入:
附上Demo7特效的个人简化备注:
}
// CEGUI::RenderEffect接口
int getPassCount() const{ return 1;} // 渲染通道个数?谁能告诉我这个是啥?
void performPreRenderFunctions(const int pass){} // 渲染前调用
void performPostRenderFunctions(){} // 渲染后调用
// GUI渲染过程:
// 1 计算RenderWindow信息
// 2 写入GeometryBuffer图像信息(Vecotr[6]的两个三角形,以及纹理什么的)
// 3 GeometryBuffer Draw
// 这一步实际就是在1,2之间时的调用
bool realiseGeometry(CEGUI::RenderingWindow& window, CEGUI::GeometryBuffer& geometry)
{
using namespace CEGUI;
Texture& tex = window.getTextureTarget().getTexture();
static const CEGUI::colour c(1, 1, 1, 1);
// 将一张纹理分解成8 * 8个正方形
// 每个方块长/高
const float qw = window.getSize().d_width / tess_x;
const float qh = window.getSize().d_height / tess_y;
// 每个长/高所包含的纹理长/高(长/高 * 1个像素所对应的纹理长/高)
const float tcx = qw * tex.getTexelScaling().d_x;
const float tcy = (window.getTextureTarget().isRenderingInverted() ? -qh : qh) * tex.getTexelScaling().d_y;
for (int j = 0; j < tess_y; ++j)
{
for (int i = 0; i < tess_x; ++i)
{
// 每次循环生成六个点(两个三角形)
int idx = (j * tess_x + i) * 6;
float top_adj = dragX * ((1.0f / tess_x) * j);
float bot_adj = dragX * ((1.0f / tess_x) * (j+1));
top_adj = ((top_adj*top_adj) / 3) * (dragX < 0 ? -1 : 1);
bot_adj = ((bot_adj*bot_adj) / 3) * (dragX < 0 ? -1 : 1);
float lef_adj = dragY * ((1.0f / tess_y) * i);
float rig_adj = dragY * ((1.0f / tess_y) * (i+1));
lef_adj = ((lef_adj*lef_adj) / 3) * (dragY < 0 ? -1 : 1);
rig_adj = ((rig_adj*rig_adj) / 3) * (dragY < 0 ? -1 : 1);
// vertex 0
vb[idx + 0].position = Vector3(i * qw - top_adj, j * qh - lef_adj, 0.0f);
vb[idx + 0].colour_val = c;
vb[idx + 0].tex_coords = Vector2(i * tcx, j*tcy);
// vertex 1
vb[idx + 1].position = Vector3(i * qw - bot_adj, j * qh + qh - lef_adj, 0.0f);
vb[idx + 1].colour_val = c;
vb[idx + 1].tex_coords = Vector2(i*tcx, j*tcy+tcy);
// vertex 2
vb[idx + 2].position = Vector3(i * qw + qw - bot_adj, j * qh + qh - rig_adj, 0.0f);
vb[idx + 2].colour_val = c;
vb[idx + 2].tex_coords = Vector2(i*tcx+tcx, j*tcy+tcy);
// vertex 3
vb[idx + 3].position = Vector3(i * qw + qw - bot_adj, j * qh + qh - rig_adj, 0.0f);
vb[idx + 3].colour_val = c;
vb[idx + 3].tex_coords = Vector2(i*tcx+tcx, j*tcy+tcy);
// vertex 4
vb[idx + 4].position = Vector3(i * qw + qw - top_adj, j * qh - rig_adj, 0.0f);
vb[idx + 4].colour_val = c;
vb[idx + 4].tex_coords = Vector2(i*tcx+tcx, j*tcy);
// vertex 5
vb[idx + 5].position = Vector3(i * qw - top_adj, j * qh - lef_adj, 0.0f);
vb[idx + 5].colour_val = c;
vb[idx + 5].tex_coords = Vector2(i * tcx, j*tcy);
}
}
geometry.setActiveTexture(&tex);
geometry.appendGeometry(vb, buffsize);
// true:交由CEGUI生成GeometryBuffer
// false:自己生成GeometryBuffer
return false;
}
// 每帧调用
bool update(const float elapsed, CEGUI::RenderingWindow& window)
{
using namespace CEGUI;
// 第一次时记录原始位置
if (!initialised)
{
initialised = true;
lastX = window.getPosition().d_x;
lastY = window.getPosition().d_y;
return true;
}
const Vector2 pos(window.getPosition()); // 当前位置
// 当前位置相当于原位置的偏移
if (pos.d_x != lastX)
{
dragX += (pos.d_x - lastX) * 0.2;
elasX = 0.05f;
lastX = pos.d_x;
if (dragX > 25)
dragX = 25;
else if (dragX < -25)
dragX = -25;
}
if (pos.d_y != lastY)
{
dragY += (pos.d_y - lastY) * 0.2f;
elasY = 0.05f;
lastY = pos.d_y;
if (dragY > 25)
dragY = 25;
else if (dragY < -25)
dragY = -25;
}
// 运算偏移
if ((dragX != 0) || (dragY != 0))
{
if (dragX < 0)
{
dragX += (elasX * 800 * elapsed);
elasX += 0.075 * elapsed;
if (dragX >0)
dragX = 0;
}
else
{
dragX -= (elasX * 800 * elapsed);
elasX += 0.075 * elapsed;
if (dragX < 0)
dragX = 0;
}
if (dragY < 0)
{
dragY += elasY * 800 * elapsed;
elasY += 0.075 * elapsed;
if (dragY >0)
dragY = 0;
}
else
{
dragY -= elasY * 800 * elapsed;
elasY += 0.075 * elapsed;
if (dragY < 0)
dragY = 0;
}
// 重绘,不重绘就白玩了,不过这样搞消耗会不会太大了
System::getSingleton().signalRedraw();
return false;
}
return true;
}
protected:
static const float tess_x;
static const float tess_y;
static const int buffsize = (8 * 8 * 6);
bool initialised;
float lastX, lastY;
float dragX, dragY;
float elasX, elasY;
CEGUI::Vertex vb[buffsize];
};
class Demo7Sample
{
public:
static void setup()
{
using namespace CEGUI;
CEGUI::Window* root = CEGUIManager::Instance().getWindowMain();
// 注册效果
RenderEffectManager::getSingleton().addEffect<MyEffect>("WobblyWindow");
// 创建schemes.
WindowFactoryManager::getSingleton().addFalagardWindowMapping(
"TaharezLook/WobblyFrameWindow", // Type
"CEGUI/FrameWindow", // 基于类型
"TaharezLook/FrameWindow", // 外观
"Falagard/FrameWindow", // 渲染
"WobblyWindow"); // 效果
WindowManager& winMgr = WindowManager::getSingleton();
root->addChildWindow(winMgr.loadWindowLayout("Demo7Windows.layout"));
}
};
//static CEGUI::colour c(1, 1, 1, 1);
//CEGUI::Size d_size = tex.getSize();
//const float tu = d_size.d_width * tex.getTexelScaling().d_x;
//const float tv = d_size.d_height * tex.getTexelScaling().d_y;
//const CEGUI::Rect tex_rect(d_textarget.isRenderingInverted() ? CEGUI::Rect(0, 1, tu, 1 - tv) : CEGUI::Rect(0, 0, tu, tv));
//const CEGUI::Rect area(0, 0, d_size.d_width, d_size.d_height);
//
//CEGUI::Vertex vbuffer[6];
//// vertex 0
//vbuffer[0].position = CEGUI::Vector3(area.d_left, area.d_top, 0.0f);
//vbuffer[0].colour_val = c;
//vbuffer[0].tex_coords = CEGUI::Vector2(tex_rect.d_left, tex_rect.d_top);
//// vertex 1
//vbuffer[1].position = CEGUI::Vector3(area.d_left, area.d_bottom, 0.0f);
//vbuffer[1].colour_val = c;
//vbuffer[1].tex_coords = CEGUI::Vector2(tex_rect.d_left, tex_rect.d_bottom);
//// vertex 2
//vbuffer[2].position = CEGUI::Vector3(area.d_right, area.d_bottom, 0.0f);
//vbuffer[2].colour_val = c;
//vbuffer[2].tex_coords = CEGUI::Vector2(tex_rect.d_right, tex_rect.d_bottom);
//// vertex 3
//vbuffer[3].position = CEGUI::Vector3(area.d_right, area.d_top, 0.0f);
//vbuffer[3].colour_val = c;
//vbuffer[3].tex_coords = CEGUI::Vector2(tex_rect.d_right, tex_rect.d_top);
//// vertex 4
//vbuffer[4].position = CEGUI::Vector3(area.d_left, area.d_top, 0.0f);
//vbuffer[4].colour_val = c;
//vbuffer[4].tex_coords = CEGUI::Vector2(tex_rect.d_left, tex_rect.d_top);
//// vertex 5
//vbuffer[5].position = CEGUI::Vector3(area.d_right, area.d_bottom, 0.0f);
//vbuffer[5].colour_val = c;
//vbuffer[5].tex_coords = CEGUI::Vector2(tex_rect.d_right, tex_rect.d_bottom);
//geometry.setActiveTexture(&tex);
//geometry.appendGeometry(vbuffer, 6);
//return false;
return true;
}