Example #1
0
	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;
}