("glGet", X, 1, "GL_PROXY_TEXTURE_1D"), # 0x8063
("glGet", X, 1, "GL_PROXY_TEXTURE_2D"), # 0x8064
("glGet", X, 1, "GL_TEXTURE_TOO_LARGE_EXT"), # 0x8065
- ("glGetTexParameter", I, 1, "GL_TEXTURE_PRIORITY"), # 0x8066
+ ("glGetTexParameter", F, 1, "GL_TEXTURE_PRIORITY"), # 0x8066
("glGetTexParameter", B, 1, "GL_TEXTURE_RESIDENT"), # 0x8067
("glGet", I, 1, "GL_TEXTURE_BINDING_1D"), # 0x8068
("glGet", I, 1, "GL_TEXTURE_BINDING_2D"), # 0x8069
glGetVertexAttrib = StateGetter('glGetVertexAttrib', {I: 'iv', F: 'fv', D: 'dv', P: 'Pointerv'})
glGetTexParameter = StateGetter('glGetTexParameter', {I: 'iv', F: 'fv'})
+glGetTexLevelParameter = StateGetter('glGetTexLevelParameter', {I: 'iv', F: 'fv'})
class JsonWriter(Visitor):
def dump(self):
print '#include <string.h>'
print '#include <iostream>'
+ print '#include <algorithm>'
print
print '#include "json.hpp"'
print '#include "glimports.hpp"'
}
}
+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 ' }'
print
print ' json.beginObject();'
- print
- print ' GLfloat param;'
- for function, type, count, name in parameters:
- if function != 'glGetTexParameter' or count != 1:
- continue
- print ' glGetTexParameterfv(target, %s, ¶m);' % name
- print ' json.beginMember("%s");' % name
- JsonWriter().visit(type, 'param')
- print ' json.endMember();'
- print
- print
print ' json.beginMember("levels");'
print ' json.beginArray();'
print ' GLint level = 0;'
print ' json.writeNumber(texture);'
print ' json.endMember();'
print
- # TODO: Generalize this
- for function, type, count, name in parameters:
- if function != 'glGetTexLevelParameter' or count != 1:
- continue
- print ' glGetTexLevelParameterfv(target, level, %s, ¶m);' % name
- print ' json.beginMember("%s");' % name
- JsonWriter().visit(type, 'param')
- print ' json.endMember();'
- print
print ' json.beginMember("image");'
print ' writeTextureImage(json, target, level);'
print ' json.endMember();'
def dump_parameters(self):
print ' json.beginMember("parameters");'
print ' json.beginObject();'
- for function, type, count, name in parameters:
- if function != 'glGet':
- continue
- if type is X:
- continue
-
- print ' // %s' % name
- print ' {'
- type, value = glGet(name)
- print ' if (glGetError() != GL_NO_ERROR) {'
- #print ' std::cerr << "warning: %s(%s) failed\\n";' % (glGet.radical, name)
- print ' } else {'
- print ' json.beginMember("%s");' % name
- JsonWriter().visit(type, value)
- print ' json.endMember();'
- print ' }'
- print ' }'
- print
+
+ self.dump_atoms(glGet)
self.dump_vertex_attribs()
+ self.dump_texture_parameters()
print ' json.endObject();'
print ' json.endMember(); // parameters'
print
def dump_vertex_attribs(self):
- print ' json.beginMember("vertex_attrib");'
- print ' json.beginArray();'
print ' GLint max_vertex_attribs = 0;'
print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs);'
print ' for (GLint index = 0; index < max_vertex_attribs; ++index) {'
+ print ' char name[32];'
+ print ' snprintf(name, sizeof name, "GL_VERTEX_ATTRIB_ARRAY%i", index);'
+ print ' json.beginMember(name);'
print ' json.beginObject();'
- for function, type, count, name in parameters:
- if function != 'glGetVertexAttrib':
- continue
- if type is X:
- contine
- print ' // %s' % name
- print ' {'
- type, value = glGetVertexAttrib('index', name)
- print ' if (glGetError() != GL_NO_ERROR) {'
- #print ' std::cerr << "warning: %s(%s) failed\\n";' % (glGet.radical, name)
- print ' } else {'
- print ' json.beginMember("%s");' % name
- JsonWriter().visit(type, value)
- print ' json.endMember();'
- print ' }'
- print ' }'
- print
+ self.dump_atoms(glGetVertexAttrib, 'index')
print ' json.endObject();'
+ print ' json.endMember(); // GL_VERTEX_ATTRIB_ARRAYi'
print ' }'
print
- print ' json.endArray();'
- print ' json.endMember(); // vertex_attrib'
+
+ def dump_texture_parameters(self):
+ print ' {'
+ print ' GLint active_texture = GL_TEXTURE0;'
+ print ' glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);'
+ print ' GLint max_texture_coords = 0;'
+ print ' glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);'
+ print ' GLint max_combined_texture_image_units = 0;'
+ print ' glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_combined_texture_image_units);'
+ print ' GLint max_units = std::max(max_combined_texture_image_units, max_texture_coords);'
+ print ' for (GLint unit = 0; unit < max_units; ++unit) {'
+ print ' char name[32];'
+ print ' snprintf(name, sizeof name, "GL_TEXTURE%i", unit);'
+ print ' json.beginMember(name);'
+ print ' glActiveTexture(GL_TEXTURE0 + unit);'
+ print ' json.beginObject();'
+ print ' GLint texture;'
+ print
+ for target, binding in texture_targets:
+ print ' // %s' % target
+ print ' texture = 0;'
+ print ' glGetIntegerv(%s, &texture);' % binding
+ print ' if (glIsEnabled(%s) || texture) {' % target
+ print ' json.beginMember("%s");' % target
+ print ' json.beginObject();'
+ self.dump_atoms(glGetTexParameter, target)
+ # We only dump the first level parameters
+ self.dump_atoms(glGetTexLevelParameter, target, "0")
+ print ' json.endObject();'
+ print ' json.endMember(); // %s' % target
+ print ' }'
+ print
+ print ' json.endObject();'
+ print ' json.endMember(); // GL_TEXTUREi'
+ print ' }'
+ print ' glActiveTexture(active_texture);'
+ print ' }'
print
def dump_current_program(self):
print
def dump_textures(self):
- print ' json.beginMember("textures");'
- print ' json.beginArray();'
- print ' GLint active_texture = GL_TEXTURE0;'
- print ' glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);'
- print ' GLint max_texture_coords = 0;'
- print ' glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);'
- print ' for (GLint unit = 0; unit < max_texture_coords; ++unit) {'
- print ' glActiveTexture(GL_TEXTURE0 + unit);'
- print ' json.beginObject();'
+ print ' {'
+ print ' json.beginMember("textures");'
+ print ' json.beginArray();'
+ print ' GLint active_texture = GL_TEXTURE0;'
+ print ' glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);'
+ print ' GLint max_texture_coords = 0;'
+ print ' glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);'
+ print ' GLint max_combined_texture_image_units = 0;'
+ print ' glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_combined_texture_image_units);'
+ print ' GLint max_units = std::max(max_combined_texture_image_units, max_texture_coords);'
+ print ' for (GLint unit = 0; unit < max_units; ++unit) {'
+ print ' glActiveTexture(GL_TEXTURE0 + unit);'
+ print ' json.beginObject();'
for target, binding in texture_targets:
- print ' json.beginMember("%s");' % target
- print ' writeTexture(json, %s, %s);' % (target, binding)
- print ' json.endMember();'
- print ' json.endObject();'
+ print ' json.beginMember("%s");' % target
+ print ' writeTexture(json, %s, %s);' % (target, binding)
+ print ' json.endMember();'
+ print ' json.endObject();'
+ print ' }'
+ print ' glActiveTexture(active_texture);'
+ print ' json.endArray();'
+ print ' json.endMember(); // texture'
print ' }'
- print ' glActiveTexture(active_texture);'
- print ' json.endArray();'
- print ' json.endMember(); // texture'
print
def dump_framebuffer(self):
print ' json.beginObject();'
# TODO: Handle real FBOs
print
- print ' json.beginMember("GL_RGBA");'
- print ' writeDrawBufferImage(json, GL_RGBA);'
- print ' json.endMember();'
+ print ' GLint boundDrawFbo = 0, boundReadFbo = 0;'
+ print ' glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundDrawFbo);'
+ print ' glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundReadFbo);'
+ print ' if (!boundDrawFbo) {'
+ print ' GLint depth_bits = 0;'
+ print ' glGetIntegerv(GL_DEPTH_BITS, &depth_bits);'
+ print ' GLint stencil_bits = 0;'
+ print ' glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);'
+ print ' writeDrawBuffers(json, depth_bits, stencil_bits);'
+ print ' } else {'
+ print ' GLint colorRb, stencilRb, depthRb;'
+ print ' GLint boundRb;'
+ print ' glGetIntegerv(GL_RENDERBUFFER_BINDING, &boundRb);'
+ print ' GLint drawbuffer = glretrace::double_buffer ? GL_BACK : GL_FRONT;'
+ print ' glGetIntegerv(GL_DRAW_BUFFER, &drawbuffer);'
print
- print ' GLint depth_bits = 0;'
- print ' glGetIntegerv(GL_DEPTH_BITS, &depth_bits);'
- print ' if (depth_bits) {'
- print ' json.beginMember("GL_DEPTH_COMPONENT");'
- print ' writeDrawBufferImage(json, GL_DEPTH_COMPONENT);'
- print ' json.endMember();'
- print ' }'
+ print ' glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,'
+ print ' drawbuffer,'
+ print ' GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,'
+ print ' &colorRb);'
+ print ' glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,'
+ print ' GL_DEPTH_ATTACHMENT,'
+ print ' GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,'
+ print ' &depthRb);'
+ print ' glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,'
+ print ' GL_STENCIL_ATTACHMENT,'
+ print ' GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,'
+ print ' &stencilRb);'
print
- print ' GLint stencil_bits = 0;'
- print ' glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);'
- print ' if (stencil_bits) {'
- print ' json.beginMember("GL_STENCIL_INDEX");'
- print ' writeDrawBufferImage(json, GL_STENCIL_INDEX);'
- print ' json.endMember();'
+ print ' GLint colorSamples, depthSamples, stencilSamples;'
+ print ' GLuint rbs[3];'
+ print ' GLint numRbs = 0;'
+ print ' GLuint fboCopy = 0;'
+ print ' glBindRenderbuffer(GL_RENDERBUFFER, colorRb);'
+ print ' glGetRenderbufferParameteriv(GL_RENDERBUFFER,'
+ print ' GL_RENDERBUFFER_SAMPLES, &colorSamples);'
+ print ' glBindRenderbuffer(GL_RENDERBUFFER, depthRb);'
+ print ' glGetRenderbufferParameteriv(GL_RENDERBUFFER,'
+ print ' GL_RENDERBUFFER_SAMPLES, &depthSamples);'
+ print ' glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);'
+ print ' glGetRenderbufferParameteriv(GL_RENDERBUFFER,'
+ print ' GL_RENDERBUFFER_SAMPLES, &stencilSamples);'
+ print ' glBindRenderbuffer(GL_RENDERBUFFER, boundRb);'
+ print
+ print ' if (colorSamples || depthSamples || stencilSamples) {'
+ print ' //glReadPixels doesnt support multisampled buffers so we need'
+ print ' // to blit the fbo to a temporary one'
+ print ' fboCopy = downsampledFramebuffer(boundDrawFbo, drawbuffer,'
+ print ' colorRb, depthRb, stencilRb,'
+ print ' rbs, &numRbs);'
+ print ' }'
+ print ' glDrawBuffer(drawbuffer);'
+ print ' glReadBuffer(drawbuffer);'
+ print
+ print ' writeDrawBuffers(json, depthRb, stencilRb);'
+ print
+ print ' if (fboCopy) {'
+ print ' glBindFramebuffer(GL_FRAMEBUFFER, boundDrawFbo);'
+ print ' glBindFramebuffer(GL_READ_FRAMEBUFFER, boundReadFbo);'
+ print ' glBindFramebuffer(GL_DRAW_FRAMEBUFFER, boundDrawFbo);'
+ print ' glBindRenderbuffer(GL_RENDERBUFFER_BINDING, boundRb);'
+ print ' glDeleteRenderbuffers(numRbs, rbs);'
+ print ' glDeleteFramebuffers(1, &fboCopy);'
+ print ' }'
print ' }'
print
print ' json.endObject();'
print ' json.endMember(); // framebuffer'
pass
+ def dump_atoms(self, getter, *args):
+ for function, type, count, name in parameters:
+ if function != getter.inflector.radical:
+ continue
+ if type is X:
+ continue
+ print ' // %s' % name
+ print ' {'
+ type, value = getter(*(args + (name,)))
+ print ' if (glGetError() != GL_NO_ERROR) {'
+ #print ' std::cerr << "warning: %s(%s) failed\\n";' % (glGet.radical, name)
+ print ' } else {'
+ print ' json.beginMember("%s");' % name
+ JsonWriter().visit(type, value)
+ print ' json.endMember();'
+ print ' }'
+ print ' }'
+ print
+
def write_line(s):
self.write(' '*self.level + s + '\n')