18
18
#include " fmt/format.h"
19
19
20
20
#include " System/Misc/TracyDefs.h"
21
+ #include " Rendering/GL/FBO.h"
22
+ #include " Rendering/GlobalRendering.h"
21
23
22
24
23
25
/* *****************************************************************************
28
30
LuaFBOs::~LuaFBOs ()
29
31
{
30
32
RECOIL_DETAILED_TRACY_ZONE;
31
- for (const FBO * fbo: fbos) {
33
+ for (const auto * fbo: fbos) {
32
34
glDeleteFramebuffersEXT (1 , &fbo->id );
33
35
}
34
36
}
@@ -48,6 +50,9 @@ bool LuaFBOs::PushEntries(lua_State* L)
48
50
REGISTER_LUA_CFUNC (ActiveFBO);
49
51
REGISTER_LUA_CFUNC (RawBindFBO);
50
52
53
+ if (GLAD_GL_VERSION_3_0)
54
+ REGISTER_LUA_CFUNC (ClearAttachmentFBO);
55
+
51
56
if (GLAD_GL_EXT_framebuffer_blit)
52
57
REGISTER_LUA_CFUNC (BlitFBO);
53
58
@@ -128,17 +133,17 @@ static GLenum ParseAttachment(const std::string& name)
128
133
/* *****************************************************************************/
129
134
/* *****************************************************************************/
130
135
131
- const LuaFBOs::FBO * LuaFBOs::GetLuaFBO (lua_State* L, int index)
136
+ const LuaFBOs::LuaFBO * LuaFBOs::GetLuaFBO (lua_State* L, int index)
132
137
{
133
138
RECOIL_DETAILED_TRACY_ZONE;
134
- return static_cast <FBO *>(LuaUtils::GetUserData (L, index, " FBO" ));
139
+ return static_cast <LuaFBO *>(LuaUtils::GetUserData (L, index, " FBO" ));
135
140
}
136
141
137
142
138
143
/* *****************************************************************************/
139
144
/* *****************************************************************************/
140
145
141
- void LuaFBOs::FBO ::Init (lua_State* L)
146
+ void LuaFBOs::LuaFBO ::Init (lua_State* L)
142
147
{
143
148
RECOIL_DETAILED_TRACY_ZONE;
144
149
index = -1u ;
@@ -151,7 +156,7 @@ void LuaFBOs::FBO::Init(lua_State* L)
151
156
}
152
157
153
158
154
- void LuaFBOs::FBO ::Free (lua_State* L)
159
+ void LuaFBOs::LuaFBO ::Free (lua_State* L)
155
160
{
156
161
RECOIL_DETAILED_TRACY_ZONE;
157
162
if (luaRef == LUA_NOREF)
@@ -184,7 +189,7 @@ void LuaFBOs::FBO::Free(lua_State* L)
184
189
int LuaFBOs::meta_gc (lua_State* L)
185
190
{
186
191
RECOIL_DETAILED_TRACY_ZONE;
187
- FBO * fbo = static_cast <FBO *>(luaL_checkudata (L, 1 , " FBO" ));
192
+ auto * fbo = static_cast <LuaFBO *>(luaL_checkudata (L, 1 , " FBO" ));
188
193
fbo->Free (L);
189
194
return 0 ;
190
195
}
@@ -193,7 +198,7 @@ int LuaFBOs::meta_gc(lua_State* L)
193
198
int LuaFBOs::meta_index (lua_State* L)
194
199
{
195
200
RECOIL_DETAILED_TRACY_ZONE;
196
- const FBO * fbo = static_cast <FBO *>(luaL_checkudata (L, 1 , " FBO" ));
201
+ const auto * fbo = static_cast <LuaFBO *>(luaL_checkudata (L, 1 , " FBO" ));
197
202
198
203
if (fbo->luaRef == LUA_NOREF)
199
204
return 0 ;
@@ -209,7 +214,7 @@ int LuaFBOs::meta_index(lua_State* L)
209
214
int LuaFBOs::meta_newindex (lua_State* L)
210
215
{
211
216
RECOIL_DETAILED_TRACY_ZONE;
212
- FBO * fbo = static_cast <FBO *>(luaL_checkudata (L, 1 , " FBO" ));
217
+ auto * fbo = static_cast <LuaFBO *>(luaL_checkudata (L, 1 , " FBO" ));
213
218
214
219
if (fbo->luaRef == LUA_NOREF)
215
220
return 0 ;
@@ -264,7 +269,7 @@ bool LuaFBOs::AttachObject(
264
269
const char * funcName,
265
270
lua_State* L,
266
271
int index,
267
- FBO * fbo,
272
+ LuaFBO * fbo,
268
273
GLenum attachID,
269
274
GLenum attachTarget,
270
275
GLenum attachLevel
@@ -353,7 +358,7 @@ void LuaFBOs::AttachObjectTexTarget(const char* funcName, GLenum fboTarget, GLen
353
358
bool LuaFBOs::ApplyAttachment (
354
359
lua_State* L,
355
360
int index,
356
- FBO * fbo,
361
+ LuaFBO * fbo,
357
362
const GLenum attachID
358
363
) {
359
364
RECOIL_DETAILED_TRACY_ZONE;
@@ -437,7 +442,7 @@ bool LuaFBOs::ApplyDrawBuffers(lua_State* L, int index)
437
442
*/
438
443
int LuaFBOs::CreateFBO (lua_State* L)
439
444
{
440
- FBO fbo;
445
+ LuaFBO fbo;
441
446
fbo.Init (L);
442
447
443
448
const int table = 1 ;
@@ -468,7 +473,7 @@ int LuaFBOs::CreateFBO(lua_State* L)
468
473
glBindFramebufferEXT (fbo.target , fbo.id );
469
474
470
475
471
- FBO * fboPtr = static_cast <FBO *>(lua_newuserdata (L, sizeof (FBO )));
476
+ auto * fboPtr = static_cast <LuaFBO *>(lua_newuserdata (L, sizeof (LuaFBO )));
472
477
*fboPtr = fbo;
473
478
474
479
luaL_getmetatable (L, " FBO" );
@@ -517,7 +522,7 @@ int LuaFBOs::DeleteFBO(lua_State* L)
517
522
if (lua_isnil (L, 1 ))
518
523
return 0 ;
519
524
520
- FBO * fbo = static_cast <FBO *>(luaL_checkudata (L, 1 , " FBO" ));
525
+ auto * fbo = static_cast <LuaFBO *>(luaL_checkudata (L, 1 , " FBO" ));
521
526
fbo->Free (L);
522
527
return 0 ;
523
528
}
@@ -537,7 +542,7 @@ int LuaFBOs::IsValidFBO(lua_State* L)
537
542
return 1 ;
538
543
}
539
544
540
- const FBO * fbo = static_cast <FBO *>(luaL_checkudata (L, 1 , " FBO" ));
545
+ const auto * fbo = static_cast <LuaFBO *>(luaL_checkudata (L, 1 , " FBO" ));
541
546
542
547
if ((fbo->id == 0 ) || (fbo->luaRef == LUA_NOREF)) {
543
548
lua_pushboolean (L, false );
@@ -580,7 +585,7 @@ int LuaFBOs::ActiveFBO(lua_State* L)
580
585
RECOIL_DETAILED_TRACY_ZONE;
581
586
CheckDrawingEnabled (L, __func__);
582
587
583
- const FBO * fbo = static_cast <FBO *>(luaL_checkudata (L, 1 , " FBO" ));
588
+ const auto * fbo = static_cast <LuaFBO *>(luaL_checkudata (L, 1 , " FBO" ));
584
589
585
590
if (fbo->id == 0 )
586
591
return 0 ;
@@ -664,7 +669,7 @@ int LuaFBOs::RawBindFBO(lua_State* L)
664
669
return 0 ;
665
670
}
666
671
667
- const FBO * fbo = static_cast <FBO *>(luaL_checkudata (L, 1 , " FBO" ));
672
+ const auto * fbo = static_cast <LuaFBO *>(luaL_checkudata (L, 1 , " FBO" ));
668
673
669
674
if (fbo->id == 0 )
670
675
return 0 ;
@@ -731,8 +736,8 @@ int LuaFBOs::BlitFBO(lua_State* L)
731
736
return 0 ;
732
737
}
733
738
734
- const FBO * fboSrc = (lua_isnil (L, 1 ))? nullptr : static_cast <FBO *>(luaL_checkudata (L, 1 , " FBO" ));
735
- const FBO * fboDst = (lua_isnil (L, 6 ))? nullptr : static_cast <FBO *>(luaL_checkudata (L, 6 , " FBO" ));
739
+ const auto * fboSrc = (lua_isnil (L, 1 ))? nullptr : static_cast <LuaFBO *>(luaL_checkudata (L, 1 , " FBO" ));
740
+ const auto * fboDst = (lua_isnil (L, 6 ))? nullptr : static_cast <LuaFBO *>(luaL_checkudata (L, 6 , " FBO" ));
736
741
737
742
// if passed a non-nil arg, userdatum buffer must always be valid
738
743
// otherwise the default framebuffer is substituted as its target
@@ -767,5 +772,157 @@ int LuaFBOs::BlitFBO(lua_State* L)
767
772
}
768
773
769
774
775
+ namespace Impl {
776
+ template <class Type , auto glClearBufferFuncPtr>
777
+ static inline void ClearBuffer (lua_State* L, int startIdx, GLenum bufferType, GLint drawBuffer) {
778
+ Type values[4 ];
779
+ values[0 ] = spring::SafeCast<Type>(luaL_optnumber (L, startIdx + 0 , 0 ));
780
+ values[1 ] = spring::SafeCast<Type>(luaL_optnumber (L, startIdx + 1 , 0 ));
781
+ values[2 ] = spring::SafeCast<Type>(luaL_optnumber (L, startIdx + 2 , 0 ));
782
+ values[3 ] = spring::SafeCast<Type>(luaL_optnumber (L, startIdx + 3 , 0 ));
783
+ (*glClearBufferFuncPtr)(bufferType, drawBuffer, values);
784
+ }
785
+ }
786
+
787
+ /* ** needs `Platform.glslVersionNum >= 300`
788
+ * Clears the "attachment" of the currently bound FBO type "target" with "clearValues"
789
+ *
790
+ * @function gl.ClearAttachmentFBO
791
+ * @param target number? (Default: GL.FRAMEBUFFER)
792
+ * @param attachment GL|string (e.g. `"color0"` or `GL.COLOR_ATTACHMENT0`)
793
+ * @param clearValue0 number
794
+ * @param clearValue1 number
795
+ * @param clearValue2 number
796
+ * @param clearValue3 number
797
+ */
798
+
799
+ int LuaFBOs::ClearAttachmentFBO (lua_State* L)
800
+ {
801
+ const auto ReportErrorAndReturn = [L](const char * errMsg = " " , const char * func = __func__) {
802
+ LOG_L (L_ERROR, " [gl.%s] Error: %s" , func, errMsg);
803
+ lua_pushboolean (L, false );
804
+ return 1 ;
805
+ };
806
+
807
+ #ifdef DEBUG
808
+ glClearErrors (" gl" , __func__, globalRendering->glDebugErrors );
809
+ #endif
810
+
811
+ int nextArg = 1 ;
812
+
813
+ GLenum target = luaL_optint (L, nextArg++, GL_FRAMEBUFFER);
814
+ GLenum queryType = 0 ;
815
+ switch (target)
816
+ {
817
+ case GL_READ_FRAMEBUFFER:
818
+ queryType = GL_READ_FRAMEBUFFER_BINDING;
819
+ break ;
820
+ case GL_DRAW_FRAMEBUFFER: [[fallthrough]];
821
+ case GL_FRAMEBUFFER:
822
+ queryType = GL_DRAW_FRAMEBUFFER_BINDING;
823
+ break ;
824
+ default :
825
+ return ReportErrorAndReturn (fmt::format (" invalid target type({}) Only GL.READ_FRAMEBUFFER|GL.DRAW_FRAMEBUFFER|GL.FRAMEBUFFER are accepted" , target).c_str ());
826
+ }
827
+
828
+ GLint fboID = 0 ;
829
+ glGetIntegerv (queryType, &fboID);
830
+
831
+ if (fboID == 0 )
832
+ return ReportErrorAndReturn (fmt::format (" no non-default fbo object is bound for target({})" , target).c_str ());
833
+
834
+
835
+ GLenum bufferType = 0 ;
836
+ GLenum attachment = 0 ;
837
+ GLenum drawBuffer = 0 ;
838
+
839
+ if (lua_isstring (L, nextArg)) {
840
+ const char * attachmentStr = luaL_checkstring (L, nextArg++);
841
+ switch (hashString (attachmentStr)) {
842
+ case hashString (" color0" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT0; drawBuffer = 0 ; } break ;
843
+ case hashString (" color1" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT1; drawBuffer = 1 ; } break ;
844
+ case hashString (" color2" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT2; drawBuffer = 2 ; } break ;
845
+ case hashString (" color3" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT3; drawBuffer = 3 ; } break ;
846
+ case hashString (" color4" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT4; drawBuffer = 4 ; } break ;
847
+ case hashString (" color5" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT5; drawBuffer = 5 ; } break ;
848
+ case hashString (" color6" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT6; drawBuffer = 6 ; } break ;
849
+ case hashString (" color7" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT7; drawBuffer = 7 ; } break ;
850
+ case hashString (" color8" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT8; drawBuffer = 8 ; } break ;
851
+ case hashString (" color9" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT9; drawBuffer = 9 ; } break ;
852
+ case hashString (" color10" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT10; drawBuffer = 10 ; } break ;
853
+ case hashString (" color11" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT11; drawBuffer = 11 ; } break ;
854
+ case hashString (" color12" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT12; drawBuffer = 12 ; } break ;
855
+ case hashString (" color13" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT13; drawBuffer = 13 ; } break ;
856
+ case hashString (" color14" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT14; drawBuffer = 14 ; } break ;
857
+ case hashString (" color15" ): { bufferType = GL_COLOR; attachment = GL_COLOR_ATTACHMENT15; drawBuffer = 15 ; } break ;
858
+ case hashString (" depth" ): { bufferType = GL_DEPTH; attachment = GL_DEPTH_ATTACHMENT; drawBuffer = 0 ; } break ;
859
+ case hashString (" stencil" ): { bufferType = GL_STENCIL; attachment = GL_STENCIL_ATTACHMENT; drawBuffer = 0 ; } break ;
860
+ default :
861
+ return ReportErrorAndReturn (fmt::format (" invalid attachment string ({})" , attachmentStr).c_str ());
862
+ }
863
+ }
864
+ else if (lua_isnumber (L, nextArg)) {
865
+ switch (attachment = luaL_checkint (L, nextArg++)) {
866
+ case GL_COLOR_ATTACHMENT0: { bufferType = GL_COLOR; drawBuffer = 0 ; } break ;
867
+ case GL_COLOR_ATTACHMENT1: { bufferType = GL_COLOR; drawBuffer = 1 ; } break ;
868
+ case GL_COLOR_ATTACHMENT2: { bufferType = GL_COLOR; drawBuffer = 2 ; } break ;
869
+ case GL_COLOR_ATTACHMENT3: { bufferType = GL_COLOR; drawBuffer = 3 ; } break ;
870
+ case GL_COLOR_ATTACHMENT4: { bufferType = GL_COLOR; drawBuffer = 4 ; } break ;
871
+ case GL_COLOR_ATTACHMENT5: { bufferType = GL_COLOR; drawBuffer = 5 ; } break ;
872
+ case GL_COLOR_ATTACHMENT6: { bufferType = GL_COLOR; drawBuffer = 6 ; } break ;
873
+ case GL_COLOR_ATTACHMENT7: { bufferType = GL_COLOR; drawBuffer = 7 ; } break ;
874
+ case GL_COLOR_ATTACHMENT8: { bufferType = GL_COLOR; drawBuffer = 8 ; } break ;
875
+ case GL_COLOR_ATTACHMENT9: { bufferType = GL_COLOR; drawBuffer = 9 ; } break ;
876
+ case GL_COLOR_ATTACHMENT10: { bufferType = GL_COLOR; drawBuffer = 10 ; } break ;
877
+ case GL_COLOR_ATTACHMENT11: { bufferType = GL_COLOR; drawBuffer = 11 ; } break ;
878
+ case GL_COLOR_ATTACHMENT12: { bufferType = GL_COLOR; drawBuffer = 12 ; } break ;
879
+ case GL_COLOR_ATTACHMENT13: { bufferType = GL_COLOR; drawBuffer = 13 ; } break ;
880
+ case GL_COLOR_ATTACHMENT14: { bufferType = GL_COLOR; drawBuffer = 14 ; } break ;
881
+ case GL_COLOR_ATTACHMENT15: { bufferType = GL_COLOR; drawBuffer = 15 ; } break ;
882
+ case GL_DEPTH_ATTACHMENT: { bufferType = GL_DEPTH; drawBuffer = 0 ; } break ;
883
+ case GL_STENCIL_ATTACHMENT: { bufferType = GL_STENCIL; drawBuffer = 0 ; } break ;
884
+ default :
885
+ return ReportErrorAndReturn (fmt::format (" invalid attachment type ({})" , attachment).c_str ());
886
+ }
887
+ }
888
+
889
+ GLint attachmentType = GL_NONE;
890
+ glGetFramebufferAttachmentParameteriv (target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &attachmentType);
891
+
892
+ if (attachmentType == GL_NONE || attachmentType == GL_FRAMEBUFFER_DEFAULT)
893
+ return ReportErrorAndReturn (fmt::format (" invalid attachment object type ({})" , attachmentType).c_str ());
894
+
895
+ GLint objectId = 0 ;
896
+ glGetFramebufferAttachmentParameteriv (target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &objectId);
897
+ if (objectId == 0 )
898
+ return ReportErrorAndReturn (fmt::format (" invalid attachment object id ({})" , objectId).c_str ());
899
+
900
+ GLint componentType = 0 ;
901
+ glGetFramebufferAttachmentParameteriv (target, attachment, GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, &componentType);
902
+
903
+ switch (componentType)
904
+ {
905
+ case GL_INT:
906
+ Impl::ClearBuffer<GLint, &glClearBufferiv>(L, nextArg, bufferType, drawBuffer);
907
+ break ;
908
+ case GL_UNSIGNED_INT:
909
+ Impl::ClearBuffer<GLuint, &glClearBufferuiv>(L, nextArg, bufferType, drawBuffer);
910
+ break ;
911
+ case GL_SIGNED_NORMALIZED: [[fallthrough]]; // is this considered a fixed point value?
912
+ case GL_UNSIGNED_NORMALIZED: [[fallthrough]]; // is this considered a fixed point value?
913
+ case GL_FLOAT:
914
+ Impl::ClearBuffer<GLfloat, &glClearBufferfv>(L, nextArg, bufferType, drawBuffer);
915
+ break ;
916
+ default :
917
+ return ReportErrorAndReturn (fmt::format (" invalid attachment component type ({}), means the attachment is invalid" , componentType).c_str ());
918
+ }
919
+
920
+ assert (glGetError () == GL_NO_ERROR);
921
+
922
+ lua_pushboolean (L, true );
923
+ return 1 ;
924
+ }
925
+
926
+
770
927
/* *****************************************************************************/
771
928
/* *****************************************************************************/
0 commit comments