Ogre源码分析与学习笔记-3 材质

第五节 利用Ogre 2.3实现雨,雪,爆炸,飞机喷气尾焰等粒子效果 先展示下官网给的12个粒子效果,具体代码放到最后。烟花效果,粒子,材质官方没有给出,自己尝试模仿写了一个,添加到文件中。2. 向上漂浮的绿色颗粒,粒子。材质自己为自己添加。3. 闪闪发光的紫色喷泉。粒子。材质为官方自带。4. 雨,粒子。材质自己实现。材质Particles.material:5. 飞机喷气尾焰,粒子。粒子和材质代码详见官方示例。6. 飞机喷气尾焰2,粒子。粒子和材质代码详见官方示例。7. 向上漂浮的光环,类似龙卷风。粒子。粒子和材质代码详见官方示例。 阅读详情

首先是Material::TextureLayer, 这是Material的一个内嵌类, 定义了一个纹理

class _OgreExport TextureLayer
{
	//Ogre支持多种纹理效果, 包括:ET_BUMP_MAP, ET_ENVIRONMENT_MAP, ET_SCROLL, ET_ROTATE, ET_TRANSFORM
	EffectMap mEffects;
	
	//Ogre 支持纹理动画, 就是在模型不变的前提下, 更换纹理, 产生一个平面动画的效果, 下面几个参数是关于平面动画的:
	/// Number of frames of animation, or frames making up cubic
	//帧数
	int mNumFrames;        
	/// The xurrent animation frame.
	//当前帧数, 动画演示时使用
	int mCurrentFrame;
	/// Duration of animation in seconds
	//每帧间隔
	Real mAnimDuration;            
	//Controller是一个通用类, 用来计算每一帧会变化的量.
	//Controller可以做时间插值, 位置插值, 像素插值等等
	//在这里用mAnimController计算动画时间, 插值出当前的动画是第几帧
	Controller* mAnimController;
	
	//Ogre支持Cube texture
	//Cube texture是一个组合纹理, 它使用6张图片来对应一个立方体的六个面
	//通过视线和法线计算出的反射光线来查询CubeMap, 可以创建一个真实的反射镜面体
	//通过视线和法线计算出的折射光线来查询CubeMap, 可以创建一个透明体.
	//Cube texture可以用来绘制天空盒(skyboxes), 或用来模拟反射效果
	bool mCubic;

	//纹理单元?
	int textureCoordSetIndex;
	//纹理模式, 对应于OpenGL的GL_REPEAT, GL_MIRRORED_REPEAT, GL_CLAMP
	TextureAddressingMode mAddressMode;                

	//blend, 用来控制本层纹理和上一层纹理的混合方式
	LayerBlendModeEx colourBlendMode;
	SceneBlendFactor colourBlendFallbackSrc;
	SceneBlendFactor colourBlendFallbackDest;
	LayerBlendModeEx alphaBlendMode;
	
	//判断当前纹理是不是一个空纹理, 一般发生在load图片失败, 或者其他一些非致命错误后
	bool mIsBlank;
	
	//定义纹理是立即被load, 还是以后被load
	bool mDeferLoad;

	//是否计算纹理矩阵
	//可以动态改变纹理矩阵, 从而改变纹理坐标, 使用这种方法可以制作一些特殊效果, 比如滚动的纹理等等.
	//纹理矩阵可以直接设置, 也可以通过一些纹理变换函数改变, 比如setTextureScale(), setTextureRotate()等
	bool mRecalcTexMatrix;
	Real mUMod, mVMod;
	Real mUScale, mVScale;
	Real mRotate;
	Matrix4 mTexModMatrix;
	
	//alpha 测试函数, 详情见OpenGL的alpha测试
	CompareFunction mAlphaRejectFunc;
	unsigned char mAlphaRejectVal;

	// Animation, will be set up as Controllers
	//animation使用, 被Controllers自动设置
	Real mUScrollAnim, mVScrollAnim;
	Real mRotateAnim;

	/// Texture layer filtering
	//纹理滤波方式
	TextureFilterOptions mTextureLayerFiltering;

	//Texture layer anisotropy
	//各向异性
	int mMaxAniso;
};


然后是纹理本身

class Material
{
	// Colour properties
	//纹理的颜色属性, 环境光, 散射光, 镜面光等等
	ColourValue mAmbient;
	ColourValue mDiffuse;
	ColourValue mSpecular;    
	ColourValue mEmissive;
	Real mShininess;
	//-------------------------------------------------------------------------

	/// Default material settings - set up by SceneManager
	static Material* mDefaultSettings;

	//-------------------------------------------------------------------------
	// Blending factors
	//混合因子, 用于多个纹理的混合
	SceneBlendFactor mSourceBlendFactor;    
	SceneBlendFactor mDestBlendFactor;
	//-------------------------------------------------------------------------
	
	//-------------------------------------------------------------------------    
	// Depth buffer settings
	//深度缓冲控制
	bool mDepthCheck;
	bool mDepthWrite;
	CompareFunction mDepthFunc;
	ushort mDepthBias;

	//-------------------------------------------------------------------------    

	//-------------------------------------------------------------------------
	// Culling mode
	//裁切控制
	CullingMode mCullMode;
	ManualCullingMode mManualCullMode;
	//-------------------------------------------------------------------------

	/// Lighting enabled?
	//光照控制
	bool mLightingEnabled;

	/// Shading options
	//对应GL_SMOOTH, GL_FLAT
	ShadeOptions mShadeOptions;

	/// Texture filtering
	//纹理过滤方式, Ogre支持双线过滤, 三线过滤, 以及各向异性过滤
	TextureFilterOptions mTextureFiltering;

	// texture anisotropy level
	int mMaxAniso;

	//-------------------------------------------------------------------------    
	// Fog
	bool mFogOverride;
	FogMode mFogMode;
	ColourValue mFogColour;
	Real mFogStart;
	Real mFogEnd;
	Real mFogDensity;
	//-------------------------------------------------------------------------    


	/** If true, loading of textures and setting up controllers is deferred 
		until the 'load' method is called.
	*/
	bool mDeferLoad;

	/// Number of texture layers
	int mNumTextureLayers;
};


然后是纹理的使用

//纹理的使用通过SceneManager::setMaterial来做, 主要是使用Material的各种属性来设置RenderSystem的状态
//一般来说, RenderSystem状态的切换的效率都不高, 因此, 要做到尽量少的切换状态
//并且进行分组排序, 使用同样状态的Material一块使用
int SceneManager::setMaterial(Material* mat, int numLayersLeft)
{
	static bool firstTime = true;
	static bool lastUsedFallback = false;
	static int lastNumTexUnitsUsed = 0;
	static Material lastMat; // Last material settings, to minimise render state changes

	// Recent changes: eliminated the need to copy all material settings to set with RenderSystem
	// Now only issues required render state changes to the render system for maximum performance

	// Set surface properties
	// 为了提高效率, 如果当前设置的纹理和前一个纹理的颜色一样, 就不做任何改变
	if (firstTime || mat->_compareSurfaceParams(lastMat) == false)
	{
	   ColourValue a, b, c, d;
	   a = mat->getAmbient();
	   b = mat->getDiffuse();
	   c = mat->getSpecular();
	   d = mat->getSelfIllumination();
		mDestRenderSystem->_setSurfaceParams( a, b, c, d, mat->getShininess() );
	}

	// Set global blending, play it safe if last one was fallback
	//设置混合方式, 网上资料一大堆
	if (firstTime || lastUsedFallback ||
	(lastMat.getSourceBlendFactor() != mat->getSourceBlendFactor() ||
	 lastMat.getDestBlendFactor() != mat->getDestBlendFactor()))
	{
		mDestRenderSystem->_setSceneBlending(mat->getSourceBlendFactor(), mat->getDestBlendFactor());
	}

	//雾设置
	// Fog
	// New fog params can either be from scene or from material
	FogMode newFogMode;
	ColourValue newFogColour;
	Real newFogStart, newFogEnd, newFogDensity;
	static FogMode oldFogMode;
	static ColourValue oldFogColour;
	static Real oldFogStart, oldFogEnd, oldFogDensity;
	if (mat->getFogOverride())
	{
		// New fog params from material
		newFogMode = mat->getFogMode();
		newFogColour = mat->getFogColour();
		newFogStart = mat->getFogStart();
		newFogEnd = mat->getFogEnd();
		newFogDensity = mat->getFogDensity();
	}
	else
	{
		// New fog params from scene
		newFogMode = mFogMode;
		newFogColour = mFogColour;
		newFogStart = mFogStart;
		newFogEnd = mFogEnd;
		newFogDensity = mFogDensity;
	}
	if (firstTime || newFogMode != oldFogMode || newFogColour != oldFogColour ||
		newFogStart != oldFogStart || newFogEnd != oldFogEnd ||
		newFogDensity != oldFogDensity)
	{
		mDestRenderSystem->_setFog(newFogMode, newFogColour, newFogDensity, newFogStart, newFogEnd);
		oldFogMode = newFogMode;
		oldFogColour = newFogColour;
		oldFogStart = newFogStart;
		oldFogEnd = newFogEnd;
		oldFogDensity = newFogDensity;
	}


	//纹理, Ogre支持多重纹理, 以及纹理混合
	// 这里, 主要使用RenderSystem::_setTextureUnitSettings()来设置纹理, 包括:
	// 1. 绑定纹理: _setTexture ->glBindTexture
	// 2. 设置纹理坐标: _setTextureCoordSet()
	// 3. 设置纹理滤波: _setTextureLayerFiltering()
	// 4. 设置各向异性: _setTextureLayerAnisotropy()
	// 5. 多重纹理的混合: _setTextureBlendMode()
	// 6. 纹理效果
	// ...	
	// Texture layers
	int texLayer = mat->getNumTextureLayers() - numLayersLeft;
	int thisUnitsRequested = numLayersLeft;
	int texUnits = mDestRenderSystem->_getNumTextureUnits();

#if OGRE_TEST_MULTIPASS == 1
	texUnits = 1;
#endif

	// Iterate over texture units, set them up to the higher of the last texturing units used and the current to be used
	//   but no higher than the number of units
	lastUsedFallback = false;
   int unit;
	for (unit = 0;
		(unit < lastNumTexUnitsUsed || unit < thisUnitsRequested) && unit < texUnits;
		++unit, ++texLayer)
	{
		if (unit >= thisUnitsRequested)
		{
			// We've run out of texture layers before we ran out of units to set
			// Turn off the texturing for this unit
			mDestRenderSystem->_disableTextureUnit(unit);
		}
		else
		{
			Material::TextureLayer* pTex = mat->getTextureLayer(texLayer);
			// We still have texture layers to put in this unit
			if (unit == 0 && thisUnitsRequested > 0 && thisUnitsRequested < mat->getNumTextureLayers())
			{
				// We're on the second (or more) leg of a multipass render
				//  because remaining layers is not the total number

				// So we need to use the multipass fallback and override first texture layer blend
				lastUsedFallback = true;

				// Copy texture layer info and set custom blending
				Material::TextureLayer newTex = *pTex;

				// Set multitexture blend to NO blend (avoids any modulation with material colour)
				newTex.setColourOperation(LBO_REPLACE);
				// Set scene blending to colour blending equivalent (fallback)
				mDestRenderSystem->_setSceneBlending(pTex->getColourBlendFallbackSrc(), pTex->getColourBlendFallbackDest());

				// Set texture unit settings
				// NB rendersystem will know to only change relevant settings
				mDestRenderSystem->_setTextureUnitSettings(unit, newTex);
			}
			else
			{
				if (lastUsedFallback)
				{
					// Ensure that fallback alpha on bottom layer does not mask out alpha on this layer
					pTex->setAlphaOperation(LBX_ADD);
				}

				// Standard issue
				mDestRenderSystem->_setTextureUnitSettings(unit, *pTex);
			}

			numLayersLeft--;
		}
	}

	// 设置一些跟纹理无关的纹理参数
	// 从这里可以看出Ogre的Material不光包括通常意义上的材质参数
	// 也包括一些可以作用在材质上, 或者改变材质属性的参数
	// 因此从某种意义上说, Ogre的Material更类似于一个"Shader"
	// Set up non-texture related material settings
	// Depth buffer settings
	if (firstTime || lastMat.getDepthFunction() != mat->getDepthFunction())
	{
		mDestRenderSystem->_setDepthBufferFunction(mat->getDepthFunction());
	}
	if (firstTime || lastMat.getDepthCheckEnabled() != mat->getDepthCheckEnabled())
	{
		mDestRenderSystem->_setDepthBufferCheckEnabled(mat->getDepthCheckEnabled());
	}
	if (firstTime || lastMat.getDepthWriteEnabled() != mat->getDepthWriteEnabled())
	{
		mDestRenderSystem->_setDepthBufferWriteEnabled(mat->getDepthWriteEnabled());
	}
	if (firstTime || lastMat.getDepthBias() != mat->getDepthBias())
	{
		mDestRenderSystem->_setDepthBias(mat->getDepthBias());
	}


	// Culling mode
	if (firstTime || lastMat.getCullingMode() != mat->getCullingMode())
	{
		mDestRenderSystem->_setCullingMode(mat->getCullingMode());

	}
	// Dynamic lighting enabled
	if (firstTime || lastMat.getLightingEnabled() != mat->getLightingEnabled())
	{
		mDestRenderSystem->setLightingEnabled(mat->getLightingEnabled());
	}
	// Shading
	if (firstTime || lastMat.getShadingMode() != mat->getShadingMode())
	{
		mDestRenderSystem->setShadingType(mat->getShadingMode());
	}
	// Texture filtering
	if (firstTime || lastMat.getTextureFiltering() != mat->getTextureFiltering())
	{
		mDestRenderSystem->setTextureFiltering(mat->getTextureFiltering());
	}
	// anisotropy
	if (firstTime || lastMat.getAnisotropy() != mat->getAnisotropy())
	{
		mDestRenderSystem->_setAnisotropy(mat->getAnisotropy());
	}


	firstTime = false;
	// Copy material settings from last render
	lastMat = *mat;
	lastNumTexUnitsUsed = unit;
	return numLayersLeft;
}


另外还有两部分跟材质相关的内容:
材质的Load以及材质脚本
不在本篇涉及范围内

ogre-next 学习笔记 - Day 4 阅读详情

相关推荐

关于 OGRE OSG 的简单比较

关于 OGRE OSG 的简单比较

ytffhew的博客 529

OGRE 学习之路(二) Cube Mapping

分类:Unsorted(未分类的) 描述:Demonstrates the cube mapping feature where a warp-around environment is reflected off of an object.Uses render-to-texture to create dynamic cubemaps. 简单来说这是一个立方体贴图的demo,并且所用的纹理...

小玩家的博客 301

Ogre学习记录

  1: 设计初衷它设计初衷是完全跨平台的。抽象的接口隐藏了平台相关的细节。它设计初衷是大幅度支持扩展的。支持多种场景类型,独立出平台和3D接口限制。2: 基本类结构关系Roo:对象为一切的入口,它负责创建Ogre的所有基础元素,三大基础元素大致包括:场景管理器,绘制系统,资源管理器。场景管理器:场景节点,动态对象。资源管理器:资源组管理,资源管理渲染模块:硬件缓冲

英雄王之路 4977

纹理阴影实现笔记

ogre纹理阴影实现的三种方法 ogre包含两种阴影实现技术,阴影体阴影纹理. 阴影体需要主cpu计算出物体的轮廓,同时生成更多的多边形,会降低帧率 并且在骨骼蒙皮时,会存在问题(如果采用硬蒙皮,无法计算轮廓,软蒙皮则降低帧率) 阴影体只需要将几何体按不同的视角绘制(往显卡数据传输量增加),对帧率影响较小. 阴影体实现的原理. 假设场影中有一个点光源,

飞天大蟾蜍的专栏 2728

文档:手册:1-4-0:3.1.3 纹理单元

<br />From OGRE 3D 中文<br />3.1.3 纹理单元<br />以下是你可以在.material脚本的'texture_unit'部分使用的属性: <br />可用的纹理层属性 <br />texture_alias <br />texture <br />anim_texture <br />cubic_texture <br />tex_coord_set <br />tex_address_mode <br />tex_border_colour <br />filtering

xiaosu123的专栏 1062

关于OGREOSG的简单比较

关于OGREOSG的简单比较 林乃养 lnychina{at}gmail.com 浙江大学CAD&CG实验室 2010年3月27日 1 前言 我曾经细致阅读过OGRE和OSG官方提供的文档,有《Pro OGRE 3D Programming》、OGRE自带手册(manual)、王锐老师等翻译的《OpenSceneGraph Quick Guide》,同时在网络上查阅了大量的OGRE架构

hualitlc的专栏 1724

Ogre源码分析学习笔记-2 纹理

Ogre纹理的继承关系:   Resource -> Texture -> GLTexture   1. Resource , 顾名思义就是资源, 包括纹理, 材质, 三角形网格等. Resource由ResourceManager管理, 几个核心函数: cla

桦树的眼睛 941

转:关于 OGRE OSG 的简单比较

1 前言 我曾经细致阅读过 OGRE 和 OSG 官方提供的文档,有《Pro OGRE 3D Programming》、OGRE自带手册(manual)、王锐老师等翻译的《OpenSceneGraph Quick Guide》,同时在网络上查阅了大量的 OGRE 架构源码分析的文章。简单使用过 OSG,对 OSG 的场景管理器设计和编程风格有所了解,而在近期的项目中大量使用 ...

aolan7349的博客 329

实现Ogre的脚本分离 - 天龙八部的源码分析(一)

实现Ogre的脚本分离

夏冰 4440

ogre--hlsl--矩阵

重要注释——矩阵的顺序:有一件事需要牢记,HLSL允许你使用2种不同方式处理矩阵和向量相乘——mul(v,m)或者mul(m,v)。二者之间唯一的区别就是矩阵被有效地变换。在OGRE中传递矩阵你应该使用mul(m,v)——因为这渲染器从像RenderMonkey一样的工具中生成的结果保持一致,并且也和Cg一致,但是使用mul(v,m)的Dx9 SDK和FX合成器不一致——在使用那些渲染器时,你...

weixin_33725126的博客 212

Ogre材质过滤技术

材质过滤知识:http://baike.baidu.com/view/49989.htm简介当材质被贴到屏幕所显示的一个3D模型上时,材质处理器必须决定哪个图素要贴在哪个像素的位置。 由于材质是2D图片,而模型是3D物件,所以通常图素的范围像素范围不会是恰好相同的。此时要解决这个像素的贴图问题,就得用插补处理的方式来解决。而 这种处理的方式共分三种:“近邻取样”、“双线过滤”、“三线过滤

痞子龙3D编程 1472

OGRE关于Demo_CubeMapping 的学习

<br />目的: 显示 立方体映射的特色(cube mapping), 还可以设置物体镜面映射出周围的景色<br />主要有两个类 CubeMapApplication 和 CubeMapListener<br /><br />* 该例中对象的周围景象反射是通过设置对象的主材质material实现的, 在脚本中设置了env_map cubic_reflect和cubic_texture属性<br />    该对象的子mesh则是复制原始mesh中的子mesh, 材质也是复制其子mesh的材质<br />

痞子龙3D编程 2366

光照设置

osg::ref_ptr light = new osg::Light; osg::Vec4 vec1(255 / 255.0f, 248 / 255.0f, 220 / 255.0f, 1.0f); osg::Vec4 vec2(156 / 255.0f, 156 / 255.0f, 156 / 255.0f, 1.0f); light->setDiffuse(vec2); light-

月下男孩的专栏 526

OGRE scene_blend

这种融合方式用于场景中当前通道。textureunit中的纹理融合运算是用于纹理层的融合,而这个融合是把这个通道的输出作为一个整体链接到渲染目标的当前内容。因此,这种融合支持物体透明度的设置和其他一些特性。它有两种定义形式,一种用于预定义融合类型,一种支持手动调节源和目标的要素。形式1: scene_blend 例子:  scene_blend add下面以简单形式列举常用的融合参数:add           渲染输出的颜色加到场景中。相当于scene_blend one onemodulate     

痞子龙3D编程 3079

Ogre动态纹理(转)

转载自: http://blog.csdn.net/programrookie/article/details/4552447 Ogre动态纹理(转) 原创 2009年09月14日 19:45:00 标签:脚本 3644   Ogre动态纹理(2007-01-18 13:48:40)   分类:Ogre

lynon的专栏 631
上一篇: Ogre源码分析与学习笔记-2 纹理
lastars
博客等级 码龄19年 4粉丝 4原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值