想在CEGUI中做点小特效,发现平移过来的CEGUI DEMO7点击事件都正常,特效死活出不来。检查原因在于CEGUI::RenderEffect需要每帧调用一次,只要在OGRE的帧监听中加入:
CEGUI::System::getSingleton().injectTimePulse(evt.timeSinceLastFrame);
附上Demo7特效的个人简化备注:
class MyEffect : public CEGUI::RenderEffect { public: MyEffect() : initialised(false), dragX(0), dragY(0), elasX(0), elasY(0) { } // 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")); } };
bool HideEffect::realiseGeometry(CEGUI::RenderingWindow& window, CEGUI::GeometryBuffer& geometry) { // 注释的是return true做的事情 //CEGUI::TextureTarget& d_textarget = window.getTextureTarget(); //CEGUI::Texture& tex = d_textarget.getTexture(); //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; }