FILE * File_Ops::get_asset_FILE(const String &filename, off_t * const &start_, off_t * const &length_) { ZENI_LOGI(("Loading asset from file '" + filename + "'.").c_str()); #ifdef ANDROID AAsset* asset = AAssetManager_open(File_Ops::get_AAssetManager(), filename.c_str(), AASSET_MODE_UNKNOWN); if(!asset) { ZENI_LOGE("!asset, throwing Error"); throw File_Ops_Asset_Load_Failure(); } // open asset as file descriptor off_t start, length; int fd = AAsset_openFileDescriptor(asset, &start, &length); AAsset_close(asset); if(fd < 0) { ZENI_LOGE("!fd, throwing Error"); throw File_Ops_Asset_Load_Failure(); } FILE *file = fdopen(fd, "rb"); #else FILE *file = fopen(filename.c_str(), "rb"); #endif if(!file) { ZENI_LOGE("!file, throwing Error"); throw File_Ops_Asset_Load_Failure(); } #ifndef ANDROID if(fseek(file, 0, SEEK_END)) { ZENI_LOGE("!fseek, throwing Error"); throw File_Ops_Asset_Load_Failure(); } off_t start = 0; off_t length = ftell(file); #endif if(fseek(file, start, SEEK_SET)) { ZENI_LOGE("!fseek, throwing Error"); throw File_Ops_Asset_Load_Failure(); } #ifndef ANDROID start = ftell(file); length -= start; #endif if(start_) *start_ = start; if(length_) *length_ = length; return file; }
String & File_Ops::load_asset(String &memory, const String &filename) { off_t length; FILE * const file = get_asset_FILE(filename, 0, &length); try { memory.resize(length, '\0'); for(String::iterator it = memory.begin(), iend = memory.end(); it != iend; ++it) { int c; c = fgetc(file); if(c != EOF) *it = char(c); else { fclose(file); ZENI_LOGE("Loading from fd failed, throwing Error"); throw File_Ops_Asset_Load_Failure(); } } } catch(...) { fclose(file); throw; } fclose(file); return memory; }
bool XML_Document::try_load_mem(const String &data) { TiXmlDocument next; if(!next.Parse(data.c_str())) { ZENI_LOGE("Loading XML data failed."); return false; } else { delete m_root; m_root = 0; m_xml_file = next; TiXmlHandle root = &m_xml_file; m_root = new XML_Element(root); return true; } }
GLuint Texture_GL::build_from_Image(const Image &image) { GLuint texture_id = 0; const GLenum format = image.color_space() == Image::Luminance ? GL_LUMINANCE : image.color_space() == Image::Luminance_Alpha ? GL_LUMINANCE_ALPHA : image.color_space() == Image::RGB ? GL_RGB : GL_RGBA; int bit_count = 0; for(int bit = 1; bit; bit <<= 1) bit_count += ((image.width() & bit) != 0) + ((image.height() & bit) != 0); if(bit_count != 2) { ZENI_LOGE("Dimensions of textures must be powers of 2."); throw Texture_Init_Failure(); } glGenTextures(1, &texture_id); if(!texture_id) { ZENI_LOGE("glGenTextures(...) failed."); throw Texture_Init_Failure(); } glBindTexture(GL_TEXTURE_2D, texture_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, image.tileable() ? GL_REPEAT : GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, image.tileable() ? GL_REPEAT : GL_CLAMP_TO_EDGE); if(glGetError() == GL_INVALID_ENUM) { static bool printed = false; if(!printed) { ZENI_LOGW("Quality Warning: Your graphics card does not support GL_CLAMP_TO_EDGE in OpenGL."); printed = true; } } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Textures::get_bilinear_filtering() ? GL_LINEAR : GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Textures::get_mipmapping() ? (Textures::get_bilinear_filtering() ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST) : (Textures::get_bilinear_filtering() ? GL_LINEAR : GL_NEAREST)); #ifndef REQUIRE_GL_ES if(Textures::get_anisotropic_filtering()) { if(Textures::get_anisotropic_filtering() < 0 || Textures::get_anisotropic_filtering() > get_Video().get_maximum_anisotropy()) Textures::set_texturing_mode(get_Video().get_maximum_anisotropy(), Textures::get_bilinear_filtering(), Textures::get_mipmapping()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, Textures::get_anisotropic_filtering()); } #endif /* glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glHint(GL_FOG_HINT, GL_NICEST); */ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); if( #ifndef REQUIRE_GL_ES GLEW_VERSION_1_4 && #endif Textures::get_mipmapping()) { glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); } #ifndef REQUIRE_GL_ES if(GLEW_VERSION_1_4 || !Textures::get_mipmapping()) #endif { glTexImage2D(GL_TEXTURE_2D, 0, format, image.width(), image.height(), 0, format, GL_UNSIGNED_BYTE, static_cast<const GLvoid *>(image.get_data())); } #ifndef REQUIRE_GL_ES else { Zeni::gluBuild2DMipmaps(GL_TEXTURE_2D, format, image.width(), image.height(), format, GL_UNSIGNED_BYTE, static_cast<const GLvoid *>(image.get_data())); } #endif return texture_id; }
Image::Image(const String &filename, const bool &tileable_) : m_tileable(tileable_) { // String memory; // ZENI_LOGD("Begin Image::Image(...)::File_Ops::get_asset_FILE(...)."); // File_Ops::load_asset(memory, filename); FILE * const file = File_Ops::get_asset_FILE(filename); class file_Destroyer { public: file_Destroyer(FILE * const &file_) : m_file(file_) {} ~file_Destroyer() {fclose(m_file);} private: FILE * m_file; } file_destroyer(file); // ZENI_LOGD("End Image::Image(...)::File_Ops::load_asset(...)."); // if(memory.length() < 8u || png_sig_cmp(reinterpret_cast<png_byte *>(const_cast<char *>(memory.c_str())), 0, 8)) { png_byte header[8]; if(!fread(header, 8u, 1u, file) || png_sig_cmp(header, 0, 8)) { ZENI_LOGE("PNG detection failure."); throw Texture_Init_Failure(); } // else // ZENI_LOGD("PNG detection success."); png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(!png_ptr) { ZENI_LOGE("png_create_read_struct(...) failed."); throw Texture_Init_Failure(); } // else // ZENI_LOGD("png_create_read_struct(...) success."); class png_structp_Destroyer { public: png_structp_Destroyer(const png_structp &ptr) : m_ptr(ptr) {} ~png_structp_Destroyer() {png_destroy_read_struct(&m_ptr, NULL, NULL);} private: png_structp m_ptr; } png_structp_destroyer(png_ptr); //create png info struct png_infop info_ptr = png_create_info_struct(png_ptr); if(!info_ptr) { ZENI_LOGE("png_create_info_struct(...) failed."); throw Texture_Init_Failure(); } // else // ZENI_LOGD("png_create_info_struct(...) success."); #ifdef _WINDOWS #pragma warning( push ) #pragma warning( disable : 4611 ) #endif //png error stuff, not sure libpng man suggests this. if(setjmp(png_jmpbuf(png_ptr))) { #ifdef _WINDOWS #pragma warning( pop ) #endif ZENI_LOGE("setjmp(png_jmpbuf(...)) failed."); throw Texture_Init_Failure(); } // else // ZENI_LOGD("setjmp(png_jmpbuf(...)) success."); //init png reading // png_bytep mem_ptr = reinterpret_cast<png_bytep>(const_cast<char *>(memory.c_str() + 8u)); // png_set_read_fn(png_ptr, &mem_ptr, png_read_from_memory); png_init_io(png_ptr, file); //let libpng know you already read the first 8 bytes png_set_sig_bytes(png_ptr, 8); // read all the info up to the image data png_read_info(png_ptr, info_ptr); //variables to pass to get info int bit_depth, color_type; png_uint_32 twidth, theight; // get info about png png_get_IHDR(png_ptr, info_ptr, &twidth, &theight, &bit_depth, &color_type, NULL, NULL, NULL); if(bit_depth != 8) { ZENI_LOGE("Image using bit depth other than 8."); throw Texture_Init_Failure(); } switch(color_type) { case PNG_COLOR_TYPE_GRAY: m_color_space = Luminance; m_bytes_per_pixel = 1; break; case PNG_COLOR_TYPE_GRAY_ALPHA: m_color_space = Luminance_Alpha; m_bytes_per_pixel = 2; break; case PNG_COLOR_TYPE_RGB: m_color_space = RGB; m_bytes_per_pixel = 3; break; case PNG_COLOR_TYPE_RGB_ALPHA: m_color_space = RGBA; m_bytes_per_pixel = 4; break; default: ZENI_LOGE("Image using must be Grayscale, RGB, or RGBA."); throw Texture_Init_Failure(); } //update width and height based on png info m_size.x = int(twidth); m_size.y = int(theight); // Update the png info struct. png_read_update_info(png_ptr, info_ptr); // Row size in bytes. m_row_size = int(png_get_rowbytes(png_ptr, info_ptr)); // Allocate the image_data as a big block, to be given to opengl m_data.resize(m_row_size * theight); //row_pointers is for pointing to image_data for reading the png with libpng std::vector<Uint8 *> row_pointers(theight); // set the individual row_pointers to point at the correct offsets of image_data for(int j = 0; j < m_size.y; ++j) row_pointers[j] = &m_data[0] + j * m_row_size; //read the png into image_data through row_pointers png_read_image(png_ptr, reinterpret_cast<png_bytep *>(&row_pointers[0])); // ZENI_LOGD(("Image: " + itoa(m_size.x) + "x" + itoa(m_size.y) + "x" + itoa(m_bytes_per_pixel) + " = " + itoa(m_row_size) + ", " + itoa(m_data.size())).c_str()); }