Skip to content

Commit

Permalink
Refactor|Client: Revising game view drawing and compositing
Browse files Browse the repository at this point in the history
The rendered game view is now drawn to the window FBO as part of
view layers composition.

Todo: Unlit floors not rendered correctly, depth/stencil issue?
  • Loading branch information
skyjake committed Sep 26, 2016
1 parent 8576f25 commit bf291d2
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 61 deletions.
6 changes: 5 additions & 1 deletion doomsday/apps/client/include/clientapp.h
Expand Up @@ -35,6 +35,8 @@
#include "busyrunner.h"
#include "world/clientserverworld.h"

class ClientPlayer;

/**
* The client application.
*/
Expand All @@ -60,6 +62,9 @@ class ClientApp : public de::BaseGuiApp, public DoomsdayApp
de::String const &userMessageIfIncompatible,
std::function<void ()> finalizeFunc) override;

de::LoopResult forLocalPlayers(std::function<de::LoopResult (ClientPlayer &)> func);

public:
/**
* Reports a new alert to the user.
*
Expand All @@ -68,7 +73,6 @@ class ClientApp : public de::BaseGuiApp, public DoomsdayApp
*/
static void alert(de::String const &msg, de::LogEntry::Level level = de::LogEntry::Message);

public:
static ClientApp & app();
static BusyRunner & busyRunner();
static Updater & updater();
Expand Down
2 changes: 2 additions & 0 deletions doomsday/apps/client/include/render/viewports.h
Expand Up @@ -134,6 +134,8 @@ viewport_t const *R_CurrentViewPort();
*/
void R_UseViewPort(viewport_t const *vp);

void R_UseViewPort(int consoleNum);

void R_UpdateViewer(int consoleNum);

void R_ResetViewer();
Expand Down
4 changes: 2 additions & 2 deletions doomsday/apps/client/include/ui/viewcompositor.h
Expand Up @@ -76,9 +76,9 @@ class ViewCompositor
* Note that the existing contents of the game view framebuffer are used as-is; the
* game view needs to be redrawn separately beforehand, if needed.
*
* @param playerNum Player number.
* @param rect Rectangle in which to draw the layers.
*/
void drawCompositedLayers();
void drawCompositedLayers(de::Rectanglei const &rect);

private:
DENG2_PRIVATE(d)
Expand Down
18 changes: 18 additions & 0 deletions doomsday/apps/client/src/clientapp.cpp
Expand Up @@ -678,6 +678,24 @@ void ClientApp::checkPackageCompatibility(StringList const &packageIds,
}
}

LoopResult ClientApp::forLocalPlayers(std::function<LoopResult (ClientPlayer &)> func)
{
auto const &players = DoomsdayApp::players();
for (int i = 0; i < players.count(); ++i)
{
ClientPlayer &player = players.at(i).as<ClientPlayer>();
if (player.isInGame() &&
player.publicData().flags & DDPF_LOCAL)
{
if (auto result = func(player))
{
return result;
}
}
}
return LoopContinue;
}

void ClientApp::alert(String const &msg, LogEntry::Level level)
{
if (ClientWindow::mainExists())
Expand Down
27 changes: 22 additions & 5 deletions doomsday/apps/client/src/render/viewports.cpp
Expand Up @@ -702,14 +702,14 @@ void R_UseViewPort(viewport_t const *vp)
if (!vp)
{
currentViewport = nullptr;
/*ClientWindow::main().game().glApplyViewport(
ClientWindow::main().game().glApplyViewport(
Rectanglei::fromSize(Vector2i(DENG_GAMEVIEW_X, DENG_GAMEVIEW_Y),
Vector2ui(DENG_GAMEVIEW_WIDTH, DENG_GAMEVIEW_HEIGHT)));*/
Vector2ui(DENG_GAMEVIEW_WIDTH, DENG_GAMEVIEW_HEIGHT)));
}
else
{
currentViewport = const_cast<viewport_t *>(vp);
//ClientWindow::main().game().glApplyViewport(vp->geometry);
ClientWindow::main().game().glApplyViewport(vp->geometry);
}
}

Expand Down Expand Up @@ -1056,6 +1056,7 @@ void R_RenderViewPort(int playerNum)
dint const oldDisplay = displayPlayer;
displayPlayer = vp->console;
R_UseViewPort(vp);
//currentViewport = vp;

if(displayPlayer < 0 || (DD_Player(displayPlayer)->publicData().flags & DDPF_UNDEFINED_ORIGIN))
{
Expand Down Expand Up @@ -1085,9 +1086,10 @@ void R_RenderViewPort(int playerNum)
//case Player3DViewLayer:

R_UpdateViewer(vp->console);

//LensFx_BeginFrame(vp->console);

gx.DrawViewPort(localNum, &vpGeometry, &vdWindow, displayPlayer, 0/*layer #0*/);
gx.DrawViewPort(localNum, &vpGeometry, &vdWindow, displayPlayer, /* layer: */ 0);

//LensFx_EndFrame();
//break;
Expand All @@ -1098,7 +1100,7 @@ void R_RenderViewPort(int playerNum)
break;

case HUDLayer:
gx.DrawViewPort(p, &vpGeometry, &vdWindow, displayPlayer, 1/*layer #1*/);
gx.DrawViewPort(p, &vpGeometry, &vdWindow, displayPlayer, /* layer: */ 1);
break;
}
#endif
Expand All @@ -1122,6 +1124,8 @@ void R_RenderViewPort(int playerNum)
// Restore things back to normal.
displayPlayer = oldDisplay;
R_UseViewPort(nullptr);

//currentViewport = nullptr;
}

#if 0
Expand Down Expand Up @@ -1489,3 +1493,16 @@ void Viewports_Register()

C_CMD("viewgrid", "ii", ViewGrid);
}

void R_UseViewPort(int consoleNum)
{
int local = P_ConsoleToLocal(consoleNum);
if (local >= 0)
{
R_UseViewPort(&viewportOfLocalPlayer[local]);
}
else
{
R_UseViewPort(nullptr);
}
}
76 changes: 73 additions & 3 deletions doomsday/apps/client/src/ui/viewcompositor.cpp
Expand Up @@ -17,9 +17,15 @@
*/

#include "ui/viewcompositor.h"
#include "ui/clientwindow.h"
#include "render/viewports.h"
#include "world/p_players.h"
#include "api_render.h"
#include "clientapp.h"

#include <de/GLState>
#include <de/GLShaderBank>
#include <de/Drawable>

using namespace de;

Expand All @@ -32,11 +38,20 @@ DENG2_PIMPL(ViewCompositor)
/// game HUD.
GLTextureFramebuffer viewFramebuf;

Drawable frameDrawable;
GLUniform uMvpMatrix { "uMvpMatrix", GLUniform::Mat4 };
GLUniform uFrameTex { "uTex", GLUniform::Sampler2D };

Impl(Public *i)
: Base(i)
, viewFramebuf(Image::RGBA_8888)
{}

~Impl()
{
DENG2_ASSERT(!frameDrawable.isReady()); // deinited earlier
}

GLFramebuffer::Size framebufferSize() const
{
// TODO: Factor in pixel density and scaled-down window size.
Expand All @@ -50,6 +65,28 @@ DENG2_PIMPL(ViewCompositor)
{
viewFramebuf.resize(framebufferSize());
viewFramebuf.glInit();

if (!frameDrawable.isReady())
{
ClientApp::shaders().build(frameDrawable.program(), "generic.texture")
<< uMvpMatrix
<< uFrameTex;

using VBuf = GuiWidget::DefaultVertexBuf;

auto *vbuf = new VBuf;
frameDrawable.addBuffer(vbuf);

VBuf::Builder verts;
verts.makeQuad(Rectanglef(0, 0, 1, 1), Rectanglef(0, 1, 1, -1));
vbuf->setVertices(gl::TriangleStrip, verts, gl::Static);
}
}

void glDeinit()
{
viewFramebuf.glDeinit();
frameDrawable.clear();
}
};

Expand All @@ -64,7 +101,7 @@ void ViewCompositor::setPlayerNumber(int playerNum)

void ViewCompositor::glDeinit()
{
d->viewFramebuf.glDeinit();
d->glDeinit();
}

void ViewCompositor::renderGameView(std::function<void (int)> renderFunc)
Expand All @@ -76,8 +113,9 @@ void ViewCompositor::renderGameView(std::function<void (int)> renderFunc)
.setViewport(Rectangleui::fromSize(d->viewFramebuf.size()))
.apply();

d->viewFramebuf.clear(GLFramebuffer::ColorDepth);
d->viewFramebuf.clear(GLFramebuffer::ColorDepthStencil);

// Rendering is done by the caller-provided callback.
renderFunc(d->playerNum);

GLState::pop()
Expand All @@ -94,7 +132,39 @@ GLTextureFramebuffer const &ViewCompositor::gameView() const
return d->viewFramebuf;
}

void ViewCompositor::drawCompositedLayers()
void ViewCompositor::drawCompositedLayers(Rectanglei const &rect)
{
DENG2_ASSERT(d->frameDrawable.isReady());

GLState::push()
.setBlend (false)
.setDepthTest(false)
.setCull (gl::None);

// First the game view (using the previously rendered texture).
d->uFrameTex = d->viewFramebuf.colorTexture();
d->uMvpMatrix = ClientWindow::main().root().projMatrix2D() *
Matrix4f::scaleThenTranslate(rect.size(), rect.topLeft);
d->frameDrawable.draw();

// View border around the game view.
auto const oldDisplayPlayer = displayPlayer;
displayPlayer = d->playerNum;

R_UseViewPort(d->playerNum);

//R_RenderPlayerViewBorder();

// Game HUD.

// Finale.

// Non-map game screens.

// Legacy engine/debug UIs (stuff from the old Net_Drawer).

R_UseViewPort(nullptr);
displayPlayer = oldDisplayPlayer;

GLState::pop().apply();
}

0 comments on commit bf291d2

Please sign in to comment.