游戏引擎设计 - 渲染(Crapell Game Engine Design - graphic)

 

自己写游戏引擎一渲染简介(make game engine by self - graphic) - twopointfive - twopointfive的博客

 

自己写游戏引擎一渲染简介(make game engine by self - graphic) - twopointfive - twopointfive的博客

 Crapell游戏引擎设计简介

 

 

       可以将整个或部分max场景导出到单一文件,也可导出到单独文件。包含关键帧动画、uv动画、粒子动画、骨骼动画、顶点动画导出插件。c++ opengl 、d3d9两种渲染方式。avi贴图,粒子特效(灵活的发射器和粒子形状,路径,模型附着,模型发射,碰撞板),lod及变形修改器。后期延迟渲染可以对ui和场景使用独立的渲染通道。shader选择了cg(实现了一些例子:水纹,特效扭曲, hdr,流体雾,体积光,shdowmap阴影,motion blur),可以方便扩充到和glsl和hlsl。

        uv动画建议使用uvXform修改器。骨骼动画可以用biped或基本骨骼。顶点动画可以直接修改或使用melt融化修改器等。新加入了布料动画,可以给布料刚性点设置关键帧或将其绑定到人物骨骼。

         MovieClip是一切模型的基类,派生出MC_Frame、MC_Partile、MC_Skeleton、MC_Vertex、MC_Light、MC_Camera、MC_Cloth、MC_Billboard、MC_Strip。分别负责关键帧动画、粒子动画、骨骼动画、顶点动画、灯光动画、视野动画、布料动画、公告板动画、尾光动画。

 

//========================================================
/**
*  Brief:   MovieClip RendCore 
*  Author:        LouLei
*  Email:  twopointfive@163.com
*
* Get what you see in 3dsmax.
* MovieClip tween morph:pos,scale,rot,alpha,material,skinbones.
* MovieClip self morph:texture,vertex.
* export patricle(super spray), light
* key mouse event:press click drag...
* Dynamic 3d mask: draw the point only if it is in the dumy_mask_mesh movieclip.
*                  implete like shadow volume stensil buf generation.
* Collide:collide with tray or tray box,this can be useful on movable zone.
*                  rts collide base on cells,fps collide base on mesh.Use tree space partion.
* Navigation graph:
* Refrence instance: use dumy for export dumplicate instance in max.
*                  refrence instance in c++,a ref mesh or ref movieclip.
* Reattach:texture,mesh,bone or keys.
*/ 
//========================================================
/*

#ifndef MovieClip_H
#define MovieClip_H
	
#include "Render/Texture.h"		
#include "Render/Particle.h"
#include <list>
#include <vector>
#include "General/ScriptMgr.h"
#include "General/ResPtr.h"
#include "General/Thread.h"
#include "General/String.h"

class MeshOcTree;
class MeshBspTree;
class VertexBuffer;
class IndexBuffer;
class CallBacks;
class Light;
class SoftObject;

namespace RendSys
{
	class Mesh;
	class MovieClip;
	class Skeleton;
	class FrameLine;
	typedef ResPtr<Mesh>      MeshPtr;
	typedef ResPtr<MovieClip> MovieClipPtr;
	typedef ResPtr<Skeleton>  SkeletonPtr;
	typedef ResPtr<FrameLine> FrameLinePtr;
	#define G_MeshMgr      (MeshMgr::GetSingleton())
	#define G_MovieClipMgr (MovieClipMgr::GetSingleton())
	#define G_SkeletonMgr  (SkeletonMgr::GetSingleton())

	struct RayMovieCollideRes:public RayCollideRes
	{
		RayMovieCollideRes(vec3& vStart_,vec3& vEnd_);
		RayMovieCollideRes();
		MovieClip* lastclip;
	};

	class CollideAABBox
	{
	public:
		CollideAABBox();
		virtual void CalBound(){}
		void Indentity();
		void Merge( const vec3& point );
		bool Intersect(vec3& v);
		bool TraceRay(vec3& vStart, vec3& vEnd,vec3& res);
		//vec3 TraceSphere(vec3& vStart, vec3& vEnd, float radius)
		//vec3 TraceBox(vec3& vStart, vec3& vEnd, vec3& vMin, vec3& vMax)
		void RendBox();
		//protected:
		vec3  m_min;
		vec3  m_max;
		vec3  m_center;
		float m_radius;
	};

	enum COORDSYS
	{
		COORD_NONE = 0,
		COORD_3DMAX,
		COORD_OGL,
		COORD_MAYA,
		COORD_D3D,
	};

#define	AccordantVertexUtil
#define	AccordantVertexUtil

	//construct fun of Vertex make new Vertex[] slow down
	//deconstruct fun make delete Vertex[] slow down
	//member fun has no effect
	class Mesh
	{
	public:
		struct Vertex
		{
			//Vertex();
			float x, y, z;
			//float u, v, w;
			float nx, ny, nz;
		};
		struct TVertex
		{	
			//TVertex();
			float u, v, w;
		};
		//struct NVertex
		//{	
		//	float nx, ny, nz;
		//};
		struct BoneWeight
		{
			//BoneWeight();
			int   boneId; 
			//String boneName;//canot memcpy Vertex,and load slow
			//char  boneName[];    //cost mem but exact than id
			float weight;
			float x, y, z;
			float nx, ny, nz;
		};
		struct VertexWeight
		{
			//VertexWeight();
			int    boneNum;
			//BoneWeight* boneWeight;//canot memcpy Vertex,and load slow need operator=
			std::vector<BoneWeight> boneWeight;//canot memcpy Vertex too
			//BoneWeight boneWeight[8]; //memory more?
			void Free();
		};
		struct Trigon
		{
			//Trigon();
			int vIndex[3];
		};
#ifdef	AccordantVertexUtil
		struct TrigonAccordant
		{
			//TrigonAccordant();
			int tIndex[3];
		};
#endif
		Mesh();
		virtual ~Mesh(){Free();}
		virtual void Free();
		void Render();
		void EditRender();
		void RenderOutline();
		bool LoadMesh(File& filein);
		bool SaveMesh(File& fileout);
		bool LoadSingleMovieMeshWeight(File& filein);
		bool SaveSingleMovieMeshWeight(File& fileout);
		void CoordConvert(COORDSYS totype);
		void LoadedProcess(bool genAABB,bool genBuff,bool accordant);
#ifdef	AccordantVertexUtil
		void AccordantVertex();
#endif
		/*virtual */void CalBound();
		bool TraceRay(RayCollideRes& res);
		void Expand(int vVertexNum,int tVertexNum,int trigonNum);
		//质心正方包围盒
		void GetMassCube(vec3& outCenter,vec3& outExtent);
		void GetBoundCube(vec3& outCenter,vec3& outExtent);
		void CreateBuff();
		void BuildTree();
		int m_trigonNum;
		int m_vVertexNum;
		int m_tVertexNum;

		Vertex*  m_vVertexs;
		TVertex* m_tVertexs;
		Trigon*  m_trigons;
#ifdef	AccordantVertexUtil
		TrigonAccordant*  m_accordantTrigons;
#endif
		VertexWeight* m_vertexWeights;
		VertexWeight (*m_debugVertexWeights)[5000];
		CollideAABBox m_collideAABBox;
		COORDSYS   m_coordSys;

		VertexBuffer*  m_verterBuffer;
		VertexBuffer*  m_tVerterBuffer0;
		VertexBuffer*  m_tVerterBuffer1;
		VertexBuffer*  m_tVerterBuffer2;
		VertexBuffer*  m_tVerterBuffer3;
		IndexBuffer*   m_indexBuffer;

		MeshOcTree*  m_octree;
		MeshBspTree* m_bsptree;
		bool m_genAABB;
		bool m_gpuAdvance;
	};


	class MixMesh:public Mesh
	{
	public:
		enum MeshCloneType
		{
			MCT_NULL = 0,
			MCT_VERTEX = 1,
			MCT_TRIGION = 1<<1,
		};
		MixMesh();
		~MixMesh();
		void CloneFrom(Mesh* mesh,MeshCloneType type = MCT_VERTEX);
		//const MixMesh& operator= (/*const*/ MixMesh& other);
		virtual void Free();
		bool TraceRay(vec3& vStart, vec3& vEnd,vec3& respos,vec3& resnorml);

		void MapVertexBuffer();
		MeshPtr m_srcMesh ;
		//Mesh::Vertex*  m_mixVertexs;
		Mesh::Vertex (*m_debugMixVertexs)[5000];

		MeshCloneType m_cloneType;

		//VertexBuffer*  m_verterBuffer;
		//IndexBuffer*   m_indexBuffer;
	};
	
	//product hair
	//class Modifier
	//{
	//};
	//now just one modifier
	class ModifierSys
	{
	public:
		enum ModifierType 
		{
			MT_NONE = 0,
			MT_TWIST,
			MT_WAVE,
			MT_SPRING,
			MT_LOD,
			MT_NUM
		};
		ModifierType m_mdType;
		ModifierSys()
			:m_movie(NULL) 
			,angleDegMax(90.0f)
			,m_mdType(MT_NONE)
		{}

		void SetSrcMovie(MovieClip* movie) { m_movie = movie;}

		void DoModify(float time);

		void SetModifyType(ModifierType type){m_mdType = type;}
		void SetTwistMaxAngle(float angle) { angleDegMax = angle; }
	private:	
		void DoTwist(float time);
		void DoWave(float time);
		void DoSpring(float time);
		void DoLod(float lodPersent);

		MovieClip* m_movie;
		float	angleDegMax;
	};


	//real time shadow 最多八盏灯
	class VolumeShadowSys
	{
	public:
		VolumeShadowSys();
		VolumeShadowSys(VolumeShadowSys& other) { *this = other;};
		const VolumeShadowSys& operator= (const VolumeShadowSys& other);
		// length of shadow volume
#define INFINITY	100
		// ax + by + cz + d = 0
		struct Plane
		{
			float a,b,c,d;
		};

		struct ShadowTrigon
		{
			Plane plane;
			// neighbor face index which have a same edge
			unsigned int neighbor[3];
			// is facing the light
			BOOL bVisible;           
		};

		ShadowTrigon*	m_pPlanes;
		Mesh*           m_mesh;

		void Free();
		void SetMesh(Mesh* mesh);
		//call CalConnectivity() when init to find the neighbors of all the faces,
		//call CalPlane() when the points of the mesh dynamic change
		void CalConnectivity();
		void CalPlane();
		void DrawShadowVolume(float lp[]);
		//mul to transform the vector
		static void vMatMult(float M[], float v[]);
		//gen after the terrain rended
		void GenShadowStencil(float lp[]);
		static void RenderShadow();
	};


	class Frame
	{
	public:
		enum InterType 
		{
			Inter,
			Smooth,
			Bezier,
		};
		Frame();
		int   m_time;
		vec3  m_pos;
		vec3  m_scale;
		vec3  m_rot;
		quat      m_quat;
		mat4      m_matrix;

		float __declspec(align(16)) m_matrixSIMD[16];

		float m_uOffset;
		float m_vOffset;
		float m_uTile;
		float m_vTile;
		bool  m_visible;
		Color m_color;
        InterType m_interType;
		//vertex anim
		Mesh* m_mesh;
		//shader Material
		//modifier
		//reactor
		//Frame& operator=(Frame& rhs);
		//MatrixF* setMatrix( MatrixF * mat ) const;

		void Format(char* buf);
		void EditRender();
		void CoordConvert(COORDSYS totype);
		void CalQuatMatrixFromRot();
		void CalFromMatrix();
		void SetPos(vec3& pos);
		static void Slerp(Frame* befter,Frame* after,float beforefactor,Frame* res);
		static void Muti(Frame& parent,Frame& sub,Frame& res);
		COORDSYS m_coordSys;
	};


	//frameLine of mc maybe just a pointer to another mc
	class FrameLine
	{
	public:
		FrameLine();
		virtual ~FrameLine();
		void Free();
		//be able to share with ohers
		void GenMixFrame(Frame& frame,float time,bool bInterplate = true);
		bool LoadSingleMovieFrame(File& filein);
		bool SaveSingleMovieFrame(File& fileout);
		bool SaveSingleMovieFrame(File& fileout,const char* space);
		void AddFrame(Frame& frame);
		void ClearFrame(int frameNum);
		const char* GetFrameName();
		int  GetFrameNum();
		float GetMaxTime();

		//pick and edit
		void EditRender();
		MovieClip* Intersect(vec3& pos);
		void IntersectImp(vec3& pos,MovieClip*& lastclip,float& lastlen);
		void CoordConvert(COORDSYS totype);

		FrameLine& operator=(FrameLine& other);
		void ConvertToRelative();

		String      m_frameLineName;
		Frame*      m_frames;
		Frame       m_firstInverse;

	//protected:
		int         m_frameNum;
		Frame      (*m_debugFrames)[100];
		float       m_maxTime;


		//script ctrl
		class FpsCmdBase
		{
		public:
			enum FpsCmdType
			{
				GOTOANDSTOP = 0,
				GOTOANDPLAY,
				REMOVETHIS,
				PAUSE,
				PLAY,
				REPORTEVENT,
				//ADDCOMMAND,
			};
			float time;
			FpsCmdType commandType;
			void* parm;
			virtual void Execute();
		};

		friend inline bool operator<(const FpsCmdBase& t1, const FpsCmdBase& t2)
		{
			return  (t1.time < t2.time);
		}

		class PcdCmdSelect:public FpsCmdBase
		{
		public:
			virtual void Execute();
		};

		class PcdCmdTransform:public FpsCmdBase
		{
		public:
			virtual void Execute();
		};

		std::list<FpsCmdBase*> m_cmds;
		void Execute();
		void AddFpsCmdBase(FpsCmdBase* command);

		void Test();
	};

	class PlayHead
	{
	public:
		PlayHead();
		virtual ~PlayHead();
		virtual void Advance();
		//loop from flag ‘runbegin’to ‘runend’
		void   SetPlayLoop(int begin,int end);
		void   SetPause(bool pause);
		float  GetCurTime();
		void   SetCurTime(float time);
		void   ReStart();
		virtual void OnFrame(const char* framename);
		
	//protected:
		bool  m_isLooping;
		bool  m_isPause;
		int   m_beginFrame;
		int   m_endFrame;

		float m_curTime;
		float m_maxTime;
		float m_speed;	
		bool  m_onFrameEnable;
		//frame tags
		//std::list<>;
	};

	class FrameHead:public PlayHead
	{
	public:
		FrameHead(MovieClip* owner);
		void Advance();
		void SetFrameLine(FrameLine* frameLine);
		FrameLine* GetFrameLine() const;
		void EditRenderMixFrame();
		Frame& GetMixFrame();
		virtual void OnFrame(const char* framename);
		bool GetInterplate() const;
		void SetInterplate(bool val);
		Frame m_mixFrame;

	private:
		FrameLine* m_frameLine;
		MovieClip* m_owner;
		bool       m_bInterplate;

	};

	struct Bone
	{
		int boneID;
		//int parentBoneID;
		String boneName;
		FrameLine    m_frameLine;
		//FrameLine    m_frameLineRelative;
	};

	class Skeleton
	{
	public:
		Skeleton();
		~Skeleton();
		void Free();
		bool LoadSingleMovieSkeleton(const char* filename);
		bool LoadSingleMovieSkeleton(File& filein);
		bool SaveSingleMovieSkeleton(File& fileout);
		virtual void  CoordConvert(COORDSYS totype);
		float GetMaxTime() { return m_maxTime;}

		int m_boneNum;
		Bone* m_bones;
		Bone (*m_debugBones)[100];
		//Bone* operator[](int id);
		Bone* GetBone(int id);
		inline int   GetBoneIndex(int id){return m_indexs[id];}
		int   GetBoneIndex(const char* boneName);
		float m_maxTime;
	//private:
		//fast
		std::vector<int> m_indexs;
	};

	class MixSkeleton:public PlayHead
	{
	public:
		MixSkeleton(MovieClip* owner=NULL);
		MixSkeleton(MovieClip* owner,MixSkeleton& bone);
		~MixSkeleton();
		const MixSkeleton& operator= (/*const*/ MixSkeleton& other);
		void  Advance();
		void  Free();
		void  SetSkeleton(Skeleton* skeleton);
		void  EditRender();
		inline Frame* GetMixFrame(int boneId);
		Frame* GetMixFrame(const char* boneName);

		virtual void OnFrame(const char* framename);

		Frame*     m_mixFrameArr;
		Frame*     m_mixFrameRelativeArr;

		Skeleton*  m_skeleton;
		float      m_blendTime;
		Skeleton*  m_lastSkeleton;
		MovieClip* m_owner;
	};

	/**
	* Get what you see in 3dsmax.
	* MovieClip tween morph:pos,scale,rot,alpha,material,skinbones.
	* MovieClip self morph:texture,vertex.
	* key mouse event:press click drag...
	* Dynamic 3d mask: draw the point only if it is in it's dumy_mask_mesh movieclip.
	*                  implete as shadow volume stensil buf gen.
	* Collide:collide with tray or tray box,this can be useful on movable zone.
	*         rts collide base on cells,fps collide base on mesh.
	* Refrence instance: use dumy for export dumplicate instance in max.
	*                    refrence instance in c++,a ref mesh or ref movieclip.
	* Reattach:texture,mesh,bone or keys.
	* modify sys: some modifiers.
	* procedural sys: create meshs and animations randly.
	* call back: frame event call back.
	* static mesh 优化  版本升级时格式兼容 分成(string)标记块读写
	* save script fun for every obj
	*/

	typedef std::list<MovieClip*> MovieClipArr;
	typedef std::list<MovieClip*>::iterator MovieClipIter;
	typedef std::list<MovieClip*>::const_iterator MovieClipConstIter;

	class MovieClip:public ScriptObject
	{
	public:
		enum MovieType
		{
			MT_UNKNOW = 0,    //enum_objtype_unknow   = 0
			MT_FRAMEMOVIE,	  //enum_objtype_mesh     = 1
			MT_CAMERA,		  //enum_objtype_camera   = 2
			MT_LIGHT,		  //enum_objtype_light    = 3
			MT_BONEMESH,	  //enum_objtype_bonemesh = 4
			MT_BONE,          //enum_objtype_bone     = 5
			MT_PARTICLE,      //enum_objtype_particle = 6
			MT_FRAMEBILLBOARDMOVIE,//enum_objtype_billboardmesh = 7
			MT_BONEBILLBOARDMOVIE, //enum_objtype_billboardbonemesh = 8
			MT_VERTEXANIMMOVIE, //enum_objtype_vertexanimmesh = 9
			MT_STRIPTAIL,     //enum_objtype_striptailmesh = 10
			MT_BONESTRIPTAIL, //enum_objtype_striptailbonemesh = 11
            MT_BONECLOTH,     //enum_objtype_boneclothmesh = 12
			MT_WITHBONEMOVIE, //enum_objtype_withbonemovie = 13
			MT_MASK,          //dynamic mask box
			MT_INSTANCE,
			MT_CONTAINER 
		};


		enum RendOption
		{
			RO_ALL = 0,
			RO_RECEIVESHADOW,
			RO_AFTERGENSHADOW,
			RO_WATER,
			RO_WATERREFLECT,
			RO_GenShadowMap,
			RO_UseShadowMap,
		};

		enum CloneType
		{
			CT_REF = 0,
			CT_INSTANCE,
			CT_COPY,
			CT_NUM
		};
		MovieClip();
		virtual ~MovieClip();

		virtual void CalBound();
		MovieClip*   Intersect(vec3& pos);
		//recursive
		void         IntersectImp(vec3& pos,MovieClip*& lastclip,float& lastlen);
		MovieClip*   IntersectTray(RayMovieCollideRes& res);
		virtual void IntersectTrayImp(RayMovieCollideRes& res);
		
		//dynamic change
		void ReAttachMesh(Mesh* mesh);
		void ReAttachTexture(const char* textureName);
		void ReAttachTexture(Texture* texture);

		MovieClip* GetRoot();
		MovieClip* GetMovieClip(const char* movieName);
		void AddMovieClip(MovieClip* movie);
		void RemoveMovieClip(MovieClip* movie,bool free = true);

		void StartDrag(bool center);
		void StopDrag ();

		bool          LoadMovieFromFile(const char* fileName,bool genAABB=false,bool genBuff=true);
		virtual void  FreeMovie();
		virtual void  Advance();
		virtual void  AdvanceThread();
		virtual void  RendClip(int option=RO_ALL);
		virtual void  GenShadow();
		//pick edit and debug
		virtual void  EditRender();;
		void          RendTransArrow(vec3& pos);

		//protected: 
		virtual bool  LoadMovie(File& filein);
		virtual bool  SaveMovie(File& fileout);
		virtual bool  LoadSingleMovie(File& filein);
		virtual bool  SaveSingleMovie(File& fileout);
		virtual void  CoordConvert(COORDSYS totype);
		virtual void  LoadedProcess(bool genAABB,bool genBuff,bool accordant);

		virtual void  AssignSkeleton(Skeleton* skeleton);
	    //attation: when src mc be free,instance mc need not be free; because share res use ptr.
		virtual MovieClip* Clone(CloneType type = CT_REF);

		virtual void OnFrame(const char* framename);

		virtual bool UseThisLight();

		bool AlphaSort();
		bool MaterialSort();
		//bool unproject( const vec3 &pt, vec3 *dest ) const;
	
		/*const*/ Frame&  GetProgramFrame() /*const*/;
		void          SetProgramFrame(Frame& frame);
		const char*   GetMovieName();
		void          SetMovieName(const char* name);
		const char*   GetTextureName();
		const char*   GetFilePath();
		MovieType     GetMovieType();
		/*const */MovieClipArr& GetSubMovieArr();
		Frame*        GetFinalFrame(); 

		void SetLoadComplete(bool finish);;
		bool GetLoadComplete();;
		void SetPickable(bool able,bool recursive = false);
		void SetPicked(bool picked,bool recursive = false);
		bool GetPicked();
		void SetVisible(bool able,bool recursive = false);
		bool GetVisible();
		bool GetInFrustum();
		void SetFogEffect(bool fogEnable,bool recursive = false);
		
		void SetReceiveShadow(bool receive,bool recursive = false);
		int  GetAlphaSortPriority(); 
		void SetAlphaSortPriority(int priority,bool recursive = false); 
		//max set sort by alpha and name,this resort by dist to camera.
		int  GetAlphaSortEnable(); 
		void SetAlphaSortEnable(bool alphaSort,bool recursive = false);
		void SetFrustumSkipEnable(bool able,bool recursive = false);
		bool GetWaterLike() const;
		void SetWaterLike(bool val);
		bool GetDepthMask() const;
		void SetDepthMask(bool val,bool recursive = false);

		bool GetBoneMixFrame(const char* boneName,Frame* frame);

		Mesh* GetMesh();
		void  SetMesh(Mesh* mesh);
		MixMesh* GetMixMesh();
		VolumeShadowSys&     GetShadowSys();
		ModifierSys*   GetModifierSys();
		void SetModefierSys(ModifierSys* modifer);
		CollideAABBox&    GetCollideSys();
		
		CallBacks*     GetCallBacks();   

		Texture* GetTexture();
		//static CallBacks* GetCallBacks(){ return &m_callBacks;}   

		//debug
		int GetTotalTrigonNum();

		enum ThreadAdvanceFlag
		{
			TO_Init,
			TO_ThreadAdvance,
			TO_RenderAdvance,
		};
		/*volatile*/ ThreadAdvanceFlag m_threadAdvanceFlag;

	protected:
		enum SkipType{Skip_None,Skip_Self,Skip_All};
		virtual SkipType CanSkipRend(int option);
		//res shared to clones
		//a Movieclip has only one Mesh,what be nested is mc not the mesh
		MeshPtr    m_mesh;
		TexturePtr m_texture;
		TexturePtr m_detailTexture;
		int        m_opacityType;

		//to do recurrent play.
		static MovieClip* m_curCamera;

	protected:
		Frame m_programFrame;
		Frame m_finalFrame;
		Frame m_finalFrameInverse;

		bool m_doCasterShadow;
		bool m_doReceiveShadow;
		bool m_doReflectedByWater;
		bool m_bWaterLike;
		bool m_doPickAble;
		bool m_doCollodeAble;
		bool m_visible;
		bool m_picked;
		int  m_alphaSortPriority;
		bool m_doAlphaSort;
		bool m_loadComplete;
		bool m_doFogEffect;
		bool m_advanceDirty;
		bool m_bInFrustum;
		bool m_doFrustumSkip;
		bool m_bLensFlare;
		bool m_doDepthMask;

		MovieClip*   m_parentMovie;
		MovieClip*   m_maskMovie;
		MovieClipArr m_movieClips;

		String m_movieName;
		String m_filePath;
		
		VolumeShadowSys m_shadowSys;
		ModifierSys*    m_mdSys;
		MixMesh*        m_mixMesh;
		CollideAABBox   m_collideAABBox;
		CallBacks*      m_callBacks;

		String    m_textureName;
		//keep one ptr at least in order to hold the resource.
		MovieType m_type;
		//shader Material
		//reactor

		float m_extra;
    protected:
		public:
	    //instance movies
		void AddRefMovie(MovieClip* movie);
		void RelseaeRefMovie(MovieClip* movie);
		MovieClipArr m_refMovies;

		void  RendSubClip(int option=RO_ALL);
		void  AdvanceSubClip();
		void  CaculFinalFrame();

	protected:
		MovieClip(const MovieClip &);
		virtual MovieClip& operator=(const MovieClip&);

	}; 

	class MC_Frame:public MovieClip
	{
	public:
		typedef MovieClip Parent;
		MC_Frame();
		void ReAttachFrameLine(FrameLine* framesys);

		virtual void  RendClip(int option=RO_ALL);
		virtual void  GenShadow();
		virtual void  EditRender();
		virtual void  Advance();
		virtual void  FreeMovie();
		virtual void  CalBound();
		virtual bool  LoadSingleMovie(File& fp);
		virtual bool  SaveSingleMovie(File& fp);
		virtual void  CoordConvert(COORDSYS totype);
		virtual void  LoadedProcess(bool genAABB,bool genBuff,bool accordant);
		virtual vec3  GetPos();
		virtual MovieClip* Clone(CloneType type = CT_REF);
		virtual SkipType CanSkipRend(int option);
		void    BeginCommonRendState(int option);
		void    EndCommonRendState();
		virtual MovieClip& operator=(const MovieClip& other);
		FrameLinePtr m_frameLine;
		FrameHead    m_frameHead;
	
	};

	//可以附着子物体 比如3d gui ,snow particles
	class MC_Camera:public MC_Frame
	{
	public:
		MC_Camera();
		virtual void  EditRender();
		virtual void  Advance();
		virtual bool  LoadSingleMovie(File& fp);
		virtual bool  SaveSingleMovie(File& fp);
		virtual void  CoordConvert(COORDSYS totype);
		virtual void  LoadedProcess(bool genAABB,bool genBuff,bool accordant);
		virtual MovieClip* Clone(CloneType type = CT_REF);
		void UseThisCamera();

	private:
		int  m_fov;
		bool m_isOrtho;
		int  m_nearPlane;
		int  m_farPlane;
		vec3 m_lookFrom;
		vec3 m_lookTo;
		vec3 m_up;
		vec3 m_coners[8];

	};

	class MC_Particle:public MC_Frame
	{
	public:
		MC_Particle();
		~MC_Particle();
	
		virtual void  RendClip(int option=RO_ALL);
		virtual void  GenShadow();
		virtual void  EditRender();
		virtual void  Advance();
		virtual void  AdvanceThread();
		virtual void  FreeMovie();
		virtual void  CalBound();
		virtual bool  LoadSingleMovie(File& fp);
		virtual bool  SaveSingleMovie(File& fp);
		virtual void  CoordConvert(COORDSYS totype);
		virtual void  LoadedProcess(bool genAABB,bool genBuff,bool accordant);
		virtual MovieClip* Clone(CloneType type = CT_REF);
		virtual SkipType CanSkipRend(int option);
		virtual MovieClip& operator=(const MovieClip&);

		EmitterDef*      m_emitterDef;
		ParticleEmitter* m_emitter;
		MovieClip*    m_attachedModel;

		String        m_attachedModelName;
		String        m_emitterdefName; 

		//MixSkeleton    m_mixBone;
		//bind bone
		int  m_parentBoneID;
		vec3 m_offset;
	};

	//each face is a billboard,center is pos,point to center is radius,
	class MC_FrameBillboard:public MC_Frame
	{
	public:
		MC_FrameBillboard();
		~MC_FrameBillboard();

		virtual void  RendClip(int option=RO_ALL);
		virtual void  GenShadow();
		virtual void  EditRender();
		virtual void  Advance();
		virtual void  AdvanceThread();
		virtual void  FreeMovie();
		virtual void  CalBound();
		virtual bool  LoadSingleMovie(File& fp);
		virtual bool  SaveSingleMovie(File& fp);
		virtual MovieClip* Clone(CloneType type = CT_REF);
		virtual SkipType CanSkipRend(int option);
		virtual MovieClip& operator=(const MovieClip& other_);
		virtual void  LoadedProcess(bool genAABB,bool genBuff,bool accordant);
	private:
		vec3* m_vVertex;
		vec2* m_tVertex;
	};

	class MC_FrameVertex:public MC_Frame
	{
	public:
		MC_FrameVertex();
		~MC_FrameVertex();

		virtual void  RendClip(int option=RO_ALL);
		virtual void  GenShadow();
		virtual void  EditRender();
		virtual void  Advance();
		virtual void  AdvanceThread();
		virtual void  FreeMovie();
		virtual void  CalBound();
		virtual bool  LoadSingleMovie(File& fp);
		virtual bool  SaveSingleMovie(File& fp);
		virtual MovieClip* Clone(CloneType type = CT_REF);
		virtual SkipType CanSkipRend(int option);
	};

	class MC_FrameStripTail:public MC_Frame
	{
	public:
		MC_FrameStripTail();
		~MC_FrameStripTail();

		virtual void  RendClip(int option=RO_ALL);
		virtual void  GenShadow();
		virtual void  EditRender();
		virtual void  Advance();
		virtual void  AdvanceThread();
		virtual void  FreeMovie();
		virtual void  CalBound();
		virtual bool  LoadSingleMovie(File& fp);
		virtual bool  SaveSingleMovie(File& fp);
		virtual void  CoordConvert(COORDSYS totype);
		virtual void  LoadedProcess(bool genAABB,bool genBuff,bool accordant);
		virtual MovieClip* Clone(CloneType type = CT_REF);
		virtual SkipType CanSkipRend(int option);
		virtual MovieClip& operator=(const MovieClip&);
		StripTail*   m_tail;
	};
	

	class MC_Light:public MC_Frame
	{
	public:
		MC_Light();
		~MC_Light();

		virtual void  RendClip(int option=RO_ALL);
		virtual void  GenShadow();
		virtual void  EditRender();
		virtual void  Advance();
		virtual void  FreeMovie();
		virtual void  CalBound();
		virtual bool  LoadSingleMovie(File& fp);
		virtual bool  SaveSingleMovie(File& fp);
		virtual MovieClip* Clone(CloneType type = CT_REF);

		virtual bool UseThisLight();
		MixSkeleton    m_mixBone;
		//bind bone
		int  m_parentBoneID;

		Light* m_light;
	};

	class MC_Skeleton:public MC_Frame
	{
	public:
		typedef MC_Frame Parent;
		MC_Skeleton();
		~MC_Skeleton();

		virtual void  RendClip(int option=RO_ALL);
		virtual void  GenShadow();
		virtual void  EditRender();
		virtual void  Advance();
		virtual void  AdvanceThread();
		virtual void  FreeMovie();
		virtual void  CalBound();
		virtual bool  LoadSingleMovie(File& fp);
		virtual bool  SaveSingleMovie(File& fp);
		virtual void  CoordConvert(COORDSYS totype);
		virtual void  LoadedProcess(bool genAABB,bool genBuff,bool accordant);
		virtual void  AssignSkeleton(Skeleton* skeleton);
	    virtual MovieClip* Clone(CloneType type = CT_REF);
		virtual void  IntersectTrayImp(RayMovieCollideRes& res);
		virtual SkipType CanSkipRend(int option);

		MixSkeleton   m_mixSkeleton;
		bool          m_gpuAdvance;
	};

	class MC_SkeletonSoftObj:public MC_Skeleton
	{
	public:
		MC_SkeletonSoftObj();
		~MC_SkeletonSoftObj();

		virtual void  RendClip(int option=RO_ALL);
		virtual void  GenShadow();
		//virtual void  EditRender();
		virtual void  Advance();
		virtual void  AdvanceThread();
		virtual void  FreeMovie();
		virtual void  CalBound();
		//virtual bool  LoadSingleMovie(File& fp);
		//virtual bool  SaveSingleMovie(File& fp);
		//virtual void  CoordConvert(COORDSYS totype);
		virtual void  LoadedProcess(bool genAABB,bool genBuff,bool accordant);
		//virtual MovieClip* Clone(CloneType type = CT_REF);
		virtual SkipType CanSkipRend(int option);
		SoftObject*   m_softObj;
	};

	class MC_SkeletonBillboard:public MC_Skeleton
	{
	public:
		MC_SkeletonBillboard();
		~MC_SkeletonBillboard();

		virtual void  RendClip(int option=RO_ALL);
		virtual void  GenShadow();
		//virtual void  EditRender();
		virtual void  Advance();
		virtual void  AdvanceThread();
		virtual void  FreeMovie();
		virtual void  CalBound();
		virtual bool  LoadSingleMovie(File& fp);
		//virtual bool  SaveSingleMovie(File& fp);
		//virtual void  CoordConvert(COORDSYS totype);
		virtual void  LoadedProcess(bool genAABB,bool genBuff,bool accordant);
		//virtual MovieClip* Clone(CloneType type = CT_REF);
		virtual SkipType CanSkipRend(int option);
	};

	class MC_SkeletonStripTail:public MC_Skeleton
	{
	public:
		MC_SkeletonStripTail();
		~MC_SkeletonStripTail();

		virtual void  RendClip(int option=RO_ALL);
		virtual void  GenShadow();
		//virtual void  EditRender();
		virtual void  Advance();
		virtual void  AdvanceThread();
		virtual void  FreeMovie();
		virtual void  CalBound();
		virtual bool  LoadSingleMovie(File& fp);
		//virtual bool  SaveSingleMovie(File& fp);
		//virtual void  CoordConvert(COORDSYS totype);
		virtual void  LoadedProcess(bool genAABB,bool genBuff,bool accordant);
		//virtual MovieClip* Clone(CloneType type = CT_REF);
		virtual SkipType CanSkipRend(int option);
		virtual MovieClip& operator=(const MovieClip&);
		StripTail*   m_tail;
	};

	class MeshMgr:public MemberSingleton<MeshMgr>,public ResPtrMgr<Mesh>
	{
	public:
		bool AddMesh(MeshPtr& ptr,const char* refName="");
	};

	class MovieClipMgr:public MemberSingleton<MovieClipMgr>,public ResPtrMgr<MovieClip>
	{
	public:
		bool AddMovieClip(MovieClipPtr& ptr,const char* fileName,const char* refName="",bool genAABB=true);
	};

	class SkeletonMgr:public MemberSingleton<SkeletonMgr>,public ResPtrMgr<Skeleton>
	{
	public:
		bool AddSkeleton(SkeletonPtr& ptr,const char* fileName,const char* refName="");
	};

  
#define G_MovieThreadLoader MovieClipThreadLoader::GetSingleton()
	//是否封装一个线程安全的vector 影响太大
	//多线程调用临时对象的虚函数run时对象已析构,发现多态不起作用 调到了基类的run中
	//ogl create buf 和 freeimage 不支持多线程
	class MovieClipThreadLoader:public ScriptObject,public SingleTaskThread,public Singleton<MovieClipThreadLoader>
	{
	public:
		MovieClipThreadLoader();
		//~MovieClipThreadLoader()
		//{}
		struct MovieLoadTask:public Task
		{
			MovieLoadTask(MovieClip* movie,const char* fileName)
				:m_movie(movie)
				,m_fileName(fileName)
			{
				m_movie->SetLoadComplete(false);
			}
			virtual void Excute();
			MovieClip* m_movie;
			String m_fileName;
		};

		virtual bool Run(ThreadParm* pData);
		void PushTask(MovieClip* movie,const char* fileName);

	};



#define G_SkeletonMovieAdvancer SkeletonMovieAdvancer::GetSingleton()
	//是否封装一个线程安全的vector 影响太大
	//多线程调用临时对象的虚函数run时对象已析构,发现多态不起作用 调到了基类的run中
	//ogl create buf 和 freeimage 不支持多线程
	class SkeletonMovieAdvancer:public SingleTaskThread,public Singleton<SkeletonMovieAdvancer>
	{
	public:
		SkeletonMovieAdvancer();
		//~SkeletonMovieAdvancer()
		//{}
		struct SkeletonMovieAdvanceTask:public Task
		{
			SkeletonMovieAdvanceTask();
			virtual void Excute();
			MovieClip* m_movie;
		};

		virtual bool Run(ThreadParm* pData);
		void PushTask(MovieClip* movie);
		void RemoveTask(MovieClip* movie);
		virtual Task* GetTaskObj();

		CriticalSection m_freeMovieLock;
		bool  m_enable;
		bool  m_bLock;
	};

	//Procedural modeling and texturing and key
	class ProceduralSys:public Singleton<ProceduralSys>
	{
	public:
		enum SelectType
		{
			ST_NONE = 0,
			ST_POINT,
			ST_EDGE,
			ST_FACE,
			ST_OUTLINE,
		};
		ProceduralSys();
		~ProceduralSys();
	
		void SetOperateMovie(MovieClip* movie);
		void GenRandMesh();

		void GenCone();
		void GenTorus();
		void GenSphere();
		void GenSylinder();

		// The shape must be closed ,The path must have three points at least and cannot be closed.
		bool    GenLoft();
		CCurve& GetPathCurve();
		CCurve& GetShapeCurve();
		CCurve& GetScaleCurve();
		CCurve& GetTwistCurve();
		void    SetUVRect(vec4& rect);

	protected:
		// 计算shape的变换矩阵
		void GetShapeMatrix( vec3& shapeNorm,  vec3& slice, const vec3& pathPnt,const vec3& pathScale, mat4& finalMat);

		void GetRayAndPlaneIntersetPnt(const vec3& rayOrig, const vec3& rayDir, 
			const vec3& planeNorm, const vec3& planePnt, vec3& point);

		void  ConvertUV(float& u,float& v);

		CCurve*	m_shapeCurve;			
		CCurve*	m_pathCurve;
		CCurve*	m_scaleCurve;
		CCurve* m_twistCurve;
		vec4    m_uvRect;

		class Edge
		{
		public:
			int indexStart;
			int indexEnd;
		};

		class SelectRes
		{
		public:

			int m_trigonNum;
			int m_vVertexNum;
			int m_vEdgeNum;

			int*  m_vertexsIndex;
			int*  m_trigonsIndex;
			Edge* m_edges;
		};

		MovieClip* m_movie;
		static const int MaxTrigonNum = 1000;
		static const int MaxVVertexNum = 1000;
		static const int MaxTVertexNum = 1000;

		//void SelectSlice(SelectType type/*,Shape& shape*/);
		//void ReverceSelect();
		//void TransSelect();
		//void SpringTransSelect();
		//clone selections then extrude them and select the new creation
		//void Extrude(); 
		//void RefranceCopy();
		//void Merge();  
		//void Weild();
		//void Remove();
		//void AddSmoth();
		//	smoth增面  减面 分形
		//	city  蜗牛赛道
		//void RendSelect();

	};

	//
	class ProTreeDef
	{
		friend class Particle;
	public:
		ProTreeDef();

		static const int MaxDepth = 6;
		String m_defName;
		String m_texture;

	
		//每一层最大叶子数
		int   m_maxLeaves;//[MaxDepth];	
		//叶与主干夹角
		float m_leafStemAngle;//[MaxDepth];	
		float m_leafSize;//[MaxDepth];	
		
		//每一层分枝数
		int m_subTreeNum[MaxDepth];
		//分枝与主干长度比
		float m_subLenMult[MaxDepth];
		//分枝与主干半径比
		float m_subRadiusMult[MaxDepth];
		//分枝与主干夹角
		float m_subStemAngle;//[MaxDepth];	
		//分枝最小高度
		float m_minSubOffset[MaxDepth];

		//初始长度
		float m_mainStemLen;
		//初始底部半径
		float m_mainStemRadius;

		//主干顶端和底部半径比
		float m_stemFac[MaxDepth];;

		int   m_depth;

		//树叶类型: 十字放样 或 mesh
		//BillBoard  m_billboard;
		//RendSys::MovieClip* m_movie;
		//bool SetMovie(const char* fileName);
		//bool SetMovie(const RendSys::MovieClip* movie);

		void Load(File& file);
		void Save(File& file);

	};

	class ProTreeDefMgr:public MemberSingleton<ProTreeDefMgr>
	{
	public:
		~ProTreeDefMgr();
		int  Init();
		void Free();
		ProTreeDef* AddProTreeDef(const char* fileName,const char* refName="");
		ProTreeDef* GetProTreeDef(const char* refName);
	};

	class TreeProceduralSys:public ProceduralSys,public Singleton<TreeProceduralSys>
	{
	public:
		TreeProceduralSys();
		void GenRandTree(ProTreeDef* def);
		void GenRandTree(const char* def);
	
	private:
		void GenRandTree(ProTreeDef* def,int depth,mat4 mat);	
		virtual void drawFoliage(float s);
	};

#define G_TreeProceduralSys TreeProceduralSys::Singleton<RendSys::TreeProceduralSys>::GetSingleton()
#define G_ProTreeDefMgr ProTreeDefMgr::GetSingleton()
}

using namespace RendSys;

//test config
#define  USEBUFFER
//亮度闪烁(diffuse设置为0即正常了)=>法线不对=>drawcall正确=>buffer错误
//#define DRAWCALL
//#define INDEXARRAY //OpenGL 1.1
#define VERTEXBUFFER 

//#define MESHOZCOLLIDE
//#define MESHOCTREE
#define MESHBSPTREE
//#define SHADOWVALUME
#define USEMATRIX

#endif

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值