//----------------------------------------------------------------------------- void HardwarePixelBuffer::blit(const HardwarePixelBufferSharedPtr &src) { blit(src, Box(0,0,0,src->getWidth(),src->getHeight(),src->getDepth()), Box(0,0,0,mWidth,mHeight,mDepth) ); }
void Sample_VolumeTex::generate() { /* Evaluate julia fractal for each point */ Julia julia(global_real, global_imag, global_theta); const float scale = 2.5; const float vcut = 29.0f; const float vscale = 1.0f/vcut; HardwarePixelBufferSharedPtr buffer = ptex->getBuffer(0, 0); Ogre::StringStream d; d << "HardwarePixelBuffer " << buffer->getWidth() << " " << buffer->getHeight() << " " << buffer->getDepth(); LogManager::getSingleton().logMessage(d.str()); buffer->lock(HardwareBuffer::HBL_NORMAL); const PixelBox &pb = buffer->getCurrentLock(); d.str(""); d << "PixelBox " << pb.getWidth() << " " << pb.getHeight() << " " << pb.getDepth() << " " << pb.rowPitch << " " << pb.slicePitch << " " << pb.data << " " << PixelUtil::getFormatName(pb.format); LogManager::getSingleton().logMessage(d.str()); Ogre::uint32 *pbptr = static_cast<Ogre::uint32*>(pb.data); for(size_t z=pb.front; z<pb.back; z++) { for(size_t y=pb.top; y<pb.bottom; y++) { for(size_t x=pb.left; x<pb.right; x++) { if(z==pb.front || z==(pb.back-1) || y==pb.top|| y==(pb.bottom-1) || x==pb.left || x==(pb.right-1)) { // On border, must be zero pbptr[x] = 0; } else { float val = julia.eval(((float)x/pb.getWidth()-0.5f) * scale, ((float)y/pb.getHeight()-0.5f) * scale, ((float)z/pb.getDepth()-0.5f) * scale); if(val > vcut) val = vcut; PixelUtil::packColour((float)x/pb.getWidth(), (float)y/pb.getHeight(), (float)z/pb.getDepth(), (1.0f-(val*vscale))*0.7f, PF_A8R8G8B8, &pbptr[x]); } } pbptr += pb.rowPitch; } pbptr += pb.getSliceSkip(); } buffer->unlock(); }
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; }
//-------------------------------------------------------------------------- void Texture::_loadImages( const ConstImagePtrList& images ) { if(images.size() < 1) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot load empty vector of images", "Texture::loadImages"); // Set desired texture size and properties from images[0] mSrcWidth = mWidth = images[0]->getWidth(); mSrcHeight = mHeight = images[0]->getHeight(); mSrcDepth = mDepth = images[0]->getDepth(); // Get source image format and adjust if required mSrcFormat = images[0]->getFormat(); if (mTreatLuminanceAsAlpha && mSrcFormat == PF_L8) { mSrcFormat = PF_A8; } if (mDesiredFormat != PF_UNKNOWN) { // If have desired format, use it mFormat = mDesiredFormat; } else { // Get the format according with desired bit depth mFormat = PixelUtil::getFormatForBitDepths(mSrcFormat, mDesiredIntegerBitDepth, mDesiredFloatBitDepth); } // The custom mipmaps in the image have priority over everything size_t imageMips = images[0]->getNumMipmaps(); if(imageMips > 0) { mNumMipmaps = mNumRequestedMipmaps = images[0]->getNumMipmaps(); // Disable flag for auto mip generation mUsage &= ~TU_AUTOMIPMAP; } // Create the texture createInternalResources(); // Check if we're loading one image with multiple faces // or a vector of images representing the faces size_t faces; bool multiImage; // Load from multiple images? if(images.size() > 1) { faces = images.size(); multiImage = true; } else { faces = images[0]->getNumFaces(); multiImage = false; } // Check wether number of faces in images exceeds number of faces // in this texture. If so, clamp it. if(faces > getNumFaces()) faces = getNumFaces(); if (TextureManager::getSingleton().getVerbose()) { // Say what we're doing StringUtil::StrStreamType str; str << "Texture: " << mName << ": Loading " << faces << " faces" << "(" << PixelUtil::getFormatName(images[0]->getFormat()) << "," << images[0]->getWidth() << "x" << images[0]->getHeight() << "x" << images[0]->getDepth() << ") with "; if (!(mMipmapsHardwareGenerated && mNumMipmaps == 0)) str << mNumMipmaps; if(mUsage & TU_AUTOMIPMAP) { if (mMipmapsHardwareGenerated) str << " hardware"; str << " generated mipmaps"; } else { str << " custom mipmaps"; } if(multiImage) str << " from multiple Images."; else str << " from Image."; // Scoped { // Print data about first destination surface HardwarePixelBufferSharedPtr buf = getBuffer(0, 0); str << " Internal format is " << PixelUtil::getFormatName(buf->getFormat()) << "," << buf->getWidth() << "x" << buf->getHeight() << "x" << buf->getDepth() << "."; } LogManager::getSingleton().logMessage( LML_NORMAL, str.str()); } // Main loading loop // imageMips == 0 if the image has no custom mipmaps, otherwise contains the number of custom mips for(size_t mip = 0; mip<=imageMips; ++mip) { for(size_t i = 0; i < faces; ++i) { PixelBox src; if(multiImage) { // Load from multiple images src = images[i]->getPixelBox(0, mip); } else { // Load from faces of images[0] src = images[0]->getPixelBox(i, mip); } // Sets to treated format in case is difference src.format = mSrcFormat; if(mGamma != 1.0f) { // Apply gamma correction // Do not overwrite original image but do gamma correction in temporary buffer MemoryDataStreamPtr buf; // for scoped deletion of conversion buffer buf.bind(OGRE_NEW MemoryDataStream( PixelUtil::getMemorySize( src.getWidth(), src.getHeight(), src.getDepth(), src.format))); PixelBox corrected = PixelBox(src.getWidth(), src.getHeight(), src.getDepth(), src.format, buf->getPtr()); PixelUtil::bulkPixelConversion(src, corrected); Image::applyGamma(static_cast<uint8*>(corrected.data), mGamma, corrected.getConsecutiveSize(), static_cast<uchar>(PixelUtil::getNumElemBits(src.format))); // Destination: entire texture. blitFromMemory does the scaling to // a power of two for us when needed getBuffer(i, mip)->blitFromMemory(corrected); } else { // Destination: entire texture. blitFromMemory does the scaling to // a power of two for us when needed getBuffer(i, mip)->blitFromMemory(src); } } } // Update size (the final size, not including temp space) mSize = getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat); }
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; }