CL_PixelBuffer get_pixelbuffer() const { if (buffer) { return buffer; } else { // FIXME: ClanLibs indexed handling seems broken, so we do // the conversion ourself const CL_Palette& palette = NetPanzerData::instance()->get_palette(); unsigned char* data = NetPanzerData::instance()->get_tiledata() + (32*32) * id; buffer = CL_PixelBuffer(32, 32, 32*3, CL_PixelFormat::rgb888); buffer.lock(); unsigned char* target = static_cast<unsigned char*>(buffer.get_data()); for(int i = 0; i < 32*32; ++i) { target[3*i+0] = palette[data[i]].get_blue(); target[3*i+1] = palette[data[i]].get_green(); target[3*i+2] = palette[data[i]].get_red(); } buffer.unlock(); return buffer; } }
void CL_PNGProvider::save(CL_PixelBuffer buffer, CL_IODevice &iodev) { if (buffer.get_format() != cl_abgr8) { CL_PixelBuffer newbuf( buffer.get_width(), buffer.get_height(), cl_abgr8); buffer.convert(newbuf); buffer = newbuf; } png_structp png_ptr; png_infop info_ptr; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); info_ptr = png_create_info_struct(png_ptr); png_set_read_fn(png_ptr, &iodev, &CustomIOFunctions::read); png_set_write_fn(png_ptr, &iodev, &CustomIOFunctions::write, CustomIOFunctions::flush); #ifndef PNG_COLOR_TYPE_RGBA #define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA #endif png_set_IHDR( png_ptr, info_ptr, buffer.get_width(), buffer.get_height(), 8 /* bitdepth */, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); png_uint_32 height = buffer.get_height(); png_uint_32 row_bytes = buffer.get_width()*4; png_byte* image = new png_byte[height * row_bytes]; png_bytep* row_pointers = new png_bytep[height]; // fill the image with data for (int i = 0; i < buffer.get_width()*buffer.get_height()*4; ++i) image[i] = static_cast<unsigned char*>(buffer.get_data())[i]; // generate row pointers for (unsigned int k = 0; k < height; k++) row_pointers[k] = image + (k * row_bytes); png_write_image(png_ptr, row_pointers); png_write_end(png_ptr, info_ptr); png_destroy_write_struct( &png_ptr, &info_ptr ); delete[] image; delete[] row_pointers; }
CL_Color Tile::calc_color() { CL_PixelBuffer buffer = get_pixelbuffer(); buffer.lock(); unsigned char* buf = static_cast<unsigned char*>(buffer.get_data()); int len = buffer.get_height() * buffer.get_width(); int red = 0; int green = 0; int blue = 0; int alpha = 0; switch (buffer.get_format().get_depth()) { case 8: { CL_Palette palette = buffer.get_palette(); for(int i = 0; i < len; ++i) { red += palette.colors[buf[i]].get_red(); green += palette.colors[buf[i]].get_green(); blue += palette.colors[buf[i]].get_blue(); alpha += 255; } } break; case 24: for(int i = 0; i < len; ++i) { red += buf[3*i + 0]; green += buf[3*i + 1]; blue += buf[3*i + 2]; alpha += 255; } break; case 32: for(int i = 0; i < len; ++i) { int a = buf[4*i + 0]; alpha += a; red += buf[4*i + 3]*a/255;; green += buf[4*i + 2]*a/255;; blue += buf[4*i + 1]*a/255;; } break; } buffer.unlock(); return CL_Color(static_cast<int>(red / len), static_cast<int>(green / len), static_cast<int>(blue / len), static_cast<int>(alpha / len)); }
void BitMask::init(const CL_PixelBuffer& pixBuf) { if (!bitStore_) { width_ = pixBuf.get_width(); height_ = pixBuf.get_height(); bitStoreSize_ = ((width_ * height_) / 8) + 1; bitStore_ = reinterpret_cast<uint8_t*>(malloc(bitStoreSize_)); memset(bitStore_, 0, bitStoreSize_); const uint32_t* bufPtr = reinterpret_cast<const uint32_t*>(pixBuf.get_data()); for (unsigned int y = 0; y < height_; ++y) { for (unsigned int x = 0; x < width_; ++x) { if (*bufPtr & 0x000000FFu) { // alpha != 0 setPixel(x, y); } ++bufPtr; } } } }
//ф-ция проверки на наличие прозрачных пикселей bool testAlpha(CL_PixelBuffer &image) { int width = image.get_width(); int height = image.get_height(); int pitch = image.get_pitch(); unsigned char *row = static_cast<unsigned char *>(image.get_data()); for (int y = 0; y < height; ++y, row += pitch) { unsigned char *pixel = row; for (int x = 0; x < width; ++x, pixel += 4) { //pixel[0]; //alpha //pixel[1]; //blue //pixel[2]; //green //pixel[3]; //red if (pixel[0] < ALPHA_LIMIT) return false; } } return true; }
void Screenshot::write_screenshot_pnm(const std::string& filename) { CL_PixelBuffer buf = take_screen_shot(); FILE* out = fopen(filename.c_str(), "wb"); if (!out) { perror(filename.c_str()); std::cout << "Screenshot: Couldn't write file: " << filename << std::endl; return; } buf.lock(); int width = buf.get_width(); int pitch = buf.get_width()*3; int height = buf.get_height(); fprintf(out, "P6\n" "# CREATOR: Feuerkraft\n" "%d %d\n" "255\n", width, height); unsigned char* data = static_cast<unsigned char*>(buf.get_data()); for(int i = height-1; i >= 0; --i) { fwrite(data + pitch*i, sizeof(unsigned char), pitch, out); } buf.unlock(); fclose(out); }
//сохранение данных о коллизии в файл void saveCollision(CL_PixelBuffer &image, CL_File file) { int width = image.get_width(); int height = image.get_height(); int pitch = image.get_pitch(); std::vector<unsigned char> collusionBits((width+7)/8*height, 0); unsigned char *row = static_cast<unsigned char *>(image.get_data()); for (int y = 0; y < height; ++y, row += pitch) { unsigned char *pixel = row; for (int x = 0; x < width; ++x, pixel += 4) { if (pixel[0] <= 255 - ALPHA_LIMIT) { //номер байта int i = y*(width/8) + x/8; //CL_Console::write_line("$$ x= %1 y= %2 -> i= %3 ", x, y, i); //установка бита смещения collusionBits[i] |= 1<<(7 - x%8); } } } //сохранение в файл сигнатуры file.write_uint32(0x4D534442); //сохранение в файл ширины спрайта file.write_uint32(width); //сохранение в файл высоты спрайта file.write_uint32(height); //сохранение в файл массива for(std::vector<unsigned char>::const_iterator iterCollusionBits = collusionBits.begin(); iterCollusionBits != collusionBits.end(); ++iterCollusionBits) file.write_uint8(*iterCollusionBits); }
void CL_Texture::set_image( CL_PixelBuffer &image, int level, int border, int format) { CLenum native_format = 0, native_type = 0; bool is_native_format = CL_OpenGL::to_opengl_pixelformat(image.get_format(), native_format, native_type); if (is_native_format) { switch (impl->target) { /* case CL_TEXTURE_3D: image.lock(); set_image3d_gl( impl->target, level, (format == 0) ? native_format : format, image.get_width(), image.get_height(), image.get_depth(), border, native_format, native_type, image.get_data()); image.unlock(); break; */ case CL_TEXTURE_2D: image.lock(); set_image2d_gl( impl->target, level, (format == 0) ? native_format : format, image.get_width(), image.get_height(), border, native_format, native_type, image.get_data()); image.unlock(); break; case CL_TEXTURE_1D: image.lock(); set_image1d_gl( impl->target, level, (format == 0) ? native_format : format, image.get_width(), border, native_format, native_type, image.get_data()); image.unlock(); break; default: throw CL_Error("CL_Texture::set_image does not support this texture format"); } } else { // For now, upload all non-opengl compatible formats in rgba8888 format: CL_PixelBuffer gl_image = image.to_format(CL_PixelFormat::rgba8888); set_image(gl_image, format, level, border); } }