110 lines
3.1 KiB
C++
110 lines
3.1 KiB
C++
/*
|
|
* Copyright 2014 Google Inc. All Rights Reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#include "tango-gl/texture.h"
|
|
#include "tango-gl/util.h"
|
|
|
|
namespace tango_gl {
|
|
|
|
static const int kMaxExponentiation = 12;
|
|
|
|
static int RoundUpPowerOfTwo(int w) {
|
|
int start = 2;
|
|
for (int i = 0; i <= kMaxExponentiation; ++i) {
|
|
if (w < start) {
|
|
w = start;
|
|
break;
|
|
} else {
|
|
start = start << 1;
|
|
}
|
|
}
|
|
return w;
|
|
}
|
|
|
|
Texture::Texture(const char* file_path) {
|
|
#ifdef __ANDROID__
|
|
if (!LoadFromPNG(file_path)) {
|
|
LOGE("Texture initialing error");
|
|
}
|
|
#endif
|
|
}
|
|
#ifdef __ANDROID__
|
|
bool Texture::LoadFromPNG(const char* file_path) {
|
|
FILE* file = fopen(file_path, "rb");
|
|
|
|
if (file == NULL) {
|
|
LOGE("fp not loaded: %s", strerror(errno));
|
|
return false;
|
|
}
|
|
|
|
fseek(file, 8, SEEK_CUR);
|
|
|
|
png_structp png_ptr =
|
|
png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
|
png_infop info_ptr = png_create_info_struct(png_ptr);
|
|
|
|
png_init_io(png_ptr, file);
|
|
png_set_sig_bytes(png_ptr, 8);
|
|
png_read_info(png_ptr, info_ptr);
|
|
png_get_IHDR(png_ptr, info_ptr, &width_, &height_, &bit_depth_, &color_type_,
|
|
NULL, NULL, NULL);
|
|
|
|
width_ = RoundUpPowerOfTwo(width_);
|
|
height_ = RoundUpPowerOfTwo(height_);
|
|
int row = width_ * (color_type_ == PNG_COLOR_TYPE_RGBA ? 4 : 3);
|
|
byte_data_ = new char[row * height_];
|
|
|
|
png_bytep* row_pointers = new png_bytep[height_];
|
|
for (uint i = 0; i < height_; ++i) {
|
|
row_pointers[i] = (png_bytep)(byte_data_ + i * row);
|
|
}
|
|
png_read_image(png_ptr, row_pointers);
|
|
png_destroy_read_struct(&png_ptr, &info_ptr, 0);
|
|
|
|
glGenTextures(1, &texture_id_);
|
|
glBindTexture(GL_TEXTURE_2D, texture_id_);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
util::CheckGlError("glBindTexture");
|
|
if (color_type_ == PNG_COLOR_TYPE_RGBA) {
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA,
|
|
GL_UNSIGNED_BYTE, byte_data_);
|
|
} else {
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width_, height_, 0, GL_RGB,
|
|
GL_UNSIGNED_BYTE, byte_data_);
|
|
}
|
|
util::CheckGlError("glTexImage2D");
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
fclose(file);
|
|
delete[] row_pointers;
|
|
delete[] byte_data_;
|
|
|
|
return true;
|
|
}
|
|
#endif
|
|
GLuint Texture::GetTextureID() const { return texture_id_; }
|
|
|
|
Texture::~Texture() {
|
|
if (byte_data_ != NULL) {
|
|
delete[] byte_data_;
|
|
}
|
|
byte_data_ = NULL;
|
|
}
|
|
|
|
} // namespace tango_gl
|