| TGX 1.1.4 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#include "Renderer3DSpotLightData.h"
41
42#include "Mesh3D.h"
43#include "Mesh3Dv2.h"
44
45 namespace tgx
46{
47
48 // forward declaration for the vertices and faces of the unit cube [-1,1]^3
49
50 extern const tgx::fVec3 UNIT_CUBE_VERTICES[8];
51 extern const tgx::fVec3 UNIT_CUBE_NORMALS[6];
52 extern const uint16_t UNIT_CUBE_FACES[6*4];
53 extern const uint16_t UNIT_CUBE_FACES_NORMALS[6 * 4];
54
55
118 template<typename color_t, Shader LOADED_SHADERS, typename ZBUFFER_t = uint16_t, int MAX_DIRECTIONAL_LIGHTS = 1, int MAX_SPOT_LIGHTS = 0>
119 class Renderer3D
120 {
121
122
123 static constexpr int MAXVIEWPORTDIMENSION = 2048 * (1 << ((8 - TGX_RASTERIZE_SUBPIXEL_BITS) >> 1));
124
125 static_assert(is_color<color_t>::value, "color_t must be one of the color types defined in color.h");
126 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");
127 static_assert(MAX_DIRECTIONAL_LIGHTS >= 1, "MAX_DIRECTIONAL_LIGHTS must be at least 1");
128 static_assert(MAX_SPOT_LIGHTS >= 0, "MAX_SPOT_LIGHTS must be non-negative");
129
130 // true if some kind of texturing may be used.
131 static constexpr int ENABLE_TEXTURING = (TGX_SHADER_HAS_ONE_FLAG(LOADED_SHADERS , (SHADER_TEXTURE | SHADER_TEXTURE_AFFINE | TGX_SHADER_MASK_TEXTURE_MODE | TGX_SHADER_MASK_TEXTURE_QUALITY)));
132 static constexpr int EXPLICIT_TEXTURE_MODE = (TGX_SHADER_HAS_TEXTURING_ENABLED(LOADED_SHADERS));
133 static constexpr Shader DEFAULT_TEXTURE_MODE = EXPLICIT_TEXTURE_MODE ? (Shader)0 : SHADER_TEXTURE;
134
135 static constexpr Shader ENABLED_SHADERS = LOADED_SHADERS | (ENABLE_TEXTURING ? DEFAULT_TEXTURE_MODE : SHADER_NOTEXTURE); // enable perspective texturing by default when only texturing options are set
136 // check that disabled shaders do not completely disable all drawing operations.
137 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");
138 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");
139 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");
140 static_assert(TGX_SHADER_HAS_ONE_FLAG(ENABLED_SHADERS,TGX_SHADER_MASK_TEXTURE), "At least one of the shaders SHADER_NOTEXTURE, SHADER_TEXTURE or SHADER_TEXTURE_AFFINE must be enabled");
141 static_assert((!TGX_SHADER_HAS_TEXTURING_ENABLED(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");
142 static_assert((!TGX_SHADER_HAS_TEXTURING_ENABLED(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");
143
144 template<Shader SHADERS> static constexpr Shader _validatedDrawCallShaders();
145
146
147
148 public:
149
150
160 TGX_NOINLINE Renderer3D(const iVec2& viewportSize = {0,0}, Image<color_t> * im = nullptr, ZBUFFER_t * zbuffer = nullptr);
161
162
163
164
165 /*****************************************************************************************
166 *****************************************************************************************/
173 /*****************************************************************************************
174 ******************************************************************************************/
175
176
197 void setViewportSize(int lx, int ly);
198
199
207 void setViewportSize(const iVec2& viewport_dim);
208
209
221 void setImage(Image<color_t>* im);
222
223
242 void setOffset(int ox, int oy);
243
244
252 void setOffset(const iVec2& offset);
253
254
272 void setProjectionMatrix(const fMat4& M);
273
274
280 fMat4 getProjectionMatrix() const;
281
282
288 void useOrthographicProjection();
289
290
296 void usePerspectiveProjection();
297
298
315 void setOrtho(float left, float right, float bottom, float top, float zNear, float zFar);
316
317
334 void setFrustum(float left, float right, float bottom, float top, float zNear, float zFar);
335
336
354 void setPerspective(float fovy, float aspect, float zNear, float zFar);
355
356
374 void setCulling(int w);
375
376
389 void setZbuffer(ZBUFFER_t* zbuffer);
390
391
400 void clearZbuffer();
401
402
450 void setShaders(Shader shaders);
451
452
460 void setTextureWrappingMode(Shader wrap_mode);
461
462
470 void setTextureQuality(Shader quality);
471
472
473
475 /*****************************************************************************************
476 *****************************************************************************************/
483 /*****************************************************************************************
484 ******************************************************************************************/
485
486
487
504 void setViewMatrix(const fMat4& M);
505
506
514 fMat4 getViewMatrix() const;
515
516
528 void setLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ);
529
530
542 void setLookAt(const fVec3 eye, const fVec3 center, const fVec3 up);
543
544
557 fVec4 worldToNDC(fVec3 P);
558
559
571 iVec2 worldToImage(fVec3 P);
572
573
574
576 /*****************************************************************************************
577 *****************************************************************************************/
587 /*****************************************************************************************
588 ******************************************************************************************/
589
590
591 /*****************************************************************************************
592 * Directional lights.
593 ******************************************************************************************/
594
595
607 void setLightAmbiant(const RGBf& color);
608
621 void setLightDirection(const fVec3& direction);
622
623
624
625
638 void setLightDiffuse(const RGBf& color);
639
640
653 void setLightSpecular(const RGBf& color);
654
655
671 void setLight(const fVec3 direction, const RGBf& ambiantColor, const RGBf& diffuseColor, const RGBf& specularColor);
672
673
685 void setDirectionalLightCount(int count);
686
687
691 int directionalLightCount() const;
692
693
697 static constexpr int maxDirectionalLightCount() { return MAX_DIRECTIONAL_LIGHTS; }
698
699
709 void setDirectionalLightAmbiant(const RGBf& color);
710
711
721 void setDirectionalLightDirection(int index, const fVec3& direction);
722
723
732 void setDirectionalLightDiffuse(int index, const RGBf& color);
733
734
743 void setDirectionalLightSpecular(int index, const RGBf& color);
744
745
757 void setDirectionalLight(int index, const fVec3& direction, const RGBf& diffuseColor, const RGBf& specularColor);
758
759
760
761 /*****************************************************************************************
762 * Spot lights.
763 ******************************************************************************************/
764
765
777 void setSpotLightCount(int count);
778
779
783 int spotLightCount() const;
784
785
789 static constexpr int maxSpotLightCount() { return MAX_SPOT_LIGHTS; }
790
791
815 void setSpotLight(int index, const fVec3& position, float range,
816 const RGBf& diffuseColor,
817 const RGBf& specularColor = RGBf(0.0f, 0.0f, 0.0f));
818
819
847 void setSpotLight(int index, const fVec3& position, const fVec3& direction,
848 float range, float outerAngleDeg,
849 const RGBf& diffuseColor,
850 const RGBf& specularColor = RGBf(0.0f, 0.0f, 0.0f));
851
852
883 void setSpotLight(int index, const fVec3& position, const fVec3& direction,
884 float range, float outerAngleDeg, float innerAngleDeg,
885 const RGBf& diffuseColor,
886 const RGBf& specularColor = RGBf(0.0f, 0.0f, 0.0f));
887
888
897 void setSpotLightPosition(int index, const fVec3& position);
898
899
909 void setSpotLightDirection(int index, const fVec3& direction);
910
911
918 void setSpotLightDiffuse(int index, const RGBf& color);
919
920
930 void setSpotLightSpecular(int index, const RGBf& color = RGBf(0.0f, 0.0f, 0.0f));
931
932
943 void setSpotLightRange(int index, float range);
944
945
960 void setSpotLightCone(int index, float outerAngleDeg, float innerAngleDeg = -1.0f);
961
962
963
964
966 /*****************************************************************************************
967 *****************************************************************************************/
974 /*****************************************************************************************
975 ******************************************************************************************/
976
977
978
989 void setModelMatrix(const fMat4& M);
990
991
999 fMat4 getModelMatrix() const;
1000
1001
1023 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 });
1024
1025
1036 fVec4 modelToNDC(fVec3 P);
1037
1038
1050 iVec2 modelToImage(fVec3 P);
1051
1052
1063 void setMaterialColor(RGBf color);
1064
1065
1074 void setMaterialAmbiantStrength(float strenght = 0.1f);
1075
1076
1085 void setMaterialDiffuseStrength(float strenght = 0.6f);
1086
1087
1096 void setMaterialSpecularStrength(float strenght = 0.5f);
1097
1098
1109 void setMaterialSpecularExponent(int exponent = 16);
1110
1111
1124 void setMaterial(RGBf color, float ambiantStrength, float diffuseStrength, float specularStrength, int specularExponent);
1125
1126
1127
1128
1129
1130
1131
1132
1134 /*****************************************************************************************
1135 *****************************************************************************************/
1149 /*****************************************************************************************
1150 ******************************************************************************************/
1151
1152
1153
1170 void drawMesh(const Mesh3D<color_t>* mesh, bool use_mesh_material = true, bool draw_chained_meshes = true);
1171
1172
1182 template<Shader SHADERS>
1183 void drawMesh(const Mesh3D<color_t>* mesh, bool use_mesh_material = true, bool draw_chained_meshes = true);
1184
1185
1198 void drawMesh(const Mesh3Dv2<color_t>* mesh, bool use_mesh_material = true);
1199
1200
1210 template<Shader SHADERS>
1211 void drawMesh(const Mesh3Dv2<color_t>* mesh, bool use_mesh_material = true);
1212
1213
1227 void drawTriangle(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3,
1228 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr,
1229 const fVec2 * T1 = nullptr, const fVec2 * T2 = nullptr, const fVec2 * T3 = nullptr,
1230 const Image<color_t> * texture = nullptr);
1231
1232
1245 void drawTriangleWithVertexColor(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3,
1246 const RGBf & col1, const RGBf & col2, const RGBf & col3,
1247 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr);
1248
1249
1268 void drawTriangles(int nb_triangles,
1269 const uint16_t * ind_vertices, const fVec3 * vertices,
1270 const uint16_t * ind_normals = nullptr, const fVec3* normals = nullptr,
1271 const uint16_t * ind_texture = nullptr, const fVec2* textures = nullptr,
1272 const Image<color_t> * texture_image = nullptr);
1273
1274
1297 void drawTriangleStrip(int nb_indices,
1298 const uint16_t* ind_vertices, const fVec3* vertices,
1299 const uint16_t* ind_normals = nullptr, const fVec3* normals = nullptr,
1300 const uint16_t* ind_texture = nullptr, const fVec2* textures = nullptr,
1301 const Image<color_t>* texture_image = nullptr);
1302
1303
1304
1320 void drawQuad(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3, const fVec3 & P4,
1321 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr, const fVec3 * N4 = nullptr,
1322 const fVec2 * T1 = nullptr, const fVec2 * T2 = nullptr, const fVec2 * T3 = nullptr, const fVec2 * T4 = nullptr,
1323 const Image<color_t>* texture = nullptr);
1324
1325
1326
1342 void drawQuadWithVertexColor(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3, const fVec3 & P4,
1343 const RGBf & col1, const RGBf & col2, const RGBf & col3, const RGBf & col4,
1344 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr, const fVec3 * N4 = nullptr);
1345
1346
1347
1348
1369 void drawQuads(int nb_quads,
1370 const uint16_t * ind_vertices, const fVec3 * vertices,
1371 const uint16_t * ind_normals = nullptr, const fVec3* normals = nullptr,
1372 const uint16_t * ind_texture = nullptr, const fVec2* textures = nullptr,
1373 const Image<color_t>* texture_image = nullptr);
1374
1375
1376
1377
1379 /*****************************************************************************************
1380 *****************************************************************************************/
1387 /*****************************************************************************************
1388 ******************************************************************************************/
1389
1390
1391
1398 void drawCube();
1399
1400
1441 void drawCube(
1442 const fVec2 v_front_ABCD[4] , const Image<color_t>* texture_front,
1443 const fVec2 v_back_EFGH[4] , const Image<color_t>* texture_back,
1444 const fVec2 v_top_HADE[4] , const Image<color_t>* texture_top,
1445 const fVec2 v_bottom_BGFC[4], const Image<color_t>* texture_bottom,
1446 const fVec2 v_left_HGBA[4] , const Image<color_t>* texture_left,
1447 const fVec2 v_right_DCFE[4] , const Image<color_t>* texture_right
1448 );
1449
1450
1485 void drawCube(
1486 const Image<color_t>* texture_front,
1487 const Image<color_t>* texture_back,
1488 const Image<color_t>* texture_top,
1489 const Image<color_t>* texture_bottom,
1490 const Image<color_t>* texture_left,
1491 const Image<color_t>* texture_right
1492 );
1493
1494
1553 void drawSkyBox(
1554 const fVec2 v_front_ABCD[4] , const Image<color_t>* texture_front,
1555 const fVec2 v_back_EFGH[4] , const Image<color_t>* texture_back,
1556 const fVec2 v_top_HADE[4] , const Image<color_t>* texture_top,
1557 const fVec2 v_bottom_BGFC[4], const Image<color_t>* texture_bottom,
1558 const fVec2 v_left_HGBA[4] , const Image<color_t>* texture_left,
1559 const fVec2 v_right_DCFE[4] , const Image<color_t>* texture_right,
1560 float rot_angle_y = 0.0f,
1561 float reference_height = 0.0f,
1562 float skybox_radius = 32768.0f,
1563 Shader texture_quality = SHADER_TEXTURE_NEAREST,
1564 Shader texture_mode = SHADER_TEXTURE_CLAMP
1565 );
1566
1567
1573 void drawSkyBox(
1574 const Image<color_t>* texture_front,
1575 const Image<color_t>* texture_back,
1576 const Image<color_t>* texture_top,
1577 const Image<color_t>* texture_bottom,
1578 const Image<color_t>* texture_left,
1579 const Image<color_t>* texture_right,
1580 float rot_angle_y = 0.0f,
1581 float reference_height = 0.0f,
1582 float skybox_radius = 32768.0f,
1583 Shader texture_quality = SHADER_TEXTURE_NEAREST,
1584 Shader texture_mode = SHADER_TEXTURE_CLAMP
1585 );
1586
1587
1588
1599 void drawSphere(int nb_sectors, int nb_stacks);
1600
1601
1614 void drawSphere(int nb_sectors, int nb_stacks, const Image<color_t>* texture);
1615
1616
1631 void drawAdaptativeSphere(float quality = 1.0f);
1632
1633
1650 void drawAdaptativeSphere(const Image<color_t>* texture, float quality = 1.0f);
1651
1652
1653
1654
1673 void drawCylinder(int nb_sectors, bool bottom_cap = true, bool top_cap = true);
1674
1675
1691 void drawCylinder(int nb_sectors, const Image<color_t>* texture_side, const Image<color_t>* texture_bottom = nullptr, const Image<color_t>* texture_top = nullptr, bool bottom_cap = true, bool top_cap = true);
1692
1693
1703 void drawCone(int nb_sectors, bool bottom_cap = true);
1704
1705
1716 void drawCone(int nb_sectors, const Image<color_t>* texture_side, const Image<color_t>* texture_bottom = nullptr, bool bottom_cap = true);
1717
1718
1732 void drawTruncatedCone(int nb_sectors, float bottom_radius, float top_radius, bool bottom_cap = true, bool top_cap = true);
1733
1734
1749 void drawTruncatedCone(int nb_sectors, float bottom_radius, float top_radius, const Image<color_t>* texture_side, const Image<color_t>* texture_bottom = nullptr, const Image<color_t>* texture_top = nullptr, bool bottom_cap = true, bool top_cap = true);
1750
1751
1752
1753
1754
1755
1757 /*****************************************************************************************
1758 *****************************************************************************************/
1773 /*****************************************************************************************
1774 ******************************************************************************************/
1775
1776
1777
1789 void drawWireFrameMesh(const Mesh3D<color_t>* mesh, bool draw_chained_meshes = true);
1790
1791
1803 void drawWireFrameMesh(const Mesh3Dv2<color_t>* mesh);
1804
1805
1816 void drawWireFrameMeshAA(const Mesh3D<color_t>* mesh, bool draw_chained_meshes = true);
1817
1818
1828 void drawWireFrameMeshAA(const Mesh3Dv2<color_t>* mesh);
1829
1830
1847 void drawWireFrameMesh(const Mesh3D<color_t>* mesh, bool draw_chained_meshes, float thickness, color_t color, float opacity);
1848
1849
1866 void drawWireFrameMesh(const Mesh3Dv2<color_t>* mesh, float thickness, color_t color, float opacity);
1867
1868
1878 void drawWireFrameLine(const fVec3& P1, const fVec3& P2);
1879
1880
1890 void drawWireFrameLineAA(const fVec3& P1, const fVec3& P2);
1891
1892
1905 void drawWireFrameLine(const fVec3& P1, const fVec3& P2, float thickness, color_t color, float opacity);
1906
1907
1919 void drawWireFrameLines(int nb_lines, const uint16_t* ind_vertices, const fVec3* vertices);
1920
1921
1933 void drawWireFrameLinesAA(int nb_lines, const uint16_t* ind_vertices, const fVec3* vertices);
1934
1935
1950 void drawWireFrameLines(int nb_lines, const uint16_t* ind_vertices, const fVec3* vertices, float thickness, color_t color, float opacity);
1951
1952
1963 void drawWireFrameTriangle(const fVec3& P1, const fVec3& P2, const fVec3& P3);
1964
1965
1975 void drawWireFrameTriangleAA(const fVec3& P1, const fVec3& P2, const fVec3& P3);
1976
1977
1992 void drawWireFrameTriangle(const fVec3& P1, const fVec3& P2, const fVec3& P3, float thickness, color_t color, float opacity);
1993
1994
2007 void drawWireFrameTriangles(int nb_triangles, const uint16_t* ind_vertices, const fVec3* vertices);
2008
2009
2021 void drawWireFrameTrianglesAA(int nb_triangles, const uint16_t* ind_vertices, const fVec3* vertices);
2022
2023
2040 void drawWireFrameTriangles(int nb_triangles, const uint16_t* ind_vertices, const fVec3* vertices, float thickness, color_t color, float opacity);
2041
2042
2057 void drawWireFrameTriangleStrip(int nb_indices, const uint16_t* ind_vertices, const fVec3* vertices);
2058
2059
2073 void drawWireFrameTriangleStripAA(int nb_indices, const uint16_t* ind_vertices, const fVec3* vertices);
2074
2075
2094 void drawWireFrameTriangleStrip(int nb_indices, const uint16_t* ind_vertices, const fVec3* vertices, float thickness, color_t color, float opacity);
2095
2096
2108 void drawWireFrameQuad(const fVec3& P1, const fVec3& P2, const fVec3& P3, const fVec3& P4);
2109
2110
2120 void drawWireFrameQuadAA(const fVec3& P1, const fVec3& P2, const fVec3& P3, const fVec3& P4);
2121
2122
2138 void drawWireFrameQuad(const fVec3& P1, const fVec3& P2, const fVec3& P3, const fVec3& P4, float thickness, color_t color, float opacity);
2139
2140
2154 void drawWireFrameQuads(int nb_quads, const uint16_t* ind_vertices, const fVec3* vertices);
2155
2156
2168 void drawWireFrameQuadsAA(int nb_quads, const uint16_t* ind_vertices, const fVec3* vertices);
2169
2170
2188 void drawWireFrameQuads(int nb_quads, const uint16_t* ind_vertices, const fVec3* vertices, float thickness, color_t color, float opacity);
2189
2190
2191
2192
2194 /*****************************************************************************************
2195 *****************************************************************************************/
2210 /*****************************************************************************************
2211 ******************************************************************************************/
2212
2213
2221 void drawWireFrameCube();
2222
2223
2231 void drawWireFrameCubeAA();
2232
2233
2247 void drawWireFrameCube(float thickness, color_t color, float opacity);
2248
2249
2261 void drawWireFrameSphere(int nb_sectors, int nb_stacks);
2262
2263
2274 void drawWireFrameSphereAA(int nb_sectors, int nb_stacks);
2275
2276
2293 void drawWireFrameSphere(int nb_sectors, int nb_stacks, float thickness, color_t color, float opacity);
2294
2295
2309 void drawWireFrameAdaptativeSphere(float quality = 1.0f);
2310
2311
2321 void drawWireFrameAdaptativeSphereAA(float quality = 1.0f);
2322
2323
2342 void drawWireFrameAdaptativeSphere(float quality, float thickness, color_t color, float opacity);
2343
2344
2354 void drawWireFrameCylinder(int nb_sectors, bool bottom_cap = true, bool top_cap = true);
2355
2356
2364 void drawWireFrameCylinderAA(int nb_sectors, bool bottom_cap = true, bool top_cap = true);
2365
2366
2379 void drawWireFrameCylinder(int nb_sectors, bool bottom_cap, bool top_cap, float thickness, color_t color, float opacity);
2380
2381
2390 void drawWireFrameCone(int nb_sectors, bool bottom_cap = true);
2391
2392
2399 void drawWireFrameConeAA(int nb_sectors, bool bottom_cap = true);
2400
2401
2413 void drawWireFrameCone(int nb_sectors, bool bottom_cap, float thickness, color_t color, float opacity);
2414
2415
2425 void drawWireFrameTruncatedCone(int nb_sectors, float bottom_radius, float top_radius, bool bottom_cap = true, bool top_cap = true);
2426
2427
2437 void drawWireFrameTruncatedConeAA(int nb_sectors, float bottom_radius, float top_radius, bool bottom_cap = true, bool top_cap = true);
2438
2439
2454 void drawWireFrameTruncatedCone(int nb_sectors, float bottom_radius, float top_radius, bool bottom_cap, bool top_cap, float thickness, color_t color, float opacity);
2455
2456
2457
2459 /*****************************************************************************************
2460 *****************************************************************************************/
2469 /*****************************************************************************************
2470 ******************************************************************************************/
2471
2472
2473
2483 void drawPixel(const fVec3& pos);
2484
2485
2497 void drawPixel(const fVec3& pos, color_t color, float opacity);
2498
2499
2510 void drawPixels(int nb_pixels, const fVec3* pos_list);
2511
2512
2527 void drawPixels(int nb_pixels, const fVec3* pos_list, const int* colors_ind, const color_t* colors, const int* opacities_ind, const float* opacities);
2528
2529
2540 void drawDot(const fVec3& pos, int r);
2541
2542
2543
2556 void drawDot(const fVec3& pos, int r, color_t color, float opacity);
2557
2558
2570 void drawDots(int nb_dots, const fVec3* pos_list, const int radius);
2571
2572
2590 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);
2591
2592
2593
2594
2595
2597
2598
2599
2600
2601
2602 private:
2603
2604
2605
2606 /*****************************************************************************************
2607 ******************************************************************************************
2608 *
2609 * BE CAREFUL PAST THIS POINT... FOR HERE BE DRAGONS !
2610 *
2611 ******************************************************************************************
2612 ******************************************************************************************/
2613
2614
2616 TGX_INLINE float _clipbound_xy() const
2617 {
2618 return (256 + 3*((MAXVIEWPORTDIMENSION * 256) / ((_lx > _ly) ? _lx : _ly))) / 1024.0f; // use integer computation up to the last divide
2619 //return (1.0f + 3.0f * (((float)MAXVIEWPORTDIMENSION) / ((_lx > _ly) ? _lx : _ly))) / 4.0f;
2620 }
2621
2622
2624 TGX_INLINE bool _validDraw() const
2625 {
2626 return ((_lx > 0) && (_ly > 0) && (_uni.im != nullptr) && (_uni.im->isValid()));
2627 }
2628
2629
2631 TGX_NOINLINE void _recompute_wa_wb();
2632
2633
2634 /***********************************************************
2635 * Making sure shader flags are coherent
2636 ************************************************************/
2637
2638 TGX_NOINLINE void _rectifyShaderOrtho();
2639
2640
2641 TGX_NOINLINE void _rectifyShaderZbuffer();
2642
2643
2644 TGX_NOINLINE void _rectifyShaderShading(Shader new_shaders);
2645
2646
2647 TGX_NOINLINE void _rectifyShaderTextureMode();
2648
2649
2650 TGX_NOINLINE void _rectifyShaderTextureWrapping();
2651
2652
2653 TGX_NOINLINE void _rectifyShaderTextureQuality();
2654
2655
2656 /***********************************************************
2657 * DRAWING STUFF
2658 ************************************************************/
2659
2660
2662 template<Shader RASTERIZER_SHADERS = ENABLED_SHADERS>
2663 void _drawTriangleClipped(const int RASTER_TYPE,
2664 const fVec4* Q0, const fVec4* Q1, const fVec4* Q2,
2665 const fVec3* N0, const fVec3* N1, const fVec3* N2,
2666 const fVec2* T0, const fVec2* T1, const fVec2* T2,
2667 const RGBf& Vcol0, const RGBf& Vcol1, const RGBf& Vcol2);
2668
2669
2671 template<Shader RASTERIZER_SHADERS = ENABLED_SHADERS>
2672 void _drawTriangleClippedSub(const int RASTER_TYPE, const int plane,
2673 const RasterizerVec4& P1, const RasterizerVec4& P2, const RasterizerVec4& P3);
2674
2675
2677 void _drawTriangle(const int RASTER_TYPE,
2678 const fVec3* P0, const fVec3* P1, const fVec3* P2,
2679 const fVec3* N0, const fVec3* N1, const fVec3* N2,
2680 const fVec2* T0, const fVec2* T1, const fVec2* T2,
2681 const RGBf& Vcol0, const RGBf& Vcol1, const RGBf& Vcol2);
2682
2683
2685 void _drawTriangleStrip(const int RASTER_TYPE, int nb_indices,
2686 const uint16_t* ind_vertices, const fVec3* vertices,
2687 const uint16_t* ind_normals, const fVec3* normals,
2688 const uint16_t* ind_texture, const fVec2* textures);
2689
2690
2692 void _drawQuad(const int RASTER_TYPE,
2693 const fVec3* P0, const fVec3* P1, const fVec3* P2, const fVec3* P3,
2694 const fVec3* N0, const fVec3* N1, const fVec3* N2, const fVec3* N3,
2695 const fVec2* T0, const fVec2* T1, const fVec2* T2, const fVec2* T3,
2696 const RGBf& Vcol0, const RGBf& Vcol1, const RGBf& Vcol2, const RGBf& Vcol3);
2697
2699 template<bool TEXTURE_BILINEAR, bool TEXTURE_WRAP>
2700 void _rasterizeSkyBoxTriangle(const RasterizerVec4& V0, const RasterizerVec4& V1, const RasterizerVec4& V2);
2701
2703 void _rasterizeSkyBoxTriangle(const RasterizerVec4& V0, const RasterizerVec4& V1, const RasterizerVec4& V2,
2704 Shader texture_quality, Shader texture_mode);
2705
2707 void _drawSkyBoxTriangleClippedSub(const int plane,
2708 const RasterizerVec4& P1, const RasterizerVec4& P2, const RasterizerVec4& P3,
2709 Shader texture_quality, Shader texture_mode);
2710
2712 void _drawSkyBoxTriangleClipped(
2713 const fVec4* Q0, const fVec4* Q1, const fVec4* Q2,
2714 const fVec2* T0, const fVec2* T1, const fVec2* T2,
2715 Shader texture_quality, Shader texture_mode);
2716
2718 void _drawSkyBoxQuad(
2719 const fVec4* P0, const fVec4* P1, const fVec4* P2, const fVec4* P3,
2720 const fVec2* T0, const fVec2* T1, const fVec2* T2, const fVec2* T3,
2721 Shader texture_quality, Shader texture_mode);
2722
2724 void _drawSkyBoxFace(const fVec4 skybox_vertices[8], const uint16_t* face, const fVec2 texture_coords[4], const Image<color_t>* texture,
2725 Shader texture_quality, Shader texture_mode);
2726
2727
2729 template<Shader RASTERIZER_SHADERS = ENABLED_SHADERS>
2730 void _drawMesh(const int RASTER_TYPE, const Mesh3D<color_t>* mesh);
2731
2733 template<Shader RASTERIZER_SHADERS = ENABLED_SHADERS>
2734 void _drawMesh(const int RASTER_TYPE, const Mesh3Dv2<color_t>* mesh, bool use_mesh_material);
2735
2737 inline bool _discardMeshlet16b(const fVec3& sphere_center, float sphere_radius, const fVec3& cone_dir, float cone_cos) const
2738 {
2739 if (cone_cos <= -1.0f) return false;
2740
2741 const fVec4 D = _r_modelViewM.mult0(cone_dir);
2742 const float dd = D.x * D.x + D.y * D.y + D.z * D.z;
2743 if (dd <= 1.0e-20f) return false;
2744
2745 float dot;
2746 float len2;
2747 if (_ortho)
2748 {
2749 dot = D.z; // object-to-camera direction is +Z in view space.
2750 len2 = dd;
2751 }
2752 else
2753 {
2754 const fVec3 anchor = sphere_center - (cone_dir * sphere_radius);
2755 const fVec4 A = _r_modelViewM.mult1(anchor);
2756 dot = -(D.x * A.x + D.y * A.y + D.z * A.z);
2757 const float aa = A.x * A.x + A.y * A.y + A.z * A.z;
2758 if (aa <= 1.0e-20f) return false;
2759 len2 = dd * aa;
2760 }
2761
2762 const float c2len2 = cone_cos * cone_cos * len2;
2763 const float dot2 = dot * dot;
2764 return (cone_cos >= 0.0f) ? ((dot < 0.0f) || (dot2 < c2len2))
2765 : ((dot < 0.0f) && (dot2 > c2len2));
2766 }
2767
2768
2769
2770 /***********************************************************
2771 * Drawing wireframe
2772 ************************************************************/
2773
2774 inline void _drawWireFrameLineFast(iVec2 P0, iVec2 P1, color_t color);
2775
2776 template<bool CHECK_NEIGHBOR> inline void _drawWireFrameLineAAFast(const fVec2& P0, const fVec2& P1, color_t color, int32_t op);
2777
2778 template<int MODE> void _drawWireFrameMesh(const Mesh3D<color_t>* mesh, bool draw_chained_meshes, color_t color, float opacity, float thickness);
2779
2780 template<int MODE> void _drawWireFrameMesh(const Mesh3Dv2<color_t>* mesh, color_t color, float opacity, float thickness);
2781
2782 template<int MODE> void _drawWireFrameLine(const fVec3& P1, const fVec3& P2, color_t color, float opacity, float thickness);
2783
2784 template<int MODE> void _drawWireFrameLines(int nb_lines, const uint16_t* ind_vertices, const fVec3* vertices, color_t color, float opacity, float thickness);
2785
2786 template<int MODE> void _drawWireFrameTriangle(const fVec3& P1, const fVec3& P2, const fVec3& P3, color_t color, float opacity, float thickness);
2787
2788 template<int MODE> void _drawWireFrameTriangles(int nb_triangles, const uint16_t* ind_vertices, const fVec3* vertices, color_t color, float opacity, float thickness);
2789
2790 template<int MODE> void _drawWireFrameTriangleStrip(int nb_indices, const uint16_t* ind_vertices, const fVec3* vertices, color_t color, float opacity, float thickness);
2791
2792 template<int MODE> void _drawWireFrameQuad(const fVec3& P1, const fVec3& P2, const fVec3& P3, const fVec3& P4, color_t color, float opacity, float thickness);
2793
2794 template<int MODE> void _drawWireFrameQuads(int nb_quads, const uint16_t* ind_vertices, const fVec3* vertices, color_t color, float opacity, float thickness);
2795
2796
2797
2798
2799 /***********************************************************
2800 * Simple geometric objects
2801 ************************************************************/
2802
2803
2804 template<bool USE_BLENDING> void _drawPixel(const fVec3& pos, color_t color, float opacity);
2805
2806
2807 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);
2808
2809
2810 template<bool USE_BLENDING> void _drawDot(const fVec3& pos, int r, color_t color, float opacity);
2811
2812
2813 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);
2814
2815
2816
2817 template<bool CHECKRANGE, bool USE_BLENDING> TGX_INLINE inline void drawPixelZbuf(int x, int y, color_t color, float opacity, float z)
2818 {
2819 if (CHECKRANGE && ((x < 0) || (x >= _uni.im->lx()) || (y < 0) || (y >= _uni.im->ly()))) return;
2820 ZBUFFER_t& W = _uni.zbuf[x + _uni.im->lx() * y];
2821 const ZBUFFER_t aa = (std::is_same<ZBUFFER_t, uint16_t>::value) ? ((ZBUFFER_t)(z * _uni.wa + _uni.wb)) : ((ZBUFFER_t)z);
2822 if (W < aa)
2823 {
2824 W = aa;
2825 if (USE_BLENDING) _uni.im->template drawPixel<false>({ x, y }, color, opacity); else _uni.im->template drawPixel<false>({ x, y }, color);
2826 }
2827 }
2828
2829
2830 template<bool CHECKRANGE, bool USE_BLENDING> inline void drawHLineZbuf(int x, int y, int w, color_t color, float opacity, float z)
2831 {
2832 if (CHECKRANGE) // optimized away at compile time
2833 {
2834 const int lx = _uni.im->lx();
2835 const int ly = _uni.im->ly();
2836 if ((y < 0) || (y >= ly) || (x >= lx)) return;
2837 if (x < 0) { w += x; x = 0; }
2838 if (x + w > lx) { w = lx - x; }
2839 if (w <= 0) return;
2840 }
2841 while(w--) drawPixelZbuf<CHECKRANGE, USE_BLENDING>(x++, y, color, opacity, z);
2842 }
2843
2844
2845 template<bool CHECKRANGE, bool USE_BLENDING> void _drawCircleZbuf(int xm, int ym, int r, color_t color, float opacity, float z);
2846
2847
2851 float _unitSphereScreenDiameter();
2852
2853
2854 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);
2855
2856 void _drawTruncatedCone(int nb_sectors, float bottom_radius, float top_radius, const Image<color_t>* texture_side, const Image<color_t>* texture_bottom, const Image<color_t>* texture_top, bool bottom_cap, bool top_cap);
2857
2858 template<int MODE> void _drawWireFrameTruncatedCone(int nb_sectors, float bottom_radius, float top_radius, bool bottom_cap, bool top_cap, float thickness, color_t color, float opacity);
2859
2860 struct ExtVec4;
2861
2862 void _drawTruncatedConeGouraudCachedTriangle(const int cone_shader, ExtVec4& E0, fVec3& N0, ExtVec4& E1, fVec3& N1, ExtVec4& E2, fVec3& N2, bool textured, bool ortho, float CLIPBOUND_XY, bool cliptestneeded);
2863
2864 void _drawTruncatedConeGouraudSideStrip(const int cone_shader, int nb_sectors, float bottom_radius, float top_radius, const float* cosTheta, const float* sinTheta, float inv_side_normal, float side_normal_y, float dtx, float CLIPBOUND_XY, bool cliptestneeded);
2865
2866 void _drawTruncatedConeGouraudConeFan(const int cone_shader, int nb_sectors, bool top_apex, float ring_radius, const float* cosTheta, const float* sinTheta, float inv_side_normal, float side_normal_y, float dtx, float CLIPBOUND_XY, bool cliptestneeded);
2867
2868 void _drawTruncatedConeGouraudCapFan(const int cap_shader, int nb_sectors, bool top_cap, float radius, const float* cosTheta, const float* sinTheta, float CLIPBOUND_XY, bool cliptestneeded);
2869
2870#if TGX_DRAWSPHERE_USE_STRIP_BANDS
2871 void _drawSphereGouraudStripBand(const int sphere_shader, int nb_sectors, const float* cosTheta, const float* sinTheta, float cosPhi, float sinPhi, float new_cosPhi, float new_sinPhi, float v, float vv, float dtx, float CLIPBOUND_XY, bool sphere_cliptestneeded);
2872
2873 void _drawSphereGouraudCap(const int sphere_shader, int nb_sectors, bool top_cap, const float* cosTheta, const float* sinTheta, float ring_y, float ring_radius, float ring_v, float dtx, float CLIPBOUND_XY, bool sphere_cliptestneeded);
2874#endif
2875
2876
2877
2878 /***********************************************************
2879 * CLIPPING
2880 ************************************************************/
2881
2882
2884 TGX_INLINE inline void _clip(int & fl, const fVec4 & P, float bx, float Bx, float by, float By)
2885 {
2886 if (P.x >= bx) { fl &= (~(1)); }
2887 if (P.x <= Bx) { fl &= (~(2)); }
2888 if (P.y >= by) { fl &= (~(4)); }
2889 if (P.y <= By) { fl &= (~(8)); }
2890 if ((P.z >= -1.0f)&&(P.w > 0)) { fl &= (~(16)); }
2891 if (P.z <= +1.0f) { fl &= (~(32)); }
2892 }
2893
2894
2896 TGX_INLINE inline void _clip(int & fl, const fVec3 & P, float bx, float Bx, float by, float By, const fMat4 & M)
2897 {
2898 fVec4 S = M.mult1(P);
2899 if (!_ortho) S.zdivide();
2900 return _clip(fl, S, bx, Bx, by, By);
2901 }
2902
2903
2904 /* test if a box is outside the image and should be discarded.
2905 transform the box coords with M then z-divide. */
2906 inline bool _discardBox(const fBox3 & bb, const fMat4 & M)
2907 {
2908 if ((bb.minX == 0) && (bb.maxX == 0) && (bb.minY == 0) && (bb.maxY == 0) && (bb.minZ == 0) && (bb.maxZ == 0))
2909 return false; // do not discard if the bounding box is uninitialized.
2910
2911 const float bx = (_ox - 1) * _ilx - 1.0f;
2912 const float Bx = (_ox + _uni.im->width() + 1) * _ilx - 1.0f;
2913 const float by = (_oy - 1) * _ily - 1.0f;
2914 const float By = (_oy + _uni.im->height() + 1) * _ily - 1.0f;
2915
2916 int fl = 63; // every bit set
2917 _clip(fl, fVec3(bb.minX, bb.minY, bb.minZ), bx, Bx, by, By, M);
2918 if (fl == 0) return false;
2919 _clip(fl, fVec3(bb.minX, bb.minY, bb.maxZ), bx, Bx, by, By, M);
2920 if (fl == 0) return false;
2921 _clip(fl, fVec3(bb.minX, bb.maxY, bb.minZ), bx, Bx, by, By, M);
2922 if (fl == 0) return false;
2923 _clip(fl, fVec3(bb.minX, bb.maxY, bb.maxZ), bx, Bx, by, By, M);
2924 if (fl == 0) return false;
2925 _clip(fl, fVec3(bb.maxX, bb.minY, bb.minZ), bx, Bx, by, By, M);
2926 if (fl == 0) return false;
2927 _clip(fl, fVec3(bb.maxX, bb.minY, bb.maxZ), bx, Bx, by, By, M);
2928 if (fl == 0) return false;
2929 _clip(fl, fVec3(bb.maxX, bb.maxY, bb.minZ), bx, Bx, by, By, M);
2930 if (fl == 0) return false;
2931 _clip(fl, fVec3(bb.maxX, bb.maxY, bb.maxZ), bx, Bx, by, By, M);
2932 if (fl == 0) return false;
2933 return true;
2934 }
2935
2936
2937 /* test if a triangle is completely outside the image and should be discarded.
2938 * coords are given after z-divide. */
2939 inline bool _discardTriangle(const fVec4 & P1, const fVec4 & P2, const fVec4 & P3)
2940 {
2941 const float bx = (_ox - 1) * _ilx - 1.0f;
2942 const float Bx = (_ox + _uni.im->width() + 1) * _ilx - 1.0f;
2943 const float by = (_oy - 1) * _ily - 1.0f;
2944 const float By = (_oy + _uni.im->height() + 1) * _ily - 1.0f;
2945
2946 int fl = 63; // every bit set
2947 _clip(fl, P1, bx, Bx, by, By);
2948 if (fl == 0) return false;
2949 _clip(fl, P2, bx, Bx, by, By);
2950 if (fl == 0) return false;
2951 _clip(fl, P3, bx, Bx, by, By);
2952 if (fl == 0) return false;
2953 return true;
2954 }
2955
2956
2958 TGX_INLINE bool _clip2(float clipboundXY, const fVec3 & P, const fMat4 & M)
2959 {
2960 fVec4 S = M.mult1(P);
2961 if (!_ortho)
2962 {
2963 S.zdivide();
2964 if (S.w <= 0) S.z = -2;
2965 }
2966 return ((S.x <= -clipboundXY) || (S.x >= clipboundXY)
2967 || (S.y <= -clipboundXY) || (S.y >= clipboundXY)
2968 || (S.z <= -1) || (S.z >= 1));
2969 }
2970
2971
2973 inline bool _clipTestNeeded(float clipboundXY, const fBox3 & bb, const fMat4 & M)
2974 {
2975 return (_clip2(clipboundXY, fVec3(bb.minX, bb.minY, bb.minZ), M)
2976 || _clip2(clipboundXY, fVec3(bb.minX, bb.minY, bb.maxZ), M)
2977 || _clip2(clipboundXY, fVec3(bb.minX, bb.maxY, bb.minZ), M)
2978 || _clip2(clipboundXY, fVec3(bb.minX, bb.maxY, bb.maxZ), M)
2979 || _clip2(clipboundXY, fVec3(bb.maxX, bb.minY, bb.minZ), M)
2980 || _clip2(clipboundXY, fVec3(bb.maxX, bb.minY, bb.maxZ), M)
2981 || _clip2(clipboundXY, fVec3(bb.maxX, bb.maxY, bb.minZ), M)
2982 || _clip2(clipboundXY, fVec3(bb.maxX, bb.maxY, bb.maxZ), M));
2983 }
2984
2985
2987 inline bool _wireFrameAANeighborCheckNeeded(const fBox3& bb, const fMat4& proj_modelview)
2988 {
2989 if ((_uni.im == nullptr) || (_uni.im->lx() <= 2) || (_uni.im->ly() <= 2)) return true;
2990
2991 const float bx = (_ox + 1.0f) * _ilx - 1.0f;
2992 const float Bx = (_ox + (float)(_uni.im->lx() - 2)) * _ilx - 1.0f;
2993 const float by = (_oy + 1.0f) * _ily - 1.0f;
2994 const float By = (_oy + (float)(_uni.im->ly() - 2)) * _ily - 1.0f;
2995
2996 const fVec3 C[8] = {
2997 fVec3(bb.minX, bb.minY, bb.minZ),
2998 fVec3(bb.minX, bb.minY, bb.maxZ),
2999 fVec3(bb.minX, bb.maxY, bb.minZ),
3000 fVec3(bb.minX, bb.maxY, bb.maxZ),
3001 fVec3(bb.maxX, bb.minY, bb.minZ),
3002 fVec3(bb.maxX, bb.minY, bb.maxZ),
3003 fVec3(bb.maxX, bb.maxY, bb.minZ),
3004 fVec3(bb.maxX, bb.maxY, bb.maxZ)
3005 };
3006
3007 for (int i = 0; i < 8; i++)
3008 {
3009 fVec4 P = proj_modelview.mult1(C[i]);
3010 if (!_ortho)
3011 {
3012 if (P.w <= 0) return true;
3013 P.zdivide();
3014 }
3015 if ((P.z < -1.0f) || (P.z > 1.0f)) return true;
3016 if ((P.x < bx) || (P.x > Bx) || (P.y < by) || (P.y > By)) return true;
3017 }
3018 return false;
3019 }
3020
3021
3022#if TGX_MESHLET_SPHERE_CLIP
3024 inline void _meshletClipPlanes(float clipboundXY, const fMat4& M, fVec4* planes, float* plane_norms) const
3025 {
3026 const float cx = clipboundXY;
3027 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]);
3028 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]);
3029 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]);
3030 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]);
3031 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]);
3032 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]);
3033 for (int i = 0; i < 6; i++)
3034 {
3035 const fVec4& P = planes[i];
3036 plane_norms[i] = sqrtf(P.x * P.x + P.y * P.y + P.z * P.z);
3037 }
3038 }
3039
3040
3042 inline int _meshletSphereClip(const fVec3& center, float radius, const fVec4* planes, const float* plane_norms) const
3043 {
3044 bool intersects = false;
3045 for (int i = 0; i < 6; i++)
3046 {
3047 const fVec4& P = planes[i];
3048 const float d = P.x * center.x + P.y * center.y + P.z * center.z + P.w;
3049 const float r = radius * plane_norms[i];
3050 if (d < -r) return -1;
3051 if (d < r) intersects = true;
3052 }
3053 return intersects ? 1 : 0;
3054 }
3055#endif
3056
3057
3058
3059
3060 /***********************************************************
3061 * TRIANGLE CLIPPING AGAINST A CLIP-PLANE
3062 ************************************************************/
3063
3072 TGX_INLINE inline float _cpdist(const tgx::fVec4& CP, float off, const tgx::fVec4& P)
3073 {
3074 return (CP.x * P.x) + (CP.y * P.y) + (CP.z * P.z) + (CP.w * P.w) + off;
3075 }
3076
3087 TGX_INLINE inline float _cpfactor(const tgx::fVec4& CP, const float sdistA, const float sdistB)
3088 {
3089 return sdistA / (sdistA - sdistB);
3090 }
3091
3092
3094 TGX_RENDERER3D_CLIP_NOINLINE void _triangleClip1in(int shader, tgx::fVec4 CP,
3095 float cp1, float cp2, float cp3,
3096 const RasterizerVec4& P1, const RasterizerVec4& P2, const RasterizerVec4& P3,
3097 RasterizerVec4& nP1, RasterizerVec4& nP2, RasterizerVec4& nP3, RasterizerVec4& nP4);
3098
3099
3101 TGX_RENDERER3D_CLIP_NOINLINE void _triangleClip2in(int shader, tgx::fVec4 CP,
3102 float cp1, float cp2, float cp3,
3103 const RasterizerVec4& P1, const RasterizerVec4& P2, const RasterizerVec4& P3,
3104 RasterizerVec4& nP1, RasterizerVec4& nP2, RasterizerVec4& nP3, RasterizerVec4& nP4);
3105
3106
3107 TGX_RENDERER3D_CLIP_NOINLINE int _triangleClip(int shader, tgx::fVec4 CP, float off,
3108 const RasterizerVec4 & P1, const RasterizerVec4 & P2, const RasterizerVec4 & P3,
3109 RasterizerVec4 & nP1, RasterizerVec4 & nP2, RasterizerVec4 & nP3, RasterizerVec4 & nP4);
3110
3111
3112
3113 /***********************************************************
3114 * PHONG LIGHTNING
3115 ************************************************************/
3116
3117 static const int _POWTABSIZE = 32; // number of entries in the precomputed power table for specular exponent.
3118 int _currentpow; // exponent for the currently computed table (<0 if table not yet computed)
3119 float _powmax; // used to compute exponent
3120 float _fastpowtab[_POWTABSIZE]; // the precomputed power table.
3121
3123 TGX_INLINE inline void _precomputeSpecularTable(int exponent)
3124 {
3125 if (_currentpow == exponent) return;
3126 _precomputeSpecularTable2(exponent);
3127 }
3128
3129 TGX_NOINLINE void _precomputeSpecularTable2(int exponent);
3130
3131
3133 TGX_INLINE inline float _powSpecular(float x) const
3134 {
3135 const float indf = (_powmax - x) * _POWTABSIZE;
3136 const int indi = max(0,(int)indf);
3137 return (indi >= (_POWTABSIZE - 1)) ? 0.0f : (_fastpowtab[indi] + (indf - indi) * (_fastpowtab[indi + 1] - _fastpowtab[indi]));;
3138 }
3139
3140
3141
3142
3144 inline void _updateDirectionalLightTransform(int index)
3145 {
3146 _r_light[index] = _viewM.mult0(_light[index]);
3147 _r_light[index] = -_r_light[index];
3148 _r_light[index].normalize();
3149 _r_light_inorm[index] = _r_light[index] * _r_inorm;
3150 _r_H[index] = fVec3(0, 0, 1); // cheating: should use the normalized current vertex position (but this is faster with almost the same result)...
3151 _r_H[index] += _r_light[index];
3152 _r_H[index].normalize();
3153 _r_H_inorm[index] = _r_H[index] * _r_inorm;
3154 }
3155
3156
3158 inline void _updateActiveDirectionalLightInorms()
3159 {
3160 for (int i = 0; i < _directionalLightCount; i++)
3161 {
3162 _r_light_inorm[i] = _r_light[i] * _r_inorm;
3163 _r_H_inorm[i] = _r_H[i] * _r_inorm;
3164 }
3165 }
3166
3167
3169 inline void _updateActiveDirectionalLightTransforms()
3170 {
3171 for (int i = 0; i < _directionalLightCount; i++)
3172 {
3173 _updateDirectionalLightTransform(i);
3174 }
3175 }
3176
3177
3178
3179 static TGX_INLINE inline bool _spotLightColorIsBlack(const RGBf& color)
3180 {
3181 return ((color.R <= 0.0f) && (color.G <= 0.0f) && (color.B <= 0.0f));
3182 }
3183
3184
3186 inline void _setSpotLightRangeValues(int index, float range)
3187 {
3188 if constexpr (MAX_SPOT_LIGHTS > 0)
3189 {
3190 if ((range > 0.0f) && (range < 1.0e15f))
3191 {
3192 _spotLights.range2[index] = range * range;
3193 _spotLights.invRange2[index] = 1.0f / _spotLights.range2[index];
3194 }
3195 else
3196 {
3197 _spotLights.range2[index] = 1.0e30f;
3198 _spotLights.invRange2[index] = 0.0f;
3199 }
3200 }
3201 }
3202
3203
3205 inline void _setSpotLightConeValues(int index, float outerAngleDeg, float innerAngleDeg)
3206 {
3207 if constexpr (MAX_SPOT_LIGHTS > 0)
3208 {
3209 if (outerAngleDeg >= 180.0f)
3210 {
3211 _spotLights.flags[index] &= ~(Renderer3D_detail::SPOT_LIGHT_CONE_ENABLED | Renderer3D_detail::SPOT_LIGHT_SOFT_CONE);
3212 _spotLights.cosOuter[index] = -1.0f;
3213 _spotLights.invCosWidth[index] = 0.0f;
3214 return;
3215 }
3216
3217 const float outer = clamp(outerAngleDeg, 0.0f, 180.0f);
3218 _spotLights.flags[index] |= Renderer3D_detail::SPOT_LIGHT_CONE_ENABLED;
3219 _spotLights.flags[index] &= ~Renderer3D_detail::SPOT_LIGHT_SOFT_CONE;
3220
3221 _spotLights.cosOuter[index] = tgx_fast_cos_deg_clamped(outer);
3222 _spotLights.invCosWidth[index] = 0.0f;
3223
3224 if ((innerAngleDeg >= 0.0f) && (innerAngleDeg < outer))
3225 {
3226 const float inner = clamp(innerAngleDeg, 0.0f, outer);
3227 const float cosInner = tgx_fast_cos_deg_clamped(inner);
3228 const float cosWidth = cosInner - _spotLights.cosOuter[index];
3229 if (cosWidth > 0.00001f)
3230 {
3231 _spotLights.flags[index] |= Renderer3D_detail::SPOT_LIGHT_SOFT_CONE;
3232 _spotLights.invCosWidth[index] = 1.0f / cosWidth;
3233 }
3234 }
3235 }
3236 }
3237
3238
3240 inline void _updateSpotLightPositionTransform(int index)
3241 {
3242 if constexpr (MAX_SPOT_LIGHTS > 0)
3243 {
3244 _spotLights.positionView[index] = _viewM.mult1(_spotLights.position[index]);
3245 }
3246 }
3247
3248
3250 inline void _updateSpotLightDirectionTransform(int index)
3251 {
3252 if constexpr (MAX_SPOT_LIGHTS > 0)
3253 {
3254 fVec3 D = _viewM.mult0(_spotLights.direction[index]);
3255 const float d2 = dotProduct(D, D);
3256 if (d2 > 0.000001f) { D *= tgx::fast_invsqrt(d2); } else { D = fVec3(0.0f, 0.0f, -1.0f); }
3257 _spotLights.directionView[index] = D;
3258 }
3259 }
3260
3261
3263 inline void _updateSpotLightTransform(int index)
3264 {
3265 if constexpr (MAX_SPOT_LIGHTS > 0)
3266 {
3267 _updateSpotLightPositionTransform(index);
3268 _updateSpotLightDirectionTransform(index);
3269 }
3270 }
3271
3272
3274 inline void _updateActiveSpotLightTransforms()
3275 {
3276 if constexpr (MAX_SPOT_LIGHTS > 0)
3277 {
3278 for (int i = 0; i < _spotLights.count; i++) { _updateSpotLightTransform(i); }
3279 }
3280 }
3281
3282
3284 inline void _updateActiveSpotLightFlags()
3285 {
3286 if constexpr (MAX_SPOT_LIGHTS > 0)
3287 {
3288 int globalFlags = 0;
3289 for (int i = 0; i < _spotLights.count; i++)
3290 {
3291 const int flags = _spotLights.flags[i];
3292 if (flags & Renderer3D_detail::SPOT_LIGHT_RUNTIME_SPECULAR_ENABLED) { globalFlags |= Renderer3D_detail::SPOT_LIGHT_GLOBAL_RUNTIME_SPECULAR; }
3293 if (flags & Renderer3D_detail::SPOT_LIGHT_CONE_ENABLED) { globalFlags |= Renderer3D_detail::SPOT_LIGHT_GLOBAL_ACTIVE_CONE; }
3294 }
3295 _spotLights.globalFlags = globalFlags;
3296 }
3297 }
3298
3299
3301 inline void _updateSpotLightColor(int index, float diffuseStrength, float specularStrength, int specularExponent)
3302 {
3303 if constexpr (MAX_SPOT_LIGHTS > 0)
3304 {
3305 _spotLights.runtimeDiffuseColor[index] = _spotLights.diffuseColor[index] * diffuseStrength;
3306 _spotLights.runtimeSpecularColor[index] = _spotLights.specularColor[index] * specularStrength;
3307 if ((specularStrength > 0.0f) && (specularExponent > 0) && (!_spotLightColorIsBlack(_spotLights.specularColor[index])))
3308 {
3309 _spotLights.flags[index] |= Renderer3D_detail::SPOT_LIGHT_RUNTIME_SPECULAR_ENABLED;
3310 }
3311 else
3312 {
3313 _spotLights.flags[index] &= ~Renderer3D_detail::SPOT_LIGHT_RUNTIME_SPECULAR_ENABLED;
3314 }
3315 }
3316 }
3317
3318
3320 inline void _updateActiveSpotLightColors(float diffuseStrength, float specularStrength, int specularExponent)
3321 {
3322 if constexpr (MAX_SPOT_LIGHTS > 0)
3323 {
3324 for (int i = 0; i < _spotLights.count; i++) { _updateSpotLightColor(i, diffuseStrength, specularStrength, specularExponent); }
3325 _updateActiveSpotLightFlags();
3326 }
3327 }
3328
3329
3331 inline void _setRuntimeMaterialLighting(float ambiantStrength, float diffuseStrength, float specularStrength, int specularExponent)
3332 {
3333 _r_ambiantColor = _ambiantColor * ambiantStrength;
3334 for (int i = 0; i < _directionalLightCount; i++)
3335 {
3336 _r_diffuseColor[i] = _diffuseColor[i] * diffuseStrength;
3337 _r_specularColor[i] = _specularColor[i] * specularStrength;
3338 }
3339 _updateActiveSpotLightColors(diffuseStrength, specularStrength, specularExponent);
3340 }
3341
3342
3344 inline void _setRuntimeMaterialLighting(float ambiantStrength, float diffuseStrength, float specularStrength)
3345 {
3346 _setRuntimeMaterialLighting(ambiantStrength, diffuseStrength, specularStrength, _specularExponent);
3347 }
3348
3349
3351 inline void _updateDirectionalLightColor(int index)
3352 {
3353 _r_diffuseColor[index] = _diffuseColor[index] * _diffuseStrength;
3354 _r_specularColor[index] = _specularColor[index] * _specularStrength;
3355 }
3356
3357
3358
3359 //
3360
3361
3363 template<bool TEXTURE> TGX_RENDERER3D_SHADING_INLINE inline RGBf _shadeVertex(const float icu, const fVec3 & N, const fVec4 & P) const
3364 {
3365 RGBf col = _r_ambiantColor;
3366 if constexpr (MAX_DIRECTIONAL_LIGHTS == 1)
3367 {
3368 col += _r_diffuseColor[0] * max(icu * dotProduct(N, _r_light_inorm[0]), 0.0f);
3369 col += _r_specularColor[0] * _powSpecular(icu * dotProduct(N, _r_H_inorm[0]));
3370 }
3371 else
3372 {
3373 for (int i = 0; i < _directionalLightCount; i++)
3374 {
3375 col += _r_diffuseColor[i] * max(icu * dotProduct(N, _r_light_inorm[i]), 0.0f);
3376 col += _r_specularColor[i] * _powSpecular(icu * dotProduct(N, _r_H_inorm[i]));
3377 }
3378 }
3379 if constexpr (MAX_SPOT_LIGHTS > 0)
3380 {
3381 const float localNormalScale = icu * _r_inorm;
3382 const int spotGlobalFlags = _spotLights.globalFlags;
3383 const bool localSpecular = (spotGlobalFlags & Renderer3D_detail::SPOT_LIGHT_GLOBAL_RUNTIME_SPECULAR) != 0;
3384 const bool localCone = (spotGlobalFlags & Renderer3D_detail::SPOT_LIGHT_GLOBAL_ACTIVE_CONE) != 0;
3385 const fVec3 Pv(P.x, P.y, P.z);
3386 for (int i = 0; i < _spotLights.count; i++)
3387 {
3388 fVec3 L = _spotLights.positionView[i] - Pv;
3389 const float d2 = dotProduct(L, L);
3390 if ((d2 <= 1.0e-12f) || (d2 >= _spotLights.range2[i])) continue;
3391
3392 const float ndotlRaw = dotProduct(N, L);
3393 const float diffRaw = localNormalScale * ndotlRaw;
3394 if (diffRaw <= 0.0f) continue;
3395
3396 const float invD = tgx::fast_invsqrt(d2);
3397 const float diff = diffRaw * invD;
3398 const float atten = 1.0f - d2 * _spotLights.invRange2[i];
3399 float lightFactor = atten * atten;
3400
3401 int flags = 0;
3402 if (localCone)
3403 {
3404 flags = _spotLights.flags[i];
3405 if (flags & Renderer3D_detail::SPOT_LIGHT_CONE_ENABLED)
3406 {
3407 const float cone = -dotProduct(_spotLights.directionView[i], L) * invD;
3408 if (cone <= _spotLights.cosOuter[i]) continue;
3409 if (flags & Renderer3D_detail::SPOT_LIGHT_SOFT_CONE)
3410 {
3411 float spot = (cone - _spotLights.cosOuter[i]) * _spotLights.invCosWidth[i];
3412 if (spot > 1.0f) spot = 1.0f;
3413 lightFactor *= spot * spot;
3414 }
3415 }
3416 }
3417
3418 col += _spotLights.runtimeDiffuseColor[i] * (diff * lightFactor);
3419
3420 if (localSpecular)
3421 {
3422 if (!localCone) flags = _spotLights.flags[i];
3423 if (flags & Renderer3D_detail::SPOT_LIGHT_RUNTIME_SPECULAR_ENABLED)
3424 {
3425 const float specRaw = diff + (localNormalScale * N.z);
3426 if (specRaw > 0.0f)
3427 {
3428 const float h2 = 2.0f + (2.0f * L.z * invD);
3429 if (h2 > 1.0e-12f)
3430 {
3431 const float invH = tgx::fast_invsqrt(h2);
3432 const float spec = _powSpecular(specRaw * invH);
3433 col += _spotLights.runtimeSpecularColor[i] * (spec * lightFactor);
3434 }
3435 }
3436 }
3437 }
3438 }
3439 }
3440 else
3441 {
3442 (void)P;
3443 }
3444 if (!(TEXTURE)) col *= _r_objectColor;
3445 col.clamp();
3446 return col;
3447 }
3448
3449
3451 TGX_RENDERER3D_SHADING_INLINE inline RGBf _shadeVertex(const float icu, const fVec3 & N, const fVec4 & P, const RGBf & color) const
3452 {
3453 RGBf col = _r_ambiantColor;
3454 if constexpr (MAX_DIRECTIONAL_LIGHTS == 1)
3455 {
3456 col += _r_diffuseColor[0] * max(icu * dotProduct(N, _r_light_inorm[0]), 0.0f);
3457 col += _r_specularColor[0] * _powSpecular(icu * dotProduct(N, _r_H_inorm[0]));
3458 }
3459 else
3460 {
3461 for (int i = 0; i < _directionalLightCount; i++)
3462 {
3463 col += _r_diffuseColor[i] * max(icu * dotProduct(N, _r_light_inorm[i]), 0.0f);
3464 col += _r_specularColor[i] * _powSpecular(icu * dotProduct(N, _r_H_inorm[i]));
3465 }
3466 }
3467 if constexpr (MAX_SPOT_LIGHTS > 0)
3468 {
3469 const float localNormalScale = icu * _r_inorm;
3470 const int spotGlobalFlags = _spotLights.globalFlags;
3471 const bool localSpecular = (spotGlobalFlags & Renderer3D_detail::SPOT_LIGHT_GLOBAL_RUNTIME_SPECULAR) != 0;
3472 const bool localCone = (spotGlobalFlags & Renderer3D_detail::SPOT_LIGHT_GLOBAL_ACTIVE_CONE) != 0;
3473 const fVec3 Pv(P.x, P.y, P.z);
3474 for (int i = 0; i < _spotLights.count; i++)
3475 {
3476 fVec3 L = _spotLights.positionView[i] - Pv;
3477 const float d2 = dotProduct(L, L);
3478 if ((d2 <= 1.0e-12f) || (d2 >= _spotLights.range2[i])) continue;
3479
3480 const float ndotlRaw = dotProduct(N, L);
3481 const float diffRaw = localNormalScale * ndotlRaw;
3482 if (diffRaw <= 0.0f) continue;
3483
3484 const float invD = tgx::fast_invsqrt(d2);
3485 const float diff = diffRaw * invD;
3486 const float atten = 1.0f - d2 * _spotLights.invRange2[i];
3487 float lightFactor = atten * atten;
3488
3489 int flags = 0;
3490 if (localCone)
3491 {
3492 flags = _spotLights.flags[i];
3493 if (flags & Renderer3D_detail::SPOT_LIGHT_CONE_ENABLED)
3494 {
3495 const float cone = -dotProduct(_spotLights.directionView[i], L) * invD;
3496 if (cone <= _spotLights.cosOuter[i]) continue;
3497 if (flags & Renderer3D_detail::SPOT_LIGHT_SOFT_CONE)
3498 {
3499 float spot = (cone - _spotLights.cosOuter[i]) * _spotLights.invCosWidth[i];
3500 if (spot > 1.0f) spot = 1.0f;
3501 lightFactor *= spot * spot;
3502 }
3503 }
3504 }
3505
3506 col += _spotLights.runtimeDiffuseColor[i] * (diff * lightFactor);
3507
3508 if (localSpecular)
3509 {
3510 if (!localCone) flags = _spotLights.flags[i];
3511 if (flags & Renderer3D_detail::SPOT_LIGHT_RUNTIME_SPECULAR_ENABLED)
3512 {
3513 const float specRaw = diff + (localNormalScale * N.z);
3514 if (specRaw > 0.0f)
3515 {
3516 const float h2 = 2.0f + (2.0f * L.z * invD);
3517 if (h2 > 1.0e-12f)
3518 {
3519 const float invH = tgx::fast_invsqrt(h2);
3520 const float spec = _powSpecular(specRaw * invH);
3521 col += _spotLights.runtimeSpecularColor[i] * (spec * lightFactor);
3522 }
3523 }
3524 }
3525 }
3526 }
3527 }
3528 else
3529 {
3530 (void)P;
3531 }
3532
3533 col *= color;
3534 col.clamp();
3535 return col;
3536 }
3537
3538
3540 template<bool TEXTURE> TGX_RENDERER3D_SHADING_INLINE inline RGBf _shadeFace(const float icu, const fVec3 & N, const fVec4 & P) const
3541 {
3542 RGBf col = _r_ambiantColor;
3543 if constexpr (MAX_DIRECTIONAL_LIGHTS == 1)
3544 {
3545 col += _r_diffuseColor[0] * max(icu * dotProduct(N, _r_light[0]), 0.0f);
3546 col += _r_specularColor[0] * _powSpecular(icu * dotProduct(N, _r_H[0]));
3547 }
3548 else
3549 {
3550 for (int i = 0; i < _directionalLightCount; i++)
3551 {
3552 col += _r_diffuseColor[i] * max(icu * dotProduct(N, _r_light[i]), 0.0f);
3553 col += _r_specularColor[i] * _powSpecular(icu * dotProduct(N, _r_H[i]));
3554 }
3555 }
3556 if constexpr (MAX_SPOT_LIGHTS > 0)
3557 {
3558 const int spotGlobalFlags = _spotLights.globalFlags;
3559 const bool localSpecular = (spotGlobalFlags & Renderer3D_detail::SPOT_LIGHT_GLOBAL_RUNTIME_SPECULAR) != 0;
3560 const bool localCone = (spotGlobalFlags & Renderer3D_detail::SPOT_LIGHT_GLOBAL_ACTIVE_CONE) != 0;
3561 const fVec3 Pv(P.x, P.y, P.z);
3562 for (int i = 0; i < _spotLights.count; i++)
3563 {
3564 fVec3 L = _spotLights.positionView[i] - Pv;
3565 const float d2 = dotProduct(L, L);
3566 if ((d2 <= 1.0e-12f) || (d2 >= _spotLights.range2[i])) continue;
3567
3568 const float ndotlRaw = dotProduct(N, L);
3569 const float diffRaw = icu * ndotlRaw;
3570 if (diffRaw <= 0.0f) continue;
3571
3572 const float invD = tgx::fast_invsqrt(d2);
3573 const float diff = diffRaw * invD;
3574 const float atten = 1.0f - d2 * _spotLights.invRange2[i];
3575 float lightFactor = atten * atten;
3576
3577 int flags = 0;
3578 if (localCone)
3579 {
3580 flags = _spotLights.flags[i];
3581 if (flags & Renderer3D_detail::SPOT_LIGHT_CONE_ENABLED)
3582 {
3583 const float cone = -dotProduct(_spotLights.directionView[i], L) * invD;
3584 if (cone <= _spotLights.cosOuter[i]) continue;
3585 if (flags & Renderer3D_detail::SPOT_LIGHT_SOFT_CONE)
3586 {
3587 float spot = (cone - _spotLights.cosOuter[i]) * _spotLights.invCosWidth[i];
3588 if (spot > 1.0f) spot = 1.0f;
3589 lightFactor *= spot * spot;
3590 }
3591 }
3592 }
3593
3594 col += _spotLights.runtimeDiffuseColor[i] * (diff * lightFactor);
3595
3596 if (localSpecular)
3597 {
3598 if (!localCone) flags = _spotLights.flags[i];
3599 if (flags & Renderer3D_detail::SPOT_LIGHT_RUNTIME_SPECULAR_ENABLED)
3600 {
3601 const float specRaw = diff + (icu * N.z);
3602 if (specRaw > 0.0f)
3603 {
3604 const float h2 = 2.0f + (2.0f * L.z * invD);
3605 if (h2 > 1.0e-12f)
3606 {
3607 const float invH = tgx::fast_invsqrt(h2);
3608 const float spec = _powSpecular(specRaw * invH);
3609 col += _spotLights.runtimeSpecularColor[i] * (spec * lightFactor);
3610 }
3611 }
3612 }
3613 }
3614 }
3615 }
3616 else
3617 {
3618 (void)P;
3619 }
3620 if (!(TEXTURE)) col *= _r_objectColor;
3621 col.clamp();
3622 return col;
3623 }
3624
3625
3627 TGX_RENDERER3D_SHADING_INLINE inline void _setFlatOrUnlitFaceColor(int raster_type, bool texture, fVec3& faceN, float cu,
3628 const fVec4& Q0, const fVec4& Q1, const fVec4& Q2)
3629 {
3630 if constexpr (TGX_SHADER_HAS_UNLIT(ENABLED_SHADERS))
3631 {
3632 if (TGX_SHADER_HAS_UNLIT(raster_type))
3633 {
3634 _uni.facecolor = texture ? RGBf(1.0f, 1.0f, 1.0f) : _r_objectColor;
3635 return;
3636 }
3637 }
3638
3639 const float icu = ((cu > 0) ? -1.0f : 1.0f); // -1 if we need to reverse the face normal.
3640 faceN.normalize_fast();
3641 if constexpr (MAX_SPOT_LIGHTS > 0)
3642 {
3643 if (_spotLights.count > 0)
3644 {
3645 const float oneThird = 1.0f / 3.0f;
3646 const fVec4 faceCenter((Q0.x + Q1.x + Q2.x) * oneThird,
3647 (Q0.y + Q1.y + Q2.y) * oneThird,
3648 (Q0.z + Q1.z + Q2.z) * oneThird,
3649 1.0f);
3650 if (texture)
3651 _uni.facecolor = _shadeFace<true>(icu, faceN, faceCenter);
3652 else
3653 _uni.facecolor = _shadeFace<false>(icu, faceN, faceCenter);
3654 return;
3655 }
3656 }
3657 if (texture)
3658 _uni.facecolor = _shadeFace<true>(icu, faceN, Q0);
3659 else
3660 _uni.facecolor = _shadeFace<false>(icu, faceN, Q0);
3661 }
3662
3663
3664
3665 /***********************************************************
3666 * MEMBER VARIABLES
3667 ************************************************************/
3668
3669 // *** general parameters ***
3670
3671 int _lx, _ly; // viewport dimension
3672 float _ilx, _ily; // inverse viewport dimension
3673
3674 int _ox, _oy; // image offset w.r.t. the viewport
3675
3676 bool _ortho; // true to use orthographic projection and false for perspective projection
3677
3678 fMat4 _projM; // projection matrix
3679
3680 RasterizerParams<color_t, color_t,ZBUFFER_t> _uni; // rasterizer param (contain the image pointer and the zbuffer pointer).
3681
3682 float _culling_dir; // culling direction postive/negative or 0 to disable back face culling.
3683
3684 int _shaders; // the shaders to use.
3685 int _texture_mode; // texture mapping mode (perspective-correct or affine)
3686 int _texture_wrap_mode; // wrapping mode (wrap_pow2 or clamp)
3687 int _texture_quality; // texturing quality (nearest or bilinear)
3688
3689 // *** scene parameters ***
3690
3691 fMat4 _viewM; // view transform matrix
3692
3693 fVec3 _light[MAX_DIRECTIONAL_LIGHTS]; // directional light directions
3694 RGBf _ambiantColor; // light ambiant color
3695 RGBf _diffuseColor[MAX_DIRECTIONAL_LIGHTS]; // directional light diffuse colors
3696 RGBf _specularColor[MAX_DIRECTIONAL_LIGHTS]; // directional light specular colors
3697 int _directionalLightCount; // number of active directional lights
3698
3699 // *** model specific parameters ***
3700
3701 fMat4 _modelM; // model transform matrix
3702
3703 // material parameters
3704 RGBf _color; // model color (use when texturing is disabled)
3705 float _ambiantStrength; // ambient light reflection strength
3706 float _diffuseStrength; // diffuse light reflection strength
3707 float _specularStrength; // specular light reflection strength
3708 int _specularExponent; // specular exponent
3709
3710
3711 // *** pre-computed values ***
3712 fMat4 _r_modelViewM; // model-view matrix
3713 float _r_inorm; // Fast normal scaling for lighting. Assumes rotation/uniform scale;
3714 // Gouraud lighting is approximate with non-uniform model scaling.
3715 fVec3 _r_light[MAX_DIRECTIONAL_LIGHTS]; // light vectors in view space (inverted and normalized)
3716 fVec3 _r_light_inorm[MAX_DIRECTIONAL_LIGHTS]; // same as above but already multiplied by inorm
3717 fVec3 _r_H[MAX_DIRECTIONAL_LIGHTS]; // halfway vectors.
3718 fVec3 _r_H_inorm[MAX_DIRECTIONAL_LIGHTS]; // same as above but already multiplied by inorm
3719 RGBf _r_ambiantColor; // ambient color multiplied by object ambient strength
3720 RGBf _r_diffuseColor[MAX_DIRECTIONAL_LIGHTS]; // diffuse colors multiplied by object diffuse strength
3721 RGBf _r_specularColor[MAX_DIRECTIONAL_LIGHTS]; // specular colors multiplied by object specular strength
3722 RGBf _r_objectColor; // color to use for drawing the object (either _color or mesh->color).
3723
3724 Renderer3D_detail::SpotLightData<MAX_SPOT_LIGHTS> _spotLights; // local spot-light data
3725
3726
3730 struct ExtVec4 : public RasterizerVec4
3731 {
3732 fVec4 P; // after model-view matrix multiplication
3733 fVec4 N; // normal vector after model-view matrix multiplication
3734 bool missedP; // true if the attributes should be computed
3735 int indn; // index for normal vector in array
3736 int indt; // index for texture vector in array
3737 };
3738
3739
3740 };
3741
3742
3743
3744}
3745
3746
3747
3748
3749#include "Renderer3D.inl"
3750#include "Renderer3DFlash.h"
3751
3752
3753#endif
3754
3755#endif
3756
3757
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(T a, T b)
Don't know why but much faster than fmaxf() for floats.
Definition: Misc.h:153
tgx::fast_invsqrt
TGX_INLINE float fast_invsqrt(float x)
Compute a fast approximation of the inverse square root of a float.
Definition: Misc.h:390
tgx::clamp
TGX_INLINE T clamp(T v, T vmin, T vmax)
Template clamp version.
Definition: Misc.h:157
tgx::tgx_fast_cos_deg_clamped
TGX_INLINE float tgx_fast_cos_deg_clamped(float deg)
Fast cosine approximation for an angle expressed in degrees.
Definition: Misc.h:467
Rasterizer.h
3D triangle rasterizer function.
TGX_RASTERIZE_SUBPIXEL_BITS
#define TGX_RASTERIZE_SUBPIXEL_BITS
Sub-pixel precision bits.
Definition: Rasterizer.h:46
Renderer3DFlash.h
Optional Teensy 4.x helpers for placing selected Renderer3D template instantiations in flash memory.
Renderer3DSpotLightData.h
Internal storage for Renderer3D local spot lights.
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_AFFINE
@ SHADER_TEXTURE_AFFINE
enable affine (non perspective-correct) texture mapping
Definition: ShaderParams.h:61
tgx::SHADER_TEXTURE
@ SHADER_TEXTURE
enable perspective-correct texture mapping
Definition: ShaderParams.h:60
Shaders.h
Triangle shader functions.
Vec2.h
2D vector.
tgx::dotProduct
TGX_INLINE T dotProduct(const Vec2< T > &U, const Vec2< T > &V)
Return the dot product U.V between two vectors.
Definition: Vec2.h:554
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:120
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::drawAdaptativeSphere
void drawAdaptativeSphere(float quality=1.0f)
Draw a unit radius sphere centered at the origin S(0,1) in model space.
tgx::Renderer3D::setTextureQuality
void setTextureQuality(Shader quality)
Set the texturing quality.
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::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::drawWireFrameMesh
void drawWireFrameMesh(const Mesh3Dv2< color_t > *mesh)
Draw a Mesh3Dv2 object in wireframe [fast].
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::drawCone
void drawCone(int nb_sectors, const Image< color_t > *texture_side, const Image< color_t > *texture_bottom=nullptr, bool bottom_cap=true)
Draw a textured unit cone in model space.
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::drawWireFrameLineAA
void drawWireFrameLineAA(const fVec3 &P1, const fVec3 &P2)
Draw a wireframe line segment [antialiased] with the current material color.
tgx::Renderer3D::setSpotLight
void setSpotLight(int index, const fVec3 &position, const fVec3 &direction, float range, float outerAngleDeg, const RGBf &diffuseColor, const RGBf &specularColor=RGBf(0.0f, 0.0f, 0.0f))
Configure one spot light with a hard cone edge.
tgx::Renderer3D::setSpotLight
void setSpotLight(int index, const fVec3 &position, float range, const RGBf &diffuseColor, const RGBf &specularColor=RGBf(0.0f, 0.0f, 0.0f))
Configure one omnidirectional local light.
tgx::Renderer3D::drawCylinder
void drawCylinder(int nb_sectors, bool bottom_cap=true, bool top_cap=true)
Draw a unit cylinder in model space.
tgx::Renderer3D::setDirectionalLightAmbiant
void setDirectionalLightAmbiant(const RGBf &color)
Set the global ambiant light shared by all directional lights.
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::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::drawWireFrameAdaptativeSphere
void drawWireFrameAdaptativeSphere(float quality=1.0f)
Draw a wireframe unit radius sphere centered at the origin (in model space) [fast].
tgx::Renderer3D::setSpotLightPosition
void setSpotLightPosition(int index, const fVec3 &position)
Set the position of one spot light.
tgx::Renderer3D::drawWireFrameCubeAA
void drawWireFrameCubeAA()
Draw the wireframe cube [0,1]^3 [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::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::setDirectionalLight
void setDirectionalLight(int index, const fVec3 &direction, const RGBf &diffuseColor, const RGBf &specularColor)
Configure one directional light at once.
tgx::Renderer3D::drawWireFrameTriangle
void drawWireFrameTriangle(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3)
Draw a wireframe triangle [fast].
tgx::Renderer3D::setLightDiffuse
void setLightDiffuse(const RGBf &color)
Set the diffuse light color of the main directional light of the scene.
tgx::Renderer3D::setSpotLightRange
void setSpotLightRange(int index, float range)
Set the range of one spot light.
tgx::Renderer3D::drawTruncatedCone
void drawTruncatedCone(int nb_sectors, float bottom_radius, float top_radius, bool bottom_cap=true, bool top_cap=true)
Draw a truncated cone in model space.
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::drawWireFrameMesh
void drawWireFrameMesh(const Mesh3D< color_t > *mesh, bool draw_chained_meshes=true)
Draw a mesh in wireframe [fast].
tgx::Renderer3D::setLightDirection
void setLightDirection(const fVec3 &direction)
Set the light source direction of the main directional light of the scene.
tgx::Renderer3D::drawMesh
void drawMesh(const Mesh3D< color_t > *mesh, bool use_mesh_material=true, bool draw_chained_meshes=true)
Advanced version of drawMesh() restricted to the shader subset listed in SHADERS.
tgx::Renderer3D::setZbuffer
void setZbuffer(ZBUFFER_t *zbuffer)
Set the z-buffer.
tgx::Renderer3D::drawSkyBox
void drawSkyBox(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, float rot_angle_y=0.0f, float reference_height=0.0f, float skybox_radius=32768.0f, Shader texture_quality=SHADER_TEXTURE_NEAREST, Shader texture_mode=SHADER_TEXTURE_CLAMP)
Draw a textured sky-box around the current camera.
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::drawWireFrameConeAA
void drawWireFrameConeAA(int nb_sectors, bool bottom_cap=true)
Draw a wireframe unit cone in model space [antialiased].
tgx::Renderer3D::drawWireFrameTruncatedConeAA
void drawWireFrameTruncatedConeAA(int nb_sectors, float bottom_radius, float top_radius, bool bottom_cap=true, bool top_cap=true)
Draw a wireframe truncated cone in model space [antialiased].
tgx::Renderer3D::drawWireFrameMeshAA
void drawWireFrameMeshAA(const Mesh3Dv2< color_t > *mesh)
Draw a Mesh3Dv2 object in wireframe [antialiased] with the current material color.
tgx::Renderer3D::Renderer3D
TGX_NOINLINE Renderer3D(const iVec2 &viewportSize={0, 0}, Image< color_t > *im=nullptr, ZBUFFER_t *zbuffer=nullptr)
Constructor.
tgx::Renderer3D::setProjectionMatrix
void setProjectionMatrix(const fMat4 &M)
Set the projection matrix.
tgx::Renderer3D::drawCube
void drawCube()
Draw the unit cube [-1,1]^3 in model space.
tgx::Renderer3D::getProjectionMatrix
fMat4 getProjectionMatrix() const
Return the current projection matrix.
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::drawMesh
void drawMesh(const Mesh3Dv2< color_t > *mesh, bool use_mesh_material=true)
Draw a Mesh3Dv2 object.
tgx::Renderer3D::drawMesh
void drawMesh(const Mesh3Dv2< color_t > *mesh, bool use_mesh_material=true)
Advanced version of drawMesh() restricted to the shader subset listed in SHADERS.
tgx::Renderer3D::setDirectionalLightSpecular
void setDirectionalLightSpecular(int index, const RGBf &color)
Set the specular color of one directional light.
tgx::Renderer3D::modelToImage
iVec2 modelToImage(fVec3 P)
Convert from model coordinates to the corresponding image pixel.
tgx::Renderer3D::setShaders
void setShaders(Shader shaders)
Set the shaders to use for subsequent drawing operations.
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::worldToImage
iVec2 worldToImage(fVec3 P)
Convert from world coordinates to the corresponding image pixel.
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::setMaterialDiffuseStrength
void setMaterialDiffuseStrength(float strenght=0.6f)
Set how much the object material reflects the diffuse light.
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::setLightAmbiant
void setLightAmbiant(const RGBf &color)
Set the scene ambiant light color.
tgx::Renderer3D::drawWireFrameAdaptativeSphereAA
void drawWireFrameAdaptativeSphereAA(float quality=1.0f)
Draw an adaptive wireframe sphere [antialiased] with the current material color.
tgx::Renderer3D::setSpotLightDirection
void setSpotLightDirection(int index, const fVec3 &direction)
Set the direction of one spot light.
tgx::Renderer3D::setImage
void setImage(Image< color_t > *im)
Set the image that will be drawn onto.
tgx::Renderer3D::drawWireFrameCylinder
void drawWireFrameCylinder(int nb_sectors, bool bottom_cap, bool top_cap, float thickness, color_t color, float opacity)
Draw a wireframe unit cylinder in model space [adjustable thickness + AA].
tgx::Renderer3D::drawWireFrameCube
void drawWireFrameCube()
Draw the wireframe cube [0,1]^3 (in model space) [fast].
tgx::Renderer3D::drawWireFrameCone
void drawWireFrameCone(int nb_sectors, bool bottom_cap=true)
Draw a wireframe unit cone in model space [fast].
tgx::Renderer3D::drawWireFrameCylinder
void drawWireFrameCylinder(int nb_sectors, bool bottom_cap=true, bool top_cap=true)
Draw a wireframe unit cylinder in model space [fast].
tgx::Renderer3D::drawWireFrameTriangleStrip
void drawWireFrameTriangleStrip(int nb_indices, const uint16_t *ind_vertices, const fVec3 *vertices, float thickness, color_t color, float opacity)
Draw a triangle strip in wireframe [adjustable thickness + AA].
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::setTextureWrappingMode
void setTextureWrappingMode(Shader wrap_mode)
Set the wrap mode when for texturing.
tgx::Renderer3D::setViewportSize
void setViewportSize(int lx, int ly)
Set the size of the viewport.
tgx::Renderer3D::getViewMatrix
fMat4 getViewMatrix() const
Return the current view matrix.
tgx::Renderer3D::setDirectionalLightCount
void setDirectionalLightCount(int count)
Set the number of active directional lights.
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::setViewportSize
void setViewportSize(const iVec2 &viewport_dim)
Set the size of the viewport.
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::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::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::setSpotLightSpecular
void setSpotLightSpecular(int index, const RGBf &color=RGBf(0.0f, 0.0f, 0.0f))
Set the specular color of one spot light.
tgx::Renderer3D::getModelMatrix
fMat4 getModelMatrix() const
Return the model transformation matrix.
tgx::Renderer3D::setMaterialSpecularStrength
void setMaterialSpecularStrength(float strenght=0.5f)
Set how much the object material reflects the specular light.
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::setModelMatrix
void setModelMatrix(const fMat4 &M)
Set the model transformation matrix.
tgx::Renderer3D::drawCylinder
void drawCylinder(int nb_sectors, const Image< color_t > *texture_side, const Image< color_t > *texture_bottom=nullptr, const Image< color_t > *texture_top=nullptr, bool bottom_cap=true, bool top_cap=true)
Draw a textured unit cylinder in model space.
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::drawSkyBox
void drawSkyBox(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, float rot_angle_y=0.0f, float reference_height=0.0f, float skybox_radius=32768.0f, Shader texture_quality=SHADER_TEXTURE_NEAREST, Shader texture_mode=SHADER_TEXTURE_CLAMP)
Draw a textured sky-box using whole images for each face.
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::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::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::maxSpotLightCount
static constexpr int maxSpotLightCount()
Return the compile-time spot-light capacity.
Definition: Renderer3D.h:789
tgx::Renderer3D::setOffset
void setOffset(const iVec2 &offset)
Set the offset of the image relative to the viewport.
tgx::Renderer3D::setPerspective
void setPerspective(float fovy, float aspect, float zNear, float zFar)
Set the projection matrix as a perspective matrix.
tgx::Renderer3D::drawWireFrameLine
void drawWireFrameLine(const fVec3 &P1, const fVec3 &P2)
Draw a wireframe line segment [fast].
tgx::Renderer3D::drawWireFrameQuad
void drawWireFrameQuad(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, const fVec3 &P4)
Draw a wireframe quad [fast].
tgx::Renderer3D::setSpotLightCone
void setSpotLightCone(int index, float outerAngleDeg, float innerAngleDeg=-1.0f)
Set the cone angles of one spot light.
tgx::Renderer3D::setOffset
void setOffset(int ox, int oy)
Set the offset of the image relative to the viewport.
tgx::Renderer3D::setSpotLightCount
void setSpotLightCount(int count)
Set the number of active spot lights.
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::drawTruncatedCone
void drawTruncatedCone(int nb_sectors, float bottom_radius, float top_radius, const Image< color_t > *texture_side, const Image< color_t > *texture_bottom=nullptr, const Image< color_t > *texture_top=nullptr, bool bottom_cap=true, bool top_cap=true)
Draw a textured truncated cone in model space.
tgx::Renderer3D::spotLightCount
int spotLightCount() const
Return the number of active spot lights.
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::setSpotLight
void setSpotLight(int index, const fVec3 &position, const fVec3 &direction, float range, float outerAngleDeg, float innerAngleDeg, const RGBf &diffuseColor, const RGBf &specularColor=RGBf(0.0f, 0.0f, 0.0f))
Configure one spot light with a soft cone edge.
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::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::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::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::modelToNDC
fVec4 modelToNDC(fVec3 P)
Convert from model coordinates to normalized device coordinates (NDC).
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::drawWireFrameTruncatedCone
void drawWireFrameTruncatedCone(int nb_sectors, float bottom_radius, float top_radius, bool bottom_cap=true, bool top_cap=true)
Draw a wireframe truncated cone in model space [fast].
tgx::Renderer3D::usePerspectiveProjection
void usePerspectiveProjection()
Set projection mode to perspective (ie with z-divide).
tgx::Renderer3D::setMaterialAmbiantStrength
void setMaterialAmbiantStrength(float strenght=0.1f)
Set how much the object material reflects the ambient light.
tgx::Renderer3D::setDirectionalLightDiffuse
void setDirectionalLightDiffuse(int index, const RGBf &color)
Set the diffuse color of one directional light.
tgx::Renderer3D::setMaterialSpecularExponent
void setMaterialSpecularExponent(int exponent=16)
Set the object specular exponent.
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::setCulling
void setCulling(int w)
Set the face culling strategy.
tgx::Renderer3D::drawWireFrameTruncatedCone
void drawWireFrameTruncatedCone(int nb_sectors, float bottom_radius, float top_radius, bool bottom_cap, bool top_cap, float thickness, color_t color, float opacity)
Draw a wireframe truncated cone in model space [adjustable thickness + AA].
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::useOrthographicProjection
void useOrthographicProjection()
Set projection mode to orthographic (ie no z-divide).
tgx::Renderer3D::drawTriangleStrip
void drawTriangleStrip(int nb_indices, 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 triangle strip.
tgx::Renderer3D::setDirectionalLightDirection
void setDirectionalLightDirection(int index, const fVec3 &direction)
Set the direction of one directional light.
tgx::Renderer3D::setViewMatrix
void setViewMatrix(const fMat4 &M)
Set the view transformation matrix.
tgx::Renderer3D::drawWireFrameTriangleStrip
void drawWireFrameTriangleStrip(int nb_indices, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw a triangle strip in wireframe [fast].
tgx::Renderer3D::clearZbuffer
void clearZbuffer()
Clear the Zbuffer.
tgx::Renderer3D::setMaterialColor
void setMaterialColor(RGBf color)
Set the object material color.
tgx::Renderer3D::worldToNDC
fVec4 worldToNDC(fVec3 P)
Convert from world coordinates to normalized device coordinates (NDC).
tgx::Renderer3D::drawPixel
void drawPixel(const fVec3 &pos)
Draw a single pixel at a given position in model space.
tgx::Renderer3D::drawWireFrameTriangleStripAA
void drawWireFrameTriangleStripAA(int nb_indices, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw a triangle strip in wireframe [antialiased] with the current material color.
tgx::Renderer3D::drawWireFrameCylinderAA
void drawWireFrameCylinderAA(int nb_sectors, bool bottom_cap=true, bool top_cap=true)
Draw a wireframe unit cylinder in model space [antialiased].
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::drawDot
void drawDot(const fVec3 &pos, int r)
Draw a dot/circle at a given position in model space.
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::setSpotLightDiffuse
void setSpotLightDiffuse(int index, const RGBf &color)
Set the diffuse color of one spot light.
tgx::Renderer3D::setLight
void setLight(const fVec3 direction, const RGBf &ambiantColor, const RGBf &diffuseColor, const RGBf &specularColor)
Set all lighting parameters of the main directional light of the scene at once.
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::setMaterial
void setMaterial(RGBf color, float ambiantStrength, float diffuseStrength, float specularStrength, int specularExponent)
Set all the object material properties at once.
tgx::Renderer3D::maxDirectionalLightCount
static constexpr int maxDirectionalLightCount()
Return the compile-time directional-light capacity.
Definition: Renderer3D.h:697
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::setLightSpecular
void setLightSpecular(const RGBf &color)
Set the specular light color of the main directional light of the scene.
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::drawCone
void drawCone(int nb_sectors, bool bottom_cap=true)
Draw a unit cone in model space.
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::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::directionalLightCount
int directionalLightCount() const
Return the number of active directional lights.
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::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::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::drawWireFrameCone
void drawWireFrameCone(int nb_sectors, bool bottom_cap, float thickness, color_t color, float opacity)
Draw a wireframe unit cone in model space [adjustable thickness + AA].
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::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:157
tgx::Mesh3Dv2
Compact meshlet-based 3D mesh data structure.
Definition: Mesh3Dv2.h:239
tgx::RGBf
Color in R,G,B float format.
Definition: Color.h:2405
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::Vec3::normalize
void normalize()
Normalise the vector so that its norm is 1 (do nothing if the vector is 0).
Definition: Vec3.h:382
tgx::Vec4< float >
tgx::Vec4::w
T w
'w' coordinate (fourth dimension)
Definition: Vec4.h:85
tgx::Vec4::zdivide
TGX_INLINE_ZDIVIDE void zdivide()
Performs the 'z-divide' operation.
Definition: Vec4.h:478