2 * \file nelrenderer.cpp
4 * \author Matt Raykowski
8 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
9 // Copyright (C) 2010 Winch Gate Property Limited
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU Affero General Public License as
13 // published by the Free Software Foundation, either version 3 of the
14 // License, or (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Affero General Public License for more details.
21 // You should have received a copy of the GNU Affero General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
25 /************************************************************************
26 purpose: Implementation of Renderer class for Nevrax engine
28 For use with GUI Library:
29 Crazy Eddie's GUI System (http://crayzedsgui.sourceforge.net)
30 Copyright (C)2004 Paul D Turner (crayzed@users.sourceforge.net)
32 This file contains code that is specific to NeL (http://www.nevrax.org)
33 *************************************************************************/
35 #include "CEGUIImagesetManager.h"
36 #include "CEGUIImageset.h"
37 #include "CEGUIImage.h"
38 #include "CEGUIExceptions.h"
39 #include "CEGUISystem.h"
40 #include "CEGUIEventArgs.h"
41 #include "CEGUIImageCodec.h"
42 #include "CEGUIDynamicModule.h"
44 #include <nel/misc/dynloadlib.h>
46 //#include <nel/cegui/inelrenderer.h>
47 #include <nel/cegui/nelrenderer.h>
48 #include <nel/cegui/neltexture.h>
49 #include <nel/cegui/nelresourceprovider.h>
51 #include <nel/3d/u_material.h>
52 #include <nel/3d/u_driver.h>
54 #include <nel/cegui/inellibrary.h>
64 #define STRINGIZE(X) S_(X)
68 //class CCeguiRendererNelLibrary : public NLMISC::INelLibrary {
69 // void onLibraryLoaded(bool /* firstTime */) { }
70 // void onLibraryUnloaded(bool /* lastTime */) { }
72 NLMISC_DECL_PURE_LIB(CCeguiRendererNelLibrary
)
74 #endif /* #ifndef NL_STATIC */
77 * Sound driver instance creation
81 // ******************************************************************
84 Renderer
* createNeLRendererInstance
86 __declspec(dllexport
) CEGUI::Renderer
*createNeLRendererInstance
88 (NL3D::UDriver
*driver
, bool withRP
=true)
90 return new CEGUI::NeLRenderer(driver
, withRP
);
93 // ******************************************************************
95 #elif defined (NL_OS_UNIX)
99 CEGUI::Renderer
*createNeLRendererInstance(NL3D::UDriver
*driver
, bool withRP
=true)
101 return new CEGUI::NeLRenderer(driver
, withRP
);
107 // Start of CEGUI namespace section
112 /*************************************************************************
113 Constants definitions
114 *************************************************************************/
115 const int NeLRenderer::VERTEX_PER_QUAD
= 4;
116 const int NeLRenderer::VERTEX_PER_TRIANGLE
= 3;
117 const int NeLRenderer::VERTEXBUFFER_CAPACITY
= 4096;
119 NeLRenderer::NeLRenderer(NL3D::UDriver
*driver
, bool withRP
, ImageCodec
* codec
)
123 NL3D::UDriver::CMode mode
;
124 driver
->getCurrentScreenMode(mode
);
125 d_display_area
.d_left
=0;
126 d_display_area
.d_top
=0;
127 d_display_area
.d_right
=(float)driver
->getWindowWidth();
128 d_display_area
.d_bottom
=(float)driver
->getWindowHeight();
129 m_InputDriver
.addToServer(m_Driver
->EventServer
);
130 m_InputDriver
.setScreenMode(d_display_area
.getWidth(),d_display_area
.getHeight(),(float)mode
.Depth
);
131 m_InputDriver
.setDriver(m_Driver
);
132 NLMISC::CHTimer::startBench();
133 m_NelProvider
=withRP
;
135 m_ImageCodec
= codec
;
136 m_ImageCodecModule
= NULL
;
142 NeLRenderer::~NeLRenderer(void)
144 destroyAllTextures();
146 m_InputDriver
.removeFromServer(m_Driver
->EventServer
);
147 NLMISC::CHTimer::clear();
150 // void NeLRenderer::addSearchPath(const std::string &path, bool recurse, bool alternative, class NLMISC::IProgressCallback *progressCallBack) {
151 // NLMISC::CPath::addSearchPath(path.c_str(),recurse,alternative,progressCallBack);
154 void NeLRenderer::addQuad(const Rect
& dest_rect
, float z
, const Texture
* tex
, const Rect
& texture_rect
, const ColourRect
& colours
, QuadSplitMode quad_split_mode
)
156 using namespace NLMISC
;
157 H_AUTO(NeLRenderer_addQuad
);
160 * Special note: quad splitting is not yet supported.
163 NLMISC::CQuadColorUV nelquad
;
165 NeLTexture
*text
=(NeLTexture
*)tex
;
166 // set quad position, flipping y co-ordinates, and applying appropriate texel origin offset
167 Rect position
=dest_rect
;
168 position
.offset(Point(-0.5f
, -0.5f
));
170 nelquad
.V0
.set(position
.d_left
, position
.d_top
, z
);
171 nelquad
.Uv0
.set(texture_rect
.d_left
, texture_rect
.d_top
);
172 nelquad
.Color0
=colorToNeL(colours
.d_bottom_left
);
175 nelquad
.V1
.set(position
.d_right
, position
.d_top
, z
);
176 nelquad
.Uv1
.set(texture_rect
.d_right
, texture_rect
.d_top
);
177 nelquad
.Color1
=colorToNeL(colours
.d_bottom_right
);
180 nelquad
.V2
.set(position
.d_right
, position
.d_bottom
, z
);
181 nelquad
.Uv2
.set(texture_rect
.d_right
, texture_rect
.d_bottom
);
182 nelquad
.Color2
=colorToNeL(colours
.d_top_right
);
185 nelquad
.V3
.set(position
.d_left
, position
.d_bottom
, z
);
186 nelquad
.Uv3
.set(texture_rect
.d_left
, texture_rect
.d_bottom
);
187 nelquad
.Color3
=colorToNeL(colours
.d_top_left
);
190 renderQuad(nelquad
,text
->getNeLTexture());
192 QuadVector::reverse_iterator itr
= d_quadlist
.rbegin();
193 if((d_quadlist
.size() > 0) && ((*itr
).texture
== text
)) {
194 (*itr
).quads
.push_back(nelquad
);
198 qI
.quads
.push_back(nelquad
);
199 d_quadlist
.push_back(qI
);
204 void NeLRenderer::renderQuad(NLMISC::CQuadColorUV quad
, NL3D::UMaterial mat
) {
205 using namespace NLMISC
;
206 H_AUTO(NeLRenderer_renderQuad
);
207 m_Driver
->setFrustum(NL3D::CFrustum(0, d_display_area
.getWidth(), d_display_area
.getHeight(), 0, -1, 1, false));
208 m_Driver
->drawQuad(quad
,mat
);
211 void NeLRenderer::doRender(void)
213 using namespace NLMISC
;
214 H_AUTO(NeLRenderer_doRender
);
216 // set the culling frustrum
217 m_Driver
->setFrustum(NL3D::CFrustum(0, d_display_area
.getWidth(), d_display_area
.getHeight(), 0, -1, 1, false));
219 // and go through the list.
220 for(QuadVector::iterator itr
=d_quadlist
.begin();itr
!=d_quadlist
.end();itr
++) {
221 NL3D::UMaterial mat
= (*itr
).texture
->getNeLTexture();
222 m_Driver
->drawQuads((*itr
).quads
,mat
);
226 if(m_FrameCount
==200) {
228 NLMISC::CHTimer::displaySummary();
229 nlinfo("Quad list size: %d", d_quadlist
.size());
235 void NeLRenderer::clearRenderList(void)
240 Texture
*NeLRenderer::createTexture(void)
243 NeLTexture
*tex
=new NeLTexture(this);
244 d_texturelist
.push_back((NeLTexture
*const)tex
);
248 Texture
*NeLRenderer::createTexture(const String
&filename
, const String
&resourceGroup
)
250 NeLTexture
*tex
=(NeLTexture
*)createTexture();
251 tex
->loadFromFile(filename
, resourceGroup
);
255 Texture
*NeLRenderer::createTexture(float size
)
257 NeLTexture
* tex
= (NeLTexture
*)createTexture();
262 void NeLRenderer::destroyTexture(Texture
* texture
)
266 NeLTexture
*tex
=(NeLTexture
*)texture
;
267 d_texturelist
.remove((NeLTexture
*const)tex
);
272 void NeLRenderer::destroyAllTextures(void)
274 while(!d_texturelist
.empty())
276 destroyTexture((Texture
*)*(d_texturelist
.begin()));
280 void NeLRenderer::sortQuads(void)
285 void NeLRenderer::setQueueingEnabled(bool setting
) {
286 d_queueing
= setting
;
289 bool NeLRenderer::isQueueingEnabled(void) const {
293 NLMISC::CRGBA
NeLRenderer::colorToNeL(CEGUI::colour color
) {
295 ctmp
.set((uint8
)(color
.getRed()*255),(uint8
)(color
.getGreen()*255),(uint8
)(color
.getBlue()*255),(uint8
)(color
.getAlpha()*255));
299 ResourceProvider
* NeLRenderer::createResourceProvider(void)
301 if(d_resourceProvider
==0) {
302 //if(m_NelProvider) {
303 d_resourceProvider
= new NeLResourceProvider();
305 // d_resourceProvider = new DefaultResourceProvider();
308 return d_resourceProvider
;
311 ImageCodec
&NeLRenderer::getImageCodec(void) {
312 return *m_ImageCodec
;
315 void NeLRenderer::setImageCodec(const String
&codecName
) {
316 setupImageCodec(codecName
);
319 void NeLRenderer::setImageCodec(ImageCodec
*codec
) {
322 m_ImageCodec
= codec
;
323 m_ImageCodecModule
= 0;
327 void NeLRenderer::setupImageCodec(const String
& codecName
) {
328 // Cleanup the old image codec
332 // Test whether we should use the default codec or not
333 if(codecName
.empty())
334 m_ImageCodecModule
= new DynamicModule(String("CEGUI") + m_DefaultImageCodecName
);
336 m_ImageCodecModule
= new DynamicModule(String("CEGUI") + codecName
);
338 // Create the codec object itself
339 ImageCodec
* (*createFunc
)(void) = (ImageCodec
* (*)(void))m_ImageCodecModule
->getSymbolAddress("createImageCodec");
340 m_ImageCodec
= createFunc();
343 void NeLRenderer::cleanupImageCodec() {
344 if (m_ImageCodec
&& m_ImageCodecModule
) {
345 void(*deleteFunc
)(ImageCodec
*) = (void(*)(ImageCodec
*))m_ImageCodecModule
->getSymbolAddress("destroyImageCodec");
346 deleteFunc(m_ImageCodec
);
348 delete m_ImageCodecModule
;
349 m_ImageCodecModule
= 0;
353 String
NeLRenderer::m_DefaultImageCodecName("DevILImageCodec");
354 } // end namespace CEGUI