3939#include " nel/3d/material.h"
4040#include " nel/misc/mutex.h"
4141#include " nel/3d/primitive_profile.h"
42+ #include " nel/3d/uniform_buffer.h"
4243
4344#include < vector>
4445#include < list>
@@ -163,9 +164,21 @@ class IDriver : public NLMISC::CRefCount
163164
164165 enum TProgram
165166 {
166- VertexProgram = 0 ,
167- PixelProgram = 1 ,
168- GeometryProgram = 2
167+ ShaderProgram = 0 , // Monolithic shader program, must contain a matching VP/PP pair at minimum.
168+ // Monolithic shaders only support UBOs, not individual uniforms. The driver light
169+ // list is split between per-vertex lights (VP) and per-pixel lights (PP). With
170+ // individual uniforms on separate shader objects, each stage has its own namespace,
171+ // so the VP and PP declare their light slots independently with separate numbering
172+ // (light0..N in VP, ppLight0..N in PP). UBOs make this unnecessary — both stages
173+ // just share the full light table and a split index. This is simpler in general
174+ // and essential for monolithic programs sharing one namespace, as well as for
175+ // modern APIs (Vulkan, Metal, D3D12) which don't have individual uniforms.
176+
177+ VertexProgram = 1 ,
178+ PixelProgram = 2 ,
179+ // GeometryProgram = 3,
180+
181+ ProgramNb
169182 };
170183
171184protected:
@@ -175,6 +188,7 @@ class IDriver : public NLMISC::CRefCount
175188 TVBDrvInfoPtrList _VBDrvInfos;
176189 TIBDrvInfoPtrList _IBDrvInfos;
177190 TGPUPrgDrvInfoPtrList _GPUPrgDrvInfos;
191+ TUBDrvInfoPtrList _UBDrvInfos;
178192
179193 TPolygonMode _PolygonMode;
180194
@@ -253,6 +267,9 @@ class IDriver : public NLMISC::CRefCount
253267 // Must be a HWND for Windows (WIN32).
254268 virtual nlWindow getDisplay () = 0;
255269
270+ // / Return true if the driver supports monitor color properties (gamma, contrast, luminosity)
271+ virtual bool supportMonitorColorProperties () const = 0;
272+
256273 // / Setup monitor color properties. Return false if setup failed
257274 virtual bool setMonitorColorProperties (const CMonitorColorProperties &properties) = 0;
258275
@@ -299,7 +316,7 @@ class IDriver : public NLMISC::CRefCount
299316 virtual bool clearZBuffer (float zval=1 ) = 0;
300317
301318 // / Clear the current target surface stencil buffer. The function ignores the viewport settings but uses the scissor.
302- virtual bool clearStencilBuffer (float stencilval=0 ) = 0;
319+ virtual bool clearStencilBuffer (sint stencilval=0 ) = 0;
303320
304321 // / Set the color mask filter through where the operation done will pass
305322 virtual void setColorMask (bool bRed, bool bGreen, bool bBlue, bool bAlpha) = 0;
@@ -488,8 +505,17 @@ class IDriver : public NLMISC::CRefCount
488505 virtual void endMaterialMultiPass () = 0;
489506 // @}
490507
491- // Does the driver support the per-pixel lighting shader ?
508+ // Does the driver support the per-pixel lighting shader ? (legacy fixed-function technique)
492509 virtual bool supportPerPixelLighting (bool specular) const = 0;
510+
511+ // / Does the driver's builtin VP/PP support per-pixel lighting features?
512+ // / When true, user shader programs may use the following CProgramFeatures:
513+ // / - InputsWorldSpaceNormal: Request world-space normal at varying location 2.
514+ // / - InputsWorldSpacePosition: Request PZB-relative world-space position at varying location 0.
515+ // / - OutputsWorldSpacePosition: Indicate that a user VP outputs world-space position at location 0.
516+ // / These enable GLSL per-pixel lighting in user PPs (light direction, attenuation, etc.).
517+ // / The builtin PP adapts fog to use world-space distance when position is in world space.
518+ virtual bool supportWorldSpacePPL () const = 0;
493519 // @}
494520
495521
@@ -581,7 +607,7 @@ class IDriver : public NLMISC::CRefCount
581607 bool getStaticMemoryToVRAM () const { return _StaticMemoryToVRAM; }
582608
583609 /* Set to true if static vertex and index buffers must by allocated in VRAM, false in AGP.
584- * Default is false .
610+ * Default is true .
585611 */
586612 void setStaticMemoryToVRAM (bool staticMemoryToVRAM);
587613
@@ -817,14 +843,20 @@ class IDriver : public NLMISC::CRefCount
817843
818844 // / \name Fog support.
819845 // @{
846+ enum TFogMode { FogLinear = 0 , FogExp, FogExp2 };
847+
820848 virtual bool fogEnabled () = 0;
821849 virtual void enableFog (bool enable = true ) = 0;
822850 // / setup fog parameters. fog must enabled to see result. start and end are distance values.
823851 virtual void setupFog (float start, float end, NLMISC::CRGBA color) = 0;
852+ // / setup fog mode and density. mode/density are orthogonal to start/end/color.
853+ virtual void setupFogMode (TFogMode mode = FogLinear, float density = 1 .f) = 0;
824854 // / Get.
825855 virtual float getFogStart () const = 0;
826856 virtual float getFogEnd () const = 0;
827857 virtual NLMISC::CRGBA getFogColor () const = 0;
858+ virtual TFogMode getFogMode () const = 0;
859+ virtual float getFogDensity () const = 0;
828860 // @}
829861
830862
@@ -1080,6 +1112,58 @@ class IDriver : public NLMISC::CRefCount
10801112 // @}
10811113
10821114
1115+ /* * \name Light Table
1116+ *
1117+ * The light table is a resizable array of CLight entries in the driver,
1118+ * populated once per frame. Each unique scene light (sun, point lights)
1119+ * is uploaded once via setLightTableEntry(). Per-object rendering then
1120+ * references lights by table index + influence factor through setLights(),
1121+ * rather than uploading fully modulated CLight data per draw call.
1122+ *
1123+ * Two modes:
1124+ * - **Table mode** (scene rendering): enableLightTableMode(true). Lights
1125+ * are set up via setLightTableEntry() and selected per object via
1126+ * setLights(). The legacy setLight()/enableLight() calls are not used.
1127+ * - **Legacy mode** (samples, UI, debug): enableLightTableMode(false).
1128+ * setLight()/enableLight() work as before.
1129+ *
1130+ * setLights() applies per-object factor modulation internally: each
1131+ * factor (0-255) scales the table entry's diffuse and specular colors.
1132+ * The ambient parameter replaces the ambient of slot 0 (sun); point
1133+ * light slots receive black ambient.
1134+ */
1135+ // @{
1136+
1137+ // / Return the maximum number of entries the light table can hold.
1138+ // / Drivers without a fixed limit (legacy, no UBO) return UINT_MAX.
1139+ virtual uint getMaxLightTableSize () const { return (uint)~0 ; }
1140+
1141+ // / Enable or disable light table mode. When disabled, legacy setLight()/enableLight() resumes.
1142+ virtual void enableLightTableMode (bool enable) = 0;
1143+
1144+ // / Resize the light table. Existing entries beyond the new size are discarded.
1145+ virtual void setLightTableSize (uint count) = 0;
1146+
1147+ // / Set a light table entry. The light is stored as-is (no factor modulation).
1148+ virtual void setLightTableEntry (uint index, const CLight &light) = 0;
1149+
1150+ /* * Set the active lights for the current object from the light table.
1151+ * \param tableIndices Array of indices into the light table. Slot 0 is the sun.
1152+ * \param factors Parallel array of influence factors (0-255) per light.
1153+ * \param numLights Number of entries in tableIndices/factors.
1154+ * \param numPerPixelLights First N lights evaluated per-pixel in PP (0 = all VP).
1155+ * \param ambient Per-object ambient color, written to slot 0's ambient.
1156+ */
1157+ virtual void setLights (
1158+ const sint16 *tableIndices,
1159+ const uint8 *factors,
1160+ uint numLights,
1161+ uint numPerPixelLights,
1162+ NLMISC::CRGBA ambient) = 0;
1163+
1164+ // @}
1165+
1166+
10831167
10841168 // / \name Vertex Program
10851169 // @{
@@ -1094,6 +1178,12 @@ class IDriver : public NLMISC::CRefCount
10941178 */
10951179 virtual bool isVertexProgramEmulated () const = 0;
10961180
1181+ /* * Return true if the driver supports builtin UBOs for vertex programs
1182+ * (NlCamera, NlLightTable, NlModel). When true, user VPs can use
1183+ * UsesObjectUBO/UsesLightTableUBO/UsesCameraUBO feature flags.
1184+ */
1185+ virtual bool supportBuiltinUBO () const { return false ; }
1186+
10971187 /* * Return true if the driver supports the specified vertex program profile.
10981188 */
10991189 virtual bool supportVertexProgram (CVertexProgram::TProfile profile) const = 0;
@@ -1217,6 +1307,10 @@ class IDriver : public NLMISC::CRefCount
12171307 virtual void setUniformFog (TProgram program, uint index) = 0;
12181308 // Set feature parameters
12191309 virtual bool isUniformProgramState () = 0;
1310+
1311+ // / Bind a user uniform buffer to a binding point. Creates GPU buffer on first use,
1312+ // / uploads if dirty. Pass NULL to unbind.
1313+ virtual bool bindUniformBuffer (TUBBinding binding, CUniformBuffer *ub) { return false ; }
12201314 // @}
12211315
12221316
@@ -1253,6 +1347,9 @@ class IDriver : public NLMISC::CRefCount
12531347 virtual bool supportTextureShaders () const = 0;
12541348 // Is the shader water supported ? If not, the driver caller should implement its own version
12551349 virtual bool supportWaterShader () const = 0;
1350+ // / Does the cubemap face convention use +Z as forward? (D3D: true, GL: false)
1351+ // / GL cubemaps map forward (-Z) to NEGATIVE_Z face, D3D maps forward (+Z) to POSITIVE_Z face.
1352+ virtual bool cubemapZPositiveForward () const = 0;
12561353 //
12571354 // / test whether a texture addressing mode is supported
12581355 virtual bool supportTextureAddrMode (CMaterial::TTexAddressingMode mode) const = 0;
@@ -1439,6 +1536,7 @@ class IDriver : public NLMISC::CRefCount
14391536 friend class IMaterialDrvInfos ;
14401537 friend class IProgramDrvInfos ;
14411538 friend class IProgramParamsDrvInfos ;
1539+ friend class IUBDrvInfos ;
14421540
14431541 // / remove ptr from the lists in the driver.
14441542 void removeVBDrvInfoPtr (ItVBDrvInfoPtrList vbDrvInfoIt);
@@ -1447,6 +1545,7 @@ class IDriver : public NLMISC::CRefCount
14471545 void removeTextureDrvSharePtr (ItTexDrvSharePtrList texDrvShareIt);
14481546 void removeMatDrvInfoPtr (ItMatDrvInfoPtrList shaderIt);
14491547 void removeGPUPrgDrvInfoPtr (ItGPUPrgDrvInfoPtrList gpuPrgDrvInfoIt);
1548+ void removeUBDrvInfoPtr (ItUBDrvInfoPtrList ubDrvInfoIt);
14501549
14511550private:
14521551 bool _StaticMemoryToVRAM;
0 commit comments