vector<Byte> BmpFormatter::Encode(const Bitmap &bmp) const { vector<Byte> product; product.resize(bmp.GetDataSize() + kBmpHeaderSize + kDipHeaderSize); const vector<Byte> &bmp_header = CreateBmpHeader(bmp); memcpy(&product[0], &bmp_header[0], kBmpHeaderSize); const vector<Byte> &dip_header = CreateDipHeader(bmp); memcpy(&product[kBmpHeaderSize], &dip_header[0], kDipHeaderSize); memcpy(&product[kBmpHeaderSize + kDipHeaderSize], &bmp.GetData()[0], bmp.GetDataSize()); return product; }
vector<Byte> PngFormatter::Encode(const Bitmap &bmp) const { png_struct *png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); if (!png) { LU_LOG_E(LU_TAG "Encode", "Failed while png_create_read_struct"); return {}; } png_info *info = png_create_info_struct(png); if (!info) { LU_LOG_E(LU_TAG "Encode", "Failed while png_create_info_struct"); png_destroy_write_struct(&png, nullptr); return {}; } const bool is_opaque = BitmapUtils::IsOpaque(bmp); const vector<Byte> &src = is_opaque ? BitmapUtils::GetBgrData(bmp) : bmp.GetData(); vector<const Byte*> src_rows; src_rows.reserve(bmp.GetH()); for (Uint i = 0; i < bmp.GetH(); ++i) { src_rows.push_back(src.data() + (bmp.GetW() * (is_opaque ? 3 : 4) * i)); } vector<Byte> product; if (setjmp(png_jmpbuf(png))) { LU_LOG_E(LU_TAG "Encode", "Unknown error"); png_destroy_write_struct(&png, &info); return {}; } png_set_write_fn(png, &product, PngWriteData, PngFlushData); png_set_compression_level(png, m_level); png_set_IHDR(png, info, bmp.GetW(), bmp.GetH(), 8, is_opaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_set_rows(png, info, const_cast<Byte**>(src_rows.data())); png_write_png(png, info, PNG_TRANSFORM_BGR, nullptr); product.shrink_to_fit(); return product; }
void Texture::Update(const Bitmap& bitmap) { // This class implements POTD texture only Size bitmap_size = bitmap.GetSize(); if ((!IsPowerOfTwo(bitmap_size.width) || !IsPowerOfTwo(bitmap_size.height)) && !g_has_texture_npot) { LOG(Error, L"[Texture::Update] supplied bitmap is NPOTD"); throw std::runtime_error("invalid bitmap"); } if (m_handle == 0) { // Allocate a fresh texture object m_size = bitmap_size; glGenTextures(1, &m_handle); Bind(); 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_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_size.width, m_size.height, 0, color_format, GL_UNSIGNED_BYTE, (uint8_t*)bitmap.GetData()); } else { // Texture object already exists, update Bind(); if (bitmap_size == m_size) { // Texture may be updated in-place glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_size.width, m_size.height, color_format, GL_UNSIGNED_BYTE, (uint8_t*)bitmap.GetData()); } else { // Texture must be reallocated with new size (done by driver) m_size = bitmap_size; glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_size.width, m_size.height, 0, color_format, GL_UNSIGNED_BYTE, (uint8_t*)bitmap.GetData()); } } }
void Texture::Update(Rectangle area, const Bitmap& bitmap) { if (m_handle == 0) { throw std::runtime_error("Texture::Update(Rectangle, const Bitmap&): uninitialized texture"); } if (area.Size() != bitmap.GetSize() || !Rectangle(m_size).Contains(area)) { throw std::runtime_error("Texture::Update(Rectangle, const Bitmap&): invalid area"); } Bind(); glTexSubImage2D(GL_TEXTURE_2D, 0, area.left, area.top, area.width, area.height, color_format, GL_UNSIGNED_BYTE, (uint8_t*)bitmap.GetData()); }
unsigned int GenerateOpenglBitmap(Bitmap &bitmap, bool smoothing, bool mipmap) { unsigned int glBitmap = 0; glGenTextures(1, &glBitmap); glBindTexture(GL_TEXTURE_2D, glBitmap); // Когда картинка будет увеличиваться(нет большей Мипмапы), используем LINEAR фильтрацию glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, smoothing ? GL_LINEAR : GL_NEAREST); if(mipmap) { // Когда минимизируем — берем две ближних мипмапы и лиейно смешиваем цвета glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, smoothing ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, smoothing ? GL_LINEAR : GL_NEAREST); } unsigned int format = bitmap.GetFormat(); unsigned int colorType = GL_RGB; switch (format) { case Bitmap::FORMAT_LUMINANCE: { colorType = GL_LUMINANCE; break; } case Bitmap::FORMAT_LUMINANCE_ALPHA: { colorType = GL_LUMINANCE_ALPHA; break; } case Bitmap::FORMAT_RGB: { colorType = GL_RGB; break; } case Bitmap::FORMAT_RGBA: { colorType = GL_RGBA; break; } default: { //LOG(LOG_WARNING, "Generate GLBitmap. Не поддерживаемый тип цвета."); break; } } //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, colorType, bitmap.GetWidth(), bitmap.GetHeight(), 0, colorType, GL_UNSIGNED_BYTE, bitmap.GetData()); //OPENGL_CHECK_ERRORS(); if(mipmap) { // Создаем сами мипмапы. glGenerateMipmap(GL_TEXTURE_2D); //OPENGL_CHECK_ERRORS(); } return glBitmap; }
Texture::Texture(Bitmap& bmp) : m_ImageHeight(bmp.GetHeight()), m_ImageWidth(bmp.GetWidth()), m_TextureWidth(NextPowerOf2(m_ImageWidth)), m_TextureHeight(NextPowerOf2(m_ImageHeight)), m_TextureID(0) { bmp.FlipAroundXAxis(); glGenTextures(1, &m_TextureID); glBindTexture(GL_TEXTURE_2D, m_TextureID); //glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // GL_LINEAR_MIPMAP_NEAREST glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_TextureWidth, m_TextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_ImageWidth, m_ImageHeight, GL_RGBA, GL_UNSIGNED_BYTE, bmp.GetData()); }
Texture::Texture(const Bitmap& bmp){ glGenTextures(1, &id); //glBindTexture(GL_TEXTURE_2D, id); Bind(); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bmp.GetWidth(), bmp.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, bmp.GetData()); this->width = bmp.GetWidth(); this->height = bmp.GetHeight(); cout << "Texture " << id << endl; }