FIund a nasty bug with the scissor which was the reason for many issues, tried to integrate the framebuffer setup and clear as part of the enginepipeline so calling display side is simpler

This commit is contained in:
Sam Gateau 2015-07-24 02:15:50 -07:00
parent 66cd17ec66
commit cb375e8ece
8 changed files with 79 additions and 108 deletions

View file

@ -879,16 +879,11 @@ void Application::paintGL() {
renderArgs._context->syncCache();
if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
{
gpu::Batch batch;
batch.setFramebuffer(nullptr);
batch.setFramebuffer(primaryFbo);
renderArgs._context->render(batch);
}
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
renderRearViewMirror(&renderArgs, _mirrorViewRect);
renderArgs._renderMode = RenderArgs::NORMAL_RENDER_MODE;
renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
{
float ratio = ((float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale());
@ -918,6 +913,9 @@ void Application::paintGL() {
Application::getInstance()->cameraMenuChanged();
}
// The render mode is default or mirror if the camera is in mirror mode, assigned further below
renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
// Always use the default eye position, not the actual head eye position.
// Using the latter will cause the camera to wobble with idle animations,
@ -954,6 +952,7 @@ void Application::paintGL() {
glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) +
(_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
}
// Update camera position
@ -961,8 +960,6 @@ void Application::paintGL() {
_myCamera.update(1.0f / _fps);
}
renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
if (OculusManager::isConnected()) {
//When in mirror mode, use camera rotation. Otherwise, use body rotation
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
@ -974,31 +971,16 @@ void Application::paintGL() {
TV3DManager::display(&renderArgs, _myCamera);
} else {
PROFILE_RANGE(__FUNCTION__ "/mainRender");
// Viewport is assigned to the size of the framebuffer
QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize();
renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height());
{
gpu::Batch batch;
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
batch.setFramebuffer(primaryFbo);
// clear the normal and specular buffers
batch.clearFramebuffer(
gpu::Framebuffer::BUFFER_COLOR0 |
gpu::Framebuffer::BUFFER_COLOR1 |
gpu::Framebuffer::BUFFER_COLOR2 |
gpu::Framebuffer::BUFFER_DEPTH,
vec4(vec3(0), 1), 1.0, 0.0);
// Viewport is assigned to the size of the framebuffer
QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize();
renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height());
batch.setViewportTransform(renderArgs._viewport);
renderArgs._context->render(batch);
}
displaySide(&renderArgs, _myCamera);
{
auto geometryCache = DependencyManager::get<GeometryCache>();
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
gpu::Batch batch;
batch.blit(primaryFbo, glm::ivec4(0, 0, _renderResolution.x, _renderResolution.y),
nullptr, glm::ivec4(0, 0, _glWidget->getDeviceSize().width(), _glWidget->getDeviceSize().height()));
@ -1006,7 +988,6 @@ void Application::paintGL() {
batch.setFramebuffer(nullptr);
renderArgs._context->render(batch);
}
_compositor.displayOverlayTexture(&renderArgs);
@ -2995,27 +2976,14 @@ PickRay Application::computePickRay(float x, float y) const {
QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) {
const int BILLBOARD_SIZE = 64;
// Need to make sure the gl context is current here
_glWidget->makeCurrent();
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
{
gpu::Batch batch;
batch.setFramebuffer(nullptr);
batch.setFramebuffer(primaryFbo);
renderArgs->_context->render(batch);
}
renderArgs->_renderMode = RenderArgs::DEFAULT_RENDER_MODE;
renderRearViewMirror(renderArgs, QRect(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), true);
{
auto mirrorViewport = glm::ivec4(0, 0,BILLBOARD_SIZE, BILLBOARD_SIZE);
gpu::Batch batch;
batch.setFramebuffer(nullptr);
renderArgs->_context->render(batch);
}
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32);
renderArgs->_context->downloadFramebuffer(primaryFbo, glm::ivec4(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), image);
@ -3445,25 +3413,10 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi
}
renderArgs->_viewport = viewport;
{
gpu::Batch batch;
batch.setViewportTransform(viewport);
batch.setStateScissorRect(viewport);
batch.clearFramebuffer(
gpu::Framebuffer::BUFFER_COLOR0 |
gpu::Framebuffer::BUFFER_COLOR1 |
gpu::Framebuffer::BUFFER_COLOR2 |
gpu::Framebuffer::BUFFER_DEPTH,
vec4(vec3(0), 1), 1.0, 0.0, true);
// Viewport is assigned to the size of the framebuffer
renderArgs->_context->render(batch);
}
// render rear mirror view
displaySide(renderArgs, _mirrorCamera, true, billboard);
renderArgs->_viewport = originalViewport;
}
void Application::resetSensors() {

View file

@ -220,10 +220,7 @@ void Batch::setStateBlendFactor(const Vec4& factor) {
void Batch::setStateScissorRect(const Vec4i& rect) {
ADD_COMMAND(setStateScissorRect);
_params.push_back(rect.x);
_params.push_back(rect.y);
_params.push_back(rect.z);
_params.push_back(rect.w);
_params.push_back(cacheData(sizeof(Vec4i), &rect));
}
void Batch::setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size) {

View file

@ -757,11 +757,8 @@ void GLBackend::do_setStateBlendFactor(Batch& batch, uint32 paramOffset) {
}
void GLBackend::do_setStateScissorRect(Batch& batch, uint32 paramOffset) {
Vec4 rect(batch._params[paramOffset + 0]._float,
batch._params[paramOffset + 1]._float,
batch._params[paramOffset + 2]._float,
batch._params[paramOffset + 3]._float);
Vec4i rect;
memcpy(&rect, batch.editData(batch._params[paramOffset]._uint), sizeof(Vec4i));
glScissor(rect.x, rect.y, rect.z, rect.w);
(void) CHECK_GL_ERROR();

View file

@ -222,12 +222,15 @@ void DeferredLightingEffect::prepare(RenderArgs* args) {
gpu::Batch batch;
batch.setStateScissorRect(args->_viewport);
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->syncCache();
args->_context->render(batch);
}
@ -535,7 +538,6 @@ void DeferredLightingEffect::render(RenderArgs* args) {
batch.setResourceTexture(2, nullptr);
batch.setResourceTexture(3, nullptr);
args->_context->syncCache();
args->_context->render(batch);
// End of the Lighting pass
@ -548,7 +550,8 @@ void DeferredLightingEffect::copyBack(RenderArgs* args) {
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->getPrimaryFramebuffer();
auto destFbo = framebufferCache->getPrimaryFramebufferDepthColor();
// gpu::Vec4i vp = args->_viewport;
// batch.blit(_copyFBO, vp, framebufferCache->getPrimaryFramebuffer(), vp);
batch.setFramebuffer(destFbo);
@ -567,11 +570,6 @@ void DeferredLightingEffect::copyBack(RenderArgs* args) {
batch.setModelTransform(model);
}
GLenum buffers[3];
int bufferCount = 0;
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
batch._glDrawBuffers(bufferCount, buffers);
batch.setResourceTexture(0, _copyFBO->getRenderBuffer(0));
batch.draw(gpu::TRIANGLE_STRIP, 4);

View file

@ -34,7 +34,8 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) {
//If the size changed, we need to delete our FBOs
if (_frameBufferSize != frameBufferSize) {
_frameBufferSize = frameBufferSize;
_primaryFramebuffer.reset();
_primaryFramebufferFull.reset();
_primaryFramebufferDepthColor.reset();
_primaryDepthTexture.reset();
_primaryColorTexture.reset();
_primaryNormalTexture.reset();
@ -45,7 +46,8 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) {
}
void FramebufferCache::createPrimaryFramebuffer() {
_primaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
_primaryFramebufferFull = gpu::FramebufferPointer(gpu::Framebuffer::create());
_primaryFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create());
auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
auto width = _frameBufferSize.width();
@ -56,24 +58,33 @@ void FramebufferCache::createPrimaryFramebuffer() {
_primaryNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primarySpecularTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primaryFramebuffer->setRenderBuffer(0, _primaryColorTexture);
_primaryFramebuffer->setRenderBuffer(1, _primaryNormalTexture);
_primaryFramebuffer->setRenderBuffer(2, _primarySpecularTexture);
_primaryFramebufferFull->setRenderBuffer(0, _primaryColorTexture);
_primaryFramebufferFull->setRenderBuffer(1, _primaryNormalTexture);
_primaryFramebufferFull->setRenderBuffer(2, _primarySpecularTexture);
_primaryFramebufferDepthColor->setRenderBuffer(0, _primaryColorTexture);
auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH);
_primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler));
_primaryFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
_primaryFramebufferFull->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
_primaryFramebufferDepthColor->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
}
gpu::FramebufferPointer FramebufferCache::getPrimaryFramebuffer() {
if (!_primaryFramebuffer) {
if (!_primaryFramebufferFull) {
createPrimaryFramebuffer();
}
return _primaryFramebuffer;
return _primaryFramebufferFull;
}
gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferDepthColor() {
if (!_primaryFramebufferDepthColor) {
createPrimaryFramebuffer();
}
return _primaryFramebufferDepthColor;
}
gpu::TexturePointer FramebufferCache::getPrimaryDepthTexture() {

View file

@ -30,6 +30,7 @@ public:
/// Returns a pointer to the primary framebuffer object. This render target includes a depth component, and is
/// used for scene rendering.
gpu::FramebufferPointer getPrimaryFramebuffer();
gpu::FramebufferPointer getPrimaryFramebufferDepthColor();
gpu::TexturePointer getPrimaryDepthTexture();
gpu::TexturePointer getPrimaryColorTexture();
@ -55,7 +56,8 @@ private:
void createPrimaryFramebuffer();
gpu::FramebufferPointer _primaryFramebuffer;
gpu::FramebufferPointer _primaryFramebufferFull;
gpu::FramebufferPointer _primaryFramebufferDepthColor;
gpu::TexturePointer _primaryDepthTexture;
gpu::TexturePointer _primaryColorTexture;
gpu::TexturePointer _primaryNormalTexture;

View file

@ -17,6 +17,7 @@
#include <RenderArgs.h>
#include <ViewFrustum.h>
#include "FramebufferCache.h"
#include "DeferredLightingEffect.h"
#include "TextureCache.h"
@ -27,6 +28,26 @@
using namespace render;
void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
RenderArgs* args = renderContext->args;
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
gpu::Batch batch;
batch.setFramebuffer(nullptr);
batch.setFramebuffer(primaryFbo);
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);
}
void PrepareDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
DependencyManager::get<DeferredLightingEffect>()->prepare(renderContext->args);
}
@ -41,6 +62,7 @@ void ResolveDeferred::run(const SceneContextPointer& sceneContext, const RenderC
}
RenderDeferredTask::RenderDeferredTask() : Task() {
_jobs.push_back(Job(new SetupDeferred::JobModel("SetupFramebuffer")));
_jobs.push_back(Job(new DrawBackground::JobModel("DrawBackground")));
_jobs.push_back(Job(new PrepareDeferred::JobModel("PrepareDeferred")));
@ -56,7 +78,6 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
auto& renderedOpaques = _jobs.back().getOutput();
_jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", _jobs.back().getOutput())));
_jobs.push_back(Job(new DrawLight::JobModel("DrawLight")));
_jobs.push_back(Job(new ResetGLState::JobModel()));
_jobs.push_back(Job(new RenderDeferred::JobModel("RenderDeferred")));
_jobs.push_back(Job(new ResolveDeferred::JobModel("ResolveDeferred")));
_jobs.push_back(Job(new FetchItems::JobModel("FetchTransparent",
@ -133,21 +154,12 @@ void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const Rend
batch.setViewTransform(viewMat);
{
GLenum buffers[3];
int bufferCount = 0;
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
buffers[bufferCount++] = GL_COLOR_ATTACHMENT1;
buffers[bufferCount++] = GL_COLOR_ATTACHMENT2;
batch._glDrawBuffers(bufferCount, buffers);
const float OPAQUE_ALPHA_THRESHOLD = 0.5f;
args->_alphaThreshold = OPAQUE_ALPHA_THRESHOLD;
}
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOpaqueItems);
// Before rendering the batch make sure we re in sync with gl state
args->_context->syncCache();
renderContext->args->_context->syncCache();
args->_context->render((*args->_batch));
args->_batch = nullptr;
}
@ -171,21 +183,15 @@ void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const
}
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f;
{
GLenum buffers[3];
int bufferCount = 0;
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
batch._glDrawBuffers(bufferCount, buffers);
const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f;
args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD;
}
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnTransparentItems);
// Before rendering the batch make sure we re in sync with gl state
args->_context->syncCache();
args->_context->render((*args->_batch));
args->_batch = nullptr;
}
@ -239,17 +245,17 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon
}
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
batch.setPipeline(getOpaquePipeline());
batch.setResourceTexture(0, args->_whiteTexture);
if (!inItems.empty()) {
batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTH, glm::vec4(), 1.f, 0);
batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTH, glm::vec4(), 1.f, 0, true);
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOverlay3DItems);
}
// Before rendering the batch make sure we re in sync with gl state
args->_context->syncCache();
args->_context->render((*args->_batch));
args->_batch = nullptr;
args->_whiteTexture.reset();

View file

@ -16,6 +16,13 @@
#include "gpu/Pipeline.h"
class SetupDeferred {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
typedef render::Job::Model<SetupDeferred> JobModel;
};
class PrepareDeferred {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);