//----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::bind(IDirect3DDevice9 *dev, IDirect3DVolume9 *volume, IDirect3DBaseTexture9 *mipTex) { D3D9_DEVICE_ACCESS_CRITICAL_SECTION BufferResources* bufferResources = getBufferResources(dev); bool isNewBuffer = false; if (bufferResources == NULL) { bufferResources = createBufferResources(); mMapDeviceToBufferResources[dev] = bufferResources; isNewBuffer = true; } bufferResources->mipTex = mipTex; bufferResources->volume = volume; bufferResources->volume->AddRef(); D3DVOLUME_DESC desc; if(volume->GetDesc(&desc) != D3D_OK) OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not get volume information", "D3D9HardwarePixelBuffer::D3D9HardwarePixelBuffer"); mWidth = desc.Width; mHeight = desc.Height; mDepth = desc.Depth; mFormat = D3D9Mappings::_getPF(desc.Format); // Default mRowPitch = mWidth; mSlicePitch = mHeight*mWidth; mSizeInBytes = PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat); if (isNewBuffer && mOwnerTexture->isManuallyLoaded()) { DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); while (it != mMapDeviceToBufferResources.end()) { if (it->second != bufferResources && it->second->volume != NULL && it->first->TestCooperativeLevel() == D3D_OK && dev->TestCooperativeLevel() == D3D_OK) { Box fullBufferBox(0,0,0,mWidth,mHeight,mDepth); PixelBox dstBox(fullBufferBox, mFormat); dstBox.data = OGRE_MALLOC(getSizeInBytes(), MEMCATEGORY_RESOURCE); blitToMemory(fullBufferBox, dstBox, it->second, it->first); blitFromMemory(dstBox, fullBufferBox, bufferResources); OGRE_FREE(dstBox.data, MEMCATEGORY_RESOURCE); break; } ++it; } } }
static Ogre::DataStreamPtr openAPKFile(const Ogre::String& fileName){ Ogre::DataStreamPtr stream; AAsset* asset = AAssetManager_open(gAssetMgr, fileName.c_str(), AASSET_MODE_BUFFER); if(asset){ off_t length = AAsset_getLength(asset); void* membuf = OGRE_MALLOC(length, Ogre::MEMCATEGORY_GENERAL); memcpy(membuf, AAsset_getBuffer(asset), length); AAsset_close(asset); stream = Ogre::DataStreamPtr(new Ogre::MemoryDataStream(membuf, length, true, true)); } return stream; }
/* void TextureAsset::RegenerateAllMipLevels() { if (ogreTexture.isNull()) return; ///\todo This function does not quite work, since ogreTexture->getNumMipmaps() will return 0 to denote a "full mipmap chain". for(int f = 0; f < ogreTexture->getNumFaces(); ++f) for(int i = 1; i < ogreTexture->getNumMipmaps(); ++i) { Ogre::HardwarePixelBufferSharedPtr src = ogreTexture->getBuffer(f, i-1); Ogre::Box srcSize(0, 0, src->getWidth(), src->getHeight()); Ogre::HardwarePixelBufferSharedPtr dst = ogreTexture->getBuffer(f, i); Ogre::Box dstSize(0, 0, dst->getWidth(), dst->getHeight()); dst->blit(src, srcSize, dstSize); } } */ bool TextureAsset::SerializeTo(std::vector<u8> &data, const QString &serializationParameters) const { if (ogreTexture.isNull()) { LogWarning("SerializeTo: Called on an unloaded texture \"" + Name().toStdString() + "\"."); return false; } try { Ogre::Image new_image; // From Ogre 1.7 Texture::convertToImage() size_t numMips = 1; size_t dataSize = Ogre::Image::calculateSize(numMips, ogreTexture->getNumFaces(), ogreTexture->getWidth(), ogreTexture->getHeight(), ogreTexture->getDepth(), ogreTexture->getFormat()); void* pixData = OGRE_MALLOC(dataSize, Ogre::MEMCATEGORY_GENERAL); // if there are multiple faces and mipmaps we must pack them into the data // faces, then mips void* currentPixData = pixData; for (size_t face = 0; face < ogreTexture->getNumFaces(); ++face) { for (size_t mip = 0; mip < numMips; ++mip) { size_t mipDataSize = Ogre::PixelUtil::getMemorySize(ogreTexture->getWidth(), ogreTexture->getHeight(), ogreTexture->getDepth(), ogreTexture->getFormat()); Ogre::PixelBox pixBox(ogreTexture->getWidth(), ogreTexture->getHeight(), ogreTexture->getDepth(), ogreTexture->getFormat(), currentPixData); ogreTexture->getBuffer(face, mip)->blitToMemory(pixBox); currentPixData = (void*)((char*)currentPixData + mipDataSize); } } // load, and tell Image to delete the memory when it's done. new_image.loadDynamicImage((Ogre::uchar*)pixData, ogreTexture->getWidth(), ogreTexture->getHeight(), ogreTexture->getDepth(), ogreTexture->getFormat(), true, ogreTexture->getNumFaces(), numMips - 1); Ogre::DataStreamPtr imageStream = new_image.encode(serializationParameters.toStdString()); if (imageStream.get() && imageStream->size() > 0) { data.resize(imageStream->size()); imageStream->read(&data[0], data.size()); } } catch (std::exception &e) { LogError("SerializeTo: Failed to export Ogre texture " + Name().toStdString() + ":"); if (e.what()) OgreRenderer::OgreRenderingModule::LogError(e.what()); return false; } return true; }
DataStreamPtr APKFileSystemArchive::open(const Ogre::String &filename, bool readOnly) const { DataStreamPtr stream; AAsset* asset = AAssetManager_open(mAssetMgr, (mPathPreFix + filename).c_str(), AASSET_MODE_BUFFER); if(asset) { off_t length = AAsset_getLength(asset); void* membuf = OGRE_MALLOC(length, Ogre::MEMCATEGORY_GENERAL); memcpy(membuf, AAsset_getBuffer(asset), length); AAsset_close(asset); stream = Ogre::DataStreamPtr(new Ogre::MemoryDataStream(membuf, length, true, true)); } return stream; }
//--------------------------------------------------------------------- void StreamSerialiser::writeData(const void* buf, size_t size, size_t count) { checkStream(false, false, true); size_t totSize = size * count; if (mFlipEndian) { void* pToWrite = OGRE_MALLOC(totSize, MEMCATEGORY_GENERAL); memcpy(pToWrite, buf, totSize); Bitwise::bswapChunks(pToWrite, size, count); mStream->write(pToWrite, totSize); OGRE_FREE(pToWrite, MEMCATEGORY_GENERAL); } else { mStream->write(buf, totSize); } }
//--------------------------------------------------------------------- void Texture::convertToImage(Image& destImage, bool includeMipMaps) { size_t numMips = includeMipMaps? getNumMipmaps() + 1 : 1; size_t dataSize = Image::calculateSize(numMips, getNumFaces(), getWidth(), getHeight(), getDepth(), getFormat()); void* pixData = OGRE_MALLOC(dataSize, Ogre::MEMCATEGORY_GENERAL); // if there are multiple faces and mipmaps we must pack them into the data // faces, then mips void* currentPixData = pixData; for (size_t face = 0; face < getNumFaces(); ++face) { uint32 width = getWidth(); uint32 height = getHeight(); uint32 depth = getDepth(); for (size_t mip = 0; mip < numMips; ++mip) { size_t mipDataSize = PixelUtil::getMemorySize(width, height, depth, getFormat()); Ogre::PixelBox pixBox(width, height, depth, getFormat(), currentPixData); getBuffer(face, mip)->blitToMemory(pixBox); currentPixData = (void*)((char*)currentPixData + mipDataSize); if(width != 1) width /= 2; if(height != 1) height /= 2; if(depth != 1) depth /= 2; } } // load, and tell Image to delete the memory when it's done. destImage.loadDynamicImage((Ogre::uchar*)pixData, getWidth(), getHeight(), getDepth(), getFormat(), true, getNumFaces(), numMips - 1); }
Ogre::DataStreamPtr CFileManager::openDataStream(const std::string& fileName) { Ogre::DataStreamPtr stream; #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID AAsset* asset = AAssetManager_open(mNativeActivity->assetManager, fileName.c_str(), AASSET_MODE_BUFFER); if(asset) { off_t length = AAsset_getLength(asset); void* membuf = OGRE_MALLOC(length, Ogre::MEMCATEGORY_GENERAL); memcpy(membuf, AAsset_getBuffer(asset), length); AAsset_close(asset); stream = Ogre::DataStreamPtr(new Ogre::MemoryDataStream(membuf, length, true, true)); } #else // first one gives a memory leak //stream = Ogre::DataStreamPtr(new Ogre::FileStreamDataStream(new std::fstream(fileName))); // second one results in strange crash (segmentation fault on closing) //stream = Ogre::DataStreamPtr(new Ogre::FileStreamDataStream(OGRE_NEW_T( std::fstream, Ogre::MEMCATEGORY_GENERAL )( fileName.c_str(), std::fstream::in ) )); // this one works stream = Ogre::DataStreamPtr(new Ogre::FileHandleDataStream(fopen(fileName.c_str(), "r"))); #endif return stream; }
Terrain* SnowTerrain::getTerrain() { if(!mTerrainGroup) return NULL; Terrain *t = mTerrainGroup->getTerrain(0,0); return t; TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator(); while (ti.hasMoreElements()) { Ogre::uint32 tkey = ti.peekNextKey(); TerrainGroup::TerrainSlot* ts = ti.getNext(); if (ts->instance && ts->instance->isLoaded()) { float* heights = ts->instance->getHeightData(); //PixelBox* pBox = ts->instance->calculateNormals()); TexturePtr texturePtr = ts->instance->getTerrainNormalMap(); HardwarePixelBufferSharedPtr buf = texturePtr->getBuffer(); size_t bytes = buf->getSizeInBytes(); size_t h = buf->getHeight(); size_t w = buf->getWidth(); size_t d = buf->getDepth(); PixelFormat f = PF_BYTE_RGB;//buf->getFormat(); uint8* tmpData = (uint8*)OGRE_MALLOC(w * h * 3, MEMCATEGORY_GENERAL); memset(tmpData,0,w*h*3); PixelBox pBox(w, h, d, f, tmpData); buf->blitToMemory(pBox); OGRE_FREE(tmpData, MEMCATEGORY_GENERAL); } } return NULL; }
//--------------------------------------------------------------------- TerrainLayerBlendMap::TerrainLayerBlendMap(Terrain* parent, uint8 layerIndex, HardwarePixelBuffer* buf) : mParent(parent) , mLayerIdx(layerIndex) , mChannel((layerIndex-1) % 4) , mDirty(false) , mBuffer(buf) , mData(0) { mData = static_cast<float*>(OGRE_MALLOC(mBuffer->getWidth() * mBuffer->getHeight() * sizeof(float), MEMCATEGORY_RESOURCE)); // we know which of RGBA we need to look at, now find it in the format // because we can't guarantee what precise format the RS gives us unsigned char rgbaShift[4]; PixelFormat fmt = mBuffer->getFormat(); PixelUtil::getBitShifts(fmt, rgbaShift); mChannelOffset = rgbaShift[mChannel] / 8; // /8 to convert to bytes #if OGRE_ENDIAN == OGRE_ENDIAN_BIG // invert (dealing bytewise) mChannelOffset = PixelUtil::getNumElemBytes(fmt) - mChannelOffset - 1; #endif download(); }
//--------------------------------------------------------------------- Image & Image::combineTwoImagesAsRGBA(const Image& rgb, const Image& alpha, PixelFormat fmt) { // the images should be the same size, have the same number of mipmaps if (rgb.getWidth() != alpha.getWidth() || rgb.getHeight() != alpha.getHeight() || rgb.getDepth() != alpha.getDepth()) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Images must be the same dimensions", "Image::combineTwoImagesAsRGBA"); } if (rgb.getNumMipmaps() != alpha.getNumMipmaps() || rgb.getNumFaces() != alpha.getNumFaces()) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Images must have the same number of surfaces (faces & mipmaps)", "Image::combineTwoImagesAsRGBA"); } // Format check if (PixelUtil::getComponentCount(fmt) != 4) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Target format must have 4 components", "Image::combineTwoImagesAsRGBA"); } if (PixelUtil::isCompressed(fmt) || PixelUtil::isCompressed(rgb.getFormat()) || PixelUtil::isCompressed(alpha.getFormat())) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Compressed formats are not supported in this method", "Image::combineTwoImagesAsRGBA"); } freeMemory(); mWidth = rgb.getWidth(); mHeight = rgb.getHeight(); mDepth = rgb.getDepth(); mFormat = fmt; mNumMipmaps = rgb.getNumMipmaps(); size_t numFaces = rgb.getNumFaces(); // Set flags mFlags = 0; if (mDepth != 1) mFlags |= IF_3D_TEXTURE; if(numFaces == 6) mFlags |= IF_CUBEMAP; mBufSize = calculateSize(mNumMipmaps, numFaces, mWidth, mHeight, mDepth, mFormat); mPixelSize = static_cast<uchar>(PixelUtil::getNumElemBytes( mFormat )); mBuffer = static_cast<uchar*>(OGRE_MALLOC(mBufSize, MEMCATEGORY_GENERAL)); // make sure we delete mAutoDelete = true; for (size_t face = 0; face < numFaces; ++face) { for (uint8 mip = 0; mip <= mNumMipmaps; ++mip) { // convert the RGB first PixelBox srcRGB = rgb.getPixelBox(face, mip); PixelBox dst = getPixelBox(face, mip); PixelUtil::bulkPixelConversion(srcRGB, dst); // now selectively add the alpha PixelBox srcAlpha = alpha.getPixelBox(face, mip); uchar* psrcAlpha = static_cast<uchar*>(srcAlpha.data); uchar* pdst = static_cast<uchar*>(dst.data); for (size_t d = 0; d < mDepth; ++d) { for (size_t y = 0; y < mHeight; ++y) { for (size_t x = 0; x < mWidth; ++x) { ColourValue colRGBA, colA; // read RGB back from dest to save having another pointer PixelUtil::unpackColour(&colRGBA, mFormat, pdst); PixelUtil::unpackColour(&colA, alpha.getFormat(), psrcAlpha); // combine RGB from alpha source texture colRGBA.a = (colA.r + colA.g + colA.b) / 3.0f; PixelUtil::packColour(colRGBA, mFormat, pdst); psrcAlpha += PixelUtil::getNumElemBytes(alpha.getFormat()); pdst += PixelUtil::getNumElemBytes(mFormat); } } } } } return *this; }
//--------------------------------------------------------------------- void DeflateStream::init() { mZStream = OGRE_ALLOC_T(z_stream, 1, MEMCATEGORY_GENERAL); mZStream->zalloc = OgreZalloc; mZStream->zfree = OgreZfree; if (getAccessMode() == READ) { mTmp = (unsigned char*)OGRE_MALLOC(OGRE_DEFLATE_TMP_SIZE, MEMCATEGORY_GENERAL); size_t restorePoint = mCompressedStream->tell(); // read early chunk mZStream->next_in = mTmp; mZStream->avail_in = static_cast<uint>(mCompressedStream->read(mTmp, getAvailInForSinglePass())); if (inflateInit(mZStream) != Z_OK) { mIsCompressedValid = false; } else mIsCompressedValid = true; if (mIsCompressedValid) { // in fact, inflateInit on some implementations doesn't try to read // anything. We need to at least read something to test Bytef testOut[4]; size_t savedIn = mZStream->avail_in; mZStream->avail_out = 4; mZStream->next_out = testOut; if (inflate(mZStream, Z_SYNC_FLUSH) != Z_OK) mIsCompressedValid = false; // restore for reading mZStream->avail_in = static_cast<uint>(savedIn); mZStream->next_in = mTmp; inflateReset(mZStream); } if (!mIsCompressedValid) { // Not compressed data! // Fail gracefully, fall back on reading the underlying stream direct destroy(); mCompressedStream->seek(restorePoint); } } else { if(mTempFileName.empty()) { // Write to temp file #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT char* tmpname = _tempnam(".", "ogre"); if (!tmpname) { // Having no file name here will cause various problems later. OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Temporary file name generation failed.", "DeflateStream::init"); } else { mTempFileName = tmpname; free(tmpname); } #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS || OGRE_PLATFORM == OGRE_PLATFORM_APPLE mTempFileName = macTempFileName(); #else char tmpname[] = "/tmp/ogreXXXXXX"; if (mkstemp(tmpname) == -1) OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Temporary file name generation failed.", "DeflateStream::init"); mTempFileName = tmpname; #endif } std::fstream *f = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); f->open(mTempFileName.c_str(), std::ios::binary | std::ios::out); mTmpWriteStream = DataStreamPtr(OGRE_NEW FileStreamDataStream(f)); } }
// memory implementations void* OgreZalloc(void* opaque, unsigned int items, unsigned int size) { return OGRE_MALLOC(items * size, MEMCATEGORY_GENERAL); }