GLint width;
GLint height;
GLint depth;
+ GLint samples;
GLint internalFormat;
inline
width(0),
height(0),
depth(0),
+ samples(0),
internalFormat(GL_NONE)
{}
+ inline bool
+ operator == (const ImageDesc &other) const {
+ return width == other.width &&
+ height == other.height &&
+ depth == other.depth &&
+ samples == other.samples &&
+ internalFormat == other.internalFormat;
+ }
+
inline bool
valid(void) const {
return width > 0 && height > 0 && depth > 0;
}
}
+ glGetTexLevelParameteriv(target, level, GL_TEXTURE_SAMPLES, &desc.samples);
+
return desc.valid();
}
}
+static inline GLboolean
+isIntegerFormat(GLenum internalFormat)
+{
+ switch (internalFormat) {
+
+ case GL_RG_INTEGER:
+ case GL_RED_INTEGER:
+ case GL_GREEN_INTEGER:
+ case GL_BLUE_INTEGER:
+ case GL_ALPHA_INTEGER:
+ case GL_RGB_INTEGER:
+ case GL_RGBA_INTEGER:
+ case GL_BGR_INTEGER:
+ case GL_BGRA_INTEGER:
+ case GL_LUMINANCE_INTEGER_EXT:
+ case GL_LUMINANCE_ALPHA_INTEGER_EXT:
+
+ case GL_R8I:
+ case GL_R8UI:
+ case GL_R16I:
+ case GL_R16UI:
+ case GL_R32I:
+ case GL_R32UI:
+ case GL_RG8I:
+ case GL_RG8UI:
+ case GL_RG16I:
+ case GL_RG16UI:
+ case GL_RG32I:
+ case GL_RG32UI:
+ case GL_RGB8I:
+ case GL_RGB8UI:
+ case GL_RGB16I:
+ case GL_RGB16UI:
+ case GL_RGB32I:
+ case GL_RGB32UI:
+ case GL_RGBA8I:
+ case GL_RGBA8UI:
+ case GL_RGBA16I:
+ case GL_RGBA16UI:
+ case GL_RGBA32I:
+ case GL_RGBA32UI:
+ case GL_RGB10_A2UI:
+ case GL_LUMINANCE8I_EXT:
+ case GL_LUMINANCE8UI_EXT:
+ case GL_LUMINANCE16I_EXT:
+ case GL_LUMINANCE16UI_EXT:
+ case GL_LUMINANCE32I_EXT:
+ case GL_LUMINANCE32UI_EXT:
+ case GL_ALPHA8I_EXT:
+ case GL_ALPHA8UI_EXT:
+ case GL_ALPHA16I_EXT:
+ case GL_ALPHA16UI_EXT:
+ case GL_ALPHA32I_EXT:
+ case GL_ALPHA32UI_EXT:
+ case GL_LUMINANCE_ALPHA8I_EXT:
+ case GL_LUMINANCE_ALPHA8UI_EXT:
+ case GL_LUMINANCE_ALPHA16I_EXT:
+ case GL_LUMINANCE_ALPHA16UI_EXT:
+ case GL_LUMINANCE_ALPHA32I_EXT:
+ case GL_LUMINANCE_ALPHA32UI_EXT:
+ case GL_INTENSITY8I_EXT:
+ case GL_INTENSITY8UI_EXT:
+ case GL_INTENSITY16I_EXT:
+ case GL_INTENSITY16UI_EXT:
+ case GL_INTENSITY32I_EXT:
+ case GL_INTENSITY32UI_EXT:
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+}
+
+
static inline void
dumpActiveTextureLevel(JSONWriter &json, Context &context, GLenum target, GLint level)
{
GLuint channels;
GLenum format;
if (!context.ES && isDepthFormat(desc.internalFormat)) {
- format = GL_DEPTH_COMPONENT;
- channels = 1;
+ format = GL_DEPTH_COMPONENT;
+ channels = 1;
} else {
- format = GL_RGBA;
- channels = 4;
+ if (isIntegerFormat(desc.internalFormat)) {
+ format = GL_RGBA_INTEGER;
+ } else {
+ format = GL_RGBA;
+ }
+ channels = 4;
}
image::Image *image = new image::Image(desc.width, desc.height*desc.depth, channels, true);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &desc.height);
desc.depth = 1;
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &desc.samples);
+
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_INTERNAL_FORMAT, &desc.internalFormat);
return desc.valid();
image::Image *image = new image::Image(width, height, channels, true);
+ while (glGetError() != GL_NO_ERROR) {}
+
// TODO: reset imaging state too
context.resetPixelPackState();
context.restorePixelPackState();
- json.writeImage(image, formatToString(internalFormat));
+ GLenum error = glGetError();
+ if (error != GL_NO_ERROR) {
+ do {
+ std::cerr << "warning: " << enumToString(error) << " while reading framebuffer\n";
+ error = glGetError();
+ } while(error != GL_NO_ERROR);
+ json.writeNull();
+ } else {
+ json.writeImage(image, formatToString(internalFormat));
+ }
delete image;
}
static inline GLuint
downsampledFramebuffer(Context &context,
GLuint oldFbo, GLint drawbuffer,
- GLint colorRb, GLint depthRb, GLint stencilRb,
+ const ImageDesc &colorDesc,
+ const ImageDesc &depthDesc,
+ const ImageDesc &stencilDesc,
GLuint *rbs, GLint *numRbs)
{
GLuint fbo;
{
// color buffer
- ImageDesc desc;
- glBindRenderbuffer(GL_RENDERBUFFER, colorRb);
- getBoundRenderbufferDesc(context, desc);
-
glGenRenderbuffers(1, &rbs[*numRbs]);
glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
- glRenderbufferStorage(GL_RENDERBUFFER, desc.internalFormat, desc.width, desc.height);
+ glRenderbufferStorage(GL_RENDERBUFFER, colorDesc.internalFormat, colorDesc.width, colorDesc.height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, drawbuffer,
GL_RENDERBUFFER, rbs[*numRbs]);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glDrawBuffer(drawbuffer);
glReadBuffer(drawbuffer);
- glBlitFramebuffer(0, 0, desc.width, desc.height, 0, 0, desc.width, desc.height,
+ glBlitFramebuffer(0, 0, colorDesc.width, colorDesc.height, 0, 0, colorDesc.width, colorDesc.height,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
++*numRbs;
}
- if (stencilRb == depthRb && stencilRb) {
+ if (stencilDesc == depthDesc &&
+ depthDesc.valid()) {
//combined depth and stencil buffer
- ImageDesc desc;
- glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
- getBoundRenderbufferDesc(context, desc);
-
glGenRenderbuffers(1, &rbs[*numRbs]);
glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
- glRenderbufferStorage(GL_RENDERBUFFER, desc.internalFormat, desc.width, desc.height);
+ glRenderbufferStorage(GL_RENDERBUFFER, depthDesc.internalFormat, depthDesc.width, depthDesc.height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, rbs[*numRbs]);
glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
- glBlitFramebuffer(0, 0, desc.width, desc.height, 0, 0, desc.width, desc.height,
+ glBlitFramebuffer(0, 0, depthDesc.width, depthDesc.height, 0, 0, depthDesc.width, depthDesc.height,
GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
++*numRbs;
} else {
- if (depthRb) {
- ImageDesc desc;
- glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
- getBoundRenderbufferDesc(context, desc);
-
+ if (depthDesc.valid()) {
glGenRenderbuffers(1, &rbs[*numRbs]);
glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
- glRenderbufferStorage(GL_RENDERBUFFER, desc.internalFormat, desc.width, desc.height);
+ glRenderbufferStorage(GL_RENDERBUFFER, depthDesc.internalFormat, depthDesc.width, depthDesc.height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, rbs[*numRbs]);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glDrawBuffer(GL_DEPTH_ATTACHMENT);
glReadBuffer(GL_DEPTH_ATTACHMENT);
- glBlitFramebuffer(0, 0, desc.width, desc.height, 0, 0, desc.width, desc.height,
+ glBlitFramebuffer(0, 0, depthDesc.width, depthDesc.height, 0, 0, depthDesc.width, depthDesc.height,
GL_DEPTH_BUFFER_BIT, GL_NEAREST);
++*numRbs;
}
- if (stencilRb) {
- ImageDesc desc;
- glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);
- getBoundRenderbufferDesc(context, desc);
-
+ if (stencilDesc.valid()) {
glGenRenderbuffers(1, &rbs[*numRbs]);
glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
- glRenderbufferStorage(GL_RENDERBUFFER, desc.internalFormat, desc.width, desc.height);
+ glRenderbufferStorage(GL_RENDERBUFFER, stencilDesc.internalFormat, stencilDesc.width, stencilDesc.height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, rbs[*numRbs]);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glDrawBuffer(GL_STENCIL_ATTACHMENT);
glReadBuffer(GL_STENCIL_ATTACHMENT);
- glBlitFramebuffer(0, 0, desc.width, desc.height, 0, 0, desc.width, desc.height,
+ glBlitFramebuffer(0, 0, stencilDesc.width, stencilDesc.height, 0, 0, stencilDesc.width, stencilDesc.height,
GL_STENCIL_BUFFER_BIT, GL_NEAREST);
++*numRbs;
}
return;
}
+ assert(desc.samples == 0);
+
json.beginMember(enumToString(attachment));
dumpReadBufferImage(json, desc.width, desc.height, format, desc.internalFormat);
json.endMember();
} else if (context.ES) {
dumpFramebufferAttachments(json, context, GL_FRAMEBUFFER);
} else {
- GLint colorRb = 0, stencilRb = 0, depthRb = 0;
GLint draw_buffer0 = GL_NONE;
glGetIntegerv(GL_DRAW_BUFFER0, &draw_buffer0);
bool multisample = false;
GLint boundRb = 0;
glGetIntegerv(GL_RENDERBUFFER_BINDING, &boundRb);
- GLint object_type;
- glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, draw_buffer0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &object_type);
- if (object_type == GL_RENDERBUFFER) {
- glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, draw_buffer0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &colorRb);
- glBindRenderbuffer(GL_RENDERBUFFER, colorRb);
- GLint samples = 0;
- glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
- if (samples) {
+ ImageDesc colorDesc;
+ if (getFramebufferAttachmentDesc(context, GL_DRAW_FRAMEBUFFER, draw_buffer0, colorDesc)) {
+ if (colorDesc.samples) {
multisample = true;
}
}
- glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &object_type);
- if (object_type == GL_RENDERBUFFER) {
- glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthRb);
- glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
- GLint samples = 0;
- glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
- if (samples) {
+ ImageDesc depthDesc;
+ if (getFramebufferAttachmentDesc(context, GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthDesc)) {
+ if (depthDesc.samples) {
multisample = true;
}
}
- glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &object_type);
- if (object_type == GL_RENDERBUFFER) {
- glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &stencilRb);
- glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);
- GLint samples = 0;
- glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
- if (samples) {
+ ImageDesc stencilDesc;
+ if (getFramebufferAttachmentDesc(context, GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, stencilDesc)) {
+ if (stencilDesc.samples) {
multisample = true;
}
}
- glBindRenderbuffer(GL_RENDERBUFFER, boundRb);
-
GLuint rbs[3];
GLint numRbs = 0;
GLuint fboCopy = 0;
// to blit the fbo to a temporary one
fboCopy = downsampledFramebuffer(context,
boundDrawFbo, draw_buffer0,
- colorRb, depthRb, stencilRb,
+ colorDesc, depthDesc, stencilDesc,
rbs, &numRbs);
+ } else {
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, boundDrawFbo);
}
- dumpFramebufferAttachments(json, context, GL_DRAW_FRAMEBUFFER);
+ dumpFramebufferAttachments(json, context, GL_READ_FRAMEBUFFER);
if (multisample) {
- glBindRenderbuffer(GL_RENDERBUFFER_BINDING, boundRb);
+ glBindRenderbuffer(GL_RENDERBUFFER, boundRb);
glDeleteRenderbuffers(numRbs, rbs);
glDeleteFramebuffers(1, &fboCopy);
}