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 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() != (const char*)(void*)pData - (const char*)pStartPos) { throw "memory overrun"; } pBuf->unlock(); }
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; }