- added percentage support for min / map hp on damage particles

- bugfixes for png support for pixmap3d (water textures)
This commit is contained in:
Mark Vejvoda
2011-07-01 23:13:55 +00:00
parent 850825695e
commit 7c996e3296
9 changed files with 334 additions and 24 deletions

View File

@@ -192,4 +192,146 @@ Pixmap2D* PNGReader::read(ifstream& is, const string& path, Pixmap2D* ret) const
return ret;
}
PNGReader3D::PNGReader3D(): FileReader<Pixmap3D>(getExtensionsPng()) {}
Pixmap3D* PNGReader3D::read(ifstream& is, const string& path, Pixmap3D* ret) const {
//Read file
is.seekg(0, ios::end);
size_t length = is.tellg();
is.seekg(0, ios::beg);
uint8 *buffer = new uint8[8];
is.read((char*)buffer, 8);
if (png_sig_cmp(buffer, 0, 8) != 0) {
delete [] buffer;
return NULL; //This is not a PNG file - could be used for fast checking whether file is supported or not
}
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
delete [] buffer;
return NULL;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_read_struct(&png_ptr, (png_infopp)NULL,(png_infopp)NULL);
delete [] buffer;
return NULL;
}
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr,(png_infopp)NULL);
delete [] buffer;
return NULL; //Error during init_io
}
png_set_read_fn(png_ptr, &is, user_read_data);
png_set_sig_bytes(png_ptr, 8);
png_read_info(png_ptr, info_ptr);
int width = info_ptr->width;
int height = info_ptr->height;
int color_type = info_ptr->color_type;
int bit_depth = info_ptr->bit_depth;
//We want RGB, 24 bit
if (color_type == PNG_COLOR_TYPE_PALETTE || (color_type == PNG_COLOR_TYPE_GRAY && info_ptr->bit_depth < 8) || (info_ptr->valid & PNG_INFO_tRNS)) {
png_set_expand(png_ptr);
}
if (color_type == PNG_COLOR_TYPE_GRAY) {
png_set_gray_to_rgb(png_ptr);
}
int number_of_passes = png_set_interlace_handling(png_ptr);
png_read_update_info(png_ptr, info_ptr);
png_bytep* row_pointers = new png_bytep[height];
if (setjmp(png_jmpbuf(png_ptr))) {
delete[] row_pointers;
delete [] buffer;
return NULL; //error during read_image
}
for (int y = 0; y < height; ++y) {
row_pointers[y] = new png_byte[info_ptr->rowbytes];
}
png_read_image(png_ptr, row_pointers);
size_t fileComponents = info_ptr->rowbytes/info_ptr->width;
size_t picComponents = (ret->getComponents()==-1)?fileComponents:ret->getComponents();
//std::cout << "PNG-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << fileComponents << std::endl;
//picComponents = 4;
//Copy image
//printf("pixmap3d loading path [%s] w = %d h = %d d = %d comp = %d\n",path.c_str(),width,height,ret->getD(),picComponents);
ret->init(width,height,ret->getD(),(int)picComponents);
uint8* pixels = ret->getPixels();
if(ret->getSlice() > 0) {
pixels = &pixels[ret->getSlice()*width*height*picComponents];
}
const size_t rowbytes = info_ptr->rowbytes;
size_t location = 0;
for (int y = height-1; y >= 0; --y) { //you have to somehow invert the lines
if (picComponents == fileComponents) {
memcpy(pixels+location,row_pointers[y],rowbytes);
} else {
int r,g,b,a,l;
for (size_t xPic = 0, xFile = 0; xFile < rowbytes; xPic+= picComponents, xFile+= fileComponents) {
switch(fileComponents) {
case 3:
r = row_pointers[y][xFile];
g = row_pointers[y][xFile+1];
b = row_pointers[y][xFile+2];
l = (r+g+b+2)/3;
a = 255;
break;
case 4:
r = row_pointers[y][xFile];
g = row_pointers[y][xFile+1];
b = row_pointers[y][xFile+2];
l = (r+g+b+2)/3;
a = row_pointers[y][xFile+3];
break;
default:
//TODO: Error
case 1:
r = g = b = l = row_pointers[y][xFile];
a = 255;
break;
}
switch (picComponents) {
case 1:
pixels[location+xPic] = l;
break;
case 4:
pixels[location+xPic+3] = a; //Next case
case 3:
pixels[location+xPic] = r;
pixels[location+xPic+1] = g;
pixels[location+xPic+2] = b;
break;
default:
//just so at least something works
for (unsigned int i = 0; i < picComponents; ++i) {
pixels[location+xPic+i] = l;
}
//TODO: Error
}
}
}
location += picComponents * width;
}
for (int y = 0; y < height; ++y) {
delete [] row_pointers[y];
}
delete[] row_pointers;
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
delete [] buffer;
return ret;
}
}} //end namespace