00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "tango-gl/texture.h"
00017 #include "tango-gl/util.h"
00018
00019 namespace tango_gl {
00020
00021 static const int kMaxExponentiation = 12;
00022
00023 static int RoundUpPowerOfTwo(int w) {
00024 int start = 2;
00025 for (int i = 0; i <= kMaxExponentiation; ++i) {
00026 if (w < start) {
00027 w = start;
00028 break;
00029 } else {
00030 start = start << 1;
00031 }
00032 }
00033 return w;
00034 }
00035
00036 Texture::Texture(const char* file_path) {
00037 if (!LoadFromPNG(file_path)) {
00038 LOGE("Texture initialing error");
00039 }
00040 }
00041
00042 bool Texture::LoadFromPNG(const char* file_path) {
00043 FILE* file = fopen(file_path, "rb");
00044
00045 if (file == NULL) {
00046 LOGE("fp not loaded: %s", strerror(errno));
00047 return false;
00048 }
00049
00050 fseek(file, 8, SEEK_CUR);
00051
00052 png_structp png_ptr =
00053 png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
00054 png_infop info_ptr = png_create_info_struct(png_ptr);
00055
00056 png_init_io(png_ptr, file);
00057 png_set_sig_bytes(png_ptr, 8);
00058 png_read_info(png_ptr, info_ptr);
00059 png_get_IHDR(png_ptr, info_ptr, &width_, &height_, &bit_depth_, &color_type_,
00060 NULL, NULL, NULL);
00061
00062 width_ = RoundUpPowerOfTwo(width_);
00063 height_ = RoundUpPowerOfTwo(height_);
00064 int row = width_ * (color_type_ == PNG_COLOR_TYPE_RGBA ? 4 : 3);
00065 byte_data_ = new char[row * height_];
00066
00067 png_bytep* row_pointers = new png_bytep[height_];
00068 for (uint i = 0; i < height_; ++i) {
00069 row_pointers[i] = (png_bytep)(byte_data_ + i * row);
00070 }
00071 png_read_image(png_ptr, row_pointers);
00072 png_destroy_read_struct(&png_ptr, &info_ptr, 0);
00073
00074 glGenTextures(1, &texture_id_);
00075 glBindTexture(GL_TEXTURE_2D, texture_id_);
00076 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00077 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00078 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00079 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00080 util::CheckGlError("glBindTexture");
00081 if (color_type_ == PNG_COLOR_TYPE_RGBA) {
00082 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA,
00083 GL_UNSIGNED_BYTE, byte_data_);
00084 } else {
00085 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width_, height_, 0, GL_RGB,
00086 GL_UNSIGNED_BYTE, byte_data_);
00087 }
00088 util::CheckGlError("glTexImage2D");
00089 glBindTexture(GL_TEXTURE_2D, 0);
00090
00091 fclose(file);
00092 delete[] row_pointers;
00093 delete[] byte_data_;
00094
00095 return true;
00096 }
00097
00098 GLuint Texture::GetTextureID() const { return texture_id_; }
00099
00100 Texture::~Texture() {
00101 if (byte_data_ != NULL) {
00102 delete[] byte_data_;
00103 }
00104 byte_data_ = NULL;
00105 }
00106
00107 }