- # shaders
- print '''
-static void
-writeShader(JSONWriter &json, GLuint shader)
-{
- if (!shader) {
- return;
- }
-
- GLint shader_type = 0;
- glGetShaderiv(shader, GL_SHADER_TYPE, &shader_type);
- if (!shader_type) {
- return;
- }
-
- GLint source_length = 0;
- glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &source_length);
- if (!source_length) {
- return;
- }
-
- GLchar *source = new GLchar[source_length];
- GLsizei length = 0;
- source[0] = 0;
- glGetShaderSource(shader, source_length, &length, source);
-
- json.beginMember(enum_string(shader_type));
- json.writeString(source);
- json.endMember();
-
- delete [] source;
-}
-
-static void
-writeShaderObj(JSONWriter &json, GLhandleARB shaderObj)
-{
- if (!shaderObj) {
- return;
- }
-
- GLint shader_type = 0;
- glGetObjectParameterivARB(shaderObj, GL_OBJECT_TYPE_ARB, &shader_type);
- if (!shader_type) {
- return;
- }
-
- GLint source_length = 0;
- glGetObjectParameterivARB(shaderObj, GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &source_length);
- if (!source_length) {
- return;
- }
-
- GLcharARB *source = new GLcharARB[source_length];
- GLsizei length = 0;
- source[0] = 0;
- glGetShaderSource(shaderObj, source_length, &length, source);
-
- json.beginMember(enum_string(shader_type));
- json.writeString(source);
- json.endMember();
-
- delete [] source;
-}
-
-static inline void
-writeCurrentProgram(JSONWriter &json)
-{
- GLint program = 0;
- glGetIntegerv(GL_CURRENT_PROGRAM, &program);
- if (!program) {
- return;
- }
-
- GLint attached_shaders = 0;
- glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
- if (!attached_shaders) {
- return;
- }
-
- GLuint *shaders = new GLuint[attached_shaders];
- GLsizei count = 0;
- glGetAttachedShaders(program, attached_shaders, &count, shaders);
- for (GLsizei i = 0; i < count; ++ i) {
- writeShader(json, shaders[i]);
- }
- delete [] shaders;
-}
-
-static inline void
-writeCurrentProgramObj(JSONWriter &json)
-{
- GLhandleARB programObj = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
- if (!programObj) {
- return;
- }
-
- GLint attached_shaders = 0;
- glGetProgramivARB(programObj, GL_OBJECT_ATTACHED_OBJECTS_ARB, &attached_shaders);
- if (!attached_shaders) {
- return;
- }
-
- GLhandleARB *shaderObjs = new GLhandleARB[attached_shaders];
- GLsizei count = 0;
- glGetAttachedObjectsARB(programObj, attached_shaders, &count, shaderObjs);
- for (GLsizei i = 0; i < count; ++ i) {
- writeShaderObj(json, shaderObjs[i]);
- }
- delete [] shaderObjs;
-}
-
-static inline void
-writeArbProgram(JSONWriter &json, GLenum target)
-{
- if (!glIsEnabled(target)) {
- return;
- }
-
- GLint program_length = 0;
- glGetProgramivARB(target, GL_PROGRAM_LENGTH_ARB, &program_length);
- if (!program_length) {
- return;
- }
-
- GLchar *source = new GLchar[program_length + 1];
- source[0] = 0;
- glGetProgramStringARB(target, GL_PROGRAM_STRING_ARB, source);
- source[program_length] = 0;
-
- json.beginMember(enum_string(target));
- json.writeString(source);
- json.endMember();
-
- delete [] source;
-}
-'''
-
- # texture image
- print '''
-static inline void
-writeTextureImage(JSONWriter &json, GLenum target, GLint level)
-{
- GLint width, height = 1, depth = 1;
-
- width = 0;
- glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
-
- if (target != GL_TEXTURE_1D) {
- height = 0;
- glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
- if (target == GL_TEXTURE_3D) {
- depth = 0;
- glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth);
- }
- }
-
- if (width <= 0 || height <= 0 || depth <= 0) {
- return;
- } else {
- char label[512];
-
- GLint active_texture = GL_TEXTURE0;
- glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
- snprintf(label, sizeof label, "%s, %s, level = %i", _enum_string(active_texture), _enum_string(target), level);
-
- json.beginMember(label);
-
- 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__", depth);
-
- // 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__", 4);
-
- GLubyte *pixels = new GLubyte[depth*width*height*4];
-
- glGetTexImage(target, level, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
-
- json.beginMember("__data__");
- char *pngBuffer;
- int pngBufferSize;
- Image::writePixelsToBuffer(pixels, width, height, 4, false, &pngBuffer, &pngBufferSize);
- json.writeBase64(pngBuffer, pngBufferSize);
- free(pngBuffer);
- json.endMember(); // __data__
-
- delete [] pixels;
- json.endObject();
- }
-}
-
-static inline void
-writeDrawBufferImage(JSONWriter &json, GLenum format)
-{
- GLint channels = __gl_format_channels(format);
-
- if (!glretrace::drawable) {
- json.writeNull();
- } else {
- GLint width = glretrace::drawable->width;
- GLint height = glretrace::drawable->height;
-
- 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);
-
- // 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[width*height*channels];
-
- GLint drawbuffer = glretrace::double_buffer ? GL_BACK : GL_FRONT;
- GLint readbuffer = glretrace::double_buffer ? GL_BACK : GL_FRONT;
- glGetIntegerv(GL_DRAW_BUFFER, &drawbuffer);
- glGetIntegerv(GL_READ_BUFFER, &readbuffer);
- glReadBuffer(drawbuffer);
-
- glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
-
- glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, pixels);
-
- glPopClientAttrib();
- glReadBuffer(readbuffer);
-
- json.beginMember("__data__");
- char *pngBuffer;
- int pngBufferSize;
- Image::writePixelsToBuffer(pixels, width, height, channels, false, &pngBuffer, &pngBufferSize);
- //std::cerr <<" Before = "<<(width * height * channels * sizeof *pixels)
- // <<", after = "<<pngBufferSize << ", ratio = " << double(width * height * channels * sizeof *pixels)/pngBufferSize;
- json.writeBase64(pngBuffer, pngBufferSize);
- free(pngBuffer);
- json.endMember(); // __data__
-
- delete [] pixels;
- json.endObject();
- }
-}
-
-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();
- }
-}
-
-'''
-
- # textures
- print 'static inline void'
- print 'writeTexture(JSONWriter &json, GLenum target, GLenum binding)'
- print '{'
- print ' GLint texture_binding = 0;'
- print ' glGetIntegerv(binding, &texture_binding);'
- print ' if (!glIsEnabled(target) && !texture_binding) {'
- print ' return;'
- print ' }'
- print
- print ' GLint level = 0;'
- print ' do {'
- print ' GLint width = 0, height = 0;'
- print ' glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);'
- print ' glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);'
- print ' if (!width || !height) {'
- print ' break;'
- print ' }'
- print
- print ' if (target == GL_TEXTURE_CUBE_MAP) {'
- print ' for (int face = 0; face < 6; ++face) {'
- print ' writeTextureImage(json, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level);'
- print ' }'
- print ' } else {'
- print ' writeTextureImage(json, target, level);'
- print ' }'
- print
- print ' ++level;'
- print ' } while(true);'
- print '}'
- print
-
- print 'void glretrace::state_dump(std::ostream &os)'