21#ifndef _TGX_RENDERER3D_H_
22#define _TGX_RENDERER3D_H_
51 extern const uint16_t UNIT_CUBE_FACES[6*4];
52 extern const uint16_t UNIT_CUBE_FACES_NORMALS[6 * 4];
107 template<
typename color_t, Shader LOADED_SHADERS = TGX_SHADER_MASK_ALL,
typename ZBUFFER_t =
float>
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");
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)));
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");
299 void setOrtho(
float left,
float right,
float bottom,
float top,
float zNear,
float zFar);
318 void setFrustum(
float left,
float right,
float bottom,
float top,
float zNear,
float zFar);
503 void setLookAt(
float eyeX,
float eyeY,
float eyeZ,
float centerX,
float centerY,
float centerZ,
float upX,
float upY,
float upZ);
776 void setMaterial(
RGBf color,
float ambiantStrength,
float diffuseStrength,
float specularStrength,
int specularExponent);
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,
872 const RGBf & col1,
const RGBf & col2,
const RGBf & col3,
873 const fVec3 * N1 =
nullptr,
const fVec3 * N2 =
nullptr,
const fVec3 * N3 =
nullptr);
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,
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,
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,
970 const fVec3 * N1 =
nullptr,
const fVec3 * N2 =
nullptr,
const fVec3 * N3 =
nullptr,
const fVec3 * N4 =
nullptr);
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,
1389 void drawWireFrameLines(
int nb_lines,
const uint16_t* ind_vertices,
const fVec3* vertices,
float thickness, color_t color,
float opacity);
1627 void drawWireFrameQuads(
int nb_quads,
const uint16_t* ind_vertices,
const fVec3* vertices,
float thickness, color_t color,
float opacity);
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);
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);
1945 TGX_INLINE
float _clipbound_xy()
const
1947 return (256 + 3*((MAXVIEWPORTDIMENSION * 256) / ((_lx > _ly) ? _lx : _ly))) / 1024.0f;
1953 TGX_INLINE
bool _validDraw()
const
1955 return ((_lx > 0) && (_ly > 0) && (_uni.im !=
nullptr) && (_uni.im->isValid()));
1960 TGX_NOINLINE
void _recompute_wa_wb();
1967 TGX_NOINLINE
void _rectifyShaderOrtho();
1970 TGX_NOINLINE
void _rectifyShaderZbuffer();
1973 TGX_NOINLINE
void _rectifyShaderShading(Shader new_shaders);
1976 TGX_NOINLINE
void _rectifyShaderTextureWrapping();
1979 TGX_NOINLINE
void _rectifyShaderTextureQuality();
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);
1996 void _drawTriangleClippedSub(
const int RASTER_TYPE,
const int plane,
1997 const RasterizerVec4& P1,
const RasterizerVec4& P2,
const RasterizerVec4& P3);
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);
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);
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);
2024 void _drawMesh(
const int RASTER_TYPE,
const Mesh3D<color_t>* mesh);
2027 void _drawMesh(
const int RASTER_TYPE,
const Mesh3Dv2<color_t>* mesh,
bool use_mesh_material);
2030 TGX_INLINE
inline bool _discardMeshlet16b(
const fVec3& sphere_center,
float sphere_radius,
const fVec3& cone_dir,
float cone_cos)
const
2032 if (cone_cos <= -1.0f)
return false;
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;
2047 const fVec3 anchor = sphere_center - (cone_dir * sphere_radius);
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;
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));
2067 inline void _drawWireFrameLineFast(iVec2 P0, iVec2 P1, color_t color);
2069 template<
bool CHECK_NEIGHBOR>
inline void _drawWireFrameLineAAFast(
const fVec2& P0,
const fVec2& P1, color_t color, int32_t op);
2071 template<
int MODE>
void _drawWireFrameMesh(
const Mesh3D<color_t>* mesh,
bool draw_chained_meshes, color_t color,
float opacity,
float thickness);
2073 template<
int MODE>
void _drawWireFrameMesh(
const Mesh3Dv2<color_t>* mesh, color_t color,
float opacity,
float thickness);
2075 template<
int MODE>
void _drawWireFrameLine(
const fVec3& P1,
const fVec3& P2, color_t color,
float opacity,
float thickness);
2077 template<
int MODE>
void _drawWireFrameLines(
int nb_lines,
const uint16_t* ind_vertices,
const fVec3* vertices, color_t color,
float opacity,
float thickness);
2079 template<
int MODE>
void _drawWireFrameTriangle(
const fVec3& P1,
const fVec3& P2,
const fVec3& P3, color_t color,
float opacity,
float thickness);
2081 template<
int MODE>
void _drawWireFrameTriangles(
int nb_triangles,
const uint16_t* ind_vertices,
const fVec3* vertices, color_t color,
float opacity,
float thickness);
2083 template<
int MODE>
void _drawWireFrameTriangleStrip(
int nb_indices,
const uint16_t* ind_vertices,
const fVec3* vertices, color_t color,
float opacity,
float thickness);
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);
2087 template<
int MODE>
void _drawWireFrameQuads(
int nb_quads,
const uint16_t* ind_vertices,
const fVec3* vertices, color_t color,
float opacity,
float thickness);
2097 template<
bool USE_BLENDING>
void _drawPixel(
const fVec3& pos, color_t color,
float opacity);
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);
2103 template<
bool USE_BLENDING>
void _drawDot(
const fVec3& pos,
int r, color_t color,
float opacity);
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);
2110 template<
bool CHECKRANGE,
bool USE_BLENDING> TGX_INLINE
inline void drawPixelZbuf(
int x,
int y, color_t color,
float opacity,
float z)
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);
2118 if (USE_BLENDING) _uni.im->template drawPixel<false>({ x, y }, color, opacity);
else _uni.im->template drawPixel<false>({ x, y }, color);
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)
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; }
2134 while(w--) drawPixelZbuf<CHECKRANGE, USE_BLENDING>(x++, y, color, opacity, z);
2138 template<
bool CHECKRANGE,
bool USE_BLENDING>
void _drawCircleZbuf(
int xm,
int ym,
int r, color_t color,
float opacity,
float z);
2144 float _unitSphereScreenDiameter();
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);
2157 TGX_INLINE
inline void _clip(
int & fl,
const fVec4 & P,
float bx,
float Bx,
float by,
float By)
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)); }
2169 TGX_INLINE
inline void _clip(
int & fl,
const fVec3 & P,
float bx,
float Bx,
float by,
float By,
const fMat4 & M)
2171 fVec4 S = M.mult1(P);
2173 return _clip(fl, S, bx, Bx, by, By);
2179 bool _discardBox(
const fBox3 & bb,
const fMat4 & M)
2181 if ((bb.minX == 0) && (bb.maxX == 0) && (bb.minY == 0) && (bb.maxY == 0) && (bb.minZ == 0) && (bb.maxZ == 0))
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;
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;
2212 bool _discardTriangle(
const fVec4 & P1,
const fVec4 & P2,
const fVec4 & P3)
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;
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;
2231 bool _clip2(
float clipboundXY,
const fVec3 & P,
const fMat4 & M)
2233 fVec4 S = M.mult1(P);
2237 if (S.w <= 0) S.z = -2;
2239 return ((S.x <= -clipboundXY) || (S.x >= clipboundXY)
2240 || (S.y <= -clipboundXY) || (S.y >= clipboundXY)
2241 || (S.z <= -1) || (S.z >= 1));
2246 bool _clipTestNeeded(
float clipboundXY,
const fBox3 & bb,
const fMat4 & M)
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));
2260 bool _wireFrameAANeighborCheckNeeded(
const fBox3& bb,
const fMat4& proj_modelview)
2262 if ((_uni.im ==
nullptr) || (_uni.im->lx() <= 2) || (_uni.im->ly() <= 2))
return true;
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;
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)
2280 for (
int i = 0; i < 8; i++)
2282 fVec4 P = proj_modelview.mult1(C[i]);
2285 if (P.w <= 0)
return true;
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;
2295#if TGX_MESHLET_SPHERE_CLIP
2297 TGX_INLINE
inline void _meshletClipPlanes(
float clipboundXY,
const fMat4& M, fVec4* planes,
float* plane_norms)
const
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++)
2308 const fVec4& P = planes[i];
2309 plane_norms[i] = sqrtf(P.x * P.x + P.y * P.y + P.z * P.z);
2315 TGX_INLINE
inline int _meshletSphereClip(
const fVec3& center,
float radius,
const fVec4* planes,
const float* plane_norms)
const
2317 bool intersects =
false;
2318 for (
int i = 0; i < 6; i++)
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;
2326 return intersects ? 1 : 0;
2347 return (CP.
x * P.
x) + (CP.
y * P.
y) + (CP.
z * P.
z) + (CP.
w * P.
w) + off;
2360 inline float _cpfactor(
const tgx::fVec4& CP,
const float sdistA,
const float sdistB)
2362 return sdistA / (sdistA - sdistB);
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);
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);
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);
2390 static const int _POWTABSIZE = 32;
2393 float _fastpowtab[_POWTABSIZE];
2396 TGX_INLINE
inline void _precomputeSpecularTable(
int exponent)
2398 if (_currentpow == exponent)
return;
2399 _precomputeSpecularTable2(exponent);
2402 TGX_NOINLINE
void _precomputeSpecularTable2(
int exponent);
2406 TGX_INLINE
inline float _powSpecular(
float x)
const
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]));;
2415 template<
bool TEXTURE> TGX_INLINE
inline RGBf _phong(
float v_diffuse,
float v_specular)
const
2417 RGBf col = _r_ambiantColor;
2418 col += _r_diffuseColor *
max(v_diffuse, 0.0f);
2419 col += _r_specularColor * _powSpecular(v_specular);
2420 if (!(TEXTURE)) col *= _r_objectColor;
2427 TGX_INLINE
inline RGBf _phong(
float v_diffuse,
float v_specular, RGBf color)
const
2429 RGBf col = _r_ambiantColor;
2430 col += _r_diffuseColor *
max(v_diffuse, 0.0f);
2431 col += _r_specularColor * _powSpecular(v_specular);
2439 TGX_INLINE
inline void _setFlatOrUnlitFaceColor(
int raster_type,
bool texture, fVec3& faceN,
float cu)
2441 if constexpr (TGX_SHADER_HAS_UNLIT(ENABLED_SHADERS))
2443 if (TGX_SHADER_HAS_UNLIT(raster_type))
2445 _uni.facecolor = texture ? RGBf(1.0f, 1.0f, 1.0f) : _r_objectColor;
2450 const float icu = ((cu > 0) ? -1.0f : 1.0f);
2451 faceN.normalize_fast();
2453 _uni.facecolor = _phong<true>(icu *
dotProduct(faceN, _r_light), icu *
dotProduct(faceN, _r_H));
2455 _uni.facecolor = _phong<false>(icu *
dotProduct(faceN, _r_light), icu *
dotProduct(faceN, _r_H));
2475 RasterizerParams<color_t, color_t,ZBUFFER_t> _uni;
2480 int _texture_wrap_mode;
2481 int _texture_quality;
2490 RGBf _specularColor;
2498 float _ambiantStrength;
2499 float _diffuseStrength;
2500 float _specularStrength;
2501 int _specularExponent;
2505 fMat4 _r_modelViewM;
2509 fVec3 _r_light_inorm;
2512 RGBf _r_ambiantColor;
2513 RGBf _r_diffuseColor;
2514 RGBf _r_specularColor;
2515 RGBf _r_objectColor;
2521 struct ExtVec4 :
public RasterizerVec4
2540#include "Renderer3D.inl"
Color classes [RGB565, RGB24, RGB32, RGB64, RGBf, HSV].
Mat4< float > fMat4
4x4 matrix with single (float) precision
Definition: Mat4.h:54
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.
T dotProduct(const Vec2< T > U, const Vec2< T > V)
Return the dot product U.V between two vectors.
Definition: Vec2.h:560
Vec3< float > fVec3
Floating point valued 3D vector with single (float) precision.
Definition: Vec3.h:52
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 ¢er=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