X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=retrace%2Fglstate_images.cpp;h=37c0ae1da66907acdc4c4e50e4ee7714c5201301;hb=d67cc37dee7e0d60af2cd172fa135962a6dc3ce5;hp=55afdd0a00392eba28c69b3eae459f1fe2d92f94;hpb=632a78d5c90941c896fa3c7156131f27c5a58b24;p=apitrace diff --git a/retrace/glstate_images.cpp b/retrace/glstate_images.cpp index 55afdd0..37c0ae1 100644 --- a/retrace/glstate_images.cpp +++ b/retrace/glstate_images.cpp @@ -24,6 +24,7 @@ **************************************************************************/ +#include #include #include @@ -58,11 +59,6 @@ OSStatus CGSGetSurfaceBounds(CGSConnectionID, CGWindowID, CGSSurfaceID, CGRect * #endif /* __APPLE__ */ -/* Change thi to one to force interpreting depth buffers as RGBA, which enables - * visualizing full dynamic range, until we can transmit HDR images to the GUI */ -#define DEPTH_AS_RGBA 0 - - namespace glstate { @@ -71,6 +67,7 @@ struct ImageDesc GLint width; GLint height; GLint depth; + GLint samples; GLint internalFormat; inline @@ -78,9 +75,19 @@ struct ImageDesc 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; @@ -88,6 +95,31 @@ struct ImageDesc }; +/** + * Sames as enumToString, but with special provision to handle formatsLUMINANCE_ALPHA. + * + * OpenGL 2.1 specification states that "internalFormat may (for backwards + * compatibility with the 1.0 version of the GL) also take on the integer + * values 1, 2, 3, and 4, which are equivalent to symbolic constants LUMINANCE, + * LUMINANCE ALPHA, RGB, and RGBA respectively". + */ +const char * +formatToString(GLenum internalFormat) { + switch (internalFormat) { + case 1: + return "GL_LUMINANCE"; + case 2: + return "GL_LUMINANCE_ALPHA"; + case 3: + return "GL_RGB"; + case 4: + return "GL_RGBA"; + default: + return enumToString(internalFormat); + } +} + + /** * OpenGL ES does not support glGetTexLevelParameteriv, but it is possible to * probe whether a texture has a given size by crafting a dummy glTexSubImage() @@ -232,6 +264,8 @@ getActiveTextureLevelDescOES(Context &context, GLenum target, GLint level, Image static inline bool getActiveTextureLevelDesc(Context &context, GLenum target, GLint level, ImageDesc &desc) { + assert(target != GL_TEXTURE_CUBE_MAP); + if (context.ES) { return getActiveTextureLevelDescOES(context, target, level, desc); } @@ -255,35 +289,58 @@ getActiveTextureLevelDesc(Context &context, GLenum target, GLint level, ImageDes } } + glGetTexLevelParameteriv(target, level, GL_TEXTURE_SAMPLES, &desc.samples); + return desc.valid(); } -/** - * OpenGL ES does not support glGetTexImage. Obtain the pixels by attaching the - * texture to a framebuffer. - */ -static inline void -getTexImageOES(GLenum target, GLint level, ImageDesc &desc, GLubyte *pixels) +static GLenum +getTextureBinding(GLenum target) { - memset(pixels, 0x80, desc.height * desc.width * 4); - - GLenum texture_binding = GL_NONE; switch (target) { + case GL_TEXTURE_1D: + return GL_TEXTURE_BINDING_1D; + case GL_TEXTURE_1D_ARRAY: + return GL_TEXTURE_BINDING_1D_ARRAY; case GL_TEXTURE_2D: - texture_binding = GL_TEXTURE_BINDING_2D; - break; + return GL_TEXTURE_BINDING_2D; + case GL_TEXTURE_2D_MULTISAMPLE: + return GL_TEXTURE_BINDING_2D_MULTISAMPLE; + case GL_TEXTURE_2D_ARRAY: + return GL_TEXTURE_BINDING_2D_ARRAY; + case GL_TEXTURE_RECTANGLE: + return GL_TEXTURE_BINDING_RECTANGLE; + case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - texture_binding = GL_TEXTURE_BINDING_CUBE_MAP; - break; - case GL_TEXTURE_3D_OES: - texture_binding = GL_TEXTURE_BINDING_3D_OES; + return GL_TEXTURE_BINDING_CUBE_MAP; + case GL_TEXTURE_CUBE_MAP_ARRAY: + return GL_TEXTURE_BINDING_CUBE_MAP_ARRAY; + case GL_TEXTURE_3D: + return GL_TEXTURE_BINDING_3D; default: + assert(false); + return GL_NONE; + } +} + + +/** + * OpenGL ES does not support glGetTexImage. Obtain the pixels by attaching the + * texture to a framebuffer. + */ +static inline void +getTexImageOES(GLenum target, GLint level, ImageDesc &desc, GLubyte *pixels) +{ + memset(pixels, 0x80, desc.height * desc.width * 4); + + GLenum texture_binding = getTextureBinding(target); + if (texture_binding == GL_NONE) { return; } @@ -330,23 +387,134 @@ getTexImageOES(GLenum target, GLint level, ImageDesc &desc, GLubyte *pixels) } -static inline GLboolean -isDepthFormat(GLenum internalFormat) +struct InternalFormatDesc +{ + GLenum internalFormat; + GLenum format; +}; + + +static const InternalFormatDesc +internalFormatDescs[] = { + + {1, GL_RED}, + {2, GL_RG}, + {3, GL_RGB}, + {4, GL_RGBA}, + + {GL_RED, GL_RED}, + {GL_GREEN, GL_GREEN}, + {GL_BLUE, GL_BLUE}, + {GL_ALPHA, GL_ALPHA}, + {GL_RG, GL_RG}, + {GL_RGB, GL_RGB}, + {GL_BGR, GL_RGB}, + {GL_RGBA, GL_RGBA}, + {GL_BGRA, GL_RGBA}, + {GL_LUMINANCE, GL_LUMINANCE}, + {GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA}, + {GL_INTENSITY, GL_INTENSITY}, + + {GL_RG8, GL_RG}, + {GL_RG16, GL_RG}, + {GL_RGB8, GL_RGB}, + {GL_RGB16, GL_RGB}, + {GL_RGBA8, GL_RGBA}, + {GL_RGBA16, GL_RGBA}, + {GL_RGB10_A2, GL_RGBA}, + {GL_LUMINANCE8, GL_LUMINANCE}, + {GL_LUMINANCE16, GL_LUMINANCE}, + {GL_ALPHA8, GL_ALPHA}, + {GL_ALPHA16, GL_ALPHA}, + {GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA}, + {GL_LUMINANCE16_ALPHA16, GL_LUMINANCE_ALPHA}, + {GL_INTENSITY8, GL_INTENSITY}, + {GL_INTENSITY16, GL_INTENSITY}, + + {GL_RED_INTEGER, GL_RED_INTEGER}, + {GL_GREEN_INTEGER, GL_GREEN_INTEGER}, + {GL_BLUE_INTEGER, GL_BLUE_INTEGER}, + {GL_ALPHA_INTEGER, GL_ALPHA_INTEGER}, + {GL_RG_INTEGER, GL_RG_INTEGER}, + {GL_RGB_INTEGER, GL_RGB_INTEGER}, + {GL_BGR_INTEGER, GL_RGB_INTEGER}, + {GL_RGBA_INTEGER, GL_RGBA_INTEGER}, + {GL_BGRA_INTEGER, GL_RGBA_INTEGER}, + {GL_LUMINANCE_INTEGER_EXT, GL_LUMINANCE_INTEGER_EXT}, + {GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT}, + + {GL_R8I, GL_RED_INTEGER}, + {GL_R8UI, GL_RED_INTEGER}, + {GL_R16I, GL_RED_INTEGER}, + {GL_R16UI, GL_RED_INTEGER}, + {GL_R32I, GL_RED_INTEGER}, + {GL_R32UI, GL_RED_INTEGER}, + {GL_RG8I, GL_RG_INTEGER}, + {GL_RG8UI, GL_RG_INTEGER}, + {GL_RG16I, GL_RG_INTEGER}, + {GL_RG16UI, GL_RG_INTEGER}, + {GL_RG32I, GL_RG_INTEGER}, + {GL_RG32UI, GL_RG_INTEGER}, + {GL_RGB8I, GL_RGB_INTEGER}, + {GL_RGB8UI, GL_RGB_INTEGER}, + {GL_RGB16I, GL_RGB_INTEGER}, + {GL_RGB16UI, GL_RGB_INTEGER}, + {GL_RGB32I, GL_RGB_INTEGER}, + {GL_RGB32UI, GL_RGB_INTEGER}, + {GL_RGBA8I, GL_RGBA_INTEGER}, + {GL_RGBA8UI, GL_RGBA_INTEGER}, + {GL_RGBA16I, GL_RGBA_INTEGER}, + {GL_RGBA16UI, GL_RGBA_INTEGER}, + {GL_RGBA32I, GL_RGBA_INTEGER}, + {GL_RGBA32UI, GL_RGBA_INTEGER}, + {GL_RGB10_A2UI, GL_RGBA_INTEGER}, + {GL_LUMINANCE8I_EXT, GL_LUMINANCE_INTEGER_EXT}, + {GL_LUMINANCE8UI_EXT, GL_LUMINANCE_INTEGER_EXT}, + {GL_LUMINANCE16I_EXT, GL_LUMINANCE_INTEGER_EXT}, + {GL_LUMINANCE16UI_EXT, GL_LUMINANCE_INTEGER_EXT}, + {GL_LUMINANCE32I_EXT, GL_LUMINANCE_INTEGER_EXT}, + {GL_LUMINANCE32UI_EXT, GL_LUMINANCE_INTEGER_EXT}, + {GL_ALPHA8I_EXT, GL_ALPHA_INTEGER_EXT}, + {GL_ALPHA8UI_EXT, GL_ALPHA_INTEGER_EXT}, + {GL_ALPHA16I_EXT, GL_ALPHA_INTEGER_EXT}, + {GL_ALPHA16UI_EXT, GL_ALPHA_INTEGER_EXT}, + {GL_ALPHA32I_EXT, GL_ALPHA_INTEGER_EXT}, + {GL_ALPHA32UI_EXT, GL_ALPHA_INTEGER_EXT}, + {GL_LUMINANCE_ALPHA8I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT}, + {GL_LUMINANCE_ALPHA8UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT}, + {GL_LUMINANCE_ALPHA16I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT}, + {GL_LUMINANCE_ALPHA16UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT}, + {GL_LUMINANCE_ALPHA32I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT}, + {GL_LUMINANCE_ALPHA32UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT}, + {GL_INTENSITY8I_EXT, GL_RED_INTEGER}, + {GL_INTENSITY8UI_EXT, GL_RED_INTEGER}, + {GL_INTENSITY16I_EXT, GL_RED_INTEGER}, + {GL_INTENSITY16UI_EXT, GL_RED_INTEGER}, + {GL_INTENSITY32I_EXT, GL_RED_INTEGER}, + {GL_INTENSITY32UI_EXT, GL_RED_INTEGER}, + + {GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT}, + {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT}, + {GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT}, + {GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT}, + {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT}, + {GL_DEPTH_COMPONENT32F_NV, GL_DEPTH_COMPONENT}, + {GL_DEPTH_STENCIL, GL_DEPTH_COMPONENT}, + {GL_DEPTH24_STENCIL8, GL_DEPTH_COMPONENT}, + {GL_DEPTH32F_STENCIL8, GL_DEPTH_COMPONENT}, + {GL_DEPTH32F_STENCIL8_NV, GL_DEPTH_COMPONENT}, +}; + + +static GLenum +getFormat(GLenum internalFormat) { - switch (internalFormat) { - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT24: - case GL_DEPTH_COMPONENT32: - case GL_DEPTH_COMPONENT32F: - case GL_DEPTH_COMPONENT32F_NV: - case GL_DEPTH_STENCIL: - case GL_DEPTH24_STENCIL8: - case GL_DEPTH32F_STENCIL8: - case GL_DEPTH32F_STENCIL8_NV: - return GL_TRUE; - } - return GL_FALSE; + for (unsigned i = 0; i < sizeof internalFormatDescs / sizeof internalFormatDescs[0]; ++i) { + if (internalFormatDescs[i].internalFormat == internalFormat) { + return internalFormatDescs[i].format; + } + } + return GL_RGBA; } @@ -359,7 +527,6 @@ dumpActiveTextureLevel(JSONWriter &json, Context &context, GLenum target, GLint } char label[512]; - GLint active_texture = GL_TEXTURE0; glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture); snprintf(label, sizeof label, "%s, %s, level = %d", @@ -367,55 +534,29 @@ dumpActiveTextureLevel(JSONWriter &json, Context &context, GLenum target, GLint json.beginMember(label); - json.beginObject(); - - GLuint channels; - GLenum format; - if (!context.ES && isDepthFormat(desc.internalFormat)) { - format = GL_DEPTH_COMPONENT; - channels = 1; - } else { - format = GL_RGBA; - channels = 4; + GLenum format = getFormat(desc.internalFormat);; + if (context.ES && format == GL_DEPTH_COMPONENT) { + format = GL_RED; } + GLuint channels = _gl_format_channels(format);; - // Tell the GUI this is no ordinary object, but an image - json.writeStringMember("__class__", "image"); - - json.writeNumberMember("__width__", desc.width); - json.writeNumberMember("__height__", desc.height); - json.writeNumberMember("__depth__", desc.depth); - - json.writeStringMember("__format__", enumToString(desc.internalFormat)); - - // Hardcoded for now, but we could chose types more adequate to the - // texture internal format - json.writeStringMember("__type__", "uint8"); - json.writeBoolMember("__normalized__", true); - json.writeNumberMember("__channels__", channels); - - GLubyte *pixels = new GLubyte[desc.depth*desc.width*desc.height*channels]; + image::Image *image = new image::Image(desc.width, desc.height*desc.depth, channels, true); context.resetPixelPackState(); if (context.ES) { - getTexImageOES(target, level, desc, pixels); + getTexImageOES(target, level, desc, image->pixels); } else { - glGetTexImage(target, level, format, GL_UNSIGNED_BYTE, pixels); + glGetTexImage(target, level, format, GL_UNSIGNED_BYTE, image->pixels); } context.restorePixelPackState(); - json.beginMember("__data__"); - char *pngBuffer; - int pngBufferSize; - image::writePixelsToBuffer(pixels, desc.width, desc.height, channels, true, &pngBuffer, &pngBufferSize); - json.writeBase64(pngBuffer, pngBufferSize); - free(pngBuffer); - json.endMember(); // __data__ + json.writeImage(image, formatToString(desc.internalFormat), desc.depth); - delete [] pixels; - json.endObject(); + delete image; + + json.endMember(); // label } @@ -431,15 +572,18 @@ dumpTexture(JSONWriter &json, Context &context, GLenum target, GLenum binding) GLint level = 0; do { ImageDesc desc; - if (!getActiveTextureLevelDesc(context, target, level, desc)) { - break; - } if (target == GL_TEXTURE_CUBE_MAP) { for (int face = 0; face < 6; ++face) { + if (!getActiveTextureLevelDesc(context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, desc)) { + return; + } dumpActiveTextureLevel(json, context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level); } } else { + if (!getActiveTextureLevelDesc(context, target, level, desc)) { + return; + } dumpActiveTextureLevel(json, context, target, level); } @@ -489,26 +633,24 @@ getDrawableBounds(GLint *width, GLint *height) { #if defined(__linux__) if (dlsym(RTLD_DEFAULT, "eglGetCurrentContext")) { EGLContext currentContext = eglGetCurrentContext(); - if (currentContext == EGL_NO_CONTEXT) { - return false; - } + if (currentContext != EGL_NO_CONTEXT) { + EGLSurface currentSurface = eglGetCurrentSurface(EGL_DRAW); + if (currentSurface == EGL_NO_SURFACE) { + return false; + } - EGLSurface currentSurface = eglGetCurrentSurface(EGL_DRAW); - if (currentSurface == EGL_NO_SURFACE) { - return false; - } + EGLDisplay currentDisplay = eglGetCurrentDisplay(); + if (currentDisplay == EGL_NO_DISPLAY) { + return false; + } - EGLDisplay currentDisplay = eglGetCurrentDisplay(); - if (currentDisplay == EGL_NO_DISPLAY) { - return false; - } + if (!eglQuerySurface(currentDisplay, currentSurface, EGL_WIDTH, width) || + !eglQuerySurface(currentDisplay, currentSurface, EGL_HEIGHT, height)) { + return false; + } - if (!eglQuerySurface(currentDisplay, currentSurface, EGL_WIDTH, width) || - !eglQuerySurface(currentDisplay, currentSurface, EGL_HEIGHT, height)) { - return false; + return true; } - - return true; } #endif @@ -589,57 +731,55 @@ getDrawableBounds(GLint *width, GLint *height) { } -static const GLenum texture_bindings[][2] = { - {GL_TEXTURE_1D, GL_TEXTURE_BINDING_1D}, - {GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D}, - {GL_TEXTURE_3D, GL_TEXTURE_BINDING_3D}, - {GL_TEXTURE_RECTANGLE, GL_TEXTURE_BINDING_RECTANGLE}, - {GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BINDING_CUBE_MAP} +struct TextureTargetBinding +{ + GLenum target; + GLenum binding; }; -static bool -bindTexture(GLint texture, GLenum &target, GLint &bound_texture) -{ +static const GLenum +textureTargets[] = { + GL_TEXTURE_1D, + GL_TEXTURE_2D, + GL_TEXTURE_RECTANGLE, + GL_TEXTURE_CUBE_MAP, + GL_TEXTURE_3D, + GL_TEXTURE_2D_MULTISAMPLE, + GL_TEXTURE_1D_ARRAY, + GL_TEXTURE_2D_ARRAY, + GL_TEXTURE_CUBE_MAP_ARRAY, +}; - for (unsigned i = 0; i < sizeof(texture_bindings)/sizeof(texture_bindings[0]); ++i) { - target = texture_bindings[i][0]; - GLenum binding = texture_bindings[i][1]; +static GLenum +getTextureTarget(GLint texture) +{ + if (!glIsTexture(texture)) { + return GL_NONE; + } + + for (unsigned i = 0; i < sizeof(textureTargets)/sizeof(textureTargets[0]); ++i) { + GLenum target = textureTargets[i]; + GLenum binding = getTextureBinding(target); while (glGetError() != GL_NO_ERROR) ; + GLint bound_texture = 0; glGetIntegerv(binding, &bound_texture); glBindTexture(target, texture); - if (glGetError() == GL_NO_ERROR) { - return true; - } + bool succeeded = glGetError() == GL_NO_ERROR; glBindTexture(target, bound_texture); - } - - target = GL_NONE; - return false; -} - - -static bool -getTextureLevelDesc(Context &context, GLint texture, GLint level, ImageDesc &desc) -{ - GLenum target; - GLint bound_texture = 0; - if (!bindTexture(texture, target, bound_texture)) { - return false; + if (succeeded) { + return target; + } } - getActiveTextureLevelDesc(context, target, level, desc); - - glBindTexture(target, bound_texture); - - return desc.valid(); + return GL_NONE; } @@ -650,6 +790,8 @@ getBoundRenderbufferDesc(Context &context, ImageDesc &desc) 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(); @@ -693,11 +835,32 @@ getFramebufferAttachmentDesc(Context &context, GLenum target, GLenum attachment, if (object_type == GL_RENDERBUFFER) { return getRenderbufferDesc(context, object_name, desc); } else if (object_type == GL_TEXTURE) { + GLint texture_face = 0; + glGetFramebufferAttachmentParameteriv(target, attachment, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, + &texture_face); + GLint texture_level = 0; glGetFramebufferAttachmentParameteriv(target, attachment, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &texture_level); - return getTextureLevelDesc(context, object_name, texture_level, desc); + + GLint bound_texture = 0; + if (texture_face != 0) { + glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &bound_texture); + glBindTexture(GL_TEXTURE_CUBE_MAP, object_name); + getActiveTextureLevelDesc(context, texture_face, texture_level, desc); + glBindTexture(GL_TEXTURE_CUBE_MAP, bound_texture); + } else { + GLenum texture_target = getTextureTarget(object_name); + GLenum texture_binding = getTextureBinding(texture_target); + glGetIntegerv(texture_binding, &bound_texture); + glBindTexture(texture_target, object_name); + getActiveTextureLevelDesc(context, texture_target, texture_level, desc); + glBindTexture(texture_target, bound_texture); + } + + return desc.valid(); } else { std::cerr << "warning: unexpected GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = " << object_type << "\n"; return false; @@ -737,13 +900,22 @@ getDrawBufferImage() { if (draw_buffer == GL_NONE) { return NULL; } + } else { + // GL_COLOR_ATTACHMENT0 is implied + draw_buffer = GL_COLOR_ATTACHMENT0; } if (!getFramebufferAttachmentDesc(context, framebuffer_target, draw_buffer, desc)) { return NULL; } } else { - if (!context.ES) { + if (context.ES) { + // XXX: Draw buffer is always FRONT for single buffer context, BACK + // for double buffered contexts. There is no way to know which (as + // GL_DOUBLEBUFFER state is also unavailable), so always assume + // double-buffering. + draw_buffer = GL_BACK; + } else { glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer); if (draw_buffer == GL_NONE) { return NULL; @@ -758,15 +930,15 @@ getDrawBufferImage() { } GLenum type = GL_UNSIGNED_BYTE; + image::ChannelType channelType = image::TYPE_UNORM8; -#if DEPTH_AS_RGBA if (format == GL_DEPTH_COMPONENT) { - type = GL_UNSIGNED_INT; - channels = 4; + type = GL_FLOAT; + channels = 1; + channelType = image::TYPE_FLOAT; } -#endif - image::Image *image = new image::Image(desc.width, desc.height, channels, true); + image::Image *image = new image::Image(desc.width, desc.height, channels, true, channelType); if (!image) { return NULL; } @@ -818,62 +990,53 @@ dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format, { GLint channels = _gl_format_channels(format); - Context context; - - json.beginObject(); - - // Tell the GUI this is no ordinary object, but an image - json.writeStringMember("__class__", "image"); - - json.writeNumberMember("__width__", width); - json.writeNumberMember("__height__", height); - json.writeNumberMember("__depth__", 1); - - json.writeStringMember("__format__", enumToString(internalFormat)); + if (internalFormat == GL_NONE) { + internalFormat = format; + } - // Hardcoded for now, but we could chose types more adequate to the - // texture internal format - json.writeStringMember("__type__", "uint8"); - json.writeBoolMember("__normalized__", true); - json.writeNumberMember("__channels__", channels); + Context context; GLenum type = GL_UNSIGNED_BYTE; + image::ChannelType channelType = image::TYPE_UNORM8; -#if DEPTH_AS_RGBA if (format == GL_DEPTH_COMPONENT) { - type = GL_UNSIGNED_INT; - channels = 4; + type = GL_FLOAT; + channels = 1; + channelType = image::TYPE_FLOAT; } -#endif - GLubyte *pixels = new GLubyte[width*height*channels]; + image::Image *image = new image::Image(width, height, channels, true, channelType); + + while (glGetError() != GL_NO_ERROR) {} // TODO: reset imaging state too context.resetPixelPackState(); - glReadPixels(0, 0, width, height, format, type, pixels); + glReadPixels(0, 0, width, height, format, type, image->pixels); context.restorePixelPackState(); - json.beginMember("__data__"); - char *pngBuffer; - int pngBufferSize; - image::writePixelsToBuffer(pixels, width, height, channels, true, &pngBuffer, &pngBufferSize); - //std::cerr <<" Before = "<<(width * height * channels * sizeof *pixels) - // <<", after = "<