TGX 1.1.1
A tiny 2D/3D graphics library optimized for 32 bits microcontrollers.
Loading...
Searching...
No Matches
Renderer3D.h
Go to the documentation of this file.
1
5//
6// Copyright 2020 Arvind Singh
7//
8// This library is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Lesser General Public
10// License as published by the Free Software Foundation; either
11//version 2.1 of the License, or (at your option) any later version.
12//
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU
16// Lesser General Public License for more details.
17//
18// You should have received a copy of the GNU Lesser General Public
19// License along with this library; If not, see <http://www.gnu.org/licenses/>.
20
21#ifndef _TGX_RENDERER3D_H_
22#define _TGX_RENDERER3D_H_
23
24// only C++, no plain C
25#ifdef __cplusplus
26
27
28#include "Misc.h"
29#include "Color.h"
30#include "Vec2.h"
31#include "Vec3.h"
32#include "Vec4.h"
33#include "Box2.h"
34#include "Box3.h"
35#include "Mat4.h"
36#include "Image.h"
37
38#include "Shaders.h"
39#include "Rasterizer.h"
40
41#include "Mesh3D.h"
42#include "Mesh3Dv2.h"
43
44namespace tgx
45{
46
47 // forward declaration for the vertices and faces of the unit cube [-1,1]^3
48
49 extern const tgx::fVec3 UNIT_CUBE_VERTICES[8];
50 extern const tgx::fVec3 UNIT_CUBE_NORMALS[6];
51 extern const uint16_t UNIT_CUBE_FACES[6*4];
52 extern const uint16_t UNIT_CUBE_FACES_NORMALS[6 * 4];
53
54
55
107 template<typename color_t, Shader LOADED_SHADERS = TGX_SHADER_MASK_ALL, typename ZBUFFER_t = float>
109 {
110
111
112 static constexpr int MAXVIEWPORTDIMENSION = 2048 * (1 << ((8 - TGX_RASTERIZE_SUBPIXEL_BITS) >> 1));
113
114 static_assert(is_color<color_t>::value, "color_t must be one of the color types defined in color.h");
115 static_assert((std::is_same<ZBUFFER_t, float>::value) || (std::is_same<ZBUFFER_t, uint16_t>::value), "The Z-buffer type must be either float or uint16_t");
116
117 // true if some kind of texturing may be used.
118 static constexpr int ENABLE_TEXTURING = (TGX_SHADER_HAS_ONE_FLAG(LOADED_SHADERS , (SHADER_TEXTURE | TGX_SHADER_MASK_TEXTURE_MODE | TGX_SHADER_MASK_TEXTURE_QUALITY)));
119
120 static constexpr Shader ENABLED_SHADERS = LOADED_SHADERS | (ENABLE_TEXTURING ? SHADER_TEXTURE : SHADER_NOTEXTURE); // enable texturing when at least one texturing related flag is set
121
122 // check that disabled shaders do not completely disable all drawing operations.
123 static_assert(TGX_SHADER_HAS_ONE_FLAG(ENABLED_SHADERS,TGX_SHADER_MASK_PROJECTION), "At least one of the two shaders SHADER_PERSPECTIVE or SHADER_ORTHO must be enabled");
124 static_assert(TGX_SHADER_HAS_ONE_FLAG(ENABLED_SHADERS,TGX_SHADER_MASK_ZBUFFER), "At least one of the two shaders SHADER_NOZBUFFER or SHADER_ZBUFFER must be enabled");
125 static_assert(TGX_SHADER_HAS_ONE_FLAG(ENABLED_SHADERS,TGX_SHADER_MASK_SHADING), "At least one of the shaders SHADER_UNLIT, SHADER_FLAT or SHADER_GOURAUD must be enabled");
126 static_assert(TGX_SHADER_HAS_ONE_FLAG(ENABLED_SHADERS,TGX_SHADER_MASK_TEXTURE), "At least one of the two shaders SHADER_TEXTURE or SHADER_NOTEXTURE must be enabled");
127 static_assert((!TGX_SHADER_HAS_TEXTURE(ENABLED_SHADERS)) || (TGX_SHADER_HAS_ONE_FLAG(ENABLED_SHADERS,TGX_SHADER_MASK_TEXTURE_QUALITY)),"When using texturing, at least one of the two shaders SHADER_TEXTURE_BILINEAR or SHADER_TEXTURE_NEAREST must be enabled");
128 static_assert((!TGX_SHADER_HAS_TEXTURE(ENABLED_SHADERS)) || (TGX_SHADER_HAS_ONE_FLAG(ENABLED_SHADERS, TGX_SHADER_MASK_TEXTURE_MODE)), "When using texturing, at least one of the two shaders SHADER_TEXTURE_WRAP_POW2 or SHADER_TEXTURE_CLAMP must be enabled");
129
130
131
132 public:
133
134
144 TGX_NOINLINE Renderer3D(const iVec2& viewportSize = {0,0}, Image<color_t> * im = nullptr, ZBUFFER_t * zbuffer = nullptr);
145
146
147
148
149 /*****************************************************************************************
150 *****************************************************************************************/
157 /*****************************************************************************************
158 ******************************************************************************************/
159
160
181 void setViewportSize(int lx, int ly);
182
183
191 void setViewportSize(const iVec2& viewport_dim);
192
193
206
207
226 void setOffset(int ox, int oy);
227
228
236 void setOffset(const iVec2& offset);
237
238
257
258
265
266
273
274
281
282
299 void setOrtho(float left, float right, float bottom, float top, float zNear, float zFar);
300
301
318 void setFrustum(float left, float right, float bottom, float top, float zNear, float zFar);
319
320
338 void setPerspective(float fovy, float aspect, float zNear, float zFar);
339
340
358 void setCulling(int w);
359
360
373 void setZbuffer(ZBUFFER_t* zbuffer);
374
375
385
386
425 void setShaders(Shader shaders);
426
427
436
437
446
447
448
450 /*****************************************************************************************
451 *****************************************************************************************/
458 /*****************************************************************************************
459 ******************************************************************************************/
460
461
462
479 void setViewMatrix(const fMat4& M);
480
481
490
491
503 void setLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ);
504
505
517 void setLookAt(const fVec3 eye, const fVec3 center, const fVec3 up);
518
519
533
534
547
548
558 void setLightDirection(const fVec3& direction);
559
560
570 void setLightAmbiant(const RGBf& color);
571
572
582 void setLightDiffuse(const RGBf& color);
583
584
594 void setLightSpecular(const RGBf& color);
595
596
611 void setLight(const fVec3 direction, const RGBf& ambiantColor, const RGBf& diffuseColor, const RGBf& specularColor);
612
613
614
615
616
618 /*****************************************************************************************
619 *****************************************************************************************/
626 /*****************************************************************************************
627 ******************************************************************************************/
628
629
630
641 void setModelMatrix(const fMat4& M);
642
643
652
653
675 void setModelPosScaleRot(const fVec3& center = fVec3{ 0,0,0 }, const fVec3& scale = fVec3(1, 1, 1), float rot_angle = 0, const fVec3& rot_dir = fVec3{ 0,1,0 });
676
677
689
690
703
704
716
717
726 void setMaterialAmbiantStrength(float strenght = 0.1f);
727
728
737 void setMaterialDiffuseStrength(float strenght = 0.6f);
738
739
748 void setMaterialSpecularStrength(float strenght = 0.5f);
749
750
761 void setMaterialSpecularExponent(int exponent = 16);
762
763
776 void setMaterial(RGBf color, float ambiantStrength, float diffuseStrength, float specularStrength, int specularExponent);
777
778
779
780
781
782
783
784
786 /*****************************************************************************************
787 *****************************************************************************************/
801 /*****************************************************************************************
802 ******************************************************************************************/
803
804
805
822 void drawMesh(const Mesh3D<color_t>* mesh, bool use_mesh_material = true, bool draw_chained_meshes = true);
823
824
837 void drawMesh(const Mesh3Dv2<color_t>* mesh, bool use_mesh_material = true);
838
839
853 void drawTriangle(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3,
854 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr,
855 const fVec2 * T1 = nullptr, const fVec2 * T2 = nullptr, const fVec2 * T3 = nullptr,
856 const Image<color_t> * texture = nullptr);
857
858
871 void drawTriangleWithVertexColor(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3,
872 const RGBf & col1, const RGBf & col2, const RGBf & col3,
873 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr);
874
875
894 void drawTriangles(int nb_triangles,
895 const uint16_t * ind_vertices, const fVec3 * vertices,
896 const uint16_t * ind_normals = nullptr, const fVec3* normals = nullptr,
897 const uint16_t * ind_texture = nullptr, const fVec2* textures = nullptr,
898 const Image<color_t> * texture_image = nullptr);
899
900
923 void drawTriangleStrip(int nb_indices,
924 const uint16_t* ind_vertices, const fVec3* vertices,
925 const uint16_t* ind_normals = nullptr, const fVec3* normals = nullptr,
926 const uint16_t* ind_texture = nullptr, const fVec2* textures = nullptr,
927 const Image<color_t>* texture_image = nullptr);
928
929
930
946 void drawQuad(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3, const fVec3 & P4,
947 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr, const fVec3 * N4 = nullptr,
948 const fVec2 * T1 = nullptr, const fVec2 * T2 = nullptr, const fVec2 * T3 = nullptr, const fVec2 * T4 = nullptr,
949 const Image<color_t>* texture = nullptr);
950
951
952
968 void drawQuadWithVertexColor(const fVec3 & P1, const fVec3 & P2, const fVec3 & P3, const fVec3 & P4,
969 const RGBf & col1, const RGBf & col2, const RGBf & col3, const RGBf & col4,
970 const fVec3 * N1 = nullptr, const fVec3 * N2 = nullptr, const fVec3 * N3 = nullptr, const fVec3 * N4 = nullptr);
971
972
973
974
995 void drawQuads(int nb_quads,
996 const uint16_t * ind_vertices, const fVec3 * vertices,
997 const uint16_t * ind_normals = nullptr, const fVec3* normals = nullptr,
998 const uint16_t * ind_texture = nullptr, const fVec2* textures = nullptr,
999 const Image<color_t>* texture_image = nullptr);
1000
1001
1002
1003
1005 /*****************************************************************************************
1006 *****************************************************************************************/
1013 /*****************************************************************************************
1014 ******************************************************************************************/
1015
1016
1017
1024 void drawCube();
1025
1026
1069 const fVec2 v_front_ABCD[4] , const Image<color_t>* texture_front,
1070 const fVec2 v_back_EFGH[4] , const Image<color_t>* texture_back,
1071 const fVec2 v_top_HADE[4] , const Image<color_t>* texture_top,
1072 const fVec2 v_bottom_BGFC[4], const Image<color_t>* texture_bottom,
1073 const fVec2 v_left_HGBA[4] , const Image<color_t>* texture_left,
1074 const fVec2 v_right_DCFE[4] , const Image<color_t>* texture_right
1075 );
1076
1077
1114 const Image<color_t>* texture_front,
1115 const Image<color_t>* texture_back,
1116 const Image<color_t>* texture_top,
1117 const Image<color_t>* texture_bottom,
1118 const Image<color_t>* texture_left,
1119 const Image<color_t>* texture_right
1120 );
1121
1122
1123
1134 void drawSphere(int nb_sectors, int nb_stacks);
1135
1136
1149 void drawSphere(int nb_sectors, int nb_stacks, const Image<color_t>* texture);
1150
1151
1166 void drawAdaptativeSphere(float quality = 1.0f);
1167
1168
1186 void drawAdaptativeSphere(const Image<color_t>* texture, float quality = 1.0f);
1187
1188
1189
1190
1191
1192
1193
1194
1196 /*****************************************************************************************
1197 *****************************************************************************************/
1212 /*****************************************************************************************
1213 ******************************************************************************************/
1214
1215
1216
1228 void drawWireFrameMesh(const Mesh3D<color_t>* mesh, bool draw_chained_meshes = true);
1229
1230
1243
1244
1255 void drawWireFrameMeshAA(const Mesh3D<color_t>* mesh, bool draw_chained_meshes = true);
1256
1257
1268
1269
1286 void drawWireFrameMesh(const Mesh3D<color_t>* mesh, bool draw_chained_meshes, float thickness, color_t color, float opacity);
1287
1288
1305 void drawWireFrameMesh(const Mesh3Dv2<color_t>* mesh, float thickness, color_t color, float opacity);
1306
1307
1317 void drawWireFrameLine(const fVec3& P1, const fVec3& P2);
1318
1319
1329 void drawWireFrameLineAA(const fVec3& P1, const fVec3& P2);
1330
1331
1344 void drawWireFrameLine(const fVec3& P1, const fVec3& P2, float thickness, color_t color, float opacity);
1345
1346
1358 void drawWireFrameLines(int nb_lines, const uint16_t* ind_vertices, const fVec3* vertices);
1359
1360
1372 void drawWireFrameLinesAA(int nb_lines, const uint16_t* ind_vertices, const fVec3* vertices);
1373
1374
1389 void drawWireFrameLines(int nb_lines, const uint16_t* ind_vertices, const fVec3* vertices, float thickness, color_t color, float opacity);
1390
1391
1402 void drawWireFrameTriangle(const fVec3& P1, const fVec3& P2, const fVec3& P3);
1403
1404
1414 void drawWireFrameTriangleAA(const fVec3& P1, const fVec3& P2, const fVec3& P3);
1415
1416
1431 void drawWireFrameTriangle(const fVec3& P1, const fVec3& P2, const fVec3& P3, float thickness, color_t color, float opacity);
1432
1433
1446 void drawWireFrameTriangles(int nb_triangles, const uint16_t* ind_vertices, const fVec3* vertices);
1447
1448
1460 void drawWireFrameTrianglesAA(int nb_triangles, const uint16_t* ind_vertices, const fVec3* vertices);
1461
1462
1479 void drawWireFrameTriangles(int nb_triangles, const uint16_t* ind_vertices, const fVec3* vertices, float thickness, color_t color, float opacity);
1480
1481
1496 void drawWireFrameTriangleStrip(int nb_indices, const uint16_t* ind_vertices, const fVec3* vertices);
1497
1498
1512 void drawWireFrameTriangleStripAA(int nb_indices, const uint16_t* ind_vertices, const fVec3* vertices);
1513
1514
1533 void drawWireFrameTriangleStrip(int nb_indices, const uint16_t* ind_vertices, const fVec3* vertices, float thickness, color_t color, float opacity);
1534
1535
1547 void drawWireFrameQuad(const fVec3& P1, const fVec3& P2, const fVec3& P3, const fVec3& P4);
1548
1549
1559 void drawWireFrameQuadAA(const fVec3& P1, const fVec3& P2, const fVec3& P3, const fVec3& P4);
1560
1561
1577 void drawWireFrameQuad(const fVec3& P1, const fVec3& P2, const fVec3& P3, const fVec3& P4, float thickness, color_t color, float opacity);
1578
1579
1593 void drawWireFrameQuads(int nb_quads, const uint16_t* ind_vertices, const fVec3* vertices);
1594
1595
1607 void drawWireFrameQuadsAA(int nb_quads, const uint16_t* ind_vertices, const fVec3* vertices);
1608
1609
1627 void drawWireFrameQuads(int nb_quads, const uint16_t* ind_vertices, const fVec3* vertices, float thickness, color_t color, float opacity);
1628
1629
1630
1631
1633 /*****************************************************************************************
1634 *****************************************************************************************/
1649 /*****************************************************************************************
1650 ******************************************************************************************/
1651
1652
1661
1662
1671
1672
1686 void drawWireFrameCube(float thickness, color_t color, float opacity);
1687
1688
1700 void drawWireFrameSphere(int nb_sectors, int nb_stacks);
1701
1702
1713 void drawWireFrameSphereAA(int nb_sectors, int nb_stacks);
1714
1715
1732 void drawWireFrameSphere(int nb_sectors, int nb_stacks, float thickness, color_t color, float opacity);
1733
1734
1748 void drawWireFrameAdaptativeSphere(float quality = 1.0f);
1749
1750
1760 void drawWireFrameAdaptativeSphereAA(float quality = 1.0f);
1761
1762
1781 void drawWireFrameAdaptativeSphere(float quality, float thickness, color_t color, float opacity);
1782
1783
1784
1785
1786
1788 /*****************************************************************************************
1789 *****************************************************************************************/
1798 /*****************************************************************************************
1799 ******************************************************************************************/
1800
1801
1802
1812 void drawPixel(const fVec3& pos);
1813
1814
1826 void drawPixel(const fVec3& pos, color_t color, float opacity);
1827
1828
1839 void drawPixels(int nb_pixels, const fVec3* pos_list);
1840
1841
1856 void drawPixels(int nb_pixels, const fVec3* pos_list, const int* colors_ind, const color_t* colors, const int* opacities_ind, const float* opacities);
1857
1858
1869 void drawDot(const fVec3& pos, int r);
1870
1871
1872
1885 void drawDot(const fVec3& pos, int r, color_t color, float opacity);
1886
1887
1899 void drawDots(int nb_dots, const fVec3* pos_list, const int radius);
1900
1901
1919 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);
1920
1921
1922
1923
1924
1926
1927
1928
1929
1930
1931 private:
1932
1933
1934
1935 /*****************************************************************************************
1936 ******************************************************************************************
1937 *
1938 * BE CAREFUL PAST THIS POINT... FOR HERE BE DRAGONS !
1939 *
1940 ******************************************************************************************
1941 ******************************************************************************************/
1942
1943
1945 TGX_INLINE float _clipbound_xy() const
1946 {
1947 return (256 + 3*((MAXVIEWPORTDIMENSION * 256) / ((_lx > _ly) ? _lx : _ly))) / 1024.0f; // use integer computation up to the last divide
1948 //return (1.0f + 3.0f * (((float)MAXVIEWPORTDIMENSION) / ((_lx > _ly) ? _lx : _ly))) / 4.0f;
1949 }
1950
1951
1953 TGX_INLINE bool _validDraw() const
1954 {
1955 return ((_lx > 0) && (_ly > 0) && (_uni.im != nullptr) && (_uni.im->isValid()));
1956 }
1957
1958
1960 TGX_NOINLINE void _recompute_wa_wb();
1961
1962
1963 /***********************************************************
1964 * Making sure shader flags are coherent
1965 ************************************************************/
1966
1967 TGX_NOINLINE void _rectifyShaderOrtho();
1968
1969
1970 TGX_NOINLINE void _rectifyShaderZbuffer();
1971
1972
1973 TGX_NOINLINE void _rectifyShaderShading(Shader new_shaders);
1974
1975
1976 TGX_NOINLINE void _rectifyShaderTextureWrapping();
1977
1978
1979 TGX_NOINLINE void _rectifyShaderTextureQuality();
1980
1981
1982 /***********************************************************
1983 * DRAWING STUFF
1984 ************************************************************/
1985
1986
1988 void _drawTriangleClipped(const int RASTER_TYPE,
1989 const fVec4* Q0, const fVec4* Q1, const fVec4* Q2,
1990 const fVec3* N0, const fVec3* N1, const fVec3* N2,
1991 const fVec2* T0, const fVec2* T1, const fVec2* T2,
1992 const RGBf& Vcol0, const RGBf& Vcol1, const RGBf& Vcol2);
1993
1994
1996 void _drawTriangleClippedSub(const int RASTER_TYPE, const int plane,
1997 const RasterizerVec4& P1, const RasterizerVec4& P2, const RasterizerVec4& P3);
1998
1999
2001 void _drawTriangle(const int RASTER_TYPE,
2002 const fVec3* P0, const fVec3* P1, const fVec3* P2,
2003 const fVec3* N0, const fVec3* N1, const fVec3* N2,
2004 const fVec2* T0, const fVec2* T1, const fVec2* T2,
2005 const RGBf& Vcol0, const RGBf& Vcol1, const RGBf& Vcol2);
2006
2007
2009 void _drawTriangleStrip(const int RASTER_TYPE, int nb_indices,
2010 const uint16_t* ind_vertices, const fVec3* vertices,
2011 const uint16_t* ind_normals, const fVec3* normals,
2012 const uint16_t* ind_texture, const fVec2* textures);
2013
2014
2016 void _drawQuad(const int RASTER_TYPE,
2017 const fVec3* P0, const fVec3* P1, const fVec3* P2, const fVec3* P3,
2018 const fVec3* N0, const fVec3* N1, const fVec3* N2, const fVec3* N3,
2019 const fVec2* T0, const fVec2* T1, const fVec2* T2, const fVec2* T3,
2020 const RGBf& Vcol0, const RGBf& Vcol1, const RGBf& Vcol2, const RGBf& Vcol3);
2021
2022
2024 void _drawMesh(const int RASTER_TYPE, const Mesh3D<color_t>* mesh);
2025
2027 void _drawMesh(const int RASTER_TYPE, const Mesh3Dv2<color_t>* mesh, bool use_mesh_material);
2028
2030 TGX_INLINE inline bool _discardMeshlet16b(const fVec3& sphere_center, float sphere_radius, const fVec3& cone_dir, float cone_cos) const
2031 {
2032 if (cone_cos <= -1.0f) return false;
2033
2034 const fVec4 D = _r_modelViewM.mult0(cone_dir);
2035 const float dd = D.x * D.x + D.y * D.y + D.z * D.z;
2036 if (dd <= 1.0e-20f) return false;
2037
2038 float dot;
2039 float len2;
2040 if (_ortho)
2041 {
2042 dot = D.z; // object-to-camera direction is +Z in view space.
2043 len2 = dd;
2044 }
2045 else
2046 {
2047 const fVec3 anchor = sphere_center - (cone_dir * sphere_radius);
2048 const fVec4 A = _r_modelViewM.mult1(anchor);
2049 dot = -(D.x * A.x + D.y * A.y + D.z * A.z);
2050 const float aa = A.x * A.x + A.y * A.y + A.z * A.z;
2051 if (aa <= 1.0e-20f) return false;
2052 len2 = dd * aa;
2053 }
2054
2055 const float c2len2 = cone_cos * cone_cos * len2;
2056 const float dot2 = dot * dot;
2057 return (cone_cos >= 0.0f) ? ((dot < 0.0f) || (dot2 < c2len2))
2058 : ((dot < 0.0f) && (dot2 > c2len2));
2059 }
2060
2061
2062
2063 /***********************************************************
2064 * Drawing wireframe
2065 ************************************************************/
2066
2067 inline void _drawWireFrameLineFast(iVec2 P0, iVec2 P1, color_t color);
2068
2069 template<bool CHECK_NEIGHBOR> inline void _drawWireFrameLineAAFast(const fVec2& P0, const fVec2& P1, color_t color, int32_t op);
2070
2071 template<int MODE> void _drawWireFrameMesh(const Mesh3D<color_t>* mesh, bool draw_chained_meshes, color_t color, float opacity, float thickness);
2072
2073 template<int MODE> void _drawWireFrameMesh(const Mesh3Dv2<color_t>* mesh, color_t color, float opacity, float thickness);
2074
2075 template<int MODE> void _drawWireFrameLine(const fVec3& P1, const fVec3& P2, color_t color, float opacity, float thickness);
2076
2077 template<int MODE> void _drawWireFrameLines(int nb_lines, const uint16_t* ind_vertices, const fVec3* vertices, color_t color, float opacity, float thickness);
2078
2079 template<int MODE> void _drawWireFrameTriangle(const fVec3& P1, const fVec3& P2, const fVec3& P3, color_t color, float opacity, float thickness);
2080
2081 template<int MODE> void _drawWireFrameTriangles(int nb_triangles, const uint16_t* ind_vertices, const fVec3* vertices, color_t color, float opacity, float thickness);
2082
2083 template<int MODE> void _drawWireFrameTriangleStrip(int nb_indices, const uint16_t* ind_vertices, const fVec3* vertices, color_t color, float opacity, float thickness);
2084
2085 template<int MODE> void _drawWireFrameQuad(const fVec3& P1, const fVec3& P2, const fVec3& P3, const fVec3& P4, color_t color, float opacity, float thickness);
2086
2087 template<int MODE> void _drawWireFrameQuads(int nb_quads, const uint16_t* ind_vertices, const fVec3* vertices, color_t color, float opacity, float thickness);
2088
2089
2090
2091
2092 /***********************************************************
2093 * Simple geometric objects
2094 ************************************************************/
2095
2096
2097 template<bool USE_BLENDING> void _drawPixel(const fVec3& pos, color_t color, float opacity);
2098
2099
2100 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);
2101
2102
2103 template<bool USE_BLENDING> void _drawDot(const fVec3& pos, int r, color_t color, float opacity);
2104
2105
2106 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);
2107
2108
2109
2110 template<bool CHECKRANGE, bool USE_BLENDING> TGX_INLINE inline void drawPixelZbuf(int x, int y, color_t color, float opacity, float z)
2111 {
2112 if (CHECKRANGE && ((x < 0) || (x >= _uni.im->lx()) || (y < 0) || (y >= _uni.im->ly()))) return;
2113 ZBUFFER_t& W = _uni.zbuf[x + _uni.im->lx() * y];
2114 const ZBUFFER_t aa = (std::is_same<ZBUFFER_t, uint16_t>::value) ? ((ZBUFFER_t)(z * _uni.wa + _uni.wb)) : ((ZBUFFER_t)z);
2115 if (W < aa)
2116 {
2117 W = aa;
2118 if (USE_BLENDING) _uni.im->template drawPixel<false>({ x, y }, color, opacity); else _uni.im->template drawPixel<false>({ x, y }, color);
2119 }
2120 }
2121
2122
2123 template<bool CHECKRANGE, bool USE_BLENDING> TGX_INLINE inline void drawHLineZbuf(int x, int y, int w, color_t color, float opacity, float z)
2124 {
2125 if (CHECKRANGE) // optimized away at compile time
2126 {
2127 const int lx = _uni.im->lx();
2128 const int ly = _uni.im->ly();
2129 if ((y < 0) || (y >= ly) || (x >= lx)) return;
2130 if (x < 0) { w += x; x = 0; }
2131 if (x + w > lx) { w = lx - x; }
2132 if (w <= 0) return;
2133 }
2134 while(w--) drawPixelZbuf<CHECKRANGE, USE_BLENDING>(x++, y, color, opacity, z);
2135 }
2136
2137
2138 template<bool CHECKRANGE, bool USE_BLENDING> void _drawCircleZbuf(int xm, int ym, int r, color_t color, float opacity, float z);
2139
2140
2144 float _unitSphereScreenDiameter();
2145
2146
2147 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);
2148
2149
2150
2151 /***********************************************************
2152 * CLIPPING
2153 ************************************************************/
2154
2155
2157 TGX_INLINE inline void _clip(int & fl, const fVec4 & P, float bx, float Bx, float by, float By)
2158 {
2159 if (P.x >= bx) { fl &= (~(1)); }
2160 if (P.x <= Bx) { fl &= (~(2)); }
2161 if (P.y >= by) { fl &= (~(4)); }
2162 if (P.y <= By) { fl &= (~(8)); }
2163 if ((P.z >= -1.0f)&&(P.w > 0)) { fl &= (~(16)); }
2164 if (P.z <= +1.0f) { fl &= (~(32)); }
2165 }
2166
2167
2169 TGX_INLINE inline void _clip(int & fl, const fVec3 & P, float bx, float Bx, float by, float By, const fMat4 & M)
2170 {
2171 fVec4 S = M.mult1(P);
2172 if (!_ortho) S.zdivide();
2173 return _clip(fl, S, bx, Bx, by, By);
2174 }
2175
2176
2177 /* test if a box is outside the image and should be discarded.
2178 transform the box coords with M then z-divide. */
2179 bool _discardBox(const fBox3 & bb, const fMat4 & M)
2180 {
2181 if ((bb.minX == 0) && (bb.maxX == 0) && (bb.minY == 0) && (bb.maxY == 0) && (bb.minZ == 0) && (bb.maxZ == 0))
2182 return false; // do not discard if the bounding box is uninitialized.
2183
2184 const float bx = (_ox - 1) * _ilx - 1.0f;
2185 const float Bx = (_ox + _uni.im->width() + 1) * _ilx - 1.0f;
2186 const float by = (_oy - 1) * _ily - 1.0f;
2187 const float By = (_oy + _uni.im->height() + 1) * _ily - 1.0f;
2188
2189 int fl = 63; // every bit set
2190 _clip(fl, fVec3(bb.minX, bb.minY, bb.minZ), bx, Bx, by, By, M);
2191 if (fl == 0) return false;
2192 _clip(fl, fVec3(bb.minX, bb.minY, bb.maxZ), bx, Bx, by, By, M);
2193 if (fl == 0) return false;
2194 _clip(fl, fVec3(bb.minX, bb.maxY, bb.minZ), bx, Bx, by, By, M);
2195 if (fl == 0) return false;
2196 _clip(fl, fVec3(bb.minX, bb.maxY, bb.maxZ), bx, Bx, by, By, M);
2197 if (fl == 0) return false;
2198 _clip(fl, fVec3(bb.maxX, bb.minY, bb.minZ), bx, Bx, by, By, M);
2199 if (fl == 0) return false;
2200 _clip(fl, fVec3(bb.maxX, bb.minY, bb.maxZ), bx, Bx, by, By, M);
2201 if (fl == 0) return false;
2202 _clip(fl, fVec3(bb.maxX, bb.maxY, bb.minZ), bx, Bx, by, By, M);
2203 if (fl == 0) return false;
2204 _clip(fl, fVec3(bb.maxX, bb.maxY, bb.maxZ), bx, Bx, by, By, M);
2205 if (fl == 0) return false;
2206 return true;
2207 }
2208
2209
2210 /* test if a triangle is completely outside the image and should be discarded.
2211 * coords are given after z-divide. */
2212 bool _discardTriangle(const fVec4 & P1, const fVec4 & P2, const fVec4 & P3)
2213 {
2214 const float bx = (_ox - 1) * _ilx - 1.0f;
2215 const float Bx = (_ox + _uni.im->width() + 1) * _ilx - 1.0f;
2216 const float by = (_oy - 1) * _ily - 1.0f;
2217 const float By = (_oy + _uni.im->height() + 1) * _ily - 1.0f;
2218
2219 int fl = 63; // every bit set
2220 _clip(fl, P1, bx, Bx, by, By);
2221 if (fl == 0) return false;
2222 _clip(fl, P2, bx, Bx, by, By);
2223 if (fl == 0) return false;
2224 _clip(fl, P3, bx, Bx, by, By);
2225 if (fl == 0) return false;
2226 return true;
2227 }
2228
2229
2231 bool _clip2(float clipboundXY, const fVec3 & P, const fMat4 & M)
2232 {
2233 fVec4 S = M.mult1(P);
2234 if (!_ortho)
2235 {
2236 S.zdivide();
2237 if (S.w <= 0) S.z = -2;
2238 }
2239 return ((S.x <= -clipboundXY) || (S.x >= clipboundXY)
2240 || (S.y <= -clipboundXY) || (S.y >= clipboundXY)
2241 || (S.z <= -1) || (S.z >= 1));
2242 }
2243
2244
2246 bool _clipTestNeeded(float clipboundXY, const fBox3 & bb, const fMat4 & M)
2247 {
2248 return (_clip2(clipboundXY, fVec3(bb.minX, bb.minY, bb.minZ), M)
2249 || _clip2(clipboundXY, fVec3(bb.minX, bb.minY, bb.maxZ), M)
2250 || _clip2(clipboundXY, fVec3(bb.minX, bb.maxY, bb.minZ), M)
2251 || _clip2(clipboundXY, fVec3(bb.minX, bb.maxY, bb.maxZ), M)
2252 || _clip2(clipboundXY, fVec3(bb.maxX, bb.minY, bb.minZ), M)
2253 || _clip2(clipboundXY, fVec3(bb.maxX, bb.minY, bb.maxZ), M)
2254 || _clip2(clipboundXY, fVec3(bb.maxX, bb.maxY, bb.minZ), M)
2255 || _clip2(clipboundXY, fVec3(bb.maxX, bb.maxY, bb.maxZ), M));
2256 }
2257
2258
2260 bool _wireFrameAANeighborCheckNeeded(const fBox3& bb, const fMat4& proj_modelview)
2261 {
2262 if ((_uni.im == nullptr) || (_uni.im->lx() <= 2) || (_uni.im->ly() <= 2)) return true;
2263
2264 const float bx = (_ox + 1.0f) * _ilx - 1.0f;
2265 const float Bx = (_ox + (float)(_uni.im->lx() - 2)) * _ilx - 1.0f;
2266 const float by = (_oy + 1.0f) * _ily - 1.0f;
2267 const float By = (_oy + (float)(_uni.im->ly() - 2)) * _ily - 1.0f;
2268
2269 const fVec3 C[8] = {
2270 fVec3(bb.minX, bb.minY, bb.minZ),
2271 fVec3(bb.minX, bb.minY, bb.maxZ),
2272 fVec3(bb.minX, bb.maxY, bb.minZ),
2273 fVec3(bb.minX, bb.maxY, bb.maxZ),
2274 fVec3(bb.maxX, bb.minY, bb.minZ),
2275 fVec3(bb.maxX, bb.minY, bb.maxZ),
2276 fVec3(bb.maxX, bb.maxY, bb.minZ),
2277 fVec3(bb.maxX, bb.maxY, bb.maxZ)
2278 };
2279
2280 for (int i = 0; i < 8; i++)
2281 {
2282 fVec4 P = proj_modelview.mult1(C[i]);
2283 if (!_ortho)
2284 {
2285 if (P.w <= 0) return true;
2286 P.zdivide();
2287 }
2288 if ((P.z < -1.0f) || (P.z > 1.0f)) return true;
2289 if ((P.x < bx) || (P.x > Bx) || (P.y < by) || (P.y > By)) return true;
2290 }
2291 return false;
2292 }
2293
2294
2295#if TGX_MESHLET_SPHERE_CLIP
2297 TGX_INLINE inline void _meshletClipPlanes(float clipboundXY, const fMat4& M, fVec4* planes, float* plane_norms) const
2298 {
2299 const float cx = clipboundXY;
2300 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]);
2301 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]);
2302 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]);
2303 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]);
2304 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]);
2305 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]);
2306 for (int i = 0; i < 6; i++)
2307 {
2308 const fVec4& P = planes[i];
2309 plane_norms[i] = sqrtf(P.x * P.x + P.y * P.y + P.z * P.z);
2310 }
2311 }
2312
2313
2315 TGX_INLINE inline int _meshletSphereClip(const fVec3& center, float radius, const fVec4* planes, const float* plane_norms) const
2316 {
2317 bool intersects = false;
2318 for (int i = 0; i < 6; i++)
2319 {
2320 const fVec4& P = planes[i];
2321 const float d = P.x * center.x + P.y * center.y + P.z * center.z + P.w;
2322 const float r = radius * plane_norms[i];
2323 if (d < -r) return -1;
2324 if (d < r) intersects = true;
2325 }
2326 return intersects ? 1 : 0;
2327 }
2328#endif
2329
2330
2331
2332
2333 /***********************************************************
2334 * TRIANGLE CLIPPING AGAINST A CLIP-PLANE
2335 ************************************************************/
2336
2345 inline float _cpdist(const tgx::fVec4& CP, float off, const tgx::fVec4& P)
2346 {
2347 return (CP.x * P.x) + (CP.y * P.y) + (CP.z * P.z) + (CP.w * P.w) + off;
2348 }
2349
2360 inline float _cpfactor(const tgx::fVec4& CP, const float sdistA, const float sdistB)
2361 {
2362 return sdistA / (sdistA - sdistB);
2363 }
2364
2365
2367 void _triangleClip1in(int shader, tgx::fVec4 CP,
2368 float cp1, float cp2, float cp3,
2369 const RasterizerVec4& P1, const RasterizerVec4& P2, const RasterizerVec4& P3,
2370 RasterizerVec4& nP1, RasterizerVec4& nP2, RasterizerVec4& nP3, RasterizerVec4& nP4);
2371
2372
2374 void _triangleClip2in(int shader, tgx::fVec4 CP,
2375 float cp1, float cp2, float cp3,
2376 const RasterizerVec4& P1, const RasterizerVec4& P2, const RasterizerVec4& P3,
2377 RasterizerVec4& nP1, RasterizerVec4& nP2, RasterizerVec4& nP3, RasterizerVec4& nP4);
2378
2379
2380 int _triangleClip(int shader, tgx::fVec4 CP, float off,
2381 const RasterizerVec4 & P1, const RasterizerVec4 & P2, const RasterizerVec4 & P3,
2382 RasterizerVec4 & nP1, RasterizerVec4 & nP2, RasterizerVec4 & nP3, RasterizerVec4 & nP4);
2383
2384
2385
2386 /***********************************************************
2387 * PHONG LIGHTNING
2388 ************************************************************/
2389
2390 static const int _POWTABSIZE = 32; // number of entries in the precomputed power table for specular exponent.
2391 int _currentpow; // exponent for the currently computed table (<0 if table not yet computed)
2392 float _powmax; // used to compute exponent
2393 float _fastpowtab[_POWTABSIZE]; // the precomputed power table.
2394
2396 TGX_INLINE inline void _precomputeSpecularTable(int exponent)
2397 {
2398 if (_currentpow == exponent) return;
2399 _precomputeSpecularTable2(exponent);
2400 }
2401
2402 TGX_NOINLINE void _precomputeSpecularTable2(int exponent);
2403
2404
2406 TGX_INLINE inline float _powSpecular(float x) const
2407 {
2408 const float indf = (_powmax - x) * _POWTABSIZE;
2409 const int indi = max(0,(int)indf);
2410 return (indi >= (_POWTABSIZE - 1)) ? 0.0f : (_fastpowtab[indi] + (indf - indi) * (_fastpowtab[indi + 1] - _fastpowtab[indi]));;
2411 }
2412
2413
2415 template<bool TEXTURE> TGX_INLINE inline RGBf _phong(float v_diffuse, float v_specular) const
2416 {
2417 RGBf col = _r_ambiantColor;
2418 col += _r_diffuseColor * max(v_diffuse, 0.0f);
2419 col += _r_specularColor * _powSpecular(v_specular); // pow() this is too slow so we use a lookup table instead
2420 if (!(TEXTURE)) col *= _r_objectColor;
2421 col.clamp();
2422 return col;
2423 }
2424
2425
2427 TGX_INLINE inline RGBf _phong(float v_diffuse, float v_specular, RGBf color) const
2428 {
2429 RGBf col = _r_ambiantColor;
2430 col += _r_diffuseColor * max(v_diffuse, 0.0f);
2431 col += _r_specularColor * _powSpecular(v_specular); // pow() this is too slow so we use a lookup table instead
2432 col *= color;
2433 col.clamp();
2434 return col;
2435 }
2436
2437
2439 TGX_INLINE inline void _setFlatOrUnlitFaceColor(int raster_type, bool texture, fVec3& faceN, float cu)
2440 {
2441 if constexpr (TGX_SHADER_HAS_UNLIT(ENABLED_SHADERS))
2442 {
2443 if (TGX_SHADER_HAS_UNLIT(raster_type))
2444 {
2445 _uni.facecolor = texture ? RGBf(1.0f, 1.0f, 1.0f) : _r_objectColor;
2446 return;
2447 }
2448 }
2449
2450 const float icu = ((cu > 0) ? -1.0f : 1.0f); // -1 if we need to reverse the face normal.
2451 faceN.normalize_fast();
2452 if (texture)
2453 _uni.facecolor = _phong<true>(icu * dotProduct(faceN, _r_light), icu * dotProduct(faceN, _r_H));
2454 else
2455 _uni.facecolor = _phong<false>(icu * dotProduct(faceN, _r_light), icu * dotProduct(faceN, _r_H));
2456 }
2457
2458
2459
2460 /***********************************************************
2461 * MEMBER VARIABLES
2462 ************************************************************/
2463
2464 // *** general parameters ***
2465
2466 int _lx, _ly; // viewport dimension
2467 float _ilx, _ily; // inverse viewport dimension
2468
2469 int _ox, _oy; // image offset w.r.t. the viewport
2470
2471 bool _ortho; // true to use orthographic projection and false for perspective projection
2472
2473 fMat4 _projM; // projection matrix
2474
2475 RasterizerParams<color_t, color_t,ZBUFFER_t> _uni; // rasterizer param (contain the image pointer and the zbuffer pointer).
2476
2477 float _culling_dir; // culling direction postive/negative or 0 to disable back face culling.
2478
2479 int _shaders; // the shaders to use.
2480 int _texture_wrap_mode; // wrapping mode (wrap_pow2 or clamp)
2481 int _texture_quality; // texturing quality (nearest or bilinear)
2482
2483 // *** scene parameters ***
2484
2485 fMat4 _viewM; // view transform matrix
2486
2487 fVec3 _light; // light direction
2488 RGBf _ambiantColor; // light ambiant color
2489 RGBf _diffuseColor; // light diffuse color
2490 RGBf _specularColor; // light specular color
2491
2492
2493 // *** model specific parameters ***
2494
2495 fMat4 _modelM; // model transform matrix
2496
2497 RGBf _color; // model color (use when texturing is disabled)
2498 float _ambiantStrength; // ambient light reflection strength
2499 float _diffuseStrength; // diffuse light reflection strength
2500 float _specularStrength; // specular light reflection strength
2501 int _specularExponent; // specular exponent
2502
2503
2504 // *** pre-computed values ***
2505 fMat4 _r_modelViewM; // model-view matrix
2506 float _r_inorm; // Fast normal scaling for lighting. Assumes rotation/uniform scale;
2507 // Gouraud lighting is approximate with non-uniform model scaling.
2508 fVec3 _r_light; // light vector in view space (inverted and normalized)
2509 fVec3 _r_light_inorm; // same as above but already multiplied by inorm
2510 fVec3 _r_H; // halfway vector.
2511 fVec3 _r_H_inorm; // same as above but already multiplied by inorm
2512 RGBf _r_ambiantColor; // ambient color multiplied by object ambient strength
2513 RGBf _r_diffuseColor; // diffuse color multiplied by object diffuse strength
2514 RGBf _r_specularColor; // specular color multiplied by object specular strength
2515 RGBf _r_objectColor; // color to use for drawing the object (either _color or mesh->color).
2516
2517
2521 struct ExtVec4 : public RasterizerVec4
2522 {
2523 fVec4 P; // after model-view matrix multiplication
2524 fVec4 N; // normal vector after model-view matrix multiplication
2525 bool missedP; // true if the attributes should be computed
2526 int indn; // index for normal vector in array
2527 int indt; // index for texture vector in array
2528 };
2529
2530
2531 };
2532
2533
2534
2535}
2536
2537
2538
2539
2540#include "Renderer3D.inl"
2541
2542
2543#endif
2544
2545#endif
2546
2547
2D box class
3D box class
Color classes [RGB565, RGB24, RGB32, RGB64, RGBf, HSV].
Main image class.
4x4 matrix class.
Mat4< float > fMat4
4x4 matrix with single (float) precision
Definition: Mat4.h:54
3D model mesh class.
Compact meshlet-based 3D model mesh format with 16-bit quantization.
Utility/miscellaneous functions used throughout the library.
TGX_INLINE T max(const T &a, const T &b)
Don't know why but much faster than fmaxf() for floats.
Definition: Misc.h:153
3D triangle rasterizer function.
#define TGX_RASTERIZE_SUBPIXEL_BITS
Sub-pixel precision bits.
Definition: Rasterizer.h:46
Shader
List of shaders available for 3D graphics.
Definition: ShaderParams.h:44
@ SHADER_NOTEXTURE
disable texture mapping
Definition: ShaderParams.h:59
@ SHADER_TEXTURE
enable texture mapping
Definition: ShaderParams.h:60
Triangle shader functions.
2D vector.
T dotProduct(const Vec2< T > U, const Vec2< T > V)
Return the dot product U.V between two vectors.
Definition: Vec2.h:560
3D vector.
Vec3< float > fVec3
Floating point valued 3D vector with single (float) precision.
Definition: Vec3.h:52
4D vector.
Vec4< float > fVec4
Floating point valued 4D vector with single (float) precision.
Definition: Vec4.h:54
Image class [MAIN CLASS FOR THE 2D API].
Definition: Image.h:145
Class for drawing 3D objects onto a Image [MAIN CLASS FOR THE 3D API].
Definition: Renderer3D.h:109
void drawAdaptativeSphere(float quality=1.0f)
Draw a unit radius sphere centered at the origin S(0,1) in model space.
void drawQuads(int nb_quads, const uint16_t *ind_vertices, const fVec3 *vertices, const uint16_t *ind_normals=nullptr, const fVec3 *normals=nullptr, const uint16_t *ind_texture=nullptr, const fVec2 *textures=nullptr, const Image< color_t > *texture_image=nullptr)
Draw a collection of quads.
void drawWireFrameLine(const fVec3 &P1, const fVec3 &P2)
Draw a wireframe line segment [fast].
void drawMesh(const Mesh3D< color_t > *mesh, bool use_mesh_material=true, bool draw_chained_meshes=true)
Draw a Mesh3D object.
void drawDot(const fVec3 &pos, int r, color_t color, float opacity)
Draw a dot/circle at a given position in model space.
void setMaterialAmbiantStrength(float strenght=0.1f)
Set how much the object material reflects the ambient light.
void drawWireFrameMesh(const Mesh3Dv2< color_t > *mesh, float thickness, color_t color, float opacity)
Draw a Mesh3Dv2 object in wireframe [adjustable thickness + AA].
void drawSphere(int nb_sectors, int nb_stacks)
Draw a unit radius sphere centered at the origin S(0,1) in model space.
void drawWireFrameAdaptativeSphere(float quality, float thickness, color_t color, float opacity)
Draw a wireframe unit radius sphere centered at the origin (in model space) [adjustable thickness + A...
void drawWireFrameCubeAA()
Draw the wireframe cube [0,1]^3 [antialiased] with the current material color.
void setMaterialSpecularExponent(int exponent=16)
Set the object specular exponent.
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.
void drawWireFrameTriangle(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3)
Draw a wireframe triangle [fast].
void drawWireFrameCube()
Draw the wireframe cube [0,1]^3 (in model space) [fast].
void drawWireFrameMeshAA(const Mesh3D< color_t > *mesh, bool draw_chained_meshes=true)
Draw a mesh in wireframe [antialiased] with the current material color.
void setMaterialSpecularStrength(float strenght=0.5f)
Set how much the object material reflects the specular light.
void setMaterialDiffuseStrength(float strenght=0.6f)
Set how much the object material reflects the diffuse light.
void drawWireFrameQuad(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, const fVec3 &P4)
Draw a wireframe quad [fast].
void setShaders(Shader shaders)
Set the shaders to use for subsequent drawing operations.
iVec2 modelToImage(fVec3 P)
Convert from model coordinates to the corresponding image pixel.
void setModelPosScaleRot(const fVec3 &center=fVec3{ 0, 0, 0 }, const fVec3 &scale=fVec3(1, 1, 1), float rot_angle=0, const fVec3 &rot_dir=fVec3{ 0, 1, 0 })
Set the model transformation matrix to move an object to a given location, scale and rotation.
void drawCube(const Image< color_t > *texture_front, const Image< color_t > *texture_back, const Image< color_t > *texture_top, const Image< color_t > *texture_bottom, const Image< color_t > *texture_left, const Image< color_t > *texture_right)
draw a textured unit cube [-1,1]^3 (in model space)
void drawDots(int nb_dots, const fVec3 *pos_list, const int *radius_ind, const int *radius, const int *colors_ind, const color_t *colors, const int *opacities_ind, const float *opacities)
Draw a list of dots/circles at given positions in model space.
fMat4 getViewMatrix() const
Return the current view matrix.
void setLookAt(const fVec3 eye, const fVec3 center, const fVec3 up)
Set the view matrix so that the camera is looking at a given direction.
void drawWireFrameMesh(const Mesh3D< color_t > *mesh, bool draw_chained_meshes, float thickness, color_t color, float opacity)
Draw a mesh in wireframe [adjustable thickness + AA].
void drawWireFrameQuads(int nb_quads, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw a collection of wireframe quads [fast].
void setLightAmbiant(const RGBf &color)
Set the scene ambiant light color.
void drawWireFrameAdaptativeSphere(float quality=1.0f)
Draw a wireframe unit radius sphere centered at the origin (in model space) [fast].
void drawCube()
Draw the unit cube [-1,1]^3 in model space.
void drawWireFrameSphere(int nb_sectors, int nb_stacks, float thickness, color_t color, float opacity)
Draw a wireframe unit radius sphere centered at the origin (in model space) [adjustable thickness + A...
fMat4 getProjectionMatrix() const
Return the current projection matrix.
void drawWireFrameLines(int nb_lines, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw a collection of wireframe line segments [fast].
void setZbuffer(ZBUFFER_t *zbuffer)
Set the z-buffer.
void drawWireFrameMesh(const Mesh3Dv2< color_t > *mesh)
Draw a Mesh3Dv2 object in wireframe [fast].
void setMaterialColor(RGBf color)
Set the object material color.
void setLightDirection(const fVec3 &direction)
Set the light source direction.
void drawMesh(const Mesh3Dv2< color_t > *mesh, bool use_mesh_material=true)
Draw a Mesh3Dv2 object.
void setLight(const fVec3 direction, const RGBf &ambiantColor, const RGBf &diffuseColor, const RGBf &specularColor)
Set all the lighting parameters of the scene at once.
void setMaterial(RGBf color, float ambiantStrength, float diffuseStrength, float specularStrength, int specularExponent)
Set all the object material properties at once.
void setTextureWrappingMode(Shader wrap_mode)
Set the wrap mode when for texturing.
void drawDots(int nb_dots, const fVec3 *pos_list, const int radius)
Draw a list of dots/circles at given positions in model space.
fVec4 worldToNDC(fVec3 P)
Convert from world coordinates to normalized device coordinates (NDC).
void setViewMatrix(const fMat4 &M)
Set the view transformation matrix.
void setViewportSize(const iVec2 &viewport_dim)
Set the size of the viewport.
TGX_NOINLINE Renderer3D(const iVec2 &viewportSize={0, 0}, Image< color_t > *im=nullptr, ZBUFFER_t *zbuffer=nullptr)
Constructor.
void setViewportSize(int lx, int ly)
Set the size of the viewport.
iVec2 worldToImage(fVec3 P)
Convert from world coordinates to the corresponding image pixel.
void setCulling(int w)
Set the face culling strategy.
void drawWireFrameSphereAA(int nb_sectors, int nb_stacks)
Draw a wireframe unit radius sphere [antialiased] with the current material color.
void drawTriangleWithVertexColor(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, const RGBf &col1, const RGBf &col2, const RGBf &col3, const fVec3 *N1=nullptr, const fVec3 *N2=nullptr, const fVec3 *N3=nullptr)
Draw a single triangle with a given colors on each of its vertices.
void usePerspectiveProjection()
Set projection mode to perspective (ie with z-divide).
void setModelMatrix(const fMat4 &M)
Set the model transformation matrix.
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].
void setPerspective(float fovy, float aspect, float zNear, float zFar)
Set the projection matrix as a perspective matrix.
void drawWireFrameQuads(int nb_quads, const uint16_t *ind_vertices, const fVec3 *vertices, float thickness, color_t color, float opacity)
Draw a collection of wireframe quads [adjustable thickness + AA].
void drawPixel(const fVec3 &pos)
Draw a single pixel at a given position in model space.
void setOrtho(float left, float right, float bottom, float top, float zNear, float zFar)
Set the projection matrix as an orthographic matrix.
fMat4 getModelMatrix() const
Return the model transformation matrix.
void drawWireFrameLines(int nb_lines, const uint16_t *ind_vertices, const fVec3 *vertices, float thickness, color_t color, float opacity)
Draw a collection of wireframe line segments [adjustable thickness + AA].
void setImage(Image< color_t > *im)
Set the image that will be drawn onto.
void drawWireFrameTriangleStrip(int nb_indices, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw a triangle strip in wireframe [fast].
void drawPixels(int nb_pixels, const fVec3 *pos_list)
Draw a list of pixels at given positions in model space.
void drawPixel(const fVec3 &pos, color_t color, float opacity)
Draw a single pixel at a given position in model space.
void drawWireFrameLinesAA(int nb_lines, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw wireframe line segments [antialiased] with the current material color.
void drawWireFrameLineAA(const fVec3 &P1, const fVec3 &P2)
Draw a wireframe line segment [antialiased] with the current material color.
void setLightDiffuse(const RGBf &color)
Set the scene diffuse light color.
void setLightSpecular(const RGBf &color)
Set the scene specular light color.
void setOffset(const iVec2 &offset)
Set the offset of the image relative to the viewport.
void 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.
void drawCube(const fVec2 v_front_ABCD[4], const Image< color_t > *texture_front, const fVec2 v_back_EFGH[4], const Image< color_t > *texture_back, const fVec2 v_top_HADE[4], const Image< color_t > *texture_top, const fVec2 v_bottom_BGFC[4], const Image< color_t > *texture_bottom, const fVec2 v_left_HGBA[4], const Image< color_t > *texture_left, const fVec2 v_right_DCFE[4], const Image< color_t > *texture_right)
Draw a textured unit cube [-1,1]^3 in model space.
void drawWireFrameQuadsAA(int nb_quads, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw wireframe quads [antialiased] with the current material color.
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].
void setLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
Set the view matrix so that the camera is looking at a given direction.
void drawWireFrameMeshAA(const Mesh3Dv2< color_t > *mesh)
Draw a Mesh3Dv2 object in wireframe [antialiased] with the current material color.
void drawWireFrameQuadAA(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, const fVec3 &P4)
Draw a wireframe quad [antialiased] with the current material color.
void useOrthographicProjection()
Set projection mode to orthographic (ie no z-divide).
void drawTriangle(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, const fVec3 *N1=nullptr, const fVec3 *N2=nullptr, const fVec3 *N3=nullptr, const fVec2 *T1=nullptr, const fVec2 *T2=nullptr, const fVec2 *T3=nullptr, const Image< color_t > *texture=nullptr)
Draw a single triangle.
void drawWireFrameTrianglesAA(int nb_triangles, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw wireframe triangles [antialiased] with the current material color.
void drawTriangles(int nb_triangles, const uint16_t *ind_vertices, const fVec3 *vertices, const uint16_t *ind_normals=nullptr, const fVec3 *normals=nullptr, const uint16_t *ind_texture=nullptr, const fVec2 *textures=nullptr, const Image< color_t > *texture_image=nullptr)
Draw a collection of triangles.
void clearZbuffer()
Clear the Zbuffer.
void drawWireFrameLine(const fVec3 &P1, const fVec3 &P2, float thickness, color_t color, float opacity)
Draw a wireframe line segment [adjustable thickness + AA].
void drawQuadWithVertexColor(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, const fVec3 &P4, const RGBf &col1, const RGBf &col2, const RGBf &col3, const RGBf &col4, const fVec3 *N1=nullptr, const fVec3 *N2=nullptr, const fVec3 *N3=nullptr, const fVec3 *N4=nullptr)
Draw a single quad with a given colors on each of its four vertices.
void drawWireFrameMesh(const Mesh3D< color_t > *mesh, bool draw_chained_meshes=true)
Draw a mesh in wireframe [fast].
fVec4 modelToNDC(fVec3 P)
Convert from model coordinates to normalized device coordinates (NDC).
void drawWireFrameTriangles(int nb_triangles, const uint16_t *ind_vertices, const fVec3 *vertices, float thickness, color_t color, float opacity)
Draw a collection of wireframe triangles [adjustable thickness + AA].
void drawSphere(int nb_sectors, int nb_stacks, const Image< color_t > *texture)
Draw a textured unit radius sphere centered at the origin S(0,1) in model space.
void drawDot(const fVec3 &pos, int r)
Draw a dot/circle at a given position in model space.
void setFrustum(float left, float right, float bottom, float top, float zNear, float zFar)
Set the projection matrix as a perspective matrix.
void setProjectionMatrix(const fMat4 &M)
Set the projection matrix.
void setTextureQuality(Shader quality)
Set the texturing quality.
void drawPixels(int nb_pixels, const fVec3 *pos_list, const int *colors_ind, const color_t *colors, const int *opacities_ind, const float *opacities)
Draw a list of pixels at given positions in model space with different colors and opacities.
void drawWireFrameTriangleAA(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3)
Draw a wireframe triangle [antialiased] with the current material color.
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].
void drawAdaptativeSphere(const Image< color_t > *texture, float quality=1.0f)
Draw a textured unit radius sphere centered at the origin S(0,1) in model space.
void drawWireFrameSphere(int nb_sectors, int nb_stacks)
Draw a wireframe unit radius sphere centered at the origin (in model space) [fast].
void drawWireFrameTriangles(int nb_triangles, const uint16_t *ind_vertices, const fVec3 *vertices)
Draw a collection of wireframe triangles [fast].
void drawQuad(const fVec3 &P1, const fVec3 &P2, const fVec3 &P3, const fVec3 &P4, const fVec3 *N1=nullptr, const fVec3 *N2=nullptr, const fVec3 *N3=nullptr, const fVec3 *N4=nullptr, const fVec2 *T1=nullptr, const fVec2 *T2=nullptr, const fVec2 *T3=nullptr, const fVec2 *T4=nullptr, const Image< color_t > *texture=nullptr)
Draw a single quad.
void setOffset(int ox, int oy)
Set the offset of the image relative to the viewport.
void drawWireFrameCube(float thickness, color_t color, float opacity)
Draw the wireframe cube [0,1]^3 (in model space) [adjustable thickness + AA].
void drawWireFrameAdaptativeSphereAA(float quality=1.0f)
Draw an adaptive wireframe sphere [antialiased] with the current material color.
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_INLINE Vec4< T > mult0(const Vec3< T > &V) const
Matrix-vector multiplication (last component of vector set to w = 0).
Definition: Mat4.h:557
3D mesh data structure.
Definition: Mesh3D.h:157
Compact meshlet-based 3D mesh data structure.
Definition: Mesh3Dv2.h:239
Color in R,G,B float format.
Definition: Color.h:2407
void clamp()
Clamp all color channel to [0.0f,1.0f].
Definition: Color.h:2647
Generic 2D vector [specializations iVec2, fVec2, dVec2].
Definition: Vec2.h:64
T x
'x' coordinate (first dimension)
Definition: Vec2.h:72
T y
'y' coordinate (second dimension)
Definition: Vec2.h:73
T z
'z' coordinate (third dimension)
Definition: Vec3.h:83
T w
'w' coordinate (fourth dimension)
Definition: Vec4.h:85
void zdivide()
Performs the 'z-divide' operation.
Definition: Vec4.h:478