Introducing the download Framebuffer call on the context to capture a snapshot

This commit is contained in:
Sam Gateau 2015-07-23 16:15:10 -07:00
parent dc10f30d3d
commit be9d99264f
7 changed files with 31 additions and 26 deletions

View file

@ -2998,18 +2998,8 @@ PickRay Application::computePickRay(float x, float y) const {
}
QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) {
/* auto primaryFramebuffer = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFramebuffer));
// clear the alpha channel so the background is transparent
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
*/
// const int BILLBOARD_SIZE = 64;
const int BILLBOARD_SIZE = 256;
const int BILLBOARD_SIZE = 64;
_glWidget->makeCurrent();
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
@ -3020,26 +3010,18 @@ QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) {
batch.setFramebuffer(primaryFbo);
renderArgs->_context->render(batch);
}
renderArgs->_renderMode = RenderArgs::MIRROR_RENDER_MODE;
renderRearViewMirror(renderArgs, QRect(0, /*_glWidget->getDeviceHeight() - BILLBOARD_SIZE*/ 0,
BILLBOARD_SIZE, BILLBOARD_SIZE),
false);
renderArgs->_renderMode = RenderArgs::NORMAL_RENDER_MODE;
renderArgs->_renderMode = RenderArgs::NORMAL_RENDER_MODE;
renderRearViewMirror(renderArgs, QRect(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), true);
auto selfieFbo = DependencyManager::get<FramebufferCache>()->getSelfieFramebuffer();
{
auto mirrorViewport = glm::ivec4(0, 0,BILLBOARD_SIZE, BILLBOARD_SIZE);
gpu::Batch batch;
// batch.blit(primaryFbo, mirrorViewport, selfieFbo, mirrorViewport);
batch.setFramebuffer(nullptr);
renderArgs->_context->render(batch);
}
QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32);
glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFbo));
glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
glBindFramebuffer(GL_FRAMEBUFFER, 0);
renderArgs->_context->downloadFramebuffer(primaryFbo, glm::ivec4(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), image);
return image;
}

View file

@ -108,7 +108,6 @@ public:
void blit(const FramebufferPointer& src, const Vec4i& srcViewport,
const FramebufferPointer& dst, const Vec4i& dstViewport);
// Query Section
void beginQuery(const QueryPointer& query);
void endQuery(const QueryPointer& query);

View file

@ -40,4 +40,8 @@ void Context::render(Batch& batch) {
void Context::syncCache() {
PROFILE_RANGE(__FUNCTION__);
_backend->syncCache();
}
}
void Context::downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) {
_backend->downloadFramebuffer(srcFramebuffer, region, destImage);
}

View file

@ -28,6 +28,8 @@ public:
virtual~ Backend() {};
virtual void render(Batch& batch) = 0;
virtual void syncCache() = 0;
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0;
class TransformObject {
public:
@ -121,6 +123,10 @@ public:
void syncCache();
// Downloading the Framebuffer is a synchronous action that is not efficient.
// It s here for convenience to easily capture a snapshot
void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage);
protected:
Context(const Context& context);

View file

@ -14,8 +14,6 @@
#include "Texture.h"
#include <memory>
class QImage;
namespace gpu {
typedef Element Format;

View file

@ -38,6 +38,10 @@ public:
// Let's try to avoid to do that as much as possible!
virtual void syncCache();
// This is the ugly "download the pixels to sysmem for taking a snapshot"
// Just avoid using it, it's ugly and will break performances
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage);
static bool checkGLError(const char* name = nullptr);
// Only checks in debug builds

View file

@ -11,6 +11,8 @@
#include "GPULogging.h"
#include "GLBackendShared.h"
#include "qimage.h"
using namespace gpu;
GLBackend::GLFramebuffer::GLFramebuffer() {}
@ -191,3 +193,13 @@ void GLBackend::do_blit(Batch& batch, uint32 paramOffset) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, getFramebufferID(_output._framebuffer));
}
}
void GLBackend::downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(srcFramebuffer));
glReadPixels(region.x, region.y, region.z, region.w, GL_BGRA, GL_UNSIGNED_BYTE, destImage.bits());
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
(void) CHECK_GL_ERROR();
}