OGRESE 混合纹理的源码 外加注释

来源:互联网 发布:abaqus混凝土本构数据 编辑:程序博客网 时间:2024/05/01 10:47
#pragma once  //混合纹理#include "OgreResource.h"#include "OgreTexture.h"namespace OgreSE{/** Interface describing a manual resource loader.@remarksResources are usually loaded from files; however in some cases youwant to be able to set the data up manually instead. This providessome problems, such as how to reload a Resource if it becomesunloaded for some reason, either because of memory constraints, orbecause a device fails and some or all of the data is lost.@parThis interface should be implemented by all classes which wish toprovide manual data to a resource. They provide a pointer to themselveswhen defining the resource (via the appropriate ResourceManager), and will be called when the Resource tries to load. They should implement the loadResource method such that the Resource is in the end set up exactly as if it had loaded from a file, although the implementations will likely differbetween subclasses of Resource, which is why no generic algorithm can be stated here. @noteThe loader must remain valid for the entire life of the resource,so that if need be it can be called upon to re-load the resourceat any time.*/class CoverageMap : public Ogre::ManualResourceLoader{public:public://混合纹理贴图的构造函数 name:混合纹理贴图名字,group 纹理资源所在的组 width height 纹理宽和高 channels纹理的通道数目 black=true 则第一个通道被填充为255CoverageMap(const std::string& name, const std::string& group, UINT width, UINT height, int channels, bool black = true);// black为false则第一个通道被填充为255~CoverageMap();////////////////////////////////////////////////////////////////// 功能:从图片中加载,图片的通道数不能大于纹理的////////////////////////////////////////////////////////////////void LoadFromImage(const Ogre::Image& image);////////////////////////////////////////////////////////////////// 功能:保存到图片,图片的通道数不应大于纹理的////////////////////////////////////////////////////////////////void SaveToImage(Ogre::Image& image);////////////////////////////////////////////////////////////////// 功能:得到索引xy处通道c的数值////////////////////////////////////////////////////////////////inline unsigned char GetValue(UINT x, UINT y, UINT c) const;////////////////////////////////////////////////////////////////// 功能:设置索引xy处通道c的数值////////////////////////////////////////////////////////////////void SetValue(UINT x, UINT y, UINT c, unsigned char val);////////////////////////////////////////////////////////////////// 功能:把内存中的编辑缓存更新到纹理像素缓存中////////////////////////////////////////////////////////////////void UpdateTexture();////////////////////////////////////////////////////////////////// 功能:重载 ManualResourceLoader,用于实现reload 纹理////////////////////////////////////////////////////////////////void loadResource(Ogre::Resource*);////////////////////////////////////////////////////////////////// 功能:覆盖图纹理的名字////////////////////////////////////////////////////////////////const std::string& GetName() const;////////////////////////////////////////////////////////////////// 功能:得到通道的数量////////////////////////////////////////////////////////////////UINT GetChannelCount(){return m_nChannelCount;};////////////////////////////////////////////////////////////////// 功能:某通道是否是空白,也就是全黑////////////////////////////////////////////////////////////////bool IsBlank(UINT c);void SetBlank(UINT c);// 只是设置空白标记不用真清空////////////////////////////////////////////////////////////////// 功能:从流中加载索引图缓存数据////////////////////////////////////////////////////////////////void Load(Ogre::DataStreamPtr& stream);void Save(std::ofstream& stream);private:////////////////////////////////////////////////////////////////// 功能:根据通道数得到纹理格式 / 根据纹理格式得到通道数////////////////////////////////////////////////////////////////Ogre::PixelFormat GetFormat(int channels);//根据通道数得到纹理格式int GetChannels(Ogre::PixelFormat format); //根据纹理格式得到通道数UINTm_nWidth, m_nHeight;// 长,宽,缓存大小(m_nWidth*m_nHeight*m_nChannelCount)intm_nChannelCount;// 通道数unsigned char*m_pData;// 编辑缓存Ogre::TexturePtrm_Texture;// 索引图纹理std::vector<bool>m_BlankFlag;// 设置通道为空白标记(为了合并重复纹理时不用真的清空通道)};}#include "StdAfx.h"#include "SECoverageMap.h"#include "OgreTextureManager.h"#include "OgreHardwarePixelBuffer.h"namespace OgreSE{//// black为false则第一个通道被填充为255CoverageMap::CoverageMap(const std::string& name, const std::string& group, UINT width, UINT height,int channels, bool black): m_nWidth(width), m_nHeight(height), m_nChannelCount(channels)//m_nWidth长,m_nHeight宽,缓存大小((m_nWidth*m_nHeight*m_nChannelCount)){UINT nSize = width*height*channels; //混合纹理的大小m_pData = new unsigned char[nSize];//编辑缓存memset(m_pData, 0, nSize);// 第一个索引图的第一个通道设为255,这样地形被第一个纹理完全填充if (!black)for (size_t i = 0; i < nSize; i += m_nChannelCount)m_pData[i] = 255;// 手工创建一个混合纹理,名字是name if (Ogre::TextureManager::getSingletonPtr()->resourceExists(name)){Ogre::TextureManager::getSingletonPtr()->remove(name);}m_Texture = Ogre::TextureManager::getSingletonPtr()->createManual(name, group, Ogre::TEX_TYPE_2D,width, height, 1, 0, GetFormat(channels), Ogre::TU_DEFAULT, this);m_BlankFlag.assign(m_nChannelCount, false);}CoverageMap::~CoverageMap(){delete[] m_pData;}void CoverageMap::loadResource(Ogre::Resource*){// the texture has requested to (re)load, we just copy our edit buffer// into the texturem_Texture->createInternalResources();UpdateTexture();}//把内存中的编辑缓存m_pData更新到纹理像素缓存中void CoverageMap::UpdateTexture(){// 把编辑缓存写入纹理缓存  m_Texture 索引图纹理/** Return hardware pixel buffer for a surface. This buffer can thenbe used to copy data from and to a particular level of the texture.@param face Face number, in case of a cubemap texture. Must be 0for other types of textures.                            For cubemaps, this is one of                             +X (0), -X (1), +Y (2), -Y (3), +Z (4), -Z (5)@param mipmapMipmap level. This goes from 0 for the first, largestmipmap level to getNumMipmaps()-1 for the smallest.@returnsA shared pointer to a hardware pixel buffer@remarksThe buffer is invalidated when the resource is unloaded or destroyed.Do not use it after the lifetime of the containing texture.*/Ogre::HardwarePixelBufferSharedPtr buffer = m_Texture->getBuffer();//m_nWidth m_nHeight 长,宽,缓存大小/** A primitive describing a volume (3D), image (2D) or line (1D) of pixels in memory.     In case of a rectangle, depth must be 1.      Pixels are stored as a succession of "depth" slices, each containing "height" rows of      "width" pixels.    */Ogre::PixelBox pixelBox (m_nWidth, m_nHeight, 1, GetFormat(m_nChannelCount), m_pData);Ogre::Image::Box imageBox (0, 0, m_nWidth, m_nHeight);/** Copies a region from normal memory to a region of this pixelbuffer. The sourceimage can be in any pixel format supported by OGRE, and in any size.    @param srcPixelBox containing the source pixels and format in memory   @param dstBoxImage::Box describing the destination region in this buffer            @remarks The source and destination regions dimensions don't have to match, in which            case scaling is done. This scaling is generally done using a bilinear filter in hardware,            but it is faster to pass the source image in the right dimensions.@note Only call this function when the buffer is unlocked. */buffer->blitFromMemory(pixelBox, imageBox);}const std::string& CoverageMap::GetName() const{return m_Texture->getName();//获取混合纹理的名字}//得到混合纹理xy处的通道c的数值 unsigned char CoverageMap::GetValue(UINT x, UINT y, UINT c) const{return m_pData[(y*m_nWidth + x)*m_nChannelCount + c];}//设置混合纹理xy处的通道c的数值为valvoid CoverageMap::SetValue(UINT x, UINT y, UINT c, unsigned char val){m_pData[(y*m_nWidth + x)*m_nChannelCount + c] = val;}//根据通道数来得到混合纹理的格式Ogre::PixelFormat CoverageMap::GetFormat(int channels){switch (channels){case 1: return Ogre::PF_BYTE_A;case 2: return Ogre::PF_BYTE_LA;case 3: return Ogre::PF_BYTE_RGB;case 4: return Ogre::PF_BYTE_RGBA;case -1: return Ogre::PF_BYTE_A;case -2: return Ogre::PF_BYTE_LA;case -3: return Ogre::PF_BYTE_BGR;case -4: return Ogre::PF_BYTE_BGRA;default: return Ogre::PF_UNKNOWN;}}//根据纹理格式来得到通道数int CoverageMap::GetChannels(Ogre::PixelFormat format){switch (format){case Ogre::PF_BYTE_A: return 1;case Ogre::PF_BYTE_LA: return 2;case Ogre::PF_BYTE_RGB: return 3;case Ogre::PF_BYTE_BGR: return -3;case Ogre::PF_BYTE_RGBA: return 4;case Ogre::PF_BYTE_BGRA: return -4;default: return 0;}}//***************************************************************************************// 功能:某通道是否是空白,也就是全黑bool CoverageMap::IsBlank(UINT c){if (m_BlankFlag[c])return true;for(unsigned short m = 0; m < m_nHeight; ++m)for(unsigned short n = 0; n < m_nWidth; ++n)//遍历混合纹理的所有的单元的通道c,如果有某个通道数值!=0那么就返回falseif (GetValue(n,m,c) != 0)return false;return true;}void CoverageMap::SetBlank(UINT c){m_BlankFlag[c] = true;}void CoverageMap::Load(Ogre::DataStreamPtr& stream){stream->read((void*)m_pData, m_nWidth*m_nHeight*m_nChannelCount);UpdateTexture();}void CoverageMap::Save(std::ofstream& stream){stream.write((char*)m_pData, m_nWidth*m_nHeight*m_nChannelCount);}//从图片中加载,图片的通道数不能大于混合纹理的void CoverageMap::LoadFromImage(const Ogre::Image& image){ if (image.getWidth() != m_nWidth || image.getHeight() != m_nHeight)OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Given image doesn't conform(符合) to the used width and height.", "CoverageMap::LoadFromImage"); if (image.getFormat() != GetFormat(m_nChannelCount) && image.getFormat() != GetFormat(-m_nChannelCount)) OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "Given image is of invalid pixel format.", "CoverageMap::loadFromImage");  memcpy(m_pData, image.getData(), image.getSize());//为编辑缓存 m_pData填充数据//根据混合纹理的格式得到通道数 if (GetChannels(image.getFormat()) <= -3) {UINT nSize = m_nHeight * m_nWidth * m_nChannelCount; // need RGB(A), but given BGR(A) so invert  我们需要RGB(A)格式的 但是给的是BGR(A)所以我们需要调整位置 for (UINT i = 0; i < nSize; i += m_nChannelCount){unsigned char c = m_pData[i];m_pData[i] = m_pData[i+2];m_pData[i+2] = c;} } UpdateTexture();} void CoverageMap::SaveToImage(Ogre::Image& image){// This method loads an image into memory held in the object. The    //           pixel format will be either greyscale or RGB with an optional     //         Alpha component.//the type can be determined by calling getFormat().   image.loadDynamicImage(m_pData, m_nWidth, m_nHeight, 1, GetFormat(m_nChannelCount));}}

原创粉丝点击