CMemoryBuffer CHardwarePixelBuffer::LockSource(size_t offset, size_t length, THardwareBufferLock opt) { if(mSize == 0) throw NOVA_EXP("CHardwarePixelBuffer::LockSource - \ mSize == 0, null pixel box..", BAD_OPERATION); CMemoryBuffer data; GLuint face_target = 0; data.AllocBuffer(mSize); COpenGLFormats informat; informat.SetExFormat(mPixelFormat); glPixelStorei(GL_PACK_ALIGNMENT, 1); GLenum type = TextureTarget(mTarget); if(mTarget == USE_CUBEMAP_TEXTURE) face_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + mFace; else face_target = type; glBindTexture(type, mTargetId); glGetTexImage(face_target, mLevel, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin()); glPixelStorei(GL_PACK_ALIGNMENT, 4); int error = glGetError(); if(error != GL_NO_ERROR) { nstringstream str; str << "CHardwarePixelBuffer::LockSource - \ detecting OpenGL error with code " << error; throw NOVA_EXP(str.str().c_str(), BAD_OPERATION); } CMemoryBuffer result; result.AllocBuffer(mLockActSize); size_t line = mLockWidth * informat.GetInternalChannels(); nova::byte * source = (nova::byte *)data.GetBegin() + offset; nova::byte * dest = (nova::byte *)result.GetBegin(); for(nova::uint i = 0; i < mLockDepth; ++i) { for(nova::uint j = 0; j < mLockHeight; ++j) { memcpy(dest, source, line); source += mRowPitch * informat.GetInternalChannels(); dest += line; } source += mSlicePitch * informat.GetInternalChannels(); } data.FreeBuffer(); return result; }
CMemoryBuffer CFilesPackage::GetFile(const nstring & name) const { stl<nstring, FileHeader>::map::const_iterator it; TFileHeader header; if(!mIsOpened) throw NOVA_EXP("CFilesPackage::GetFile: package not opened, open package file first!", BAD_OPERATION); if(mWritePackage) throw NOVA_EXP("CFilesPackage::GetFile: package opened for writing!", BAD_OPERATION); if((it = mPackageMap.find(name)) != mPackageMap.end()) header = (*it).second; else return CMemoryBuffer(); CMemoryBuffer result; mFile->Seek(header.pos); result.AllocBuffer(header.size); mFile->Read(result); return result; }
void CFreeFont::MakeLetter(wchar_t code) { // Первая вещь, которую нам надо сделать, это вывести наш символ // в растр. Это делается набором команд FreeType // Загрузить глифы для каждого символа. if(FT_Load_Glyph(face, FT_Get_Char_Index(face, code), FT_LOAD_DEFAULT)) throw NOVA_EXP("CFreeFont::MakeLetter - FT_Load_Glyph failed", BAD_OPERATION); // Поместить глиф в объект. FT_Glyph glyph; if(FT_Get_Glyph(face->glyph, &glyph)) throw NOVA_EXP("CFreeFont::MakeLetter - FT_Get_Glyph failed", BAD_OPERATION); // Конвертировать глиф в растр. FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1); FT_BitmapGlyph bitmap_glyph = reinterpret_cast<FT_BitmapGlyph>(glyph); // С помощью этой ссылки, получаем легкий доступ до растра. FT_Bitmap & bitmap = bitmap_glyph->bitmap; // Используем нашу вспомогательную функцию для вычисления ширины и высоты // текстуры для нашего растра. nInt32 bwidth = NextP2(bitmap.width); nInt32 bheight = NextP2(bitmap.rows); // Выделим память для данных текстуры. //nByte * expanded_data = NULL; //expanded_data = getmem<nByte>(expanded_data, 2 * bwidth * bheight); CMemoryBuffer mem; mem.AllocBuffer(2 * bwidth * bheight); nByte * expanded_data = (nova::nByte *)mem.GetBegin(); // Поместим данные в расширенный растр. // Отмечу, что использован двухканальный растр (Один для // канала яркости и один для альфа), но мы будем назначать // обоим каналам одно и тоже значение, которое мы // получим из растра FreeType. // Мы используем оператор ?: для того чтобы поместить 0 в зону вне растра FreeType. for(nInt32 j = 0; j < bheight; ++j) for(nInt32 i = 0; i < bwidth; ++i) expanded_data[2*(i + j * bwidth)] = expanded_data[2*(i + j * bwidth)+1] = (i >= bitmap.width || j >= bitmap.rows) ? 0 : bitmap.buffer[i + bitmap.width*j]; /* GLuint texture; glGenTextures(1, &texture); glBindTexture( GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Здесь мы создаем текстуру // Помните, что используем GL_LUMINANCE_ALPHA, чтобы было два альфа канала данных glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bwidth, bheight, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data); */ //nInt32 tid = CTextureManager::GetSingeltonPtr()->AddTexture(GL_TEXTURE_2D, // expanded_data, bwidth, bheight, CImageFormats::NF_LUMINANCE_ALPHA); /* CTexturePtr ptex = CTextureManager::GetSingeltonPtr()->AddTexture(new CTexture(fname.c_str(), GL_TEXTURE_2D)); ptex->SetEnvType(GL_MODULATE); ptex->CreateTexture(expanded_data, bwidth, bheight, CImageFormats::NF_LUMINANCE_ALPHA, GL_CLAMP); // После создания текстуры, мы больше не нуждаемся в промежуточных данных. freemems(expanded_data); CLetter letter(slot->metrics.horiBearingX >> 6, slot->metrics.horiBearingY >> 6, slot->metrics.horiAdvance >> 6, bwidth, bheight, bitmap.width, bitmap.rows, code, ptex); */ nstring resnamet; nstring resnamei("TempFontImage"); resnamet = mName + "_" + CStringUtils::IntTo16xString(static_cast<nInt32>(code)); // Создаем промежуточное изображение в памяти CImagePtr pImage = CImageManager::GetSingelton().CreateNewImage(resnamei, mName, mem, bwidth, bheight, 1, CImageFormats::NF_LUMINANCE_ALPHA, CResource::NV_FREE); // На базе изображения создаем текстуру CTexturePtr texp = CTextureManager::GetSingelton().CreateNewTexture(resnamet, mName, pImage); // После создания текстуры, мы больше не нуждаемся в промежуточных данных. mem.FreeBuffer(); CLetter letter(slot->metrics.horiBearingX >> 6, slot->metrics.horiBearingY >> 6, slot->metrics.horiAdvance >> 6, bwidth, bheight, bitmap.width, bitmap.rows, code, texp); mSize += texp->GetSize(); /// Создаем дисплейный список на букву /////////////////////////////////////////////// letter.GetDispList().CreateList(); letter.GetDispList().BeginList(); /// ////////////////////////////////////////////////////////////////////////////////// if(!texp.IsNull()) texp->ApplyTexture(); // Вычислим какая часть нашей текстуры будет заполнена пустым пространством. // Мы рисуем только ту часть текстуры, в которой находится символ, и сохраняем // информацию в переменных x и y, затем, когда мы рисуем четырехугольник, // мы будем только ссылаться на ту часть текстуры, в которой непосредственно // содержится символ. nReal x = static_cast<nReal>(letter.GetBitmapw()) / static_cast<nReal>(letter.GetWidth()), y = static_cast<nReal>(letter.GetBitmapr()) / static_cast<nReal>(letter.GetHeight()); //glBindTexture(GL_TEXTURE_2D, let.GetTex()); glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex2i(0,0); glTexCoord2f(0,y); glVertex2i(0,letter.GetBitmapr()); glTexCoord2f(x,y); glVertex2i(letter.GetBitmapw(), letter.GetBitmapr()); glTexCoord2f(x,0); glVertex2i(letter.GetBitmapw(), 0); glEnd(); /// Завершаем дисплейный список ////////////////////////////////////////////////// letter.GetDispList().EndList(); /// ////////////////////////////////////////////////////////////////////////////// letters_map[code] = letter; }
void CDevILCodec::CodeToBuffer(CMemoryBuffer & out, const CImage &image, ESaveFormats ext) { ILuint imageid; CDevILFormats informat; informat.SetExFormat(image.GetPixelFormat()); // Generate the main image name to use. ilGenImages(1, &imageid); // Bind this image name. ilBindImage(imageid); ilTexImage(image.GetWidth(), image.GetHeight(), image.GetDepth(), informat.GetInternalChannels(), informat.GetFormat(), IL_UNSIGNED_BYTE, image.GetBitsPtr()); ILenum type = 0; switch(ext) { case SF_BMP: type = IL_BMP; break; case SF_ICO: type = IL_ICO; break; case SF_JPG: type = IL_JPG; break; case SF_PCX: type = IL_PCX; break; case SF_PIC: type = IL_PIC; break; case SF_PNG: type = IL_PNG; break; case SF_TGA: type = IL_TGA; break; case SF_TIF: type = IL_TIF; break; case SF_GIF: type = IL_GIF; break; case SF_DDS: type = IL_DDS; break; case SF_PIX: type = IL_PIX; break; case SF_HDR: type = IL_HDR; break; default: return; } out.AllocBuffer(image.GetSize()+0xff); ilSaveL(type, out.GetBegin(), out.GetBufferSize()); ilDeleteImages(1, &imageid); ILenum Error = 0; if((Error = ilGetError()) != NULL) { nstring str("CDevILCodec::CodeToStream: "); str.append(iluErrorString(Error)); throw NOVA_EXP(str.c_str(), BAD_OPERATION); } }