Browse Source

Add blur shader and improve tool tweening

master
C. J. Howard 6 years ago
parent
commit
b49d872e30
9 changed files with 631 additions and 114 deletions
  1. +1
    -1
      data
  2. +173
    -19
      src/application.cpp
  3. +22
    -2
      src/application.hpp
  4. +150
    -7
      src/game/tool.cpp
  5. +25
    -1
      src/game/tool.hpp
  6. +102
    -3
      src/render-passes.cpp
  7. +32
    -0
      src/render-passes.hpp
  8. +66
    -44
      src/states/game-state.cpp
  9. +60
    -37
      src/states/title-state.cpp

+ 1
- 1
data

@ -1 +1 @@
Subproject commit c3fb5da7ac7e7cf776dd00296ecb865fcf4b7b1e
Subproject commit 80851f29bad4062b4505549f572f853db7c50983

+ 173
- 19
src/application.cpp View File

@ -558,14 +558,13 @@ int Application::execute()
// Update frame time label
if (frameTimeLabel->isVisible())
{
/*
std::u32string frameTimeString;
std::basic_stringstream<char32_t> stream;
std::u32string label;
std::stringstream stream;
stream.precision(2);
stream << std::fixed << meanFrameTime;
stream >> frameTimeString;
frameTimeLabel->setText(frameTimeString);
*/
std::string streamstring = stream.str();
label.assign(streamstring.begin(), streamstring.end());
frameTimeLabel->setText(label);
}
}
@ -773,6 +772,7 @@ bool Application::loadScene()
// Unbind shadow map depth texture
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Setup shadow map render target
shadowMapRenderTarget.width = shadowMapResolution;
@ -788,23 +788,109 @@ bool Application::loadScene()
shadowMapCompositor.addPass(&shadowMapPass);
shadowMapCompositor.load(nullptr);
// Post-processing framebuffers
{
// Generate color texture
glGenTextures(1, &framebufferAColorTexture);
glBindTexture(GL_TEXTURE_2D, framebufferAColorTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, static_cast<GLsizei>(resolution.x), static_cast<GLsizei>(resolution.y), 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Generate depth texture
glGenTextures(1, &framebufferADepthTexture);
glBindTexture(GL_TEXTURE_2D, framebufferADepthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, static_cast<GLsizei>(resolution.x), static_cast<GLsizei>(resolution.y), 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
// Generate framebuffer
glGenFramebuffers(1, &framebufferA);
glBindFramebuffer(GL_FRAMEBUFFER, framebufferA);
// Attach textures to framebuffer
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferAColorTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, framebufferADepthTexture, 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
//glReadBuffer(GL_COLOR_ATTACHMENT0);
// Unbind framebuffer and texture
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Setup render target
framebufferARenderTarget.width = static_cast<int>(resolution.x);
framebufferARenderTarget.height = static_cast<int>(resolution.y);
framebufferARenderTarget.framebuffer = framebufferA;
}
{
// Generate color texture
glGenTextures(1, &framebufferBColorTexture);
glBindTexture(GL_TEXTURE_2D, framebufferBColorTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, static_cast<GLsizei>(resolution.x), static_cast<GLsizei>(resolution.y), 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Generate framebuffer
glGenFramebuffers(1, &framebufferA);
glBindFramebuffer(GL_FRAMEBUFFER, framebufferA);
// Attach textures to framebuffer
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferBColorTexture, 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
//glReadBuffer(GL_COLOR_ATTACHMENT0);
// Unbind framebuffer and texture
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Setup render target
framebufferBRenderTarget.width = static_cast<int>(resolution.x);
framebufferBRenderTarget.height = static_cast<int>(resolution.y);
framebufferBRenderTarget.framebuffer = framebufferA;
}
// Setup skybox pass
skyboxPass.setRenderTarget(&defaultRenderTarget);
skyboxPass.setRenderTarget(&framebufferARenderTarget);
// Setup clear depth pass
clearDepthPass.setRenderTarget(&defaultRenderTarget);
clearDepthPass.setRenderTarget(&framebufferARenderTarget);
clearDepthPass.setClear(false, true, false);
clearDepthPass.setClearDepth(1.0f);
// Setup soil pass
soilPass.setRenderTarget(&defaultRenderTarget);
soilPass.setRenderTarget(&framebufferARenderTarget);
// Setup lighting pass
lightingPass.setRenderTarget(&defaultRenderTarget);
lightingPass.setRenderTarget(&framebufferARenderTarget);
lightingPass.setShadowMap(shadowMapDepthTexture);
lightingPass.setShadowCamera(&sunlightCamera);
lightingPass.setShadowMapPass(&shadowMapPass);
// Setup blur passes
horizontalBlurPass.setRenderTarget(&framebufferBRenderTarget);
horizontalBlurPass.setTexture(framebufferAColorTexture);
horizontalBlurPass.setDirection(Vector2(0.0f, 0.0f));
verticalBlurPass.setRenderTarget(&framebufferARenderTarget);
verticalBlurPass.setTexture(framebufferBColorTexture);
verticalBlurPass.setDirection(Vector2(0.0f, 0.0f));
horizontalBlurPass2.setRenderTarget(&framebufferBRenderTarget);
horizontalBlurPass2.setTexture(framebufferAColorTexture);
horizontalBlurPass2.setDirection(Vector2(0.0f, 0.0f));
verticalBlurPass2.setRenderTarget(&defaultRenderTarget);
verticalBlurPass2.setTexture(framebufferBColorTexture);
verticalBlurPass2.setDirection(Vector2(0.0f, 0.0f));
// Setup debug pass
debugPass.setRenderTarget(&defaultRenderTarget);
@ -812,6 +898,10 @@ bool Application::loadScene()
defaultCompositor.addPass(&skyboxPass);
defaultCompositor.addPass(&soilPass);
defaultCompositor.addPass(&lightingPass);
defaultCompositor.addPass(&horizontalBlurPass);
defaultCompositor.addPass(&verticalBlurPass);
defaultCompositor.addPass(&horizontalBlurPass2);
defaultCompositor.addPass(&verticalBlurPass2);
//defaultCompositor.addPass(&debugPass);
defaultCompositor.load(nullptr);
@ -959,10 +1049,17 @@ bool Application::loadUI()
// Create "Press any key" element
anyKeyLabel = new UILabel();
anyKeyLabel->setLayerOffset(ANTKEEPER_UI_LAYER_MENU);
anyKeyLabel->setVisible(false);
uiRootElement->addChild(anyKeyLabel);
// Create copyright element
copyrightLabel = new UILabel();
copyrightLabel->setLayerOffset(ANTKEEPER_UI_LAYER_MENU);
copyrightLabel->setVisible(false);
copyrightLabel->setTintColor(Vector4(1.0f, 1.0f, 1.0f, 0.15f));
uiRootElement->addChild(copyrightLabel);
rectangularPaletteImage = new UIImage();
rectangularPaletteImage->setTexture(rectangularPaletteTexture);
rectangularPaletteImage->setVisible(false);
@ -1017,13 +1114,52 @@ bool Application::loadUI()
pieMenu->getContainer()->setActive(true);
// Setup screen fade in/fade out tween
fadeInTween = new Tween<Vector4>(EaseFunction::IN_CUBIC, 0.0f, 2.0f, Vector4(0.0f, 0.0f, 0.0f, 1.0f), Vector4(0.0f, 0.0f, 0.0f, -1.0f));
fadeInTween = new Tween<Vector4>(EaseFunction::IN_QUINT, 0.0f, 2.0f, Vector4(0.0f, 0.0f, 0.0f, 1.0f), Vector4(0.0f, 0.0f, 0.0f, -1.0f));
fadeInTween->setUpdateCallback(std::bind(&UIElement::setTintColor, blackoutImage, std::placeholders::_1));
tweener->addTween(fadeInTween);
fadeOutTween = new Tween<Vector4>(EaseFunction::OUT_CUBIC, 0.0f, 2.0f, Vector4(0.0f, 0.0f, 0.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
fadeOutTween = new Tween<Vector4>(EaseFunction::OUT_QUINT, 0.0f, 2.0f, Vector4(0.0f, 0.0f, 0.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
fadeOutTween->setUpdateCallback(std::bind(&UIElement::setTintColor, blackoutImage, std::placeholders::_1));
tweener->addTween(fadeOutTween);
// Setup darken fade in/fade out tweens
darkenFadeInTween = new Tween<Vector4>(EaseFunction::OUT_CUBIC, 0.0f, 0.15f, Vector4(0.0f, 0.0f, 0.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 0.4f));
darkenFadeInTween->setStartCallback(std::bind(&UIElement::setVisible, darkenImage, true));
darkenFadeInTween->setUpdateCallback(std::bind(&UIElement::setTintColor, darkenImage, std::placeholders::_1));
tweener->addTween(darkenFadeInTween);
darkenFadeOutTween = new Tween<Vector4>(EaseFunction::OUT_CUBIC, 0.0f, 0.15f, Vector4(0.0f, 0.0f, 0.0f, 0.4f), Vector4(0.0f, 0.0f, 0.0f, -0.4f));
darkenFadeOutTween->setUpdateCallback(std::bind(&UIElement::setTintColor, darkenImage, std::placeholders::_1));
darkenFadeOutTween->setEndCallback(std::bind(&UIElement::setVisible, darkenImage, false));
tweener->addTween(darkenFadeOutTween);
// Setup blur fade in/fade out tweens
blurFadeInTween = new Tween<float>(EaseFunction::OUT_CUBIC, 0.0f, 0.15f, 0.0f, 1.0f);
blurFadeInTween->setUpdateCallback
(
[this](float t)
{
float factor = blurFadeInTween->getTweenValue();
horizontalBlurPass.setDirection(Vector2(1.0f, 0.0f) * t);
horizontalBlurPass2.setDirection(Vector2(3.0f, 0.0f) * t);
verticalBlurPass.setDirection(Vector2(0.0f, 1.0f) * t);
verticalBlurPass2.setDirection(Vector2(0.0f, 3.0f) * t);
}
);
tweener->addTween(blurFadeInTween);
blurFadeOutTween = new Tween<float>(EaseFunction::OUT_CUBIC, 0.0f, 0.15f, 1.0f, -1.0f);
blurFadeOutTween->setUpdateCallback
(
[this](float t)
{
float factor = blurFadeInTween->getTweenValue();
horizontalBlurPass.setDirection(Vector2(1.0f, 0.0f) * t);
horizontalBlurPass2.setDirection(Vector2(3.0f, 0.0f) * t);
verticalBlurPass.setDirection(Vector2(0.0f, 1.0f) * t);
verticalBlurPass2.setDirection(Vector2(0.0f, 3.0f) * t);
}
);
tweener->addTween(blurFadeOutTween);
// Setup splash screen tween
splashFadeInTween = new Tween<Vector4>(EaseFunction::IN_CUBIC, 0.0f, 0.5f, Vector4(1.0f, 1.0f, 1.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 1.0f));
splashFadeInTween->setUpdateCallback(std::bind(&UIElement::setTintColor, splashImage, std::placeholders::_1));
@ -1097,6 +1233,9 @@ bool Application::loadUI()
mainMenu->getUIContainer()->setAnchor(Vector2(0.5f, 0.8f));
mainMenu->getUIContainer()->setLayerOffset(ANTKEEPER_UI_LAYER_MENU);
mainMenu->setLineSpacing(1.0f);
mainMenu->getUIContainer()->setActive(false);
mainMenu->getUIContainer()->setVisible(false);
uiRootElement->addChild(mainMenu->getUIContainer());
mainMenuContinueItem = mainMenu->addItem();
mainMenuContinueItem->setActivatedCallback(std::bind(&Application::continueGame, this));
@ -1122,10 +1261,6 @@ bool Application::loadUI()
mainMenuExitItem = mainMenu->addItem();
mainMenuExitItem->setActivatedCallback(std::bind(&Application::close, this, EXIT_SUCCESS));
mainMenu->getUIContainer()->setActive(false);
mainMenu->getUIContainer()->setVisible(false);
uiRootElement->addChild(mainMenu->getUIContainer());
}
// Levels menu
@ -1454,6 +1589,7 @@ bool Application::loadGame()
lens = new Lens(lensModel);
lens->setCameraController(surfaceCam);
lens->setSunDirection(glm::normalize(-sunlightCamera.getTranslation()));
brush = new Brush(brushModel);
brush->setCameraController(surfaceCam);
@ -1487,6 +1623,10 @@ void Application::resizeUI()
frameTimeLabel->setTranslation(Vector2(0.0f));
anyKeyLabel->setAnchor(Vector2(0.5f, 1.0f));
anyKeyLabel->setTranslation(Vector2(0.0f, (int)(-resolution.y * (1.0f / 4.0f) - menuFont->getMetrics().getHeight() * 0.5f)));
copyrightLabel->setAnchor(Vector2(0.0f, 1.0f));
copyrightLabel->setTranslation(Vector2(resolution.x, -resolution.y) * 0.02f);
rectangularPaletteImage->setAnchor(Vector2(0.0f, 1.0f));
rectangularPaletteImage->setDimensions(Vector2(rectangularPaletteTexture->getWidth(), rectangularPaletteTexture->getHeight()));
rectangularPaletteImage->setTranslation(Vector2(16.0f, -16.0f));
@ -1581,6 +1721,7 @@ void Application::restringUI()
levelNameLabel->setFont(levelNameFont);
frameTimeLabel->setFont(copyrightFont);
anyKeyLabel->setFont(menuFont);
copyrightLabel->setFont(copyrightFont);
mainMenu->setFont(menuFont);
levelsMenu->setFont(menuFont);
optionsMenu->setFont(menuFont);
@ -1589,6 +1730,7 @@ void Application::restringUI()
// Title screen
anyKeyLabel->setText(stringMap["press-any-key"]);
copyrightLabel->setText(stringMap["copyright"]);
// Main menu
mainMenuContinueItem->setName(stringMap["continue"]);
@ -1921,7 +2063,13 @@ void Application::pauseSimulation()
{
simulationPaused = true;
darkenImage->setVisible(true);
darkenFadeOutTween->stop();
darkenFadeInTween->reset();
darkenFadeInTween->start();
blurFadeOutTween->stop();
blurFadeInTween->reset();
blurFadeInTween->start();
openMenu(pauseMenu);
pauseMenu->select(0);
@ -1931,7 +2079,13 @@ void Application::unpauseSimulation()
{
simulationPaused = false;
darkenImage->setVisible(false);
darkenFadeInTween->stop();
darkenFadeOutTween->reset();
darkenFadeOutTween->start();
blurFadeInTween->stop();
blurFadeOutTween->reset();
blurFadeOutTween->start();
closeMenu();
}

+ 22
- 2
src/application.hpp View File

@ -178,6 +178,16 @@ public:
ShadowMapRenderPass shadowMapPass;
Compositor shadowMapCompositor;
GLuint framebufferAColorTexture;
GLuint framebufferADepthTexture;
GLuint framebufferA;
RenderTarget framebufferARenderTarget;
GLuint framebufferBColorTexture;
GLuint framebufferBDepthTexture;
GLuint framebufferB;
RenderTarget framebufferBRenderTarget;
ClearRenderPass clearDepthPass;
SoilRenderPass soilPass;
LightingRenderPass lightingPass;
@ -194,6 +204,10 @@ public:
TextureLoader* textureLoader;
MaterialLoader* materialLoader;
ModelLoader* modelLoader;
BlurRenderPass horizontalBlurPass;
BlurRenderPass verticalBlurPass;
BlurRenderPass horizontalBlurPass2;
BlurRenderPass verticalBlurPass2;
// Controls
Control* bindingControl;
@ -277,7 +291,8 @@ public:
UIImage* titleImage;
UIImage* darkenImage;
UILabel* frameTimeLabel;
UILabel* anyKeyLabel;
UILabel* anyKeyLabel;
UILabel* copyrightLabel;
UIImage* rectangularPaletteImage;
UIImage* foodIndicatorImage;
UIImage* contextButtonImage0;
@ -291,9 +306,13 @@ public:
Tweener* tweener;
Tween<Vector4>* fadeInTween;
Tween<Vector4>* fadeOutTween;
Tween<Vector4>* darkenFadeInTween;
Tween<Vector4>* darkenFadeOutTween;
Tween<float>* blurFadeInTween;
Tween<float>* blurFadeOutTween;
Tween<Vector4>* splashFadeInTween;
Tween<float>* splashHangTween;
Tween<Vector4>* splashFadeOutTween;
Tween<float>* splashHangTween;
Tween<Vector4>* titleFadeInTween;
Tween<Vector4>* titleFadeOutTween;
Tween<Vector4>* anyKeyFadeInTween;
@ -303,6 +322,7 @@ public:
Tween<float>* menuActivateTween;
Tween<Vector3>* cameraTranslationTween;
Tween<float>* forcepsSwoopTween;
// Menus
Menu* activeMenu;

+ 150
- 7
src/game/tool.cpp View File

@ -349,11 +349,36 @@ Lens::Lens(const Model* model)
// Setup model instance
modelInstance.setModel(model);
hoverDistance = 12.0f;
unfocusedDistance = 15.0f;
focusedDistance = 12.0f;
focused = false;
sunDirection = Vector3(0, -1, 0);
// Setup timing
float descentDuration = 0.75f;
float ascentDuration = 0.25f;
// Allocate tweener and and setup tweens
tweener = new Tweener();
descentTween = new Tween<float>(EaseFunction::OUT_CUBIC, 0.0f, descentDuration, unfocusedDistance, focusedDistance - unfocusedDistance);
ascentTween = new Tween<float>(EaseFunction::OUT_CUBIC, 0.0f, ascentDuration, focusedDistance, unfocusedDistance - focusedDistance);
descentTween->setEndCallback
(
[this](float t)
{
focused = true;
}
);
tweener->addTween(descentTween);
tweener->addTween(ascentTween);
}
Lens::~Lens()
{}
{
delete descentTween;
delete ascentTween;
delete tweener;
}
void Lens::update(float dt)
{
@ -375,14 +400,48 @@ void Lens::update(float dt)
*/
modelInstance.setActive(active);
Quaternion alignment = glm::angleAxis(cameraController->getAzimuth() + glm::radians(90.0f), Vector3(0, 1, 0));
// Update tweener
tweener->update(dt);
float lensDistance = (focused) ? focusedDistance : unfocusedDistance;
if (!ascentTween->isStopped())
{
lensDistance = ascentTween->getTweenValue();
}
else if (!descentTween->isStopped())
{
lensDistance = descentTween->getTweenValue();
}
//Quaternion alignment = glm::angleAxis(cameraController->getAzimuth() + glm::radians(90.0f), Vector3(0, 1, 0));
Quaternion alignment = glm::rotation(Vector3(0, 1, 0), -sunDirection) * glm::angleAxis(glm::radians(90.0f), Vector3(0, 1, 0));
Quaternion rotation = glm::normalize(alignment);
Vector3 translation = pick + Vector3(0, hoverDistance, 0);
Vector3 translation = pick + sunDirection * -lensDistance;
modelInstance.setTranslation(translation);
modelInstance.setRotation(rotation);
}
void Lens::focus()
{
ascentTween->stop();
descentTween->reset();
descentTween->start();
}
void Lens::unfocus()
{
descentTween->stop();
focused = false;
ascentTween->reset();
ascentTween->start();
}
void Lens::setSunDirection(const Vector3& direction)
{
sunDirection = direction;
}
Brush::Brush(const Model* model)
{
// Allocate pose and initialize to bind pose
@ -394,22 +453,106 @@ Brush::Brush(const Model* model)
modelInstance.setModel(model);
modelInstance.setPose(pose);
hoverDistance = 0.0f;
hoverDistance = 0.5f;
// Setup timing
float descentDuration = 0.1f;
float ascentDuration = 0.1f;
// Allocate tweener and and setup tweens
tweener = new Tweener();
descentTween = new Tween<float>(EaseFunction::OUT_CUBIC, 0.0f, descentDuration, hoverDistance, -hoverDistance);
ascentTween = new Tween<float>(EaseFunction::OUT_CUBIC, 0.0f, ascentDuration, 0.0f, hoverDistance);
descentTween->setEndCallback
(
[this](float t)
{
descended = true;
}
);
tweener->addTween(descentTween);
tweener->addTween(ascentTween);
descended = false;
oldPick = pick;
tiltAngle = 0.0f;
targetTiltAngle = 0.0f;
tiltAxis = Vector3(1.0f, 0.0f, 0.0f);
targetTiltAxis = tiltAxis;
}
Brush::~Brush()
{
delete pose;
delete descentTween;
delete ascentTween;
delete tweener;
}
void Brush::update(float dt)
{
modelInstance.setActive(active);
// Update tweener
tweener->update(dt);
float brushDistance = (descended) ? 0.0f : hoverDistance;
if (!ascentTween->isStopped())
{
brushDistance = ascentTween->getTweenValue();
}
else if (!descentTween->isStopped())
{
brushDistance = descentTween->getTweenValue();
}
targetTiltAngle = 0.0f;
if (descended)
{
Vector3 difference = pick - oldPick;
float distanceSquared = glm::dot(difference, difference);
if (distanceSquared > 0.005f)
{
float maxDistance = 0.25f;
float maxTiltAngle = glm::radians(45.0f);
float distance = std::sqrt(distanceSquared);
float tiltFactor = std::min<float>(maxDistance, distance) / maxDistance;
targetTiltAngle = maxTiltAngle * tiltFactor;
targetTiltAxis = glm::normalize(Vector3(difference.z, 0.0f, -difference.x));
}
}
float angleInterpolationFactor = 0.1f / (1.0 / 60.0f) * dt;
float axisInterpolationFactor = 0.2f / (1.0 / 60.0f) * dt;
tiltAngle = glm::mix(tiltAngle, targetTiltAngle, angleInterpolationFactor);
tiltAxis = glm::mix(tiltAxis, targetTiltAxis, axisInterpolationFactor);
Quaternion tilt = glm::angleAxis(tiltAngle, tiltAxis);
Quaternion alignment = glm::angleAxis(cameraController->getAzimuth(), Vector3(0, 1, 0));
Quaternion rotation = glm::normalize(alignment);
Vector3 translation = pick + Vector3(0, hoverDistance, 0);
Quaternion rotation = glm::normalize(tilt);
Vector3 translation = pick + Vector3(0, brushDistance, 0);
modelInstance.setTranslation(translation);
modelInstance.setRotation(rotation);
oldPick = pick;
}
void Brush::press()
{
ascentTween->stop();
descentTween->reset();
descentTween->start();
}
void Brush::release()
{
descentTween->stop();
descended = false;
ascentTween->reset();
ascentTween->start();
}

+ 25
- 1
src/game/tool.hpp View File

@ -223,8 +223,19 @@ public:
*/
virtual void update(float dt);
void focus();
void unfocus();
void setSunDirection(const Vector3& direction);
private:
float hoverDistance;
float unfocusedDistance;
float focusedDistance;
bool focused;
Vector3 sunDirection;
Tweener* tweener;
Tween<float>* descentTween;
Tween<float>* ascentTween;
};
/**
@ -238,9 +249,22 @@ public:
virtual void update(float dt);
void press();
void release();
private:
Pose* pose;
float hoverDistance;
bool descended;
Vector3 oldPick;
Tweener* tweener;
Tween<float>* descentTween;
Tween<float>* ascentTween;
float tiltAngle;
float targetTiltAngle;
Vector3 tiltAxis;
Vector3 targetTiltAxis;
};
#endif // TOOL_HPP

+ 102
- 3
src/render-passes.cpp View File

@ -87,6 +87,105 @@ void ClearRenderPass::setClearStencil(int index)
this->index = index;
}
BlurRenderPass::BlurRenderPass():
textureID(0)
{
textureParam = parameterSet.addParameter("blurTexture", ShaderParameter::Type::INT, 1);
resolutionParam = parameterSet.addParameter("resolution", ShaderParameter::Type::VECTOR_2, 1);
directionParam = parameterSet.addParameter("direction", ShaderParameter::Type::VECTOR_2, 1);
}
bool BlurRenderPass::load(const RenderContext* renderContext)
{
// Load shader
shaderLoader.undefine();
shaderLoader.define("VERTEX_POSITION", EMERGENT_VERTEX_POSITION);
shader = shaderLoader.load("data/shaders/blur.glsl", &parameterSet);
if (!shader)
{
return false;
}
const float quadVertexData[] =
{
-1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f
};
const std::uint32_t quadIndexData[] =
{
0, 1, 3,
3, 1, 2
};
quadVertexCount = 4;
quadIndexCount = 6;
// Create AABB geometry
glGenVertexArrays(1, &quadVAO);
glBindVertexArray(quadVAO);
glGenBuffers(1, &quadVBO);
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * quadVertexCount, quadVertexData, GL_STATIC_DRAW);
glEnableVertexAttribArray(EMERGENT_VERTEX_POSITION);
glVertexAttribPointer(EMERGENT_VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (char*)0 + 0*sizeof(float));
glGenBuffers(1, &quadIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadIBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(std::uint32_t) * quadIndexCount, quadIndexData, GL_STATIC_DRAW);
return true;
}
void BlurRenderPass::unload()
{
delete shader;
shader = nullptr;
glDeleteBuffers(1, &quadIBO);
glDeleteBuffers(1, &quadVBO);
glDeleteVertexArrays(1, &quadVAO);
parameterSet.removeParameters();
}
void BlurRenderPass::render(RenderContext* renderContext)
{
// Bind framebuffer and setup viewport
glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
glViewport(0, 0, renderTarget->width, renderTarget->height);
// Clear the framebuffer
glClear(GL_COLOR_BUFFER_BIT);
// Disable depth testing
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
// Disable culling
glDisable(GL_CULL_FACE);
// Bind shader
shader->bind();
// Bind texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID);
// Pass texture unit to shader
shader->setParameter(textureParam, 0);
shader->setParameter(resolutionParam, Vector2(renderTarget->width, renderTarget->height));
shader->setParameter(directionParam, direction);
// Render quad
glBindVertexArray(quadVAO);
glDrawElementsBaseVertex(GL_TRIANGLES, quadIndexCount, GL_UNSIGNED_INT, (void*)0, 0);
// Unbind texture
glBindTexture(GL_TEXTURE_2D, 0);
}
ShadowMapRenderPass::ShadowMapRenderPass():
unskinnedShader(nullptr),
skinnedShader(nullptr),
@ -197,14 +296,14 @@ void ShadowMapRenderPass::render(RenderContext* renderContext)
glBindFramebuffer(GL_FRAMEBUFFER, renderTarget->framebuffer);
glViewport(0, 0, renderTarget->width, renderTarget->height);
// Clear the framebuffer depth
glClear(GL_DEPTH_BUFFER_BIT);
// Enable depth testing
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LESS);
// Clear the framebuffer depth
glClear(GL_DEPTH_BUFFER_BIT);
// Draw front and back faces
glDisable(GL_CULL_FACE);

+ 32
- 0
src/render-passes.hpp View File

@ -51,6 +51,38 @@ private:
int index;
};
/**
* Blurs a texture
*/
class BlurRenderPass: public RenderPass
{
public:
BlurRenderPass();
virtual bool load(const RenderContext* renderContext);
virtual void unload();
virtual void render(RenderContext* renderContext);
inline void setTexture(GLuint textureID) { this->textureID = textureID; }
inline void setDirection(Vector2 direction) { this->direction = direction; }
private:
ShaderParameterSet parameterSet;
const ShaderParameter* textureParam;
const ShaderParameter* resolutionParam;
const ShaderParameter* directionParam;
ShaderLoader shaderLoader;
Shader* shader;
GLuint textureID;
Vector2 direction;
int quadVertexCount;
int quadIndexCount;
GLuint quadVAO;
GLuint quadVBO;
GLuint quadIBO;
};
/**
* Renders the distance from the view frustum's near clipping plane to scene geometry. The render target should have a depth only framebuffer.
*/

+ 66
- 44
src/states/game-state.cpp View File

@ -75,7 +75,7 @@ void GameState::enter()
// Spawn ants
Navmesh* navmesh = application->currentLevel->terrain.getSurfaceNavmesh();
for (int i = 0; i < 50; ++i)
for (int i = 0; i < 200; ++i)
{
Navmesh::Triangle* triangle = (*navmesh->getTriangles())[0];
@ -250,51 +250,50 @@ void GameState::execute()
application->surfaceCam->update(application->dt);
// Picking
glm::ivec2 mousePosition = application->mouse->getCurrentPosition();
mousePosition.y = application->resolution.y - mousePosition.y;
Vector4 viewport(0.0f, 0.0f, application->resolution.x, application->resolution.y);
Vector3 mouseNear = application->camera.unproject(Vector3(mousePosition.x, mousePosition.y, 0.0f), viewport);
Vector3 mouseFar = application->camera.unproject(Vector3(mousePosition.x, mousePosition.y, 1.0f), viewport);
pickingRay.origin = mouseNear;
pickingRay.direction = glm::normalize(mouseFar - mouseNear);
std::list<Navmesh::Triangle*> triangles;
application->currentLevel->terrain.getSurfaceOctree()->query(pickingRay, &triangles);
auto result = intersects(pickingRay, triangles);
if (std::get<0>(result))
if (!application->simulationPaused)
{
pick = pickingRay.extrapolate(std::get<1>(result));
glm::ivec2 mousePosition = application->mouse->getCurrentPosition();
mousePosition.y = application->resolution.y - mousePosition.y;
Vector4 viewport(0.0f, 0.0f, application->resolution.x, application->resolution.y);
Vector3 mouseNear = application->camera.unproject(Vector3(mousePosition.x, mousePosition.y, 0.0f), viewport);
Vector3 mouseFar = application->camera.unproject(Vector3(mousePosition.x, mousePosition.y, 1.0f), viewport);
std::size_t triangleIndex = std::get<3>(result);
pickTriangle = (*application->currentLevel->terrain.getSurfaceNavmesh()->getTriangles())[triangleIndex];
pickingRay.origin = mouseNear;
pickingRay.direction = glm::normalize(mouseFar - mouseNear);
/*
float forcepsDistance = application->forcepsSwoopTween->getTweenValue();
std::list<Navmesh::Triangle*> triangles;
application->currentLevel->terrain.getSurfaceOctree()->query(pickingRay, &triangles);
//Quaternion rotation = glm::rotation(Vector3(0, 1, 0), triangle->normal);
Quaternion rotation = glm::angleAxis(application->surfaceCam->getAzimuth(), Vector3(0, 1, 0)) *
glm::angleAxis(glm::radians(15.0f), Vector3(0, 0, -1));
auto result = intersects(pickingRay, triangles);
if (std::get<0>(result))
{
pick = pickingRay.extrapolate(std::get<1>(result));
std::size_t triangleIndex = std::get<3>(result);
pickTriangle = (*application->currentLevel->terrain.getSurfaceNavmesh()->getTriangles())[triangleIndex];
/*
float forcepsDistance = application->forcepsSwoopTween->getTweenValue();
//Quaternion rotation = glm::rotation(Vector3(0, 1, 0), triangle->normal);
Quaternion rotation = glm::angleAxis(application->surfaceCam->getAzimuth(), Vector3(0, 1, 0)) *
glm::angleAxis(glm::radians(15.0f), Vector3(0, 0, -1));
Vector3 translation = pick + rotation * Vector3(0, forcepsDistance, 0);
// Set tool position
application->forcepsModelInstance.setTranslation(translation);
application->forcepsModelInstance.setRotation(rotation);
*/
}
Vector3 translation = pick + rotation * Vector3(0, forcepsDistance, 0);
// Update tools
if (application->currentTool != nullptr)
{
application->currentTool->setPick(pick);
application->currentTool->update(application->dt);
}
// Set tool position
application->forcepsModelInstance.setTranslation(translation);
application->forcepsModelInstance.setRotation(rotation);
*/
}
// Update tools
if (application->currentTool != nullptr)
{
application->currentTool->setPick(pick);
application->currentTool->update(application->dt);
}
// Update colony
if (!application->simulationPaused)
{
application->colony->update(application->dt);
}
}
@ -329,16 +328,39 @@ void GameState::exit()
void GameState::mouseButtonPressed(int button, int x, int y)
{
if (button == 1 && application->forceps->isActive())
if (button == 1)
{
application->forceps->pinch();
if (application->forceps->isActive())
{
application->forceps->pinch();
}
else if (application->brush->isActive())
{
application->brush->press();
}
else if (application->lens->isActive())
{
application->lens->focus();
}
}
}
void GameState::mouseButtonReleased(int button, int x, int y)
{
if (button == 1 && application->forceps->isActive())
if (button == 1)
{
application->forceps->release();
if (application->forceps->isActive())
{
application->forceps->release();
}
else if (application->brush->isActive())
{
application->brush->release();
}
else if (application->lens->isActive())
{
application->lens->unfocus();
}
}
}

+ 60
- 37
src/states/title-state.cpp View File

@ -40,7 +40,7 @@ void TitleState::enter()
windowResized(application->resolution.x, application->resolution.y);
application->camera.setPerspective(
glm::radians(25.0f),
glm::radians(30.0f),
application->resolution.x / application->resolution.y,
0.1f,
1000.0f);
@ -63,9 +63,13 @@ void TitleState::enter()
// Show title
application->titleImage->setVisible(true);
application->titleImage->setTintColor(Vector4(1.0f));
application->copyrightLabel->setVisible(true);
// Open main menu
application->openMenu(application->mainMenu);
// Show "Press any key"
application->anyKeyLabel->setVisible(true);
application->anyKeyLabel->setActive(true);
application->anyKeyFadeInTween->reset();
application->anyKeyFadeInTween->start();
// Position options menu
application->optionsMenu->getUIContainer()->setAnchor(Vector2(0.5f, 0.8f));
@ -79,60 +83,79 @@ void TitleState::enter()
void TitleState::execute()
{
// Navigate menu
if (application->activeMenu != nullptr)
if (application->anyKeyLabel->isActive())
{
MenuItem* selectedItem = application->activeMenu->getSelectedItem();
InputEvent event;
application->inputManager->listen(&event);
if (application->menuDown.isTriggered() && !application->menuDown.wasTriggered())
if (event.type != InputEvent::Type::NONE)
{
application->anyKeyLabel->setVisible(false);
application->anyKeyLabel->setActive(false);
application->anyKeyFadeInTween->stop();
application->anyKeyFadeOutTween->stop();
application->inputManager->update();
application->openMenu(application->mainMenu);
}
}
else
{
// Navigate menu
if (application->activeMenu != nullptr)
{
if (selectedItem != nullptr)
MenuItem* selectedItem = application->activeMenu->getSelectedItem();
if (application->menuDown.isTriggered() && !application->menuDown.wasTriggered())
{
if (selectedItem->getItemIndex() < application->activeMenu->getItemCount() - 1)
if (selectedItem != nullptr)
{
application->selectMenuItem(selectedItem->getItemIndex() + 1);
if (selectedItem->getItemIndex() < application->activeMenu->getItemCount() - 1)
{
application->selectMenuItem(selectedItem->getItemIndex() + 1);
}
else
{
application->selectMenuItem(0);
}
}
else
{
application->selectMenuItem(0);
}
}
else
else if (application->menuUp.isTriggered() && !application->menuUp.wasTriggered())
{
application->selectMenuItem(0);
}
}
else if (application->menuUp.isTriggered() && !application->menuUp.wasTriggered())
{
if (selectedItem != nullptr)
{
if (selectedItem->getItemIndex() > 0)
if (selectedItem != nullptr)
{
application->selectMenuItem(selectedItem->getItemIndex() - 1);
if (selectedItem->getItemIndex() > 0)
{
application->selectMenuItem(selectedItem->getItemIndex() - 1);
}
else
{
application->selectMenuItem(application->activeMenu->getItemCount() - 1);
}
}
else
{
application->selectMenuItem(application->activeMenu->getItemCount() - 1);
}
}
else
if (application->menuLeft.isTriggered() && !application->menuLeft.wasTriggered())
{
application->selectMenuItem(application->activeMenu->getItemCount() - 1);
application->decrementMenuItem();
}
else if (application->menuRight.isTriggered() && !application->menuRight.wasTriggered())
{
application->incrementMenuItem();
}
if (application->menuSelect.isTriggered() && !application->menuSelect.wasTriggered())
{
application->activateMenuItem();
}
}
if (application->menuLeft.isTriggered() && !application->menuLeft.wasTriggered())
{
application->decrementMenuItem();
}
else if (application->menuRight.isTriggered() && !application->menuRight.wasTriggered())
{
application->incrementMenuItem();
}
if (application->menuSelect.isTriggered() && !application->menuSelect.wasTriggered())
{
application->activateMenuItem();
}
}
@ -159,9 +182,9 @@ void TitleState::exit()
// Hide UI
application->titleImage->setVisible(false);
application->copyrightLabel->setVisible(false);
application->anyKeyLabel->setVisible(false);
application->darkenImage->setVisible(false);
// Remove clear scene
application->backgroundLayer->removeObject(&application->bgCamera);

Loading…
Cancel
Save