Choosing a GUI framework for a C++ engine

Editor
Mar 21, 2013 at 11:36 PM
I would really appreciate your input as far as choosing a GUI framework for an editor that runs on top of a C++ (unmanaged) engine. In the past I utilized WinForms and WPF for XNA and DirectX9. I'm trying to decide on whether I want to write C++/CLI wrappers for each of my engine classes (a big pain in the ass, but is this the norm in the industry?) or utilize a full-fledge C++ GUI framework (wxWidgets, Qt, ect..). It's hard to find guidance online as far as what the pros use. It makes since to use C#/WinForms/WPF as the GUI front-end for RAD, but WPF doesn't play well with DirectX 10/11.
Coordinator
Mar 22, 2013 at 2:07 AM
That is actually a really tough call. I don't work in the games industry (I'm in the automotive industry...) so my advice may be slanted somewhat from your target audience. I have thought about this quite a bit, and even started to prototype a couple of systems in Hieroglyph to see what would work out the best. In the end, I think it just depends on what you want to be able to do, and which platform will be hosting your tools.

For example, if you are working with multi-platform (which I know you are from your previous discussions) then it can be beneficial to use something that runs inside of your engine. If you don't need too complicated of a GUI setup, this can be a nice option. There are a few fairly easy to use systems out there (such as GWEN UI, or possibly CEGUI), so you don't need to start from scratch either. One nice benefit is that changes can be applied in realtime, and your editor is your application - so hot loading of assets or scripts becomes much easier. But this of course has its down sides too, in that if something goes wrong in your engine, then your tool is down too. Plus it is intrusive to your game and can influence the performance of the scene rendering.

On the native side, I have always tended to use the full C++ GUI frameworks rather than going down the interop road. I never really learned much .net (only trivially when it first came out) so it would have been a steep learning curve for me, and I just didn't have the time to do it. So with the full C++ systems, MFC is dead simple to interface with, but it is completely archaic and difficult to do non-trivial things in. I have had a cursory look into wxWidgets, and it seemed like a multi-platform version of MFC - but that is just my first impression. I have heard very good things about Qt, but haven't tried it for myself either... So if you go down the native route, then I would recommend checking out Qt to see how that treats you.

The issues that you mentioned about WPF are valid, and I wouldn't venture down that path at all. However, if you are planning on Win8 being a development platform, then you can start investigating how XAML and D3D11 native interop works. This allows you to use the XAML UI, and D3D11 either in a panel or as full screen with XAML overlaid. This is the first time that there is true support for D3D in a GUI framework, and it looks great to me.

So my own plans are to investigate XAML+D3D11, and then also to build in some small GUI facilities (in 3D nonetheless!) within the engine. That will allow for the option to use either one when it makes sense - in engine for the easy stuff, and XAML for the hard stuff.

I would be really interested to hear where your research takes you, and what you finally settle on! I hope that helps somewhat...
Editor
Mar 22, 2013 at 8:12 PM
I kept thinking you worked for MS for some reason ;). Yeah, it's been rolling around in my mind for a while too. I come from a .NET world, so my first instinct is to use that for the front-end. My more I think about it though, it seems that might not be the answer.

I checked out GWEN UI and it seems the original dev doesn't support it anymore. CEGUI looks promising though!

Yeah it seems the full C++ GUI framework route is the best bet. You're right, MFC is a bit archaic. I started learning it in the early 2000's and had a hard time trucking through it. Like you said, too much code needed to be written in order to do simple (trivial) things. Thank goodness .NET came out the following year ;). I've heard good and bad things about wxWidgets. More good things about Qt though. It seems to be the goto framework for cross-platform development. Plus, a lot of professional apps have been made with Qt (e.g. Photoshop, Maya, Sype, ect.). I'll definitely let you know what I choose though.

I completely forgot about the new WPF + DirectX 11.1 interop in Win8. That is pretty slick! I might need that if I decide to support WP8 and Win Store Apps in the near future. I would definitely be interested in your findings as you pursue XAML+D3D11.

I will let you know once I've chosen a GUI framework. Your input was great. Thanks a lot Jason :)!
Coordinator
Mar 23, 2013 at 12:57 AM
No problem! I'm looking forward to hear where you land, and I will certainly keep you posted about my XAML+D3D11 progress.
Mar 23, 2013 at 11:57 PM
Edited Mar 24, 2013 at 4:10 AM
I work with Direct2D. Its an independent renderer that i wrote. It works well. Furthermore i build an api on top of the renderer that is similar to the HTML5 canvas.

I init my renderer and update it inside the update method in the App class. It works over shared surfaces (Because its the only way to support Direct2D with DirectX11 on Windows7 )

I can throw the GUI on Meshes. Thats nice. But primary Ive created a GUIOverlay class that inherits from IRenderView (now its Task class i think)

(But the best solution for an GUI is:
http://www.webkit.org/

If webkit is possible to be implemented it will be the perfect GUI for the future i think. perhaps a little bit over engineered everything but CSS Styles and HTML5 Canvas support included.

Here is my integration of the render loop code of my D2D1Renderer:
void App::Update()
{
    //Update the timer to determine the elapsed time since last frame.  This can then used for animation during the frame.
    m_pTimer->Update();

    //Send an event to everyone that a new frame has started.  This will be used in later examples for using the material system with render views.
    EvtManager.ProcessEvent( EvtFrameStartPtr( new EvtFrameStart( m_pTimer->Elapsed() ) ) );

    _rendererD2D1->Update();

    //Update the scene, and then render all cameras within the scene.
    m_pScene->Update( m_pTimer->Elapsed() );
    m_pScene->Render( m_pRenderer11 );

    //Perform the rendering and presentation for the window.
    m_pRenderer11->Present( m_pWindow->GetHandle(), m_pWindow->GetSwapChain() );
}
//---
Coordinator
Mar 24, 2013 at 12:48 AM
@TypeOverride: Are you using the D2D GUI in Hieroglyph as an overlay? If so, would you mind posting a screenshot or two? I would be really interested to hear more about what you can do with Direct2D as far as the GUI system - as I understand it, it is only for drawing in 2D, and doesn't include a UI system - right?
Mar 24, 2013 at 1:43 AM
Edited Mar 26, 2013 at 12:19 AM
Yes i use it as an overlay (class GUIOverlay : public Task) and yes Direct2D doesnt include a UI system.

Ive build on top of the D2D1 (Direct2D) renderer a HTML5 canvas API implementation. With this API i build a Adobe Flash like API for the Interaction and better controll of creating GUI DisplayObjects. With this i build scrollbar, window, slider, button, etc.

Ive build the gui elements with no gradiant or other good looking things. the gui was for functionality that i needed for the moment.
For nice guis the most peoples uses images. So images are possible too. This shows only the drawing functionality.

There will be much more work for the gui in the future. Like culling or clipping or GUI skins, gui scripting, mark up language for gui build, using flash as gui builder (like Autodesk Scaleform API).

If you have interest i can give you the code per mail or dont know how to send you files.

The gui is very usefull for debugging output. I like to have one very flexible GUI with easy drawing methods. Its easy to convert HTML5 Javascript code for canvas rendering into corresponding C++ code.

Example for an implementation of a simple checkbox gui element (without good design):
CheckBox::CheckBox(int x, int y, int width, int height) : DisplayObject(x, y, width, height) {
    _highlight = false;
    _toggle = false;
}

CheckBox::~CheckBox(void) {
}

//pure virtual method 
bool CheckBox::Draw(Direct2DContext* ctx, D2D1::Matrix3x2F* mtx) {
    ctx->SetFillStyle(0.5f, 0.5f, 0.5f);
    ctx->rect(0, 0, _width, _height);
    ctx->fill();

    ctx->lineWidth = 1;
        
    if(_highlight) {
        ctx->SetStrokeStyle(0.7f, 0.7f, 0.7f);
    } else {
        ctx->SetStrokeStyle(0.3f, 0.3f, 0.3f);
    }

    ctx->stroke();
    
    if(_toggle) {
        ctx->SetStrokeStyle(0.9f, 0.9f, 0.9f);
        ctx->lineWidth = 2;

        float offsetTick = _width*0.2;

        ctx->beginPath();

        ctx->moveTo(offsetTick, _height*0.5);
        ctx->lineTo(offsetTick + (_width - offsetTick*2)*0.5, offsetTick + _height-offsetTick*2);
        ctx->moveTo(offsetTick + (_width - offsetTick*2)*0.5, offsetTick + _height-offsetTick*2);
        ctx->lineTo(offsetTick + (_width - offsetTick*2), 3);

        ctx->stroke();

        ctx->closePath();
    }

    return true;
}

//virtual method 
void CheckBox::OnMouseOver(const MouseEvent &e) {
    _highlight = true;
}

//virtual method 
void CheckBox::OnMouseOut(const MouseEvent &e) {
    _highlight = false;
}

//virtual method 
void CheckBox::OnMouseUp0(const MouseEvent &e) {
    _toggle = !_toggle;
}

}
Mar 24, 2013 at 1:56 AM
Edited Mar 24, 2013 at 3:49 AM
GUIOverlay.h (hieroglyph3-83010)
//--------------------------------------------------------------------------------
// This file is a portion of the Hieroglyph 3 Rendering Engine.  It is distributed
// under the MIT License, available in the root of this distribution and 
// at the following URL:
//
// http://www.opensource.org/licenses/mit-license.php
//
// Copyright (c) Jason Zink 
//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
// ViewTextOverlay
//
// ViewTextOverlay is intended to render text as an overlay of a given scene.
//--------------------------------------------------------------------------------
#ifndef GUIOverlay_h
#define GUIOverlay_h
//--------------------------------------------------------------------------------
#include "Task.h"
#include "SpriteFontLoaderDX11.h"
#include "SpriteRendererDX11.h"

#include "Rendering\D2D1Renderer.h"
//--------------------------------------------------------------------------------
namespace Glyph3
{

    class GUIOverlay : public Task
    {
    public:
        GUIOverlay( RendererDX11& Renderer, D2D1Renderer& RendererD2D1, ResourcePtr RenderTarget );
        virtual ~GUIOverlay();

        virtual void Update( float fTime );
        virtual void QueuePreTasks( RendererDX11* pRenderer );
        virtual void ExecuteTask( PipelineManagerDX11* pPipelineManager, IParameterManager* pParamManager );
        virtual void Resize( UINT width, UINT height );

        virtual void SetRenderParams( IParameterManager* pParamManager );
        virtual void SetUsageParams( IParameterManager* pParamManager );

        virtual std::wstring GetName();

    protected:
        Vector4f                m_vColor;
        int                     m_iViewport;

        ResourcePtr             m_RenderTarget;

        SpriteFontPtr           m_pSpriteFont;
        SpriteRendererDX11*     m_pSpriteRenderer;
        
    private:
        ResourcePtr _direct2DTexture;

    };
};
//--------------------------------------------------------------------------------
#endif // GUIOverlay_h
GUIOverlay.cpp (hieroglyph3-83010)
//--------------------------------------------------------------------------------
// This file is a portion of the Hieroglyph 3 Rendering Engine.  It is distributed
// under the MIT License, available in the root of this distribution and 
// at the following URL:
//
// http://www.opensource.org/licenses/mit-license.php
//
// Copyright (c) Jason Zink 
//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
#include "PCH.h"
#include "GUIOverlay.h"
#include "Entity3D.h"
#include "Node3D.h"
#include "Texture2dConfigDX11.h"
#include "Log.h"
#include "IParameterManager.h"
#include "PipelineManagerDX11.h"
#include "Texture2dDX11.h"
//--------------------------------------------------------------------------------
using namespace Glyph3;
//--------------------------------------------------------------------------------
GUIOverlay::GUIOverlay( RendererDX11& Renderer, D2D1Renderer& RendererD2D1, ResourcePtr RenderTarget )
{
    //m_sParams.iViewType = VT_GUI_SKIN;

    m_RenderTarget = RenderTarget;

    //ViewMatrix.MakeIdentity();
    //ProjMatrix.MakeIdentity();

    //m_pEntity = 0;
    m_vColor.MakeZero();

    ResourceDX11* pResource = Renderer.GetResourceByIndex( m_RenderTarget->m_iResource );

    if ( pResource->GetType() == RT_TEXTURE2D )
    {
        Texture2dDX11* pTexture = (Texture2dDX11*)pResource;
        D3D11_TEXTURE2D_DESC desc = pTexture->GetActualDescription();

        // Create a view port to use on the scene.  This basically selects the 
        // entire floating point area of the render target.
        D3D11_VIEWPORT viewport;
        viewport.Width = static_cast< float >( desc.Width );
        viewport.Height = static_cast< float >( desc.Height );
        viewport.MinDepth = 0.0f;
        viewport.MaxDepth = 1.0f;
        viewport.TopLeftX = 0;
        viewport.TopLeftY = 0;

        m_iViewport = Renderer.CreateViewPort( viewport );
    }

    // Create the text rendering classes.
    _direct2DTexture = Renderer.LoadTexture(RendererD2D1.GetTexture()); //@MODIFICATION HIEROGLYPH3 0001

    m_pSpriteRenderer = new SpriteRendererDX11();
    m_pSpriteRenderer->Initialize();
}
//--------------------------------------------------------------------------------
GUIOverlay::~GUIOverlay()
{
    SAFE_DELETE( m_pSpriteRenderer );
}
//--------------------------------------------------------------------------------
void GUIOverlay::Update( float fTime )
{
}
//--------------------------------------------------------------------------------
void GUIOverlay::QueuePreTasks( RendererDX11* pRenderer )
{
    // Queue this view into the renderer for processing.
    pRenderer->QueueTask( this );
}
//--------------------------------------------------------------------------------
void GUIOverlay::ExecuteTask( PipelineManagerDX11* pPipelineManager, IParameterManager* pParamManager )
{
    Matrix4f mat = Matrix4f::Identity(); //TODO: Matrix global machen.

    // Set the parameters for rendering this view
    pPipelineManager->ClearRenderTargets();
    pPipelineManager->OutputMergerStage.DesiredState.RenderTargetViews.SetState( 0, m_RenderTarget->m_iResourceRTV );
    pPipelineManager->ApplyRenderTargets();

    pPipelineManager->RasterizerStage.DesiredState.ViewportCount.SetState( 1 );
    pPipelineManager->RasterizerStage.DesiredState.Viewports.SetState( 0, m_iViewport );
    pPipelineManager->RasterizerStage.DesiredState.RasterizerState.SetState( 0 );

    // Set default states for these stages
    pPipelineManager->OutputMergerStage.DesiredState.DepthStencilState.SetState( 0 );
    pPipelineManager->OutputMergerStage.DesiredState.BlendState.SetState( 0 );

    m_pSpriteRenderer->Render( pPipelineManager, pParamManager, _direct2DTexture, mat); //TODO: Matrix global machen.
}
//--------------------------------------------------------------------------------
void GUIOverlay::Resize( UINT width, UINT height )
{
    RendererDX11::Get()->ResizeViewport( m_iViewport, width, height );
}
//--------------------------------------------------------------------------------
void GUIOverlay::SetRenderParams( IParameterManager* pParamManager )
{
//  pParamManager->SetViewMatrixParameter( &ViewMatrix );
//  pParamManager->SetProjMatrixParameter( &ProjMatrix );
}
//--------------------------------------------------------------------------------
void GUIOverlay::SetUsageParams( IParameterManager* pParamManager )
{

}
//--------------------------------------------------------------------------------
std::wstring GUIOverlay::GetName()
{
    return( L"GUIOverlay" );
}
//--------------------------------------------------------------------------------
Here i init the Direct2DRenderer + StageAPI that is like Flashs API:
//--------------------------------------------------------------------------------
bool App::InitializeD2D1Renderer(int width, int height) {
    _rendererD2D1 = new D2D1Renderer();
    
    if(!_rendererD2D1->Initialize(m_pWindow->GetHandle(), &m_pRenderer11->GetDevice(), width, height)) {
        return false;
    }

    _stage = new D2::Stage();
    _rendererD2D1->addD2D1FrameRenderListener(_stage);
    
    _guiOverlayView = new GUIOverlay( *m_pRenderer11, *_rendererD2D1, m_BackBuffer );
    m_pCamera->getComponent<CameraComponent>()->SetOverlayView( _guiOverlayView );
    
    return true;
}

void App::Update()
{
    //Update the timer to determine the elapsed time since last frame.  This can then used for animation during the frame.
    m_pTimer->Update();

    //Send an event to everyone that a new frame has started.  This will be used in later examples for using the material system with render views.
    EvtManager.ProcessEvent( EvtFrameStartPtr( new EvtFrameStart( m_pTimer->Elapsed() ) ) );

    _rendererD2D1->Update();

    //Update the scene, and then render all cameras within the scene.
    m_pScene->Update( m_pTimer->Elapsed() );
    m_pScene->Render( m_pRenderer11 );

    //Perform the rendering and presentation for the window.
    m_pRenderer11->Present( m_pWindow->GetHandle(), m_pWindow->GetSwapChain() );
}
//--------------------------------------------------------------------------------
Basic elements of the Flash-Like API are:
Stage
DisplayObject
DisplayObjectContainer
Graphics
Text
Bitmap
Shape

Build a sublass of DisplayObject and you can make your own rendercode. Like i did for the GUI-Elements.
Coordinator
Mar 24, 2013 at 1:10 PM
That looks really great - nice work! I had never considered directly using Direct2D like this as a secondary renderer, but it really makes sense. Have you considered creating an open source project out of your UI system/D2D renderer? I think this discussion thread shows that there is an appetite for such a solution, but it is difficult to find a good one...

I would even consider hosting it directly within Hieroglyph if you don't want to make your own project. Do you use the system in a commercial product, or is it more for hobby level projects at the moment? It sounds like you have big plans for it!
Mar 24, 2013 at 6:33 PM
Edited Mar 24, 2013 at 6:44 PM
Thats great. I will overlook the whole code. Give me a few days. Make a little clean up.

I do not know codeplex so well. I will give it a try and make a codeplex project.

Is it possible to share the project that you have all rights on the project like me?
Furthermore, there are three Source Control Configs: Git, Team Foundation Server, Mercurial ... which one have you choosen?
Mar 24, 2013 at 7:16 PM
Edited Mar 25, 2013 at 12:13 AM
Here are my Keyboard and Mouse Changes for the engine. They are not needed for the integration of the D2D1Renderer/UI-System because i will integrade a similar version of this for the D2D1Renderer/UI-System.

So the inputs for the UI-System will be independent to the engine. But it will have the same procedur as below. Intern the ui-system has a different event management. Its like yours but different. A Flash-like EventDispatcher. It is easy to handle and makes the gui programming very flexible.

So here are my changes to your engine that i made to the mouse and keyboard event system:

<Keyboard>

I need a method in your EvtKeyboardMsg class:

Your GetCharacterCode() brings me a Virtual-Key Code (Windows) "Hardware-Independent" -> http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731%28v=vs.85%29.aspx

And my GetASCIICode() brings me an ASCII_Key Code -> http://www.theasciicode.com.ar/extended-ascii-code/box-drawing-character-ascii-code-188.html

So there is the virtual key code and the ascii key code

EvtKeyboardMsg.h
....
        unsigned int GetCharacterCode(); 
        unsigned int GetASCIICode();

        unsigned int GetRepeatCount();
....
EvtKeyboardMsg.cpp
unsigned int EvtKeyboardMsg::GetASCIICode()
{
    BYTE buf[256];
    WORD p;
    GetKeyboardState (&buf[0]);
    ToAscii (m_wparam, m_lparam, &buf[0], &p, 0);
    char c = (char)p;

    return c;
}
unsigned int vkey = pKeyDown->GetCharacterCode(); //(Virtual Key)
unsigned int ckey = pKeyDown->GetASCIICode(); (Character Key)

perhaps the name of the functions should be renamed.
GetCharacterCode into GetVirtualCode
GetASCIICode into GetCharacterCode

I think the m_wparam is the virtual keycode given by windows

EvtKeyboardMsg.cpp
unsigned int EvtKeyboardMsg::GetCharacterCode()
{
    return( m_wparam );
}
Mar 24, 2013 at 8:47 PM
Edited Mar 24, 2013 at 11:23 PM
I have re-added the RawInput from beginning now without the API for RawInput (remember: gave you a link). I think we have to walk on a low level when implementing better mouse interaction. Mouse State Objects and Keyboard State Objects can the user make by himself if he want.

<Mouse>

The SYSTEM_LBUTTON_DOWN, SYSTEM_LBUTTON_UP, SYSTEM_MBUTTON_DOWN, SYSTEM_MBUTTON_UP, SYSTEM_RBUTTON_DOWN, SYSTEM_RBUTTON_UP are
too much. Delete it.
There have only to be one SYSTEM_MOUSE_DOWN and one SYSTEM_MOUSE_UP eEvent entry.

IEvent.h
...
RENDER_FRAME_START,
        //SYSTEM_LBUTTON_DOWN,
        //SYSTEM_LBUTTON_UP,
        //SYSTEM_MBUTTON_DOWN,
        //SYSTEM_MBUTTON_UP,
        //SYSTEM_RBUTTON_DOWN,
        //SYSTEM_RBUTTON_UP,
        SYSTEM_MOUSE_DOWN,
        SYSTEM_MOUSE_UP,
        SYSTEM_MOUSE_LEAVE,
...
The data if the left or middle or right mouse is pressed will be inside the MouseEvent-Object.

Next

EvtMouseLButtonDown.h/cpp (delete)
EvtMouseLButtonUph/cpp (delete)
EvtMouseRButtonDownh/cpp (delete)
EvtMouseRButtonUph/cpp (delete)
EvtMouseMButtonDownh/cpp (delete)
EvtMouseMButtonUp.h/cpp (delete)

have to be deleted and the classes EvtMouseDown and EvtMouseUp have to be created.

EvtMouseDown.h (new File)
//--------------------------------------------------------------------------------
// This file is a portion of the Hieroglyph 3 Rendering Engine.  It is distributed
// under the MIT License, available in the root of this distribution and 
// at the following URL:
//
// http://www.opensource.org/licenses/mit-license.php
//
// Copyright (c) Jason Zink 
//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
// EvtMouseLButtonDown
//
//--------------------------------------------------------------------------------
#ifndef EvtMouseDown_h
#define EvtMouseDown_h

#define RI_MOUSE_BUTTON_1    (RI_MOUSE_BUTTON_1_DOWN | RI_MOUSE_BUTTON_1_UP)
#define RI_MOUSE_BUTTON_2    (RI_MOUSE_BUTTON_2_DOWN | RI_MOUSE_BUTTON_2_UP)
#define RI_MOUSE_BUTTON_3    (RI_MOUSE_BUTTON_3_DOWN | RI_MOUSE_BUTTON_3_UP)
#define RI_MOUSE_BUTTON_4    (RI_MOUSE_BUTTON_4_DOWN | RI_MOUSE_BUTTON_4_UP)
#define RI_MOUSE_BUTTON_5    (RI_MOUSE_BUTTON_5_DOWN | RI_MOUSE_BUTTON_5_UP)

//--------------------------------------------------------------------------------
#include "EvtMouseMsg.h"
//--------------------------------------------------------------------------------
namespace Glyph3
{
    class EvtMouseDown : public EvtMouseMsg
    {
    public:
        EvtMouseDown( HWND hwnd, unsigned int wparam, long lparam );
        virtual ~EvtMouseDown( );

        virtual std::wstring GetEventName( );
        virtual eEVENT GetEventType( );
    };

    typedef std::shared_ptr<EvtMouseDown> EvtMouseDownPtr;
};
//--------------------------------------------------------------------------------
#endif // EvtMouseButtonDown_h

EvtMouseDown.cpp (new File)
//--------------------------------------------------------------------------------
// This file is a portion of the Hieroglyph 3 Rendering Engine.  It is distributed
// under the MIT License, available in the root of this distribution and 
// at the following URL:
//
// http://www.opensource.org/licenses/mit-license.php
//
// Copyright (c) Jason Zink 
//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
#include "PCH.h"
#include "EvtMouseDown.h"
//--------------------------------------------------------------------------------
using namespace Glyph3;
//--------------------------------------------------------------------------------
EvtMouseDown::EvtMouseDown( HWND hwnd, unsigned int wparam, long lparam )
: EvtMouseMsg( hwnd, wparam, lparam )
{
}
//--------------------------------------------------------------------------------
EvtMouseDown::~EvtMouseDown( )
{
}
//--------------------------------------------------------------------------------
std::wstring EvtMouseDown::GetEventName( )
{
    return( std::wstring( L"button_down" ) );
}
//--------------------------------------------------------------------------------
eEVENT EvtMouseDown::GetEventType( )
{
    return( SYSTEM_MOUSE_DOWN );
}
//--------------------------------------------------------------------------------

EvtMouseUp.h

//--------------------------------------------------------------------------------
// This file is a portion of the Hieroglyph 3 Rendering Engine.  It is distributed
// under the MIT License, available in the root of this distribution and 
// at the following URL:
//
// http://www.opensource.org/licenses/mit-license.php
//
// Copyright (c) Jason Zink 
//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
// EvtMouseLButtonUp
//
//--------------------------------------------------------------------------------
#ifndef EvtMouseUp_h
#define EvtMouseUp_h
//--------------------------------------------------------------------------------
#include "EvtMouseMsg.h"
//--------------------------------------------------------------------------------
namespace Glyph3
{
    class EvtMouseUp : public EvtMouseMsg
    {
    public:
        EvtMouseUp( HWND hwnd, unsigned int wparam, long lparam );
        virtual ~EvtMouseUp( );

        virtual std::wstring GetEventName( );
        virtual eEVENT GetEventType( );
    };

    typedef std::shared_ptr<EvtMouseUp> EvtMouseUpPtr;
};
//--------------------------------------------------------------------------------
#endif // EvtMouseButtonUp_h
EvtMouseUp.cpp
//--------------------------------------------------------------------------------
// This file is a portion of the Hieroglyph 3 Rendering Engine.  It is distributed
// under the MIT License, available in the root of this distribution and 
// at the following URL:
//
// http://www.opensource.org/licenses/mit-license.php
//
// Copyright (c) Jason Zink 
//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
#include "PCH.h"
#include "EvtMouseUp.h"
//--------------------------------------------------------------------------------
using namespace Glyph3;
//--------------------------------------------------------------------------------
EvtMouseUp::EvtMouseUp( HWND hwnd, unsigned int wparam, long lparam )
: EvtMouseMsg( hwnd, wparam, lparam )
{
}
//--------------------------------------------------------------------------------
EvtMouseUp::~EvtMouseUp( )
{
}
//--------------------------------------------------------------------------------
std::wstring EvtMouseUp::GetEventName( )
{
    return( std::wstring( L"button_up" ) );
}
//--------------------------------------------------------------------------------
eEVENT EvtMouseUp::GetEventType( )
{
    return( SYSTEM_MOUSE_UP );
}
//--------------------------------------------------------------------------------
The EvtMouseMsg.h has to be changed.
bool LButtonDown(); (remove)
bool MButtonDown(); (remove)
bool RButtonDown(); (remove)

unsigned int GetKey(); (add)

EvtMouseMsg.h
...
unsigned int GetKey();
...
EvtMouseMsg.cpp
...
unsigned int EvtMouseMsg::GetKey() {
    return m_wparam; 
}
...
Application.cpp
RequestEvent( SYSTEM_MOUSE_UP );
    RequestEvent( SYSTEM_MOUSE_DOWN );
    RequestEvent( SYSTEM_MOUSE_MOVE );
    RequestEvent( SYSTEM_MOUSE_WHEEL );
add this members and methods to the Application.h

Application.h
...
private:
        void InitializeRawInput();
    void ProcessMouseMessage(RAWMOUSE* mouse, HWND hwnd);
    int _mouseX;
    int _mouseY;
...
Application.cpp
void Application::InitializeRawInput() {
    _mouseX = 0;
    _mouseY = 0;

    RAWINPUTDEVICE Rid[1];

    // Keyboard
    //Rid[0].usUsagePage = 1;
    //Rid[0].usUsage = 6;
    //Rid[0].dwFlags = 0;
    //Rid[0].hwndTarget = NULL;

    // Mouse
    Rid[0].usUsagePage = 1;
    Rid[0].usUsage = 2;
    Rid[0].dwFlags = 0;
    Rid[0].hwndTarget = NULL;

    if(RegisterRawInputDevices(Rid, 1, sizeof(RAWINPUTDEVICE)) == FALSE) {
        MessageBox(NULL, L"Failed to Register Input Devices!", L"ALERT", MB_OK);
        exit(1);
    }
}
Application.cpp (Code Piece)
...
    RequestEvent( INFO_MESSAGE );
    RequestEvent( ERROR_MESSAGE );

    // Create the scene to be manipulated.

    m_pScene = new Scene();

    InitializeRawInput();
}
//--------------------------------------------------------------------------------
Application::~Application( )
{
}
...
Mar 24, 2013 at 9:10 PM
Edited Mar 25, 2013 at 1:57 AM
You can see that i have to make _mouseX and _mouseY members inside Application.h. This is because i want to have the mouse position... i get it fromthe Window MOUSE_MOVE Message. Its better to get it from there because else you have to write a function to get coodinates relative to the window. Someday i did write a function for this but i see that there are a lot mess of doing that. So this is easier.

Application.cpp (Code Piece)
case WM_MOUSEMOVE:
            {
                EvtMouseMovePtr pEvent = EvtMouseMovePtr( new EvtMouseMove( hwnd, wparam, lparam ) );
                _mouseX = pEvent->GetX();
                _mouseY = pEvent->GetY();

                EvtManager.ProcessEvent( pEvent );
            } break;
Application.cpp
void Application::ProcessMouseMessage(RAWMOUSE* mouse, HWND hwnd) {
    if((mouse->usButtonFlags & (RI_MOUSE_BUTTON_1_DOWN|RI_MOUSE_BUTTON_2_DOWN|RI_MOUSE_BUTTON_3_DOWN|RI_MOUSE_BUTTON_4_DOWN|RI_MOUSE_BUTTON_5_DOWN)) != 0) {
        //coding the mouse position into a long.
        long lparam = _mouseY << 16 | _mouseX;
        unsigned int wparam = mouse->usButtonFlags;

        //throw the event.
        EvtMouseDownPtr pEvent = EvtMouseDownPtr( new EvtMouseDown( hwnd, wparam, lparam)); //mouse.GetData().usButtonFlags, mouse.GetData().usFlags ) );
        EvtManager.ProcessEvent( pEvent );
    }

    if((mouse->usButtonFlags & (RI_MOUSE_BUTTON_1_UP|RI_MOUSE_BUTTON_2_UP|RI_MOUSE_BUTTON_3_UP|RI_MOUSE_BUTTON_4_UP|RI_MOUSE_BUTTON_5_UP)) != 0) {
        //coding the mouse position into a long.
        long lparam = _mouseY << 16 | _mouseX;
        unsigned int wparam = mouse->usButtonFlags;

        //throw the event.
        EvtMouseUpPtr pEvent = EvtMouseUpPtr( new EvtMouseUp( hwnd, wparam, lparam)); //( hwnd, mouse.GetData().usButtonFlags, mouse.GetData().usFlags ) );
        EvtManager.ProcessEvent( pEvent );
    }
}
inside Application::WindowProc
delete ->
WM_LBUTTONUP:
WM_LBUTTONDOWN
WM_MBUTTONUP
WM_MBUTTONDOWN
WM_RBUTTONUP
WM_WM_RBUTTONDOWN

and create
case WM_INPUT: 
            {
                //Determine how big the buffer should be
                UINT iBuffer;

                GetRawInputData((HRAWINPUT)lparam, RID_INPUT, NULL, &iBuffer, sizeof(RAWINPUTHEADER));
                LPBYTE lpb = new BYTE[iBuffer];
                if(lpb == NULL) {
                    return 0;
                } 

                UINT readSize = GetRawInputData( (HRAWINPUT)lparam, RID_INPUT, lpb, &iBuffer, sizeof(RAWINPUTHEADER) ) ;

                if(readSize != iBuffer)
                    puts( "ERROR:  GetRawInputData didn't return correct size!" ) ;
                RAWINPUT *raw = (RAWINPUT*) lpb;                

                if (raw->header.dwType== RIM_TYPEMOUSE) {
                    ProcessMouseMessage(&raw->data.mouse, hwnd);
                }
                //if (raw->header.dwType== RIM_TYPEKEYBOARD) {
                //  ProcessKeyboardMessage(&raw->data.keyboard);
                //}  
            } break;
Now you can catch the SYSTEM_MOUSE_DOWN inside the App.cpp like:
if ( e == SYSTEM_MOUSE_DOWN ) 
    {
        EvtMouseDownPtr pMouseDown = std::static_pointer_cast<EvtMouseDown>( pEvent );

        if(pMouseDown->GetKey() & RI_MOUSE_BUTTON_1) {
            int a = 0;
        }
        if(pMouseDown->GetKey() & RI_MOUSE_BUTTON_2) {
            int a = 0;
        }
        if(pMouseDown->GetKey() & RI_MOUSE_BUTTON_3) {
            int a = 0;
        }
        if(pMouseDown->GetKey() & RI_MOUSE_BUTTON_4) {
            int a = 0;
        }
        if(pMouseDown->GetKey() & RI_MOUSE_BUTTON_5) {
            int a = 0;
        }
    } 
How you can see RI_MOUSE_BUTTON_1 are the constants that integrated in EvtMouseMsg_h. But they are only warper to the RI_MOUSE_BUTTON_1_DOWN, etc from microsofts WinUser.h

It looks so big when i post it. But its not much.
Coordinator
Mar 25, 2013 at 12:10 AM
Wow - you have been busy today! I have not problem to take over the mouse and keyboard updates - what you indicated above makes sense to combine the messages. It will probably take a day or two for me to review the code and integrate the changes, but I am planning to incorporate several of your change requests at the same time.

Regarding the type of project, I am currently using SVN for Hieroglyph 3, but I am planning to update to Git fairly soon. You can add me as a project member to your project, and then I would be able to make commits against the project code base. There are several different levels of team member that you can choose for people, so there is some flexibility available. In addition you can just accept patches from people and apply them that way as well.

If you have any questions about the process, please feel free to send me a PM or just post the question here and I'll do my best to answer them!
Mar 25, 2013 at 5:04 AM
Edited Mar 25, 2013 at 6:45 AM
here it is:

https://d2d1renderer.codeplex.com/

I take your folder structure so that it is nearly the same structure like in your project. If you try to integrate the renderer and it makes problems because of the same folder structure (collision) visual studio can handle this somewhere in the solution config. If you have the problems i figure out what it was.

I think i have to rework the whole notation of my code. There are a lot of ugly notations, like for position of a displayobject obj->_x or for width obj->_width.

Tomorrow i will make short tutorials for everything on the codeplex site.
Coordinator
Mar 25, 2013 at 12:32 PM
That's really great - I'll read through some of the code today and post back to you. Its really great that you are sharing your work, and I applaud you for it! Welcome to the open source community!
Mar 25, 2013 at 3:10 PM
Edited Mar 25, 2013 at 11:02 PM
Thanks. Have no problem to sharing it. You give me a well writen book for learning directX11 and a free to use open source DirectX11 engine. I think i have to thank you. I have written a DirectX11 Engine too in the past. But it is not as good as your well written API. In the moment i try to port my game. The first steps was to modificate everything to my need in your engine. But i think this was not a good way. Furthermore you give me no need when you added everything i need. But i only want this if you really think this is an improvement for your engine. For everything else i will find a workaround.

You can send me bugs or improving tips too when you see something is wrong when you using the renderer/ui-system.

You can make a thread on the projectsite if you have problems to integrate/use it.

I will try to write a little bit more documentation.
Coordinator
Mar 27, 2013 at 2:28 AM
That's the beauty of open source - everyone benefits from everyone else :) I'm going to be trying out some experiments with your renderer and get it working in a Task. Your instructions look pretty clear already, so it should be fairly easy to try out. I will certainly let you know once I get it up and running and give you some feedback. Please be patient though - it seems that my free time is becoming more and more scarce...

Thanks again, and I'll be in touch soon.
Mar 27, 2013 at 4:12 AM
Edited Mar 27, 2013 at 5:08 AM
Yeah open source is great. Dont like software patents.

Look:
http://d2d1renderer.codeplex.com/wikipage?title=Setup%20Visual%20Studio%20for%20Hieroglyph%203%20%28directX11%20render%20engine%29&referringTitle=Documentation

(Do you put the D2D1Renderer inside your Dependencies-Folder?)

and

http://d2d1renderer.codeplex.com/wikipage?title=Integration%20of%20the%20renderer%20in%20Hieroglyph%203%20%28directX11%20render%20engine%29&referringTitle=Documentation

The tutorals are for the new version. (Not uploaded yet)

At the momement i try to make Examples that can be found in the _Example-Folder in the next upload. I want to implement Gradients too, for better optic.
Coordinator
Mar 27, 2013 at 6:28 PM
Regarding the location of the D2D1Renderer, I would probably put it into the extensions folder, since some output from that library (i.e. the GUIOverlay) requires access to the Hieroglyph 3 classes. If you look at the GlyphKinect library, I think this would fall into a similar category. Depending on how the code shapes up in the long run, it would be possible to integrate it completely into the core Hieroglyph codebase, but I would need to make sure that D2D1 is supported on all of the eventual platforms for that (which I think WP8 would have issues there at the moment).
Mar 27, 2013 at 8:26 PM
Never written for other platforms than the platform im working on. But sure, i think it is necessary that it works with more than Windows 7. But dont know how to test it. I run it with the latest Windows 8 SDK to be able to make someday the step to Windows 8. But if i would it run on Windows 8 nativly i would use DirectX11.1 for direct Direct2D support. Windows Phone 8 i dont know. Perhaps there is a software emulator for Windows 7 like Android has to test it. I see that Windows Phone 8 dont supports Direct2D (for drawing) or DirectWrite (for text drawing) which both i used. But http://kennykerr.ca/2012/12/01/windows-phone-and-direct2d/ says that there is a way to run it without problems on WIndows Phone 8.
Furthemore to bring perhaps later all hardware accelerated things from microsoft to the hieroglyph engine i have made it to play a video on screen over the microsoft media foundation classes. But its restricted with Windows 7 and Windows 8 only gives the capabilities to use it in full manner. But its nice to see that full hd videos plays with excellent performance.
Coordinator
Mar 28, 2013 at 2:44 AM
I don't think it will be a big problem - we can just implement a different solution for WP8, or possibly even exclude the 2D rendering capabilities from the WP8 version until D2D is supported.

The video rendering is certainly a great addition - especially since it can be used in a general scene environment! I will certainly be looking closer into this one in the coming days.
Editor
Apr 29, 2013 at 11:33 PM
Got an update on where my research lead me. I played around with Qt for a bit and liked what I saw. The API is intuitive, plenty of documentation, and free (sort of). Qt is free as long as the project you build is opensource. For closed source applications, you're going to have to cough up a pretty penny. So, I had to scratch off Qt from the list :(. Next I switched over to wxWidgets. Again, I liked what I saw. API is also intuitive, but makes heavy use of macros (can be a good or bad thing depending on how you see it), lots of documentation (the online wiki is great), tons of samples with the source code, and 100% free (commercial and non-commercial use).

Once I got everything setup (needs to be compiled from source) and running, I was able to create a simple form with buttons, textboxes, and menu items with all of their events hooked up to handlers. I then proceeded to integrate my engine into a simple form and render a simple triangle (the hello world equivalent of 3D programming :) ). Everything worked beautifully! The tough part was finding an example of integrating DirectX with wxWidgets, but a few google searches lead me to here. Look at the last post by Timmy79. He has all of the code there that's needed. The key is in the OnPaint and OnBackgroundPaint events and the GetHWND method needed to return the HWND handle for DirectX. This is actually very similar to setting up .NET WinForms and DirectX/XNA to work together if you've ever done so.

I think integrating wxWidgets with Hieroglyph3 would be a sinch. I can create a sample Hieroglyph3/wxWidgets project and show you if you're interested. Let me know :)!
Coordinator
Apr 30, 2013 at 2:25 AM
@rmncp3: That sounds great! I have a basic MFC sample in the code distribution already, but adding a wxWidgets sample would be fantastic. Actually, the steps you described sound very similar to what needs to be done in MFC as well, so that it probably maps down to a Win32 thing at a lower level just like MFC. If I recall correctly, wxWidgets is similar to MFC in design, with the exception that it is cross platform, so that would make sense too...

I would really appreciate if you have the time to put together a sample program with some instructions on setup. In fact, if you are interested in writing a short wiki page about how you set it up that would be even better. If you don't have the time, I can always put something together based on your sample too, so either way is an option.

Thanks a lot for the update and the offer - I look forward to seeing what you have cooked up :)
Editor
Apr 30, 2013 at 3:46 PM
After reading your response I checked out your MFC project you have integrated with Hierogrlyph 3 and the code is very similiar to wxWidgets. Awesome! I never did too much MFC. As I started down that path, .NET came out, so I pursued that instead. I can see now how the two frameworks are similiar.

I would be more than happy to create a wiki page that demonstrates wxWidgets integration with Hieroglyph 3 for ya ;). Would adding it to this codeplex project be ok? Would I need admin permissions?
Editor
Apr 30, 2013 at 7:38 PM
2 points:

- I've used QT a fair bit in the past and just wanted to mention QT is free _regardless_ of whether your app is closed-source. Nokia re-licensed it LGPL a few years back and added a special linking exception (e.g. for inline code in the headers). So, as long as you avoid static linking you should be fine (any modifications to QT itself of course are a different matter).

- Not sure what your ultimate intent is but I've played around with CEGUI and while it can't compete with the big GUI frameworks in terms of feature set, it allows far tighter integration via input injection/custom file system backend/custom rendering backend/etc. (Although it provides good defaults, e.g. a native DX11 backend out of the box). It also supports use-cases like render to texture. And needless to say it's much lighter-weight.You probably wouldn't want to use it for say, an editor, but for "in-game" GUI systems or cases where you don't want to see your frame-rate impacted by the GUI, it's a far better choice imo.


Editor
Apr 30, 2013 at 8:15 PM
@jmkinzer

Thanks for the input! I didn't realize Nokia re-licensed Qt. They should do a better job of mentioning that on their site ; ). Unless I'm just blind : ). That's good news though. Makes for a good fallback just in case wxWidgets doesn't pan out, which I doubt it will. It's a pretty solid framework.

It's funny you mention CEGUI. I ran across his site a few weeks back while doing research for in-game UI. It seems like a slick framework. I'll definitely be circling back to CEGUI once I get to implementing the UI system for my engine. Have you run into any gotchas with using CEGUI?

Thanks again!
Coordinator
May 1, 2013 at 2:51 AM
@rmncp3: I added you as an editor to the project, so you should now have access to modify wiki pages. If you have any trouble, or it isn't working, just let me know. Also, if you are able to put together a sample of integrating a Hieroglyph 3 rendering into a wxWidgets app, please send it over and I'll package it up and put it into the repository.

Thanks again for the offer and the contribution!
Editor
May 1, 2013 at 3:10 AM
Well, it definitely doesn't have the breadth of widgets that QT does. But then again, it's intended for games, not, spreadsheets ;-) So it really depends on what you're looking for. If I were creating an editor I'd go with QT, no questions asked. But so far I'm really impressed. I've actually tried a number of frameworks (mygui, librocket, ...) and CEGUI seems about optimal for my purposes. The only reason I hadn't tried it earlier is google doesn't seem to like it much (you'll find posts berating it for poor performance, complexity, etc.). However I haven't seen that at all - for me at least it seems very well designed (it does everything good middleware should), has a decent set of features (e.g. internationalization), and the performance is good.


Editor
May 1, 2013 at 2:41 PM
@jzink

Awesome thanks! I'll start work on the wiki page a little later today. I'll send you the project that I'm going to use for the wiki once I'm done.

Happy to help : )! You helped me out plenty over the last few months. Just returning the favor ; ).
Editor
May 1, 2013 at 2:48 PM
@jmkinzer

Nice! From what I've seen, CEGUI looks great for game development. I didn't plan on using it for anything else ; ). I looked over the LGPL for Qt and it seems that you are right sir. I may have to consider switching to Qt later. It was the preferred framework that I originally wanted to use for my editor. For now, I'll continue on with wxWidgets unless there's a deal breaker for me.

From what I've seen, a lot of people seem to be happy with CEGUI. A good bit of games have been shipped using it. I'll keep a lookout for any performance issues or gotchas once I start playing with it.

Thanks again for the info!
Editor
May 1, 2013 at 10:26 PM
@jzink

I'm seeing a strange error when including "RendererDX11.h"

"syntax error : '(' for file dxgi1_2.h"

If i remove the renderer header the error goes away. Are you using any of the DXGI interfaces at all in Hieroglyph3? I'm building this on Win8. Thanks!
Coordinator
May 2, 2013 at 11:41 AM
@rmncp3: I am only using them in the initialization of the renderer, but very, very little. There are a couple of classes that wrap DXGI objects (DXGIAdapter iirc), but again, they aren't doing much. I have built Hieroglyph 3 on Win8 before, but it has been a little while - so it is possible that some of the newer updates have caused an issue.

Do you see this on the stock download of HG3, or is this in a customized project you are working on?
Editor
May 2, 2013 at 2:09 PM
@jzink

This is for the new app I added to the solution. I know MS removed the old DXGI out of the DX9/10 libs into their own for Win8, but that shouldn't be affecting anything. I can run and build all of the other apps in Hieroglyph3 just fine. I'll take a look in the project settings some more to see if anything stands out. Thanks!
Coordinator
May 2, 2013 at 2:48 PM
@rmncp3: Sometimes I find it useful to just copy one of the existing projects which is similar to what I want, and then modify the *.vcxproj file directly before adding it to the solution. That may ease the pain of integrating into a new application, rather than using one generated from a wizard.

Of course, if you still have trouble, just post it in the discussions (probably under a new discussion topic) and we can work through it together.
Editor
May 2, 2013 at 4:36 PM
@jzink

Yeah, I should have just done that : ). I'll let you know if I run into anything. Thanks!