1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "nel/3d/coarse_mesh_manager.h"
20 #include "nel/3d/mesh.h"
21 #include "nel/3d/texture_file.h"
22 #include "nel/misc/hierarchical_timer.h"
23 #include "nel/3d/clip_trav.h"
24 #include "nel/3d/debug_vb.h"
26 #include "nel/misc/fast_mem.h"
29 using namespace NLMISC
;
39 H_AUTO_DECL( NL3D_StaticLod_AddMesh
)
42 // ***************************************************************************
43 CCoarseMeshManager::CCoarseMeshManager()
47 _Texture
=new CTextureFile ();
48 _TextureCategory
= new ITexture::CTextureCategory("COARSE MESH MANAGER");
49 _Texture
->setTextureCategory(_TextureCategory
);
54 _Material
.initUnlit ();
55 _Material
.setDoubleSided (true);
56 _Material
.setAlphaTest (true);
57 _Material
.setColor (CRGBA (255, 255, 255));
58 // Init blend Factors, for possible Alpha transition
59 _Material
.setSrcBlend(CMaterial::srcalpha
);
60 _Material
.setDstBlend(CMaterial::invsrcalpha
);
63 _Material
.setTexture (0, _Texture
);
66 _VBuffer
.setVertexFormat(NL3D_COARSEMESH_VERTEX_FORMAT_MGR
);
67 _VBuffer
.setNumVertices(NL3D_COARSEMESH_VERTEXBUFFER_SIZE
);
68 _VBuffer
.setName("CCoarseMeshManager");
69 _VBuffer
.setPreferredMemory(CVertexBuffer::AGPVolatile
, false);
70 _Triangles
.setFormat(NL_COARSE_MESH_INDEX_FORMAT
);
71 _Triangles
.setNumIndexes(NL3D_COARSEMESH_TRIANGLE_SIZE
*3);
72 _Triangles
.setPreferredMemory(CIndexBuffer::RAMVolatile
, false); // TODO : see if agp index is better
73 _CurrentNumVertices
= 0;
74 _CurrentNumTriangles
= 0;
75 NL_SET_IB_NAME(_Triangles
, "CCoarseMeshManager");
78 // ***************************************************************************
80 void CCoarseMeshManager::setTextureFile (const char* file
)
82 _Texture
->setFileName (file
);
85 // ***************************************************************************
87 bool CCoarseMeshManager::addMesh (uint numVertices
, const uint8
*vBuffer
, uint numTris
, const TCoarseMeshIndexType
*indexBuffer
)
89 H_AUTO_USE( NL3D_StaticLod_AddMesh
);
92 if(numTris
==0 || numVertices
==0)
96 if(_CurrentNumVertices
+ numVertices
> NL3D_COARSEMESH_VERTEXBUFFER_SIZE
)
100 if(_CurrentNumTriangles
+ numTris
> NL3D_COARSEMESH_TRIANGLE_SIZE
)
104 mi
.NumVertices
= numVertices
;
105 mi
.VBuffer
= vBuffer
;
106 mi
.NumTris
= numTris
;
107 mi
.IndexBuffer
= indexBuffer
;
108 _Meshs
.push_back(mi
);
109 _CurrentNumVertices
+= numVertices
;
110 _CurrentNumTriangles
+= numTris
;
116 // ***************************************************************************
118 void CCoarseMeshManager::flushRender (IDriver
*drv
)
120 H_AUTO( NL3D_StaticLod_Render
);
121 if (_Meshs
.empty()) return;
123 // if the driver is BGRA (Direct3D), then invert color format
124 if(!_VBuffer
.isResident() && drv
->getVertexColorFormat()==CVertexBuffer::TBGRA
)
126 // since actually empty, no need to swap current memory
127 _VBuffer
.setNumVertices(0);
128 _VBuffer
.setVertexColorFormat(CVertexBuffer::TBGRA
);
132 _VBuffer
.setNumVertices(_CurrentNumVertices
);
133 _Triangles
.setNumIndexes(_CurrentNumTriangles
* 3);
134 _VBuffer
.lock (_VBA
);
135 _Triangles
.lock(_IBA
);
136 uint currentNumVertices
= 0;
137 uint currentNumTriangles
= 0;
138 for(std::vector
<CMeshInfo
>::iterator it
= _Meshs
.begin(); it
!= _Meshs
.end(); ++it
)
140 // Copy Vertices to VBuffer
141 uint baseVertex
= currentNumVertices
;
142 CHECK_VBA_RANGE(_VBA
, _VBA
.getVertexCoordPointer(baseVertex
), it
->NumVertices
*_VBuffer
.getVertexSize());
143 CFastMem::memcpy(_VBA
.getVertexCoordPointer(baseVertex
), it
->VBuffer
, it
->NumVertices
*_VBuffer
.getVertexSize());
146 currentNumVertices
+= it
->NumVertices
;
148 // Copy tris to triangles, adding baseVertex to index
149 TCoarseMeshIndexType
*triDst
= (TCoarseMeshIndexType
*) _IBA
.getPtr()+currentNumTriangles
*3;
150 const TCoarseMeshIndexType
*triSrc
= it
->IndexBuffer
;
151 uint numIdx
= it
->NumTris
*3;
152 // NB: for the majority of CoarseMesh (4 faces==48 bytes of indices), not interressant to use CFastMem::precache()
153 for(;numIdx
>0;numIdx
--, triSrc
++, triDst
++)
155 CHECK_IBA(_IBA
, triDst
)
156 *triDst
= *triSrc
+ baseVertex
;
159 currentNumTriangles
+= it
->NumTris
;
164 // If not empty, render
165 if(_CurrentNumVertices
&& _CurrentNumTriangles
)
168 drv
->setupModelMatrix (CMatrix::Identity
);
171 drv
->activeVertexBuffer(_VBuffer
);
172 drv
->activeIndexBuffer(_Triangles
);
175 drv
->renderTriangles(_Material
, 0, _CurrentNumTriangles
);
179 _CurrentNumVertices
= 0;
180 _CurrentNumTriangles
= 0;