| TGX 1.1.0 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#include "Mesh3Dv2.h"
43
44 namespace tgx
45{
46
47 // forward declaration for the vertices and faces of the unit cube [-1,1]^3
48
49 extern const tgx::fVec3 UNIT_CUBE_VERTICES[8];
50 extern const tgx::fVec3 UNIT_CUBE_NORMALS[6];
51 extern const uint16_t UNIT_CUBE_FACES[6*4];
52 extern const uint16_t UNIT_CUBE_FACES_NORMALS[6 * 4];
53
54
55
107 template<typename color_t, Shader LOADED_SHADERS = TGX_SHADER_MASK_ALL, typename ZBUFFER_t = float>
108 class Renderer3D
109 {
110
111
112 static constexpr int MAXVIEWPORTDIMENSION = 2048 * (1 << ((8 - TGX_RASTERIZE_SUBPIXEL_BITS) >> 1));
113
114 static_assert(is_color<color_t>::value, "color_t must be one of the color types defined in color.h");
115 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");
116
117 // true if some kind of texturing may be used.
118 static constexpr int ENABLE_TEXTURING = (TGX_SHADER_HAS_ONE_FLAG(LOADED_SHADERS , (SHADER_TEXTURE | TGX_SHADER_MASK_TEXTURE_MODE | TGX_SHADER_MASK_TEXTURE_QUALITY)));
119
120 static constexpr Shader ENABLED_SHADERS = LOADED_SHADERS | (ENABLE_TEXTURING ? SHADER_TEXTURE : SHADER_NOTEXTURE); // enable texturing when at least one texturing related flag is set
121
122 // check that disabled shaders do not completely disable all drawing operations.
123 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");
124 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");
125 static_assert(TGX_SHADER_HAS_ONE_FLAG(ENABLED_SHADERS,TGX_SHADER_MASK_SHADING), "At least one of the shaders SHADER_UNLIT, SHADER_FLAT or SHADER_GOURAUD must be enabled");
126 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");
127 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");
128 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");
129
130
131
132 public:
133
134
144 TGX_NOINLINE Renderer3D(const iVec2& viewportSize = {0,0}, Image<color_t> * im = nullptr, ZBUFFER_t * zbuffer = nullptr);
145
146
147
148
149 /*****************************************************************************************
150 *****************************************************************************************/
157 /*****************************************************************************************
158 ******************************************************************************************/
159
160
181 void setViewportSize(int lx, int ly);
182
183
191 void setViewportSize(const iVec2& viewport_dim);
192
193
205 void setImage(Image<color_t>* im);
206
207
226 void setOffset(int ox, int oy);
227
228
236 void setOffset(const iVec2& offset);
237
238
256 void setProjectionMatrix(const fMat4& M);
257
258
264 fMat4 getProjectionMatrix() const;
265
266
272 void useOrthographicProjection();
273
274
280 void usePerspectiveProjection();
281
282
299 void setOrtho(float left, float right, float bottom, float top, float zNear, float zFar);
300
301
318 void setFrustum(float left, float right, float bottom, float top, float zNear, float zFar);
319
320
338 void setPerspective(float fovy, float aspect, float zNear, float zFar);
339
340
358 void setCulling(int w);
359
360
373 void setZbuffer(ZBUFFER_t* zbuffer);
374
375
384 void clearZbuffer();
385
386
425 void setShaders(Shader shaders);
426
427
435 void setTextureWrappingMode(Shader wrap_mode);
436
437
445 void setTextureQuality(Shader quality);
446
447
448
450 /*****************************************************************************************
451 *****************************************************************************************/
458 /*****************************************************************************************
459 ******************************************************************************************/
460
461
462
479 void setViewMatrix(const fMat4& M);
480
481
489 fMat4 getViewMatrix() const;
490
491
503 void setLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ);
504
505
517 void setLookAt(const fVec3 eye, const fVec3 center, const fVec3 up);
518
519
532 fVec4 worldToNDC(fVec3 P);
533
534
546 iVec2 worldToImage(fVec3 P);
547
548
558 void setLightDirection(const fVec3& direction);
559
560
570 void setLightAmbiant(const RGBf& color);
571
572
582 void setLightDiffuse(const RGBf& color);
583
584
594 void setLightSpecular(const RGBf& color);
595
596
611 void setLight(const fVec3 direction, const RGBf& ambiantColor, const RGBf& diffuseColor, const RGBf& specularColor);
612
613
614
615
616
618 /*****************************************************************************************
619 *****************************************************************************************/
626 /*****************************************************************************************
627 ******************************************************************************************/
628
629
630
641 void setModelMatrix(const fMat4& M);
642
643
651 fMat4 getModelMatrix() const;
652
653
675 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 });
676
677
688 fVec4 modelToNDC(fVec3 P);
689
690
702 iVec2 modelToImage(fVec3 P);
703
704
715 void setMaterialColor(RGBf color);
716
717
726 void setMaterialAmbiantStrength(float strenght = 0.1f);
727
728
737 void setMaterialDiffuseStrength(float strenght = 0.6f);
738
739
748 void setMaterialSpecularStrength(float strenght = 0.5f);
749
750
761 void setMaterialSpecularExponent(int exponent = 16);
762
763
776 void setMaterial(RGBf color, float ambiantStrength, float diffuseStrength, float specularStrength, int specularExponent);
777
778
779
780
781
782
783
784
786 /*****************************************************************************************
787 *****************************************************************************************/
801 /*****************************************************************************************
802 ******************************************************************************************/
803
804
805
822 void drawMesh(const Mesh3D<color_t>* mesh, bool use_mesh_material = true, bool draw_chained_meshes = true);
823
824
837 void drawMesh(const Mesh3Dv2<color_t>* mesh, bool use_mesh_material = true);
838
839
853 void drawTriangle(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3,
854 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr,
855 const fVec2 * T1 = nullptr, const fVec2 * T2 = nullptr, const fVec2 * T3 = nullptr,
856 const Image<color_t> * texture = nullptr);
857
858
871 void drawTriangleWithVertexColor(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3,
872 const RGBf & col1, const RGBf & col2, const RGBf & col3,
873 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr);
874
875
894 void drawTriangles(int nb_triangles,
895 const uint16_t * ind_vertices, const fVec3 * vertices,
896 const uint16_t * ind_normals = nullptr, const fVec3* normals = nullptr,
897 const uint16_t * ind_texture = nullptr, const fVec2* textures = nullptr,
898 const Image<color_t> * texture_image = nullptr);
899
900
901
917 void drawQuad(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3, const fVec3 & P4,
918 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr, const fVec3 * N4 = nullptr,
919 const fVec2 * T1 = nullptr, const fVec2 * T2 = nullptr, const fVec2 * T3 = nullptr, const fVec2 * T4 = nullptr,
920 const Image<color_t>* texture = nullptr);
921
922
923
939 void drawQuadWithVertexColor(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3, const fVec3 & P4,
940 const RGBf & col1, const RGBf & col2, const RGBf & col3, const RGBf & col4,
941 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr, const fVec3 * N4 = nullptr);
942
943
944
945
966 void drawQuads(int nb_quads,
967 const uint16_t * ind_vertices, const fVec3 * vertices,
968 const uint16_t * ind_normals = nullptr, const fVec3* normals = nullptr,
969 const uint16_t * ind_texture = nullptr, const fVec2* textures = nullptr,
970 const Image<color_t>* texture_image = nullptr);
971
972
973
974
976 /*****************************************************************************************
977 *****************************************************************************************/
984 /*****************************************************************************************
985 ******************************************************************************************/
986
987
988
995 void drawCube();
996
997
1039 void drawCube(
1040 const fVec2 v_front_ABCD[4] , const Image<color_t>* texture_front,
1041 const fVec2 v_back_EFGH[4] , const Image<color_t>* texture_back,
1042 const fVec2 v_top_HADE[4] , const Image<color_t>* texture_top,
1043 const fVec2 v_bottom_BGFC[4], const Image<color_t>* texture_bottom,
1044 const fVec2 v_left_HGBA[4] , const Image<color_t>* texture_left,
1045 const fVec2 v_right_DCFE[4] , const Image<color_t>* texture_right
1046 );
1047
1048
1084 void drawCube(
1085 const Image<color_t>* texture_front,
1086 const Image<color_t>* texture_back,
1087 const Image<color_t>* texture_top,
1088 const Image<color_t>* texture_bottom,
1089 const Image<color_t>* texture_left,
1090 const Image<color_t>* texture_right
1091 );
1092
1093
1094
1105 void drawSphere(int nb_sectors, int nb_stacks);
1106
1107
1120 void drawSphere(int nb_sectors, int nb_stacks, const Image<color_t>* texture);
1121
1122
1137 void drawAdaptativeSphere(float quality = 1.0f);
1138
1139
1157 void drawAdaptativeSphere(const Image<color_t>* texture, float quality = 1.0f);
1158
1159
1160
1161
1162
1163
1164
1165
1167 /*****************************************************************************************
1168 *****************************************************************************************/
1183 /*****************************************************************************************
1184 ******************************************************************************************/
1185
1186
1187
1199 void drawWireFrameMesh(const Mesh3D<color_t>* mesh, bool draw_chained_meshes = true);
1200
1201
1213 void drawWireFrameMesh(const Mesh3Dv2<color_t>* mesh);
1214
1215
1226 void drawWireFrameMeshAA(const Mesh3D<color_t>* mesh, bool draw_chained_meshes = true);
1227
1228
1238 void drawWireFrameMeshAA(const Mesh3Dv2<color_t>* mesh);
1239
1240
1257 void drawWireFrameMesh(const Mesh3D<color_t>* mesh, bool draw_chained_meshes, float thickness, color_t color, float opacity);
1258
1259
1276 void drawWireFrameMesh(const Mesh3Dv2<color_t>* mesh, float thickness, color_t color, float opacity);
1277
1278
1288 void drawWireFrameLine(const fVec3& P1, const fVec3& P2);
1289
1290
1300 void drawWireFrameLineAA(const fVec3& P1, const fVec3& P2);
1301
1302
1315 void drawWireFrameLine(const fVec3& P1, const fVec3& P2, float thickness, color_t color, float opacity);
1316
1317
1329 void drawWireFrameLines(int nb_lines, const uint16_t* ind_vertices, const fVec3* vertices);
1330
1331
1343 void drawWireFrameLinesAA(int nb_lines, const uint16_t* ind_vertices, const fVec3* vertices);
1344
1345
1360 void drawWireFrameLines(int nb_lines, const uint16_t* ind_vertices, const fVec3* vertices, float thickness, color_t color, float opacity);
1361
1362
1373 void drawWireFrameTriangle(const fVec3& P1, const fVec3& P2, const fVec3& P3);
1374
1375
1385 void drawWireFrameTriangleAA(const fVec3& P1, const fVec3& P2, const fVec3& P3);
1386
1387
1402 void drawWireFrameTriangle(const fVec3& P1, const fVec3& P2, const fVec3& P3, float thickness, color_t color, float opacity);
1403
1404
1417 void drawWireFrameTriangles(int nb_triangles, const uint16_t* ind_vertices, const fVec3* vertices);
1418
1419
1431 void drawWireFrameTrianglesAA(int nb_triangles, const uint16_t* ind_vertices, const fVec3* vertices);
1432
1433
1450 void drawWireFrameTriangles(int nb_triangles, const uint16_t* ind_vertices, const fVec3* vertices, float thickness, color_t color, float opacity);
1451
1452
1464 void drawWireFrameQuad(const fVec3& P1, const fVec3& P2, const fVec3& P3, const fVec3& P4);
1465
1466
1476 void drawWireFrameQuadAA(const fVec3& P1, const fVec3& P2, const fVec3& P3, const fVec3& P4);
1477
1478
1494 void drawWireFrameQuad(const fVec3& P1, const fVec3& P2, const fVec3& P3, const fVec3& P4, float thickness, color_t color, float opacity);
1495
1496
1510 void drawWireFrameQuads(int nb_quads, const uint16_t* ind_vertices, const fVec3* vertices);
1511
1512
1524 void drawWireFrameQuadsAA(int nb_quads, const uint16_t* ind_vertices, const fVec3* vertices);
1525
1526
1544 void drawWireFrameQuads(int nb_quads, const uint16_t* ind_vertices, const fVec3* vertices, float thickness, color_t color, float opacity);
1545
1546
1547
1548
1550 /*****************************************************************************************
1551 *****************************************************************************************/
1566 /*****************************************************************************************
1567 ******************************************************************************************/
1568
1569
1577 void drawWireFrameCube();
1578
1579
1587 void drawWireFrameCubeAA();
1588
1589
1603 void drawWireFrameCube(float thickness, color_t color, float opacity);
1604
1605
1617 void drawWireFrameSphere(int nb_sectors, int nb_stacks);
1618
1619
1630 void drawWireFrameSphereAA(int nb_sectors, int nb_stacks);
1631
1632
1649 void drawWireFrameSphere(int nb_sectors, int nb_stacks, float thickness, color_t color, float opacity);
1650
1651
1665 void drawWireFrameAdaptativeSphere(float quality = 1.0f);
1666
1667
1677 void drawWireFrameAdaptativeSphereAA(float quality = 1.0f);
1678
1679
1698 void drawWireFrameAdaptativeSphere(float quality, float thickness, color_t color, float opacity);
1699
1700
1701
1702
1703
1705 /*****************************************************************************************
1706 *****************************************************************************************/
1715 /*****************************************************************************************
1716 ******************************************************************************************/
1717
1718
1719
1729 void drawPixel(const fVec3& pos);
1730
1731
1743 void drawPixel(const fVec3& pos, color_t color, float opacity);
1744
1745
1756 void drawPixels(int nb_pixels, const fVec3* pos_list);
1757
1758
1773 void drawPixels(int nb_pixels, const fVec3* pos_list, const int* colors_ind, const color_t* colors, const int* opacities_ind, const float* opacities);
1774
1775
1786 void drawDot(const fVec3& pos, int r);
1787
1788
1789
1802 void drawDot(const fVec3& pos, int r, color_t color, float opacity);
1803
1804
1816 void drawDots(int nb_dots, const fVec3* pos_list, const int radius);
1817
1818
1836 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);
1837
1838
1839
1840
1841
1843
1844
1845
1846
1847
1848 private:
1849
1850
1851
1852 /*****************************************************************************************
1853 ******************************************************************************************
1854 *
1855 * BE CAREFUL PAST THIS POINT... FOR HERE BE DRAGONS !
1856 *
1857 ******************************************************************************************
1858 ******************************************************************************************/
1859
1860
1862 TGX_INLINE float _clipbound_xy() const
1863 {
1864 return (256 + 3*((MAXVIEWPORTDIMENSION * 256) / ((_lx > _ly) ? _lx : _ly))) / 1024.0f; // use integer computation up to the last divide
1865 //return (1.0f + 3.0f * (((float)MAXVIEWPORTDIMENSION) / ((_lx > _ly) ? _lx : _ly))) / 4.0f;
1866 }
1867
1868
1870 TGX_INLINE bool _validDraw() const
1871 {
1872 return ((_lx > 0) && (_ly > 0) && (_uni.im != nullptr) && (_uni.im->isValid()));
1873 }
1874
1875
1877 TGX_NOINLINE void _recompute_wa_wb();
1878
1879
1880 /***********************************************************
1881 * Making sure shader flags are coherent
1882 ************************************************************/
1883
1884 TGX_NOINLINE void _rectifyShaderOrtho();
1885
1886
1887 TGX_NOINLINE void _rectifyShaderZbuffer();
1888
1889
1890 TGX_NOINLINE void _rectifyShaderShading(Shader new_shaders);
1891
1892
1893 TGX_NOINLINE void _rectifyShaderTextureWrapping();
1894
1895
1896 TGX_NOINLINE void _rectifyShaderTextureQuality();
1897
1898
1899 /***********************************************************
1900 * DRAWING STUFF
1901 ************************************************************/
1902
1903
1905 void _drawTriangleClipped(const int RASTER_TYPE,
1906 const fVec4* Q0, const fVec4* Q1, const fVec4* Q2,
1907 const fVec3* N0, const fVec3* N1, const fVec3* N2,
1908 const fVec2* T0, const fVec2* T1, const fVec2* T2,
1909 const RGBf& Vcol0, const RGBf& Vcol1, const RGBf& Vcol2);
1910
1911
1913 void _drawTriangleClippedSub(const int RASTER_TYPE, const int plane,
1914 const RasterizerVec4& P1, const RasterizerVec4& P2, const RasterizerVec4& P3);
1915
1916
1918 void _drawTriangle(const int RASTER_TYPE,
1919 const fVec3* P0, const fVec3* P1, const fVec3* P2,
1920 const fVec3* N0, const fVec3* N1, const fVec3* N2,
1921 const fVec2* T0, const fVec2* T1, const fVec2* T2,
1922 const RGBf& Vcol0, const RGBf& Vcol1, const RGBf& Vcol2);
1923
1924
1926 void _drawQuad(const int RASTER_TYPE,
1927 const fVec3* P0, const fVec3* P1, const fVec3* P2, const fVec3* P3,
1928 const fVec3* N0, const fVec3* N1, const fVec3* N2, const fVec3* N3,
1929 const fVec2* T0, const fVec2* T1, const fVec2* T2, const fVec2* T3,
1930 const RGBf& Vcol0, const RGBf& Vcol1, const RGBf& Vcol2, const RGBf& Vcol3);
1931
1932
1934 void _drawMesh(const int RASTER_TYPE, const Mesh3D<color_t>* mesh);
1935
1937 void _drawMesh(const int RASTER_TYPE, const Mesh3Dv2<color_t>* mesh, bool use_mesh_material);
1938
1940 TGX_INLINE inline bool _discardMeshlet16b(const fVec3& sphere_center, float sphere_radius, const fVec3& cone_dir, float cone_cos) const
1941 {
1942 if (cone_cos <= -1.0f) return false;
1943
1944 const fVec4 D = _r_modelViewM.mult0(cone_dir);
1945 const float dd = D.x * D.x + D.y * D.y + D.z * D.z;
1946 if (dd <= 1.0e-20f) return false;
1947
1948 float dot;
1949 float len2;
1950 if (_ortho)
1951 {
1952 dot = D.z; // object-to-camera direction is +Z in view space.
1953 len2 = dd;
1954 }
1955 else
1956 {
1957 const fVec3 anchor = sphere_center - (cone_dir * sphere_radius);
1958 const fVec4 A = _r_modelViewM.mult1(anchor);
1959 dot = -(D.x * A.x + D.y * A.y + D.z * A.z);
1960 const float aa = A.x * A.x + A.y * A.y + A.z * A.z;
1961 if (aa <= 1.0e-20f) return false;
1962 len2 = dd * aa;
1963 }
1964
1965 const float c2len2 = cone_cos * cone_cos * len2;
1966 const float dot2 = dot * dot;
1967 return (cone_cos >= 0.0f) ? ((dot < 0.0f) || (dot2 < c2len2))
1968 : ((dot < 0.0f) && (dot2 > c2len2));
1969 }
1970
1971
1972
1973 /***********************************************************
1974 * Drawing wireframe
1975 ************************************************************/
1976
1977 inline void _drawWireFrameLineFast(iVec2 P0, iVec2 P1, color_t color);
1978
1979 template<bool CHECK_NEIGHBOR> inline void _drawWireFrameLineAAFast(const fVec2& P0, const fVec2& P1, color_t color, int32_t op);
1980
1981 template<int MODE> void _drawWireFrameMesh(const Mesh3D<color_t>* mesh, bool draw_chained_meshes, color_t color, float opacity, float thickness);
1982
1983 template<int MODE> void _drawWireFrameMesh(const Mesh3Dv2<color_t>* mesh, color_t color, float opacity, float thickness);
1984
1985 template<int MODE> void _drawWireFrameLine(const fVec3& P1, const fVec3& P2, color_t color, float opacity, float thickness);
1986
1987 template<int MODE> void _drawWireFrameLines(int nb_lines, const uint16_t* ind_vertices, const fVec3* vertices, color_t color, float opacity, float thickness);
1988
1989 template<int MODE> void _drawWireFrameTriangle(const fVec3& P1, const fVec3& P2, const fVec3& P3, color_t color, float opacity, float thickness);
1990
1991 template<int MODE> void _drawWireFrameTriangles(int nb_triangles, const uint16_t* ind_vertices, const fVec3* vertices, color_t color, float opacity, float thickness);
1992
1993 template<int MODE> void _drawWireFrameQuad(const fVec3& P1, const fVec3& P2, const fVec3& P3, const fVec3& P4, color_t color, float opacity, float thickness);
1994
1995 template<int MODE> void _drawWireFrameQuads(int nb_quads, const uint16_t* ind_vertices, const fVec3* vertices, color_t color, float opacity, float thickness);
1996
1997
1998
1999
2000 /***********************************************************
2001 * Simple geometric objects
2002 ************************************************************/
2003
2004
2005 template<bool USE_BLENDING> void _drawPixel(const fVec3& pos, color_t color, float opacity);
2006
2007
2008 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);
2009
2010
2011 template<bool USE_BLENDING> void _drawDot(const fVec3& pos, int r, color_t color, float opacity);
2012
2013
2014 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);
2015
2016
2017
2018 template<bool CHECKRANGE, bool USE_BLENDING> TGX_INLINE inline void drawPixelZbuf(int x, int y, color_t color, float opacity, float z)
2019 {
2020 if (CHECKRANGE && ((x < 0) || (x >= _uni.im->lx()) || (y < 0) || (y >= _uni.im->ly()))) return;
2021 ZBUFFER_t& W = _uni.zbuf[x + _uni.im->lx() * y];
2022 const ZBUFFER_t aa = (std::is_same<ZBUFFER_t, uint16_t>::value) ? ((ZBUFFER_t)(z * _uni.wa + _uni.wb)) : ((ZBUFFER_t)z);
2023 if (W < aa)
2024 {
2025 W = aa;
2026 if (USE_BLENDING) _uni.im->template drawPixel<false>({ x, y }, color, opacity); else _uni.im->template drawPixel<false>({ x, y }, color);
2027 }
2028 }
2029
2030
2031 template<bool CHECKRANGE, bool USE_BLENDING> TGX_INLINE inline void drawHLineZbuf(int x, int y, int w, color_t color, float opacity, float z)
2032 {
2033 if (CHECKRANGE) // optimized away at compile time
2034 {
2035 const int lx = _uni.im->lx();
2036 const int ly = _uni.im->ly();
2037 if ((y < 0) || (y >= ly) || (x >= lx)) return;
2038 if (x < 0) { w += x; x = 0; }
2039 if (x + w > lx) { w = lx - x; }
2040 if (w <= 0) return;
2041 }
2042 while(w--) drawPixelZbuf<CHECKRANGE, USE_BLENDING>(x++, y, color, opacity, z);
2043 }
2044
2045
2046 template<bool CHECKRANGE, bool USE_BLENDING> void _drawCircleZbuf(int xm, int ym, int r, color_t color, float opacity, float z);
2047
2048
2052 float _unitSphereScreenDiameter();
2053
2054
2055 template<bool WIREFRAME, int MODE> void _drawSphere(int nb_sectors, int nb_stacks, const Image<color_t>* texture, float thickness, color_t color, float opacity);
2056
2057
2058
2059 /***********************************************************
2060 * CLIPPING
2061 ************************************************************/
2062
2063
2065 TGX_INLINE inline void _clip(int & fl, const fVec4 & P, float bx, float Bx, float by, float By)
2066 {
2067 if (P.x >= bx) { fl &= (~(1)); }
2068 if (P.x <= Bx) { fl &= (~(2)); }
2069 if (P.y >= by) { fl &= (~(4)); }
2070 if (P.y <= By) { fl &= (~(8)); }
2071 if ((P.z >= -1.0f)&&(P.w > 0)) { fl &= (~(16)); }
2072 if (P.z <= +1.0f) { fl &= (~(32)); }
2073 }
2074
2075
2077 TGX_INLINE inline void _clip(int & fl, const fVec3 & P, float bx, float Bx, float by, float By, const fMat4 & M)
2078 {
2079 fVec4 S = M.mult1(P);
2080 if (!_ortho) S.zdivide();
2081 return _clip(fl, S, bx, Bx, by, By);
2082 }
2083
2084
2085 /* test if a box is outside the image and should be discarded.
2086 transform the box coords with M then z-divide. */
2087 bool _discardBox(const fBox3 & bb, const fMat4 & M)
2088 {
2089 if ((bb.minX == 0) && (bb.maxX == 0) && (bb.minY == 0) && (bb.maxY == 0) && (bb.minZ == 0) && (bb.maxZ == 0))
2090 return false; // do not discard if the bounding box is uninitialized.
2091
2092 const float bx = (_ox - 1) * _ilx - 1.0f;
2093 const float Bx = (_ox + _uni.im->width() + 1) * _ilx - 1.0f;
2094 const float by = (_oy - 1) * _ily - 1.0f;
2095 const float By = (_oy + _uni.im->height() + 1) * _ily - 1.0f;
2096
2097 int fl = 63; // every bit set
2098 _clip(fl, fVec3(bb.minX, bb.minY, bb.minZ), bx, Bx, by, By, M);
2099 if (fl == 0) return false;
2100 _clip(fl, fVec3(bb.minX, bb.minY, bb.maxZ), bx, Bx, by, By, M);
2101 if (fl == 0) return false;
2102 _clip(fl, fVec3(bb.minX, bb.maxY, bb.minZ), bx, Bx, by, By, M);
2103 if (fl == 0) return false;
2104 _clip(fl, fVec3(bb.minX, bb.maxY, bb.maxZ), bx, Bx, by, By, M);
2105 if (fl == 0) return false;
2106 _clip(fl, fVec3(bb.maxX, bb.minY, bb.minZ), bx, Bx, by, By, M);
2107 if (fl == 0) return false;
2108 _clip(fl, fVec3(bb.maxX, bb.minY, bb.maxZ), bx, Bx, by, By, M);
2109 if (fl == 0) return false;
2110 _clip(fl, fVec3(bb.maxX, bb.maxY, bb.minZ), bx, Bx, by, By, M);
2111 if (fl == 0) return false;
2112 _clip(fl, fVec3(bb.maxX, bb.maxY, bb.maxZ), bx, Bx, by, By, M);
2113 if (fl == 0) return false;
2114 return true;
2115 }
2116
2117
2118 /* test if a triangle is completely outside the image and should be discarded.
2119 * coords are given after z-divide. */
2120 bool _discardTriangle(const fVec4 & P1, const fVec4 & P2, const fVec4 & P3)
2121 {
2122 const float bx = (_ox - 1) * _ilx - 1.0f;
2123 const float Bx = (_ox + _uni.im->width() + 1) * _ilx - 1.0f;
2124 const float by = (_oy - 1) * _ily - 1.0f;
2125 const float By = (_oy + _uni.im->height() + 1) * _ily - 1.0f;
2126
2127 int fl = 63; // every bit set
2128 _clip(fl, P1, bx, Bx, by, By);
2129 if (fl == 0) return false;
2130 _clip(fl, P2, bx, Bx, by, By);
2131 if (fl == 0) return false;
2132 _clip(fl, P3, bx, Bx, by, By);
2133 if (fl == 0) return false;
2134 return true;
2135 }
2136
2137
2139 bool _clip2(float clipboundXY, const fVec3 & P, const fMat4 & M)
2140 {
2141 fVec4 S = M.mult1(P);
2142 if (!_ortho)
2143 {
2144 S.zdivide();
2145 if (S.w <= 0) S.z = -2;
2146 }
2147 return ((S.x <= -clipboundXY) || (S.x >= clipboundXY)
2148 || (S.y <= -clipboundXY) || (S.y >= clipboundXY)
2149 || (S.z <= -1) || (S.z >= 1));
2150 }
2151
2152
2154 bool _clipTestNeeded(float clipboundXY, const fBox3 & bb, const fMat4 & M)
2155 {
2156 return (_clip2(clipboundXY, fVec3(bb.minX, bb.minY, bb.minZ), M)
2157 || _clip2(clipboundXY, fVec3(bb.minX, bb.minY, bb.maxZ), M)
2158 || _clip2(clipboundXY, fVec3(bb.minX, bb.maxY, bb.minZ), M)
2159 || _clip2(clipboundXY, fVec3(bb.minX, bb.maxY, bb.maxZ), M)
2160 || _clip2(clipboundXY, fVec3(bb.maxX, bb.minY, bb.minZ), M)
2161 || _clip2(clipboundXY, fVec3(bb.maxX, bb.minY, bb.maxZ), M)
2162 || _clip2(clipboundXY, fVec3(bb.maxX, bb.maxY, bb.minZ), M)
2163 || _clip2(clipboundXY, fVec3(bb.maxX, bb.maxY, bb.maxZ), M));
2164 }
2165
2166
2168 bool _wireFrameAANeighborCheckNeeded(const fBox3& bb, const fMat4& proj_modelview)
2169 {
2170 if ((_uni.im == nullptr) || (_uni.im->lx() <= 2) || (_uni.im->ly() <= 2)) return true;
2171
2172 const float bx = (_ox + 1.0f) * _ilx - 1.0f;
2173 const float Bx = (_ox + (float)(_uni.im->lx() - 2)) * _ilx - 1.0f;
2174 const float by = (_oy + 1.0f) * _ily - 1.0f;
2175 const float By = (_oy + (float)(_uni.im->ly() - 2)) * _ily - 1.0f;
2176
2177 const fVec3 C[8] = {
2178 fVec3(bb.minX, bb.minY, bb.minZ),
2179 fVec3(bb.minX, bb.minY, bb.maxZ),
2180 fVec3(bb.minX, bb.maxY, bb.minZ),
2181 fVec3(bb.minX, bb.maxY, bb.maxZ),
2182 fVec3(bb.maxX, bb.minY, bb.minZ),
2183 fVec3(bb.maxX, bb.minY, bb.maxZ),
2184 fVec3(bb.maxX, bb.maxY, bb.minZ),
2185 fVec3(bb.maxX, bb.maxY, bb.maxZ)
2186 };
2187
2188 for (int i = 0; i < 8; i++)
2189 {
2190 fVec4 P = proj_modelview.mult1(C[i]);
2191 if (!_ortho)
2192 {
2193 if (P.w <= 0) return true;
2194 P.zdivide();
2195 }
2196 if ((P.z < -1.0f) || (P.z > 1.0f)) return true;
2197 if ((P.x < bx) || (P.x > Bx) || (P.y < by) || (P.y > By)) return true;
2198 }
2199 return false;
2200 }
2201
2202
2203#if TGX_MESHLET_SPHERE_CLIP
2205 TGX_INLINE inline void _meshletClipPlanes(float clipboundXY, const fMat4& M, fVec4* planes, float* plane_norms) const
2206 {
2207 const float cx = clipboundXY;
2208 planes[0] = fVec4(M.M[0] + cx * M.M[3], M.M[4] + cx * M.M[7], M.M[8] + cx * M.M[11], M.M[12] + cx * M.M[15]);
2209 planes[1] = fVec4(-M.M[0] + cx * M.M[3], -M.M[4] + cx * M.M[7], -M.M[8] + cx * M.M[11], -M.M[12] + cx * M.M[15]);
2210 planes[2] = fVec4(M.M[1] + cx * M.M[3], M.M[5] + cx * M.M[7], M.M[9] + cx * M.M[11], M.M[13] + cx * M.M[15]);
2211 planes[3] = fVec4(-M.M[1] + cx * M.M[3], -M.M[5] + cx * M.M[7], -M.M[9] + cx * M.M[11], -M.M[13] + cx * M.M[15]);
2212 planes[4] = fVec4(M.M[2] + M.M[3], M.M[6] + M.M[7], M.M[10] + M.M[11], M.M[14] + M.M[15]);
2213 planes[5] = fVec4(-M.M[2] + M.M[3], -M.M[6] + M.M[7], -M.M[10] + M.M[11], -M.M[14] + M.M[15]);
2214 for (int i = 0; i < 6; i++)
2215 {
2216 const fVec4& P = planes[i];
2217 plane_norms[i] = sqrtf(P.x * P.x + P.y * P.y + P.z * P.z);
2218 }
2219 }
2220
2221
2223 TGX_INLINE inline int _meshletSphereClip(const fVec3& center, float radius, const fVec4* planes, const float* plane_norms) const
2224 {
2225 bool intersects = false;
2226 for (int i = 0; i < 6; i++)
2227 {
2228 const fVec4& P = planes[i];
2229 const float d = P.x * center.x + P.y * center.y + P.z * center.z + P.w;
2230 const float r = radius * plane_norms[i];
2231 if (d < -r) return -1;
2232 if (d < r) intersects = true;
2233 }
2234 return intersects ? 1 : 0;
2235 }
2236#endif
2237
2238
2239
2240
2241 /***********************************************************
2242 * TRIANGLE CLIPPING AGAINST A CLIP-PLANE
2243 ************************************************************/
2244
2253 inline float _cpdist(const tgx::fVec4& CP, float off, const tgx::fVec4& P)
2254 {
2255 return (CP.x * P.x) + (CP.y * P.y) + (CP.z * P.z) + (CP.w * P.w) + off;
2256 }
2257
2268 inline float _cpfactor(const tgx::fVec4& CP, const float sdistA, const float sdistB)
2269 {
2270 return sdistA / (sdistA - sdistB);
2271 }
2272
2273
2275 void _triangleClip1in(int shader, tgx::fVec4 CP,
2276 float cp1, float cp2, float cp3,
2277 const RasterizerVec4& P1, const RasterizerVec4& P2, const RasterizerVec4& P3,
2278 RasterizerVec4& nP1, RasterizerVec4& nP2, RasterizerVec4& nP3, RasterizerVec4& nP4);
2279
2280
2282 void _triangleClip2in(int shader, tgx::fVec4 CP,
2283 float cp1, float cp2, float cp3,
2284 const RasterizerVec4& P1, const RasterizerVec4& P2, const RasterizerVec4& P3,
2285 RasterizerVec4& nP1, RasterizerVec4& nP2, RasterizerVec4& nP3, RasterizerVec4& nP4);
2286
2287
2288 int _triangleClip(int shader, tgx::fVec4 CP, float off,
2289 const RasterizerVec4 & P1, const RasterizerVec4 & P2, const RasterizerVec4 & P3,
2290 RasterizerVec4 & nP1, RasterizerVec4 & nP2, RasterizerVec4 & nP3, RasterizerVec4 & nP4);
2291
2292
2293
2294 /***********************************************************
2295 * PHONG LIGHTNING
2296 ************************************************************/
2297
2298 static const int _POWTABSIZE = 32; // number of entries in the precomputed power table for specular exponent.
2299 int _currentpow; // exponent for the currently computed table (<0 if table not yet computed)
2300 float _powmax; // used to compute exponent
2301 float _fastpowtab[_POWTABSIZE]; // the precomputed power table.
2302
2304 TGX_INLINE inline void _precomputeSpecularTable(int exponent)
2305 {
2306 if (_currentpow == exponent) return;
2307 _precomputeSpecularTable2(exponent);
2308 }
2309
2310 TGX_NOINLINE void _precomputeSpecularTable2(int exponent);
2311
2312
2314 TGX_INLINE inline float _powSpecular(float x) const
2315 {
2316 const float indf = (_powmax - x) * _POWTABSIZE;
2317 const int indi = max(0,(int)indf);
2318 return (indi >= (_POWTABSIZE - 1)) ? 0.0f : (_fastpowtab[indi] + (indf - indi) * (_fastpowtab[indi + 1] - _fastpowtab[indi]));;
2319 }
2320
2321
2323 template<bool TEXTURE> TGX_INLINE inline RGBf _phong(float v_diffuse, float v_specular) const
2324 {
2325 RGBf col = _r_ambiantColor;
2326 col += _r_diffuseColor * max(v_diffuse, 0.0f);
2327 col += _r_specularColor * _powSpecular(v_specular); // pow() this is too slow so we use a lookup table instead
2328 if (!(TEXTURE)) col *= _r_objectColor;
2329 col.clamp();
2330 return col;
2331 }
2332
2333
2335 TGX_INLINE inline RGBf _phong(float v_diffuse, float v_specular, RGBf color) const
2336 {
2337 RGBf col = _r_ambiantColor;
2338 col += _r_diffuseColor * max(v_diffuse, 0.0f);
2339 col += _r_specularColor * _powSpecular(v_specular); // pow() this is too slow so we use a lookup table instead
2340 col *= color;
2341 col.clamp();
2342 return col;
2343 }
2344
2345
2347 TGX_INLINE inline void _setFlatOrUnlitFaceColor(int raster_type, bool texture, fVec3& faceN, float cu)
2348 {
2349 if constexpr (TGX_SHADER_HAS_UNLIT(ENABLED_SHADERS))
2350 {
2351 if (TGX_SHADER_HAS_UNLIT(raster_type))
2352 {
2353 _uni.facecolor = texture ? RGBf(1.0f, 1.0f, 1.0f) : _r_objectColor;
2354 return;
2355 }
2356 }
2357
2358 const float icu = ((cu > 0) ? -1.0f : 1.0f); // -1 if we need to reverse the face normal.
2359 faceN.normalize_fast();
2360 if (texture)
2361 _uni.facecolor = _phong<true>(icu * dotProduct(faceN, _r_light), icu * dotProduct(faceN, _r_H));
2362 else
2363 _uni.facecolor = _phong<false>(icu * dotProduct(faceN, _r_light), icu * dotProduct(faceN, _r_H));
2364 }
2365
2366
2367
2368 /***********************************************************
2369 * MEMBER VARIABLES
2370 ************************************************************/
2371
2372 // *** general parameters ***
2373
2374 int _lx, _ly; // viewport dimension
2375 float _ilx, _ily; // inverse viewport dimension
2376
2377 int _ox, _oy; // image offset w.r.t. the viewport
2378
2379 bool _ortho; // true to use orthographic projection and false for perspective projection
2380
2381 fMat4 _projM; // projection matrix
2382
2383 RasterizerParams<color_t, color_t,ZBUFFER_t> _uni; // rasterizer param (contain the image pointer and the zbuffer pointer).
2384
2385 float _culling_dir; // culling direction postive/negative or 0 to disable back face culling.
2386
2387 int _shaders; // the shaders to use.
2388 int _texture_wrap_mode; // wrapping mode (wrap_pow2 or clamp)
2389 int _texture_quality; // texturing quality (nearest or bilinear)
2390
2391 // *** scene parameters ***
2392
2393 fMat4 _viewM; // view transform matrix
2394
2395 fVec3 _light; // light direction
2396 RGBf _ambiantColor; // light ambiant color
2397 RGBf _diffuseColor; // light diffuse color
2398 RGBf _specularColor; // light specular color
2399
2400
2401 // *** model specific parameters ***
2402
2403 fMat4 _modelM; // model transform matrix
2404
2405 RGBf _color; // model color (use when texturing is disabled)
2406 float _ambiantStrength; // ambient light reflection strength
2407 float _diffuseStrength; // diffuse light reflection strength
2408 float _specularStrength; // specular light reflection strength
2409 int _specularExponent; // specular exponent
2410
2411
2412 // *** pre-computed values ***
2413 fMat4 _r_modelViewM; // model-view matrix
2414 float _r_inorm; // Fast normal scaling for lighting. Assumes rotation/uniform scale;
2415 // Gouraud lighting is approximate with non-uniform model scaling.
2416 fVec3 _r_light; // light vector in view space (inverted and normalized)
2417 fVec3 _r_light_inorm; // same as above but already multiplied by inorm
2418 fVec3 _r_H; // halfway vector.
2419 fVec3 _r_H_inorm; // same as above but already multiplied by inorm
2420 RGBf _r_ambiantColor; // ambient color multiplied by object ambient strength
2421 RGBf _r_diffuseColor; // diffuse color multiplied by object diffuse strength
2422 RGBf _r_specularColor; // specular color multiplied by object specular strength
2423 RGBf _r_objectColor; // color to use for drawing the object (either _color or mesh->color).
2424
2425
2429 struct ExtVec4 : public RasterizerVec4
2430 {
2431 fVec4 P; // after model-view matrix multiplication
2432 fVec4 N; // normal vector after model-view matrix multiplication
2433 bool missedP; // true if the attributes should be computed
2434 int indn; // index for normal vector in array
2435 int indt; // index for texture vector in array
2436 };
2437
2438
2439 };
2440
2441
2442
2443}
2444
2445
2446
2447
2448#include "Renderer3D.inl"
2449
2450
2451#endif
2452
2453#endif
2454
2455
Box2.h
2D box class
Box3.h
3D box class
Color.h
Color classes [RGB565, RGB24, RGB32, RGB64, RGBf, HSV].
Image.h
Main image class.
Mat4.h
4x4 matrix class.
tgx::fMat4
Mat4< float > fMat4
4x4 matrix with single (float) precision
Definition: Mat4.h:54
Mesh3D.h
3D model mesh class.
Mesh3Dv2.h
Compact meshlet-based 3D model mesh format with 16-bit quantization.
Misc.h
Utility/miscellaneous functions used throughout the library.
tgx::max
TGX_INLINE T max(const T &a, const T &b)
Don't know why but much faster than fmaxf() for floats.
Definition: Misc.h:153
Rasterizer.h
3D triangle rasterizer function.
TGX_RASTERIZE_SUBPIXEL_BITS
#define TGX_RASTERIZE_SUBPIXEL_BITS
Sub-pixel precision bits.
Definition: Rasterizer.h:46
tgx::Shader
Shader
List of shaders available for 3D graphics.
Definition: ShaderParams.h:44
tgx::SHADER_NOTEXTURE
@ SHADER_NOTEXTURE
disable texture mapping
Definition: ShaderParams.h:59
tgx::SHADER_TEXTURE
@ SHADER_TEXTURE
enable texture mapping
Definition: ShaderParams.h:60
Shaders.h
Triangle shader functions.
Vec2.h
2D vector.
tgx::dotProduct
T dotProduct(const Vec2< T > U, const Vec2< T > V)
Return the dot product U.V between two vectors.
Definition: Vec2.h:560
Vec3.h
3D vector.
tgx::fVec3
Vec3< float > fVec3
Floating point valued 3D vector with single (float) precision.
Definition: Vec3.h:52
Vec4.h
4D vector.
tgx::fVec4
Vec4< float > fVec4
Floating point valued 4D vector with single (float) precision.
Definition: Vec4.h:54
tgx::Image
Image class [MAIN CLASS FOR THE 2D API].
Definition: Image.h:145
tgx::Renderer3D
Class for drawing 3D objects onto a Image [MAIN CLASS FOR THE 3D API].
Definition: Renderer3D.h:109
tgx::Renderer3D::drawAdaptativeSphere
void drawAdaptativeSphere(float quality=1.0f)
Draw a unit radius sphere centered at the origin S(0,1) in model space.
tgx::Renderer3D::drawQuads
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.
tgx::Renderer3D::drawWireFrameLine
void drawWireFrameLine(const fVec3 &P1, const fVec3 &P2)
Draw a wireframe line segment [fast].
tgx::Renderer3D::drawMesh
void drawMesh(const Mesh3D< color_t > *mesh, bool use_mesh_material=true, bool draw_chained_meshes=true)
Draw a Mesh3D object.
tgx::Renderer3D::drawDot
void drawDot(const fVec3 &pos, int r, color_t color, float opacity)
Draw a dot/circle at a given position in model space.
tgx::Renderer3D::setMaterialAmbiantStrength
void setMaterialAmbiantStrength(float strenght=0.1f)
Set how much the object material reflects the ambient light.
tgx::Renderer3D::drawWireFrameMesh
void drawWireFrameMesh(const Mesh3Dv2< color_t > *mesh, float thickness, color_t color, float opacity)
Draw a Mesh3Dv2 object in wireframe [adjustable thickness + AA].
tgx::Renderer3D::drawSphere
void drawSphere(int nb_sectors, int nb_stacks)
Draw a unit radius sphere centered at the origin S(0,1) in model space.
tgx::Renderer3D::drawWireFrameAdaptativeSphere
void drawWireFrameAdaptativeSphere(float quality, float thickness, color_t color, float opacity)
Draw a wireframe unit radius sphere centered at the origin (in model space) [adjustable thickness + A...
tgx::Renderer3D::drawWireFrameCubeAA
void drawWireFrameCubeAA()
Draw the wireframe cube [0,1]^3 [antialiased] with the current material color.
tgx::Renderer3D::setMaterialSpecularExponent
void setMaterialSpecularExponent(int exponent=16)
Set the object specular exponent.
tgx::Renderer3D::drawWireFrameTriangle
void drawWireFrameTriangle(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3)
Draw a wireframe triangle [fast].
tgx::Renderer3D::drawWireFrameCube
void drawWireFrameCube()
Draw the wireframe cube [0,1]^3 (in model space) [fast].
tgx::Renderer3D::drawWireFrameMeshAA
void drawWireFrameMeshAA(const Mesh3D< color_t > *mesh, bool draw_chained_meshes=true)
Draw a mesh in wireframe [antialiased] with the current material color.
tgx::Renderer3D::setMaterialSpecularStrength
void setMaterialSpecularStrength(float strenght=0.5f)
Set how much the object material reflects the specular light.
tgx::Renderer3D::setMaterialDiffuseStrength
void setMaterialDiffuseStrength(float strenght=0.6f)
Set how much the object material reflects the diffuse light.
tgx::Renderer3D::drawWireFrameQuad
void drawWireFrameQuad(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, const fVec3 &P4)
Draw a wireframe quad [fast].
tgx::Renderer3D::setShaders
void setShaders(Shader shaders)
Set the shaders to use for subsequent drawing operations.
tgx::Renderer3D::modelToImage
iVec2 modelToImage(fVec3 P)
Convert from model coordinates to the corresponding image pixel.
tgx::Renderer3D::setModelPosScaleRot
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 transformation matrix to move an object to a given location, scale and rotation.
tgx::Renderer3D::drawCube
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)
tgx::Renderer3D::drawDots
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.
tgx::Renderer3D::getViewMatrix
fMat4 getViewMatrix() const
Return the current view matrix.
tgx::Renderer3D::setLookAt
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.
tgx::Renderer3D::drawWireFrameMesh
void drawWireFrameMesh(const Mesh3D< color_t > *mesh, bool draw_chained_meshes, float thickness, color_t color, float opacity)
Draw a mesh in wireframe [adjustable thickness + AA].
tgx::Renderer3D::drawWireFrameQuads
void drawWireFrameQuads(int nb_quads, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw a collection of wireframe quads [fast].
tgx::Renderer3D::setLightAmbiant
void setLightAmbiant(const RGBf &color)
Set the scene ambiant light color.
tgx::Renderer3D::drawWireFrameAdaptativeSphere
void drawWireFrameAdaptativeSphere(float quality=1.0f)
Draw a wireframe unit radius sphere centered at the origin (in model space) [fast].
tgx::Renderer3D::drawCube
void drawCube()
Draw the unit cube [-1,1]^3 in model space.
tgx::Renderer3D::drawWireFrameSphere
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) [adjustable thickness + A...
tgx::Renderer3D::getProjectionMatrix
fMat4 getProjectionMatrix() const
Return the current projection matrix.
tgx::Renderer3D::drawWireFrameLines
void drawWireFrameLines(int nb_lines, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw a collection of wireframe line segments [fast].
tgx::Renderer3D::setZbuffer
void setZbuffer(ZBUFFER_t *zbuffer)
Set the z-buffer.
tgx::Renderer3D::drawWireFrameMesh
void drawWireFrameMesh(const Mesh3Dv2< color_t > *mesh)
Draw a Mesh3Dv2 object in wireframe [fast].
tgx::Renderer3D::setMaterialColor
void setMaterialColor(RGBf color)
Set the object material color.
tgx::Renderer3D::setLightDirection
void setLightDirection(const fVec3 &direction)
Set the light source direction.
tgx::Renderer3D::drawMesh
void drawMesh(const Mesh3Dv2< color_t > *mesh, bool use_mesh_material=true)
Draw a Mesh3Dv2 object.
tgx::Renderer3D::setLight
void setLight(const fVec3 direction, const RGBf &ambiantColor, const RGBf &diffuseColor, const RGBf &specularColor)
Set all the lighting parameters of the scene at once.
tgx::Renderer3D::setMaterial
void setMaterial(RGBf color, float ambiantStrength, float diffuseStrength, float specularStrength, int specularExponent)
Set all the object material properties at once.
tgx::Renderer3D::setTextureWrappingMode
void setTextureWrappingMode(Shader wrap_mode)
Set the wrap mode when for texturing.
tgx::Renderer3D::drawDots
void drawDots(int nb_dots, const fVec3 *pos_list, const int radius)
Draw a list of dots/circles at given positions in model space.
tgx::Renderer3D::worldToNDC
fVec4 worldToNDC(fVec3 P)
Convert from world coordinates to normalized device coordinates (NDC).
tgx::Renderer3D::setViewMatrix
void setViewMatrix(const fMat4 &M)
Set the view transformation matrix.
tgx::Renderer3D::setViewportSize
void setViewportSize(const iVec2 &viewport_dim)
Set the size of the viewport.
tgx::Renderer3D::Renderer3D
TGX_NOINLINE Renderer3D(const iVec2 &viewportSize={0, 0}, Image< color_t > *im=nullptr, ZBUFFER_t *zbuffer=nullptr)
Constructor.
tgx::Renderer3D::setViewportSize
void setViewportSize(int lx, int ly)
Set the size of the viewport.
tgx::Renderer3D::worldToImage
iVec2 worldToImage(fVec3 P)
Convert from world coordinates to the corresponding image pixel.
tgx::Renderer3D::setCulling
void setCulling(int w)
Set the face culling strategy.
tgx::Renderer3D::drawWireFrameSphereAA
void drawWireFrameSphereAA(int nb_sectors, int nb_stacks)
Draw a wireframe unit radius sphere [antialiased] with the current material color.
tgx::Renderer3D::drawTriangleWithVertexColor
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.
tgx::Renderer3D::usePerspectiveProjection
void usePerspectiveProjection()
Set projection mode to perspective (ie with z-divide).
tgx::Renderer3D::setModelMatrix
void setModelMatrix(const fMat4 &M)
Set the model transformation matrix.
tgx::Renderer3D::drawWireFrameTriangle
void drawWireFrameTriangle(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, float thickness, color_t color, float opacity)
Draw a wireframe triangle [adjustable thickness + AA].
tgx::Renderer3D::setPerspective
void setPerspective(float fovy, float aspect, float zNear, float zFar)
Set the projection matrix as a perspective matrix.
tgx::Renderer3D::drawWireFrameQuads
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 [adjustable thickness + AA].
tgx::Renderer3D::drawPixel
void drawPixel(const fVec3 &pos)
Draw a single pixel at a given position in model space.
tgx::Renderer3D::setOrtho
void setOrtho(float left, float right, float bottom, float top, float zNear, float zFar)
Set the projection matrix as an orthographic matrix.
tgx::Renderer3D::getModelMatrix
fMat4 getModelMatrix() const
Return the model transformation matrix.
tgx::Renderer3D::drawWireFrameLines
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 [adjustable thickness + AA].
tgx::Renderer3D::setImage
void setImage(Image< color_t > *im)
Set the image that will be drawn onto.
tgx::Renderer3D::drawPixels
void drawPixels(int nb_pixels, const fVec3 *pos_list)
Draw a list of pixels at given positions in model space.
tgx::Renderer3D::drawPixel
void drawPixel(const fVec3 &pos, color_t color, float opacity)
Draw a single pixel at a given position in model space.
tgx::Renderer3D::drawWireFrameLinesAA
void drawWireFrameLinesAA(int nb_lines, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw wireframe line segments [antialiased] with the current material color.
tgx::Renderer3D::drawWireFrameLineAA
void drawWireFrameLineAA(const fVec3 &P1, const fVec3 &P2)
Draw a wireframe line segment [antialiased] with the current material color.
tgx::Renderer3D::setLightDiffuse
void setLightDiffuse(const RGBf &color)
Set the scene diffuse light color.
tgx::Renderer3D::setLightSpecular
void setLightSpecular(const RGBf &color)
Set the scene specular light color.
tgx::Renderer3D::setOffset
void setOffset(const iVec2 &offset)
Set the offset of the image relative to the viewport.
tgx::Renderer3D::drawCube
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.
tgx::Renderer3D::drawWireFrameQuadsAA
void drawWireFrameQuadsAA(int nb_quads, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw wireframe quads [antialiased] with the current material color.
tgx::Renderer3D::drawWireFrameQuad
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 [adjustable thickness + AA].
tgx::Renderer3D::setLookAt
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.
tgx::Renderer3D::drawWireFrameMeshAA
void drawWireFrameMeshAA(const Mesh3Dv2< color_t > *mesh)
Draw a Mesh3Dv2 object in wireframe [antialiased] with the current material color.
tgx::Renderer3D::drawWireFrameQuadAA
void drawWireFrameQuadAA(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, const fVec3 &P4)
Draw a wireframe quad [antialiased] with the current material color.
tgx::Renderer3D::useOrthographicProjection
void useOrthographicProjection()
Set projection mode to orthographic (ie no z-divide).
tgx::Renderer3D::drawTriangle
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.
tgx::Renderer3D::drawWireFrameTrianglesAA
void drawWireFrameTrianglesAA(int nb_triangles, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw wireframe triangles [antialiased] with the current material color.
tgx::Renderer3D::drawTriangles
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.
tgx::Renderer3D::clearZbuffer
void clearZbuffer()
Clear the Zbuffer.
tgx::Renderer3D::drawWireFrameLine
void drawWireFrameLine(const fVec3 &P1, const fVec3 &P2, float thickness, color_t color, float opacity)
Draw a wireframe line segment [adjustable thickness + AA].
tgx::Renderer3D::drawQuadWithVertexColor
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.
tgx::Renderer3D::drawWireFrameMesh
void drawWireFrameMesh(const Mesh3D< color_t > *mesh, bool draw_chained_meshes=true)
Draw a mesh in wireframe [fast].
tgx::Renderer3D::modelToNDC
fVec4 modelToNDC(fVec3 P)
Convert from model coordinates to normalized device coordinates (NDC).
tgx::Renderer3D::drawWireFrameTriangles
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 [adjustable thickness + AA].
tgx::Renderer3D::drawSphere
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.
tgx::Renderer3D::drawDot
void drawDot(const fVec3 &pos, int r)
Draw a dot/circle at a given position in model space.
tgx::Renderer3D::setFrustum
void setFrustum(float left, float right, float bottom, float top, float zNear, float zFar)
Set the projection matrix as a perspective matrix.
tgx::Renderer3D::setProjectionMatrix
void setProjectionMatrix(const fMat4 &M)
Set the projection matrix.
tgx::Renderer3D::setTextureQuality
void setTextureQuality(Shader quality)
Set the texturing quality.
tgx::Renderer3D::drawPixels
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.
tgx::Renderer3D::drawWireFrameTriangleAA
void drawWireFrameTriangleAA(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3)
Draw a wireframe triangle [antialiased] with the current material color.
tgx::Renderer3D::drawAdaptativeSphere
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.
tgx::Renderer3D::drawWireFrameSphere
void drawWireFrameSphere(int nb_sectors, int nb_stacks)
Draw a wireframe unit radius sphere centered at the origin (in model space) [fast].
tgx::Renderer3D::drawWireFrameTriangles
void drawWireFrameTriangles(int nb_triangles, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw a collection of wireframe triangles [fast].
tgx::Renderer3D::drawQuad
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.
tgx::Renderer3D::setOffset
void setOffset(int ox, int oy)
Set the offset of the image relative to the viewport.
tgx::Renderer3D::drawWireFrameCube
void drawWireFrameCube(float thickness, color_t color, float opacity)
Draw the wireframe cube [0,1]^3 (in model space) [adjustable thickness + AA].
tgx::Renderer3D::drawWireFrameAdaptativeSphereAA
void drawWireFrameAdaptativeSphereAA(float quality=1.0f)
Draw an adaptive wireframe sphere [antialiased] with the current material color.
tgx::Mat4< float >
tgx::Mat4::mult1
TGX_INLINE Vec4< T > mult1(const Vec3< T > &V) const
Matrix-vector multiplication (last component of vector set to w = 1)
Definition: Mat4.h:578
tgx::Mat4::mult0
TGX_INLINE Vec4< T > mult0(const Vec3< T > &V) const
Matrix-vector multiplication (last component of vector set to w = 0).
Definition: Mat4.h:557
tgx::Mesh3D
3D mesh data structure.
Definition: Mesh3D.h:155
tgx::Mesh3Dv2
Compact meshlet-based 3D mesh data structure.
Definition: Mesh3Dv2.h:207
tgx::RGBf
Color in R,G,B float format.
Definition: Color.h:2407
tgx::RGBf::clamp
void clamp()
Clamp all color channel to [0.0f,1.0f].
Definition: Color.h:2647
tgx::Vec2
Generic 2D vector [specializations iVec2, fVec2, dVec2].
Definition: Vec2.h:64
tgx::Vec2::x
T x
'x' coordinate (first dimension)
Definition: Vec2.h:72
tgx::Vec2::y
T y
'y' coordinate (second dimension)
Definition: Vec2.h:73
tgx::Vec3< float >
tgx::Vec3::z
T z
'z' coordinate (third dimension)
Definition: Vec3.h:83
tgx::Vec4< float >
tgx::Vec4::w
T w
'w' coordinate (fourth dimension)
Definition: Vec4.h:85
tgx::Vec4::zdivide
void zdivide()
Performs the 'z-divide' operation.
Definition: Vec4.h:478