static inline void
writeTextureImage(JSONWriter &json, GLenum target, GLint level)
{
- json.beginMember("__image__");
-
GLint width = 0, height = 0;
glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
if (!width || !height) {
json.writeNull();
} else {
+ 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__", "float");
+ json.writeNumberMember("__channels__", 4);
+
float *pixels = new float[width*height*4];
+
glGetTexImage(target, level, GL_RGBA, GL_FLOAT, pixels);
- json.beginArray();
- for (GLint y = 0; y < height; ++y) {
+
+ if (0) {
+ json.writeStringMember("__encoding__", "array");
+ json.beginMember("__data__");
+
json.beginArray();
- for (GLint x = 0; x < width; ++x) {
+ for (GLint y = 0; y < height; ++y) {
json.beginArray();
- for (GLint chan = 0; chan < 4; ++chan) {
- json.writeNumber(pixels[(y*width + x)*4 + chan]);
+ for (GLint x = 0; x < width; ++x) {
+ json.beginArray();
+ for (GLint chan = 0; chan < 4; ++chan) {
+ json.writeNumber(pixels[(y*width + x)*4 + chan]);
+ }
+ json.endArray();
}
json.endArray();
}
json.endArray();
+ json.endMember(); // __data__
+ } else {
+ json.writeStringMember("__encoding__", "base64");
+ json.beginMember("__data__");
+ json.writeBase64(pixels, width * height * 4 * sizeof *pixels);
+ json.endMember(); // __data__
}
- json.endArray();
+
delete [] pixels;
+ json.endObject();
}
}
'''
print ' json.writeNumber(height);'
print ' json.endMember();'
print
+ print ' json.beginMember("image");'
print ' writeTextureImage(json, target, level);'
+ print ' json.endMember();'
print
print ' json.endObject();'
print ' ++level;'
os << "\"";
}
+ void encodeBase64String(const unsigned char *bytes, size_t size) {
+ const char *table64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ unsigned char c0, c1, c2, c3;
+ char buf[4];
+ unsigned written;
+
+ os << "\"";
+
+ written = 0;
+ while (size >= 3) {
+ c0 = bytes[0] >> 2;
+ c1 = ((bytes[0] & 0x03) << 4) | ((bytes[1] & 0xf0) >> 4);
+ c2 = ((bytes[1] & 0x0f) << 2) | ((bytes[2] & 0xc0) >> 6);
+ c3 = bytes[2] & 0x3f;
+
+ buf[0] = table64[c0];
+ buf[1] = table64[c1];
+ buf[2] = table64[c2];
+ buf[3] = table64[c3];
+
+ os.write(buf, 4);
+
+ bytes += 3;
+ size -= 3;
+ ++written;
+
+ if (written >= 76/4) {
+ os << "\n";
+ written = 0;
+ }
+ }
+
+ if (size > 0) {
+ c0 = bytes[0] >> 2;
+ c1 = ((bytes[0] & 0x03) << 4);
+
+ if (size > 1) {
+ c1 |= ((bytes[1] & 0xf0) >> 4);
+ c2 = ((bytes[1] & 0x0f) << 2);
+ if (size > 2) {
+ c2 |= ((bytes[2] & 0xc0) >> 6);
+ c3 = bytes[2] & 0x3f;
+ buf[3] = table64[c3];
+ } else {
+ buf[3] = '=';
+ }
+ buf[2] = table64[c2];
+ } else {
+ buf[3] = '=';
+ buf[2] = '=';
+ }
+ buf[1] = table64[c1];
+ buf[0] = table64[c0];
+
+ os.write(buf, 4);
+ }
+
+ os << "\"";
+ }
+
public:
JSONWriter(std::ostream &_os) :
os(_os),
space = ' ';
}
+ inline void writeBase64(const void *bytes, size_t size) {
+ separator();
+ encodeBase64String((const unsigned char *)bytes, size);
+ value = true;
+ space = ' ';
+ }
+
inline void writeNull(void) {
separator();
os << "null";
}
template<class T>
- void writeNumber(T n) {
+ inline void writeNumber(T n) {
separator();
os << std::dec << n;
value = true;
space = ' ';
}
+
+ inline void writeStringMember(const char *name, const char *s) {
+ beginMember(name);
+ writeString(s);
+ endMember();
+ }
+
+ inline void writeBoolMember(const char *name, bool b) {
+ beginMember(name);
+ writeBool(b);
+ endMember();
+ }
+
+ template<class T>
+ inline void writeNumberMember(const char *name, T n) {
+ beginMember(name);
+ writeNumber(n);
+ endMember();
+ }
};
#endif /* _JSON_HPP_ */