void RenderHandler::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList &dirtyRects, const void *buffer, int width, int height) { Ogre::HardwarePixelBufferSharedPtr texBuf = m_texture->getBuffer(); texBuf->lock(Ogre::HardwareBuffer::HBL_DISCARD); memcpy(texBuf->getCurrentLock().data, buffer, width*height*4); texBuf->unlock(); }
void MiniMapMaker::init(void) { // 创建纹理 Ogre::TexturePtr pTexture = Ogre::TextureManager::getSingleton().createManual( "RttTex", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, mTexWidth, mTexHeight, 1, 0, mOutPutFormat, Ogre::TU_RENDERTARGET, 0); Ogre::HardwarePixelBufferSharedPtr pBuffer = pTexture->getBuffer(0, 0); mRenderTexture = pBuffer->getRenderTarget(0); { mCamera = mManipulator->getSceneManager()->createCamera("RttCam"); // 设置摄像机的基本属性 mCamera->setAspectRatio(1); mCamera->setProjectionType(Ogre::PT_ORTHOGRAPHIC); mCamera->setFOVy(Ogre::Degree(90)); _setCameraAttribute(); Ogre::Viewport *v = mRenderTexture->addViewport( mCamera ); v->setClearEveryFrame( true ); v->setBackgroundColour( Ogre::ColourValue::Black ); v->setOverlaysEnabled(false); v->setSkiesEnabled(false); v->setShadowsEnabled(true); } }
//------------------------------------------------------------------------------ void OgreVideoTexture::_initTexture(Ogre::TexturePtr _texture) { // Get the pixel buffer Ogre::HardwarePixelBufferSharedPtr pixelBuffer = _texture->getBuffer(); // Lock the pixel buffer and get a pixel box pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL); // for best performance use HBL_DISCARD! const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock(); Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data); for (size_t j = 0; j < _texture->getHeight(); j++) for(size_t i = 0; i < _texture->getWidth() ; i++) { if (j<480-5 && i<640-5) { *pDest++ = 255; // B *pDest++ = 0; // G *pDest++ = 255; // R } else { *pDest++ = 255; // B *pDest++ = 0; // G *pDest++ = 0; // R } } pixelBuffer->unlock(); }
void VideoVisual::render(const cv::Mat& image) { // Fix image size if necessary const cv::Mat* image_ptr = ℑ cv::Mat converted_image; if (image_ptr->rows != height_ || image_ptr->cols != width_) { cv::resize(*image_ptr, converted_image, cv::Size(width_, height_)); image_ptr = &converted_image; } // Get the pixel buffer Ogre::HardwarePixelBufferSharedPtr pixelBuffer = this->texture_->getBuffer(); // Lock the pixel buffer and get a pixel box pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock(); uint8_t* pDest = static_cast<uint8_t*>(pixelBox.data); memcpy(pDest, image_ptr->data, height_ * width_ * 4); // Unlock the pixel buffer pixelBuffer->unlock(); }
void HTML::PaintScrollImage(Ogre::HardwarePixelBufferSharedPtr pixelBuffer, const Berkelium::Rect& scrollOrigRect, int scroll_dx, int scroll_dy) { Berkelium::Rect scrolledRect = scrollOrigRect.translate(scroll_dx, scroll_dy); Berkelium::Rect scrolled_shared_rect = scrollOrigRect.intersect(scrolledRect); // Only do scrolling if they have non-zero intersection if(scrolled_shared_rect.width() == 0 || scrolled_shared_rect.height() == 0) return; Berkelium::Rect shared_rect = scrolled_shared_rect.translate(-scroll_dx, -scroll_dy); size_t width = shared_rect.width(); size_t height = shared_rect.height(); Ogre::TexturePtr shadow = Ogre::TextureManager::getSingleton().createManual("scrollbuf", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, Ogre::Bitwise::firstPO2From(width), Ogre::Bitwise::firstPO2From(height), 1, 1, Ogre::PF_BYTE_BGRA); { Ogre::HardwarePixelBufferSharedPtr shadowBuffer = shadow->getBuffer(); Berkelium::Rect borderedScrollRect = GetBorderedRect(shared_rect); Berkelium::Rect borderedScrolledRect = GetBorderedRect(scrolled_shared_rect); shadowBuffer->blit(pixelBuffer, Ogre::Box(borderedScrollRect.left(), borderedScrollRect.top(), borderedScrollRect.right(), borderedScrollRect.bottom()), Ogre::Box(0, 0, width, height)); pixelBuffer->blit(shadowBuffer, Ogre::Box(0, 0, width, height), Ogre::Box(borderedScrolledRect.left(), borderedScrolledRect.top(), borderedScrolledRect.right(), borderedScrolledRect.bottom())); } Ogre::ResourcePtr shadowResource(shadow); Ogre::TextureManager::getSingleton().remove(shadowResource); }
//------------------------------------------------------------------------------ void OgreVideoTexture::_copyImagePerPixel(const IplImage *_image ,Ogre::HardwarePixelBufferSharedPtr _pixelBuffer) { // Lock the pixel buffer and get a pixel box _pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); // for best performance use HBL_DISCARD! const Ogre::PixelBox& pixelBox = _pixelBuffer->getCurrentLock(); Ogre::uint32* pDest = static_cast<Ogre::uint32*>(pixelBox.data); size_t w, h, widthStep; w = _image->width; h = _image->height; widthStep = _image->widthStep; Ogre::uint32 pixelBGRA; for(size_t i=0 ; i < h ; i++) { size_t offset = i*widthStep; for (size_t j=0 ; j < w ; j++) { memcpy(&pixelBGRA, _image->imageData + offset +j*3, sizeof(Ogre::uint32)); pDest[i *1024 + j] = pixelBGRA; } } _pixelBuffer->unlock(); }
//------------------------------------------------------------------------------ void OgreVideoTexture::_copyImagePerChannel(const IplImage *_image ,Ogre::HardwarePixelBufferSharedPtr _pixelBuffer) { // Lock the pixel buffer and get a pixel box _pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); // for best performance use HBL_DISCARD! const Ogre::PixelBox& pixelBox = _pixelBuffer->getCurrentLock(); Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data); for (size_t j = 0; j < _image->height; j++) for(size_t i = 0; i < _image->width ; i++) { char pixelR = CV_IMAGE_ELEM(_image, char, j, i*3+2 ); char pixelG = CV_IMAGE_ELEM(_image, char, j, i*3+1); char pixelB = CV_IMAGE_ELEM(_image, char, j, i*3 ); int w = mVideoTexture->getWidth(); pDest[j*1024*4 + i*4] = pixelB; pDest[j*1024*4 + i*4+1] = pixelG; pDest[j*1024*4 + i*4+2] = pixelR; //pDest[j*w*4 + i*4+3] = 255; } _pixelBuffer->unlock(); }
void video_display(VideoState *is) { VideoPicture *vp; vp = &is->pictq[is->pictq_rindex]; if (is->video_st->codec->width != 0 && is->video_st->codec->height != 0) { Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton ().getByName("VideoTexture"); if (texture.isNull () || texture->getWidth() != is->video_st->codec->width || texture->getHeight() != is->video_st->codec->height) { Ogre::TextureManager::getSingleton ().remove ("VideoTexture"); texture = Ogre::TextureManager::getSingleton().createManual( "VideoTexture", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, is->video_st->codec->width, is->video_st->codec->height, 0, Ogre::PF_BYTE_RGBA, Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE); } Ogre::PixelBox pb(is->video_st->codec->width, is->video_st->codec->height, 1, Ogre::PF_BYTE_RGBA, vp->data); Ogre::HardwarePixelBufferSharedPtr buffer = texture->getBuffer(); buffer->blitFromMemory(pb); } free(vp->data); }
void DataManager::_updateVolTextureData(Cell ***c, const VolTextureId& TexId, const int& nx, const int& ny, const int& nz) { Ogre::HardwarePixelBufferSharedPtr buffer = mVolTextures[TexId]->getBuffer(0,0); buffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); const Ogre::PixelBox &pb = buffer->getCurrentLock(); Ogre::uint32 *pbptr = static_cast<Ogre::uint32*>(pb.data); size_t x, y, z; for (z=pb.front; z<pb.back; z++) { for (y=pb.top; y<pb.bottom; y++) { for (x=pb.left; x<pb.right; x++) { Ogre::PixelUtil::packColour(c[x][y][z].dens/* TODO!!!! */, c[x][y][z].light, 0, 0, pb.format, &pbptr[x]); } pbptr += pb.rowPitch; } pbptr += pb.getSliceSkip(); } buffer->unlock(); }
/** * @inheritDoc. */ void BrowserWindow::onPaint(Berkelium::Window *win, const unsigned char *sourceBuffer, const Berkelium::Rect &sourceBufferRect, size_t numCopyRects, const Berkelium::Rect *copyRects, int dx, int dy, const Berkelium::Rect &scrollRect) { const Ogre::HardwarePixelBufferSharedPtr textureBuffer = m_texture->getBuffer(); const Ogre::PixelBox srcBox = Ogre::PixelBox(rectToBox(sourceBufferRect), Ogre::PF_BYTE_BGRA, const_cast<unsigned char*>(sourceBuffer)); for(int i = 0; i < numCopyRects; i++) { const Ogre::Box destBox = rectToBox(copyRects[i]); textureBuffer->blitFromMemory(srcBox.getSubVolume(destBox), destBox); } }
bool TextureManager::_updateNormalMap(Image &Image) { if (!mCreated) { HydraxLOG("Error in TextureManager::_updateNormalMap, create() does not called."); return false; } if (Image.getType() != Image::TYPE_RGB) { HydraxLOG("Error in TextureManager::_updateNormalMap, Image type isn't correct."); return false; } Ogre::TexturePtr &Texture = getTexture(TEX_NORMAL_ID); Size ImageSize = Image.getSize(); if (Texture->getWidth() != ImageSize.Width || Texture->getHeight() != ImageSize.Height) { HydraxLOG("Error in TextureManager::update, Update size doesn't correspond to " + getTextureName(TEX_NORMAL_ID) + " texture size"); return false; } Ogre::HardwarePixelBufferSharedPtr pixelBuffer = Texture->getBuffer(); pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL); const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock(); Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data); int x, y; for (x = 0; x < ImageSize.Width; x++) { for (y = 0; y < ImageSize.Height; y++) { *pDest++ = Image.getValue(x,y,2); // B *pDest++ = Image.getValue(x,y,1); // G *pDest++ = Image.getValue(x,y,0); // R *pDest++ = 255; // A } } pixelBuffer->unlock(); return true; }
bool OgreARAppLogic::update(Ogre::Real deltaTime) { if (!pause) { if( !userUpdate(this)) return false; // call user-defined funcions // update background image if (!mTexture.isNull()) { //Pedimos a ogre que actualice la imagen desde el PixelBox Ogre::HardwarePixelBufferSharedPtr pixelBuffer = mTexture->getBuffer(); pixelBuffer->blitFromMemory(mPixelBox); } } bool result = processInputs(deltaTime); return result; }
void SourceTexture::Rectangle(int x, int y, int width, int height, unsigned long color) { Ogre::HardwarePixelBufferSharedPtr pixelBuffer = m_spTexture->getBuffer(); pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); const Ogre::PixelBox& pixelbox = pixelBuffer->getCurrentLock(); /*unsigned int dstBpp = Ogre::PixelUtil::getNumElemBytes(pixelbox.format); unsigned int dstPitch = pixelbox.rowPitch * dstBpp;*/ unsigned char *pImage = static_cast<unsigned char*>(pixelbox.data); int dst_width = pixelbox.getWidth(); unsigned char *pTmp = pImage + ( ( y*m_nWidth) + x )*4; for(int i = 0 ; i < width ; i++, pTmp += 4) { *(pTmp+0) = (unsigned char)(color >> 16); *(pTmp+1) = (unsigned char)(color >> 8); *(pTmp+2) = (unsigned char)(color); *(pTmp+3) = 255; } pTmp = pImage + ( ( (y+height-1)*m_nWidth) + x )*4; for(int i = 0 ; i < width ; i++, pTmp += 4) { *(pTmp+0) = (unsigned char)(color >> 16); *(pTmp+1) = (unsigned char)(color >> 8); *(pTmp+2) = (unsigned char)(color); *(pTmp+3) = 255; } pTmp = pImage + ( ( y*m_nWidth) + x )*4; for(int i = 0 ; i < height ; i++, pTmp += m_nWidth*4) { *(pTmp+0) = (unsigned char)(color >> 16); *(pTmp+1) = (unsigned char)(color >> 8); *(pTmp+2) = (unsigned char)(color); *(pTmp+3) = 255; } pTmp = pImage + ( ( y*m_nWidth) + x+width-1 )*4; for(int i = 0 ; i < height ; i++, pTmp += m_nWidth*4) { *(pTmp+0) = (unsigned char)(color >> 16); *(pTmp+1) = (unsigned char)(color >> 8); *(pTmp+2) = (unsigned char)(color); *(pTmp+3) = 255; } //m_spImageData->SetFlag(NxImageData::UPDATE_PIXEL); }
//----------------------------------------------------------------------------------------- void CTerrainGroupEditor::setBrushName(const std::string& brush) { mBrushName = brush; if(!mDecalTexture.isNull()) { Ogre::Image img; img.load(brush,"Brushes"); unsigned char *dataptr = OGRE_ALLOC_T(unsigned char, img.getWidth() * img.getHeight() * 3, Ogre::MEMCATEGORY_GEOMETRY); Ogre::PixelBox resultbox(img.getWidth(),img.getHeight(),1,Ogre::PF_B8G8R8,dataptr); Ogre::PixelUtil::bulkPixelConversion(img.getPixelBox(), resultbox); resultbox.setConsecutive(); int pos = 0; Ogre::ColourValue colval; for(unsigned int x = 0;x < img.getHeight() * img.getWidth();x++) { dataptr[pos] = 0; dataptr[pos + 1] = 0; dataptr[pos + 2] *= 0.8f; pos += 3; } mDecalTexture->setHeight(img.getHeight()); mDecalTexture->setWidth(img.getWidth()); Ogre::HardwarePixelBufferSharedPtr ptr = mDecalTexture->getBuffer(); ptr->blitFromMemory(resultbox); OGRE_FREE(dataptr, Ogre::MEMCATEGORY_GEOMETRY); img.resize(mBrushSize, mBrushSize); img.resize(BRUSH_DATA_SIZE, BRUSH_DATA_SIZE); pos = 0; Ogre::ColourValue cval; for(unsigned int y = 0;y < BRUSH_DATA_SIZE ;y++) { pos = ((BRUSH_DATA_SIZE - 1) - y) * BRUSH_DATA_SIZE; for(unsigned int x = 0;x < BRUSH_DATA_SIZE ;x++) { cval = img.getColourAt(x,y,0); mBrushData[pos] = cval.r; pos++; } } }
void UiManager::renderIntoTexture(const Ogre::TexturePtr &aTexture) { assert(!aTexture.isNull()); assert(isViewSizeMatching(aTexture)); Ogre::HardwarePixelBufferSharedPtr hwBuffer = aTexture->getBuffer(0, 0); hwBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); const Ogre::PixelBox &pb = hwBuffer->getCurrentLock(); // render into texture buffer QImage textureImg((uchar *)pb.data, pb.getWidth(), pb.getHeight(), QImage::Format_ARGB32); textureImg.fill(0); QPainter painter(&textureImg); mWidgetView->render(&painter, QRect(QPoint(0, 0), mWidgetView->size()), QRect(QPoint(0, 0), mWidgetView->size())); hwBuffer->unlock(); }
//------------------------------------------------------------------------------ void OgreVideoTexture::_copyImagePerLine(const IplImage *_image ,Ogre::HardwarePixelBufferSharedPtr _pixelBuffer) { // Lock the pixel buffer and get a pixel box _pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); // for best performance use HBL_DISCARD! const Ogre::PixelBox& pixelBox = _pixelBuffer->getCurrentLock(); //Ogre::uint32* pDest = static_cast<Ogre::uint32*>(pixelBox.data); Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data); for (size_t i = 0 ; i < _image->height ; i++) { memcpy(pDest + i*1024*4 , (_image->imageData) + i*_image->width * 3 , _image->width * 3); } _pixelBuffer->unlock(); }
void HTML::Paint(Ogre::HardwarePixelBufferSharedPtr pixelBuffer, const unsigned char*srcBuffer, const Berkelium::Rect& srcRect, size_t num_copy_rects, const Berkelium::Rect *copy_rects) { /**/ const Ogre::PixelBox srcBox = Ogre::PixelBox(ToBox(srcRect), Ogre::PF_BYTE_BGRA, const_cast<unsigned char*>(srcBuffer)); for(unsigned int i = 0; i < num_copy_rects; i++) { const Ogre::Box destBox = ToBox(copy_rects[i]); pixelBuffer->blitFromMemory(srcBox.getSubVolume(destBox), destBox); } }
bool KinectDevice::UpdateColorDepthTexture() { bool updated = false; if (!mColorTexture.isNull() && mColorTextureAvailable) { Ogre::HardwarePixelBufferSharedPtr pixelBuffer = mColorTexture->getBuffer(); pixelBuffer->blitFromMemory(mColorPixelBox); mColorTextureAvailable = false; updated = true; } if (!mDepthTexture.isNull() && mDepthTextureAvailable) { Ogre::HardwarePixelBufferSharedPtr pixelBuffer = mDepthTexture->getBuffer(); pixelBuffer->blitFromMemory(mDepthPixelBox); mDepthTextureAvailable = false; updated = true; } if (!mColoredDepthTexture.isNull()&& mColoredDepthTextureAvailable) { Ogre::HardwarePixelBufferSharedPtr pixelBuffer = mColoredDepthTexture->getBuffer(); pixelBuffer->blitFromMemory(mColoredDepthPixelBox); mColoredDepthTextureAvailable = false; updated = true; } return updated; }
//----------------------------------------------------------------------- CoherentUIView::CoherentUIView(Ogre::CoherentUIViewListener* listener, int width, int height, bool enableDepthWrite) : mView(NULL) { mViewListener = OGRE_NEW CoherentUIViewListenerBridge(this, listener); static int _textureCounter = 0; Ogre::StringStream ss; ss << "CoherentDynamicTexture" << ++_textureCounter; Ogre::String textureName = ss.str(); ss << "_Mat"; Ogre::String materialName = ss.str(); // Create a texture mTexture = TextureManager::getSingleton().createManual( textureName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, width, height, 1, PF_BYTE_BGRA, TU_DYNAMIC_WRITE_ONLY_DISCARDABLE); // Clear the texture Ogre::HardwarePixelBufferSharedPtr pixelBuffer = mTexture->getBuffer(); pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock(); Ogre::uint32* dest = static_cast<Ogre::uint32*>(pixelBox.data); std::memset(dest, 0, (width * 4 + pixelBox.getRowSkip()) * height); pixelBuffer->unlock(); // Create a material using the texture mTextureMaterial = MaterialManager::getSingleton().create( materialName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); mTextureMaterial->getTechnique(0)->getPass(0)->createTextureUnitState(textureName); mTextureMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBF_ONE, SBF_ONE_MINUS_SOURCE_ALPHA); mTextureMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(enableDepthWrite); }
void DirectShowMovieTexture::cleanTextureContents() { unsigned int idx; int x, y; // OGRE TEXTURE LOCK // get the texture pixel buffer int texw=mTexture->getWidth(); int texh=mTexture->getHeight(); Ogre::HardwarePixelBufferSharedPtr pixelBuffer = mTexture->getBuffer(); // lock the pixel buffer and get a pixel box pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock(); Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data); // FILL! for (x=0, y=0; y<texh; ){ idx=(x*4)+y*pixelBox.rowPitch*4; // paint pDest[idx]=0;//b pDest[idx+1]=0;//g pDest[idx+2]=0;//r pDest[idx+3]=255;//a x++; if (x>=texw) { x=0; y++; } } // UNLOCK EVERYTHING! // unlock the pixel buffer pixelBuffer->unlock(); // OGRE END }
void test(const std::vector<std::vector<TxzFileSerializer::rgba>>& data) { //Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().load("clf_l.png.png", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // kWorldResourceGroup Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().createManual("BackgroundTex", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 640, 256, 0, Ogre::PF_B8G8R8, Ogre:: TU_DYNAMIC); Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create("BackgroundMat",Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); material->getTechnique(0)->getPass(0)->createTextureUnitState("BackgroundTex"); //material->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_COLOUR); Ogre::HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer(); pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock(); Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data); for(size_t i=0; i < 256; i++) { for(size_t j=0; j < 640; j++) { *pDest++ = data[i][j].b; *pDest++ = data[i][j].g; *pDest++ = data[i][j].r; *pDest++ = 0; } } pixelBuffer->unlock(); }
/*! Get the result of the rendering loop. \param I : The image on which to copy the result of the rendering loop. \param cMo : The desired camera pose. */ void vpAROgre::getRenderingOutput(vpImage<vpRGBa> &I, const vpHomogeneousMatrix &cMo) { updateCameraParameters(cMo); Ogre::TexturePtr dynTexPtr = Ogre::TextureManager::getSingleton().getByName("rtf"); //#if ( OGRE_VERSION >= (1 << 16 | 9 << 8 | 0) ) // .dynamicCast<Ogre::Texture>(); //#else // ; //#endif Ogre::RenderTexture* RTarget = dynTexPtr->getBuffer()->getRenderTarget(); mWindow->update(); RTarget->update(); if(I.getHeight() != mWindow->getHeight() || I.getWidth() != mWindow->getWidth()){ I.resize(mWindow->getHeight(), mWindow->getWidth()); } Ogre::HardwarePixelBufferSharedPtr mPixelBuffer = dynTexPtr->getBuffer(); mPixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); const Ogre::PixelBox& pixelBox = mPixelBuffer->getCurrentLock(); dynTexPtr->getBuffer()->blitToMemory(pixelBox); Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data); #if 1 // if texture in BGRa format for(unsigned int i=0; i<I.getHeight(); i++){ for(unsigned int j=0; j<I.getWidth(); j++){ // Color Image I[i][j].B = *pDest++; // Blue component I[i][j].G = *pDest++; // Green component I[i][j].R = *pDest++; // Red component I[i][j].A = *pDest++; // Alpha component } } #else // if texture in RGBa format which is the format of the input image memcpy(I.bitmap, pDest, I.getHeight()*I.getWidth()*sizeof(vpRGBa)); #endif // Unlock the pixel buffer mPixelBuffer->unlock(); }
bool EC_WidgetCanvas::Blit(const QImage &source, Ogre::TexturePtr destination) { #if defined(DIRECTX_ENABLED) && defined(WIN32) Ogre::HardwarePixelBufferSharedPtr pb = destination->getBuffer(); Ogre::D3D9HardwarePixelBuffer *pixelBuffer = dynamic_cast<Ogre::D3D9HardwarePixelBuffer*>(pb.get()); if (!pixelBuffer) return false; LPDIRECT3DSURFACE9 surface = pixelBuffer->getSurface(Ogre::D3D9RenderSystem::getActiveD3D9Device()); if (surface) { D3DSURFACE_DESC desc; HRESULT hr = surface->GetDesc(&desc); if (SUCCEEDED(hr)) { D3DLOCKED_RECT lock; HRESULT hr = surface->LockRect(&lock, 0, 0); if (SUCCEEDED(hr)) { const int bytesPerPixel = 4; ///\todo Count from Ogre::PixelFormat! const int sourceStride = bytesPerPixel * source.width(); if (lock.Pitch == sourceStride) memcpy(lock.pBits, source.bits(), sourceStride * source.height()); else for(int y = 0; y < source.height(); ++y) memcpy((u8*)lock.pBits + lock.Pitch * y, source.bits() + sourceStride * y, sourceStride); surface->UnlockRect(); } } } #else if (!destination->getBuffer().isNull()) { Ogre::Box update_box(0, 0, source.width(), source.height()); Ogre::PixelBox pixel_box(update_box, Ogre::PF_A8R8G8B8, (void*)source.bits()); destination->getBuffer()->blitFromMemory(pixel_box, update_box); } #endif return true; }
void _makeScene() { mCamera->setNearClipDistance(1); mCamera->setFarClipDistance(1000); // Create the texture Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().createManual( "DynamicTexture", // name Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, // type 128, 128, // width & height 0, // number of mipmaps Ogre::PF_BYTE_BGRA, // pixel format Ogre::TU_DEFAULT); // usage; should be TU_DYNAMIC_WRITE_ONLY_DISCARDABLE for // textures updated very often (e.g. each frame) // Get the pixel buffer Ogre::HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer(); // Lock the pixel buffer and get a pixel box pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL); // for best performance use HBL_DISCARD! const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock(); Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data); // Fill in some pixel data. This will give a semi-transparent blue, // but this is of course dependent on the chosen pixel format. for (size_t j = 0; j < 128; j++) for(size_t i = 0; i < 128; i++) { *pDest++ = 82 + (Ogre::Math::Sin(i) + Ogre::Math::Cos(j) * 10.5); *pDest++ = 45 + (Ogre::Math::Cos(i) + Ogre::Math::Sin(j) * 10.5); *pDest++ = 128 + (Ogre::Math::Tan(i) + Ogre::Math::Cos(j) * 10.5); *pDest++ = 255; // A } // Unlock the pixel buffer pixelBuffer->unlock(); // Create a material using the texture Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create( "DynamicTextureMaterial", // name Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); Ogre::TextureUnitState* tus = material->getTechnique(0)->getPass(0)->createTextureUnitState("DynamicTexture"); tus->setScrollAnimation(0.005f, 0.0025f); tus->setRotateAnimation(0.009f); material->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA); Ogre::Plane plane(Ogre::Vector3::UNIT_Y, 0); Ogre::MeshManager::getSingleton().createPlane("ground", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 1500, 1500, 1, 1, true, 1, 1, 1, Ogre::Vector3::UNIT_Z); Ogre::Entity* entGround = mSceneMgr->createEntity("GroundEntity", "ground"); mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(entGround); entGround->setMaterialName("DynamicTextureMaterial"); entGround->setCastShadows(false); mCamera->setPosition(25,100,30); mCamera->lookAt(0,0,0); }
Surface* FontFile::GetSurface(void) { int width = 512; int height = 4096; int chars = 0; int char_num = 6165; Surface* ret = CreateSurface(width, height); int x_16 = 0; int y_16 = 0; struct ClutColor { u8 r; /**< @brief red color in CLUT */ u8 g; /**< @brief green color in CLUT */ u8 b; /**< @brief blue color in CLUT */ u8 a; /**< @brief alpha in CLUT */ }; ClutColor color; color.r = 0; color.g = 0; color.b = 0; color.a = 255; u8 data = 0; for (int chars = 0; chars < char_num; ++chars) { Surface* glyth = CreateSurface(16, 16); for (int y = 0; y < 16; ++y) { data = (y < 11) ? GetU8(0xE + chars * 22 + y * 2 + 0) : 0; //LOGGER->Log(LOGGER_INFO, "%x, %02x", y, data); int j = 0; for (int i = 7; i >= 0; --i) { color.r = ((data >> i) & 0x01 == 1) ? 0 : 255; color.g = ((data >> i) & 0x01 == 1) ? 0 : 255; color.b = ((data >> i) & 0x01 == 1) ? 0 : 255; color.a = ((data >> i) & 0x01 == 1) ? 255 : 255; memcpy(glyth->pixels + 64 * y + j, &color, sizeof(ClutColor)); j += 4; } data = (y < 11) ? GetU8(0xE + chars * 22 + y * 2 + 1) : 0; //LOGGER->Log(LOGGER_INFO, "%02x", data); for (int i = 7; i >= 0; --i) { color.r = ((data >> i) & 0x01 == 1) ? 0 : 255; color.g = ((data >> i) & 0x01 == 1) ? 0 : 255; color.b = ((data >> i) & 0x01 == 1) ? 0 : 255; color.a = ((data >> i) & 0x01 == 1) ? 255 : 255; memcpy(glyth->pixels + 64 * y + j, &color, sizeof(ClutColor)); j += 4; } } CopyToSurface(ret, x_16, y_16, glyth); delete glyth; x_16 += 16; if (x_16 == ret->width) { y_16 += 16; x_16 = 0; } } Ogre::TexturePtr ptex; Ogre::HardwarePixelBufferSharedPtr buffer; ptex = Ogre::TextureManager::getSingleton().createManual("DynaTex", "General", Ogre::TEX_TYPE_2D, ret->width, ret->height, 0, Ogre::PF_R8G8B8A8, Ogre::TU_STATIC); buffer = ptex->getBuffer(0, 0); buffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); const Ogre::PixelBox& pb = buffer->getCurrentLock(); for (Uint32 y = 0; y < ret->height; ++y) { Uint32* data = static_cast<Uint32*>(pb.data) + y * pb.rowPitch; for (Uint32 x = 0; x < ret->width; ++x) { Uint32 clut = ret->pixels[y * ret->width * 4 + x * 4 + 3] | (ret->pixels[y * ret->width * 4 + x * 4 + 2] << 8) | (ret->pixels[y * ret->width * 4 + x * 4 + 1] << 16) | (ret->pixels[y * ret->width * 4 + x * 4 + 0] << 24); data[x] = clut; } } Ogre::Image image; image.loadDynamicImage((Ogre::uchar*)pb.data, ret->width, ret->height, Ogre::PF_R8G8B8A8); image.save("font.png"); buffer->unlock(); Ogre::TextureManager::getSingleton().remove("DynaTex"); return ret; }
void Canvas::Texture::loadResource(Ogre::Resource* resource) { Ogre::HardwarePixelBufferSharedPtr pixelBuffer = ((Ogre::Texture*) resource)->getBuffer(); if (!pixelBuffer.isNull()) uploadTexture(); }
CRosRttTexture::CRosRttTexture(unsigned width, unsigned height, Ogre::Camera * camera, bool isDepth /*= false*/ ) : m_materialName("MyRttMaterial") , width_(width) , height_(height) , frame_("/map") , m_bIsDepth( isDepth ) { assert( height > 0 && width > 0 ); { // Set encoding current_image_.encoding = ROS_IMAGE_FORMAT; // Set image size current_image_.width = width; current_image_.height = height; // Set image row length in bytes (row length * 3 bytes for a color) current_image_.step = width * BPP; #if OGRE_ENDIAN == ENDIAN_BIG current_image_.is_bigendian = true; #else current_image_.is_bigendian = false; #endif // Resize data current_image_.data.resize( width_ * height_ * BPP); } Ogre::TextureManager & lTextureManager( Ogre::TextureManager::getSingleton() ); Ogre::String textureName("RVIZ_CamCast_Texture"); bool lGammaCorrection( false ); unsigned int lAntiAliasing( 0 ); unsigned int lNumMipmaps( 0 ); if( isDepth ) { texture_ = lTextureManager.createManual(textureName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, width, height, lNumMipmaps, OGRE_DEPTH_TEXTURE_FORMAT, Ogre::TU_RENDERTARGET, 0, lGammaCorrection, lAntiAliasing); } else { texture_ = lTextureManager.createManual(textureName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, width, height, lNumMipmaps, OGRE_TEXTURE_FORMAT, Ogre::TU_RENDERTARGET, 0, lGammaCorrection, lAntiAliasing); } // Create render target Ogre::RenderTexture* lRenderTarget = NULL; Ogre::HardwarePixelBufferSharedPtr lRttBuffer = texture_->getBuffer(); lRenderTarget = lRttBuffer->getRenderTarget(); lRenderTarget->setAutoUpdated(true); // Create and attach viewport Ogre::Viewport* lRttViewport1 = lRenderTarget->addViewport(camera, 50, 0.00f, 0.00f, 1.0f, 1.0f); lRttViewport1->setAutoUpdated(true); Ogre::ColourValue lBgColor1(0.0,0.0,0.0,1.0); lRttViewport1->setBackgroundColour(lBgColor1); // create a material using this texture. //Get a reference on the material manager, which is a singleton. Ogre::MaterialManager& lMaterialManager = Ogre::MaterialManager::getSingleton(); Ogre::MaterialPtr lMaterial = lMaterialManager.create(m_materialName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); Ogre::Technique * lTechnique = lMaterial->getTechnique(0); Ogre::Pass* lPass = lTechnique->getPass(0); if( isDepth ) { lPass->setLightingEnabled(false); } Ogre::TextureUnitState* lTextureUnit = lPass->createTextureUnitState(); lTextureUnit->setTextureName(textureName); lTextureUnit->setNumMipmaps(0); lTextureUnit->setTextureFiltering(Ogre::TFO_BILINEAR); update(); }
void DirectShowMovieTexture::updateMovieTexture() { HRESULT hr; unsigned int i, idx; int x, y; BYTE* bmpTmp; // only do this if there is a graph that has been set up if (!dsdata->pGraph) return; // Find the required buffer size. long cbBuffer = 0; hr = dsdata->pGrabber->GetCurrentBuffer(&cbBuffer, NULL); if (cbBuffer<=0) { // nothing to do here yet return; } char *pBuffer = new char[cbBuffer]; if (!pBuffer) { // out of memory! throw("[DSHOW] Out of memory or empty buffer"); } hr = dsdata->pGrabber->GetCurrentBuffer(&cbBuffer, (long*)pBuffer); if (hr==E_INVALIDARG || hr==VFW_E_NOT_CONNECTED || hr==VFW_E_WRONG_STATE) { // we aren't buffering samples yet, do nothing delete[] pBuffer; return; } if (FAILED(hr)) throw("[DSHOW] Failed at GetCurrentBuffer!"); // OGRE BEGIN // OGRE TEXTURE LOCK // get the texture pixel buffer int texw=mTexture->getWidth(); int texh=mTexture->getHeight(); Ogre::HardwarePixelBufferSharedPtr pixelBuffer = mTexture->getBuffer(); bmpTmp=(BYTE*)pBuffer; // lock the pixel buffer and get a pixel box pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock(); Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data); // FILL! // check for mirroring... bool shouldBeMirrored=mHorizontalMirroring; if (shouldBeMirrored){ x=dsdata->videoWidth-1; y=dsdata->videoHeight-1; }else{ x=0; y=dsdata->videoHeight-1; } // go set all bits... for (i=0; i<(dsdata->videoWidth*dsdata->videoHeight*3); i+=3){ idx=(x*4)+y*pixelBox.rowPitch*4; // paint pDest[idx]=bmpTmp[i];//b pDest[idx+1]=bmpTmp[i+1];//g pDest[idx+2]=bmpTmp[i+2];//r pDest[idx+3]=255;//a if (shouldBeMirrored){ x--; if (x<0){ x=dsdata->videoWidth-1; y--; if (y<0) y=0; } }else{ x++; if (x>=dsdata->videoWidth){ x=0; y--; if (y<0) y=0; } } } // UNLOCK EVERYTHING! // unlock the pixel buffer pixelBuffer->unlock(); // OGRE END // bye delete[] pBuffer; }
//------------------------------------------------------ void TextureAtlas::build() { if (!mIsDirty) return; bool fitted; size_t area = 0; // build the fonts (if this didn't happen already) // so we'll be sure the glyphs are there to be atlassed FontSet::iterator fit = mMyFonts.begin(); while (fit != mMyFonts.end()) { FontDrawSource* fdsp = *fit++; if (!fdsp->isBuilt()) fdsp->build(); } // First, we sort by size of the DrawSource mMyDrawSources.sort(DrawSourceLess()); // now try to allocate all the draw sources. If we fail, grow and try again do { fitted = true; area = 0; // try to fit DrawSourceList::iterator it = mMyDrawSources.begin(); while (it != mMyDrawSources.end()) { const DrawSourcePtr& ds = *it++; const PixelSize& ps = ds->getPixelSize(); area += ps.getPixelArea(); LOG_VERBOSE("TextureAtlas: (%s) Trying to place %d x %d (%d -> %d)", mAtlasName.c_str(), ps.width, ps.height, ps.getPixelArea(), area); // try to allocate FreeSpaceInfo* fsi = mAtlasAllocation->allocate(ps.width, ps.height); if (fsi) { ds->setPlacementPtr(fsi); } else { fitted = false; break; } } // fitted? if (!fitted) // nope - Enlarge! enlarge(area); } while (!fitted); LOG_INFO("TextureAtlas: (%s) Creating atlas with dimensions %d x %d", mAtlasName.c_str(), mAtlasSize.width, mAtlasSize.height); if (mTexture.isNull()) prepareResources(); // TODO: Reallocate the texture here if needed! Ogre::HardwarePixelBufferSharedPtr pixelBuffer = mTexture->getBuffer(); pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); const Ogre::PixelBox& targetBox = pixelBuffer->getCurrentLock(); size_t pixelsize = Ogre::PixelUtil::getNumElemBytes(targetBox.format); size_t rowsize = targetBox.rowPitch * pixelsize; Ogre::uint8* dstData = static_cast<Ogre::uint8*>(targetBox.data); // We'll iterate over all draw sources, painting the pixels onto the allocated space DrawSourceList::iterator it = mMyDrawSources.begin(); while (it != mMyDrawSources.end()) { const DrawSourcePtr& ds = *it++; // render all pixels into the right place FreeSpaceInfo* fsi = reinterpret_cast<FreeSpaceInfo*>(ds->getPlacementPtr()); assert(fsi); // render into the specified place unsigned char* conversionBuf = NULL; const PixelSize& dps = ds->getPixelSize(); Ogre::Image* img = ds->getImage(); Ogre::PixelBox srcPixels = img->getPixelBox(); // convert if the source data don't match if(img->getFormat() != Ogre::PF_BYTE_BGRA) { conversionBuf = new unsigned char[img->getWidth() * img->getHeight() * pixelsize]; Ogre::PixelBox convPixels(Ogre::Box(0, 0, dps.width, dps.height), Ogre::PF_BYTE_BGRA, conversionBuf); Ogre::PixelUtil::bulkPixelConversion(srcPixels, convPixels); srcPixels = convPixels; } size_t srcrowsize = srcPixels.rowPitch * pixelsize; Ogre::uint8* srcData = static_cast<Ogre::uint8*>(srcPixels.data); // TODO: we're always handling 32bit data, so we could as well transfer 4 bytes each iteration instead of one (speedup) for(size_t row = 0; row < dps.height; row++) { for(size_t col = 0; col < srcrowsize; col++) { dstData[((row + fsi->y) * rowsize) + (fsi->x * pixelsize) + col] = srcData[(row * srcrowsize) + col]; } } delete[] conversionBuf; // Convert the full draw source pixel coordinates to the atlas contained ones (initializes the texturing coordinates transform) ds->atlas(mMaterial, fsi->x, fsi->y, mAtlasSize.width, mAtlasSize.height); } // for debug, write the texture to a file /*unsigned char *readrefdata = static_cast<unsigned char*>(targetBox.data); Ogre::Image img; img = img.loadDynamicImage (readrefdata, mTexture->getWidth(), mTexture->getHeight(), mTexture->getFormat()); img.save(mAtlasName + ".png");*/ // and close the pixel buffer of the atlas at the end pixelBuffer->unlock(); mIsDirty = false; }
void TestGame::DrawPlanetMap(Logic::PlanetJustGenerateEvent *evnt){ std::map<Logic::BaseCountry*,std::vector<Logic::CountryTile>>::iterator CntrItr; std::vector<Logic::CountryTile>::iterator TileItr; int tilesize=TILESIZE; bool why; Ogre::Vector3 tempVect; int maxX = (int)Logic::BaseAsset::GetSigleton("MAP_X"),maxY=(int)Logic::BaseAsset::GetSigleton("MAP_Y"); Ogre::SceneNode* node,*capitalNode,*mapnode =mSceneMgr->getRootSceneNode()->createChildSceneNode("Map"); mapnode->translate(-maxX/2*tilesize,-maxY/2*tilesize,0); Ogre::Entity* entNinja = 0; Ogre::FontPtr font = Ogre::FontManager::getSingleton().getResourceIterator().begin()->second; // Make sure the texture is not WRITE_ONLY, we need to read the buffer to do the blending with the font (get the alpha for example) int j =0; for(CntrItr=evnt->allTiles.begin();CntrItr!=evnt->allTiles.end(); CntrItr++){ Ogre::ManualObject* manual = mSceneMgr->createManualObject("CountryObject"+CntrItr->first->mName); Ogre::Texture* texture = Ogre::TextureManager::getSingleton().createManual("CountryText"+CntrItr->first->mName,"General",Ogre::TEX_TYPE_2D,512, 512, 0, Ogre::PF_FLOAT32_RGBA , Ogre::TU_DEFAULT).getPointer(); Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create("CountryMaterial"+CntrItr->first->mName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); //Draw the background to the new texture Ogre::HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer(); // Lock the pixel buffer and get a pixel box pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL); // for best performance use HBL_DISCARD! const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock(); float *pDest = static_cast<float*>(pixelBox.data); Ogre::ColourValue *temp = &CntrItr->first->mColor; // Fill in some pixel data. This will give a semi-transparent blue, // but this is of course dependent on the chosen pixel format. for (size_t k = 0; k < 512; k++) for(size_t q = 0; q < 512; q++) { *pDest++ =temp->b; // B *pDest++ = temp->g; *pDest++ =temp->r; *pDest++ = 0; // A*/ /* *pDest++ = 255; // B *pDest++ = 0; // G *pDest++ = 0; // R *pDest++ = 127; // A*/ } // Unlock the pixel buffer pixelBuffer->unlock(); ///WriteToTexture(Logic::LogicStd::IntToString(j),Ogre::TexturePtr(texture),Ogre::Image::Box(25,275,370,500),font,Ogre::ColourValue(1.0,1.0,1.0,1.0),'c'); mat->getTechnique(0)->getPass(0)->createTextureUnitState("CountryText"+CntrItr->first->mName); // mat->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA); j++; // specify the material (by name) and rendering type manual->begin("CountryMaterial"+CntrItr->first->mName, Ogre::RenderOperation::OT_TRIANGLE_LIST); int i=0; for(TileItr= CntrItr->second.begin();TileItr!= CntrItr->second.end();TileItr++){ tempVect = calculateActualPointFromCenter(CntrItr->first->mCapital.mPosition,(*TileItr).mPosition); tempVect =tempVect*tilesize; manual->position(tempVect.x-tilesize/2,tempVect.y+tilesize/2,tempVect.z); //manual->colour(CntrItr->first->mColor); manual->position(tempVect.x+tilesize/2,tempVect.y+tilesize/2,tempVect.z); //manual->colour(CntrItr->first->mColor); manual->position(tempVect.x+tilesize/2,tempVect.y-tilesize/2,tempVect.z); //manual->colour(CntrItr->first->mColor); manual->position(tempVect.x-tilesize/2,tempVect.y-tilesize/2,tempVect.z); //manual->colour(CntrItr->first->mColor); manual->triangle(i*4+0,i*4+2,i*4+1); manual->triangle(i*4+0,i*4+3,i*4+2); //manual->quad(i*4+0,i*4+2,i*4+3,i*4+1); i++; } // tell Ogre, your definition has finished manual->end(); // add ManualObject to the RootSceneNode (so it will be visible) node =mapnode->createChildSceneNode(); entNinja= mSceneMgr->createEntity("Capital/"+CntrItr->first->mName, "capital.mesh"); entNinja->setCastShadows(true); entNinja->setMaterialName("CountryMaterial"+CntrItr->first->mName); Control::ClickHelper* helpr = new Control::ClickHelper(Logic::CHT_COUNTRY); helpr->target = CntrItr->first; entNinja->setUserAny(Ogre::Any(helpr)); CntrItr->first->mNode = node; capitalNode = node->createChildSceneNode(); capitalNode->attachObject(entNinja); capitalNode->pitch(Ogre::Degree(90)); node->attachObject(manual); // I move the SceneNode so that it is visible to the camera. tempVect = Ogre::Vector3(CntrItr->first->mCapital.mPosition.x*tilesize,CntrItr->first->mCapital.mPosition.y*tilesize,-10); node->translate(tempVect); } mapnode->pitch(Ogre::Degree(-45)); }