Merge pull request #5885 from ZappoMan/batchOptimizations

Batch optimizations
This commit is contained in:
samcake 2015-09-23 19:30:51 -07:00
commit 46e9c463fc
14 changed files with 733 additions and 697 deletions

View file

@ -1035,13 +1035,6 @@ void Application::initializeUi() {
updateInputModes();
}
template<typename F>
void doInBatch(RenderArgs* args, F f) {
gpu::Batch batch;
f(batch);
args->_context->render(batch);
}
void Application::paintGL() {
PROFILE_RANGE(__FUNCTION__);
if (nullptr == _displayPlugin) {
@ -1095,12 +1088,12 @@ void Application::paintGL() {
auto mirrorRectDest = glm::ivec4(mirrorRect.z, mirrorRect.y, mirrorRect.x, mirrorRect.w);
auto selfieFbo = DependencyManager::get<FramebufferCache>()->getSelfieFramebuffer();
gpu::Batch batch;
batch.setFramebuffer(selfieFbo);
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f));
batch.blit(primaryFbo, mirrorRect, selfieFbo, mirrorRectDest);
batch.setFramebuffer(nullptr);
renderArgs._context->render(batch);
doInBatch(renderArgs._context, [=](gpu::Batch& batch) {
batch.setFramebuffer(selfieFbo);
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f));
batch.blit(primaryFbo, mirrorRect, selfieFbo, mirrorRectDest);
batch.setFramebuffer(nullptr);
});
}
}
@ -1224,7 +1217,7 @@ void Application::paintGL() {
}
displaySide(&renderArgs, _myCamera);
renderArgs._context->enableStereo(false);
doInBatch(&renderArgs, [](gpu::Batch& batch) {
doInBatch(renderArgs._context, [](gpu::Batch& batch) {
batch.setFramebuffer(nullptr);
});
}
@ -1288,9 +1281,9 @@ void Application::paintGL() {
// Reset the gpu::Context Stages
// Back to the default framebuffer;
gpu::Batch batch;
batch.resetStages();
renderArgs._context->render(batch);
doInBatch(renderArgs._context, [=](gpu::Batch& batch) {
batch.resetStages();
});
}
void Application::runTests() {

View file

@ -207,36 +207,36 @@ void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) {
updateTooltips();
//Handle fading and deactivation/activation of UI
gpu::Batch batch;
doInBatch(renderArgs->_context, [=](gpu::Batch& batch) {
auto geometryCache = DependencyManager::get<GeometryCache>();
auto geometryCache = DependencyManager::get<GeometryCache>();
geometryCache->useSimpleDrawPipeline(batch);
batch.setViewportTransform(renderArgs->_viewport);
batch.setModelTransform(Transform());
batch.setViewTransform(Transform());
batch.setProjectionTransform(mat4());
batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0));
geometryCache->renderUnitQuad(batch, vec4(vec3(1), _alpha));
geometryCache->useSimpleDrawPipeline(batch);
batch.setViewportTransform(renderArgs->_viewport);
batch.setModelTransform(Transform());
batch.setViewTransform(Transform());
batch.setProjectionTransform(mat4());
batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0));
geometryCache->renderUnitQuad(batch, vec4(vec3(1), _alpha));
// Doesn't actually render
renderPointers(batch);
// Doesn't actually render
renderPointers(batch);
//draw the mouse pointer
// Get the mouse coordinates and convert to NDC [-1, 1]
vec2 canvasSize = qApp->getCanvasSize();
vec2 mousePosition = toNormalizedDeviceScale(vec2(qApp->getMouse()), canvasSize);
// Invert the Y axis
mousePosition.y *= -1.0f;
//draw the mouse pointer
// Get the mouse coordinates and convert to NDC [-1, 1]
vec2 canvasSize = qApp->getCanvasSize();
vec2 mousePosition = toNormalizedDeviceScale(vec2(qApp->getMouse()), canvasSize);
// Invert the Y axis
mousePosition.y *= -1.0f;
Transform model;
model.setTranslation(vec3(mousePosition, 0));
vec2 mouseSize = CURSOR_PIXEL_SIZE / canvasSize;
model.setScale(vec3(mouseSize, 1.0f));
batch.setModelTransform(model);
bindCursorTexture(batch);
geometryCache->renderUnitQuad(batch, vec4(1));
renderArgs->_context->render(batch);
Transform model;
model.setTranslation(vec3(mousePosition, 0));
vec2 mouseSize = CURSOR_PIXEL_SIZE / canvasSize;
model.setScale(vec3(mouseSize, 1.0f));
batch.setModelTransform(model);
bindCursorTexture(batch);
geometryCache->renderUnitQuad(batch, vec4(1));
});
}
@ -278,75 +278,67 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
auto geometryCache = DependencyManager::get<GeometryCache>();
gpu::Batch batch;
geometryCache->useSimpleDrawPipeline(batch);
//batch._glDisable(GL_DEPTH_TEST);
//batch._glDisable(GL_CULL_FACE);
//batch._glBindTexture(GL_TEXTURE_2D, texture);
//batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
doInBatch(renderArgs->_context, [=](gpu::Batch& batch) {
geometryCache->useSimpleDrawPipeline(batch);
batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0));
batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0));
mat4 camMat;
_cameraBaseTransform.getMatrix(camMat);
camMat = camMat * qApp->getEyePose(eye);
batch.setViewportTransform(renderArgs->_viewport);
batch.setViewTransform(camMat);
mat4 camMat;
_cameraBaseTransform.getMatrix(camMat);
camMat = camMat * qApp->getEyePose(eye);
batch.setViewportTransform(renderArgs->_viewport);
batch.setViewTransform(camMat);
batch.setProjectionTransform(qApp->getEyeProjection(eye));
batch.setProjectionTransform(qApp->getEyeProjection(eye));
#ifdef DEBUG_OVERLAY
{
batch.setModelTransform(glm::translate(mat4(), vec3(0, 0, -2)));
geometryCache->renderUnitQuad(batch, glm::vec4(1));
}
#else
{
//batch.setModelTransform(overlayXfm);
#ifdef DEBUG_OVERLAY
{
batch.setModelTransform(glm::translate(mat4(), vec3(0, 0, -2)));
geometryCache->renderUnitQuad(batch, glm::vec4(1));
}
#else
{
batch.setModelTransform(_modelTransform);
drawSphereSection(batch);
}
#endif
batch.setModelTransform(_modelTransform);
drawSphereSection(batch);
}
#endif
// Doesn't actually render
renderPointers(batch);
vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize);
// Doesn't actually render
renderPointers(batch);
vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize);
bindCursorTexture(batch);
bindCursorTexture(batch);
//Controller Pointers
glm::mat4 overlayXfm;
_modelTransform.getMatrix(overlayXfm);
//Controller Pointers
glm::mat4 overlayXfm;
_modelTransform.getMatrix(overlayXfm);
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) {
PalmData& palm = myAvatar->getHand()->getPalms()[i];
if (palm.isActive()) {
glm::vec2 polar = getPolarCoordinates(palm);
// Convert to quaternion
mat4 pointerXfm = glm::mat4_cast(quat(vec3(polar.y, -polar.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
mat4 reticleXfm = overlayXfm * pointerXfm;
reticleXfm = glm::scale(reticleXfm, reticleScale);
batch.setModelTransform(reticleXfm);
// Render reticle at location
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
}
}
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) {
PalmData& palm = myAvatar->getHand()->getPalms()[i];
if (palm.isActive()) {
glm::vec2 polar = getPolarCoordinates(palm);
// Convert to quaternion
mat4 pointerXfm = glm::mat4_cast(quat(vec3(polar.y, -polar.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
//Mouse Pointer
if (_reticleActive[MOUSE]) {
glm::vec2 projection = screenToSpherical(glm::vec2(_reticlePosition[MOUSE].x(),
_reticlePosition[MOUSE].y()));
mat4 pointerXfm = glm::mat4_cast(quat(vec3(-projection.y, projection.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
mat4 reticleXfm = overlayXfm * pointerXfm;
reticleXfm = glm::scale(reticleXfm, reticleScale);
batch.setModelTransform(reticleXfm);
// Render reticle at location
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
}
}
//Mouse Pointer
if (_reticleActive[MOUSE]) {
glm::vec2 projection = screenToSpherical(glm::vec2(_reticlePosition[MOUSE].x(),
_reticlePosition[MOUSE].y()));
mat4 pointerXfm = glm::mat4_cast(quat(vec3(-projection.y, projection.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
mat4 reticleXfm = overlayXfm * pointerXfm;
reticleXfm = glm::scale(reticleXfm, reticleScale);
batch.setModelTransform(reticleXfm);
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
}
renderArgs->_context->render(batch);
});
}

View file

@ -94,6 +94,8 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
renderArgs->_context->render(batch);
qDebug() << "ApplicationOverlay::renderOverlay() batch:" << batch.getCacheState();
renderArgs->_batch = nullptr; // so future users of renderArgs don't try to use our batch
CHECK_GL_ERROR();

View file

@ -10,6 +10,7 @@
//
#include "Batch.h"
#include <QDebug>
#include <string.h>
#if defined(NSIGHT_FOUND)
@ -41,7 +42,21 @@ Batch::Batch() :
{
}
Batch::Batch(const CacheState& cacheState) : Batch() {
_commands.reserve(cacheState.commandsSize);
_commandOffsets.reserve(cacheState.offsetsSize);
_params.reserve(cacheState.paramsSize);
_data.reserve(cacheState.dataSize);
}
Batch::CacheState Batch::getCacheState() {
return CacheState(_commands.size(), _commandOffsets.size(), _params.size(), _data.size(),
_buffers.size(), _textures.size(), _streamFormats.size(), _transforms.size(), _pipelines.size(),
_framebuffers.size(), _queries.size());
}
Batch::~Batch() {
//qDebug() << "Batch::~Batch()... " << getCacheState();
}
void Batch::clear() {
@ -358,3 +373,14 @@ void Batch::preExecute() {
}
_namedData.clear();
}
QDebug& operator<<(QDebug& debug, const Batch::CacheState& cacheState) {
debug << "Batch::CacheState[ "
<< "commandsSize:" << cacheState.commandsSize
<< "offsetsSize:" << cacheState.offsetsSize
<< "paramsSize:" << cacheState.paramsSize
<< "dataSize:" << cacheState.dataSize
<< "]";
return debug;
}

View file

@ -22,6 +22,7 @@
#include "Texture.h"
#include "Transform.h"
#if defined(NSIGHT_FOUND)
class ProfileRange {
public:
@ -33,6 +34,8 @@
#define PROFILE_RANGE(name)
#endif
class QDebug;
namespace gpu {
enum ReservedSlot {
@ -70,7 +73,34 @@ public:
using NamedBatchDataMap = std::map<std::string, NamedBatchData>;
class CacheState {
public:
size_t commandsSize;
size_t offsetsSize;
size_t paramsSize;
size_t dataSize;
size_t buffersSize;
size_t texturesSize;
size_t streamFormatsSize;
size_t transformsSize;
size_t pipelinesSize;
size_t framebuffersSize;
size_t queriesSize;
CacheState() : commandsSize(0), offsetsSize(0), paramsSize(0), dataSize(0), buffersSize(0), texturesSize(0),
streamFormatsSize(0), transformsSize(0), pipelinesSize(0), framebuffersSize(0), queriesSize(0) { }
CacheState(size_t commandsSize, size_t offsetsSize, size_t paramsSize, size_t dataSize, size_t buffersSize,
size_t texturesSize, size_t streamFormatsSize, size_t transformsSize, size_t pipelinesSize,
size_t framebuffersSize, size_t queriesSize) :
commandsSize(commandsSize), offsetsSize(offsetsSize), paramsSize(paramsSize), dataSize(dataSize),
buffersSize(buffersSize), texturesSize(texturesSize), streamFormatsSize(streamFormatsSize),
transformsSize(transformsSize), pipelinesSize(pipelinesSize), framebuffersSize(framebuffersSize), queriesSize(queriesSize) { }
};
Batch();
Batch(const CacheState& cacheState);
explicit Batch(const Batch& batch);
~Batch();
@ -78,6 +108,9 @@ public:
void preExecute();
CacheState getCacheState();
// Batches may need to override the context level stereo settings
// if they're performing framebuffer copy operations, like the
// deferred lighting resolution mechanism
@ -307,6 +340,7 @@ public:
public:
std::vector< Cache<T> > _items;
size_t size() const { return _items.size(); }
uint32 cache(const Data& data) {
uint32 offset = _items.size();
_items.push_back(Cache<T>(data));
@ -373,4 +407,6 @@ protected:
}
QDebug& operator<<(QDebug& debug, const gpu::Batch::CacheState& cacheState);
#endif

View file

@ -217,4 +217,13 @@ typedef std::shared_ptr<Context> ContextPointer;
};
template<typename F>
void doInBatch(std::shared_ptr<gpu::Context> context, F f) {
static gpu::Batch::CacheState cacheState;
gpu::Batch batch(cacheState);
f(batch);
context->render(batch);
cacheState = batch.getCacheState();
}
#endif

View file

@ -173,23 +173,22 @@ void ViveControllerManager::updateRendering(RenderArgs* args, render::ScenePoint
UserInputMapper::PoseValue leftHand = _poseStateMap[makeInput(JointChannel::LEFT_HAND).getChannel()];
UserInputMapper::PoseValue rightHand = _poseStateMap[makeInput(JointChannel::RIGHT_HAND).getChannel()];
gpu::Batch batch;
auto geometryCache = DependencyManager::get<GeometryCache>();
geometryCache->useSimpleDrawPipeline(batch);
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, true);
doInBatch(args->_context, [=](gpu::Batch& batch) {
auto geometryCache = DependencyManager::get<GeometryCache>();
geometryCache->useSimpleDrawPipeline(batch);
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, true);
auto mesh = _modelGeometry.getMesh();
batch.setInputFormat(mesh->getVertexFormat());
//batch._glBindTexture(GL_TEXTURE_2D, _uexture);
auto mesh = _modelGeometry.getMesh();
batch.setInputFormat(mesh->getVertexFormat());
//batch._glBindTexture(GL_TEXTURE_2D, _uexture);
if (leftHand.isValid()) {
renderHand(leftHand, batch, LEFT_HAND);
}
if (rightHand.isValid()) {
renderHand(rightHand, batch, RIGHT_HAND);
}
args->_context->render(batch);
if (leftHand.isValid()) {
renderHand(leftHand, batch, LEFT_HAND);
}
if (rightHand.isValid()) {
renderHand(rightHand, batch, RIGHT_HAND);
}
});
}
}

View file

@ -178,112 +178,109 @@ void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, cons
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
gpu::Batch batch;
RenderArgs* args = renderContext->args;
auto framebufferCache = DependencyManager::get<FramebufferCache>();
QSize framebufferSize = framebufferCache->getFrameBufferSize();
float fbWidth = framebufferSize.width();
float fbHeight = framebufferSize.height();
float sMin = args->_viewport.x / fbWidth;
float sWidth = args->_viewport.z / fbWidth;
float tMin = args->_viewport.y / fbHeight;
float tHeight = args->_viewport.w / fbHeight;
doInBatch(args->_context, [=](gpu::Batch& batch) {
auto framebufferCache = DependencyManager::get<FramebufferCache>();
QSize framebufferSize = framebufferCache->getFrameBufferSize();
float fbWidth = framebufferSize.width();
float fbHeight = framebufferSize.height();
float sMin = args->_viewport.x / fbWidth;
float sWidth = args->_viewport.z / fbWidth;
float tMin = args->_viewport.y / fbHeight;
float tHeight = args->_viewport.w / fbHeight;
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setModelTransform(Transform());
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setModelTransform(Transform());
// Occlusion step
getOcclusionPipeline();
batch.setResourceTexture(0, framebufferCache->getPrimaryDepthTexture());
batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture());
_occlusionBuffer->setRenderBuffer(0, _occlusionTexture);
batch.setFramebuffer(_occlusionBuffer);
// Occlusion step
getOcclusionPipeline();
batch.setResourceTexture(0, framebufferCache->getPrimaryDepthTexture());
batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture());
_occlusionBuffer->setRenderBuffer(0, _occlusionTexture);
batch.setFramebuffer(_occlusionBuffer);
// Occlusion uniforms
g_scale = 1.0f;
g_bias = 1.0f;
g_sample_rad = 1.0f;
g_intensity = 1.0f;
// Occlusion uniforms
g_scale = 1.0f;
g_bias = 1.0f;
g_sample_rad = 1.0f;
g_intensity = 1.0f;
// Bind the first gpu::Pipeline we need - for calculating occlusion buffer
batch.setPipeline(getOcclusionPipeline());
batch._glUniform1f(_gScaleLoc, g_scale);
batch._glUniform1f(_gBiasLoc, g_bias);
batch._glUniform1f(_gSampleRadiusLoc, g_sample_rad);
batch._glUniform1f(_gIntensityLoc, g_intensity);
// Bind the first gpu::Pipeline we need - for calculating occlusion buffer
batch.setPipeline(getOcclusionPipeline());
batch._glUniform1f(_gScaleLoc, g_scale);
batch._glUniform1f(_gBiasLoc, g_bias);
batch._glUniform1f(_gSampleRadiusLoc, g_sample_rad);
batch._glUniform1f(_gIntensityLoc, g_intensity);
// setup uniforms for unpacking a view-space position from the depth buffer
// This is code taken from DeferredLightEffect.render() method in DeferredLightingEffect.cpp.
// DeferredBuffer.slh shows how the unpacking is done and what variables are needed.
// setup uniforms for unpacking a view-space position from the depth buffer
// This is code taken from DeferredLightEffect.render() method in DeferredLightingEffect.cpp.
// DeferredBuffer.slh shows how the unpacking is done and what variables are needed.
// initialize the view-space unpacking uniforms using frustum data
float left, right, bottom, top, nearVal, farVal;
glm::vec4 nearClipPlane, farClipPlane;
// initialize the view-space unpacking uniforms using frustum data
float left, right, bottom, top, nearVal, farVal;
glm::vec4 nearClipPlane, farClipPlane;
args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
float depthScale = (farVal - nearVal) / farVal;
float nearScale = -1.0f / nearVal;
float depthTexCoordScaleS = (right - left) * nearScale / sWidth;
float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight;
float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS;
float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT;
float depthScale = (farVal - nearVal) / farVal;
float nearScale = -1.0f / nearVal;
float depthTexCoordScaleS = (right - left) * nearScale / sWidth;
float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight;
float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS;
float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT;
// now set the position-unpacking unforms
batch._glUniform1f(_nearLoc, nearVal);
batch._glUniform1f(_depthScaleLoc, depthScale);
batch._glUniform2f(_depthTexCoordOffsetLoc, depthTexCoordOffsetS, depthTexCoordOffsetT);
batch._glUniform2f(_depthTexCoordScaleLoc, depthTexCoordScaleS, depthTexCoordScaleT);
// now set the position-unpacking unforms
batch._glUniform1f(_nearLoc, nearVal);
batch._glUniform1f(_depthScaleLoc, depthScale);
batch._glUniform2f(_depthTexCoordOffsetLoc, depthTexCoordOffsetS, depthTexCoordOffsetT);
batch._glUniform2f(_depthTexCoordScaleLoc, depthTexCoordScaleS, depthTexCoordScaleT);
batch._glUniform2f(_renderTargetResLoc, fbWidth, fbHeight);
batch._glUniform2f(_renderTargetResInvLoc, 1.0f / fbWidth, 1.0f / fbHeight);
batch._glUniform2f(_renderTargetResLoc, fbWidth, fbHeight);
batch._glUniform2f(_renderTargetResInvLoc, 1.0f / fbWidth, 1.0f / fbHeight);
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
glm::vec2 bottomLeft(-1.0f, -1.0f);
glm::vec2 topRight(1.0f, 1.0f);
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
glm::vec2 bottomLeft(-1.0f, -1.0f);
glm::vec2 topRight(1.0f, 1.0f);
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
// Vertical blur step
getVBlurPipeline();
batch.setResourceTexture(0, _occlusionTexture);
_vBlurBuffer->setRenderBuffer(0, _vBlurTexture);
batch.setFramebuffer(_vBlurBuffer);
// Vertical blur step
getVBlurPipeline();
batch.setResourceTexture(0, _occlusionTexture);
_vBlurBuffer->setRenderBuffer(0, _vBlurTexture);
batch.setFramebuffer(_vBlurBuffer);
// Bind the second gpu::Pipeline we need - for calculating blur buffer
batch.setPipeline(getVBlurPipeline());
// Bind the second gpu::Pipeline we need - for calculating blur buffer
batch.setPipeline(getVBlurPipeline());
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
// Horizontal blur step
getHBlurPipeline();
batch.setResourceTexture(0, _vBlurTexture);
_hBlurBuffer->setRenderBuffer(0, _hBlurTexture);
batch.setFramebuffer(_hBlurBuffer);
// Horizontal blur step
getHBlurPipeline();
batch.setResourceTexture(0, _vBlurTexture);
_hBlurBuffer->setRenderBuffer(0, _hBlurTexture);
batch.setFramebuffer(_hBlurBuffer);
// Bind the third gpu::Pipeline we need - for calculating blur buffer
batch.setPipeline(getHBlurPipeline());
// Bind the third gpu::Pipeline we need - for calculating blur buffer
batch.setPipeline(getHBlurPipeline());
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
// Blend step
getBlendPipeline();
batch.setResourceTexture(0, _hBlurTexture);
batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer());
// Blend step
getBlendPipeline();
batch.setResourceTexture(0, _hBlurTexture);
batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer());
// Bind the fourth gpu::Pipeline we need - for blending the primary color buffer with blurred occlusion texture
batch.setPipeline(getBlendPipeline());
// Bind the fourth gpu::Pipeline we need - for blending the primary color buffer with blurred occlusion texture
batch.setPipeline(getBlendPipeline());
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
// Ready to render
args->_context->render((batch));
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
});
}

View file

@ -100,66 +100,62 @@ void Antialiasing::run(const render::SceneContextPointer& sceneContext, const re
return;
}
gpu::Batch batch;
batch.enableStereo(false);
RenderArgs* args = renderContext->args;
doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
auto framebufferCache = DependencyManager::get<FramebufferCache>();
QSize framebufferSize = framebufferCache->getFrameBufferSize();
float fbWidth = framebufferSize.width();
float fbHeight = framebufferSize.height();
// float sMin = args->_viewport.x / fbWidth;
// float sWidth = args->_viewport.z / fbWidth;
// float tMin = args->_viewport.y / fbHeight;
// float tHeight = args->_viewport.w / fbHeight;
auto framebufferCache = DependencyManager::get<FramebufferCache>();
QSize framebufferSize = framebufferCache->getFrameBufferSize();
float fbWidth = framebufferSize.width();
float fbHeight = framebufferSize.height();
// float sMin = args->_viewport.x / fbWidth;
// float sWidth = args->_viewport.z / fbWidth;
// float tMin = args->_viewport.y / fbHeight;
// float tHeight = args->_viewport.w / fbHeight;
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setModelTransform(Transform());
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setModelTransform(Transform());
// FXAA step
getAntialiasingPipeline();
batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture());
_antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture);
batch.setFramebuffer(_antialiasingBuffer);
batch.setPipeline(getAntialiasingPipeline());
// FXAA step
getAntialiasingPipeline();
batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture());
_antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture);
batch.setFramebuffer(_antialiasingBuffer);
batch.setPipeline(getAntialiasingPipeline());
// initialize the view-space unpacking uniforms using frustum data
float left, right, bottom, top, nearVal, farVal;
glm::vec4 nearClipPlane, farClipPlane;
// initialize the view-space unpacking uniforms using frustum data
float left, right, bottom, top, nearVal, farVal;
glm::vec4 nearClipPlane, farClipPlane;
args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
// float depthScale = (farVal - nearVal) / farVal;
// float nearScale = -1.0f / nearVal;
// float depthTexCoordScaleS = (right - left) * nearScale / sWidth;
// float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight;
// float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS;
// float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT;
// float depthScale = (farVal - nearVal) / farVal;
// float nearScale = -1.0f / nearVal;
// float depthTexCoordScaleS = (right - left) * nearScale / sWidth;
// float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight;
// float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS;
// float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT;
batch._glUniform2f(_texcoordOffsetLoc, 1.0f / fbWidth, 1.0f / fbHeight);
batch._glUniform2f(_texcoordOffsetLoc, 1.0f / fbWidth, 1.0f / fbHeight);
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
glm::vec2 bottomLeft(-1.0f, -1.0f);
glm::vec2 topRight(1.0f, 1.0f);
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
glm::vec2 bottomLeft(-1.0f, -1.0f);
glm::vec2 topRight(1.0f, 1.0f);
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
// Blend step
getBlendPipeline();
batch.setResourceTexture(0, _antialiasingTexture);
batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer());
batch.setPipeline(getBlendPipeline());
// Blend step
getBlendPipeline();
batch.setResourceTexture(0, _antialiasingTexture);
batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer());
batch.setPipeline(getBlendPipeline());
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
// Ready to render
args->_context->render((batch));
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
});
}

View file

@ -340,341 +340,338 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu
}
void DeferredLightingEffect::prepare(RenderArgs* args) {
gpu::Batch batch;
batch.enableStereo(false);
doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
batch.setStateScissorRect(args->_viewport);
batch.setStateScissorRect(args->_viewport);
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
batch.setFramebuffer(primaryFbo);
// clear the normal and specular buffers
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR1, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true);
const float MAX_SPECULAR_EXPONENT = 128.0f;
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR2, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f / MAX_SPECULAR_EXPONENT), true);
args->_context->render(batch);
batch.setFramebuffer(primaryFbo);
// clear the normal and specular buffers
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR1, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true);
const float MAX_SPECULAR_EXPONENT = 128.0f;
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR2, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f / MAX_SPECULAR_EXPONENT), true);
});
}
gpu::FramebufferPointer _copyFBO;
void DeferredLightingEffect::render(RenderArgs* args) {
gpu::Batch batch;
// Allocate the parameters buffer used by all the deferred shaders
if (!_deferredTransformBuffer[0]._buffer) {
DeferredTransform parameters;
_deferredTransformBuffer[0] = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(DeferredTransform), (const gpu::Byte*) &parameters));
_deferredTransformBuffer[1] = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(DeferredTransform), (const gpu::Byte*) &parameters));
}
// Framebuffer copy operations cannot function as multipass stereo operations.
batch.enableStereo(false);
// perform deferred lighting, rendering to free fbo
auto framebufferCache = DependencyManager::get<FramebufferCache>();
QSize framebufferSize = framebufferCache->getFrameBufferSize();
// binding the first framebuffer
_copyFBO = framebufferCache->getFramebuffer();
batch.setFramebuffer(_copyFBO);
// Clearing it
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
batch.clearColorFramebuffer(_copyFBO->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true);
// BInd the G-Buffer surfaces
batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture());
batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture());
batch.setResourceTexture(2, framebufferCache->getPrimarySpecularTexture());
batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture());
// THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport)
auto monoViewport = args->_viewport;
float sMin = args->_viewport.x / (float)framebufferSize.width();
float sWidth = args->_viewport.z / (float)framebufferSize.width();
float tMin = args->_viewport.y / (float)framebufferSize.height();
float tHeight = args->_viewport.w / (float)framebufferSize.height();
// The view frustum is the mono frustum base
auto viewFrustum = args->_viewFrustum;
// Eval the mono projection
mat4 monoProjMat;
viewFrustum->evalProjectionMatrix(monoProjMat);
// The mono view transform
Transform monoViewTransform;
viewFrustum->evalViewTransform(monoViewTransform);
// THe mono view matrix coming from the mono view transform
glm::mat4 monoViewMat;
monoViewTransform.getMatrix(monoViewMat);
// Running in stero ?
bool isStereo = args->_context->isStereo();
int numPasses = 1;
mat4 projMats[2];
Transform viewTransforms[2];
ivec4 viewports[2];
vec4 clipQuad[2];
vec2 screenBottomLeftCorners[2];
vec2 screenTopRightCorners[2];
vec4 fetchTexcoordRects[2];
DeferredTransform deferredTransforms[2];
auto geometryCache = DependencyManager::get<GeometryCache>();
if (isStereo) {
numPasses = 2;
mat4 eyeViews[2];
args->_context->getStereoProjections(projMats);
args->_context->getStereoViews(eyeViews);
float halfWidth = 0.5f * sWidth;
for (int i = 0; i < numPasses; i++) {
// In stereo, the 2 sides are layout side by side in the mono viewport and their width is half
int sideWidth = monoViewport.z >> 1;
viewports[i] = ivec4(monoViewport.x + (i * sideWidth), monoViewport.y, sideWidth, monoViewport.w);
deferredTransforms[i].projection = projMats[i];
auto sideViewMat = eyeViews[i] * monoViewMat;
viewTransforms[i].evalFromRawMatrix(sideViewMat);
deferredTransforms[i].viewInverse = sideViewMat;
deferredTransforms[i].stereoSide = (i == 0 ? -1.0f : 1.0f);
clipQuad[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight);
screenBottomLeftCorners[i] = glm::vec2(-1.0f + i * 1.0f, -1.0f);
screenTopRightCorners[i] = glm::vec2(i * 1.0f, 1.0f);
fetchTexcoordRects[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight);
}
} else {
viewports[0] = monoViewport;
projMats[0] = monoProjMat;
deferredTransforms[0].projection = monoProjMat;
deferredTransforms[0].viewInverse = monoViewMat;
viewTransforms[0] = monoViewTransform;
deferredTransforms[0].stereoSide = 0.0f;
clipQuad[0] = glm::vec4(sMin, tMin, sWidth, tHeight);
screenBottomLeftCorners[0] = glm::vec2(-1.0f, -1.0f);
screenTopRightCorners[0] = glm::vec2(1.0f, 1.0f);
fetchTexcoordRects[0] = glm::vec4(sMin, tMin, sWidth, tHeight);
}
auto eyePoint = viewFrustum->getPosition();
float nearRadius = glm::distance(eyePoint, viewFrustum->getNearTopLeft());
for (int side = 0; side < numPasses; side++) {
// Render in this side's viewport
batch.setViewportTransform(viewports[side]);
batch.setStateScissorRect(viewports[side]);
// Sync and Bind the correct DeferredTransform ubo
_deferredTransformBuffer[side]._buffer->setSubData(0, sizeof(DeferredTransform), (const gpu::Byte*) &deferredTransforms[side]);
batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, _deferredTransformBuffer[side]);
glm::vec2 topLeft(-1.0f, -1.0f);
glm::vec2 bottomRight(1.0f, 1.0f);
glm::vec2 texCoordTopLeft(clipQuad[side].x, clipQuad[side].y);
glm::vec2 texCoordBottomRight(clipQuad[side].x + clipQuad[side].z, clipQuad[side].y + clipQuad[side].w);
// First Global directional light and ambient pass
{
bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap());
auto& program = _directionalLight;
LightLocationsPtr locations = _directionalLightLocations;
// TODO: At some point bring back the shadows...
// Setup the global directional pass pipeline
{
if (useSkyboxCubemap) {
program = _directionalSkyboxLight;
locations = _directionalSkyboxLightLocations;
} else if (_ambientLightMode > -1) {
program = _directionalAmbientSphereLight;
locations = _directionalAmbientSphereLightLocations;
}
batch.setPipeline(program);
}
{ // Setup the global lighting
auto globalLight = _allocatedLights[_globalLights.front()];
if (locations->ambientSphere >= 0) {
gpu::SphericalHarmonics sh = globalLight->getAmbientSphere();
if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) {
sh = (*_skybox->getCubemap()->getIrradiance());
}
for (int i =0; i <gpu::SphericalHarmonics::NUM_COEFFICIENTS; i++) {
batch._glUniform4fv(locations->ambientSphere + i, 1, (const float*) (&sh) + i * 4);
}
}
if (useSkyboxCubemap) {
batch.setResourceTexture(5, _skybox->getCubemap());
}
if (locations->lightBufferUnit >= 0) {
batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer());
}
doInBatch(args->_context, [=](gpu::Batch& batch) {
if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) {
batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer());
}
}
{
batch.setModelTransform(Transform());
batch.setProjectionTransform(glm::mat4());
batch.setViewTransform(Transform());
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
geometryCache->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
}
if (useSkyboxCubemap) {
batch.setResourceTexture(5, nullptr);
}
// Allocate the parameters buffer used by all the deferred shaders
if (!_deferredTransformBuffer[0]._buffer) {
DeferredTransform parameters;
_deferredTransformBuffer[0] = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(DeferredTransform), (const gpu::Byte*) &parameters));
_deferredTransformBuffer[1] = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(DeferredTransform), (const gpu::Byte*) &parameters));
}
auto texcoordMat = glm::mat4();
/* texcoordMat[0] = glm::vec4(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f);
texcoordMat[1] = glm::vec4(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f);
*/ texcoordMat[0] = glm::vec4(fetchTexcoordRects[side].z / 2.0f, 0.0f, 0.0f, fetchTexcoordRects[side].x + fetchTexcoordRects[side].z / 2.0f);
texcoordMat[1] = glm::vec4(0.0f, fetchTexcoordRects[side].w / 2.0f, 0.0f, fetchTexcoordRects[side].y + fetchTexcoordRects[side].w / 2.0f);
texcoordMat[2] = glm::vec4(0.0f, 0.0f, 1.0f, 0.0f);
texcoordMat[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
// Framebuffer copy operations cannot function as multipass stereo operations.
batch.enableStereo(false);
// enlarge the scales slightly to account for tesselation
const float SCALE_EXPANSION = 0.05f;
batch.setProjectionTransform(projMats[side]);
batch.setViewTransform(viewTransforms[side]);
// Splat Point lights
if (!_pointLights.empty()) {
batch.setPipeline(_pointLight);
batch._glUniformMatrix4fv(_pointLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
for (auto lightID : _pointLights) {
auto& light = _allocatedLights[lightID];
// IN DEBUG: light->setShowContour(true);
if (_pointLightLocations->lightBufferUnit >= 0) {
batch.setUniformBuffer(_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());
}
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) {
Transform model;
model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f));
batch.setModelTransform(model);
batch.setViewTransform(Transform());
batch.setProjectionTransform(glm::mat4());
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
batch.setProjectionTransform(projMats[side]);
batch.setViewTransform(viewTransforms[side]);
} else {
Transform model;
model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z));
batch.setModelTransform(model.postScale(expandedRadius));
batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
geometryCache->renderSphere(batch);
}
}
}
// perform deferred lighting, rendering to free fbo
auto framebufferCache = DependencyManager::get<FramebufferCache>();
// Splat spot lights
if (!_spotLights.empty()) {
batch.setPipeline(_spotLight);
QSize framebufferSize = framebufferCache->getFrameBufferSize();
// binding the first framebuffer
_copyFBO = framebufferCache->getFramebuffer();
batch.setFramebuffer(_copyFBO);
batch._glUniformMatrix4fv(_spotLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
// Clearing it
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
batch.clearColorFramebuffer(_copyFBO->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true);
for (auto lightID : _spotLights) {
auto light = _allocatedLights[lightID];
// IN DEBUG: light->setShowContour(true);
// BInd the G-Buffer surfaces
batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture());
batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture());
batch.setResourceTexture(2, framebufferCache->getPrimarySpecularTexture());
batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture());
batch.setUniformBuffer(_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());
// THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport)
auto monoViewport = args->_viewport;
float sMin = args->_viewport.x / (float)framebufferSize.width();
float sWidth = args->_viewport.z / (float)framebufferSize.width();
float tMin = args->_viewport.y / (float)framebufferSize.height();
float tHeight = args->_viewport.w / (float)framebufferSize.height();
auto eyeLightPos = eyePoint - light->getPosition();
auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection());
// The view frustum is the mono frustum base
auto viewFrustum = args->_viewFrustum;
const float TANGENT_LENGTH_SCALE = 0.666f;
glm::vec4 coneParam(light->getSpotAngleCosSin(), TANGENT_LENGTH_SCALE * tanf(0.5f * light->getSpotAngle()), 1.0f);
// Eval the mono projection
mat4 monoProjMat;
viewFrustum->evalProjectionMatrix(monoProjMat);
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
if ((eyeHalfPlaneDistance > -nearRadius) &&
(glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius)) {
coneParam.w = 0.0f;
batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
// The mono view transform
Transform monoViewTransform;
viewFrustum->evalViewTransform(monoViewTransform);
Transform model;
model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f));
batch.setModelTransform(model);
batch.setViewTransform(Transform());
// THe mono view matrix coming from the mono view transform
glm::mat4 monoViewMat;
monoViewTransform.getMatrix(monoViewMat);
// Running in stero ?
bool isStereo = args->_context->isStereo();
int numPasses = 1;
mat4 projMats[2];
Transform viewTransforms[2];
ivec4 viewports[2];
vec4 clipQuad[2];
vec2 screenBottomLeftCorners[2];
vec2 screenTopRightCorners[2];
vec4 fetchTexcoordRects[2];
DeferredTransform deferredTransforms[2];
auto geometryCache = DependencyManager::get<GeometryCache>();
if (isStereo) {
numPasses = 2;
mat4 eyeViews[2];
args->_context->getStereoProjections(projMats);
args->_context->getStereoViews(eyeViews);
float halfWidth = 0.5f * sWidth;
for (int i = 0; i < numPasses; i++) {
// In stereo, the 2 sides are layout side by side in the mono viewport and their width is half
int sideWidth = monoViewport.z >> 1;
viewports[i] = ivec4(monoViewport.x + (i * sideWidth), monoViewport.y, sideWidth, monoViewport.w);
deferredTransforms[i].projection = projMats[i];
auto sideViewMat = eyeViews[i] * monoViewMat;
viewTransforms[i].evalFromRawMatrix(sideViewMat);
deferredTransforms[i].viewInverse = sideViewMat;
deferredTransforms[i].stereoSide = (i == 0 ? -1.0f : 1.0f);
clipQuad[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight);
screenBottomLeftCorners[i] = glm::vec2(-1.0f + i * 1.0f, -1.0f);
screenTopRightCorners[i] = glm::vec2(i * 1.0f, 1.0f);
fetchTexcoordRects[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight);
}
} else {
viewports[0] = monoViewport;
projMats[0] = monoProjMat;
deferredTransforms[0].projection = monoProjMat;
deferredTransforms[0].viewInverse = monoViewMat;
viewTransforms[0] = monoViewTransform;
deferredTransforms[0].stereoSide = 0.0f;
clipQuad[0] = glm::vec4(sMin, tMin, sWidth, tHeight);
screenBottomLeftCorners[0] = glm::vec2(-1.0f, -1.0f);
screenTopRightCorners[0] = glm::vec2(1.0f, 1.0f);
fetchTexcoordRects[0] = glm::vec4(sMin, tMin, sWidth, tHeight);
}
auto eyePoint = viewFrustum->getPosition();
float nearRadius = glm::distance(eyePoint, viewFrustum->getNearTopLeft());
for (int side = 0; side < numPasses; side++) {
// Render in this side's viewport
batch.setViewportTransform(viewports[side]);
batch.setStateScissorRect(viewports[side]);
// Sync and Bind the correct DeferredTransform ubo
_deferredTransformBuffer[side]._buffer->setSubData(0, sizeof(DeferredTransform), (const gpu::Byte*) &deferredTransforms[side]);
batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, _deferredTransformBuffer[side]);
glm::vec2 topLeft(-1.0f, -1.0f);
glm::vec2 bottomRight(1.0f, 1.0f);
glm::vec2 texCoordTopLeft(clipQuad[side].x, clipQuad[side].y);
glm::vec2 texCoordBottomRight(clipQuad[side].x + clipQuad[side].z, clipQuad[side].y + clipQuad[side].w);
// First Global directional light and ambient pass
{
bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap());
auto& program = _directionalLight;
LightLocationsPtr locations = _directionalLightLocations;
// TODO: At some point bring back the shadows...
// Setup the global directional pass pipeline
{
if (useSkyboxCubemap) {
program = _directionalSkyboxLight;
locations = _directionalSkyboxLightLocations;
} else if (_ambientLightMode > -1) {
program = _directionalAmbientSphereLight;
locations = _directionalAmbientSphereLightLocations;
}
batch.setPipeline(program);
}
{ // Setup the global lighting
auto globalLight = _allocatedLights[_globalLights.front()];
if (locations->ambientSphere >= 0) {
gpu::SphericalHarmonics sh = globalLight->getAmbientSphere();
if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) {
sh = (*_skybox->getCubemap()->getIrradiance());
}
for (int i =0; i <gpu::SphericalHarmonics::NUM_COEFFICIENTS; i++) {
batch._glUniform4fv(locations->ambientSphere + i, 1, (const float*) (&sh) + i * 4);
}
}
if (useSkyboxCubemap) {
batch.setResourceTexture(5, _skybox->getCubemap());
}
if (locations->lightBufferUnit >= 0) {
batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer());
}
if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) {
batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer());
}
}
{
batch.setModelTransform(Transform());
batch.setProjectionTransform(glm::mat4());
batch.setViewTransform(Transform());
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
geometryCache->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
}
if (useSkyboxCubemap) {
batch.setResourceTexture(5, nullptr);
}
}
auto texcoordMat = glm::mat4();
/* texcoordMat[0] = glm::vec4(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f);
texcoordMat[1] = glm::vec4(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f);
*/ texcoordMat[0] = glm::vec4(fetchTexcoordRects[side].z / 2.0f, 0.0f, 0.0f, fetchTexcoordRects[side].x + fetchTexcoordRects[side].z / 2.0f);
texcoordMat[1] = glm::vec4(0.0f, fetchTexcoordRects[side].w / 2.0f, 0.0f, fetchTexcoordRects[side].y + fetchTexcoordRects[side].w / 2.0f);
texcoordMat[2] = glm::vec4(0.0f, 0.0f, 1.0f, 0.0f);
texcoordMat[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
// enlarge the scales slightly to account for tesselation
const float SCALE_EXPANSION = 0.05f;
batch.setProjectionTransform(projMats[side]);
batch.setViewTransform(viewTransforms[side]);
// Splat Point lights
if (!_pointLights.empty()) {
batch.setPipeline(_pointLight);
batch._glUniformMatrix4fv(_pointLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
for (auto lightID : _pointLights) {
auto& light = _allocatedLights[lightID];
// IN DEBUG: light->setShowContour(true);
if (_pointLightLocations->lightBufferUnit >= 0) {
batch.setUniformBuffer(_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());
}
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) {
Transform model;
model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f));
batch.setModelTransform(model);
batch.setViewTransform(Transform());
batch.setProjectionTransform(glm::mat4());
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
batch.setProjectionTransform( projMats[side]);
batch.setViewTransform(viewTransforms[side]);
} else {
coneParam.w = 1.0f;
batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
batch.setProjectionTransform(projMats[side]);
batch.setViewTransform(viewTransforms[side]);
} else {
Transform model;
model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z));
batch.setModelTransform(model.postScale(expandedRadius));
batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
geometryCache->renderSphere(batch);
}
}
}
// Splat spot lights
if (!_spotLights.empty()) {
batch.setPipeline(_spotLight);
Transform model;
model.setTranslation(light->getPosition());
model.postRotate(light->getOrientation());
model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius));
batch._glUniformMatrix4fv(_spotLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
batch.setModelTransform(model);
auto mesh = getSpotLightMesh();
for (auto lightID : _spotLights) {
auto light = _allocatedLights[lightID];
// IN DEBUG: light->setShowContour(true);
batch.setIndexBuffer(mesh->getIndexBuffer());
batch.setInputBuffer(0, mesh->getVertexBuffer());
batch.setInputFormat(mesh->getVertexFormat());
batch.setUniformBuffer(_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());
auto& part = mesh->getPartBuffer().get<model::Mesh::Part>();
auto eyeLightPos = eyePoint - light->getPosition();
auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection());
batch.drawIndexed(model::Mesh::topologyToPrimitive(part._topology), part._numIndices, part._startIndex);
const float TANGENT_LENGTH_SCALE = 0.666f;
glm::vec4 coneParam(light->getSpotAngleCosSin(), TANGENT_LENGTH_SCALE * tanf(0.5f * light->getSpotAngle()), 1.0f);
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
if ((eyeHalfPlaneDistance > -nearRadius) &&
(glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius)) {
coneParam.w = 0.0f;
batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
Transform model;
model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f));
batch.setModelTransform(model);
batch.setViewTransform(Transform());
batch.setProjectionTransform(glm::mat4());
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
batch.setProjectionTransform( projMats[side]);
batch.setViewTransform(viewTransforms[side]);
} else {
coneParam.w = 1.0f;
batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
Transform model;
model.setTranslation(light->getPosition());
model.postRotate(light->getOrientation());
model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius));
batch.setModelTransform(model);
auto mesh = getSpotLightMesh();
batch.setIndexBuffer(mesh->getIndexBuffer());
batch.setInputBuffer(0, mesh->getVertexBuffer());
batch.setInputFormat(mesh->getVertexFormat());
auto& part = mesh->getPartBuffer().get<model::Mesh::Part>();
batch.drawIndexed(model::Mesh::topologyToPrimitive(part._topology), part._numIndices, part._startIndex);
}
}
}
}
}
// Probably not necessary in the long run because the gpu layer would unbound this texture if used as render target
batch.setResourceTexture(0, nullptr);
batch.setResourceTexture(1, nullptr);
batch.setResourceTexture(2, nullptr);
batch.setResourceTexture(3, nullptr);
batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, nullptr);
args->_context->render(batch);
// Probably not necessary in the long run because the gpu layer would unbound this texture if used as render target
batch.setResourceTexture(0, nullptr);
batch.setResourceTexture(1, nullptr);
batch.setResourceTexture(2, nullptr);
batch.setResourceTexture(3, nullptr);
batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, nullptr);
});
// End of the Lighting pass
if (!_pointLights.empty()) {
@ -687,36 +684,37 @@ void DeferredLightingEffect::render(RenderArgs* args) {
void DeferredLightingEffect::copyBack(RenderArgs* args) {
gpu::Batch batch;
batch.enableStereo(false);
auto framebufferCache = DependencyManager::get<FramebufferCache>();
QSize framebufferSize = framebufferCache->getFrameBufferSize();
doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
QSize framebufferSize = framebufferCache->getFrameBufferSize();
// TODO why doesn't this blit work? It only seems to affect a small area below the rear view mirror.
// auto destFbo = framebufferCache->getPrimaryFramebuffer();
auto destFbo = framebufferCache->getPrimaryFramebufferDepthColor();
// gpu::Vec4i vp = args->_viewport;
// batch.blit(_copyFBO, vp, framebufferCache->getPrimaryFramebuffer(), vp);
batch.setFramebuffer(destFbo);
batch.setViewportTransform(args->_viewport);
batch.setProjectionTransform(glm::mat4());
batch.setViewTransform(Transform());
{
float sMin = args->_viewport.x / (float)framebufferSize.width();
float sWidth = args->_viewport.z / (float)framebufferSize.width();
float tMin = args->_viewport.y / (float)framebufferSize.height();
float tHeight = args->_viewport.w / (float)framebufferSize.height();
Transform model;
batch.setPipeline(_blitLightBuffer);
model.setTranslation(glm::vec3(sMin, tMin, 0.0));
model.setScale(glm::vec3(sWidth, tHeight, 1.0));
batch.setModelTransform(model);
}
// TODO why doesn't this blit work? It only seems to affect a small area below the rear view mirror.
// auto destFbo = framebufferCache->getPrimaryFramebuffer();
auto destFbo = framebufferCache->getPrimaryFramebufferDepthColor();
// gpu::Vec4i vp = args->_viewport;
// batch.blit(_copyFBO, vp, framebufferCache->getPrimaryFramebuffer(), vp);
batch.setFramebuffer(destFbo);
batch.setViewportTransform(args->_viewport);
batch.setProjectionTransform(glm::mat4());
batch.setViewTransform(Transform());
{
float sMin = args->_viewport.x / (float)framebufferSize.width();
float sWidth = args->_viewport.z / (float)framebufferSize.width();
float tMin = args->_viewport.y / (float)framebufferSize.height();
float tHeight = args->_viewport.w / (float)framebufferSize.height();
Transform model;
batch.setPipeline(_blitLightBuffer);
model.setTranslation(glm::vec3(sMin, tMin, 0.0));
model.setScale(glm::vec3(sWidth, tHeight, 1.0));
batch.setModelTransform(model);
}
batch.setResourceTexture(0, _copyFBO->getRenderBuffer(0));
batch.draw(gpu::TRIANGLE_STRIP, 4);
batch.setResourceTexture(0, _copyFBO->getRenderBuffer(0));
batch.draw(gpu::TRIANGLE_STRIP, 4);
args->_context->render(batch);
args->_context->render(batch);
});
framebufferCache->releaseFramebuffer(_copyFBO);
}

View file

@ -63,23 +63,22 @@ void HitEffect::run(const render::SceneContextPointer& sceneContext, const rende
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
RenderArgs* args = renderContext->args;
gpu::Batch batch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setModelTransform(Transform());
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setModelTransform(Transform());
batch.setPipeline(getHitEffectPipeline());
batch.setPipeline(getHitEffectPipeline());
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
glm::vec2 bottomLeft(-1.0f, -1.0f);
glm::vec2 topRight(1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, color);
args->_context->render((batch));
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
glm::vec2 bottomLeft(-1.0f, -1.0f);
glm::vec2 topRight(1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, color);
});
}

View file

@ -32,23 +32,22 @@ using namespace render;
void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
RenderArgs* args = renderContext->args;
doInBatch(args->_context, [=](gpu::Batch& batch) {
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
gpu::Batch batch;
batch.enableStereo(false);
batch.setFramebuffer(nullptr);
batch.setFramebuffer(primaryFbo);
batch.enableStereo(false);
batch.setFramebuffer(nullptr);
batch.setFramebuffer(primaryFbo);
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
batch.clearFramebuffer(
gpu::Framebuffer::BUFFER_COLOR0 |
gpu::Framebuffer::BUFFER_DEPTH,
vec4(vec3(0), 1), 1.0, 0.0, true);
args->_context->render(batch);
batch.clearFramebuffer(
gpu::Framebuffer::BUFFER_COLOR0 |
gpu::Framebuffer::BUFFER_DEPTH,
vec4(vec3(0), 1), 1.0, 0.0, true);
});
}
void PrepareDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
@ -167,30 +166,28 @@ void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const Rend
assert(renderContext->args->_viewFrustum);
RenderArgs* args = renderContext->args;
gpu::Batch batch;
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
args->_batch = &batch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
args->_batch = &batch;
renderContext->_numDrawnOpaqueItems = inItems.size();
renderContext->_numDrawnOpaqueItems = inItems.size();
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
{
const float OPAQUE_ALPHA_THRESHOLD = 0.5f;
args->_alphaThreshold = OPAQUE_ALPHA_THRESHOLD;
}
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOpaqueItems);
args->_context->render((*args->_batch));
args->_batch = nullptr;
{
const float OPAQUE_ALPHA_THRESHOLD = 0.5f;
args->_alphaThreshold = OPAQUE_ALPHA_THRESHOLD;
}
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOpaqueItems);
args->_batch = nullptr;
});
}
void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) {
@ -198,31 +195,27 @@ void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const
assert(renderContext->args->_viewFrustum);
RenderArgs* args = renderContext->args;
gpu::Batch batch;
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
args->_batch = &batch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
args->_batch = &batch;
renderContext->_numDrawnTransparentItems = inItems.size();
renderContext->_numDrawnTransparentItems = inItems.size();
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
{
const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f;
args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD;
}
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnTransparentItems);
args->_context->render((*args->_batch));
args->_batch = nullptr;
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnTransparentItems);
args->_batch = nullptr;
});
}
gpu::PipelinePointer DrawOverlay3D::_opaquePipeline;
@ -274,8 +267,7 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon
}
// Render the items
{
gpu::Batch batch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
args->_batch = &batch;
args->_whiteTexture = DependencyManager::get<TextureCache>()->getWhiteTexture();
@ -292,10 +284,8 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon
batch.setPipeline(getOpaquePipeline());
batch.setResourceTexture(0, args->_whiteTexture);
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOverlay3DItems);
args->_context->render((*args->_batch));
args->_batch = nullptr;
args->_whiteTexture.reset();
}
});
args->_batch = nullptr;
args->_whiteTexture.reset();
}
}

View file

@ -126,40 +126,38 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex
}
// Allright, something to render let's do it
gpu::Batch batch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setModelTransform(Transform());
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setModelTransform(Transform());
// bind the one gpu::Pipeline we need
batch.setPipeline(getDrawItemBoundsPipeline());
// bind the one gpu::Pipeline we need
batch.setPipeline(getDrawItemBoundsPipeline());
AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData());
AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData());
const unsigned int VEC3_ADRESS_OFFSET = 3;
const unsigned int VEC3_ADRESS_OFFSET = 3;
for (int i = 0; i < nbItems; i++) {
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i));
batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
for (int i = 0; i < nbItems; i++) {
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i));
batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
batch.draw(gpu::LINES, 24, 0);
}
batch.draw(gpu::LINES, 24, 0);
}
batch.setPipeline(getDrawItemStatusPipeline());
for (int i = 0; i < nbItems; i++) {
batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*) (itemAABox + i));
batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
batch._glUniform4iv(_drawItemStatusValueLoc, 1, (const int*) (itemStatus + i));
batch.setPipeline(getDrawItemStatusPipeline());
for (int i = 0; i < nbItems; i++) {
batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*) (itemAABox + i));
batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
batch._glUniform4iv(_drawItemStatusValueLoc, 1, (const int*) (itemStatus + i));
batch.draw(gpu::TRIANGLES, 24, 0);
}
args->_context->render(batch);
batch.draw(gpu::TRIANGLES, 24, 0);
}
});
}

View file

@ -19,6 +19,7 @@
#include <ViewFrustum.h>
#include <gpu/Context.h>
using namespace render;
DrawSceneTask::DrawSceneTask() : Task() {
@ -235,10 +236,10 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext
cullItems(sceneContext, renderContext, inItems, culledItems);
RenderArgs* args = renderContext->args;
gpu::Batch theBatch;
args->_batch = &theBatch;
renderItems(sceneContext, renderContext, culledItems);
args->_context->render((*args->_batch));
doInBatch(args->_context, [=](gpu::Batch& batch) {
args->_batch = &batch;
renderItems(sceneContext, renderContext, culledItems);
});
args->_batch = nullptr;
}
@ -257,22 +258,22 @@ void DrawBackground::run(const SceneContextPointer& sceneContext, const RenderCo
inItems.emplace_back(id);
}
RenderArgs* args = renderContext->args;
gpu::Batch batch;
batch.enableSkybox(true);
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
args->_batch = &batch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
args->_batch = &batch;
batch.enableSkybox(true);
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
renderItems(sceneContext, renderContext, inItems);
args->_context->render((*args->_batch));
renderItems(sceneContext, renderContext, inItems);
});
args->_batch = nullptr;
}