static inline void dumpArbProgram(StateWriter &writer, Context &context, GLenum target) { if (context.ES || context.core || !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; writer.beginMember(enumToString(target)); writer.writeString(source); writer.endMember(); delete [] source; }
DataArrayCommand::DataArrayCommand(DataType _type, double _coef, double _defaultValue){ type = _type; name = enumToString(type); values = gcnew List<List<String^>^>(); coef = _coef; defaultValue = _defaultValue; }
/** * Dump the image of the currently bound read buffer. */ static inline void dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format, GLint internalFormat = GL_NONE) { GLint channels = _gl_format_channels(format); if (internalFormat == GL_NONE) { internalFormat = 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 if (format == GL_DEPTH_COMPONENT) { type = GL_UNSIGNED_INT; channels = 4; } #endif GLubyte *pixels = new GLubyte[width*height*channels]; // TODO: reset imaging state too context.resetPixelPackState(); glReadPixels(0, 0, width, height, format, type, 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 = "<<pngBufferSize << ", ratio = " << double(width * height * channels * sizeof *pixels)/pngBufferSize; json.writeBase64(pngBuffer, pngBufferSize); free(pngBuffer); json.endMember(); // __data__ delete [] pixels; json.endObject(); }
static void getShaderSource(ShaderMap &shaderMap, 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); shaderMap[enumToString(shader_type)] += source; delete [] source; }
void dumpCurrentContext(std::ostream &os) { JSONWriter json(os); #ifndef NDEBUG GLint old_bindings[NUM_BINDINGS]; for (unsigned i = 0; i < NUM_BINDINGS; ++i) { old_bindings[i] = 0; glGetIntegerv(bindings[i], &old_bindings[i]); } #endif dumpParameters(json); dumpShaders(json); dumpTextures(json); dumpFramebuffer(json); #ifndef NDEBUG for (unsigned i = 0; i < NUM_BINDINGS; ++i) { GLint new_binding = 0; glGetIntegerv(bindings[i], &new_binding); if (new_binding != old_bindings[i]) { std::cerr << "warning: " << enumToString(bindings[i]) << " was clobbered\n"; } } #endif }
static void dumpShader(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(enumToString(shader_type)); json.writeString(source); json.endMember(); delete [] source; }
static void dumpShaderObj(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(enumToString(shader_type)); json.writeString(source); json.endMember(); delete [] source; }
QVariant ConnectionTesterModel::data(const QModelIndex &index, int role) const { if (index.row() < 0 || index.row() >= m_rows.size()) { return QVariant(); } const RowData &data = m_rows.at(index.row()); switch (role) { case TestNameRole: { switch (data.testType) { case ConnectionTester::ActiveInterface: return tr("Online state"); case ConnectionTester::DefaultGateway: return tr("Gateway"); case ConnectionTester::DefaultDns: return tr("DNS"); case ConnectionTester::PingDefaultGateway: return tr("Access Gateway"); case ConnectionTester::PingGoogleDnsServer: return tr("Access IP"); case ConnectionTester::PingGoogleDomain: return tr("Access Google"); default: break; } } return enumToString(ConnectionTester, TestType, data.testType); case TestTypeRole: return (int)data.testType; case TestFinishedRole: return QVariant::fromValue(data.finished); case TestResultRole: return data.result; case TestSuccessRole: return QVariant::fromValue(data.success); default: break; } return QVariant(); }
/** * Special path to obtain texture size on OpenGL ES, that does not rely on * glGetTexLevelParameteriv */ static bool getActiveTextureLevelDescOES(Context &context, GLenum target, GLint level, ImageDesc &desc) { if (target == GL_TEXTURE_1D) { // OpenGL ES does not support 1D textures return false; } const GLint size[3] = {1, 1, 1}; if (!probeTextureLevelSizeOES(target, level, size)) { return false; } // XXX: mere guess desc.internalFormat = GL_RGBA; GLint maxSize = 0; switch (target) { case GL_TEXTURE_2D: glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); desc.width = bisectTextureLevelSizeOES(target, level, 0, maxSize); desc.height = bisectTextureLevelSizeOES(target, level, 1, maxSize); desc.depth = 1; break; 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: glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxSize); desc.width = bisectTextureLevelSizeOES(target, level, 0, maxSize); desc.height = desc.width; desc.depth = 1; break; case GL_TEXTURE_3D_OES: glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_OES, &maxSize); desc.width = bisectTextureLevelSizeOES(target, level, 0, maxSize); desc.width = bisectTextureLevelSizeOES(target, level, 1, maxSize); desc.depth = bisectTextureLevelSizeOES(target, level, 2, maxSize); break; default: return false; } if (0) { std::cerr << enumToString(target) << " " << level << " " << desc.width << "x" << desc.height << "x" << desc.depth << "\n"; } return desc.valid(); }
/** * Dump images of current draw drawable/window. */ static void dumpDrawableImages(JSONWriter &json, Context &context) { GLint width, height; if (!getDrawableBounds(&width, &height)) { return; } GLint draw_buffer = GL_NONE; if (context.ES) { draw_buffer = GL_BACK; } else { glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer); glReadBuffer(draw_buffer); } if (draw_buffer != GL_NONE) { GLint read_buffer = GL_NONE; if (!context.ES) { glGetIntegerv(GL_READ_BUFFER, &read_buffer); } GLint alpha_bits = 0; #if 0 // XXX: Ignore alpha until we are able to match the traced visual glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); #endif GLenum format = alpha_bits ? GL_RGBA : GL_RGB; json.beginMember(enumToString(draw_buffer)); dumpReadBufferImage(json, width, height, format); json.endMember(); if (!context.ES) { glReadBuffer(read_buffer); } } if (!context.ES) { GLint depth_bits = 0; glGetIntegerv(GL_DEPTH_BITS, &depth_bits); if (depth_bits) { json.beginMember("GL_DEPTH_COMPONENT"); dumpReadBufferImage(json, width, height, GL_DEPTH_COMPONENT); json.endMember(); } GLint stencil_bits = 0; glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); if (stencil_bits) { json.beginMember("GL_STENCIL_INDEX"); dumpReadBufferImage(json, width, height, GL_STENCIL_INDEX); json.endMember(); } } }
void dumpEnum(JSONWriter &json, GLenum pname) { const char *s = enumToString(pname); if (s) { json.writeString(s); } else { json.writeInt(pname); } }
void dumpEnum(StateWriter &writer, GLenum pname) { const char *s = enumToString(pname); if (s) { writer.writeString(s); } else { writer.writeInt(pname); } }
/** * Dump the specified framebuffer attachment. * * In the case of a color attachment, it assumes it is already bound for read. */ static void dumpFramebufferAttachment(JSONWriter &json, Context &context, GLenum target, GLenum attachment, GLenum format) { ImageDesc desc; if (!getFramebufferAttachmentDesc(context, target, attachment, desc)) { return; } json.beginMember(enumToString(attachment)); dumpReadBufferImage(json, desc.width, desc.height, format, desc.internalFormat); json.endMember(); }
/** * Dump the specified framebuffer attachment. * * In the case of a color attachment, it assumes it is already bound for read. */ static void dumpFramebufferAttachment(JSONWriter &json, GLenum target, GLenum attachment, GLenum format) { GLint width = 0, height = 0; if (!getFramebufferAttachmentSize(target, attachment, &width, &height)) { return; } json.beginMember(enumToString(attachment)); dumpReadBufferImage(json, width, height, format); json.endMember(); }
const InternalFormatDesc & getInternalFormatDesc(GLenum internalFormat) { for (unsigned i = 0; i < sizeof internalFormatDescs / sizeof internalFormatDescs[0]; ++i) { if (internalFormatDescs[i].internalFormat == internalFormat) { return internalFormatDescs[i]; } } std::cerr << "warning: unexpected internalFormat " << enumToString(internalFormat) << "\n"; return defaultInternalFormatDesc; }
void dumpCurrentContext(std::ostream &os) { JSONWriter json(os); #ifndef NDEBUG GLint old_bindings[NUM_BINDINGS]; for (unsigned i = 0; i < NUM_BINDINGS; ++i) { old_bindings[i] = 0; glGetIntegerv(bindings[i], &old_bindings[i]); } #endif Context context; /* Temporarily disable messages, as dumpParameters blindlessly tries to * get state, regardless the respective extension is supported or not. */ GLDEBUGPROC prevDebugCallbackFunction = 0; void *prevDebugCallbackUserParam = 0; if (context.KHR_debug) { glGetPointerv(GL_DEBUG_CALLBACK_FUNCTION, (GLvoid **) &prevDebugCallbackFunction); glGetPointerv(GL_DEBUG_CALLBACK_USER_PARAM, &prevDebugCallbackUserParam); glDebugMessageCallback(NULL, NULL); } dumpParameters(json, context); // Use our own debug-message callback. if (context.KHR_debug) { glDebugMessageCallback(debugMessageCallback, NULL); } dumpShadersUniforms(json, context); dumpTextures(json, context); dumpFramebuffer(json, context); #ifndef NDEBUG for (unsigned i = 0; i < NUM_BINDINGS; ++i) { GLint new_binding = 0; glGetIntegerv(bindings[i], &new_binding); if (new_binding != old_bindings[i]) { std::cerr << "warning: " << enumToString(bindings[i]) << " was clobbered\n"; } } #endif // Restore debug message callback if (context.KHR_debug) { glDebugMessageCallback(prevDebugCallbackFunction, prevDebugCallbackUserParam); } }
/** * Sames as enumToString, but with special provision to handle luminance/alpha * formats. * * 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); } }
/** * Dump images of current draw drawable/window. */ static void dumpDrawableImages(JSONWriter &json) { GLint width, height; if (!getDrawableBounds(&width, &height)) { return; } GLint draw_buffer = GL_NONE; glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer); glReadBuffer(draw_buffer); if (draw_buffer != GL_NONE) { GLint read_buffer = GL_NONE; glGetIntegerv(GL_READ_BUFFER, &read_buffer); GLint alpha_bits = 0; glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); GLenum format = alpha_bits ? GL_RGBA : GL_RGB; json.beginMember(enumToString(draw_buffer)); dumpReadBufferImage(json, width, height, format); json.endMember(); glReadBuffer(read_buffer); } GLint depth_bits = 0; glGetIntegerv(GL_DEPTH_BITS, &depth_bits); if (depth_bits) { json.beginMember("GL_DEPTH_COMPONENT"); dumpReadBufferImage(json, width, height, GL_DEPTH_COMPONENT); json.endMember(); } GLint stencil_bits = 0; glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); if (stencil_bits) { json.beginMember("GL_STENCIL_INDEX"); dumpReadBufferImage(json, width, height, GL_STENCIL_INDEX); json.endMember(); } }
QVariant ConnectionTesterModel::result() const { // Prepare upnp data QVariantMap upnp; QListIterator<RowData> iter(m_rows); while (iter.hasNext()) { const RowData &row = iter.next(); QString name = enumToString(ConnectionTester, TestType, row.testType); name = name.replace(QRegExp("([A-Z])"), "-\\1").toLower(); name.remove(0, 1); upnp.insert(name, row.result); } return upnp; }
GLvoid * BufferMapping::map(GLenum _target, GLuint _buffer) { if (target == _target && buffer == _buffer) { return map_pointer; } target = _target; buffer = _buffer; map_pointer = NULL; unmap = false; BufferBinding bb(target, buffer); // Recursive mappings of the same buffer are not allowed. And with the // pursuit of persistent mappings for performance this will become more // and more common. GLint mapped = GL_FALSE; glGetBufferParameteriv(target, GL_BUFFER_MAPPED, &mapped); if (mapped) { glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, &map_pointer); assert(map_pointer != NULL); GLint map_offset = 0; glGetBufferParameteriv(target, GL_BUFFER_MAP_OFFSET, &map_offset); if (map_offset != 0) { std::cerr << "warning: " << enumToString(target) << " buffer " << buffer << " is already mapped with offset " << map_offset << "\n"; // FIXME: This most likely won't work. We should remap the // buffer with the full range, then re-map when done. This // should never happen in practice with persistent mappings // though. map_pointer = (GLubyte *)map_pointer - map_offset; } } else { map_pointer = glMapBuffer(target, GL_READ_ONLY); if (map_pointer) { unmap = true; } } return map_pointer; }
void VotingManager::vote(const QString &id, VotingManager::VoteType voteType) { Q_ASSERT(m_manager != 0); if (m_reply != 0) { m_reply->disconnect(); m_reply->deleteLater(); m_reply = 0; } if (m_isBusy != true) { m_isBusy = true; emit busyChanged(); } QUrl voteUrl("http://9gag.com/vote/"+ enumToString(voteType).toLower() +"/id/" + id); m_reply = m_manager->networkManager()->createPostRequest(voteUrl, QByteArray()); m_reply->setParent(this); connect(m_reply, SIGNAL(finished()), this, SLOT(onReplyFinished())); }
Result UPnP::result() const { // List for all results QVariantList deviceResultList; foreach (UPnPHash resultHash, results) { QHashIterator<UPnP::DataType, QVariant> iter(resultHash); // results from one interface QVariantMap deviceResult; while (iter.hasNext()) { iter.next(); QString name = enumToString(UPnP, DataType, iter.key()); name = name.replace(QRegExp("([A-Z])"), "_\\1").toLower(); name.remove(0, 1); deviceResult.insert(name, iter.value()); } deviceResultList.append(deviceResult); }
static inline void dumpArbProgram(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(enumToString(target)); json.writeString(source); json.endMember(); delete [] source; }
/** * Dump an uniform that belows to an uniform block. */ static void dumpUniformBlock(StateWriter &writer, GLint program, GLint size, GLenum type, const GLchar *name, GLuint index, GLuint block_index) { GLint offset = 0; GLint array_stride = 0; GLint matrix_stride = 0; GLint is_row_major = GL_FALSE; glGetActiveUniformsiv(program, 1, &index, GL_UNIFORM_OFFSET, &offset); glGetActiveUniformsiv(program, 1, &index, GL_UNIFORM_ARRAY_STRIDE, &array_stride); glGetActiveUniformsiv(program, 1, &index, GL_UNIFORM_MATRIX_STRIDE, &matrix_stride); glGetActiveUniformsiv(program, 1, &index, GL_UNIFORM_IS_ROW_MAJOR, &is_row_major); GLint slot = -1; glGetActiveUniformBlockiv(program, block_index, GL_UNIFORM_BLOCK_BINDING, &slot); if (slot == -1) { return; } AttribDesc desc(type, size, array_stride, matrix_stride, is_row_major); if (!desc) { return; } if (0) { GLint active_uniform_block_max_name_length = 0; glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &active_uniform_block_max_name_length); GLchar* block_name = new GLchar[active_uniform_block_max_name_length]; GLint block_data_size = 0; glGetActiveUniformBlockiv(program, index, GL_UNIFORM_BLOCK_DATA_SIZE, &block_data_size); GLsizei length = 0; glGetActiveUniformBlockName(program, index, active_uniform_block_max_name_length, &length, block_name); std::cerr << "uniform `" << name << "`, size " << size << ", type " << enumToString(desc.type) << "\n" << " block " << block_index << ", name `" << block_name << "`, size " << block_data_size << "; binding " << slot << "; \n" << " offset " << offset << ", array stride " << array_stride << ", matrix stride " << matrix_stride << ", row_major " << is_row_major << "\n" ; delete [] block_name; } GLint ubo = 0; glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, slot, &ubo); GLint start = 0; glGetIntegeri_v(GL_UNIFORM_BUFFER_START, slot, &start); BufferMapping mapping; const GLbyte *raw_data = (const GLbyte *)mapping.map(GL_UNIFORM_BUFFER, ubo); if (raw_data) { std::string qualifiedName = resolveUniformName(name, size); dumpAttribArray(writer, qualifiedName, desc, raw_data + start + offset); } }
#include "DataBlock.h" DataBlock::DataBlock(CheckBox^ _chkBox, DataType _type) { chkBox = _chkBox; type = _type; name = enumToString(type); oldSign = ","; newSign = "."; } void DataBlock::setChecked(bool checked) { chkBox->Checked = checked; } bool DataBlock::isChecked() { return chkBox->Checked; } void DataBlock::save(String^ time, String ^ baseFileName) { String^ fileName = gcnew String("results/" + baseFileName + "/" + name + ".txt"); StreamWriter^ swn = gcnew StreamWriter(fileName, true); swn->Write(time + ";" + data->Replace(oldSign, newSign)); swn->WriteLine(); swn->Close(); delete swn; } void DataBlock::setSeparationSign(String ^ ch) { if (ch == ";") {
/** * 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 = GL_NONE; switch (target) { case GL_TEXTURE_2D: texture_binding = GL_TEXTURE_BINDING_2D; break; 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; default: return; } GLint texture = 0; glGetIntegerv(texture_binding, &texture); if (!texture) { return; } GLint prev_fbo = 0; GLuint fbo = 0; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prev_fbo); glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); GLenum status; switch (target) { case GL_TEXTURE_2D: 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: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, level); status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { std::cerr << __FUNCTION__ << ": " << enumToString(status) << "\n"; } glReadPixels(0, 0, desc.width, desc.height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); break; case GL_TEXTURE_3D_OES: for (int i = 0; i < desc.depth; i++) { glFramebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, texture, level, i); glReadPixels(0, 0, desc.width, desc.height, GL_RGBA, GL_UNSIGNED_BYTE, pixels + 4 * i * desc.width * desc.height); } break; } glBindFramebuffer(GL_FRAMEBUFFER, prev_fbo); glDeleteFramebuffers(1, &fbo); }
void validateCast( MetadataElement::Type actualType, MetadataElement::Type targetType) { if ( actualType!=targetType ) { MR4C_THROW(std::runtime_error, "Illegal metadata cast attempt: " << enumToString(actualType) << " to " << enumToString(targetType)); } }
/** * OpenGL ES does not support glGetTexLevelParameteriv, but it is possible to * probe whether a texture has a given size by crafting a dummy glTexSubImage() * call. */ static bool probeTextureLevelSizeOES(GLenum target, GLint level, const GLint size[3]) { while (glGetError() != GL_NO_ERROR) ; GLenum internalFormat = GL_RGBA; GLenum type = GL_UNSIGNED_BYTE; GLint dummy = 0; switch (target) { case GL_TEXTURE_2D: 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: glTexSubImage2D(target, level, size[0], size[1], 0, 0, internalFormat, type, &dummy); break; case GL_TEXTURE_3D_OES: glTexSubImage3DOES(target, level, size[0], size[1], size[2], 0, 0, 0, internalFormat, type, &dummy); default: assert(0); return false; } GLenum error = glGetError(); if (0) { std::cerr << "(" << size[0] << ", " << size[1] << ", " << size[2] << ") = " << enumToString(error) << "\n"; } if (error == GL_NO_ERROR) { return true; } while (glGetError() != GL_NO_ERROR) ; return false; }
static inline void dumpActiveTextureLevel(JSONWriter &json, Context &context, GLenum target, GLint level) { ImageDesc desc; if (!getActiveTextureLevelDesc(context, target, level, desc)) { return; } char label[512]; GLint active_texture = GL_TEXTURE0; glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture); snprintf(label, sizeof label, "%s, %s, level = %d", enumToString(active_texture), enumToString(target), level); 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; } // 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]; context.resetPixelPackState(); if (context.ES) { getTexImageOES(target, level, desc, pixels); } else { glGetTexImage(target, level, format, GL_UNSIGNED_BYTE, 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__ delete [] pixels; json.endObject(); }
image::Image * getDrawBufferImage() { GLenum format = GL_RGB; GLint channels = _gl_format_channels(format); if (channels > 4) { return NULL; } Context context; GLenum framebuffer_binding; GLenum framebuffer_target; if (context.ES) { framebuffer_binding = GL_FRAMEBUFFER_BINDING; framebuffer_target = GL_FRAMEBUFFER; } else { framebuffer_binding = GL_DRAW_FRAMEBUFFER_BINDING; framebuffer_target = GL_DRAW_FRAMEBUFFER; } GLint draw_framebuffer = 0; glGetIntegerv(framebuffer_binding, &draw_framebuffer); GLint draw_buffer = GL_NONE; ImageDesc desc; if (draw_framebuffer) { if (context.ARB_draw_buffers) { glGetIntegerv(GL_DRAW_BUFFER0, &draw_buffer); if (draw_buffer == GL_NONE) { return NULL; } } if (!getFramebufferAttachmentDesc(context, framebuffer_target, draw_buffer, desc)) { return NULL; } } else { if (!context.ES) { glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer); if (draw_buffer == GL_NONE) { return NULL; } } if (!getDrawableBounds(&desc.width, &desc.height)) { return NULL; } desc.depth = 1; } GLenum type = GL_UNSIGNED_BYTE; #if DEPTH_AS_RGBA if (format == GL_DEPTH_COMPONENT) { type = GL_UNSIGNED_INT; channels = 4; } #endif image::Image *image = new image::Image(desc.width, desc.height, channels, true); if (!image) { return NULL; } while (glGetError() != GL_NO_ERROR) {} GLint read_framebuffer = 0; GLint read_buffer = GL_NONE; if (!context.ES) { glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer); glBindFramebuffer(GL_READ_FRAMEBUFFER, draw_framebuffer); glGetIntegerv(GL_READ_BUFFER, &read_buffer); glReadBuffer(draw_buffer); } // TODO: reset imaging state too context.resetPixelPackState(); glReadPixels(0, 0, desc.width, desc.height, format, type, image->pixels); context.restorePixelPackState(); if (!context.ES) { glReadBuffer(read_buffer); glBindFramebuffer(GL_READ_FRAMEBUFFER, read_framebuffer); } GLenum error = glGetError(); if (error != GL_NO_ERROR) { do { std::cerr << "warning: " << enumToString(error) << " while getting snapshot\n"; error = glGetError(); } while(error != GL_NO_ERROR); delete image; return NULL; } return image; }