/***************************
テクスチャ
***************************/
#include "Texture.h"
#include <libpng/jni/png.h>
namespace sys
{
/*****************************************
作成
引数 data = テクスチャデータ
*****************************************/
void Texture::make(const u8* data)
{
clear();
glGenTextures(1, &texture); // テクスチャオブジェクト作成
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
switch ( format ) {
case FORMAT_RGBA :
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
break;
case FORMAT_RGB :
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
break;
}
}
/**********
削除
**********/
void Texture::clear(void)
{
if ( texture ) {
glDeleteTextures(1, &texture);
texture = 0;
}
}
/********************************
メモリ読み込みコールバック
********************************/
static
void png_read(png_structp png_ptr, png_bytep data, png_size_t length)
{
u8** _p = (u8**)png_get_io_ptr(png_ptr); // データポインタ
memcpy(data, *_p, length);
*_p += length;
}
/**********************************
PNG読み込み
引数 data = PNGデータ
**********************************/
void Texture::load_png(const u8* data)
{
png_structp _png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
assert(_png);
png_infop _info = png_create_info_struct(_png);
assert(_info);
png_set_read_fn(_png, NULL, png_read);
png_init_io(_png, (png_FILE_p)&data);
png_read_info(_png, _info);
png_uint_32 _width, _height;
int _bit_depth, _color_type;
png_get_IHDR(_png, _info, &_width, &_height, &_bit_depth, &_color_type, NULL, NULL, NULL);
switch ( _color_type ) {
case PNG_COLOR_TYPE_RGB :
format = FORMAT_RGB;
break;
case PNG_COLOR_TYPE_PALETTE :
png_set_palette_to_rgb(_png);
png_read_update_info(_png, _info);
png_get_IHDR(_png, _info, &_width, &_height, &_bit_depth, &_color_type, NULL, NULL, NULL);
format = (_color_type == PNG_COLOR_TYPE_RGB) ? FORMAT_RGB : FORMAT_RGBA;
break;
case PNG_COLOR_TYPE_GRAY :
png_set_gray_to_rgb(_png);
png_read_update_info(_png, _info);
format = FORMAT_RGB;
break;
case PNG_COLOR_TYPE_GRAY_ALPHA :
png_set_gray_to_rgb(_png);
png_read_update_info(_png, _info);
format = FORMAT_RGBA;
break;
default :
format = FORMAT_RGBA;
break;
}
width = (short)_width;
height = (short)_height;
int _row_bytes = width*((format == FORMAT_RGBA) ? 4 : 3);
u8* _buf = (u8*)memalign(4, _row_bytes*height);
png_bytep _rows[height];
assert(_buf != NULL);
for (int i = 0; i < height; i++) {
_rows[i] = _buf + i*_row_bytes;
}
png_read_image(_png, _rows);
make(_buf); // テクスチャ作成
png_destroy_read_struct(&_png, &_info, NULL);
free(_buf);
}
}
/**************** End of File ******************************************/
・PNG読み込み(load_png)
大体は libpngの普通の使い方になっていますが、ちょっと変えているのは以下の2点。
libpngは基本的にデータをファイルから読み込むようになっていますが、メモリから読み込むように読み込みコールバックを差し替えています(76行目)。
また、ピクセルフォーマットを24ビットRGB(不透明)か、32ビットRGBA(α付き)に揃えています(84行目から)。
・テクスチャ設定(make)
glGenTexturesでテクスチャオブジェクトを作成して、glTexImage2Dでデータの設定という、これまた普通の使い方です。
コメントをする