llrender.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. /**
  2. * @file llrender.h
  3. * @brief LLRender definition
  4. *
  5. * This class acts as a wrapper for OpenGL calls.
  6. * The goal of this class is to minimize the number of api calls due to legacy
  7. * rendering code, to define an interface for a multiple rendering API
  8. * abstraction of the UI rendering, and to abstract out direct rendering calls
  9. * in a way that is cleaner and easier to maintain.
  10. *
  11. * $LicenseInfo:firstyear=2001&license=viewergpl$
  12. *
  13. * Copyright (c) 2001-2009, Linden Research, Inc.
  14. *
  15. * Second Life Viewer Source Code
  16. * The source code in this file ("Source Code") is provided by Linden Lab
  17. * to you under the terms of the GNU General Public License, version 2.0
  18. * ("GPL"), unless you have obtained a separate licensing agreement
  19. * ("Other License"), formally executed by you and Linden Lab. Terms of
  20. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  21. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  22. *
  23. * There are special exceptions to the terms and conditions of the GPL as
  24. * it is applied to this Source Code. View the full text of the exception
  25. * in the file doc/FLOSS-exception.txt in this software distribution, or
  26. * online at
  27. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  28. *
  29. * By copying, modifying or distributing this software, you acknowledge
  30. * that you have read and understood your obligations described above,
  31. * and agree to abide by those obligations.
  32. *
  33. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  34. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  35. * COMPLETENESS OR PERFORMANCE.
  36. * $/LicenseInfo$
  37. */
  38. #ifndef LL_LLGLRENDER_H
  39. #define LL_LLGLRENDER_H
  40. #include "llcolor4u.h"
  41. #include "llglheaders.h"
  42. #include "llmatrix4a.h"
  43. #include "llpointer.h"
  44. #include "llrect.h"
  45. #include "llstrider.h"
  46. #include "llvector2.h"
  47. #include "llvector3.h"
  48. #include "llvector4.h"
  49. class LLCubeMap;
  50. class LLImageGL;
  51. class LLMatrix4a;
  52. class LLRenderTarget;
  53. class LLGLTexture;
  54. class LLVertexBuffer;
  55. #define LL_MATRIX_STACK_DEPTH 32
  56. constexpr U32 LL_NUM_TEXTURE_LAYERS = 32;
  57. constexpr U32 LL_NUM_LIGHT_UNITS = 8;
  58. class LLTexUnit
  59. {
  60. friend class LLRender;
  61. protected:
  62. LOG_CLASS(LLTexUnit);
  63. public:
  64. typedef enum
  65. {
  66. TT_TEXTURE = 0, // Standard 2D Texture
  67. TT_RECT_TEXTURE, // Non power of 2 texture
  68. TT_CUBE_MAP, // 6-sided cube map texture
  69. TT_CUBE_MAP_ARRAY, // Array of cube maps (PBR renderer only)
  70. TT_MULTISAMPLE_TEXTURE, // See GL_ARB_texture_multisample
  71. TT_NONE // No texture type is currently enabled
  72. } eTextureType;
  73. typedef enum
  74. {
  75. TAM_WRAP = 0, // Standard 2D Texture
  76. TAM_MIRROR, // Non power of 2 texture
  77. TAM_CLAMP // No texture type is currently enabled
  78. } eTextureAddressMode;
  79. typedef enum
  80. { // Note: if mipmapping or anisotropic are not enabled or supported it
  81. // should fall back gracefully.
  82. TFO_POINT = 0, // Equal to: min=point, mag=point, mip=none.
  83. TFO_BILINEAR, // Equal to: min=linear, mag=linear, mip=point.
  84. TFO_TRILINEAR, // Equal to: min=linear, mag=linear, mip=linear.
  85. TFO_ANISOTROPIC // Equal to: min=anisotropic, max=anisotropic, mip=linear.
  86. } eTextureFilterOptions;
  87. typedef enum
  88. {
  89. TMG_NONE = 0, // Mipmaps are not automatically generated.
  90. TMG_AUTO, // Mipmaps are automatically generated.
  91. TMG_MANUAL // Mipmaps are manually generated.
  92. } eMipGeneration;
  93. typedef enum
  94. {
  95. TBS_PREV_COLOR = 0, // Color from the previous texture stage
  96. TBS_PREV_ALPHA,
  97. TBS_ONE_MINUS_PREV_COLOR,
  98. TBS_ONE_MINUS_PREV_ALPHA,
  99. TBS_TEX_COLOR, // Color from the texture bound to this stage
  100. TBS_TEX_ALPHA,
  101. TBS_ONE_MINUS_TEX_COLOR,
  102. TBS_ONE_MINUS_TEX_ALPHA,
  103. TBS_VERT_COLOR, // The vertex color currently set
  104. TBS_VERT_ALPHA,
  105. TBS_ONE_MINUS_VERT_COLOR,
  106. TBS_ONE_MINUS_VERT_ALPHA,
  107. TBS_CONST_COLOR, // The constant color value currently set
  108. TBS_CONST_ALPHA,
  109. TBS_ONE_MINUS_CONST_COLOR,
  110. TBS_ONE_MINUS_CONST_ALPHA
  111. } eTextureBlendSrc;
  112. typedef enum
  113. {
  114. TCS_LINEAR = 0,
  115. TCS_SRGB
  116. } eTextureColorSpace;
  117. LLTexUnit(S32 index);
  118. // Refreshes renderer state of the texture unit to the cached values.
  119. // Needed when the render context has changed and invalidated the
  120. // current state
  121. void refreshState();
  122. // Returns the index of this texture unit
  123. LL_INLINE S32 getIndex() const { return mIndex; }
  124. // Sets this tex unit to be the currently active one
  125. void activate();
  126. // Enables this texture unit for the given texture type
  127. // (automatically disables any previously enabled texture type)
  128. void enable(eTextureType type);
  129. // Disables the current texture unit
  130. void disable();
  131. // Binds the LLImageGL to this texture unit (automatically enables the
  132. // unit for the LLImageGL's texture type)
  133. bool bind(LLImageGL* glimagep, bool force_bind = false, S32 usename = 0);
  134. bool bind(LLGLTexture* gltexp, bool force_bind = false);
  135. // Bind implementation for inner loops which makes the following
  136. // assumptions:
  137. // - No need for gGL.flush()
  138. // - texture is not NULL
  139. // - This gltexp is not being bound redundantly
  140. // - USE_SRGB_DECODE is disabled
  141. // - mTexOptionsDirty is false
  142. void bindFast(LLGLTexture* gltexp);
  143. // Binds a cubemap to this texture unit (automatically enables the
  144. // texture unit for cubemaps)
  145. bool bind(LLCubeMap* cube_map);
  146. // Binds a render target to this texture unit (automatically enables the
  147. // texture unit for the RT's texture type)
  148. bool bind(LLRenderTarget* targetp, bool bind_depth = false);
  149. // Manually binds a texture to the texture unit (automatically enables the
  150. // tex unit for the given texture type)
  151. bool bindManual(eTextureType type, U32 texture, bool has_mips = false);
  152. // Unbinds the currently bound texture of the given type
  153. // (only if there's a texture of the given type currently bound)
  154. void unbind(eTextureType type);
  155. // Fast but unsafe version of unbind
  156. void unbindFast(eTextureType type);
  157. // Sets the addressing mode used to sample the texture.
  158. // Warning: this stays set for the bound texture forever; make sure you
  159. // want to permanently change the address mode for the bound texture.
  160. void setTextureAddressMode(eTextureAddressMode mode);
  161. // Sets the filtering options used to sample the texture.
  162. // Warning: this stays set for the bound texture forever; make sure you
  163. // want to permanently change the filtering for the bound texture.
  164. void setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option);
  165. LL_INLINE U32 getCurrTexture() { return mCurrTexture; }
  166. LL_INLINE eTextureType getCurrType() { return mCurrTexType; }
  167. LL_INLINE void setHasMipMaps(bool has_mips) { mHasMipMaps = has_mips; }
  168. LL_INLINE void setTextureColorSpace(eTextureColorSpace s)
  169. {
  170. mTexColorSpace = s;
  171. }
  172. LL_INLINE eTextureColorSpace getCurColorSpace() { return mTexColorSpace; }
  173. static U32 getInternalType(eTextureType type);
  174. protected:
  175. void debugTextureUnit();
  176. void setColorScale(S32 scale);
  177. void setAlphaScale(S32 scale);
  178. S32 getTextureSource(eTextureBlendSrc src);
  179. S32 getTextureSourceType(eTextureBlendSrc src, bool is_alpha = false);
  180. public:
  181. static U32 sWhiteTexture;
  182. protected:
  183. const S32 mIndex;
  184. U32 mCurrTexture;
  185. eTextureType mCurrTexType;
  186. eTextureColorSpace mTexColorSpace;
  187. S32 mCurrColorScale;
  188. S32 mCurrAlphaScale;
  189. bool mHasMipMaps;
  190. };
  191. class LLLightState
  192. {
  193. friend class LLRender;
  194. public:
  195. LLLightState(S32 index);
  196. void enable();
  197. void disable();
  198. void setDiffuse(const LLColor4& diffuse);
  199. void setDiffuseB(const LLColor4& diffuse);
  200. void setAmbient(const LLColor4& ambient);
  201. void setSpecular(const LLColor4& specular);
  202. void setPosition(const LLVector4& position);
  203. void setConstantAttenuation(F32 atten);
  204. void setLinearAttenuation(F32 atten);
  205. void setQuadraticAttenuation(F32 atten);
  206. void setSpotExponent(F32 exponent);
  207. void setSpotCutoff(F32 cutoff);
  208. void setSpotDirection(const LLVector3& direction);
  209. void setSunPrimary(bool b);
  210. void setSize(F32 size);
  211. void setFalloff(F32 falloff);
  212. protected:
  213. S32 mIndex;
  214. LLColor4 mDiffuse;
  215. LLColor4 mDiffuseB;
  216. LLColor4 mAmbient;
  217. LLColor4 mSpecular;
  218. LLVector4 mPosition;
  219. LLVector3 mSpotDirection;
  220. F32 mConstantAtten;
  221. F32 mLinearAtten;
  222. F32 mQuadraticAtten;
  223. F32 mSpotExponent;
  224. F32 mSpotCutoff;
  225. F32 mSize;
  226. F32 mFalloff;
  227. bool mSunIsPrimary;
  228. bool mEnabled;
  229. };
  230. class LLRender
  231. {
  232. friend class LLLightState;
  233. friend class LLTexUnit;
  234. protected:
  235. LOG_CLASS(LLRender);
  236. public:
  237. typedef enum
  238. {
  239. DIFFUSE_MAP = 0,
  240. ALTERNATE_DIFFUSE_MAP = 1,
  241. NORMAL_MAP = 1,
  242. SPECULAR_MAP = 2,
  243. NUM_TEXTURE_CHANNELS = 3,
  244. } eTexIndex;
  245. enum eVolumeTexIndex : U32
  246. {
  247. LIGHT_TEX = 0,
  248. SCULPT_TEX,
  249. NUM_VOLUME_TEXTURE_CHANNELS,
  250. };
  251. enum eGeomModes : U32
  252. {
  253. TRIANGLES = 0,
  254. TRIANGLE_STRIP,
  255. TRIANGLE_FAN,
  256. POINTS,
  257. LINES,
  258. LINE_STRIP,
  259. LINE_LOOP,
  260. NUM_MODES
  261. };
  262. enum eBlendType : U32
  263. {
  264. BT_ALPHA = 0,
  265. BT_ADD,
  266. BT_ADD_WITH_ALPHA, // Additive blend modulated by the fragment's alpha.
  267. BT_MULT,
  268. BT_MULT_ALPHA,
  269. BT_MULT_X2,
  270. BT_REPLACE
  271. };
  272. // WARNING: this MUST match LL_PART_BF_* values in the llpartdata.h enum !
  273. enum eBlendFactor : U32
  274. {
  275. BF_ONE = 0,
  276. BF_ZERO = 1,
  277. BF_DEST_COLOR = 2,
  278. BF_SOURCE_COLOR = 3,
  279. BF_ONE_MINUS_DEST_COLOR = 4,
  280. BF_ONE_MINUS_SOURCE_COLOR = 5,
  281. BF_DEST_ALPHA = 6,
  282. BF_SOURCE_ALPHA = 7,
  283. BF_ONE_MINUS_DEST_ALPHA = 8,
  284. BF_ONE_MINUS_SOURCE_ALPHA = 9,
  285. BF_UNDEF = 10
  286. };
  287. enum eMatrixMode : U32
  288. {
  289. MM_MODELVIEW = 0,
  290. MM_PROJECTION,
  291. MM_TEXTURE0,
  292. MM_TEXTURE1,
  293. MM_TEXTURE2,
  294. MM_TEXTURE3,
  295. NUM_MATRIX_MODES,
  296. MM_TEXTURE
  297. };
  298. LLRender();
  299. ~LLRender();
  300. void init();
  301. void shutdown();
  302. LL_INLINE bool isValid() { return mValid; }
  303. void initVertexBuffer();
  304. void resetVertexBuffer();
  305. // Refreshes renderer state to the cached values. Needed when the render
  306. // context has changed and invalidated the current state.
  307. void refreshState();
  308. void translatef(F32 x, F32 y, F32 z);
  309. void scalef(F32 x, F32 y, F32 z);
  310. void rotatef(F32 a, F32 x, F32 y, F32 z);
  311. // Requires the generation of a transform matrix involving sine/cosine. If
  312. // rotating by a constant value, use gl_gen_rot(), store the result in a
  313. // static variable, and pass it to rotatef().
  314. void rotatef(const LLMatrix4a& rot);
  315. void ortho(F32 left, F32 right, F32 bottom, F32 top, F32 znear, F32 zfar);
  316. bool projectf(const LLVector3& object, const LLMatrix4a& modelview,
  317. const LLMatrix4a& projection, const LLRect& viewport,
  318. LLVector3& window_coord);
  319. bool unprojectf(const LLVector3& window_coord, const LLMatrix4a& modelview,
  320. const LLMatrix4a& projection, const LLRect& viewport,
  321. LLVector3& object);
  322. void pushMatrix();
  323. void popMatrix();
  324. void loadMatrix(const F32* m);
  325. void loadMatrix(const LLMatrix4a& m);
  326. void loadIdentity();
  327. void multMatrix(const F32* m);
  328. void multMatrix(const LLMatrix4a& m);
  329. void matrixMode(U32 mode);
  330. U32 getMatrixMode();
  331. const LLMatrix4a& getModelviewMatrix();
  332. void syncMatrices();
  333. void syncLightState();
  334. // *HACK: to prevent lighting changes in preview shaders. HB
  335. LL_INLINE void freezeLightState(bool freeze) { mFrozenLights = freeze; }
  336. void translateUI(F32 x, F32 y, F32 z);
  337. void scaleUI(F32 x, F32 y, F32 z);
  338. void pushUIMatrix();
  339. void popUIMatrix();
  340. void loadUIIdentity();
  341. LLVector3 getUITranslation();
  342. LLVector3 getUIScale();
  343. void flush();
  344. void begin(U32 mode);
  345. void end(bool force_flush = false);
  346. void vertex3f(F32 x, F32 y, F32 z);
  347. LL_INLINE void vertex2i(S32 x, S32 y)
  348. {
  349. vertex3f((F32)x, (F32)y, 0.f);
  350. }
  351. LL_INLINE void vertex2f(F32 x, F32 y)
  352. {
  353. vertex3f(x, y, 0.f);
  354. }
  355. LL_INLINE void vertex2fv(const F32* v)
  356. {
  357. vertex3f(v[0], v[1], 0.f);
  358. }
  359. LL_INLINE void vertex3fv(const F32* v)
  360. {
  361. vertex3f(v[0], v[1], v[2]);
  362. }
  363. LL_INLINE void texCoord2i(S32 x, S32 y)
  364. {
  365. mTexcoordsp[mCount].set((F32)x, (F32)y);
  366. }
  367. LL_INLINE void texCoord2f(F32 x, F32 y)
  368. {
  369. mTexcoordsp[mCount].set(x, y);
  370. }
  371. LL_INLINE void texCoord2fv(const F32* tc)
  372. {
  373. texCoord2f(tc[0], tc[1]);
  374. }
  375. void color4ub(U8 r, U8 g, U8 b, U8 a);
  376. LL_INLINE void color4ubv(const U8* c)
  377. {
  378. color4ub(c[0], c[1], c[2], c[3]);
  379. }
  380. LL_INLINE void color4f(F32 r, F32 g, F32 b, F32 a)
  381. {
  382. color4ub((U8)(llclamp(r, 0.f, 1.f) * 255),
  383. (U8)(llclamp(g, 0.f, 1.f) * 255),
  384. (U8)(llclamp(b, 0.f, 1.f) * 255),
  385. (U8)(llclamp(a, 0.f, 1.f) * 255));
  386. }
  387. LL_INLINE void color4fv(const F32* c)
  388. {
  389. color4f(c[0], c[1], c[2], c[3]);
  390. }
  391. LL_INLINE void color3f(F32 r, F32 g, F32 b)
  392. {
  393. color4f(r, g, b, 1);
  394. }
  395. LL_INLINE void color3fv(const F32* c)
  396. {
  397. color4f(c[0], c[1], c[2], 1);
  398. }
  399. void diffuseColor3f(F32 r, F32 g, F32 b);
  400. void diffuseColor3fv(const F32* c);
  401. void diffuseColor4f(F32 r, F32 g, F32 b, F32 a);
  402. void diffuseColor4fv(const F32* c);
  403. void diffuseColor4ubv(const U8* c);
  404. void diffuseColor4ub(U8 r, U8 g, U8 b, U8 a);
  405. void lineWidth(F32 width);
  406. void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count);
  407. void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs,
  408. S32 vert_count);
  409. void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs,
  410. LLColor4U*, S32 vert_count);
  411. void setColorMask(bool write_color, bool write_alpha);
  412. void setColorMask(bool write_red, bool write_green, bool write_blue,
  413. bool write_alpha);
  414. void setSceneBlendType(U32 type);
  415. // Applies blend func to both color and alpha
  416. void blendFunc(U32 sfactor, U32 dfactor);
  417. // Applies separate blend functions to color and alpha
  418. void blendFunc(U32 color_sfactor, U32 color_dfactor, U32 alpha_sfactor,
  419. U32 alpha_dfactor);
  420. LLLightState* getLight(U32 index);
  421. void setAmbientLightColor(const LLColor4& color);
  422. LLTexUnit* getTexUnit(U32 index);
  423. LL_INLINE U32 getCurrentTexUnitIndex() const { return mCurrTextureUnitIndex; }
  424. bool verifyTexUnitActive(U32 unit_to_verify);
  425. void debugTexUnits();
  426. void cleanupVertexBufferCache(U32 current_frame);
  427. private:
  428. static void APIENTRY debugCallback(GLenum, GLenum type, GLuint id,
  429. GLenum severity, GLsizei,
  430. const GLchar* message, GLvoid*);
  431. public:
  432. static U32 sCurrentFrame;
  433. static bool sGLCoreProfile;
  434. static bool sUseBufferCache;
  435. private:
  436. alignas(16) LLMatrix4a mMatrix[NUM_MATRIX_MODES][LL_MATRIX_STACK_DEPTH];
  437. U32 mMatIdx[NUM_MATRIX_MODES];
  438. U32 mMatHash[NUM_MATRIX_MODES];
  439. U32 mCurMatHash[NUM_MATRIX_MODES];
  440. U32 mMatrixMode;
  441. U32 mLightHash;
  442. LLColor4 mAmbientLightColor;
  443. U32 mDummyVAO;
  444. U32 mCacheMissCount;
  445. U32 mCount;
  446. U32 mMode;
  447. U32 mCurrTextureUnitIndex;
  448. U32 mCurrBlendColorSFactor;
  449. U32 mCurrBlendColorDFactor;
  450. U32 mCurrBlendAlphaSFactor;
  451. U32 mCurrBlendAlphaDFactor;
  452. LLPointer<LLVertexBuffer> mBuffer;
  453. LLStrider<LLVector3> mVerticesp;
  454. LLStrider<LLVector2> mTexcoordsp;
  455. LLStrider<LLColor4U> mColorsp;
  456. LLTexUnit* mDummyTexUnit;
  457. std::vector<LLTexUnit*> mTexUnits;
  458. std::vector<LLLightState*> mLightState;
  459. std::vector<LLVector3> mUIOffset;
  460. std::vector<LLVector3> mUIScale;
  461. bool mCurrColorMask[4];
  462. bool mDirty;
  463. bool mValid;
  464. bool mFrozenLights;
  465. };
  466. extern thread_local LLRender gGL;
  467. extern LLMatrix4a gGLModelView;
  468. extern LLMatrix4a gGLLastModelView;
  469. extern LLMatrix4a gGLDeltaModelView; // For PBR rendering only
  470. extern LLMatrix4a gGLInverseDeltaModelView; // For PBR rendering only
  471. extern LLMatrix4a gGLProjection;
  472. extern LLMatrix4a gGLLastProjection;
  473. extern S32 gGLViewport[4];
  474. // This rotation matrix moves the default OpenGL reference frame
  475. // (-Z at, Y up) to Cory's favorite reference frame (X at, Z up)
  476. static const F32 OGL_TO_CFR_ROTATION[16] =
  477. {
  478. 0.f, 0.f, -1.f, 0.f, // -Z becomes X
  479. -1.f, 0.f, 0.f, 0.f, // -X becomes Y
  480. 0.f, 1.f, 0.f, 0.f, // Y becomes Z
  481. 0.f, 0.f, 0.f, 1.f
  482. };
  483. // Same thing, as an LLMatrix4a...
  484. static const LLMatrix4a OGL_TO_CFR_ROT4A(
  485. LLVector4a( 0.f, 0.f, -1.f, 0.f), // -Z becomes X
  486. LLVector4a(-1.f, 0.f, 0.f, 0.f), // -X becomes Y
  487. LLVector4a( 0.f, 1.f, 0.f, 0.f), // Y becomes Z
  488. LLVector4a( 0.f, 0.f, 0.f, 1.f)
  489. );
  490. // Functions commonly used for OpenGL matrices transformations
  491. LLMatrix4a gl_gen_rot(F32 a, const LLVector4a& axis);
  492. LL_INLINE LLMatrix4a gl_gen_rot(F32 a, F32 x, F32 y, F32 z)
  493. {
  494. return gl_gen_rot(a, LLVector4a(x, y, z));
  495. }
  496. LLMatrix4a gl_ortho(F32 left, F32 right, F32 bottom, F32 top, F32 znear,
  497. F32 zfar);
  498. LLMatrix4a gl_perspective(F32 fovy, F32 aspect, F32 znear, F32 zfar);
  499. #endif