Skip to content

Commit

Permalink
Client: Added CompositorWidget, testing it in ClientWindow
Browse files Browse the repository at this point in the history
CompositorWidget uses a texture target for all its children.

ClientWindow is now set up to use a compositor for everything that
is not the game view. This should only be done when necessary, not
always as currently.

GuiRootWidget::addOnTop() was added so that widgets can be added
easily into the compositor or the root if a compositor is not in use.
  • Loading branch information
skyjake committed Nov 4, 2013
1 parent d22f97a commit 090a3e3
Show file tree
Hide file tree
Showing 13 changed files with 335 additions and 34 deletions.
2 changes: 2 additions & 0 deletions doomsday/client/client.pro
Expand Up @@ -420,6 +420,7 @@ DENG_HEADERS += \
include/ui/widgets/buttonwidget.h \
include/ui/widgets/choicewidget.h \
include/ui/widgets/commandwidget.h \
include/ui/widgets/compositorwidget.h \
include/ui/widgets/consolecommandwidget.h \
include/ui/widgets/consolewidget.h \
include/ui/widgets/cvarchoicewidget.h \
Expand Down Expand Up @@ -767,6 +768,7 @@ SOURCES += \
src/ui/widgets/buttonwidget.cpp \
src/ui/widgets/choicewidget.cpp \
src/ui/widgets/commandwidget.cpp \
src/ui/widgets/compositorwidget.cpp \
src/ui/widgets/consolecommandwidget.cpp \
src/ui/widgets/consolewidget.cpp \
src/ui/widgets/cvarchoicewidget.cpp \
Expand Down
9 changes: 9 additions & 0 deletions doomsday/client/include/ui/clientwindow.h
Expand Up @@ -78,6 +78,15 @@ class ClientWindow : public de::PersistentCanvasWindow,
GameWidget &game();
BusyWidget &busy();

/**
* Adds a widget to the widget tree so that it will be displayed over
* other widgets.
*
* @param widget Widget to add on top of others. Ownership of the
* widget taken by the new parent.
*/
void addOnTop(GuiWidget *widget);

/**
* Installs a sidebar widget into the window. If there is an existing
* sidebar, it will be deleted. Sidebar widgets are expected to control
Expand Down
8 changes: 8 additions & 0 deletions doomsday/client/include/ui/framework/guirootwidget.h
Expand Up @@ -26,6 +26,7 @@
#include <de/Matrix>

class ClientWindow;
class GuiWidget;

/**
* Graphical root widget.
Expand All @@ -49,6 +50,13 @@ class GuiRootWidget : public de::RootWidget
*/
ClientWindow &window();

/**
* Adds a widget over all others.
*
* @param widget Widget to add on top.
*/
void addOnTop(GuiWidget *widget);

de::AtlasTexture &atlas();
de::GLUniform &uAtlas();
de::Id solidWhitePixel() const;
Expand Down
56 changes: 56 additions & 0 deletions doomsday/client/include/ui/widgets/compositorwidget.h
@@ -0,0 +1,56 @@
/** @file compositorwidget.h Off-screen compositor.
*
* @authors Copyright (c) 2013 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

#ifndef DENG_CLIENT_COMPOSITORWIDGET_H
#define DENG_CLIENT_COMPOSITORWIDGET_H

#include "GuiWidget"

/**
* Off-screen compositor.
*
* All children of the compositor are drawn to an off-screen render target
* whose size is equal to the default render target. The default behavior of
* the compositor is to then draw the composited off-screen target back to the
* default target.
*
* @todo Allow optionally requesting more target attachments beyond the default
* color buffer.
*/
class CompositorWidget : public GuiWidget
{
public:
CompositorWidget(de::String const &name = "");

de::GLTexture &composite() const;

// Events.
void viewResized();
void preDrawChildren();
void postDrawChildren();

protected:
void glInit();
void glDeinit();
void drawComposite();

private:
DENG2_PRIVATE(d)
};

#endif // DENG_CLIENT_COMPOSITORWIDGET_H
2 changes: 1 addition & 1 deletion doomsday/client/include/ui/widgets/gameuiwidget.h
Expand Up @@ -29,7 +29,7 @@ class GameUIWidget : public GuiWidget
public:
GameUIWidget();

void draw();
void drawContent();

private:
DENG2_PRIVATE(d)
Expand Down
48 changes: 34 additions & 14 deletions doomsday/client/src/ui/clientwindow.cpp
Expand Up @@ -35,6 +35,7 @@

#include "gl/sys_opengl.h"
#include "gl/gl_main.h"
#include "ui/widgets/compositorwidget.h"
#include "ui/widgets/gamewidget.h"
#include "ui/widgets/gameuiwidget.h"
#include "ui/widgets/busywidget.h"
Expand Down Expand Up @@ -68,6 +69,7 @@ DENG2_OBSERVES(App, GameChange)

/// Root of the nomal UI widgets of this window.
GuiRootWidget root;
CompositorWidget *compositor;
GameWidget *legacy;
GameUIWidget *gameUI;
TaskBarWidget *taskBar;
Expand All @@ -94,6 +96,7 @@ DENG2_OBSERVES(App, GameChange)
needRootSizeUpdate(false),
mode(Normal),
root(thisPublic),
compositor(0),
legacy(0),
gameUI(0),
taskBar(0),
Expand Down Expand Up @@ -127,21 +130,26 @@ DENG2_OBSERVES(App, GameChange)
self.canvas().audienceForKeyEvent -= this;
}

Widget &container()
{
if(compositor)
{
return *compositor;
}
return root;
}

void setupUI()
{
Style &style = ClientApp::windowSystem().style();

// Background for Ring Zero.
background = new LabelWidget;
background = new LabelWidget("background");
background->setImage(style.images().image("window.background"));
background->setImageFit(ui::FitToSize);
background->setSizePolicy(ui::Filled, ui::Filled);
background->margins().set("");
background->rule()
.setInput(Rule::Left, root.viewLeft())
.setInput(Rule::Top, root.viewTop())
.setInput(Rule::Right, root.viewRight())
.setInput(Rule::Bottom, root.viewBottom());
background->rule().setRect(root.viewRule());
root.add(background);

legacy = new GameWidget;
Expand All @@ -151,10 +159,16 @@ DENG2_OBSERVES(App, GameChange)
legacy->disable();
root.add(legacy);

/// @todo Compositor only needed in VR modes.

compositor = new CompositorWidget;
compositor->rule().setRect(root.viewRule());
root.add(compositor);

gameUI = new GameUIWidget;
gameUI->rule().setRect(root.viewRule());
gameUI->disable();
root.add(gameUI);
container().add(gameUI);

// Game selection.
games = new GameSelectionWidget;
Expand All @@ -164,14 +178,14 @@ DENG2_OBSERVES(App, GameChange)
.setInput(Rule::Width, OperatorRule::minimum(root.viewWidth(),
style.rules().rule("gameselection.max.width")))
.setAnchorPoint(Vector2f(.5f, .5f));
root.add(games);
container().add(games);

// Common notification area.
notifications = new NotificationWidget;
notifications->rule()
.setInput(Rule::Top, root.viewTop() + style.rules().rule("gap") - notifications->shift())
.setInput(Rule::Right, legacy->rule().right() - style.rules().rule("gap"));
root.add(notifications);
container().add(notifications);

// FPS counter for the notification area.
fpsCounter = new LabelWidget;
Expand All @@ -184,13 +198,12 @@ DENG2_OBSERVES(App, GameChange)
.setInput(Rule::Left, root.viewLeft())
.setInput(Rule::Bottom, root.viewBottom() + taskBar->shift())
.setInput(Rule::Width, root.viewWidth());
root.add(taskBar);
container().add(taskBar);

// The game selection's height depends on the taskbar.
games->rule().setInput(Rule::Height,
OperatorRule::minimum(root.viewHeight(),
(taskBar->rule().top() - root.viewHeight() / 2) * 2,
style.rules().rule("gameselection.max.height")));
(taskBar->rule().top() - root.viewHeight() / 2) * 2, style.rules().rule("gameselection.max.height")));

// Color adjustment dialog.
colorAdjust = new ColorAdjustmentDialog;
Expand Down Expand Up @@ -393,7 +406,7 @@ DENG2_OBSERVES(App, GameChange)
}

sidebar = widget;
root.insertBefore(sidebar, *notifications);
container().insertBefore(sidebar, *notifications);
}

void uninstallSidebar(SidebarLocation location)
Expand All @@ -408,7 +421,7 @@ DENG2_OBSERVES(App, GameChange)
break;
}

root.remove(*sidebar);
container().remove(*sidebar);
sidebar->deleteLater();
sidebar = 0;
}
Expand Down Expand Up @@ -541,6 +554,8 @@ void ClientWindow::canvasGLDraw(Canvas &canvas)
d->updateRootSize();
}

qDebug() << "ClientWindow drawing the content";

d->contentXf.drawTransformed();

// Finish GL drawing and swap it on to the screen. Blocks until buffers
Expand Down Expand Up @@ -712,6 +727,11 @@ void ClientWindow::showColorAdjustments()
d->colorAdjust->open();
}

void ClientWindow::addOnTop(GuiWidget *widget)
{
d->container().add(widget);
}

void ClientWindow::setSidebar(SidebarLocation location, GuiWidget *sidebar)
{
DENG2_ASSERT(location == RightEdge);
Expand Down
6 changes: 6 additions & 0 deletions doomsday/client/src/ui/framework/guirootwidget.cpp
Expand Up @@ -197,6 +197,12 @@ ClientWindow &GuiRootWidget::window()
return *d->window;
}

void GuiRootWidget::addOnTop(GuiWidget *widget)
{
// The window knows what is the correct top to add to.
window().addOnTop(widget);
}

AtlasTexture &GuiRootWidget::atlas()
{
d->initAtlas();
Expand Down

0 comments on commit 090a3e3

Please sign in to comment.