+static inline GLuint
+downsampledFramebuffer(GLuint oldFbo, GLint drawbuffer,
+ GLint colorRb, GLint depthRb, GLint stencilRb,
+ GLuint *rbs, GLint *numRbs)
+{
+ GLuint fbo;
+ GLint format;
+ GLint w, h;
+
+ *numRbs = 0;
+
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, colorRb);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_WIDTH, &w);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_HEIGHT, &h);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
+
+ glGenRenderbuffers(1, &rbs[*numRbs]);
+ glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
+ glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, drawbuffer,
+ GL_RENDERBUFFER, rbs[*numRbs]);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+ glDrawBuffer(drawbuffer);
+ glReadBuffer(drawbuffer);
+ glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ ++*numRbs;
+
+ if (stencilRb == depthRb && stencilRb) {
+ //combined depth and stencil buffer
+ glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_WIDTH, &w);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_HEIGHT, &h);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
+
+ glGenRenderbuffers(1, &rbs[*numRbs]);
+ glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
+ glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, rbs[*numRbs]);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+ glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
+ GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ ++*numRbs;
+ } else {
+ if (depthRb) {
+ glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_WIDTH, &w);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_HEIGHT, &h);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
+
+ glGenRenderbuffers(1, &rbs[*numRbs]);
+ glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
+ glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, rbs[*numRbs]);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+ glDrawBuffer(GL_DEPTH_ATTACHMENT);
+ glReadBuffer(GL_DEPTH_ATTACHMENT);
+ glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
+ GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ ++*numRbs;
+ }
+ if (stencilRb) {
+ glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_WIDTH, &w);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_HEIGHT, &h);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
+
+ glGenRenderbuffers(1, &rbs[*numRbs]);
+ glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
+ glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, rbs[*numRbs]);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+ glDrawBuffer(GL_STENCIL_ATTACHMENT);
+ glReadBuffer(GL_STENCIL_ATTACHMENT);
+ glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
+ GL_STENCIL_BUFFER_BIT, GL_NEAREST);
+ ++*numRbs;
+ }
+ }
+
+ return fbo;
+}
+
+static void
+writeDrawBuffers(JSONWriter &json, GLboolean writeDepth, GLboolean writeStencil)
+{
+ json.beginMember("GL_RGBA");
+ writeDrawBufferImage(json, GL_RGBA);
+ json.endMember();
+
+ if (writeDepth) {
+ json.beginMember("GL_DEPTH_COMPONENT");
+ writeDrawBufferImage(json, GL_DEPTH_COMPONENT);
+ json.endMember();
+ }
+
+ if (writeStencil) {
+ json.beginMember("GL_STENCIL_INDEX");
+ writeDrawBufferImage(json, GL_STENCIL_INDEX);
+ json.endMember();
+ }
+}
+