Linked Windows with Ogre

For help with general CEGUI usage:
- Questions about the usage of CEGUI and its features, if not explained in the documentation.
- Problems with the CMAKE configuration or problems occuring during the build process/compilation.
- Errors or unexpected behaviour.

Moderators: CEGUI MVP, CEGUI Team

User avatar
Nickenstein79
Quite a regular
Quite a regular
Posts: 93
Joined: Thu May 09, 2013 06:19

Linked Windows with Ogre

Postby Nickenstein79 » Mon Jun 10, 2013 07:16

One of the things that made me finally decide to make the switch to CEGUI (in favour of my home-rolled solution) was the very cool LinkedWindows video on the main page.

The demo code for that relies on GL/GLut so I did a slight rework of it to use in my Ogre-based game (so it would work the same on a GL or DX setup.)

I ended up with this, which works fine when you run your Ogre-Game with DX or GL.

Hopefully this will be helpful to someone out there. :)


(NOTE: This requires that you add the DynamicLines class to your ogre project.)



Ogre-Modded version of LinkGeometryBuffer.cpp: -

Code: Select all

#include "LinkGeometryBuffer.h"
#include "LinkedWindow.h"
 
using namespace CEGUI;
 
//----------------------------------------------------------------------------//
LinkGeometryBuffer::LinkGeometryBuffer(LinkedWindow* owner) :
    d_owner(owner),
   LineStart(0),
   LineEnd(0),
   linesNode(0),
   lines(0)
{
   // create Ogre::DynamicLine stuff
   lines = new DynamicLines(Ogre::RenderOperation::OT_LINE_LIST);
   LineStart = new Ogre::Vector3(0,0,0);
   LineEnd = new Ogre::Vector3(0,0,0);
   lines->addPoint(*LineStart);
   lines->addPoint(*LineEnd);
   lines->update();
   sprintf(LineNodeName, "%s_LINE_NODE", owner->getName().c_str());
   linesNode = pGlobalSceneMgr->getRootSceneNode()->createChildSceneNode(LineNodeName);
   linesNode->attachObject(lines);
}
 
//----------------------------------------------------------------------------//
void LinkGeometryBuffer::draw() const
{
    if (!d_owner->getTarget())
        return;

   if (!pGlobalCameraMan)
      return;
 
    const Rect src_area(d_owner->getUnclippedOuterRect());
    const Rect dst_area(d_owner->getTarget()->getUnclippedOuterRect());
 
    const Vector2 source(
        src_area.d_right,
        src_area.d_top + ((src_area.d_bottom - src_area.d_top) / 2));
 
    const Vector2 dest(
        dst_area.d_left,
        dst_area.d_top + ((dst_area.d_bottom - dst_area.d_top) / 2));

   // Ogre::DynamicLines class requires world-space coords, so de-project the screen-space values through camera plane...
   // (I know; It's slightly wastefull as they will be projected back to screen space by the Ogre::DynamicLines render, but this is to get things working in Ogre quickly.)

   // line start
   Ogre::Ray CameraRay = pGlobalCameraMan->getCamera()->getCameraToViewportRay(source.d_x/(double)pGlobalCameraMan->getCamera()->getViewport()->getActualWidth(), source.d_y/(double)pGlobalCameraMan->getCamera()->getViewport()->getActualHeight());
   Ogre::Vector3 RayDirection = CameraRay.getDirection();
   RayDirection.normalise();
   RayDirection*=0.01f; // push the points just beyond the near-clip plane
   LineStart->x = CameraRay.getOrigin().x + RayDirection.x;
   LineStart->y = CameraRay.getOrigin().y + RayDirection.y;
   LineStart->z = CameraRay.getOrigin().z + RayDirection.z;

   // line end
   CameraRay = pGlobalCameraMan->getCamera()->getCameraToViewportRay(dest.d_x/(double)pGlobalCameraMan->getCamera()->getViewport()->getActualWidth(), dest.d_y/(double)pGlobalCameraMan->getCamera()->getViewport()->getActualHeight());
   RayDirection = CameraRay.getDirection();
   RayDirection.normalise();
   RayDirection*=0.01f; // push the points just beyond the near-clip plane
   LineEnd->x = CameraRay.getOrigin().x + RayDirection.x;
   LineEnd->y = CameraRay.getOrigin().y + RayDirection.y;
   LineEnd->z = CameraRay.getOrigin().z + RayDirection.z;

   // set line points
   lines->setPoint(0, *LineStart);
   lines->setPoint(1, *LineEnd);
   lines->update();
   linesNode->needUpdate();

   // draw hierarchy arrow
}
 
//----------------------------------------------------------------------------//




Ogre-Modded version of LinkGeometryBuffer.h: -

Code: Select all

#ifndef _LINK_GEOMETRY_BUFFER_H
#define _LINK_GEOMETRY_BUFFER_H
 
#include <CEGUIGeometryBuffer.h>
 
class LinkedWindow;
 
 
/*!
/brief
    Custom GeometryBuffer used for drawing links from a LinkedWindow to its
    target window.
 
\note
    The only part of the regular GeometryBuffer interface we will implement is
    the GeometryBuffer::draw function, the rest is stubbed out.  Note also that
    we don't actually 'buffer' anything here, but do direct drawing within the
    draw function.
*/
class LinkGeometryBuffer : public CEGUI::GeometryBuffer
{
public:
    LinkGeometryBuffer(LinkedWindow* owner);
 
    // required interface functions for base class.
    void draw() const;
    void setTranslation(const CEGUI::Vector3& v) {}
    void setRotation(const CEGUI::Vector3& r) {}
    void setPivot(const CEGUI::Vector3& p) {}
    void setClippingRegion(const CEGUI::Rect& region) {}
    void appendVertex(const CEGUI::Vertex& vertex) {}
    void appendGeometry(const CEGUI::Vertex* const vbuff, CEGUI::uint vertex_count) {}
    void setActiveTexture(CEGUI::Texture* texture) {}
    void reset() {}
    CEGUI::Texture* getActiveTexture() const {return 0;}
    CEGUI::uint getVertexCount() const {return 0;}
    CEGUI::uint getBatchCount() const {return 0;}
    void setRenderEffect(CEGUI::RenderEffect* effect) {}
    CEGUI::RenderEffect* getRenderEffect() {return 0;}

   // line render
   Ogre::SceneNode *linesNode;
   DynamicLines *lines;
   Ogre::Vector3 *LineStart;
   Ogre::Vector3 *LineEnd;
   char LineNodeName[256];

protected:
 
    //! LinkedWindow that created and owns the GeometryBuffer.
    LinkedWindow* d_owner;


};
 
#endif



Cheers,
Nick

Return to “Help”

Who is online

Users browsing this forum: No registered users and 19 guests