X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=retrace%2Fglstate_images.cpp;h=598d56cceb8e2746bec9e22fc519609d33667b64;hb=2b4c51753aeb95015fa3fba58654bf44ea18a370;hp=6390980966a91c8e17048718b20f01630e6aa338;hpb=c748fbcb434374ec13e14cc837ade7c581789e0c;p=apitrace diff --git a/retrace/glstate_images.cpp b/retrace/glstate_images.cpp index 6390980..598d56c 100644 --- a/retrace/glstate_images.cpp +++ b/retrace/glstate_images.cpp @@ -24,6 +24,7 @@ **************************************************************************/ +#include #include #include @@ -88,6 +89,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 +258,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); } @@ -359,7 +387,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,8 +394,6 @@ dumpActiveTextureLevel(JSONWriter &json, Context &context, GLenum target, GLint json.beginMember(label); - json.beginObject(); - GLuint channels; GLenum format; if (!context.ES && isDepthFormat(desc.internalFormat)) { @@ -379,43 +404,23 @@ dumpActiveTextureLevel(JSONWriter &json, Context &context, GLenum target, GLint channels = 4; } - // 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 +436,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); } @@ -737,13 +745,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; @@ -824,23 +841,6 @@ dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum 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)); - - // 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); - GLenum type = GL_UNSIGNED_BYTE; #if DEPTH_AS_RGBA @@ -850,27 +850,18 @@ dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format, } #endif - GLubyte *pixels = new GLubyte[width*height*channels]; + image::Image *image = new image::Image(width, height, channels, true); // 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 = "<