void LodTextureManager::loadResource(Ogre::Resource* res) { int alpha = 0; angel::Log << angel::aeLog::debug <<"loading texture " << res->getName() << angel::aeLog::endl; angel::pLodData ldata = angel::LodManager.LoadFileData( res->getName() ); // angel::pLodData ldata=angel::LodManager.LoadFile( res->getName() ); if(!ldata) return GetDefaultTexture(res); angel::pLodData hdr = angel::LodManager.LoadFileHdr( res->getName() ); BYTE*data= &((*ldata)[0]); BYTE*hdrdata= &((*hdr)[0]); int size = (int)ldata->size(); int psize = *(int*)(hdrdata+0x4); unsigned int unpsize1 = *(int*)(hdrdata+0x0); unsigned long unpsize2 = *(int*)(hdrdata+0x18); if( unpsize2+0x300 != size ) { //angel::Log <<"texture " << res->getName() << " error datasize " << unpsize2 << "/" << size<< angel::aeLog::endl; //return GetDefaultTexture(res); return loadSprite(res,hdr,ldata); } // if( unpsize2 && unpsize2 < unpsize1) // return GetDefaultTexture(res); BYTE* pal = data + unpsize2; int width = *(WORD*)(hdrdata+0x8); int height = *(WORD*)(hdrdata+0xa); int imgsize = width*height; BYTE *pSrc=data; /* BYTE*data= &((*ldata)[0]); int size = (int)ldata->size(); int psize = *(int*)(data+0x14); unsigned int unpsize1 = *(int*)(data+0x10); unsigned long unpsize2 = *(int*)(data+0x28); if( psize+0x30+0x300 != size ) return GetDefaultTexture(res); if( unpsize2 && unpsize2 < unpsize1) return GetDefaultTexture(res); BYTE* pal = data + 0x30 + psize; BYTE*unpdata = new BYTE[unpsize2 ]; boost::scoped_array<BYTE> sunpdata(unpdata); if ( uncompress( unpdata, &unpsize2 , data + 0x30, psize ) != Z_OK ) return; int width = *(WORD*)(data+0x18); int height = *(WORD*)(data+0x1a); int imgsize = width*height; BYTE *pSrc=unpdata;*/ int nummipmaps = 3; // Create the texture Texture* texture = static_cast<Texture*>(res); texture->setTextureType(TEX_TYPE_2D); texture->setWidth(width); texture->setHeight(height); texture->setNumMipmaps(nummipmaps); texture->setFormat(PF_BYTE_BGRA); texture->setUsage(TU_DEFAULT); texture->setDepth(1); texture->setHardwareGammaEnabled(false); texture->setFSAA(0); texture->createInternalResources(); /*TextureManager::getSingleton().createManual( name + ".Texture", // name ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, // type width, height, // width & height nummipmaps, // number of mipmaps PF_BYTE_BGRA, // pixel format TU_DEFAULT); // usage; should be TU_DYNAMIC_WRITE_ONLY_DISCARDABLE for */ // Fill in some pixel data. This will give a semi-transparent blue, // but this is of course dependent on the chosen pixel format. int w=width; int h=height; int n=0,off=0; nummipmaps = (int)texture->getNumMipmaps(); for ( n = 0,off= 0; off < (int)unpsize2 && n <nummipmaps + 1 ; n++) { if( w < 1 || h <1 ) break; // Get the pixel buffer HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer(0,n); // Lock the pixel buffer and get a pixel box pixelBuffer->lock(HardwareBuffer::HBL_NORMAL); // for best performance use HBL_DISCARD! const PixelBox& pixelBox = pixelBuffer->getCurrentLock(); uint8* pDest = static_cast<uint8*>(pixelBox.data); for (int j = 0; j < w; j++) for(int i = 0; i < h; i++) { int index=*pSrc++; int r = pal[index*3+0]; int g = pal[index*3+1]; int b = pal[index*3+2]; int a = 0xff; if( index == 0 && ((r == 0 && g >250 && b > 250) || (r > 250 && g ==0 && b > 250))) { alpha=1; a= 0; r=g=b=0; } *pDest++ = b; // G *pDest++ = g; // R *pDest++ = r; *pDest++ = a; // A } pixelBuffer->unlock(); //off += w*h; w/=2; h/=2; } // Unlock the pixel buffer }
//------------------------------------------------------------------------------ void SegmentedDynamicLightManager::updateTextureFromSegmentedLists(const Camera* i_pCamera) { float spotIntensity = 1; HardwarePixelBufferSharedPtr pBuf = mLightTexture->getBuffer(); void* pStartPos = pBuf->lock(HardwareBuffer::HBL_DISCARD); uint16* pData = (uint16*)pStartPos; size_t remainBufWidth = mTextureWidth; for(size_t j = 0; j < SDL_SEGMENT_GRID_SIZE; ++j) { //assign first row with number of indexes in the block float maxRow = (float)(mSegmentedLightGrid[j].size() - 1 + SDL_TEXTURE_DATA_ROWS); PixelUtil::packColour(maxRow,0.0f,0.0f,0.0f,PF_FLOAT16_RGBA, pData); pData += 4 * SDL_LIGHT_DATA_SIZE; remainBufWidth -= SDL_LIGHT_DATA_SIZE; } //advance the remaining space of the row pData += 4 * remainBufWidth; for(size_t i = 0 ; i < SDL_LIGHT_PER_BLOCK ; ++i) { remainBufWidth = mTextureWidth; for(size_t j = 0; j < SDL_SEGMENT_GRID_SIZE; ++j) { if (i < mSegmentedLightGrid[j].size()) { const Light* pLight = mSegmentedLightGrid[j][i]; const Vector3& position = pLight->getDerivedPosition(true); Vector3 direction = -pLight->getDerivedDirection(); direction.normalise(); // Update spotlight parameters. Vector3 spotParam; float inverseRange = 1.0f / (float)pLight->getAttenuationRange(); float spotAngle = -1; float spotInvAngleRange = std::numeric_limits<float>::max(); if (pLight->getType() == Light::LT_SPOTLIGHT) { Real phi = Math::Cos(pLight->getSpotlightOuterAngle().valueRadians() * 0.5f); Real theta = Math::Cos(pLight->getSpotlightInnerAngle().valueRadians() * 0.5f); spotAngle = (float)phi; spotInvAngleRange = 1.0f / (float)(theta - phi); } PixelUtil::packColour( (float)position.x, (float)position.y, (float)position.z, inverseRange, PF_FLOAT16_RGBA, pData); pData += 4; PixelUtil::packColour( (float)direction.x, (float)direction.y, (float)direction.z, spotAngle, PF_FLOAT16_RGBA, pData); pData += 4; PixelUtil::packColour( pLight->getDiffuseColour().r * spotIntensity, pLight->getDiffuseColour().g * spotIntensity, pLight->getDiffuseColour().b * spotIntensity, spotInvAngleRange, PF_FLOAT16_RGBA, pData); pData += 4; } else { //assign position zero with zero width PixelUtil::packColour(0.0f,0.0f,0.0f,std::numeric_limits<float>::max(), PF_FLOAT16_RGBA, pData); pData += 4; for(int d = 0 ; d < (SDL_LIGHT_DATA_SIZE - 1) ; ++d) { PixelUtil::packColour(0.0f,0.0f,0.0f,0.0f,PF_FLOAT16_RGBA, pData); pData += 4; } } remainBufWidth -= 3; } //advance the remaining space of the row pData += 4 * remainBufWidth; } //Check for memory overrun if (pBuf->getSizeInBytes() != (size_t)((const char*)(void*)pData - (const char*)pStartPos)) { throw "memory overrun"; } pBuf->unlock(); }
//-------------------------------------------------------------------------- void CompositorDemo::createTextures(void) { using namespace Ogre; TexturePtr tex = TextureManager::getSingleton().createManual( "HalftoneVolume", "General", TEX_TYPE_3D, 64,64,64, 0, PF_A8 ); HardwarePixelBufferSharedPtr ptr = tex->getBuffer(0,0); ptr->lock(HardwareBuffer::HBL_DISCARD); const PixelBox &pb = ptr->getCurrentLock(); uint8 *data = static_cast<uint8*>(pb.data); size_t height = pb.getHeight(); size_t width = pb.getWidth(); size_t depth = pb.getDepth(); size_t rowPitch = pb.rowPitch; size_t slicePitch = pb.slicePitch; for (size_t z = 0; z < depth; ++z) { for (size_t y = 0; y < height; ++y) { for(size_t x = 0; x < width; ++x) { float fx = 32-(float)x+0.5f; float fy = 32-(float)y+0.5f; float fz = 32-((float)z)/3+0.5f; float distanceSquare = fx*fx+fy*fy+fz*fz; data[slicePitch*z + rowPitch*y + x] = 0x00; if (distanceSquare < 1024.0f) data[slicePitch*z + rowPitch*y + x] += 0xFF; } } } ptr->unlock(); Ogre::Viewport *vp = mRoot->getAutoCreatedWindow()->getViewport(0); TexturePtr tex2 = TextureManager::getSingleton().createManual( "DitherTex", "General", TEX_TYPE_2D, vp->getActualWidth(),vp->getActualHeight(),1, 0, PF_A8 ); HardwarePixelBufferSharedPtr ptr2 = tex2->getBuffer(0,0); ptr2->lock(HardwareBuffer::HBL_DISCARD); const PixelBox &pb2 = ptr2->getCurrentLock(); uint8 *data2 = static_cast<uint8*>(pb2.data); size_t height2 = pb2.getHeight(); size_t width2 = pb2.getWidth(); size_t rowPitch2 = pb2.rowPitch; for (size_t y = 0; y < height2; ++y) { for(size_t x = 0; x < width2; ++x) { data2[rowPitch2*y + x] = Ogre::Math::RangeRandom(64.0,192); } } ptr2->unlock(); }
//Parse sceneMetaData into UserTexture void KinectDevice::ParseUserTexture(xn::SceneMetaData *sceneMetaData, bool m_front) { #if SHOW_DEPTH || SHOW_BAR //TexturePtr texture = TextureManager::getSingleton().getByName("MyDepthTexture"); //TexturePtr texture = TextureManager::getSingleton().getByName("MyDepthTexture2"); if(mUserTexture.isNull()) return; // Get the pixel buffer HardwarePixelBufferSharedPtr pixelBuffer = mUserTexture->getBuffer(); // Lock the pixel buffer and get a pixel box pixelBuffer->lock(HardwareBuffer::HBL_DISCARD); const PixelBox& pixelBox = pixelBuffer->getCurrentLock(); unsigned char* pDest = static_cast<unsigned char*>(pixelBox.data); // Get label map const XnLabel* pUsersLBLs = sceneMetaData->Data(); for (size_t j = 0; j < KINECT_DEPTH_HEIGHT; j++) { pDest = static_cast<unsigned char*>(pixelBox.data) + j*pixelBox.rowPitch*4; #if SHOW_DEPTH for(size_t i = 0; i < KINECT_DEPTH_WIDTH; i++) #elif SHOW_BAR for(size_t i = 0; i < 50; i++) #endif { // fix i if we are mirrored uint fixed_i = i; if(!m_front) { fixed_i = KINECT_DEPTH_WIDTH - i; } // determine color #if SHOW_DEPTH unsigned int color = GetColorForUser(pUsersLBLs[j*KINECT_DEPTH_WIDTH + fixed_i]); // if we have a candidate, filter out the rest if (m_candidateID != 0) { if (m_candidateID == pUsersLBLs[j*KINECT_DEPTH_WIDTH + fixed_i]) { color = GetColorForUser(1); if( j > KINECT_DEPTH_HEIGHT*(1 - m_pStartPoseDetector->GetDetectionPercent())) { //highlight user color |= 0xFF070707; } if( j < KINECT_DEPTH_HEIGHT*(m_pEndPoseDetector->GetDetectionPercent())) { //hide user color &= 0x20F0F0F0; } } else { color = 0; } } #elif SHOW_BAR // RED. kinda. unsigned int color = 0x80FF0000; if( j > KINECT_DEPTH_HEIGHT*(1 - m_pStartPoseDetector->GetDetectionPercent())) { //highlight user color |= 0xFF070707; } if( j < KINECT_DEPTH_HEIGHT*(m_pEndPoseDetector->GetDetectionPercent())) { //hide user color &= 0x20F0F0F0; } if ((m_pStartPoseDetector->GetDetectionPercent() == 1) || (m_pEndPoseDetector->GetDetectionPercent() == 1)) { color = 0; } #endif // write to output buffer *((unsigned int*)pDest) = color; pDest+=4; } } // Unlock the pixel buffer pixelBuffer->unlock(); #endif // SHOW_DEPTH }
TexturePtr GetLodTexture(const std::string& name) { std::string texname(name + ".Texture"); if(TextureManager::getSingleton().resourceExists(texname)) return TextureManager::getSingleton().getByName(texname); angel::Log << "loading texture " << name << angel::aeLog::endl; int alpha = 0; angel::pLodData ldata=angel::LodManager.LoadFile( name ); if(!ldata) return GetDefaultTexture(); BYTE*data= &((*ldata)[0]); int size = (int)ldata->size(); int psize = *(int*)(data+0x14); unsigned int unpsize1 = *(int*)(data+0x10); unsigned long unpsize2 = *(int*)(data+0x28); if( psize+0x30+0x300 != size ) return GetDefaultTexture(); if( unpsize2 && unpsize2 < unpsize1) return GetDefaultTexture(); BYTE* pal = data + 0x30 + psize; BYTE*unpdata = new BYTE[unpsize2 ]; boost::scoped_array<BYTE> sunpdata(unpdata); if ( uncompress( unpdata, &unpsize2 , data + 0x30, psize ) != Z_OK ) return GetDefaultTexture(); int width = *(WORD*)(data+0x18); int height = *(WORD*)(data+0x1a); int imgsize = width*height; BYTE *pSrc=unpdata; int nummipmaps = 3; // Create the texture TexturePtr texture = TextureManager::getSingleton().createManual( name + ".Texture", // name ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, // type width, height, // width & height nummipmaps, // number of mipmaps PF_BYTE_BGRA, // pixel format TU_DEFAULT); // usage; should be TU_DYNAMIC_WRITE_ONLY_DISCARDABLE for // Fill in some pixel data. This will give a semi-transparent blue, // but this is of course dependent on the chosen pixel format. int w=width; int h=height; int n=0,off=0; nummipmaps = (int)texture->getNumMipmaps(); for ( n = 0,off= 0; off < (int)unpsize2 && n <nummipmaps + 1 ; n++) { if( w < 1 || h <1 ) break; // Get the pixel buffer HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer(0,n); // Lock the pixel buffer and get a pixel box pixelBuffer->lock(HardwareBuffer::HBL_NORMAL); // for best performance use HBL_DISCARD! const PixelBox& pixelBox = pixelBuffer->getCurrentLock(); uint8* pDest = static_cast<uint8*>(pixelBox.data); for (int j = 0; j < w; j++) for(int i = 0; i < h; i++) { int index=*pSrc++; int r = pal[index*3+0]; int g = pal[index*3+1]; int b = pal[index*3+2]; int a = 0xff; if( index == 0 && ((r == 0 && g >250 && b > 250) || (r > 250 && g ==0 && b > 250))) { alpha=1; a= 0; r=g=b=0; } *pDest++ = b; // G *pDest++ = g; // R *pDest++ = r; *pDest++ = a; // A } pixelBuffer->unlock(); //off += w*h; w/=2; h/=2; } // Unlock the pixel buffer return texture; }
void WriteToTexture(const String &str, TexturePtr destTexture, Image::Box destRectangle, Font* font, const ColourValue &color, char justify, bool wordwrap) { using namespace Ogre; if (destTexture->getHeight() < destRectangle.bottom) destRectangle.bottom = destTexture->getHeight(); if (destTexture->getWidth() < destRectangle.right) destRectangle.right = destTexture->getWidth(); if (!font->isLoaded()) font->load(); TexturePtr fontTexture = (TexturePtr) TextureManager::getSingleton().getByName(font->getMaterial()->getTechnique(0)->getPass(0)->getTextureUnitState(0)->getTextureName()); HardwarePixelBufferSharedPtr fontBuffer = fontTexture->getBuffer(); HardwarePixelBufferSharedPtr destBuffer = destTexture->getBuffer(); PixelBox destPb = destBuffer->lock(destRectangle,HardwareBuffer::HBL_NORMAL); // The font texture buffer was created write only...so we cannot read it back :o). One solution is to copy the buffer instead of locking it. (Maybe there is a way to create a font texture which is not write_only ?) // create a buffer size_t nBuffSize = fontBuffer->getSizeInBytes(); unsigned char* buffer = (unsigned char*)calloc(nBuffSize, sizeof(unsigned char)); // create pixel box using the copy of the buffer PixelBox fontPb(fontBuffer->getWidth(), fontBuffer->getHeight(),fontBuffer->getDepth(), fontBuffer->getFormat(), buffer); fontBuffer->blitToMemory(fontPb); unsigned char* fontData = static_cast<unsigned char*>( fontPb.data ); unsigned char* destData = static_cast<unsigned char*>( destPb.data ); const size_t fontPixelSize = PixelUtil::getNumElemBytes(fontPb.format); const size_t destPixelSize = PixelUtil::getNumElemBytes(destPb.format); const size_t fontRowPitchBytes = fontPb.rowPitch * fontPixelSize; const size_t destRowPitchBytes = destPb.rowPitch * destPixelSize; Box *GlyphTexCoords; GlyphTexCoords = new Box[str.size()]; Font::UVRect glypheTexRect; size_t charheight = 0; size_t charwidth = 0; for (unsigned int i = 0; i < str.size(); i++) { if ((str[i] != '\t') && (str[i] != '\n') && (str[i] != ' ')) { glypheTexRect = font->getGlyphTexCoords(str[i]); GlyphTexCoords[i].left = glypheTexRect.left * fontTexture->getSrcWidth(); GlyphTexCoords[i].top = glypheTexRect.top * fontTexture->getSrcHeight(); GlyphTexCoords[i].right = glypheTexRect.right * fontTexture->getSrcWidth(); GlyphTexCoords[i].bottom = glypheTexRect.bottom * fontTexture->getSrcHeight(); if (GlyphTexCoords[i].getHeight() > charheight) charheight = GlyphTexCoords[i].getHeight(); if (GlyphTexCoords[i].getWidth() > charwidth) charwidth = GlyphTexCoords[i].getWidth(); } } size_t cursorX = 0; size_t cursorY = 0; size_t lineend = destRectangle.getWidth(); bool carriagreturn = true; for (unsigned int strindex = 0; strindex < str.size(); strindex++) { switch(str[strindex]) { case ' ': cursorX += charwidth; break; case '\t': cursorX += charwidth * 3; break; case '\n': cursorY += charheight; carriagreturn = true; break; default: { //wrapping if ((cursorX + GlyphTexCoords[strindex].getWidth()> lineend) && !carriagreturn ) { cursorY += charheight; carriagreturn = true; } //justify if (carriagreturn) { size_t l = strindex; size_t textwidth = 0; size_t wordwidth = 0; while( (l < str.size() ) && (str[l] != '\n')) { wordwidth = 0; switch (str[l]) { case ' ': wordwidth = charwidth; ++l; break; case '\t': wordwidth = charwidth *3; ++l; break; case '\n': l = str.size(); } if (wordwrap) while((l < str.size()) && (str[l] != ' ') && (str[l] != '\t') && (str[l] != '\n')) { wordwidth += GlyphTexCoords[l].getWidth(); ++l; } else { wordwidth += GlyphTexCoords[l].getWidth(); l++; } if ((textwidth + wordwidth) <= destRectangle.getWidth()) textwidth += (wordwidth); else break; } if ((textwidth == 0) && (wordwidth > destRectangle.getWidth())) textwidth = destRectangle.getWidth(); switch (justify) { case 'c': cursorX = (destRectangle.getWidth() - textwidth)/2; lineend = destRectangle.getWidth() - cursorX; break; case 'r': cursorX = (destRectangle.getWidth() - textwidth); lineend = destRectangle.getWidth(); break; default: cursorX = 0; lineend = textwidth; break; } carriagreturn = false; } //abort - net enough space to draw if ((cursorY + charheight) > destRectangle.getHeight()) goto stop; //draw pixel by pixel for (size_t i = 0; i < GlyphTexCoords[strindex].getHeight(); i++ ) for (size_t j = 0; j < GlyphTexCoords[strindex].getWidth(); j++) { float alpha = color.a * (fontData[(i + GlyphTexCoords[strindex].top) * fontRowPitchBytes + (j + GlyphTexCoords[strindex].left) * fontPixelSize +1 ] / 255.0); float invalpha = 1.0 - alpha; size_t offset = (i + cursorY) * destRowPitchBytes + (j + cursorX) * destPixelSize; ColourValue pix; PixelUtil::unpackColour(&pix,destPb.format,&destData[offset]); pix = (pix * invalpha) + (color * alpha); PixelUtil::packColour(pix,destPb.format,&destData[offset]); } cursorX += GlyphTexCoords[strindex].getWidth(); }//default }//switch }//for stop: delete[] GlyphTexCoords; destBuffer->unlock(); // Free the memory allocated for the buffer free(buffer); buffer = 0; }
TexturePtr TerrainManager::getVertexColours(ESM::Land* land, int cellX, int cellY, int fromX, int fromY, int size) { TextureManager* const texMgr = TextureManager::getSingletonPtr(); const std::string colourTextureName = "VtexColours_" + boost::lexical_cast<std::string>(cellX) + "_" + boost::lexical_cast<std::string>(cellY) + "_" + boost::lexical_cast<std::string>(fromX) + "_" + boost::lexical_cast<std::string>(fromY); TexturePtr tex = texMgr->getByName(colourTextureName); if ( !tex.isNull() ) { return tex; } tex = texMgr->createManual(colourTextureName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, size, size, 0, PF_BYTE_BGR); HardwarePixelBufferSharedPtr pixelBuffer = tex->getBuffer(); pixelBuffer->lock(HardwareBuffer::HBL_DISCARD); const PixelBox& pixelBox = pixelBuffer->getCurrentLock(); uint8* pDest = static_cast<uint8*>(pixelBox.data); if ( land != NULL ) { const char* const colours = land->mLandData->mColours; for ( int y = 0; y < size; y++ ) { for ( int x = 0; x < size; x++ ) { const size_t colourOffset = (y+fromY)*3*65 + (x+fromX)*3; assert( colourOffset < 65*65*3 && "Colour offset is out of the expected bounds of record" ); const unsigned char r = colours[colourOffset + 0]; const unsigned char g = colours[colourOffset + 1]; const unsigned char b = colours[colourOffset + 2]; //as is the case elsewhere we need to flip the y const size_t imageOffset = (size - 1 - y)*size*4 + x*4; pDest[imageOffset + 0] = b; pDest[imageOffset + 1] = g; pDest[imageOffset + 2] = r; } } } else { for ( int y = 0; y < size; y++ ) { for ( int x = 0; x < size; x++ ) { for ( int k = 0; k < 3; k++ ) { *pDest++ = 0; } } } } pixelBuffer->unlock(); return tex; }
void HTML::CreateMaterial(const std::string &name, bool destroyPrevious) { using namespace Ogre; if(destroyPrevious) { static_cast<Ogre::MaterialPtr>(Ogre::MaterialManager::getSingleton().getByName(materialName))->getTechnique(0)->getPass(0)->removeAllTextureUnitStates(); std::string texture_name = texture->getName(); Ogre::TextureManager::getSingleton().remove(texture_name); texture = 0; } if(!Bitwise::isPO2(textureWidth) || !Bitwise::isPO2(textureHeight)) { const Ogre::RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); if(caps && caps->hasCapability(RSC_NON_POWER_OF_2_TEXTURES)) { if(Root::getSingleton().getRenderSystem()->getCapabilities()->getNonPOW2TexturesLimited()) compensateNPOT = true; } else compensateNPOT = true; if(compensateNPOT) { textureWidth = Bitwise::firstPO2From(textureWidth); textureHeight = Bitwise::firstPO2From(textureHeight); } } //Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME texture = Ogre::TextureManager::getSingleton().createManual(name + "_texture", MY_GROUP_NAME, Ogre::TEX_TYPE_2D, textureWidth, textureHeight, 0, // no mipmaps Ogre::PF_BYTE_BGRA, Ogre::TU_DYNAMIC).get(); //Ogre::PF_BYTE_RGBA, Ogre::TU_DYNAMIC).get(); //Ogre::PF_BYTE_RGBA, Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE).get(); // this clears buffer. may not be needed /**/ HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer(); pixelBuffer->lock(HardwareBuffer::HBL_DISCARD); const PixelBox& pixelBox = pixelBuffer->getCurrentLock(); unsigned int texDepth = Ogre::PixelUtil::getNumElemBytes(pixelBox.format); unsigned int texPitch = (pixelBox.rowPitch * texDepth); uint8* pDest = static_cast<uint8*>(pixelBox.data); memset(pDest, 0, textureHeight * texPitch); pixelBuffer->unlock(); Ogre::MaterialPtr materialPtr; if(materialName == "") { materialName = name + "_mat"; //Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME materialPtr = Ogre::MaterialManager::getSingletonPtr()->create(materialName, MY_GROUP_NAME); } else materialPtr = static_cast<Ogre::MaterialPtr>(Ogre::MaterialManager::getSingleton().getByName(materialName)); materialPtr->getTechnique(0)->getPass(0)->removeAllTextureUnitStates(); // createTextureUnitState should take texture name of the texture we created!!! materialPtr->getTechnique(0)->getPass(0)->createTextureUnitState(name + "_texture"); Ogre::Pass *matPass = materialPtr->getTechnique(0)->getPass(0); //matPass->setSeparateSceneBlending(SBF_ONE, SBF_ONE_MINUS_SOURCE_ALPHA, SBF_SOURCE_ALPHA, SBF_ONE_MINUS_SOURCE_ALPHA); matPass->setDepthWriteEnabled(false); }
/// update brush preview texture //-------------------------------------------------------------------------------------------------------------------------- void App::updateBrushPrv(bool first) { if (!first && (!ovBrushPrv || edMode >= ED_Road /*|| bMoveCam/*|| !bEdit()*/)) return; if (!pSet->brush_prv || brushPrvTex.isNull()) return; // Lock texture and fill pixel data HardwarePixelBufferSharedPtr pbuf = brushPrvTex->getBuffer(); pbuf->lock(HardwareBuffer::HBL_DISCARD); const PixelBox& pb = pbuf->getCurrentLock(); uint8* p = static_cast<uint8*>(pb.data); const float fB = brClr[edMode][0]*255.f, fG = brClr[edMode][1]*255.f, fR = brClr[edMode][2]*255.f; const float s = BrPrvSize * 0.5f, s1 = 1.f/s, fP = mBrPow[curBr], fQ = mBrFq[curBr]*5.f, nof = mBrNOf[curBr]; int oct = mBrOct[curBr]; const float PiN = PI_d/oct; switch (mBrShape[curBr]) { case BRS_Noise2: for (size_t y = 0; y < BrPrvSize; ++y) for (size_t x = 0; x < BrPrvSize; ++x) { float fx = ((float)x - s)*s1, fy = ((float)y - s)*s1; // -1..1 float d = std::max(0.f, 1.f - float(sqrt(fx*fx + fy*fy))); // 0..1 float c = d * (1.0-pow( fabs(Noise(x*s1+nof,y*s1+nof, fQ, oct, 0.5f)), fP*d)) * (1.5f-fP*0.1); c = std::max(0.f, c); uint8 bR = c * fR, bG = c * fG, bB = c * fB; *p++ = bR; *p++ = bG; *p++ = bB; *p++ = bG > 32 ? 255 : 0; } break; case BRS_Noise: for (size_t y = 0; y < BrPrvSize; ++y) for (size_t x = 0; x < BrPrvSize; ++x) { float fx = ((float)x - s)*s1, fy = ((float)y - s)*s1; // -1..1 float d = std::max(0.f, 1.f - float(sqrt(fx*fx + fy*fy))); // 0..1 float c = d * pow( fabs(Noise(x*s1+nof,y*s1+nof, fQ, oct, 0.5f)), fP*0.5f) * 0.9f; uint8 bR = c * fR, bG = c * fG, bB = c * fB; *p++ = bR; *p++ = bG; *p++ = bB; *p++ = bG > 32 ? 255 : 0; } break; case BRS_Sinus: for (size_t y = 0; y < BrPrvSize; ++y) for (size_t x = 0; x < BrPrvSize; ++x) { float fx = ((float)x - s)*s1, fy = ((float)y - s)*s1; // -1..1 float d = std::max(0.f, 1.f - float(sqrt(fx*fx + fy*fy))); // 0..1 float c = powf( sinf(d * PI_d*0.5f), fP); uint8 bR = c * fR, bG = c * fG, bB = c * fB; *p++ = bR; *p++ = bG; *p++ = bB; *p++ = bG > 32 ? 255 : 0; } break; case BRS_Ngon: for (size_t y = 0; y < BrPrvSize; ++y) for (size_t x = 0; x < BrPrvSize; ++x) { float fx = ((float)x - s)*s1, fy = ((float)y - s)*s1; // -1..1 float d = std::max(0.f, 1.f - float(sqrt(fx*fx + fy*fy))); // 0..1 float k = GetAngle(fx,fy); // 0..2Pi float c = std::max(0.f, std::min(1.f, fQ * powf(fabs(d / (-1.f+nof + cosf(PiN) / cosf( fmodf(k, 2*PiN) - PiN ) )),fP) )); uint8 bR = c * fR, bG = c * fG, bB = c * fB; *p++ = bR; *p++ = bG; *p++ = bB; *p++ = bG > 32 ? 255 : 0; } break; case BRS_Triangle: for (size_t y = 0; y < BrPrvSize; ++y) for (size_t x = 0; x < BrPrvSize; ++x) { float fx = ((float)x - s)*s1, fy = ((float)y - s)*s1; // -1..1 float d = std::max(0.f, 1.f - float(sqrt(fx*fx + fy*fy))); // 0..1 float c = powf( abs(d), fP); uint8 bR = c * fR, bG = c * fG, bB = c * fB; *p++ = bR; *p++ = bG; *p++ = bB; *p++ = bG > 32 ? 255 : 0; } break; } pbuf->unlock(); }
void FlashControl::update() { if(isClean) return; int dirtyWidth = dirtyBounds.right - dirtyBounds.left; int dirtyHeight = dirtyBounds.bottom - dirtyBounds.top; int dirtyBufSize = dirtyWidth * dirtyHeight * 4; static int lastDirtyWidth = 0; static int lastDirtyHeight = 0; IViewObject* curView = 0; flashInterface->QueryInterface(IID_IViewObject, (void**)&curView); if(!oleObject || !curView) return; if(!mainContext || dirtyWidth != lastDirtyWidth || dirtyHeight != lastDirtyHeight) { if(mainContext) { DeleteDC(mainContext); mainContext = 0; } if(mainBitmap) { DeleteObject(mainBitmap); mainBitmap = 0; } lastDirtyWidth = dirtyWidth; lastDirtyHeight = dirtyHeight; HDC hdc = GetDC(0); BITMAPINFOHEADER bih = {0}; bih.biSize = sizeof(BITMAPINFOHEADER); bih.biBitCount = 32; bih.biCompression = BI_RGB; bih.biPlanes = 1; bih.biWidth = dirtyWidth; bih.biHeight = -dirtyHeight; mainContext = CreateCompatibleDC(hdc); mainBitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void**)&mainBuffer, 0, 0); SelectObject(mainContext, mainBitmap); if(usingAlphaHack) { if(altContext) { DeleteDC(altContext); altContext = 0; } if(altBitmap) { DeleteObject(altBitmap); altBitmap = 0; } altContext = CreateCompatibleDC(hdc); altBitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void **)&altBuffer, 0, 0); SelectObject(altContext, altBitmap); } ReleaseDC(0, hdc); } RECT local; local.left = -dirtyBounds.left; local.top = -dirtyBounds.top; local.right = local.left + dirtyBounds.right; local.bottom = local.top + dirtyBounds.bottom; if(!usingAlphaHack) { memset(mainBuffer, 0, dirtyBufSize); HRESULT hr = OleDraw(curView, DVASPECT_TRANSPARENT, mainContext, &local); } else { memset(mainBuffer, 0, dirtyBufSize); memset(altBuffer, 255, dirtyBufSize); OleDraw(curView, DVASPECT_TRANSPARENT, mainContext, &local); OleDraw(curView, DVASPECT_TRANSPARENT, altContext, &local); // We've rendered the dirty area twice: once on black and once // on white. Now we compare the red channels of each to determine // the alpha value of each pixel. BYTE *blackBuffer, *whiteBuffer; blackBuffer = mainBuffer; whiteBuffer = altBuffer; BYTE blackRed, whiteRed; int size = dirtyWidth * dirtyHeight; for(int i = 0; i < size; i++) { blackRed = *blackBuffer; whiteRed = *whiteBuffer; blackBuffer += 3; whiteBuffer += 4; *blackBuffer++ = 255 - (whiteRed - blackRed); } } renderBuffer->copyArea(dirtyBounds, mainBuffer, dirtyWidth * 4); HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer(); pixelBuffer->lock(HardwareBuffer::HBL_DISCARD); const PixelBox& pixelBox = pixelBuffer->getCurrentLock(); uint8* destBuffer = static_cast<uint8*>(pixelBox.data); renderBuffer->blitBGR(destBuffer, (int)texPitch, (int)texDepth); pixelBuffer->unlock(); isClean = true; isTotallyDirty = false; }