TGX 1.0.5
A tiny 2D/3D graphics library optimized for 32 bits microcontrollers.
Loading...
Searching...
No Matches
Renderer3D.h
Go to the documentation of this file.
1
5//
6// Copyright 2020 Arvind Singh
7//
8// This library is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Lesser General Public
10// License as published by the Free Software Foundation; either
11//version 2.1 of the License, or (at your option) any later version.
12//
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU
16// Lesser General Public License for more details.
17//
18// You should have received a copy of the GNU Lesser General Public
19// License along with this library; If not, see <http://www.gnu.org/licenses/>.
20
21#ifndef _TGX_RENDERER3D_H_
22#define _TGX_RENDERER3D_H_
23
24// only C++, no plain C
25#ifdef __cplusplus
26
27
28#include "Misc.h"
29#include "Color.h"
30#include "Vec2.h"
31#include "Vec3.h"
32#include "Vec4.h"
33#include "Box2.h"
34#include "Box3.h"
35#include "Mat4.h"
36#include "Image.h"
37
38#include "Shaders.h"
39#include "Rasterizer.h"
40
41#include "Mesh3D.h"
42
43
44
45
46
47
48
49
50namespace tgx
51{
52
53 // forward declaration for the vertices and faces of the unit cube [-1,1]^3
54
55 extern const tgx::fVec3 UNIT_CUBE_VERTICES[8];
56 extern const tgx::fVec3 UNIT_CUBE_NORMALS[6];
57 extern const uint16_t UNIT_CUBE_FACES[6*4];
58 extern const uint16_t UNIT_CUBE_FACES_NORMALS[6 * 4];
59
60
61
111 template<typename color_t, Shader LOADED_SHADERS = TGX_SHADER_MASK_ALL, typename ZBUFFER_t = float>
113 {
114
115
116 static constexpr int MAXVIEWPORTDIMENSION = 2048 * (1 << ((8 - TGX_RASTERIZE_SUBPIXEL_BITS) >> 1));
117
118 static_assert(is_color<color_t>::value, "color_t must be one of the color types defined in color.h");
119 static_assert((std::is_same<ZBUFFER_t, float>::value) || (std::is_same<ZBUFFER_t, uint16_t>::value), "The Z-buffer type must be either float or uint16_t");
120
121 // true if some kind of texturing may be used.
122 static constexpr int ENABLE_TEXTURING = (TGX_SHADER_HAS_ONE_FLAG(LOADED_SHADERS , (SHADER_TEXTURE | TGX_SHADER_MASK_TEXTURE_MODE | TGX_SHADER_MASK_TEXTURE_QUALITY)));
123
124 static constexpr Shader ENABLED_SHADERS = LOADED_SHADERS | (ENABLE_TEXTURING ? SHADER_TEXTURE : SHADER_NOTEXTURE); // enable texturing when at least one texturing related flag is set
125
126 // check that disabled shaders do not completely disable all drawing operations.
127 static_assert(TGX_SHADER_HAS_ONE_FLAG(ENABLED_SHADERS,TGX_SHADER_MASK_PROJECTION), "At least one of the two shaders SHADER_PERSPECTIVE or SHADER_ORTHO must be enabled");
128 static_assert(TGX_SHADER_HAS_ONE_FLAG(ENABLED_SHADERS,TGX_SHADER_MASK_ZBUFFER), "At least one of the two shaders SHADER_NOZBUFFER or SHADER_ZBUFFER must be enabled");
129 static_assert(TGX_SHADER_HAS_ONE_FLAG(ENABLED_SHADERS,TGX_SHADER_MASK_SHADING), "At least one of the two shaders SHADER_FLAT or SHADER_GOURAUD must be enabled");
130 static_assert(TGX_SHADER_HAS_ONE_FLAG(ENABLED_SHADERS,TGX_SHADER_MASK_TEXTURE), "At least one of the two shaders SHADER_TEXTURE or SHADER_NOTEXTURE must be enabled");
131 static_assert((~(TGX_SHADER_HAS_TEXTURE(ENABLED_SHADERS))) || (TGX_SHADER_HAS_ONE_FLAG(ENABLED_SHADERS,TGX_SHADER_MASK_TEXTURE_QUALITY)),"When using texturing, at least one of the two shaders SHADER_TEXTURE_BILINEAR or SHADER_TEXTURE_NEAREST must be enabled");
132 static_assert((~(TGX_SHADER_HAS_TEXTURE(ENABLED_SHADERS))) || (TGX_SHADER_HAS_ONE_FLAG(ENABLED_SHADERS, TGX_SHADER_MASK_TEXTURE_MODE)), "When using texturing, at least one of the two shaders SHADER_TEXTURE_WRAP_POW2 or SHADER_TEXTURE_CLAMP must be enabled");
133
134
135
136 public:
137
138
148 TGX_NOINLINE Renderer3D(const iVec2& viewportSize = {0,0}, Image<color_t> * im = nullptr, ZBUFFER_t * zbuffer = nullptr);
149
150
151
152
153 /*****************************************************************************************
154 *****************************************************************************************/
161 /*****************************************************************************************
162 ******************************************************************************************/
163
164
185 void setViewportSize(int lx, int ly);
186
187
195 void setViewportSize(const iVec2& viewport_dim);
196
197
210
211
230 void setOffset(int ox, int oy);
231
232
240 void setOffset(const iVec2& offset);
241
242
261
262
269
270
277
278
285
286
303 void setOrtho(float left, float right, float bottom, float top, float zNear, float zFar);
304
305
322 void setFrustum(float left, float right, float bottom, float top, float zNear, float zFar);
323
324
342 void setPerspective(float fovy, float aspect, float zNear, float zFar);
343
344
362 void setCulling(int w);
363
364
377 void setZbuffer(ZBUFFER_t* zbuffer);
378
379
389
390
426 void setShaders(Shader shaders);
427
428
437
438
447
448
449
451 /*****************************************************************************************
452 *****************************************************************************************/
459 /*****************************************************************************************
460 ******************************************************************************************/
461
462
463
480 void setViewMatrix(const fMat4& M);
481
482
491
492
504 void setLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ);
505
506
518 void setLookAt(const fVec3 eye, const fVec3 center, const fVec3 up);
519
520
534
535
548
549
559 void setLightDirection(const fVec3& direction);
560
561
571 void setLightAmbiant(const RGBf& color);
572
573
583 void setLightDiffuse(const RGBf& color);
584
585
595 void setLightSpecular(const RGBf& color);
596
597
612 void setLight(const fVec3 direction, const RGBf& ambiantColor, const RGBf& diffuseColor, const RGBf& specularColor);
613
614
615
616
617
619 /*****************************************************************************************
620 *****************************************************************************************/
627 /*****************************************************************************************
628 ******************************************************************************************/
629
630
631
642 void setModelMatrix(const fMat4& M);
643
644
653
654
676 void setModelPosScaleRot(const fVec3& center = fVec3{ 0,0,0 }, const fVec3& scale = fVec3(1, 1, 1), float rot_angle = 0, const fVec3& rot_dir = fVec3{ 0,1,0 });
677
678
690
691
704
705
717
718
727 void setMaterialAmbiantStrength(float strenght = 0.1f);
728
729
738 void setMaterialDiffuseStrength(float strenght = 0.6f);
739
740
749 void setMaterialSpecularStrength(float strenght = 0.5f);
750
751
762 void setMaterialSpecularExponent(int exponent = 16);
763
764
777 void setMaterial(RGBf color, float ambiantStrength, float diffuseStrength, float specularStrength, int specularExponent);
778
779
780
781
782
783
784
785
787 /*****************************************************************************************
788 *****************************************************************************************/
802 /*****************************************************************************************
803 ******************************************************************************************/
804
805
806
823 void drawMesh(const Mesh3D<color_t>* mesh, bool use_mesh_material = true, bool draw_chained_meshes = true);
824
825
839 void drawTriangle(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3,
840 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr,
841 const fVec2 * T1 = nullptr, const fVec2 * T2 = nullptr, const fVec2 * T3 = nullptr,
842 const Image<color_t> * texture = nullptr);
843
844
857 void drawTriangleWithVertexColor(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3,
858 const RGBf & col1, const RGBf & col2, const RGBf & col3,
859 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr);
860
861
880 void drawTriangles(int nb_triangles,
881 const uint16_t * ind_vertices, const fVec3 * vertices,
882 const uint16_t * ind_normals = nullptr, const fVec3* normals = nullptr,
883 const uint16_t * ind_texture = nullptr, const fVec2* textures = nullptr,
884 const Image<color_t> * texture_image = nullptr);
885
886
887
903 void drawQuad(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3, const fVec3 & P4,
904 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr, const fVec3 * N4 = nullptr,
905 const fVec2 * T1 = nullptr, const fVec2 * T2 = nullptr, const fVec2 * T3 = nullptr, const fVec2 * T4 = nullptr,
906 const Image<color_t>* texture = nullptr);
907
908
909
925 void drawQuadWithVertexColor(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3, const fVec3 & P4,
926 const RGBf & col1, const RGBf & col2, const RGBf & col3, const RGBf & col4,
927 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr, const fVec3 * N4 = nullptr);
928
929
930
931
952 void drawQuads(int nb_quads,
953 const uint16_t * ind_vertices, const fVec3 * vertices,
954 const uint16_t * ind_normals = nullptr, const fVec3* normals = nullptr,
955 const uint16_t * ind_texture = nullptr, const fVec2* textures = nullptr,
956 const Image<color_t>* texture_image = nullptr);
957
958
959
960
962 /*****************************************************************************************
963 *****************************************************************************************/
970 /*****************************************************************************************
971 ******************************************************************************************/
972
973
974
981 void drawCube();
982
983
1026 const fVec2 v_front_ABCD[4] , const Image<color_t>* texture_front,
1027 const fVec2 v_back_EFGH[4] , const Image<color_t>* texture_back,
1028 const fVec2 v_top_HADE[4] , const Image<color_t>* texture_top,
1029 const fVec2 v_bottom_BGFC[4], const Image<color_t>* texture_bottom,
1030 const fVec2 v_left_HGBA[4] , const Image<color_t>* texture_left,
1031 const fVec2 v_right_DCFE[4] , const Image<color_t>* texture_right
1032 );
1033
1034
1071 const Image<color_t>* texture_front,
1072 const Image<color_t>* texture_back,
1073 const Image<color_t>* texture_top,
1074 const Image<color_t>* texture_bottom,
1075 const Image<color_t>* texture_left,
1076 const Image<color_t>* texture_right
1077 );
1078
1079
1080
1091 void drawSphere(int nb_sectors, int nb_stacks);
1092
1093
1106 void drawSphere(int nb_sectors, int nb_stacks, const Image<color_t>* texture);
1107
1108
1123 void drawAdaptativeSphere(float quality = 1.0f);
1124
1125
1143 void drawAdaptativeSphere(const Image<color_t>* texture, float quality = 1.0f);
1144
1145
1146
1147
1148
1149
1150
1151
1153 /*****************************************************************************************
1154 *****************************************************************************************/
1167 /*****************************************************************************************
1168 ******************************************************************************************/
1169
1170
1171
1183 void drawWireFrameMesh(const Mesh3D<color_t>* mesh, bool draw_chained_meshes = true);
1184
1185
1201 void drawWireFrameMesh(const Mesh3D<color_t>* mesh, bool draw_chained_meshes, float thickness, color_t color, float opacity);
1202
1203
1213 void drawWireFrameLine(const fVec3& P1, const fVec3& P2);
1214
1215
1228 void drawWireFrameLine(const fVec3& P1, const fVec3& P2, float thickness, color_t color, float opacity);
1229
1230
1242 void drawWireFrameLines(int nb_lines, const uint16_t* ind_vertices, const fVec3* vertices);
1243
1244
1259 void drawWireFrameLines(int nb_lines, const uint16_t* ind_vertices, const fVec3* vertices, float thickness, color_t color, float opacity);
1260
1261
1272 void drawWireFrameTriangle(const fVec3& P1, const fVec3& P2, const fVec3& P3);
1273
1274
1289 void drawWireFrameTriangle(const fVec3& P1, const fVec3& P2, const fVec3& P3, float thickness, color_t color, float opacity);
1290
1291
1304 void drawWireFrameTriangles(int nb_triangles, const uint16_t* ind_vertices, const fVec3* vertices);
1305
1306
1323 void drawWireFrameTriangles(int nb_triangles, const uint16_t* ind_vertices, const fVec3* vertices, float thickness, color_t color, float opacity);
1324
1325
1337 void drawWireFrameQuad(const fVec3& P1, const fVec3& P2, const fVec3& P3, const fVec3& P4);
1338
1339
1355 void drawWireFrameQuad(const fVec3& P1, const fVec3& P2, const fVec3& P3, const fVec3& P4, float thickness, color_t color, float opacity);
1356
1357
1371 void drawWireFrameQuads(int nb_quads, const uint16_t* ind_vertices, const fVec3* vertices);
1372
1373
1391 void drawWireFrameQuads(int nb_quads, const uint16_t* ind_vertices, const fVec3* vertices, float thickness, color_t color, float opacity);
1392
1393
1394
1395
1397 /*****************************************************************************************
1398 *****************************************************************************************/
1411 /*****************************************************************************************
1412 ******************************************************************************************/
1413
1414
1423
1424
1438 void drawWireFrameCube(float thickness, color_t color, float opacity);
1439
1440
1452 void drawWireFrameSphere(int nb_sectors, int nb_stacks);
1453
1454
1471 void drawWireFrameSphere(int nb_sectors, int nb_stacks, float thickness, color_t color, float opacity);
1472
1473
1487 void drawWireFrameAdaptativeSphere(float quality = 1.0f);
1488
1489
1508 void drawWireFrameAdaptativeSphere(float quality, float thickness, color_t color, float opacity);
1509
1510
1511
1512
1513
1515 /*****************************************************************************************
1516 *****************************************************************************************/
1525 /*****************************************************************************************
1526 ******************************************************************************************/
1527
1528
1529
1539 void drawPixel(const fVec3& pos);
1540
1541
1553 void drawPixel(const fVec3& pos, color_t color, float opacity);
1554
1555
1566 void drawPixels(int nb_pixels, const fVec3* pos_list);
1567
1568
1583 void drawPixels(int nb_pixels, const fVec3* pos_list, const int* colors_ind, const color_t* colors, const int* opacities_ind, const float* opacities);
1584
1585
1596 void drawDot(const fVec3& pos, int r);
1597
1598
1599
1612 void drawDot(const fVec3& pos, int r, color_t color, float opacity);
1613
1614
1626 void drawDots(int nb_dots, const fVec3* pos_list, const int radius);
1627
1628
1646 void drawDots(int nb_dots, const fVec3* pos_list, const int* radius_ind, const int* radius, const int* colors_ind, const color_t* colors, const int* opacities_ind, const float* opacities);
1647
1648
1649
1650
1651
1653
1654
1655
1656
1657
1658 private:
1659
1660
1661
1662 /*****************************************************************************************
1663 ******************************************************************************************
1664 *
1665 * BE CAREFUL PAST THIS POINT... FOR HERE BE DRAGONS !
1666 *
1667 ******************************************************************************************
1668 ******************************************************************************************/
1669
1670
1672 TGX_INLINE float _clipbound_xy() const
1673 {
1674 return (256 + 3*((MAXVIEWPORTDIMENSION * 256) / ((_lx > _ly) ? _lx : _ly))) / 1024.0f; // use integer computation up to the last divide
1675 //return (1.0f + 3.0f * (((float)MAXVIEWPORTDIMENSION) / ((_lx > _ly) ? _lx : _ly))) / 4.0f;
1676 }
1677
1678
1680 TGX_INLINE bool _validDraw() const
1681 {
1682 return ((_lx > 0) && (_ly > 0) && (_uni.im != nullptr) && (_uni.im->isValid()));
1683 }
1684
1685
1687 TGX_NOINLINE void _recompute_wa_wb();
1688
1689
1690 /***********************************************************
1691 * Making sure shader flags are coherent
1692 ************************************************************/
1693
1694 TGX_NOINLINE void _rectifyShaderOrtho();
1695
1696
1697 TGX_NOINLINE void _rectifyShaderZbuffer();
1698
1699
1700 TGX_NOINLINE void _rectifyShaderShading(Shader new_shaders);
1701
1702
1703 TGX_NOINLINE void _rectifyShaderTextureWrapping();
1704
1705
1706 TGX_NOINLINE void _rectifyShaderTextureQuality();
1707
1708
1709 /***********************************************************
1710 * DRAWING STUFF
1711 ************************************************************/
1712
1713
1715 void _drawTriangleClipped(const int RASTER_TYPE,
1716 const fVec4* Q0, const fVec4* Q1, const fVec4* Q2,
1717 const fVec3* N0, const fVec3* N1, const fVec3* N2,
1718 const fVec2* T0, const fVec2* T1, const fVec2* T2,
1719 const RGBf& Vcol0, const RGBf& Vcol1, const RGBf& Vcol2);
1720
1721
1723 void _drawTriangleClippedSub(const int RASTER_TYPE, const int plane,
1724 const RasterizerVec4& P1, const RasterizerVec4& P2, const RasterizerVec4& P3);
1725
1726
1728 void _drawTriangle(const int RASTER_TYPE,
1729 const fVec3* P0, const fVec3* P1, const fVec3* P2,
1730 const fVec3* N0, const fVec3* N1, const fVec3* N2,
1731 const fVec2* T0, const fVec2* T1, const fVec2* T2,
1732 const RGBf& Vcol0, const RGBf& Vcol1, const RGBf& Vcol2);
1733
1734
1736 void _drawQuad(const int RASTER_TYPE,
1737 const fVec3* P0, const fVec3* P1, const fVec3* P2, const fVec3* P3,
1738 const fVec3* N0, const fVec3* N1, const fVec3* N2, const fVec3* N3,
1739 const fVec2* T0, const fVec2* T1, const fVec2* T2, const fVec2* T3,
1740 const RGBf& Vcol0, const RGBf& Vcol1, const RGBf& Vcol2, const RGBf& Vcol3);
1741
1742
1744 void _drawMesh(const int RASTER_TYPE, const Mesh3D<color_t>* mesh);
1745
1746
1747
1748 /***********************************************************
1749 * Drawing wireframe
1750 ************************************************************/
1751
1752
1753 template<bool DRAW_FAST> void _drawWireFrameMesh(const Mesh3D<color_t>* mesh, bool draw_chained_meshes, color_t color, float opacity, float thickness);
1754
1755 template<bool DRAW_FAST> void _drawWireFrameLine(const fVec3& P1, const fVec3& P2, color_t color, float opacity, float thickness);
1756
1757 template<bool DRAW_FAST> void _drawWireFrameLines(int nb_lines, const uint16_t* ind_vertices, const fVec3* vertices, color_t color, float opacity, float thickness);
1758
1759 template<bool DRAW_FAST> void _drawWireFrameTriangle(const fVec3& P1, const fVec3& P2, const fVec3& P3, color_t color, float opacity, float thickness);
1760
1761 template<bool DRAW_FAST> void _drawWireFrameTriangles(int nb_triangles, const uint16_t* ind_vertices, const fVec3* vertices, color_t color, float opacity, float thickness);
1762
1763 template<bool DRAW_FAST> void _drawWireFrameQuad(const fVec3& P1, const fVec3& P2, const fVec3& P3, const fVec3& P4, color_t color, float opacity, float thickness);
1764
1765 template<bool DRAW_FAST> void _drawWireFrameQuads(int nb_quads, const uint16_t* ind_vertices, const fVec3* vertices, color_t color, float opacity, float thickness);
1766
1767
1768
1769
1770 /***********************************************************
1771 * Simple geometric objects
1772 ************************************************************/
1773
1774
1775 template<bool USE_BLENDING> void _drawPixel(const fVec3& pos, color_t color, float opacity);
1776
1777
1778 template<bool USE_COLORS, bool USE_BLENDING> void _drawPixels(int nb_pixels, const fVec3* pos_list, const int* colors_ind, const color_t* colors, const int* opacities_ind, const float* opacities);
1779
1780
1781 template<bool USE_BLENDING> void _drawDot(const fVec3& pos, int r, color_t color, float opacity);
1782
1783
1784 template<bool USE_RADIUS, bool USE_COLORS, bool USE_BLENDING> void _drawDots(int nb_dots, const fVec3* pos_list, const int* radius_ind, const int* radius, const int* colors_ind, const color_t* colors, const int* opacities_ind, const float* opacities);
1785
1786
1787
1788 template<bool CHECKRANGE, bool USE_BLENDING> TGX_INLINE inline void drawPixelZbuf(int x, int y, color_t color, float opacity, float z)
1789 {
1790 if (CHECKRANGE && ((x < 0) || (x >= _uni.im->lx()) || (y < 0) || (y >= _uni.im->ly()))) return;
1791 ZBUFFER_t& W = _uni.zbuf[x + _uni.im->lx() * y];
1792 const ZBUFFER_t aa = (std::is_same<ZBUFFER_t, uint16_t>::value) ? ((ZBUFFER_t)(z * _uni.wa + _uni.wb)) : ((ZBUFFER_t)z);
1793 if (W < aa)
1794 {
1795 W = aa;
1796 if (USE_BLENDING) _uni.im->template drawPixel<false>({ x, y }, color, opacity); else _uni.im->template drawPixel<false>({ x, y }, color);
1797 }
1798 }
1799
1800
1801 template<bool CHECKRANGE, bool USE_BLENDING> TGX_INLINE inline void drawHLineZbuf(int x, int y, int w, color_t color, float opacity, float z)
1802 {
1803 if (CHECKRANGE) // optimized away at compile time
1804 {
1805 const int lx = _uni.im->lx();
1806 const int ly = _uni.im->ly();
1807 if ((y < 0) || (y >= ly) || (x >= lx)) return;
1808 if (x < 0) { w += x; x = 0; }
1809 if (x + w > lx) { w = lx - x; }
1810 }
1811 while(w--) drawPixelZbuf<CHECKRANGE, USE_BLENDING>(x++, y, color, opacity, z);
1812 }
1813
1814
1815 template<bool CHECKRANGE, bool USE_BLENDING> void _drawCircleZbuf(int xm, int ym, int r, color_t color, float opacity, float z);
1816
1817
1821 float _unitSphereScreenDiameter();
1822
1823
1824 template<bool WIREFRAME, bool DRAWFAST> void _drawSphere(int nb_sectors, int nb_stacks, const Image<color_t>* texture, float thickness, color_t color, float opacity);
1825
1826
1827
1828 /***********************************************************
1829 * CLIPPING
1830 ************************************************************/
1831
1832
1834 TGX_INLINE inline void _clip(int & fl, const fVec4 & P, float bx, float Bx, float by, float By)
1835 {
1836 if (P.x >= bx) { fl &= (~(1)); }
1837 if (P.x <= Bx) { fl &= (~(2)); }
1838 if (P.y >= by) { fl &= (~(4)); }
1839 if (P.y <= By) { fl &= (~(8)); }
1840 if ((P.z >= -1.0f)&&(P.w > 0)) { fl &= (~(16)); }
1841 if (P.z <= +1.0f) { fl &= (~(32)); }
1842 }
1843
1844
1846 TGX_INLINE inline void _clip(int & fl, const fVec3 & P, float bx, float Bx, float by, float By, const fMat4 & M)
1847 {
1848 fVec4 S = M.mult1(P);
1849 if (!_ortho) S.zdivide();
1850 return _clip(fl, S, bx, Bx, by, By);
1851 }
1852
1853
1854 /* test if a box is outside the image and should be discarded.
1855 transform the box coords with M then z-divide. */
1856 bool _discardBox(const fBox3 & bb, const fMat4 & M)
1857 {
1858 if ((bb.minX == 0) && (bb.maxX == 0) && (bb.minY == 0) && (bb.maxY == 0) && (bb.minZ == 0) && (bb.maxZ == 0))
1859 return false; // do not discard if the bounding box is uninitialized.
1860
1861 const float bx = (_ox - 1) * _ilx - 1.0f;
1862 const float Bx = (_ox + _uni.im->width() + 1) * _ilx - 1.0f;
1863 const float by = (_oy - 1) * _ily - 1.0f;
1864 const float By = (_oy + _uni.im->height() + 1) * _ily - 1.0f;
1865
1866 int fl = 63; // every bit set
1867 _clip(fl, fVec3(bb.minX, bb.minY, bb.minZ), bx, Bx, by, By, M);
1868 if (fl == 0) return false;
1869 _clip(fl, fVec3(bb.minX, bb.minY, bb.maxZ), bx, Bx, by, By, M);
1870 if (fl == 0) return false;
1871 _clip(fl, fVec3(bb.minX, bb.maxY, bb.minZ), bx, Bx, by, By, M);
1872 if (fl == 0) return false;
1873 _clip(fl, fVec3(bb.minX, bb.maxY, bb.maxZ), bx, Bx, by, By, M);
1874 if (fl == 0) return false;
1875 _clip(fl, fVec3(bb.maxX, bb.minY, bb.minZ), bx, Bx, by, By, M);
1876 if (fl == 0) return false;
1877 _clip(fl, fVec3(bb.maxX, bb.minY, bb.maxZ), bx, Bx, by, By, M);
1878 if (fl == 0) return false;
1879 _clip(fl, fVec3(bb.maxX, bb.maxY, bb.minZ), bx, Bx, by, By, M);
1880 if (fl == 0) return false;
1881 _clip(fl, fVec3(bb.maxX, bb.maxY, bb.maxZ), bx, Bx, by, By, M);
1882 if (fl == 0) return false;
1883 return true;
1884 }
1885
1886
1887 /* test if a triangle is completely outside the image and should be discarded.
1888 * coords are given after z-divide. */
1889 bool _discardTriangle(const fVec4 & P1, const fVec4 & P2, const fVec4 & P3)
1890 {
1891 const float bx = (_ox - 1) * _ilx - 1.0f;
1892 const float Bx = (_ox + _uni.im->width() + 1) * _ilx - 1.0f;
1893 const float by = (_oy - 1) * _ily - 1.0f;
1894 const float By = (_oy + _uni.im->height() + 1) * _ily - 1.0f;
1895
1896 int fl = 63; // every bit set
1897 _clip(fl, P1, bx, Bx, by, By);
1898 if (fl == 0) return false;
1899 _clip(fl, P2, bx, Bx, by, By);
1900 if (fl == 0) return false;
1901 _clip(fl, P3, bx, Bx, by, By);
1902 if (fl == 0) return false;
1903 return true;
1904 }
1905
1906
1908 bool _clip2(float clipboundXY, const fVec3 & P, const fMat4 & M)
1909 {
1910 fVec4 S = M.mult1(P);
1911 if (!_ortho)
1912 {
1913 S.zdivide();
1914 if (S.w <= 0) S.z = -2;
1915 }
1916 return ((S.x <= -clipboundXY) || (S.x >= clipboundXY)
1917 || (S.y <= -clipboundXY) || (S.y >= clipboundXY)
1918 || (S.z <= -1) || (S.z >= 1));
1919 }
1920
1921
1923 bool _clipTestNeeded(float clipboundXY, const fBox3 & bb, const fMat4 & M)
1924 {
1925 return (_clip2(clipboundXY, fVec3(bb.minX, bb.minY, bb.minZ), M)
1926 || _clip2(clipboundXY, fVec3(bb.minX, bb.minY, bb.maxZ), M)
1927 || _clip2(clipboundXY, fVec3(bb.minX, bb.maxY, bb.minZ), M)
1928 || _clip2(clipboundXY, fVec3(bb.minX, bb.maxY, bb.maxZ), M)
1929 || _clip2(clipboundXY, fVec3(bb.maxX, bb.minY, bb.minZ), M)
1930 || _clip2(clipboundXY, fVec3(bb.maxX, bb.minY, bb.maxZ), M)
1931 || _clip2(clipboundXY, fVec3(bb.maxX, bb.maxY, bb.minZ), M)
1932 || _clip2(clipboundXY, fVec3(bb.maxX, bb.maxY, bb.maxZ), M));
1933 }
1934
1935
1936
1937
1938 /***********************************************************
1939 * TRIANGLE CLIPPING AGAINST A CLIP-PLANE
1940 ************************************************************/
1941
1950 inline float _cpdist(const tgx::fVec4& CP, float off, const tgx::fVec4& P)
1951 {
1952 return (CP.x * P.x) + (CP.y * P.y) + (CP.z * P.z) + (CP.w * P.w) + off;
1953 }
1954
1965 inline float _cpfactor(const tgx::fVec4& CP, const float sdistA, const float sdistB)
1966 {
1967 return sdistA / (sdistA - sdistB);
1968 }
1969
1970
1972 void _triangleClip1in(int shader, tgx::fVec4 CP,
1973 float cp1, float cp2, float cp3,
1974 const RasterizerVec4& P1, const RasterizerVec4& P2, const RasterizerVec4& P3,
1975 RasterizerVec4& nP1, RasterizerVec4& nP2, RasterizerVec4& nP3, RasterizerVec4& nP4);
1976
1977
1979 void _triangleClip2in(int shader, tgx::fVec4 CP,
1980 float cp1, float cp2, float cp3,
1981 const RasterizerVec4& P1, const RasterizerVec4& P2, const RasterizerVec4& P3,
1982 RasterizerVec4& nP1, RasterizerVec4& nP2, RasterizerVec4& nP3, RasterizerVec4& nP4);
1983
1984
1985 int _triangleClip(int shader, tgx::fVec4 CP, float off,
1986 const RasterizerVec4 & P1, const RasterizerVec4 & P2, const RasterizerVec4 & P3,
1987 RasterizerVec4 & nP1, RasterizerVec4 & nP2, RasterizerVec4 & nP3, RasterizerVec4 & nP4);
1988
1989
1990
1991 /***********************************************************
1992 * PHONG LIGHTNING
1993 ************************************************************/
1994
1995 static const int _POWTABSIZE = 32; // number of entries in the precomputed power table for specular exponent.
1996 int _currentpow; // exponent for the currently computed table (<0 if table not yet computed)
1997 float _powmax; // used to compute exponent
1998 float _fastpowtab[_POWTABSIZE]; // the precomputed power table.
1999
2001 TGX_INLINE inline void _precomputeSpecularTable(int exponent)
2002 {
2003 if (_currentpow == exponent) return;
2004 _precomputeSpecularTable2(exponent);
2005 }
2006
2007 TGX_NOINLINE void _precomputeSpecularTable2(int exponent);
2008
2009
2011 TGX_INLINE inline float _powSpecular(float x) const
2012 {
2013 const float indf = (_powmax - x) * _POWTABSIZE;
2014 const int indi = max(0,(int)indf);
2015 return (indi >= (_POWTABSIZE - 1)) ? 0.0f : (_fastpowtab[indi] + (indf - indi) * (_fastpowtab[indi + 1] - _fastpowtab[indi]));;
2016 }
2017
2018
2020 template<bool TEXTURE> TGX_INLINE inline RGBf _phong(float v_diffuse, float v_specular) const
2021 {
2022 RGBf col = _r_ambiantColor;
2023 col += _r_diffuseColor * max(v_diffuse, 0.0f);
2024 col += _r_specularColor * _powSpecular(v_specular); // pow() this is too slow so we use a lookup table instead
2025 if (!(TEXTURE)) col *= _r_objectColor;
2026 col.clamp();
2027 return col;
2028 }
2029
2030
2032 TGX_INLINE inline RGBf _phong(float v_diffuse, float v_specular, RGBf color) const
2033 {
2034 RGBf col = _r_ambiantColor;
2035 col += _r_diffuseColor * max(v_diffuse, 0.0f);
2036 col += _r_specularColor * _powSpecular(v_specular); // pow() this is too slow so we use a lookup table instead
2037 col *= color;
2038 col.clamp();
2039 return col;
2040 }
2041
2042
2043
2044 /***********************************************************
2045 * MEMBER VARIABLES
2046 ************************************************************/
2047
2048 // *** general parameters ***
2049
2050 int _lx, _ly; // viewport dimension
2051 float _ilx, _ily; // inverse viewport dimension
2052
2053 int _ox, _oy; // image offset w.r.t. the viewport
2054
2055 bool _ortho; // true to use orthographic projection and false for perspective projection
2056
2057 fMat4 _projM; // projection matrix
2058
2059 RasterizerParams<color_t, color_t,ZBUFFER_t> _uni; // rasterizer param (contain the image pointer and the zbuffer pointer).
2060
2061 float _culling_dir; // culling direction postive/negative or 0 to disable back face culling.
2062
2063 int _shaders; // the shaders to use.
2064 int _texture_wrap_mode; // wrapping mode (wrap_pow2 or clamp)
2065 int _texture_quality; // texturing quality (nearest or bilinear)
2066
2067 // *** scene parameters ***
2068
2069 fMat4 _viewM; // view transform matrix
2070
2071 fVec3 _light; // light direction
2072 RGBf _ambiantColor; // light ambiant color
2073 RGBf _diffuseColor; // light diffuse color
2074 RGBf _specularColor; // light specular color
2075
2076
2077 // *** model specific parameters ***
2078
2079 fMat4 _modelM; // model transform matrix
2080
2081 RGBf _color; // model color (use when texturing is disabled)
2082 float _ambiantStrength; // ambient light reflection strength
2083 float _diffuseStrength; // diffuse light reflection strength
2084 float _specularStrength; // specular light reflection strength
2085 int _specularExponent; // specular exponent
2086
2087
2088 // *** pre-computed values ***
2089 fMat4 _r_modelViewM; // model-view matrix
2090 float _r_inorm; // inverse of the norm of a unit vector after view transform
2091 fVec3 _r_light; // light vector in view space (inverted and normalized)
2092 fVec3 _r_light_inorm; // same as above but alreadsy muliplied by inorm
2093 fVec3 _r_H; // halfway vector.
2094 fVec3 _r_H_inorm; // same as above but already muliplied by inorm
2095 RGBf _r_ambiantColor; // ambient color multipled by object ambient strenght
2096 RGBf _r_diffuseColor; // diffuse color multipled by object diffuse strenght
2097 RGBf _r_specularColor; // specular color multipled by object specular strenght
2098 RGBf _r_objectColor; // color to use for drawing the object (either _color or mesh->color).
2099
2100
2104 struct ExtVec4 : public RasterizerVec4
2105 {
2106 fVec4 P; // after model-view matrix multiplication
2107 fVec4 N; // normal vector after model-view matrix multiplication
2108 bool missedP; // true if the attributes should be computed
2109 int indn; // index for normal vector in array
2110 int indt; // index for texture vector in array
2111 };
2112
2113
2114 };
2115
2116
2117
2118}
2119
2120
2121
2122
2123#include "Renderer3D.inl"
2124
2125
2126#endif
2127
2128#endif
2129
2130
2D box class
3D box class
Color classes [RGB565, RGB24, RGB32, RGB64, RGBf, HSV].
Main image class.
4x4 matrix class.
Mat4< float > fMat4
4x4 matrix with single (float) precision
Definition: Mat4.h:54
3D model mesh class.
Utility/miscellaneous functions used throughout the library.
TGX_INLINE T max(const T &a, const T &b)
Don't know why but much faster than fmaxf() for floats.
Definition: Misc.h:136
3D triangle rasterizer function.
#define TGX_RASTERIZE_SUBPIXEL_BITS
Sub-pixel precision bits.
Definition: Rasterizer.h:46
Shader
List of shaders available for 3D graphics.
Definition: ShaderParams.h:44
@ SHADER_NOTEXTURE
disable texture mapping
Definition: ShaderParams.h:58
@ SHADER_TEXTURE
enable texture mapping
Definition: ShaderParams.h:59
Triangle shader functions.
2D vector.
3D vector.
Vec3< float > fVec3
Floating point valued 3D vector with single (float) precision.
Definition: Vec3.h:52
4D vector.
Vec4< float > fVec4
Floating point valued 4D vector with single (float) precision.
Definition: Vec4.h:54
Image class [MAIN CLASS FOR THE 2D API].
Definition: Image.h:143
Class for drawing 3D objects onto a Image [MAIN CLASS FOR THE 3D API].
Definition: Renderer3D.h:113
void drawAdaptativeSphere(float quality=1.0f)
Draw a unit radius sphere centered at the origin S(0,1) in model space.
void drawQuads(int nb_quads, const uint16_t *ind_vertices, const fVec3 *vertices, const uint16_t *ind_normals=nullptr, const fVec3 *normals=nullptr, const uint16_t *ind_texture=nullptr, const fVec2 *textures=nullptr, const Image< color_t > *texture_image=nullptr)
Draw a collection of quads.
void drawWireFrameLine(const fVec3 &P1, const fVec3 &P2)
Draw a wireframe line segment [low quality].
void drawMesh(const Mesh3D< color_t > *mesh, bool use_mesh_material=true, bool draw_chained_meshes=true)
Draw a Mesh3D object.
void drawDot(const fVec3 &pos, int r, color_t color, float opacity)
Draw a dot/circle at a given position in model space.
void setMaterialAmbiantStrength(float strenght=0.1f)
Set how much the object material reflects the ambient light.
void drawSphere(int nb_sectors, int nb_stacks)
Draw a unit radius sphere centered at the origin S(0,1) in model space.
void drawWireFrameAdaptativeSphere(float quality, float thickness, color_t color, float opacity)
Draw a wireframe unit radius sphere centered at the origin (in model space) [high quality].
void setMaterialSpecularExponent(int exponent=16)
Set the object specular exponent.
void drawWireFrameTriangle(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3)
Draw a wireframe triangle [low quality].
void drawWireFrameCube()
Draw the wireframe cube [0,1]^3 (in model space) [low quality].
void setMaterialSpecularStrength(float strenght=0.5f)
Set how much the object material reflects the specular light.
void setMaterialDiffuseStrength(float strenght=0.6f)
Set how much the object material reflects the diffuse light.
void drawWireFrameQuad(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, const fVec3 &P4)
Draw a wireframe quad [low quality].
void setShaders(Shader shaders)
Set the shaders to use for subsequent drawing operations.
iVec2 modelToImage(fVec3 P)
Convert from model coordinates to the corresponding image pixel.
void setModelPosScaleRot(const fVec3 &center=fVec3{ 0, 0, 0 }, const fVec3 &scale=fVec3(1, 1, 1), float rot_angle=0, const fVec3 &rot_dir=fVec3{ 0, 1, 0 })
Set the model tranformation matrix to move an object to a given a given location, scale and rotation.
void drawCube(const Image< color_t > *texture_front, const Image< color_t > *texture_back, const Image< color_t > *texture_top, const Image< color_t > *texture_bottom, const Image< color_t > *texture_left, const Image< color_t > *texture_right)
draw a textured unit cube [-1,1]^3 (in model space)
void drawDots(int nb_dots, const fVec3 *pos_list, const int *radius_ind, const int *radius, const int *colors_ind, const color_t *colors, const int *opacities_ind, const float *opacities)
Draw a list of dots/circles at given positions in model space.
fMat4 getViewMatrix() const
Return the current view matrix.
void setLookAt(const fVec3 eye, const fVec3 center, const fVec3 up)
Set the view matrix so that the camera is looking at a given direction.
void drawWireFrameMesh(const Mesh3D< color_t > *mesh, bool draw_chained_meshes, float thickness, color_t color, float opacity)
Draw a mesh in wireframe [high quality].
void drawWireFrameQuads(int nb_quads, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw a collection of wireframe quads [low quality].
void setLightAmbiant(const RGBf &color)
Set the scene ambiant light color.
void drawWireFrameAdaptativeSphere(float quality=1.0f)
Draw a wireframe unit radius sphere centered at the origin (in model space) [low quality].
void drawCube()
Draw the unit cube [-1,1]^3 in model space.
void drawWireFrameSphere(int nb_sectors, int nb_stacks, float thickness, color_t color, float opacity)
Draw a wireframe unit radius sphere centered at the origin (in model space) [high quality].
fMat4 getProjectionMatrix() const
Return the current projection matrix.
void drawWireFrameLines(int nb_lines, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw a collection of wireframe line segments [low quality].
void setZbuffer(ZBUFFER_t *zbuffer)
Set the z-buffer.
void setMaterialColor(RGBf color)
Set the object material color.
void setLightDirection(const fVec3 &direction)
Set the light source direction.
void setLight(const fVec3 direction, const RGBf &ambiantColor, const RGBf &diffuseColor, const RGBf &specularColor)
Set all the lighting parameters of the scene at once.
void setMaterial(RGBf color, float ambiantStrength, float diffuseStrength, float specularStrength, int specularExponent)
Set all the object material properties at once.
void setTextureWrappingMode(Shader wrap_mode)
Set the wrap mode when for texturing.
void drawDots(int nb_dots, const fVec3 *pos_list, const int radius)
Draw a list of dots/circles at given positions in model space.
fVec4 worldToNDC(fVec3 P)
Convert from world coordinates to normalized device coordinates (NDC).
void setViewMatrix(const fMat4 &M)
Set the view transformation matrix.
void setViewportSize(const iVec2 &viewport_dim)
Set the size of the viewport.
TGX_NOINLINE Renderer3D(const iVec2 &viewportSize={0, 0}, Image< color_t > *im=nullptr, ZBUFFER_t *zbuffer=nullptr)
Constructor.
void setViewportSize(int lx, int ly)
Set the size of the viewport.
iVec2 worldToImage(fVec3 P)
Convert from world coordinates to the corresponding image pixel.
void setCulling(int w)
Set the face culling strategy.
void drawTriangleWithVertexColor(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, const RGBf &col1, const RGBf &col2, const RGBf &col3, const fVec3 *N1=nullptr, const fVec3 *N2=nullptr, const fVec3 *N3=nullptr)
Draw a single triangle with a given colors on each of its vertices.
void usePerspectiveProjection()
Set projection mode to perspective (ie with z-divide).
void setModelMatrix(const fMat4 &M)
Set the model tranformation matrix.
void drawWireFrameTriangle(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, float thickness, color_t color, float opacity)
Draw a wireframe triangle [high quality].
void setPerspective(float fovy, float aspect, float zNear, float zFar)
Set the projection matrix as a perspective matrix.
void drawWireFrameQuads(int nb_quads, const uint16_t *ind_vertices, const fVec3 *vertices, float thickness, color_t color, float opacity)
Draw a collection of wireframe quads [high quality].
void drawPixel(const fVec3 &pos)
Draw a single pixel at a given position in model space.
void setOrtho(float left, float right, float bottom, float top, float zNear, float zFar)
Set the projection matrix as an orthographic matrix.
fMat4 getModelMatrix() const
Return the model tranformation matrix.
void drawWireFrameLines(int nb_lines, const uint16_t *ind_vertices, const fVec3 *vertices, float thickness, color_t color, float opacity)
Draw a collection of wireframe line segments [high quality].
void setImage(Image< color_t > *im)
Set the image that will be drawn onto.
void drawPixels(int nb_pixels, const fVec3 *pos_list)
Draw a list of pixels at given positions in model space.
void drawPixel(const fVec3 &pos, color_t color, float opacity)
Draw a single pixel at a given position in model space.
void setLightDiffuse(const RGBf &color)
Set the scene diffuse light color.
void setLightSpecular(const RGBf &color)
Set the scene specular light color.
void setOffset(const iVec2 &offset)
Set the offset of the image relative to the viewport.
void drawCube(const fVec2 v_front_ABCD[4], const Image< color_t > *texture_front, const fVec2 v_back_EFGH[4], const Image< color_t > *texture_back, const fVec2 v_top_HADE[4], const Image< color_t > *texture_top, const fVec2 v_bottom_BGFC[4], const Image< color_t > *texture_bottom, const fVec2 v_left_HGBA[4], const Image< color_t > *texture_left, const fVec2 v_right_DCFE[4], const Image< color_t > *texture_right)
Draw a textured unit cube [-1,1]^3 in model space.
void drawWireFrameQuad(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, const fVec3 &P4, float thickness, color_t color, float opacity)
Draw a wireframe quad [high quality].
void setLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
Set the view matrix so that the camera is looking at a given direction.
void useOrthographicProjection()
Set projection mode to orthographic (ie no z-divide).
void drawTriangle(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, const fVec3 *N1=nullptr, const fVec3 *N2=nullptr, const fVec3 *N3=nullptr, const fVec2 *T1=nullptr, const fVec2 *T2=nullptr, const fVec2 *T3=nullptr, const Image< color_t > *texture=nullptr)
Draw a single triangle.
void drawTriangles(int nb_triangles, const uint16_t *ind_vertices, const fVec3 *vertices, const uint16_t *ind_normals=nullptr, const fVec3 *normals=nullptr, const uint16_t *ind_texture=nullptr, const fVec2 *textures=nullptr, const Image< color_t > *texture_image=nullptr)
Draw a collection of triangles.
void clearZbuffer()
Clear the Zbuffer.
void drawWireFrameLine(const fVec3 &P1, const fVec3 &P2, float thickness, color_t color, float opacity)
Draw a wireframe line segment [high quality].
void drawQuadWithVertexColor(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, const fVec3 &P4, const RGBf &col1, const RGBf &col2, const RGBf &col3, const RGBf &col4, const fVec3 *N1=nullptr, const fVec3 *N2=nullptr, const fVec3 *N3=nullptr, const fVec3 *N4=nullptr)
Draw a single quad with a given colors on each of its four vertices.
void drawWireFrameMesh(const Mesh3D< color_t > *mesh, bool draw_chained_meshes=true)
Draw a mesh in wireframe [low quality].
fVec4 modelToNDC(fVec3 P)
Convert from model coordinates to normalized device coordinates (NDC).
void drawWireFrameTriangles(int nb_triangles, const uint16_t *ind_vertices, const fVec3 *vertices, float thickness, color_t color, float opacity)
Draw a collection of wireframe triangles [high quality].
void drawSphere(int nb_sectors, int nb_stacks, const Image< color_t > *texture)
Draw a textured unit radius sphere centered at the origin S(0,1) in model space.
void drawDot(const fVec3 &pos, int r)
Draw a dot/circle at a given position in model space.
void setFrustum(float left, float right, float bottom, float top, float zNear, float zFar)
Set the projection matrix as a perspective matrix.
void setProjectionMatrix(const fMat4 &M)
Set the projection matrix.
void setTextureQuality(Shader quality)
Set the texturing quality.
void drawPixels(int nb_pixels, const fVec3 *pos_list, const int *colors_ind, const color_t *colors, const int *opacities_ind, const float *opacities)
Draw a list of pixels at given positions in model space with different colors and opacities.
void drawAdaptativeSphere(const Image< color_t > *texture, float quality=1.0f)
Draw a textured unit radius sphere centered at the origin S(0,1) in model space.
void drawWireFrameSphere(int nb_sectors, int nb_stacks)
Draw a wireframe unit radius sphere centered at the origin (in model space) [low quality].
void drawWireFrameTriangles(int nb_triangles, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw a collection of wireframe triangles [low quality].
void drawQuad(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, const fVec3 &P4, const fVec3 *N1=nullptr, const fVec3 *N2=nullptr, const fVec3 *N3=nullptr, const fVec3 *N4=nullptr, const fVec2 *T1=nullptr, const fVec2 *T2=nullptr, const fVec2 *T3=nullptr, const fVec2 *T4=nullptr, const Image< color_t > *texture=nullptr)
Draw a single quad.
void setOffset(int ox, int oy)
Set the offset of the image relative to the viewport.
void drawWireFrameCube(float thickness, color_t color, float opacity)
Draw the wireframe cube [0,1]^3 (in model space) [high quality].
3D mesh data stucture.
Definition: Mesh3D.h:155
Color in R,G,B float format.
Definition: Color.h:2407
void clamp()
Clamp all color channel to [0.0f,1.0f].
Definition: Color.h:2647
Generic 2D vector [specializations iVec2, fVec2, dVec2].
Definition: Vec2.h:64
T x
'x' coordinate (first dimension)
Definition: Vec2.h:72
T y
'y' coordinate (second dimension)
Definition: Vec2.h:73
T z
'z' coordinate (third dimension)
Definition: Vec3.h:83
T w
'w' coordinate (fourth dimension)
Definition: Vec4.h:85
void zdivide()
Performs the 'z-divide' operation.
Definition: Vec4.h:478