// Ryzom - MMORPG Framework
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
#ifndef NL_VIEW_RENDERER_H
#define NL_VIEW_RENDERER_H
#include "nel/misc/types_nl.h"
#include "nel/misc/rgba.h"
#include "nel/misc/uv.h"
#include "nel/misc/plane.h"
#include "nel/3d/u_texture.h"
#include "nel/3d/u_material.h"
#include "nel/3d/u_text_context.h"
#include "nel/3d/u_driver.h"
#include "nel/3d/frustum.h"
namespace NLGUI
{
// ***************************************************************************
#define VR_NUM_LAYER 32
#define VR_BIAS_LAYER (VR_NUM_LAYER/2)
#define VR_LAYER_MAX (VR_NUM_LAYER-VR_BIAS_LAYER-1)
#define VR_LAYER_MIN (-VR_BIAS_LAYER)
// ***************************************************************************
/**
* class rendering the views
* All the quads of the interface are displayed in the following order
*
* 3--2
* | |
* 0--1
*
* \author Matthieu 'TrapII' Besson
* \author Nevrax France
* \date 2002
*/
class CViewRenderer
{
public:
enum TSystemTexture
{
QuantityCrossTexture= 0,
DefaultBrickTexture,
DefaultItemTexture,
ItemPlanTexture,
SkillTexture,
ItemEnchantedTexture,
DragCopyTexture,
ItemWornedTexture,
OutOfRangeTexture,
RegenTexture,
RegenBackTexture,
GlowStarTexture,
ItemLockedByOwnerTexture,
NumSystemTextures,
};
public:
/** That class hold a texture id. It handle texture id destruction.
* Please use this class in your view and not sint32 to hold a texture id
*/
class CTextureId
{
public:
// Default constructor
CTextureId ()
{
_TextureId = -2;
}
// Destructor call deleteTextureId;
~CTextureId ();
// Set the texture id
bool setTexture (const char *textureName, sint32 offsetX = 0, sint32 offsetY = 0, sint32 width = -1, sint32 height = -1,
bool uploadDXTC=true, bool bReleasable=true);
// Convert in texture id
operator sint32 () const
{
return _TextureId;
}
void serial(NLMISC::IStream &f);
private:
sint32 _TextureId;
};
private:
CViewRenderer();
~CViewRenderer();
public:
static CViewRenderer* getInstance();
/// setup the default values for everything
void setup();
/// init when TextContext and Driver are created
void init();
/// set the driver render states for the interface
void setRenderStates ();
/// Delete all textures and the like and reset the view renderer
void reset();
/// Release the resources of CViewRenderer, and delete the Singleton
static void release();
/// Retrieves the 3d driver we are using
static NL3D::UDriver* getDriver();
/// Sets the current TextContext.
static void setTextContext( NL3D::UTextContext *textcontext );
/// Sets the current driver
static void setDriver( NL3D::UDriver *driver );
/*
* setClipWindow : set the current clipping window
* (this window do not inherit properties from parent or whatever)
*/
void setClipWindow (sint32 x, sint32 y, sint32 w, sint32 h);
/*
* getClipWindow : get the current clipping region
*/
void getClipWindow (sint32 &x, sint32 &y, sint32 &w, sint32 &h)
{
x = _ClipX;
y = _ClipY;
w = _ClipW;
h = _ClipH;
}
/*
* true if the clipping region is empty: clipW or clipH is <=0
*/
bool isClipWindowEmpty() const {return _ClipW<=0 || _ClipH<=0;}
/*
* checkNewScreenSize : check if the opengl screen size. This is SLOW !
* NB: if the window is minimized (w==h==0), then the old screen size is kept, and isMinimized() return true
*/
void checkNewScreenSize ();
/*
* getScreenSize : get the screen window size changed (at last checkNewScreenSize called)
*/
void getScreenSize(uint32 &w, uint32 &h);
/*
* get OOW / OOH
*/
void getScreenOOSize (float &oow, float &ooh);
/*
* is the Screen minimized?
*/
bool isMinimized() const {return _IsMinimized;}
/*
* drawBitmap : this is the interface with all the views
*
*/
void drawRotFlipBitmap (sint layerId, sint32 x, sint32 y, sint32 width, sint32 height, uint8 rot, bool flipv,
sint32 nTxId, const NLMISC::CRGBA &col = NLMISC::CRGBA(255,255,255,255));
/*
* Draw a simple wired quad. No flushing is done as the draw is done instantly (usually for debug)
*/
void drawWiredQuad(sint32 x, sint32 y, sint32 width, sint32 height, NLMISC::CRGBA col = NLMISC::CRGBA::White);
/*
* Draw a simple filled quad. No flushing is done as the draw is done instantly (usually for debug)
*/
void drawFilledQuad(sint32 x, sint32 y, sint32 width, sint32 height, NLMISC::CRGBA col = NLMISC::CRGBA::White);
/*
* drawBitmap : Tiled version
* \param tileOrigin 2 bits 1 - Left/Right (0/1) 2 - Bottom/Top (0/1) (0-BL)(1-BR)(2-TL)(3-TR)
*
*/
void drawRotFlipBitmapTiled (sint layerId, sint32 x, sint32 y, sint32 width, sint32 height, uint8 rot, bool flipv,
sint32 nTxId, uint tileOrigin, const NLMISC::CRGBA &col = NLMISC::CRGBA(255,255,255,255));
/*
* drawBitmap : draw a bitmap roted by 90 degrees in CW 'rot times'
* flipv is a boolean that indicates if there is a vertical flip
* this is a 1:1 ratio so if texture is x long there are x pixels on screen
*/
void draw11RotFlipBitmap (sint layerId, sint32 x, sint32 y, uint8 rot, bool flipv, sint32 nTxId,
const NLMISC::CRGBA &col = NLMISC::CRGBA(255,255,255,255));
/** Draw an arbitrary quad (fast version) , possibly clipping it. Unlike draw11RotFlipBitmap & the like, texture is filtered here.
* quads are all batched in the same render layer
*/
void drawQuad(sint layerId, const NLMISC::CQuadUV &quadUV, sint32 nTxId,
NLMISC::CRGBA col, bool additif, bool filtered = true);
/** Draw a set of untextured triangle in the given layer. all triangles of the same layer are batched
*/
void drawUnclippedTriangles(sint layerId, const std::vector &tris, NLMISC::CRGBA col);
/*
* Draw a text
*/
void drawText (sint layerId, float x, float y, uint wordIndex, float xmin, float ymin, float xmax, float ymax, NL3D::UTextContext &textContext);
/*
* loadTextures : load all textures associated with the interface
* this function add a globaltexture to the vector of global textures
*/
bool loadTextures (const std::string &textureFileName, const std::string &uvFileName, bool uploadDXTC);
/*
* createTexture : create a texture for the interface, possibly from an externally created texture
* If no external texture is given, then 'sGlobalTextureName' is the filename of the big texture
* You should call deleteTexture when the texture is not used anymore
* The method returns the texture id of the new texture
*/
sint32 createTexture (const std::string &sGlobalTextureName, // unique id identifying this big texture, (its filename if not externally created)
sint32 offsetX = 0,
sint32 offsetY = 0,
sint32 width = -1,
sint32 height = -1,
bool uploadDXTC=true,
bool bReleasable=true
);
// change position of a sub-texture (inside its big texture) from the sub-texture filename
void updateTexturePos(const std::string &texturefileName,
sint32 offsetX = 0,
sint32 offsetY = 0,
sint32 width = -1,
sint32 height = -1
);
/** Add / change a global texture from an externally created texture
* \param defaultTexWidth width to used when CTextureId::createTexture is used without giving the width (e.g width = -1), useful for cropped textures
* \param defaultTexHeight height to used when CTextureId::createTexture is used without giving the height (e.g height = -1), useful for cropped textures
*/
void setExternalTexture(const std::string &sGlobalTextureName,
NL3D::UTexture *externalTexture = NULL,
uint32 externalTexWidth = 1,
uint32 externalTexHeight = 1,
uint32 defaultTexWidth = 1,
uint32 defaultTexHeight = 1
);
/*
* deleteTexture : create a texture for the interface
*/
void deleteTexture (sint32 textureId);
// get a global texture pointer from its name
NL3D::UTexture *getGlobalTexture(const std::string &name);
/*
* Flush all parsed view and computed strings to screen
*/
void flush ();
/// Retrives a texture
bool getTexture( NLMISC::CBitmap &bm, const std::string &name );
/// Retrieve the texture names
void getTextureNames( std::vector< std::string > &textures );
/**
* get a texture file pointer from a string name. O(logN)
* \param id : the id of the texture
* \return a texture file pointer. -1 if not found or if sName is empty()
*/
sint32 getTextureIdFromName (const std::string &sName) const;
std::string getTextureNameFromId (sint32 TxID);
void getTextureSizeFromId (sint32 id, sint32 &width, sint32 &height);
NLMISC::CRGBA getTextureColor(sint32 id, sint32 x, sint32 y);
/**
* \return the texture associated with the param figur
*/
sint32 getFigurTextureId(uint index)
{
nlassert(index < 10);
return _IndexesToTextureIds[index];
}
/**
* \return the texture for figur separator '-'
*/
sint32 getFigurSeparator() const { return _FigurSeparatorTextureId; }
sint32 getFigurTextureW() const {return _WFigurTexture;}
sint32 getFigurTextureH() const {return _HFigurTexture;}
sint32 getFigurSeparatorW() const {return _WFigurSeparatorTexture;}
sint32 getFigurSeparatorH() const {return _HFigurSeparatorTexture;}
sint32 getFigurBlankTextureId ()
{
return _FigurBlankId;
}
sint32 getBlankTextureId ()
{
return _BlankId;
}
sint32 getTypoTextureW(char c);
sint32 getTypoTextureH(char c);
sint32 getTypoTextureId(char c);
/// System Texture Manager. Used to avoid storing an id in each Ctrl for some texture code is aware of
// @{
sint32 getSystemTextureId(TSystemTexture e) const {return _SystemTextures[e].Id;}
sint32 getSystemTextureW(TSystemTexture e) const {return _SystemTextures[e].W;}
sint32 getSystemTextureH(TSystemTexture e) const {return _SystemTextures[e].H;}
// @}
/// For string rendering, get the RenderBuffer to the specified layer
NL3D::URenderStringBuffer *getStringRenderBuffer(sint layerId);
/** Custom Rendering Interface
* Note that this function is EXTREMLY SLOW so it should be used with care
* This function flush the quad cache, clip the quad passed with current clipping region
* and draw (with drawQuedUV2) it with the material passed in parameter. There is no cache operation done.
* uv used are from (0,0) -> (1,1) for the 2 stages
*/
void drawCustom (sint32 x, sint32 y, sint32 width, sint32 height, NLMISC::CRGBA col, NL3D::UMaterial Mat);
// Same but we can control uv mapping of first stage
void drawCustom (sint32 x, sint32 y, sint32 width, sint32 height,
const NLMISC::CUV &uv0Min, const NLMISC::CUV &uv0Max,
NLMISC::CRGBA col, NL3D::UMaterial Mat);
// Same but we can control uv mapping of 2 stages
void drawCustom (sint32 x, sint32 y, sint32 width, sint32 height,
const NLMISC::CUV &uv0Min, const NLMISC::CUV &uv0Max, const NLMISC::CUV &uv1Min, const NLMISC::CUV &uv1Max,
NLMISC::CRGBA col, NL3D::UMaterial Mat);
// **** World space interface methods
/** Set the current Z in projCenter.z.
* If you want to scale the window position, set a scale!=1. projCenter.x/y is used as the
* pivot (in window coordinates)
*/
void setInterfaceDepth (const NLMISC::CVector &projCenter, float scale);
// Activate world space transformation
void activateWorldSpaceMatrix (bool activate);
// Set the screen to world space matrix
void setWorldSpaceFrustum (const NL3D::CFrustum &cameraFrustum);
// Get the current Frustum
const NL3D::CFrustum &getFrustum () const
{
return _CameraFrustum;
}
private:
/**
* init the map _IndexesToTextures
*/
void initIndexesToTextureIds ();
void initTypo ();
bool needClipping (const NLMISC::CQuad &q);
void clip (NLMISC::CQuadColorUV &qout, const NLMISC::CQuadColorUV &qin, uint rot);
void clip (NLMISC::CQuadColorUV2 &qout, const NLMISC::CQuadColorUV2 &qin);
private:
// A layer is a vector of Quads.
class CLayer
{
public:
// unfiltered quads
std::vector Quads;
uint32 NbQuads;
std::vector Tris;
// filtered alpha blended quads
std::vector FilteredAlphaBlendedQuads;
// filtered alpha blended tris
std::vector FilteredAlphaBlendedTris;
// filtered additif blended quads
std::vector FilteredAdditifQuads;
// filtered additif blended tris
std::vector FilteredAdditifTris;
CLayer()
{
NbQuads= 0;
}
};
// SGlobalTexture is a texture that regroup other texture. We store also current quads to render
struct SGlobalTexture
{
SGlobalTexture ()
{
FromGlobaleTexture = true;
}
uint32 Width, Height;
uint32 DefaultWidth, DefaultHeight;
NL3D::UTexture *Texture;
std::string Name;
bool FromGlobaleTexture;
// Array of layers
CLayer Layers[VR_NUM_LAYER];
};
// For each Layer, store a string Buffer
NL3D::URenderStringBuffer *_StringRBLayers[VR_NUM_LAYER];
// For each Layer, tells if empty or not
bool _EmptyLayer[VR_NUM_LAYER];
// SImage is one texture of the SGlobalTexture textures
struct SImage
{
std::string Name;
SGlobalTexture *GlobalTexturePtr;
NLMISC::CUV UVMin, UVMax;
// Assign UV of this image to a quad depending on the flip and rot
void setupQuadUV(bool flipv, uint8 rot, NLMISC::CQuadColorUV &dest);
};
// ***************************************************************************
// \name Texture management
// ***************************************************************************
// SImage accessors
SImage *getSImage(sint32 textureId)
{
return &(*(_SImageIterators[textureId]));
}
// Add a SImage
sint32 addSImage(const SImage &image)
{
uint i;
for (i=0; i<_SImageIterators.size(); i++)
{
// Free ?
if (_SImageIterators[i] == _SImages.end())
break;
}
// Nothing free ?
if (i == _SImageIterators.size())
_SImageIterators.push_back(_SImages.end());
_SImages.push_back(image);
_SImageIterators[i] = _SImages.end();
_SImageIterators[i]--;
return (sint32)i;
}
// Remove a SImage
void removeSImage(sint32 textureId)
{
// Allocated ?
nlassert (_SImageIterators[textureId] != _SImages.end());
// Remove the image
_SImages.erase (_SImageIterators[textureId]);
// Remove the index entry
_SImageIterators[textureId] = _SImages.end();
}
typedef std::list TGlobalTextureList;
typedef std::list TSImageList;
typedef std::vector::iterator> TSImageIterator;
// List of global textures
TGlobalTextureList _GlobalTextures;
// List of SImage
TSImageList _SImages;
// Array used to convert a texture ID in _SImages iterator
TSImageIterator _SImageIterators;
// ***************************************************************************
typedef std::map TTextureMap;
TTextureMap _TextureMap;
NL3D::UMaterial _Material;
// Clip & screen system
sint32 _ClipX, _ClipY, _ClipW, _ClipH;
float _XMin, _XMax, _YMin, _YMax;
sint32 _ScreenW, _ScreenH;
float _OneOverScreenW, _OneOverScreenH;
bool _IsMinimized;
//map linking a uint to a bitmap. Used to display figurs
std::vector _IndexesToTextureIds;
sint32 _FigurSeparatorTextureId;
sint32 _FigurBlankId, _BlankId;
sint32 _WFigurTexture;
sint32 _HFigurTexture;
sint32 _WFigurSeparatorTexture;
sint32 _HFigurSeparatorTexture;
NLMISC::CUV _BlankUV;
SGlobalTexture *_BlankGlobalTexture;
// System textures
class CSystemTexture
{
public:
sint32 Id;
sint32 W;
sint32 H;
CSystemTexture()
{
Id= -1;
W= H= 0;
}
};
CSystemTexture _SystemTextures[NumSystemTextures];
// Typo texture
enum
{
NumTypoChar= 127,
};
sint32 _TypoCharToTextureIds[NumTypoChar];
sint32 _TypoCharWs[NumTypoChar];
sint32 _TypoH;
void addSystemTexture(TSystemTexture e, const char *s);
void initSystemTextures();
/**
* put a new quad in the cache (call flush if texture different)
*/
void putQuadInLayer (SGlobalTexture >, sint layerId, const NLMISC::CQuadColorUV &qcoluv, uint rot);
// World space interface methods
void worldSpaceTransformation (NLMISC::CQuadColorUV &qcoluv);
bool _WorldSpaceTransformation; // Transform into world space
float _CurrentZ; // Current z used for the scene
NL3D::CFrustum _CameraFrustum; // Transform from screen space to world space
NLMISC::CMatrix _WorldSpaceMatrix; // Matrix to be applied for world space transformation
bool _WorldSpaceScale;
static CViewRenderer *instance;
static NL3D::UDriver *driver;
static NL3D::UTextContext *textcontext;
typedef CHashMap< std::string, NL3D::UTextContext* > TFontsList;
static TFontsList fonts;
public:
static NL3D::UTextContext* getTextContext(const std::string &name="");
static bool registerFont(const std::string &name, const std::string &font);
/// Set of hw cursor images
static std::set< std::string > *hwCursors;
static float hwCursorScale;
};
}
#endif // NL_VIEW_RENDERER_H
/* End of view_renderer.h */