GLS.State.pas 118 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523
  1. //
  2. // The graphics engine GLScene https://github.com/glscene
  3. //
  4. unit GLS.State;
  5. (* Tools for managing an application-side cache of OpenGL state. *)
  6. (*
  7. TODO: Proper client-side pushing + popping of state, in OpenGL 3+ contexts,
  8. rather than using glPushAttrib + glPopAttrib.
  9. TODO: Proper support for textures, taking into account that they probably
  10. won't be linked to texture units in some future version of OpenGL.
  11. TODO: Once more of GLScene is cache-aware, enable some of the checks before
  12. changing OpenGL state (where we will gain a speed increase).
  13. DONE: Cache some relevant legacy state
  14. TODO: improve binding objects to binding points
  15. TODO: decide how to implement the new Enable* options (without going above
  16. 32 elements in sets if possible, which would be slower in 32bit Delphi)
  17. DONE: remove stTexture1D, 2D, etc from TGLState if possible, since they are
  18. per texture-unit + also deprecated in OpenGL 3+
  19. *)
  20. interface
  21. {$I GLScene.Defines.inc}
  22. { .$DEFINE USE_CACHE_MISS_CHECK }
  23. uses
  24. Winapi.OpenGL,
  25. Winapi.OpenGLext,
  26. System.Classes,
  27. System.SysUtils,
  28. GLScene.OpenGLTokens,
  29. GLScene.VectorTypes,
  30. GLScene.VectorGeometry,
  31. GLScene.TextureFormat,
  32. GLScene.Utils;
  33. const
  34. GLS_VERTEX_ATTR_NUM = 16;
  35. type
  36. TGLStateType = (sttCurrent, sttPoint, sttLine, sttPolygon, sttPolygonStipple,
  37. sttPixelMode, sttLighting, sttFog, sttDepthBuffer, sttAccumBuffer,
  38. sttStencilBuffer, sttViewport, sttTransform, sttEnable, sttColorBuffer,
  39. sttHint, sttEval, sttList, sttTexture, sttScissor,
  40. sttMultisample);
  41. TGLStateTypes = set of TGLStateType;
  42. const
  43. cAllAttribBits = [low(TGLStateType) .. High(TGLStateType)];
  44. type
  45. TGLMeshPrimitive = (
  46. mpNOPRIMITIVE,
  47. mpTRIANGLES,
  48. mpTRIANGLE_STRIP,
  49. mpTRIANGLE_FAN,
  50. mpPOINTS,
  51. mpLINES,
  52. mpLINE_LOOP,
  53. mpLINE_STRIP,
  54. mpLINES_ADJACENCY,
  55. mpLINE_STRIP_ADJACENCY,
  56. mpTRIANGLES_ADJACENCY,
  57. mpTRIANGLE_STRIP_ADJACENCY,
  58. mpPATCHES
  59. );
  60. TGLMeshPrimitives = set of TGLMeshPrimitive;
  61. const
  62. cAllMeshPrimitive = [
  63. mpTRIANGLES,
  64. mpTRIANGLE_STRIP,
  65. mpTRIANGLE_FAN,
  66. mpPOINTS,
  67. mpLINES,
  68. mpLINE_LOOP,
  69. mpLINE_STRIP,
  70. mpLINES_ADJACENCY,
  71. mpLINE_STRIP_ADJACENCY,
  72. mpTRIANGLES_ADJACENCY,
  73. mpTRIANGLE_STRIP_ADJACENCY,
  74. mpPATCHES];
  75. type
  76. // Reflects all relevant (binary) states of OpenGL subsystem
  77. TGLState = (stAlphaTest, stAutoNormal,
  78. stBlend, stColorMaterial, stCullFace, stDepthTest, stDither,
  79. stFog, stLighting, stLineSmooth, stLineStipple,
  80. stIndexLogicOp, stColorLogicOp, stNormalize, stPointSmooth, stPointSprite,
  81. stPolygonSmooth, stPolygonStipple, stScissorTest, stStencilTest,
  82. stPolygonOffsetPoint, stPolygonOffsetLine, stPolygonOffsetFill,
  83. stDepthClamp);
  84. TGLStates = set of TGLState;
  85. TGLComparisonFunction = (cfNever, cfAlways, cfLess, cfLEqual, cfEqual,
  86. cfGreater, cfNotEqual, cfGEqual);
  87. TGLStencilFunction = TGLComparisonFunction;
  88. TGLDepthFunction = TGLComparisonFunction;
  89. TGLBlendFunction = (bfZero, bfOne,
  90. bfSrcColor, bfOneMinusSrcColor, bfDstColor, bfOneMinusDstColor,
  91. bfSrcAlpha, bfOneMinusSrcAlpha, bfDstAlpha, bfOneMinusDstAlpha,
  92. bfConstantColor, bfOneMinusConstantColor,
  93. bfConstantAlpha, bfOneMinusConstantAlpha,
  94. bfSrcAlphaSat);
  95. TGLDstBlendFunction = bfZero..bfOneMinusConstantAlpha;
  96. TGLBlendEquation = (beAdd, beSubtract, beReverseSubtract, beMin, beMax);
  97. TGLStencilOp = (soKeep, soZero, soReplace, soIncr, soDecr, soInvert, soIncrWrap,
  98. soDecrWrap);
  99. TGLLogicOp = (loClear, loAnd, loAndReverse, loCopy, loAndInverted, loNoOp,
  100. loXOr, loOr, loNor, loEquiv, loInvert, loOrReverse, loCopyInverted,
  101. loOrInverted, loNAnd, loSet);
  102. TGLQueryType = (
  103. qrySamplesPassed,
  104. qryPrimitivesGenerated,
  105. qryTransformFeedbackPrimitivesWritten,
  106. qryTimeElapsed,
  107. qryAnySamplesPassed);
  108. // Describe what kind of winding has a front face
  109. TGLFaceWinding = (fwCounterClockWise, fwClockWise);
  110. TGLPolygonMode = (pmFill, pmLines, pmPoints);
  111. TGLCullFaceMode = (cmFront, cmBack, cmFrontAndBack);
  112. // TSingleCullFaceMode = cmFront..cmBack;
  113. TGLColorComponent = (ccRed, ccGreen, ccBlue, ccAlpha);
  114. TGLColorMask = set of TGLColorComponent;
  115. const
  116. cAllColorComponents = [ccRed, ccGreen, ccBlue, ccAlpha];
  117. MAX_HARDWARE_LIGHT = 16;
  118. MAX_SHADER_LIGHT = 8;
  119. MAX_HARDWARE_TEXTURE_UNIT = 48;
  120. MAX_HARDWARE_UNIFORM_BUFFER_BINDING = 75;
  121. type
  122. TGLHintType = (hintDontCare, hintFastest, hintNicest);
  123. TGLLightSourceState = packed record
  124. Position: array [0 .. MAX_HARDWARE_LIGHT - 1] of TGLVector;
  125. Ambient: array [0 .. MAX_HARDWARE_LIGHT - 1] of TGLVector;
  126. Diffuse: array [0 .. MAX_HARDWARE_LIGHT - 1] of TGLVector;
  127. Specular: array [0 .. MAX_HARDWARE_LIGHT - 1] of TGLVector;
  128. SpotDirection: array [0 .. MAX_HARDWARE_LIGHT - 1] of TGLVector;
  129. SpotCosCutoffExponent: array [0 .. MAX_HARDWARE_LIGHT - 1] of TGLVector;
  130. Attenuation: array [0 .. MAX_HARDWARE_LIGHT - 1] of TGLVector;
  131. end;
  132. TGLShaderLightSourceState = packed record
  133. Position: array [0 .. MAX_SHADER_LIGHT - 1] of TGLVector;
  134. Ambient: array [0 .. MAX_SHADER_LIGHT - 1] of TGLVector;
  135. Diffuse: array [0 .. MAX_SHADER_LIGHT - 1] of TGLVector;
  136. Specular: array [0 .. MAX_SHADER_LIGHT - 1] of TGLVector;
  137. SpotDirection: array [0 .. MAX_SHADER_LIGHT - 1] of TGLVector;
  138. SpotCosCutoffExponent: array [0 .. MAX_SHADER_LIGHT - 1] of TGLVector;
  139. Attenuation: array [0 .. MAX_SHADER_LIGHT - 1] of TGLVector;
  140. end;
  141. TGLOnLightsChanged = procedure(Sender: TObject);
  142. TGLBufferBindingTarget = (bbtUniform, bbtTransformFeedBack);
  143. TUBOStates = record
  144. FUniformBufferBinding: Cardinal;
  145. FOffset: TGLintptr;
  146. FSize: TGLsizeiptr;
  147. end;
  148. TGLMaterialLevel = (mlAuto, mlFixedFunction, mlMultitexturing, mlSM3, mlSM4, mlSM5);
  149. (* Manages an application-side cache of OpenGL states and parameters.
  150. Purpose of this class is to eliminate redundant state and parameter
  151. changes, and there will typically be no more than one state cache per
  152. OpenGL context *)
  153. TGLStateCache = class
  154. strict private
  155. // Legacy state
  156. FFrontBackColors: array [0 .. 1, 0 .. 3] of TGLVector;
  157. FFrontBackShininess: array [0 .. 1] of Integer;
  158. FAlphaFunc: TGLComparisonFunction;
  159. FAlphaRef: Single;
  160. FPolygonBackMode: TGLPolygonMode; // Front + back have same polygon mode
  161. // Lighting state
  162. FMaxLights: Cardinal;
  163. FLightEnabling: array [0 .. MAX_HARDWARE_LIGHT - 1] of Boolean;
  164. FLightIndices: array [0 .. MAX_HARDWARE_LIGHT - 1] of TGLint;
  165. FLightNumber: Integer;
  166. FLightStates: TGLLightSourceState;
  167. FSpotCutoff: array [0 .. MAX_HARDWARE_LIGHT - 1] of Single;
  168. FShaderLightStates: TGLShaderLightSourceState;
  169. FShaderLightStatesChanged: Boolean;
  170. FColorWriting: Boolean; // TODO: change to per draw buffer (FColorWriteMask)
  171. FStates: TGLStates;
  172. FListStates: array of TGLStateTypes;
  173. FCurrentList: Cardinal;
  174. FTextureMatrixIsIdentity: array [0 .. 3] of Boolean;
  175. // FForwardContext: Boolean;
  176. FFFPLight: Boolean;
  177. // Vertex Array Data state
  178. FVertexArrayBinding: Cardinal;
  179. FArrayBufferBinding: Cardinal;
  180. FElementBufferBinding: Cardinal;
  181. FTextureBufferBinding: Cardinal;
  182. FEnablePrimitiveRestart: TGLboolean;
  183. FPrimitiveRestartIndex: Cardinal;
  184. // Transformation state
  185. FViewPort: TVector4i;
  186. FDepthRange: array [0 .. 1] of TGLclampd;
  187. FEnableClipDistance: array [0 .. 7] of TGLboolean;
  188. FEnableDepthClamp: TGLboolean;
  189. // Coloring state
  190. FClampReadColor: Cardinal; // GL_FIXED_ONLY
  191. FProvokingVertex: Cardinal; // GL_LAST_VERTEX_CONVENTION
  192. // Rasterization state
  193. FPointSize: TGLfloat;
  194. FPointFadeThresholdSize: TGLfloat;
  195. FPointSpriteCoordOrigin: Cardinal; // GL_UPPER_LEFT
  196. FLineWidth: Single;
  197. FLineStippleFactor: TGLint;
  198. FLineStipplePattern: TGLushort;
  199. FEnableLineSmooth: TGLboolean;
  200. FEnableCullFace: TGLboolean;
  201. FCullFaceMode: TGLCullFaceMode;
  202. FFrontFace: TGLFaceWinding;
  203. FEnablePolygonSmooth: TGLboolean;
  204. FPolygonMode: TGLPolygonMode;
  205. FPolygonOffsetFactor: TGLfloat;
  206. FPolygonOffsetUnits: TGLfloat;
  207. FEnablePolygonOffsetPoint: TGLboolean;
  208. FEnablePolygonOffsetLine: TGLboolean;
  209. FEnablePolygonOffsetFill: TGLboolean;
  210. // Multisample state
  211. FEnableMultisample: TGLboolean;
  212. FEnableSampleAlphaToCoverage: TGLboolean;
  213. FEnableSampleAlphaToOne: TGLboolean;
  214. FEnableSampleCoverage: TGLboolean;
  215. FSampleCoverageValue: TGLfloat;
  216. FSampleCoverageInvert: TGLboolean;
  217. FEnableSampleMask: TGLboolean;
  218. FSampleMaskValue: array [0 .. 15] of TGLbitfield;
  219. // Texture state
  220. FMaxTextureSize: Cardinal;
  221. FMax3DTextureSize: Cardinal;
  222. FMaxCubeTextureSize: Cardinal;
  223. FMaxArrayTextureSize: Cardinal;
  224. FMaxTextureImageUnits: Cardinal;
  225. FMaxTextureAnisotropy: Cardinal;
  226. FMaxSamples: Cardinal;
  227. FTextureBinding: array [0 .. MAX_HARDWARE_TEXTURE_UNIT - 1, TGLTextureTarget] of Cardinal;
  228. FTextureBindingTime: array [0 .. MAX_HARDWARE_TEXTURE_UNIT - 1, TGLTextureTarget] of Double;
  229. FSamplerBinding: array [0 .. MAX_HARDWARE_TEXTURE_UNIT - 1] of Cardinal;
  230. // Active texture state
  231. FActiveTexture: TGLint; // 0 .. Max_texture_units
  232. FActiveTextureEnabling: array [0 .. MAX_HARDWARE_TEXTURE_UNIT - 1, TGLTextureTarget] of Boolean;
  233. // Pixel operation state
  234. FEnableScissorTest: TGLboolean;
  235. FScissorBox: TVector4i;
  236. FEnableStencilTest: TGLboolean;
  237. FStencilFunc: TGLStencilFunction;
  238. FStencilValueMask: Cardinal;
  239. FStencilRef: TGLint;
  240. FStencilFail: TGLStencilOp;
  241. FStencilPassDepthFail: TGLStencilOp;
  242. FStencilPassDepthPass: TGLStencilOp;
  243. FStencilBackFunc: TGLStencilFunction;
  244. FStencilBackValueMask: Cardinal;
  245. FStencilBackRef: Cardinal;
  246. FStencilBackFail: TGLStencilOp;
  247. FStencilBackPassDepthPass: TGLStencilOp;
  248. FStencilBackPassDepthFail: TGLStencilOp;
  249. FEnableDepthTest: TGLboolean;
  250. FDepthFunc: TGLDepthFunction;
  251. FEnableBlend: array [0 .. 15] of TGLboolean;
  252. FBlendSrcRGB: TGLBlendFunction;
  253. FBlendSrcAlpha: TGLBlendFunction;
  254. FBlendDstRGB: TGLDstBlendFunction;
  255. FBlendDstAlpha: TGLDstBlendFunction;
  256. FBlendEquationRGB: TGLBlendEquation;
  257. FBlendEquationAlpha: TGLBlendEquation;
  258. FBlendColor: TGLVector;
  259. FEnableFramebufferSRGB: TGLboolean;
  260. FEnableDither: TGLboolean;
  261. FEnableColorLogicOp: TGLboolean;
  262. FLogicOpMode: TGLLogicOp;
  263. // Framebuffer control state
  264. FColorWriteMask: array [0 .. 15] of TGLColorMask;
  265. FDepthWriteMask: TGLboolean;
  266. FStencilWriteMask: Cardinal;
  267. FStencilBackWriteMask: Cardinal;
  268. FColorClearValue: TGLVector;
  269. FDepthClearValue: TGLfloat;
  270. FStencilClearValue: Cardinal;
  271. // Framebuffer state
  272. FDrawFrameBuffer: Cardinal;
  273. FReadFrameBuffer: Cardinal;
  274. // Renderbuffer state
  275. FRenderBuffer: Cardinal;
  276. // Pixels state
  277. FUnpackSwapBytes: TGLboolean;
  278. FUnpackLSBFirst: TGLboolean;
  279. FUnpackImageHeight: Cardinal;
  280. FUnpackSkipImages: Cardinal;
  281. FUnpackRowLength: Cardinal;
  282. FUnpackSkipRows: Cardinal;
  283. FUnpackSkipPixels: Cardinal;
  284. FUnpackAlignment: Cardinal;
  285. FPackSwapBytes: TGLboolean;
  286. FPackLSBFirst: TGLboolean;
  287. FPackImageHeight: Cardinal;
  288. FPackSkipImages: Cardinal;
  289. FPackRowLength: Cardinal;
  290. FPackSkipRows: Cardinal;
  291. FPackSkipPixels: Cardinal;
  292. FPackAlignment: Cardinal;
  293. FPixelPackBufferBinding: Cardinal;
  294. FPixelUnpackBufferBinding: Cardinal;
  295. // Program state
  296. FCurrentProgram: Cardinal;
  297. FMaxTextureUnits: Cardinal;
  298. FUniformBufferBinding: Cardinal;
  299. FUBOStates: array [TGLBufferBindingTarget, 0 .. MAX_HARDWARE_UNIFORM_BUFFER_BINDING - 1] of TUBOStates;
  300. // Vector + Geometry Shader state
  301. FCurrentVertexAttrib: array [0 .. 15] of TGLVector;
  302. FEnableProgramPointSize: TGLboolean;
  303. // Transform Feedback state
  304. FTransformFeedbackBufferBinding: Cardinal;
  305. // Hints state
  306. FTextureCompressionHint: TGLHintType;
  307. FPolygonSmoothHint: TGLHintType;
  308. FFragmentShaderDerivitiveHint: TGLHintType;
  309. FLineSmoothHint: TGLHintType;
  310. FMultisampleFilterHint: TGLHintType;
  311. // Misc state
  312. FCurrentQuery: array [TGLQueryType] of Cardinal;
  313. FCopyReadBufferBinding: Cardinal;
  314. FCopyWriteBufferBinding: Cardinal;
  315. FEnableTextureCubeMapSeamless: TGLboolean;
  316. FInsideList: Boolean;
  317. FOnLightsChanged: TGLOnLightsChanged;
  318. protected
  319. // Vertex Array Data state
  320. procedure SetVertexArrayBinding(const Value: Cardinal); inline;
  321. function GetArrayBufferBinding: Cardinal; inline;
  322. procedure SetArrayBufferBinding(const Value: Cardinal); inline;
  323. function GetElementBufferBinding: Cardinal; inline;
  324. procedure SetElementBufferBinding(const Value: Cardinal); inline;
  325. function GetEnablePrimitiveRestart: TGLboolean; inline;
  326. function GetPrimitiveRestartIndex: Cardinal; inline;
  327. procedure SetEnablePrimitiveRestart(const enabled: TGLboolean); inline;
  328. procedure SetPrimitiveRestartIndex(const index: Cardinal); inline;
  329. procedure SetTextureBufferBinding(const Value: Cardinal); inline;
  330. // Transformation state
  331. procedure SetViewPort(const Value: TVector4i); inline;
  332. function GetEnableClipDistance(ClipDistance: Cardinal): TGLboolean; inline;
  333. procedure SetEnableClipDistance(index: Cardinal; const Value: TGLboolean); inline;
  334. function GetDepthRangeFar: TGLclampd; inline;
  335. procedure SetDepthRangeFar(const Value: TGLclampd); inline;
  336. function GetDepthRangeNear: TGLclampd; inline;
  337. procedure SetDepthRangeNear(const Value: TGLclampd); inline;
  338. procedure SetEnableDepthClamp(const enabled: TGLboolean); inline;
  339. // Coloring state
  340. procedure SetClampReadColor(const Value: Cardinal); inline;
  341. procedure SetProvokingVertex(const Value: Cardinal); inline;
  342. // Rasterization state
  343. procedure SetPointSize(const Value: TGLfloat); inline;
  344. procedure SetPointFadeThresholdSize(const Value: TGLfloat); inline;
  345. procedure SetPointSpriteCoordOrigin(const Value: Cardinal); inline;
  346. procedure SetLineWidth(const Value: TGLfloat); inline;
  347. procedure SetLineStippleFactor(const Value: TGLint); inline;
  348. procedure SetLineStipplePattern(const Value: TGLushort); inline;
  349. procedure SetEnableLineSmooth(const Value: TGLboolean); inline;
  350. procedure SetEnableCullFace(const Value: TGLboolean); inline;
  351. procedure SetCullFaceMode(const Value: TGLCullFaceMode); inline;
  352. procedure SetFrontFace(const Value: TGLFaceWinding); inline;
  353. procedure SetEnablePolygonSmooth(const Value: TGLboolean); inline;
  354. procedure SetPolygonMode(const Value: TGLPolygonMode); inline;
  355. procedure SetPolygonOffsetFactor(const Value: TGLfloat); inline;
  356. procedure SetPolygonOffsetUnits(const Value: TGLfloat); inline;
  357. procedure SetEnablePolygonOffsetPoint(const Value: TGLboolean); inline;
  358. procedure SetEnablePolygonOffsetLine(const Value: TGLboolean); inline;
  359. procedure SetEnablePolygonOffsetFill(const Value: TGLboolean); inline;
  360. // Multisample state
  361. procedure SetEnableMultisample(const Value: TGLboolean); inline;
  362. procedure SetEnableSampleAlphaToCoverage(const Value: TGLboolean); inline;
  363. procedure SetEnableSampleAlphaToOne(const Value: TGLboolean); inline;
  364. procedure SetEnableSampleCoverage(const Value: TGLboolean); inline;
  365. procedure SetSampleCoverageValue(const Value: TGLfloat); inline;
  366. procedure SetSampleCoverageInvert(const Value: TGLboolean); inline;
  367. procedure SetEnableSampleMask(const Value: TGLboolean); inline;
  368. function GetSampleMaskValue(index: Integer): TGLbitfield; inline;
  369. procedure SetSampleMaskValue(index: Integer; const Value: TGLbitfield); inline;
  370. // Texture state
  371. function GetMaxTextureSize: Cardinal; inline;
  372. function GetMax3DTextureSize: Cardinal; inline;
  373. function GetMaxCubeTextureSize: Cardinal; inline;
  374. function GetMaxArrayTextureSize: Cardinal; inline;
  375. function GetMaxTextureImageUnits: Cardinal; inline;
  376. function GetMaxTextureAnisotropy: Cardinal; inline;
  377. function GetMaxSamples: Cardinal; inline;
  378. function GetTextureBinding(index: Integer; target: TGLTextureTarget): Cardinal; inline;
  379. function GetTextureBindingTime(index: Integer; target: TGLTextureTarget): Double; inline;
  380. procedure SetTextureBinding(index: Integer; target: TGLTextureTarget; const Value: Cardinal);
  381. function GetActiveTextureEnabled(target: TGLTextureTarget): Boolean; inline;
  382. procedure SetActiveTextureEnabled(target: TGLTextureTarget; const Value: Boolean); inline;
  383. function GetSamplerBinding(index: Cardinal): Cardinal; inline;
  384. procedure SetSamplerBinding(index: Cardinal; const Value: Cardinal); inline;
  385. // Active texture
  386. procedure SetActiveTexture(const Value: TGLint); inline;
  387. // Pixel operations
  388. procedure SetEnableScissorTest(const Value: TGLboolean); inline;
  389. procedure SetScissorBox(const Value: TVector4i); inline;
  390. procedure SetEnableStencilTest(const Value: TGLboolean); inline;
  391. procedure SetEnableDepthTest(const Value: TGLboolean); inline;
  392. procedure SetDepthFunc(const Value: TGLDepthFunction); inline;
  393. function GetEnableBlend(index: Integer): TGLboolean; inline;
  394. procedure SetEnableBlend(index: Integer; const Value: TGLboolean); inline;
  395. procedure SetBlendColor(const Value: TGLVector); inline;
  396. procedure SetEnableFramebufferSRGB(const Value: TGLboolean); inline;
  397. procedure SetEnableDither(const Value: TGLboolean); inline;
  398. procedure SetEnableColorLogicOp(const Value: TGLboolean); inline;
  399. procedure SetLogicOpMode(const Value: TGLLogicOp); inline;
  400. // Framebuffer control
  401. function GetColorWriteMask(index: Integer): TGLColorMask; inline;
  402. procedure SetColorWriteMask(index: Integer; const Value: TGLColorMask); inline;
  403. procedure SetDepthWriteMask(const Value: TGLboolean); inline;
  404. procedure SetStencilWriteMask(const Value: Cardinal); inline;
  405. procedure SetStencilBackWriteMask(const Value: Cardinal); inline;
  406. procedure SetColorClearValue(const Value: TGLVector); inline;
  407. procedure SetDepthClearValue(const Value: TGLfloat); inline;
  408. procedure SetStencilClearValue(const Value: Cardinal); inline;
  409. // Framebuffer
  410. procedure SetDrawFrameBuffer(const Value: Cardinal); inline;
  411. procedure SetReadFrameBuffer(const Value: Cardinal); inline;
  412. // Renderbuffer
  413. procedure SetRenderBuffer(const Value: Cardinal); inline;
  414. // Pixels
  415. procedure SetUnpackSwapBytes(const Value: TGLboolean); inline;
  416. procedure SetUnpackLSBFirst(const Value: TGLboolean); inline;
  417. procedure SetUnpackImageHeight(const Value: Cardinal); inline;
  418. procedure SetUnpackSkipImages(const Value: Cardinal); inline;
  419. procedure SetUnpackRowLength(const Value: Cardinal); inline;
  420. procedure SetUnpackSkipRows(const Value: Cardinal); inline;
  421. procedure SetUnpackSkipPixels(const Value: Cardinal); inline;
  422. procedure SetUnpackAlignment(const Value: Cardinal); inline;
  423. procedure SetPackSwapBytes(const Value: TGLboolean); inline;
  424. procedure SetPackLSBFirst(const Value: TGLboolean); inline;
  425. procedure SetPackImageHeight(const Value: Cardinal); inline;
  426. procedure SetPackSkipImages(const Value: Cardinal); inline;
  427. procedure SetPackRowLength(const Value: Cardinal); inline;
  428. procedure SetPackSkipRows(const Value: Cardinal); inline;
  429. procedure SetPackSkipPixels(const Value: Cardinal); inline;
  430. procedure SetPackAlignment(const Value: Cardinal); inline;
  431. procedure SetPixelPackBufferBinding(const Value: Cardinal);
  432. procedure SetPixelUnpackBufferBinding(const Value: Cardinal);
  433. // Program
  434. procedure SetCurrentProgram(const Value: Cardinal); inline;
  435. procedure SetUniformBufferBinding(const Value: Cardinal); inline;
  436. function GetMaxTextureUnits: Cardinal; inline;
  437. // Vector + Geometry Shader state
  438. function GetCurrentVertexAttrib(index: Integer): TGLVector; inline;
  439. procedure SetCurrentVertexAttrib(index: Integer; const Value: TGLVector); inline;
  440. procedure SetEnableProgramPointSize(const Value: TGLboolean); inline;
  441. // Transform Feedback state
  442. procedure SetTransformFeedbackBufferBinding(const Value: Cardinal); inline;
  443. // Hints
  444. procedure SetLineSmoothHint(const Value: TGLHintType); inline;
  445. procedure SetPolygonSmoothHint(const Value: TGLHintType); inline;
  446. procedure SetTextureCompressionHint(const Value: TGLHintType); inline;
  447. procedure SetFragmentShaderDerivitiveHint(const Value: TGLHintType); inline;
  448. procedure SetMultisampleFilterHint(const Value: TGLHintType); inline;
  449. // Misc
  450. function GetCurrentQuery(index: TGLQueryType): Cardinal; inline;
  451. // procedure SetCurrentQuery(Index: TQueryType; const Value: Cardinal);
  452. procedure SetCopyReadBufferBinding(const Value: Cardinal); inline;
  453. procedure SetCopyWriteBufferBinding(const Value: Cardinal); inline;
  454. procedure SetEnableTextureCubeMapSeamless(const Value: TGLboolean); inline;
  455. // Ligting
  456. procedure SetFFPLight(Value: Boolean); inline;
  457. function GetMaxLights: Integer; inline;
  458. function GetLightEnabling(I: Integer): Boolean; inline;
  459. procedure SetLightEnabling(I: Integer; Value: Boolean); inline;
  460. function GetLightPosition(I: Integer): TGLVector; inline;
  461. procedure SetLightPosition(I: Integer; const Value: TGLVector); inline;
  462. function GetLightSpotDirection(I: Integer): TAffineVector; inline;
  463. procedure SetLightSpotDirection(I: Integer; const Value: TAffineVector); inline;
  464. function GetLightAmbient(I: Integer): TGLVector; inline;
  465. procedure SetLightAmbient(I: Integer; const Value: TGLVector); inline;
  466. function GetLightDiffuse(I: Integer): TGLVector; inline;
  467. procedure SetLightDiffuse(I: Integer; const Value: TGLVector); inline;
  468. function GetLightSpecular(I: Integer): TGLVector; inline;
  469. procedure SetLightSpecular(I: Integer; const Value: TGLVector); inline;
  470. function GetSpotCutoff(I: Integer): Single; inline;
  471. procedure SetSpotCutoff(I: Integer; const Value: Single); inline;
  472. function GetSpotExponent(I: Integer): Single; inline;
  473. procedure SetSpotExponent(I: Integer; const Value: Single); inline;
  474. function GetConstantAtten(I: Integer): Single; inline;
  475. procedure SetConstantAtten(I: Integer; const Value: Single); inline;
  476. function GetLinearAtten(I: Integer): Single; inline;
  477. procedure SetLinearAtten(I: Integer; const Value: Single); inline;
  478. function GetQuadAtten(I: Integer): Single; inline;
  479. procedure SetQuadAtten(I: Integer; const Value: Single); inline;
  480. procedure SetForwardContext(Value: Boolean); inline;
  481. function GetMaterialAmbient(const aFace: TGLCullFaceMode): TGLVector; inline;
  482. function GetMaterialDiffuse(const aFace: TGLCullFaceMode): TGLVector; inline;
  483. function GetMaterialSpecular(const aFace: TGLCullFaceMode): TGLVector; inline;
  484. function GetMaterialEmission(const aFace: TGLCullFaceMode): TGLVector; inline;
  485. function GetMaterialShininess(const aFace: TGLCullFaceMode): Integer; inline;
  486. public
  487. constructor Create; virtual;
  488. destructor Destroy; override;
  489. procedure PushAttrib(const stateTypes: TGLStateTypes); inline;
  490. procedure PopAttrib(); inline;
  491. procedure Enable(const aState: TGLState);
  492. procedure Disable(const aState: TGLState);
  493. procedure PerformEnable(const aState: TGLState); inline;
  494. procedure PerformDisable(const aState: TGLState); inline;
  495. procedure SetGLState(const aState: TGLState); deprecated; inline;
  496. procedure UnSetGLState(const aState: TGLState); deprecated; inline;
  497. procedure ResetGLPolygonMode; deprecated; inline;
  498. procedure ResetGLMaterialColors; deprecated; inline;
  499. procedure ResetGLTexture(const TextureUnit: Integer); deprecated; inline;
  500. procedure ResetGLCurrentTexture; deprecated;
  501. procedure ResetGLFrontFace; deprecated;
  502. procedure SetGLFrontFaceCW; deprecated; inline;
  503. procedure ResetAll; deprecated; inline;
  504. // Adjusts material colors for a face
  505. procedure SetGLMaterialColors(const aFace: TGLCullFaceMode; const emission, Ambient, Diffuse, Specular: TGLVector;
  506. const shininess: Integer);
  507. property MaterialAmbient[const aFace: TGLCullFaceMode]: TGLVector read GetMaterialAmbient;
  508. property MaterialDiffuse[const aFace: TGLCullFaceMode]: TGLVector read GetMaterialDiffuse;
  509. property MaterialSpecular[const aFace: TGLCullFaceMode]: TGLVector read GetMaterialSpecular;
  510. property MaterialEmission[const aFace: TGLCullFaceMode]: TGLVector read GetMaterialEmission;
  511. property MaterialShininess[const aFace: TGLCullFaceMode]: Integer read GetMaterialShininess;
  512. // Adjusts material alpha channel for a face
  513. procedure SetGLMaterialAlphaChannel(const aFace: Cardinal; const alpha: TGLfloat);
  514. // Adjusts material diffuse color for a face
  515. procedure SetGLMaterialDiffuseColor(const aFace: Cardinal; const Diffuse: TGLVector);
  516. // Lighting states
  517. property FixedFunctionPipeLight: Boolean read FFFPLight write SetFFPLight;
  518. property MaxLights: Integer read GetMaxLights;
  519. property LightEnabling[Index: Integer]: Boolean read GetLightEnabling write SetLightEnabling;
  520. property LightPosition[Index: Integer]: TGLVector read GetLightPosition write SetLightPosition;
  521. property LightSpotDirection[Index: Integer]: TAffineVector read GetLightSpotDirection write SetLightSpotDirection;
  522. property LightAmbient[Index: Integer]: TGLVector read GetLightAmbient write SetLightAmbient;
  523. property LightDiffuse[Index: Integer]: TGLVector read GetLightDiffuse write SetLightDiffuse;
  524. property LightSpecular[Index: Integer]: TGLVector read GetLightSpecular write SetLightSpecular;
  525. property LightSpotCutoff[Index: Integer]: Single read GetSpotCutoff write SetSpotCutoff;
  526. property LightSpotExponent[Index: Integer]: Single read GetSpotExponent write SetSpotExponent;
  527. property LightConstantAtten[Index: Integer]: Single read GetConstantAtten write SetConstantAtten;
  528. property LightLinearAtten[Index: Integer]: Single read GetLinearAtten write SetLinearAtten;
  529. property LightQuadraticAtten[Index: Integer]: Single read GetQuadAtten write SetQuadAtten;
  530. function GetLightIndicesAsAddress: PGLInt;
  531. function GetLightStateAsAddress: Pointer;
  532. property LightNumber: Integer read FLightNumber;
  533. property OnLightsChanged: TGLOnLightsChanged read FOnLightsChanged write FOnLightsChanged;
  534. // Blending states
  535. procedure SetGLAlphaFunction(func: TGLComparisonFunction; ref: Single); inline;
  536. // Vertex Array Data state
  537. (* The currently bound array buffer (calling glVertexAttribPointer
  538. locks this buffer to the currently bound VBO). *)
  539. property VertexArrayBinding: Cardinal read FVertexArrayBinding write SetVertexArrayBinding;
  540. // The currently bound vertex buffer object (VAO)
  541. property ArrayBufferBinding: Cardinal read GetArrayBufferBinding write SetArrayBufferBinding;
  542. // The currently bound element buffer object (EBO)
  543. property ElementBufferBinding: Cardinal read GetElementBufferBinding write SetElementBufferBinding;
  544. // Determines whether primitive restart is turned on or off
  545. property EnablePrimitiveRestart: TGLboolean read GetEnablePrimitiveRestart write SetEnablePrimitiveRestart;
  546. // The index Value that causes a primitive restart
  547. property PrimitiveRestartIndex: Cardinal read GetPrimitiveRestartIndex write SetPrimitiveRestartIndex;
  548. // The currently bound texture buffer object (TBO)
  549. property TextureBufferBinding: Cardinal read FTextureBufferBinding write SetTextureBufferBinding;
  550. // Transformation state
  551. property ViewPort: TVector4i read FViewPort write SetViewPort;
  552. // Modifies the near + far clipping planes
  553. procedure SetDepthRange(const ZNear, ZFar: TGLclampd); inline;
  554. // The near clipping plane distance
  555. property DepthRangeNear: TGLclampd read GetDepthRangeNear write SetDepthRangeNear;
  556. // The far clipping plane distance
  557. property DepthRangeFar: TGLclampd read GetDepthRangeFar write SetDepthRangeFar;
  558. // Enables/Disables each of the clip distances, used in shaders
  559. property EnableClipDistance[Index: Cardinal]: TGLboolean read GetEnableClipDistance write SetEnableClipDistance;
  560. // Enables/Disables depth clamping
  561. property EnableDepthClamp: TGLboolean read FEnableDepthClamp write SetEnableDepthClamp;
  562. // Coloring state Controls read color clamping
  563. property ClampReadColor: Cardinal read FClampReadColor write SetClampReadColor;
  564. (* The provoking vertex used in flat shading. All the vertices of each
  565. primitive will the same value determined by this property. *)
  566. property ProvokingVertex: Cardinal read FProvokingVertex write SetProvokingVertex;
  567. // Rasterization state
  568. (* The default point size, used when EnableProgramPointSize = false *)
  569. property PointSize: TGLfloat read FPointSize write SetPointSize;
  570. // If multisampling is enabled, this can control when points are faded out
  571. property PointFadeThresholdSize: TGLfloat read FPointFadeThresholdSize write SetPointFadeThresholdSize;
  572. // The texture coordinate origin of point sprites
  573. property PointSpriteCoordOrigin: Cardinal read FPointSpriteCoordOrigin write SetPointSpriteCoordOrigin;
  574. // The line width
  575. property LineWidth: TGLfloat read FLineWidth write SetLineWidth;
  576. // The line stipple
  577. property LineStippleFactor: TGLint read FLineStippleFactor write SetLineStippleFactor;
  578. // The line stipple
  579. property LineStipplePattern: TGLushort read FLineStipplePattern write SetLineStipplePattern;
  580. // Enable/Disable line smoothing
  581. property EnableLineSmooth: TGLboolean read FEnableLineSmooth write SetEnableLineSmooth;
  582. // Enable/Disable face culling
  583. property EnableCullFace: TGLboolean read FEnableCullFace write SetEnableCullFace;
  584. // Selects which faces to cull: front, back or front+back
  585. property CullFaceMode: TGLCullFaceMode read FCullFaceMode write SetCullFaceMode;
  586. // The winding direction that indicates a front facing primitive
  587. property FrontFace: { Cardinal } TGLFaceWinding read FFrontFace write SetFrontFace;
  588. // Enables/Disables polygon smoothing.
  589. property EnablePolygonSmooth: TGLboolean read FEnablePolygonSmooth write SetEnablePolygonSmooth;
  590. // Whether polygons appear filled, lines or points
  591. property PolygonMode: TGLPolygonMode read FPolygonMode write SetPolygonMode;
  592. // Scales the maximum depth of the polygon
  593. property PolygonOffsetFactor: TGLfloat read FPolygonOffsetFactor write SetPolygonOffsetFactor;
  594. // Scales an implementation-dependent constant that relates to the usable resolution of the depth buffer
  595. property PolygonOffsetUnits: TGLfloat read FPolygonOffsetUnits write SetPolygonOffsetUnits;
  596. // Set polygon offset
  597. procedure SetPolygonOffset(const factor, units: TGLfloat);
  598. // Enable/Disable polygon offset for polygons in point mode
  599. property EnablePolygonOffsetPoint: TGLboolean read FEnablePolygonOffsetPoint write SetEnablePolygonOffsetPoint;
  600. // Enable/Disable polygon offset for polygons in line mode
  601. property EnablePolygonOffsetLine: TGLboolean read FEnablePolygonOffsetLine write SetEnablePolygonOffsetLine;
  602. // Enable/Disable polygon offset for polygons in fill mode
  603. property EnablePolygonOffsetFill: TGLboolean read FEnablePolygonOffsetFill write SetEnablePolygonOffsetFill;
  604. // Multisample state
  605. // Enable/Disable multisampling
  606. property EnableMultisample: TGLboolean read FEnableMultisample write SetEnableMultisample;
  607. // Enable/Disable sample alpha to coverage
  608. property EnableSampleAlphaToCoverage: TGLboolean read FEnableSampleAlphaToCoverage write SetEnableSampleAlphaToCoverage;
  609. // Enable/Disable sample alpha to one
  610. property EnableSampleAlphaToOne: TGLboolean read FEnableSampleAlphaToOne write SetEnableSampleAlphaToOne;
  611. // Enable/Disable sample coverage
  612. property EnableSampleCoverage: TGLboolean read FEnableSampleCoverage write SetEnableSampleCoverage;
  613. // Sample coverage Value
  614. property SampleCoverageValue: TGLfloat read FSampleCoverageValue write SetSampleCoverageValue;
  615. // Inverts sample coverage Value
  616. property SampleCoverageInvert: TGLboolean read FSampleCoverageInvert write SetSampleCoverageInvert;
  617. // Set sample coverage
  618. procedure SetSampleCoverage(const Value: TGLfloat; invert: TGLboolean);
  619. // Enable/Disable sample mask
  620. property EnableSampleMask: TGLboolean read FEnableSampleMask write SetEnableSampleMask;
  621. // Sample mask values
  622. property SampleMaskValue[Index: Integer]: TGLbitfield read GetSampleMaskValue write SetSampleMaskValue;
  623. // Textures
  624. // Textures bound to each texture unit + binding point.
  625. property TextureBinding[Index: Integer; target: TGLTextureTarget]: Cardinal read GetTextureBinding write SetTextureBinding;
  626. property TextureBindingTime[Index: Integer; target: TGLTextureTarget]: Double read GetTextureBindingTime;
  627. property ActiveTextureEnabled[target: TGLTextureTarget]: Boolean read GetActiveTextureEnabled write SetActiveTextureEnabled;
  628. property SamplerBinding[Index: Cardinal]: Cardinal read GetSamplerBinding write SetSamplerBinding;
  629. property MaxTextureSize: Cardinal read GetMaxTextureSize;
  630. property Max3DTextureSize: Cardinal read GetMax3DTextureSize;
  631. property MaxCubeTextureSize: Cardinal read GetMaxCubeTextureSize;
  632. property MaxArrayTextureSize: Cardinal read GetMaxArrayTextureSize;
  633. property MaxTextureImageUnits: Cardinal read GetMaxTextureImageUnits;
  634. property MaxTextureAnisotropy: Cardinal read GetMaxTextureAnisotropy;
  635. property MaxSamples: Cardinal read GetMaxSamples;
  636. // TODO: GL_TEXTURE_BUFFER_DATA_STORE_BINDING ?
  637. // Active texture
  638. (* The active texture unit. Valid values are 0 .. Max texture units. *)
  639. property ActiveTexture: TGLint read FActiveTexture write SetActiveTexture;
  640. // Pixel operations
  641. (* Enables/Disables scissor test. *)
  642. property EnableScissorTest: TGLboolean read FEnableScissorTest write SetEnableScissorTest;
  643. // The bounding box used in scissor test.
  644. property ScissorBox: TVector4i read FScissorBox write SetScissorBox;
  645. // Enables/Disables stencil test.
  646. property EnableStencilTest: TGLboolean read FEnableStencilTest write SetEnableStencilTest;
  647. (* The stencil function. Determines the comparison function to be used
  648. when comparing the reference + stored stencil values. *)
  649. property StencilFunc: TGLStencilFunction read FStencilFunc;
  650. // write SetStencilFunc;
  651. (* The stencil value mask. Masks both the reference + stored stencil values *)
  652. property StencilValueMask: Cardinal read FStencilValueMask;
  653. // write SetStencilValueMask;
  654. (* The stencil reference value. Clamped to 0..255 with an 8 bit stencil. *)
  655. property StencilRef: TGLint read FStencilRef; // write SetStencilRef;
  656. // The operation to perform when stencil test fails.
  657. property StencilFail: TGLStencilOp read FStencilFail; // write SetStencilFail;
  658. // The operation to perform when stencil test passes + depth test fails.
  659. property StencilPassDepthFail: TGLStencilOp read FStencilPassDepthFail;
  660. // write SetStencilPassDepthFail;
  661. (* The operation to perform when stencil test passes + depth test passes. *)
  662. property StencilPassDepthPass: TGLStencilOp read FStencilPassDepthPass;
  663. // write SetStencilPassDepthPass;
  664. (* The stencil back function. Determines the comparison function to be
  665. used when comparing the reference + stored stencil values on back facing primitives. *)
  666. property StencilBackFunc: TGLStencilFunction read FStencilBackFunc;
  667. // write SetStencilBackFunc;
  668. (* The stencil back value mask. Masks both the reference + stored stencil values. *)
  669. property StencilBackValueMask: Cardinal read FStencilBackValueMask;
  670. // write SetStencilBackValueMask;
  671. (* The stencil back reference value. Clamped to 0..255 with an 8 bit stencil. *)
  672. property StencilBackRef: Cardinal read FStencilBackRef;
  673. // write SetStencilBackRef;
  674. (* The operation to perform when stencil test fails on back facing primitives. *)
  675. property StencilBackFail: TGLStencilOp read FStencilBackFail;
  676. // write SetStencilBackFail;
  677. (* The operation to perform when stencil test passes + depth test fails on
  678. back facing primitives. *)
  679. property StencilBackPassDepthFail: TGLStencilOp read FStencilBackPassDepthFail;
  680. // write SetStencilBackPassDepthFail;
  681. (* The operation to perform when stencil test passes + depth test passes on
  682. back facing primitives. *)
  683. property StencilBackPassDepthPass: TGLStencilOp read FStencilBackPassDepthPass;
  684. // write SetStencilBackPassDepthPass;
  685. (* Used to set stencil Function, Reference + Mask values, for both front +
  686. back facing primitives. *)
  687. procedure SetStencilFunc(const func: TGLStencilFunction; const ref: TGLint; const mask: Cardinal); inline;
  688. (* Used to set stencil Function, Reference + Mask values for either the
  689. front or back facing primitives (or both, which is the same as calling
  690. SetStencilFunc). *)
  691. procedure SetStencilFuncSeparate(const face: TGLCullFaceMode; const func: TGLStencilFunction; const ref: TGLint;
  692. const mask: Cardinal); inline;
  693. // Used to set the StencilFail, StencilPassDepthFail + StencilPassDepthPass in one go.
  694. procedure SetStencilOp(const fail, zfail, zpass: TGLStencilOp); inline;
  695. (* Used to set the StencilFail, StencilPassDepthFail + StencilPassDepthPass
  696. in one go, for either front or back facing primitives. *)
  697. procedure SetStencilOpSeparate(const face: TGLCullFaceMode; const sfail, dpfail, dppass: TGLStencilOp); inline;
  698. // Enables/disables depth testing.
  699. property EnableDepthTest: TGLboolean read FEnableDepthTest write SetEnableDepthTest;
  700. (* The depth function. Used to determine whether to keep a fragment or
  701. discard it, depending on the current value stored in the depth buffer. *)
  702. property DepthFunc: TGLDepthFunction read FDepthFunc write SetDepthFunc;
  703. // Enables/disables blending for each draw buffer.
  704. property EnableBlend[Index: Integer]: TGLboolean read GetEnableBlend write SetEnableBlend;
  705. // The weighting factor used in blending equation, for source RGB.
  706. property BlendSrcRGB: TGLBlendFunction read FBlendSrcRGB;
  707. // write SetBlendSrcRGB;
  708. (* The weighting factor used in blending equation, for source alpha. *)
  709. property BlendSrcAlpha: TGLBlendFunction read FBlendSrcAlpha;
  710. // write SetBlendSrcAlpha;
  711. (* The weighting factor used in blending equation, for destination RGB. *)
  712. property BlendDstRGB: TGLDstBlendFunction read FBlendDstRGB;
  713. // write SetBlendDstRGB;
  714. (* The weighting factor used in blending equation, for destination alpha. *)
  715. property BlendDstAlpha: TGLDstBlendFunction read FBlendDstAlpha;
  716. // write SetBlendDstAlpha;
  717. (* Sets the weighting factors to be used by the blending equation, for both color + alpha *)
  718. procedure SetBlendFunc(const Src: TGLBlendFunction; const Dst: TGLDstBlendFunction); inline;
  719. (* Sets the weighting factors to be used by the blending equation, with
  720. separate values used for color + alpha components. *)
  721. procedure SetBlendFuncSeparate(const SrcRGB: TGLBlendFunction; const DstRGB: TGLDstBlendFunction;
  722. const SrcAlpha: TGLBlendFunction; const DstAlpha: TGLDstBlendFunction); inline;
  723. (* The blending equation. Determines how the incoming source fragment's
  724. RGB are combined with the destination RGB. *)
  725. property BlendEquationRGB: TGLBlendEquation read FBlendEquationRGB;
  726. // write SetBlendEquationRGB;
  727. (* The blending equation. Determines how the incoming source fragment's
  728. alpha values are combined with the destination alpha values. *)
  729. property BlendEquationAlpha: TGLBlendEquation read FBlendEquationAlpha;
  730. // write SetBlendEquationAlpha;
  731. // Sets the blend equation for RGB + alpha to the same value.
  732. procedure SetBlendEquation(const mode: TGLBlendEquation); inline;
  733. // Sets the blend equations for RGB + alpha separately.
  734. procedure SetBlendEquationSeparate(const modeRGB, modeAlpha: TGLBlendEquation); inline;
  735. // A constant blend color, that can be used in the blend equation.
  736. property BlendColor: TGLVector read FBlendColor write SetBlendColor;
  737. // Enables/disables framebuffer SRGB.
  738. property EnableFramebufferSRGB: TGLboolean read FEnableFramebufferSRGB write SetEnableFramebufferSRGB;
  739. // Enables/disables dithering.
  740. property EnableDither: TGLboolean read FEnableDither write SetEnableDither;
  741. // Enables/disables color logic op.
  742. property EnableColorLogicOp: TGLboolean read FEnableColorLogicOp write SetEnableColorLogicOp;
  743. // Logic op mode.
  744. property LogicOpMode: TGLLogicOp read FLogicOpMode write SetLogicOpMode;
  745. // The color write mask, for each draw buffer.
  746. property ColorWriteMask[Index: Integer]: TGLColorMask read GetColorWriteMask write SetColorWriteMask;
  747. // Set the color write mask for all draw buffers.
  748. procedure SetColorMask(mask: TGLColorMask); inline;
  749. // The depth write mask.
  750. property DepthWriteMask: TGLboolean read FDepthWriteMask write SetDepthWriteMask;
  751. // The stencil write mask.
  752. property StencilWriteMask: Cardinal read FStencilWriteMask write SetStencilWriteMask;
  753. // The stencil back write mask.
  754. property StencilBackWriteMask: Cardinal read FStencilBackWriteMask write SetStencilBackWriteMask;
  755. // The color clear value.
  756. property ColorClearValue: TGLVector read FColorClearValue write SetColorClearValue;
  757. // The depth clear value.
  758. property DepthClearValue: TGLfloat read FDepthClearValue write SetDepthClearValue;
  759. // The stencil clear value.
  760. property StencilClearValue: Cardinal read FStencilClearValue write SetStencilClearValue;
  761. // Framebuffer to be used for draw operations, 0 = default framebuffer.
  762. property DrawFrameBuffer: Cardinal read FDrawFrameBuffer write SetDrawFrameBuffer;
  763. // Framebuffer to be used for read operations, 0 = default framebuffer.
  764. property ReadFrameBuffer: Cardinal read FReadFrameBuffer write SetReadFrameBuffer;
  765. // set both draw + read framebuffer.
  766. procedure SetFrameBuffer(const Value: Cardinal); inline;
  767. // property FrameBuffer: Cardinal read FDrawFrameBuffer write SetFrameBuffer;
  768. // Renderbuffer currently bound render buffer.
  769. property RenderBuffer: Cardinal read FRenderBuffer write SetRenderBuffer;
  770. // Pixels
  771. (* Controls whether byte swapping occurs during pixel unpacking. *)
  772. property UnpackSwapBytes: TGLboolean read FUnpackSwapBytes write SetUnpackSwapBytes;
  773. // Whether unpacked data is required with LSB (least significant bit) first.
  774. property UnpackLSBFirst: TGLboolean read FUnpackLSBFirst write SetUnpackLSBFirst;
  775. // Unpack image height
  776. property UnpackImageHeight: Cardinal read FUnpackImageHeight write SetUnpackImageHeight;
  777. // Unpack skip images
  778. property UnpackSkipImages: Cardinal read FUnpackSkipImages write SetUnpackSkipImages;
  779. // Unpack row length
  780. property UnpackRowLength: Cardinal read FUnpackRowLength write SetUnpackRowLength;
  781. // Unpack skip rows
  782. property UnpackSkipRows: Cardinal read FUnpackSkipRows write SetUnpackSkipRows;
  783. // Unpack skip pixels
  784. property UnpackSkipPixels: Cardinal read FUnpackSkipPixels write SetUnpackSkipPixels;
  785. // Unpack alignment
  786. property UnpackAlignment: Cardinal read FUnpackAlignment write SetUnpackAlignment;
  787. // Controls whether byte swapping occurs during pixel packing
  788. property PackSwapBytes: TGLboolean read FPackSwapBytes write SetPackSwapBytes;
  789. // Whether packed data is required with LSB (least significant bit) first
  790. property PackLSBFirst: TGLboolean read FPackLSBFirst write SetPackLSBFirst;
  791. // Pack image height
  792. property PackImageHeight: Cardinal read FPackImageHeight write SetPackImageHeight;
  793. // Pack skip images
  794. property PackSkipImages: Cardinal read FPackSkipImages write SetPackSkipImages;
  795. // Pack row length
  796. property PackRowLength: Cardinal read FPackRowLength write SetPackRowLength;
  797. // Pack skip rows
  798. property PackSkipRows: Cardinal read FPackSkipRows write SetPackSkipRows;
  799. // Pack skip pixels
  800. property PackSkipPixels: Cardinal read FPackSkipPixels write SetPackSkipPixels;
  801. // Pack alignment
  802. property PackAlignment: Cardinal read FPackAlignment write SetPackAlignment;
  803. // Buffer bound for pixel packing (eg. ReadPixels)
  804. property PixelPackBufferBinding: Cardinal read FPixelPackBufferBinding write SetPixelPackBufferBinding;
  805. // Buffer bound for pixel unpacking (eg. Tex*Image)
  806. property PixelUnpackBufferBinding: Cardinal read FPixelUnpackBufferBinding write SetPixelUnpackBufferBinding;
  807. // Currently bound program
  808. property CurrentProgram: Cardinal read FCurrentProgram write SetCurrentProgram;
  809. property MaxTextureUnits: Cardinal read GetMaxTextureUnits;
  810. // Currently bound uniform buffer
  811. property UniformBufferBinding: Cardinal read FUniformBufferBinding write SetUniformBufferBinding;
  812. procedure SetBufferIndexedBinding(const Value: Cardinal; ATarget: TGLBufferBindingTarget; AIndex: Cardinal;
  813. ABufferSize: TGLsizeiptr); overload; inline;
  814. procedure SetBufferIndexedBinding(const Value: Cardinal; ATarget: TGLBufferBindingTarget; AIndex: Cardinal;
  815. AOffset: TGLintptr; ARangeSize: TGLsizeiptr); overload; inline;
  816. // Default values to be used when a vertex array is not used for that attribute
  817. property CurrentVertexAttrib[Index: Integer]: TGLVector read GetCurrentVertexAttrib write SetCurrentVertexAttrib;
  818. // Enables/disables program point size
  819. property EnableProgramPointSize: TGLboolean read FEnableProgramPointSize write SetEnableProgramPointSize;
  820. // Currently bound transform feedbac buffer
  821. property TransformFeedbackBufferBinding: Cardinal read FTransformFeedbackBufferBinding
  822. write SetTransformFeedbackBufferBinding;
  823. // Line smooth hint
  824. property LineSmoothHint: TGLHintType read FLineSmoothHint write SetLineSmoothHint;
  825. // Polygon smooth hint
  826. property PolygonSmoothHint: TGLHintType read FPolygonSmoothHint write SetPolygonSmoothHint;
  827. // Texture compression hint
  828. property TextureCompressionHint: TGLHintType read FTextureCompressionHint write SetTextureCompressionHint;
  829. // Fragment shader derivitive hint
  830. property FragmentShaderDerivitiveHint: TGLHintType read FFragmentShaderDerivitiveHint write SetFragmentShaderDerivitiveHint;
  831. property MultisampleFilterHint: TGLHintType read FMultisampleFilterHint write SetMultisampleFilterHint;
  832. // Current queries. Misc
  833. property CurrentQuery[Index: TGLQueryType]: Cardinal read GetCurrentQuery;
  834. // Begins a query of "Target" type. "Value" must be a valid query object
  835. procedure BeginQuery(const target: TGLQueryType; const Value: Cardinal); inline;
  836. // Ends current query of type "Target"
  837. procedure EndQuery(const target: TGLQueryType); inline;
  838. (* The buffer currently bound to the copy read buffer binding point, this
  839. is an extra binding point provided so that you don't need to overwrite
  840. other binding points to copy between buffers. *)
  841. property CopyReadBufferBinding: Cardinal read FCopyReadBufferBinding write SetCopyReadBufferBinding;
  842. (* The buffer currently bound to the copy write buffer binding point, this
  843. is an extra binding point provided so that you don't need to overwrite
  844. other binding points to copy between buffers. *)
  845. property CopyWriteBufferBinding: Cardinal read FCopyWriteBufferBinding write SetCopyWriteBufferBinding;
  846. // Enables/Disables seamless texture cube maps
  847. property EnableTextureCubeMapSeamless: TGLboolean read FEnableTextureCubeMapSeamless write SetEnableTextureCubeMapSeamless;
  848. // Indicates the current presence within the list
  849. property InsideList: Boolean read FInsideList;
  850. // Begin new display list
  851. procedure NewList(list: Cardinal; mode: Cardinal); inline;
  852. // End display list
  853. procedure EndList; inline;
  854. // Call display list
  855. procedure CallList(list: Cardinal); inline;
  856. // Defines the OpenGL texture matrix. Assumed texture mode is GL_MODELVIEW.
  857. procedure SetTextureMatrix(const matrix: TGLMatrix); inline;
  858. procedure ResetTextureMatrix; inline;
  859. procedure ResetAllTextureMatrix; inline;
  860. // note: needs to change to per draw-buffer
  861. procedure SetColorWriting(flag: Boolean); inline;
  862. // Inverts front face winding (CCW/CW)
  863. procedure InvertFrontFace; inline;
  864. // read only properties
  865. property States: TGLStates read FStates;
  866. // True for ignore deprecated and removed features in OpenGL 3x
  867. (* property ForwardContext: Boolean read FForwardContext write SetForwardContext; *)
  868. end;
  869. type
  870. TStateRecord = record
  871. GLConst: Cardinal;
  872. GLDeprecated: Boolean;
  873. end;
  874. const
  875. {$WARN SYMBOL_DEPRECATED OFF}
  876. cGLStateTypeToGLEnum: array [TGLStateType] of Cardinal = (
  877. GL_CURRENT_BIT, GL_POINT_BIT, GL_LINE_BIT, GL_POLYGON_BIT,
  878. GL_POLYGON_STIPPLE_BIT, GL_PIXEL_MODE_BIT, GL_LIGHTING_BIT, GL_FOG_BIT,
  879. GL_DEPTH_BUFFER_BIT, GL_ACCUM_BUFFER_BIT, GL_STENCIL_BUFFER_BIT,
  880. GL_VIEWPORT_BIT, GL_TRANSFORM_BIT, GL_ENABLE_BIT, GL_COLOR_BUFFER_BIT,
  881. GL_HINT_BIT, GL_EVAL_BIT, GL_LIST_BIT, GL_TEXTURE_BIT, GL_SCISSOR_BIT,
  882. GL_MULTISAMPLE_BIT);
  883. {$WARN SYMBOL_DEPRECATED ON}
  884. cGLStateToGLEnum: array[TGLState] of TStateRecord =
  885. ((GLConst: GL_ALPHA_TEST; GLDeprecated: True),
  886. (GLConst: GL_AUTO_NORMAL; GLDeprecated: True),
  887. (GLConst: GL_BLEND; GLDeprecated: False),
  888. (GLConst: GL_COLOR_MATERIAL; GLDeprecated: True),
  889. (GLConst: GL_CULL_FACE; GLDeprecated: False),
  890. (GLConst: GL_DEPTH_TEST; GLDeprecated: False),
  891. (GLConst: GL_DITHER; GLDeprecated: False),
  892. (GLConst: GL_FOG; GLDeprecated: True),
  893. (GLConst: GL_LIGHTING; GLDeprecated: True),
  894. (GLConst: GL_LINE_SMOOTH; GLDeprecated: True),
  895. (GLConst: GL_LINE_STIPPLE; GLDeprecated: True),
  896. (GLConst: GL_INDEX_LOGIC_OP; GLDeprecated: True),
  897. (GLConst: GL_COLOR_LOGIC_OP; GLDeprecated: False),
  898. (GLConst: GL_NORMALIZE; GLDeprecated: True),
  899. (GLConst: GL_POINT_SMOOTH; GLDeprecated: True),
  900. (GLConst: GL_POINT_SPRITE; GLDeprecated: True),
  901. (GLConst: GL_POLYGON_SMOOTH; GLDeprecated: True),
  902. (GLConst: GL_POLYGON_STIPPLE; GLDeprecated: True),
  903. (GLConst: GL_SCISSOR_TEST; GLDeprecated: False),
  904. (GLConst: GL_STENCIL_TEST; GLDeprecated: False),
  905. (GLConst: GL_POLYGON_OFFSET_POINT; GLDeprecated: False),
  906. (GLConst: GL_POLYGON_OFFSET_LINE; GLDeprecated: False),
  907. (GLConst: GL_POLYGON_OFFSET_FILL; GLDeprecated: False),
  908. (GLConst: GL_DEPTH_CLAMP; GLDeprecated: False)
  909. );
  910. cGLTexTypeToGLEnum: array[TGLTextureTarget] of Cardinal =
  911. (0, GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_1D_ARRAY,
  912. GL_TEXTURE_2D_ARRAY, GL_TEXTURE_RECTANGLE, GL_TEXTURE_BUFFER,
  913. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D_MULTISAMPLE,
  914. GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY);
  915. cGLQueryTypeToGLEnum: array[TGLQueryType] of Cardinal =
  916. (GL_SAMPLES_PASSED, GL_PRIMITIVES_GENERATED,
  917. GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN,
  918. GL_TIME_ELAPSED, GL_ANY_SAMPLES_PASSED);
  919. cGLStencilOpToGLEnum: array[TGLStencilOp] of Cardinal =
  920. (GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT, GL_INCR_WRAP,
  921. GL_DECR_WRAP);
  922. cGLLogicOpToGLEnum: array[TGLLogicOp] of Cardinal =
  923. (GL_CLEAR, GL_AND, GL_AND_REVERSE, GL_COPY, GL_AND_INVERTED, GL_NOOP,
  924. GL_XOR, GL_OR, GL_NOR, GL_EQUIV, GL_INVERT, GL_OR_REVERSE,
  925. GL_COPY_INVERTED, GL_OR_INVERTED, GL_NAND, GL_SET);
  926. cGLComparisonFunctionToGLEnum: array[TGLComparisonFunction] of Cardinal =
  927. (GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GREATER,
  928. GL_NOTEQUAL, GL_GEQUAL);
  929. cGLBlendFunctionToGLEnum: array[TGLBlendFunction] of Cardinal =
  930. (GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR,
  931. GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
  932. GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_CONSTANT_COLOR,
  933. GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_ALPHA,
  934. GL_ONE_MINUS_CONSTANT_ALPHA, GL_SRC_ALPHA_SATURATE {valid for src only});
  935. cGLBlendEquationToGLEnum: array[TGLBlendEquation] of Cardinal =
  936. (GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MIN,
  937. GL_MAX);
  938. cGLFaceWindingToGLEnum: array[TGLFaceWinding] of Cardinal =
  939. (GL_CCW, GL_CW);
  940. cGLPolygonModeToGLEnum: array[TGLPolygonMode] of Cardinal =
  941. (GL_FILL, GL_LINE, GL_POINT);
  942. cGLCullFaceModeToGLEnum: array[TGLCullFaceMode] of Cardinal =
  943. (GL_FRONT, GL_BACK, GL_FRONT_AND_BACK);
  944. cGLHintToGLEnum: array[TGLHintType] of Cardinal =
  945. (GL_DONT_CARE, GL_FASTEST, GL_NICEST);
  946. cGLBufferBindingTarget: array[TGLBufferBindingTarget] of Cardinal =
  947. (GL_UNIFORM_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER);
  948. //------------------------------------------------------
  949. implementation
  950. // ------------------------------------------------------
  951. uses
  952. GLS.Context,
  953. GLS.Color;
  954. // ------------------
  955. // ------------------ TGLStateCache ------------------
  956. // ------------------
  957. procedure TGLStateCache.BeginQuery(const target: TGLQueryType; const Value: Cardinal);
  958. begin
  959. Assert(FCurrentQuery[target] = 0, 'Can only have one query (of each type)' + ' running at a time');
  960. // Assert(glIsQuery(Value), 'Not a valid query');
  961. // if Value<>FCurrentQuery[Target] then
  962. begin
  963. FCurrentQuery[target] := Value;
  964. gl.BeginQuery(cGLQueryTypeToGLEnum[target], Value);
  965. end;
  966. end;
  967. constructor TGLStateCache.Create;
  968. var
  969. I: Integer;
  970. begin
  971. inherited;
  972. SetLength(FListStates, $FFFFF);
  973. FCurrentList := 0;
  974. // Material colors
  975. FFrontBackColors[0][0] := clrBlack;
  976. FFrontBackColors[0][1] := clrGray20;
  977. FFrontBackColors[0][2] := clrGray80;
  978. FFrontBackColors[0][3] := clrBlack;
  979. FFrontBackShininess[0] := 0;
  980. FFrontBackColors[1][0] := clrBlack;
  981. FFrontBackColors[1][1] := clrGray20;
  982. FFrontBackColors[1][2] := clrGray80;
  983. FFrontBackColors[1][3] := clrBlack;
  984. FFrontBackShininess[1] := 0;
  985. FAlphaFunc := cfAlways;
  986. // Lighting
  987. FFFPLight := True;
  988. FMaxLights := 0;
  989. FLightNumber := 0;
  990. for I := High(FLightEnabling) downto 0 do
  991. begin
  992. FLightEnabling[I] := False;
  993. FLightIndices[I] := 0;
  994. FLightStates.Position[I] := NullHmgVector;
  995. FLightStates.Ambient[I] := clrBlack;
  996. FLightStates.Diffuse[I] := clrBlack;
  997. FLightStates.Specular[I] := clrBlack;
  998. FLightStates.SpotDirection[I] := VectorMake(0.0, 0.0, -1.0, 0.0);
  999. FSpotCutoff[I] := 180.0;
  1000. FLightStates.SpotCosCutoffExponent[I].X := -1;
  1001. FLightStates.SpotCosCutoffExponent[I].Y := 0;
  1002. FLightStates.Attenuation[I] := NullHmgVector;
  1003. end;
  1004. FLightStates.Diffuse[0] := clrWhite;
  1005. FLightStates.Specular[0] := clrWhite;
  1006. for I := High(FTextureMatrixIsIdentity) downto 0 do
  1007. FTextureMatrixIsIdentity[I] := False;
  1008. // FForwardContext := False;
  1009. // Vertex Array Data state
  1010. FVertexArrayBinding := 0;
  1011. FTextureBufferBinding := 0;
  1012. // Transformation state
  1013. // FViewPort := Rect(0,0,0,0); // (0, 0, Width, Height)
  1014. FDepthRange[0] := 0.0;
  1015. FDepthRange[1] := 1.0;
  1016. FillChar(FEnableClipDistance, sizeof(FEnableClipDistance), $00);
  1017. FEnableDepthClamp := False;
  1018. // Coloring state
  1019. FClampReadColor := GL_FIXED_ONLY;
  1020. FProvokingVertex := GL_LAST_VERTEX_CONVENTION;
  1021. // Rasterization state
  1022. FPointSize := 1.0;
  1023. FPointFadeThresholdSize := 1.0;
  1024. FPointSpriteCoordOrigin := GL_UPPER_LEFT;
  1025. FLineWidth := 1.0;
  1026. FLineStippleFactor := 1;
  1027. FLineStipplePattern := $FFFF;
  1028. FEnableLineSmooth := False;
  1029. FEnableCullFace := False;
  1030. FCullFaceMode := cmBack;
  1031. FFrontFace := fwCounterClockWise;
  1032. FEnablePolygonSmooth := False;
  1033. FPolygonMode := pmFill;
  1034. FPolygonOffsetFactor := 0.0;
  1035. FPolygonOffsetUnits := 0.0;
  1036. FEnablePolygonOffsetPoint := False;
  1037. FEnablePolygonOffsetLine := False;
  1038. FEnablePolygonOffsetFill := False;
  1039. // Multisample state
  1040. FEnableMultisample := True;
  1041. FEnableSampleAlphaToCoverage := False;
  1042. FEnableSampleAlphaToOne := False;
  1043. FEnableSampleCoverage := False;
  1044. FSampleCoverageValue := 1.0;
  1045. FSampleCoverageInvert := False;
  1046. FEnableSampleMask := False;
  1047. FillChar(FSampleMaskValue, sizeof(FSampleMaskValue), $FF);
  1048. // Texture state
  1049. FillChar(FTextureBinding, sizeof(FTextureBinding), $00);
  1050. FillChar(FActiveTextureEnabling, sizeof(FActiveTextureEnabling), $00);
  1051. // Active texture state
  1052. FActiveTexture := 0;
  1053. // Pixel operation state
  1054. FEnableScissorTest := False;
  1055. // FScissorBox := Rect(0, 0, Width, Height);
  1056. FEnableStencilTest := False;
  1057. FStencilFunc := cfAlways;
  1058. FStencilValueMask := $FFFFFFFF;
  1059. FStencilRef := 0;
  1060. FStencilFail := soKeep;
  1061. FStencilPassDepthFail := soKeep;
  1062. FStencilPassDepthPass := soKeep;
  1063. FStencilBackFunc := cfAlways;
  1064. FStencilBackValueMask := $FFFFFFFF;
  1065. FStencilBackRef := 0;
  1066. FStencilBackFail := soKeep;
  1067. FStencilBackPassDepthPass := soKeep;
  1068. FStencilBackPassDepthFail := soKeep;
  1069. FEnableDepthTest := False;
  1070. FDepthFunc := cfLess;
  1071. FillChar(FEnableBlend, sizeof(FEnableBlend), $0);
  1072. FBlendSrcRGB := bfOne;
  1073. FBlendSrcAlpha := bfOne;
  1074. FBlendDstRGB := bfZero;
  1075. FBlendDstAlpha := bfZero;
  1076. FBlendEquationRGB := beAdd;
  1077. FBlendEquationAlpha := beAdd;
  1078. FBlendColor := NullHmgVector;
  1079. FEnableFramebufferSRGB := False;
  1080. FEnableDither := True;
  1081. FEnableColorLogicOp := False;
  1082. FLogicOpMode := loCopy;
  1083. // Framebuffer control state
  1084. // for I := 0 to Length(FColorWriteMask) - 1 do
  1085. // FColorWriteMask[i] := [ccRed, ccGreen, ccBlue, ccAlpha];
  1086. FillChar(FColorWriteMask, sizeof(FColorWriteMask), $F);
  1087. FDepthWriteMask := True;
  1088. FStencilWriteMask := $FFFFFFFF;
  1089. FStencilBackWriteMask := $FFFFFFFF;
  1090. FColorClearValue := NullHmgVector;
  1091. FDepthClearValue := 1.0;
  1092. FStencilClearValue := 0;
  1093. // Framebuffer state
  1094. FDrawFrameBuffer := 0;
  1095. FReadFrameBuffer := 0;
  1096. // Renderbuffer state
  1097. FRenderBuffer := 0;
  1098. // Pixels state
  1099. FUnpackSwapBytes := False;
  1100. FUnpackLSBFirst := False;
  1101. FUnpackImageHeight := 0;
  1102. FUnpackSkipImages := 0;
  1103. FUnpackRowLength := 0;
  1104. FUnpackSkipRows := 0;
  1105. FUnpackSkipPixels := 0;
  1106. FUnpackAlignment := 4;
  1107. FPackSwapBytes := False;
  1108. FPackLSBFirst := False;
  1109. FPackImageHeight := 0;
  1110. FPackSkipImages := 0;
  1111. FPackRowLength := 0;
  1112. FPackSkipRows := 0;
  1113. FPackSkipPixels := 0;
  1114. FPackAlignment := 4;
  1115. FPixelPackBufferBinding := 0;
  1116. FPixelUnpackBufferBinding := 0;
  1117. // Program state
  1118. FCurrentProgram := 0;
  1119. FUniformBufferBinding := 0;
  1120. FillChar(FUBOStates[bbtUniform][0], SizeOf(FUBOStates), $00);
  1121. // Vector + Geometry Shader state
  1122. for I := 0 to Length(FCurrentVertexAttrib) - 1 do
  1123. FCurrentVertexAttrib[I] := NullHmgPoint;
  1124. FEnableProgramPointSize := False;
  1125. // Transform Feedback state
  1126. FTransformFeedbackBufferBinding := 0;
  1127. // Hints state
  1128. FTextureCompressionHint := hintDontCare;
  1129. FPolygonSmoothHint := hintDontCare;
  1130. FFragmentShaderDerivitiveHint := hintDontCare;
  1131. FLineSmoothHint := hintDontCare;
  1132. // Misc state
  1133. FillChar(FCurrentQuery, sizeof(FCurrentQuery), $00);
  1134. FCopyReadBufferBinding := 0;
  1135. FCopyWriteBufferBinding := 0;
  1136. FEnableTextureCubeMapSeamless := False;
  1137. FInsideList := False;
  1138. end;
  1139. destructor TGLStateCache.Destroy;
  1140. begin
  1141. inherited;
  1142. end;
  1143. procedure TGLStateCache.EndQuery(const target: TGLQueryType);
  1144. begin
  1145. Assert(FCurrentQuery[target] <> 0, 'No query running');
  1146. FCurrentQuery[target] := 0;
  1147. gl.EndQuery(cGLQueryTypeToGLEnum[target]);
  1148. end;
  1149. procedure TGLStateCache.Enable(const aState: TGLState);
  1150. begin
  1151. { if cGLStateToGLEnum[aState].GLDeprecated and FForwardContext then
  1152. exit; }
  1153. if not(aState in FStates) or FInsideList then
  1154. begin
  1155. if FInsideList then
  1156. Include(FListStates[FCurrentList], sttEnable)
  1157. else
  1158. Include(FStates, aState);
  1159. {$IFDEF USE_CACHE_MISS_CHECK}
  1160. if gl.IsEnabled(cGLStateToGLEnum[aState].GLConst) then
  1161. GLSLogger.LogError(strStateCashMissing + 'Enable');
  1162. {$ENDIF}
  1163. gl.Enable(cGLStateToGLEnum[aState].GLConst);
  1164. end;
  1165. end;
  1166. procedure TGLStateCache.Disable(const aState: TGLState);
  1167. begin
  1168. { if cGLStateToGLEnum[aState].GLDeprecated and FForwardContext then
  1169. exit; }
  1170. if (aState in FStates) or FInsideList then
  1171. begin
  1172. if FInsideList then
  1173. Include(FListStates[FCurrentList], sttEnable)
  1174. else
  1175. Exclude(FStates, aState);
  1176. {$IFDEF USE_CACHE_MISS_CHECK}
  1177. if not gl.IsEnabled(cGLStateToGLEnum[aState].GLConst) then
  1178. GLSLogger.LogError(strStateCashMissing + 'Disable');
  1179. {$ENDIF}
  1180. gl.Disable(cGLStateToGLEnum[aState].GLConst);
  1181. if aState = stColorMaterial then
  1182. if FInsideList then
  1183. Include(FListStates[FCurrentList], sttLighting)
  1184. else
  1185. begin
  1186. gl.Materialfv(GL_FRONT, GL_EMISSION, @FFrontBackColors[0][0]);
  1187. gl.Materialfv(GL_FRONT, GL_AMBIENT, @FFrontBackColors[0][1]);
  1188. gl.Materialfv(GL_FRONT, GL_DIFFUSE, @FFrontBackColors[0][2]);
  1189. gl.Materialfv(GL_FRONT, GL_SPECULAR, @FFrontBackColors[0][3]);
  1190. gl.Materiali(GL_FRONT, GL_SHININESS, FFrontBackShininess[0]);
  1191. gl.Materialfv(GL_BACK, GL_EMISSION, @FFrontBackColors[1][0]);
  1192. gl.Materialfv(GL_BACK, GL_AMBIENT, @FFrontBackColors[1][1]);
  1193. gl.Materialfv(GL_BACK, GL_DIFFUSE, @FFrontBackColors[1][2]);
  1194. gl.Materialfv(GL_BACK, GL_SPECULAR, @FFrontBackColors[1][3]);
  1195. gl.Materiali(GL_BACK, GL_SHININESS, FFrontBackShininess[1]);
  1196. end;
  1197. end;
  1198. end;
  1199. procedure TGLStateCache.PerformEnable(const aState: TGLState);
  1200. begin
  1201. { if cGLStateToGLEnum[aState].GLDeprecated and FForwardContext then
  1202. exit; }
  1203. Include(FStates, aState);
  1204. gl.Enable(cGLStateToGLEnum[aState].GLConst);
  1205. end;
  1206. procedure TGLStateCache.PerformDisable(const aState: TGLState);
  1207. begin
  1208. { if cGLStateToGLEnum[aState].GLDeprecated and FForwardContext then
  1209. exit; }
  1210. Exclude(FStates, aState);
  1211. gl.Disable(cGLStateToGLEnum[aState].GLConst);
  1212. end;
  1213. procedure TGLStateCache.PopAttrib;
  1214. begin
  1215. // TODO: replace with proper client side push/pop
  1216. gl.PopAttrib();
  1217. end;
  1218. procedure TGLStateCache.PushAttrib(const stateTypes: TGLStateTypes);
  1219. var
  1220. tempFlag: Cardinal;
  1221. I: Integer;
  1222. begin
  1223. // TODO: replace with proper client side push/pop
  1224. tempFlag := 0;
  1225. for I := Integer(Low(TGLStateType)) to Integer(high(TGLStateType)) do
  1226. begin
  1227. if TGLStateType(I) in stateTypes then
  1228. begin
  1229. tempFlag := tempFlag or cGLStateTypeToGLEnum[TGLStateType(I)];
  1230. end;
  1231. end;
  1232. gl.PushAttrib(tempFlag);
  1233. end;
  1234. procedure TGLStateCache.SetGLMaterialColors(const aFace: TGLCullFaceMode;
  1235. const emission, ambient, diffuse, specular: TGLVector;
  1236. const shininess: Integer);
  1237. var
  1238. I: Integer;
  1239. currentFace: Cardinal;
  1240. begin
  1241. { if FForwardContext then
  1242. exit; }
  1243. Assert((aFace = cmFront) or (aFace = cmBack), 'Only cmFront or cmBack supported');
  1244. I := Integer(aFace);
  1245. currentFace := cGLCullFaceModeToGLEnum[aFace];
  1246. if FInsideList then
  1247. begin
  1248. gl.Materiali(currentFace, GL_SHININESS, shininess);
  1249. gl.Materialfv(currentFace, GL_EMISSION, @emission);
  1250. gl.Materialfv(currentFace, GL_AMBIENT, @Ambient);
  1251. gl.Materialfv(currentFace, GL_DIFFUSE, @Diffuse);
  1252. gl.Materialfv(currentFace, GL_SPECULAR, @Specular);
  1253. Include(FListStates[FCurrentList], sttLighting);
  1254. end
  1255. else
  1256. begin
  1257. if (FFrontBackShininess[I] <> shininess) then
  1258. begin
  1259. gl.Materiali(currentFace, GL_SHININESS, shininess);
  1260. FFrontBackShininess[I] := shininess;
  1261. end;
  1262. if not AffineVectorEquals(FFrontBackColors[I][0], emission) then
  1263. begin
  1264. gl.Materialfv(currentFace, GL_EMISSION, @emission);
  1265. SetVector(FFrontBackColors[I][0], emission);
  1266. end;
  1267. if not AffineVectorEquals(FFrontBackColors[I][1], Ambient) then
  1268. begin
  1269. gl.Materialfv(currentFace, GL_AMBIENT, @Ambient);
  1270. SetVector(FFrontBackColors[I][1], Ambient);
  1271. end;
  1272. if not VectorEquals(FFrontBackColors[I][2], Diffuse) then
  1273. begin
  1274. gl.Materialfv(currentFace, GL_DIFFUSE, @Diffuse);
  1275. SetVector(FFrontBackColors[I][2], Diffuse);
  1276. end;
  1277. if not AffineVectorEquals(FFrontBackColors[I][3], Specular) then
  1278. begin
  1279. gl.Materialfv(currentFace, GL_SPECULAR, @Specular);
  1280. SetVector(FFrontBackColors[I][3], Specular);
  1281. end;
  1282. end;
  1283. end;
  1284. procedure TGLStateCache.SetGLMaterialAlphaChannel(const aFace: Cardinal; const alpha: TGLfloat);
  1285. var
  1286. I: Integer;
  1287. color: TVector4f;
  1288. begin
  1289. { if FForwardContext then Exit; }
  1290. if not(stLighting in FStates) then
  1291. begin
  1292. // We need a temp variable, because FColor is cauched.
  1293. gl.GetFloatv(GL_CURRENT_COLOR, @color);
  1294. color.W := alpha;
  1295. gl.Color4fv(@color);
  1296. end
  1297. else
  1298. begin
  1299. I := aFace - GL_FRONT;
  1300. if (FFrontBackColors[I][2].W <> alpha) or FInsideList then
  1301. begin
  1302. if FInsideList then
  1303. begin
  1304. Include(FListStates[FCurrentList], sttLighting);
  1305. gl.Materialfv(aFace, GL_DIFFUSE, @FFrontBackColors[I][2]);
  1306. end
  1307. else
  1308. begin
  1309. FFrontBackColors[I][2].W := alpha;
  1310. gl.Materialfv(aFace, GL_DIFFUSE, @FFrontBackColors[I][2]);
  1311. end;
  1312. end;
  1313. end;
  1314. end;
  1315. procedure TGLStateCache.SetGLMaterialDiffuseColor(const aFace: Cardinal; const Diffuse: TGLVector);
  1316. var
  1317. I: Integer;
  1318. begin
  1319. { if FForwardContext then Exit; }
  1320. if not(stLighting in FStates) then
  1321. begin
  1322. gl.Color4fv(@Diffuse);
  1323. end
  1324. else
  1325. begin
  1326. //
  1327. I := aFace - GL_FRONT;
  1328. if (not VectorEquals(FFrontBackColors[I][2], Diffuse)) or FInsideList then
  1329. begin
  1330. if FInsideList then
  1331. begin
  1332. Include(FListStates[FCurrentList], sttLighting);
  1333. gl.Materialfv(aFace, GL_DIFFUSE, @FFrontBackColors[I][2]);
  1334. end
  1335. else
  1336. begin
  1337. FFrontBackColors[I][2] := Diffuse;
  1338. gl.Materialfv(aFace, GL_DIFFUSE, @Diffuse);
  1339. end;
  1340. end;
  1341. end;
  1342. end;
  1343. procedure TGLStateCache.SetActiveTexture(const Value: TGLint);
  1344. begin
  1345. if gl.ARB_multitexture then
  1346. if (Value <> FActiveTexture) or FInsideList then
  1347. begin
  1348. if FInsideList then
  1349. Include(FListStates[FCurrentList], sttTexture)
  1350. else
  1351. FActiveTexture := Value;
  1352. gl.ActiveTexture(GL_TEXTURE0 + Value);
  1353. end;
  1354. end;
  1355. procedure TGLStateCache.SetVertexArrayBinding(const Value: Cardinal);
  1356. begin
  1357. if Value <> FVertexArrayBinding then
  1358. begin
  1359. FVertexArrayBinding := Value;
  1360. gl.BindVertexArray(Value);
  1361. end;
  1362. end;
  1363. function TGLStateCache.GetArrayBufferBinding: Cardinal;
  1364. begin
  1365. Result := FArrayBufferBinding;
  1366. end;
  1367. procedure TGLStateCache.SetArrayBufferBinding(const Value: Cardinal);
  1368. begin
  1369. if (Value <> FArrayBufferBinding) or (FVertexArrayBinding <> 0) then
  1370. begin
  1371. FArrayBufferBinding := Value;
  1372. gl.BindBuffer(GL_ARRAY_BUFFER, Value);
  1373. end;
  1374. end;
  1375. function TGLStateCache.GetElementBufferBinding: Cardinal;
  1376. begin
  1377. Result := FElementBufferBinding
  1378. end;
  1379. procedure TGLStateCache.SetElementBufferBinding(const Value: Cardinal);
  1380. begin
  1381. if (Value <> FElementBufferBinding) or (FVertexArrayBinding <> 0) then
  1382. begin
  1383. FElementBufferBinding := Value;
  1384. gl.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, Value);
  1385. end;
  1386. end;
  1387. function TGLStateCache.GetEnablePrimitiveRestart: TGLboolean;
  1388. begin
  1389. Result := FEnablePrimitiveRestart;
  1390. end;
  1391. procedure TGLStateCache.SetEnablePrimitiveRestart(const enabled: TGLboolean);
  1392. begin
  1393. if enabled <> FEnablePrimitiveRestart then
  1394. begin
  1395. FEnablePrimitiveRestart := enabled;
  1396. if GL.NV_primitive_restart then
  1397. begin
  1398. if enabled then
  1399. gl.EnableClientState(GL_PRIMITIVE_RESTART_NV)
  1400. else
  1401. gl.DisableClientState(GL_PRIMITIVE_RESTART_NV);
  1402. end
  1403. else
  1404. begin
  1405. if enabled then
  1406. gl.Enable(GL_PRIMITIVE_RESTART)
  1407. else
  1408. gl.Disable(GL_PRIMITIVE_RESTART);
  1409. end;
  1410. end;
  1411. end;
  1412. function TGLStateCache.GetPrimitiveRestartIndex: Cardinal;
  1413. begin
  1414. Result := FPrimitiveRestartIndex;
  1415. end;
  1416. procedure TGLStateCache.SetPrimitiveRestartIndex(const index: Cardinal);
  1417. begin
  1418. if index <> FPrimitiveRestartIndex then
  1419. begin
  1420. if gl.NV_primitive_restart then
  1421. begin
  1422. FPrimitiveRestartIndex := index;
  1423. gl.PrimitiveRestartIndex(index)
  1424. end;
  1425. end;
  1426. end;
  1427. procedure TGLStateCache.SetEnableProgramPointSize(const Value: TGLboolean);
  1428. begin
  1429. if Value <> FEnableProgramPointSize then
  1430. begin
  1431. FEnableProgramPointSize := Value;
  1432. if Value then
  1433. gl.Enable(GL_PROGRAM_POINT_SIZE)
  1434. else
  1435. gl.Disable(GL_PROGRAM_POINT_SIZE);
  1436. end;
  1437. end;
  1438. procedure TGLStateCache.SetBlendColor(const Value: TGLVector);
  1439. begin
  1440. if not VectorEquals(Value, FBlendColor) or FInsideList then
  1441. begin
  1442. if FInsideList then
  1443. Include(FListStates[FCurrentList], sttColorBuffer)
  1444. else
  1445. FBlendColor := Value;
  1446. gl.BlendColor(Value.X, Value.Y, Value.Z, Value.W);
  1447. end;
  1448. end;
  1449. procedure TGLStateCache.SetBlendEquationSeparate(const modeRGB, modeAlpha: TGLBlendEquation);
  1450. begin
  1451. if (modeRGB <> FBlendEquationRGB) or (modeAlpha <> FBlendEquationAlpha) or FInsideList then
  1452. begin
  1453. FBlendEquationRGB := modeRGB;
  1454. FBlendEquationAlpha := modeAlpha;
  1455. gl.BlendEquationSeparate(cGLBlendEquationToGLEnum[modeRGB], cGLBlendEquationToGLEnum[modeAlpha]);
  1456. end;
  1457. if FInsideList then
  1458. Include(FListStates[FCurrentList], sttColorBuffer);
  1459. end;
  1460. procedure TGLStateCache.SetBlendEquation(const mode: TGLBlendEquation);
  1461. begin
  1462. if (mode <> FBlendEquationRGB) or (mode <> FBlendEquationAlpha) or FInsideList then
  1463. begin
  1464. if FInsideList then
  1465. Include(FListStates[FCurrentList], sttColorBuffer)
  1466. else
  1467. begin
  1468. FBlendEquationRGB := mode;
  1469. FBlendEquationAlpha := mode;
  1470. end;
  1471. gl.BlendEquation(cGLBlendEquationToGLEnum[mode]);
  1472. end;
  1473. end;
  1474. procedure TGLStateCache.SetBlendFunc(const Src: TGLBlendFunction; const Dst: TGLDstBlendFunction);
  1475. begin
  1476. if (Src <> FBlendSrcRGB) or (Dst <> FBlendDstRGB) or FInsideList then
  1477. begin
  1478. if FInsideList then
  1479. Include(FListStates[FCurrentList], sttColorBuffer)
  1480. else
  1481. begin
  1482. FBlendSrcRGB := Src;
  1483. FBlendDstRGB := Dst;
  1484. FBlendSrcAlpha := Src;
  1485. FBlendSrcAlpha := Dst;
  1486. end;
  1487. gl.BlendFunc(cGLBlendFunctionToGLEnum[Src], cGLBlendFunctionToGLEnum[Dst]);
  1488. end;
  1489. end;
  1490. procedure TGLStateCache.SetBlendFuncSeparate(const SrcRGB: TGLBlendFunction;
  1491. const DstRGB: TGLDstBlendFunction; const SrcAlpha: TGLBlendFunction; const DstAlpha: TGLDstBlendFunction);
  1492. begin
  1493. if (SrcRGB <> FBlendSrcRGB) or (DstRGB <> FBlendDstRGB) or
  1494. (SrcAlpha <> FBlendSrcAlpha) or (DstAlpha <> FBlendDstAlpha)
  1495. or FInsideList then
  1496. begin
  1497. if FInsideList then
  1498. Include(FListStates[FCurrentList], sttColorBuffer)
  1499. else
  1500. begin
  1501. FBlendSrcRGB := SrcRGB;
  1502. FBlendDstRGB := DstRGB;
  1503. FBlendSrcAlpha := SrcAlpha;
  1504. FBlendDstAlpha := DstAlpha;
  1505. end;
  1506. gl.BlendFuncSeparate(
  1507. cGLBlendFunctionToGLEnum[SrcRGB],
  1508. cGLBlendFunctionToGLEnum[DstRGB],
  1509. cGLBlendFunctionToGLEnum[SrcAlpha],
  1510. cGLBlendFunctionToGLEnum[DstAlpha]);
  1511. end;
  1512. end;
  1513. procedure TGLStateCache.SetClampReadColor(const Value: Cardinal);
  1514. begin
  1515. if (Value <> FClampReadColor) or FInsideList then
  1516. begin
  1517. if FInsideList then
  1518. Include(FListStates[FCurrentList], sttColorBuffer)
  1519. else
  1520. FClampReadColor := Value;
  1521. gl.ClampColor(GL_CLAMP_READ_COLOR, Value);
  1522. end;
  1523. end;
  1524. procedure TGLStateCache.SetColorWriteMask(index: Integer; const Value: TGLColorMask);
  1525. begin
  1526. if FColorWriteMask[Index] <> Value then
  1527. begin
  1528. FColorWriteMask[Index] := Value;
  1529. gl.ColorMaski(Index, ccRed in Value, ccGreen in Value, ccBlue in Value, ccAlpha in Value);
  1530. end;
  1531. end;
  1532. procedure TGLStateCache.SetCopyReadBufferBinding(const Value: Cardinal);
  1533. begin
  1534. if Value <> FCopyReadBufferBinding then
  1535. begin
  1536. FCopyReadBufferBinding := Value;
  1537. gl.BindBuffer(GL_COPY_READ_BUFFER, Value);
  1538. end;
  1539. end;
  1540. procedure TGLStateCache.SetCopyWriteBufferBinding(const Value: Cardinal);
  1541. begin
  1542. if Value <> FCopyWriteBufferBinding then
  1543. begin
  1544. FCopyWriteBufferBinding := Value;
  1545. gl.BindBuffer(GL_COPY_WRITE_BUFFER, Value);
  1546. end;
  1547. end;
  1548. procedure TGLStateCache.SetCullFaceMode(const Value: TGLCullFaceMode);
  1549. begin
  1550. if (Value <> FCullFaceMode) or FInsideList then
  1551. begin
  1552. if FInsideList then
  1553. Include(FListStates[FCurrentList], sttPolygon)
  1554. else
  1555. FCullFaceMode := Value;
  1556. gl.CullFace(cGLCullFaceModeToGLEnum[Value]);
  1557. end;
  1558. end;
  1559. procedure TGLStateCache.SetCurrentProgram(const Value: Cardinal);
  1560. begin
  1561. if Value <> FCurrentProgram then
  1562. begin
  1563. FCurrentProgram := Value;
  1564. gl.UseProgram(Value);
  1565. end;
  1566. end;
  1567. procedure TGLStateCache.SetTextureBufferBinding(const Value: Cardinal);
  1568. begin
  1569. if Value <> FTextureBufferBinding then
  1570. begin
  1571. FTextureBufferBinding := Value;
  1572. gl.BindBuffer(GL_TEXTURE_BUFFER, Value);
  1573. end;
  1574. end;
  1575. procedure TGLStateCache.SetCurrentVertexAttrib(index: Integer; const Value: TGLVector);
  1576. begin
  1577. if not VectorEquals(Value, FCurrentVertexAttrib[Index]) then
  1578. begin
  1579. FCurrentVertexAttrib[Index] := Value;
  1580. gl.VertexAttrib4fv(Index, @Value.X);
  1581. end;
  1582. end;
  1583. procedure TGLStateCache.SetDepthClearValue(const Value: TGLfloat);
  1584. begin
  1585. if (Value <> FDepthClearValue) or FInsideList then
  1586. begin
  1587. if FInsideList then
  1588. Include(FListStates[FCurrentList], sttDepthBuffer)
  1589. else
  1590. FDepthClearValue := Value;
  1591. gl.ClearDepth(Value);
  1592. end;
  1593. end;
  1594. procedure TGLStateCache.SetDepthFunc(const Value: TGLDepthFunction);
  1595. begin
  1596. if (Value <> FDepthFunc) or FInsideList then
  1597. begin
  1598. if FInsideList then
  1599. Include(FListStates[FCurrentList], sttDepthBuffer)
  1600. else
  1601. FDepthFunc := Value;
  1602. gl.DepthFunc(cGLComparisonFunctionToGLEnum[Value]);
  1603. end;
  1604. end;
  1605. procedure TGLStateCache.SetDepthRange(const ZNear, ZFar: TGLclampd);
  1606. begin
  1607. if (ZNear <> FDepthRange[0]) or (ZFar <> FDepthRange[1]) or FInsideList then
  1608. begin
  1609. if FInsideList then
  1610. Include(FListStates[FCurrentList], sttViewport)
  1611. else
  1612. begin
  1613. FDepthRange[0] := ZNear;
  1614. FDepthRange[1] := ZFar;
  1615. end;
  1616. gl.DepthRange(ZNear, ZFar);
  1617. end;
  1618. end;
  1619. procedure TGLStateCache.SetDepthRangeFar(const Value: TGLclampd);
  1620. begin
  1621. if (Value <> FDepthRange[1]) or FInsideList then
  1622. begin
  1623. if FInsideList then
  1624. Include(FListStates[FCurrentList], sttViewport)
  1625. else
  1626. FDepthRange[1] := Value;
  1627. gl.DepthRange(FDepthRange[0], Value);
  1628. end;
  1629. end;
  1630. procedure TGLStateCache.SetDepthRangeNear(const Value: TGLclampd);
  1631. begin
  1632. if (Value <> FDepthRange[0]) or FInsideList then
  1633. begin
  1634. if FInsideList then
  1635. Include(FListStates[FCurrentList], sttViewport)
  1636. else
  1637. FDepthRange[0] := Value;
  1638. gl.DepthRange(Value, FDepthRange[1]);
  1639. end;
  1640. end;
  1641. procedure TGLStateCache.SetDepthWriteMask(const Value: TGLboolean);
  1642. begin
  1643. if (Value <> FDepthWriteMask) or FInsideList then
  1644. begin
  1645. if FInsideList then
  1646. Include(FListStates[FCurrentList], sttDepthBuffer)
  1647. else
  1648. FDepthWriteMask := Value;
  1649. gl.DepthMask(Value);
  1650. end;
  1651. end;
  1652. procedure TGLStateCache.SetDrawFrameBuffer(const Value: Cardinal);
  1653. begin
  1654. if Value <> FDrawFrameBuffer then
  1655. begin
  1656. FDrawFrameBuffer := Value;
  1657. gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, Value);
  1658. end;
  1659. end;
  1660. procedure TGLStateCache.SetEnableBlend(index: Integer; const Value: TGLboolean);
  1661. begin
  1662. if FEnableBlend[Index] <> Value then
  1663. begin
  1664. FEnableBlend[Index] := Value;
  1665. if Value then
  1666. gl.Enablei(GL_BLEND, Index)
  1667. else
  1668. gl.Disablei(GL_BLEND, Index);
  1669. end;
  1670. end;
  1671. procedure TGLStateCache.SetEnableClipDistance(index: Cardinal; const Value: TGLboolean);
  1672. begin
  1673. if FEnableClipDistance[Index] <> Value then
  1674. begin
  1675. FEnableClipDistance[Index] := Value;
  1676. if Value then
  1677. gl.Enable(GL_CLIP_DISTANCE0 + Index)
  1678. else
  1679. gl.Disable(GL_CLIP_DISTANCE0 + Index);
  1680. end;
  1681. end;
  1682. procedure TGLStateCache.SetEnableColorLogicOp(const Value: TGLboolean);
  1683. begin
  1684. if Value <> FEnableColorLogicOp then
  1685. begin
  1686. FEnableColorLogicOp := Value;
  1687. if Value then
  1688. gl.Enable(GL_COLOR_LOGIC_OP)
  1689. else
  1690. gl.Disable(GL_COLOR_LOGIC_OP);
  1691. end;
  1692. end;
  1693. procedure TGLStateCache.SetEnableCullFace(const Value: TGLboolean);
  1694. begin
  1695. end;
  1696. procedure TGLStateCache.SetEnableDepthClamp(const enabled: TGLboolean);
  1697. begin
  1698. end;
  1699. procedure TGLStateCache.SetEnableDepthTest(const Value: TGLboolean);
  1700. begin
  1701. end;
  1702. procedure TGLStateCache.SetEnableDither(const Value: TGLboolean);
  1703. begin
  1704. end;
  1705. procedure TGLStateCache.SetEnableFramebufferSRGB(const Value: TGLboolean);
  1706. begin
  1707. end;
  1708. procedure TGLStateCache.SetEnableLineSmooth(const Value: TGLboolean);
  1709. begin
  1710. end;
  1711. procedure TGLStateCache.SetEnableMultisample(const Value: TGLboolean);
  1712. begin
  1713. end;
  1714. procedure TGLStateCache.SetEnablePolygonOffsetFill(const Value: TGLboolean);
  1715. begin
  1716. end;
  1717. procedure TGLStateCache.SetEnablePolygonOffsetLine(const Value: TGLboolean);
  1718. begin
  1719. end;
  1720. procedure TGLStateCache.SetEnablePolygonOffsetPoint(const Value: TGLboolean);
  1721. begin
  1722. end;
  1723. procedure TGLStateCache.SetEnablePolygonSmooth(const Value: TGLboolean);
  1724. begin
  1725. end;
  1726. procedure TGLStateCache.SetEnableSampleAlphaToCoverage(const Value: TGLboolean);
  1727. begin
  1728. if Value <> FEnableSampleAlphaToCoverage then
  1729. begin
  1730. FEnableSampleAlphaToCoverage := Value;
  1731. if Value then
  1732. gl.Enable(GL_SAMPLE_ALPHA_TO_COVERAGE)
  1733. else
  1734. gl.Disable(GL_SAMPLE_ALPHA_TO_COVERAGE);
  1735. end;
  1736. end;
  1737. procedure TGLStateCache.SetEnableSampleCoverage(const Value: TGLboolean);
  1738. begin
  1739. if Value <> FEnableSampleCoverage then
  1740. begin
  1741. FEnableSampleCoverage := Value;
  1742. if Value then
  1743. gl.Enable(GL_SAMPLE_COVERAGE)
  1744. else
  1745. gl.Disable(GL_SAMPLE_COVERAGE);
  1746. end;
  1747. end;
  1748. procedure TGLStateCache.SetEnableSampleMask(const Value: TGLboolean);
  1749. begin
  1750. if Value <> FEnableSampleMask then
  1751. begin
  1752. FEnableSampleMask := Value;
  1753. if Value then
  1754. gl.Enable(GL_SAMPLE_MASK)
  1755. else
  1756. gl.Disable(GL_SAMPLE_MASK);
  1757. end;
  1758. end;
  1759. procedure TGLStateCache.SetEnableSampleAlphaToOne(const Value: TGLboolean);
  1760. begin
  1761. if Value <> FEnableSampleAlphaToOne then
  1762. begin
  1763. FEnableSampleAlphaToOne := Value;
  1764. if Value then
  1765. gl.Enable(GL_SAMPLE_ALPHA_TO_ONE)
  1766. else
  1767. gl.Disable(GL_SAMPLE_ALPHA_TO_ONE);
  1768. end;
  1769. end;
  1770. procedure TGLStateCache.SetEnableScissorTest(const Value: TGLboolean);
  1771. begin
  1772. end;
  1773. procedure TGLStateCache.SetEnableStencilTest(const Value: TGLboolean);
  1774. begin
  1775. end;
  1776. procedure TGLStateCache.SetFragmentShaderDerivitiveHint(const Value: TGLHintType);
  1777. begin
  1778. if Value <> FFragmentShaderDerivitiveHint then
  1779. begin
  1780. if FInsideList then
  1781. Include(FListStates[FCurrentList], sttHint)
  1782. else
  1783. FFragmentShaderDerivitiveHint := Value;
  1784. gl.Hint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, cGLHintToGLEnum[Value]);
  1785. end;
  1786. end;
  1787. procedure TGLStateCache.SetMultisampleFilterHint(const Value: TGLHintType);
  1788. begin
  1789. if GL.NV_multisample_filter_hint then
  1790. if Value <> FMultisampleFilterHint then
  1791. begin
  1792. if FInsideList then
  1793. Include(FListStates[FCurrentList], sttHint)
  1794. else
  1795. FMultisampleFilterHint := Value;
  1796. gl.Hint(GL_MULTISAMPLE_FILTER_HINT_NV, cGLHintToGLEnum[Value]);
  1797. end;
  1798. end;
  1799. procedure TGLStateCache.SetFrameBuffer(const Value: Cardinal);
  1800. begin
  1801. if (Value <> FDrawFrameBuffer) or (Value <> FReadFrameBuffer) or FInsideList then
  1802. begin
  1803. FDrawFrameBuffer := Value;
  1804. FReadFrameBuffer := Value;
  1805. gl.BindFramebuffer(GL_FRAMEBUFFER, Value);
  1806. end;
  1807. end;
  1808. procedure TGLStateCache.SetFrontFace(const Value: TGLFaceWinding);
  1809. begin
  1810. if (Value <> FFrontFace) or FInsideList then
  1811. begin
  1812. if FInsideList then
  1813. Include(FListStates[FCurrentList], sttPolygon)
  1814. else
  1815. FFrontFace := Value;
  1816. gl.FrontFace(cGLFaceWindingToGLEnum[Value]);
  1817. end;
  1818. end;
  1819. procedure TGLStateCache.SetGLAlphaFunction(func: TGLComparisonFunction; ref: Single);
  1820. {$IFDEF USE_CACHE_MISS_CHECK}
  1821. var
  1822. I: Cardinal;
  1823. E: Single;
  1824. {$ENDIF}
  1825. begin
  1826. { if FForwardContext then
  1827. exit; }
  1828. {$IFDEF USE_CACHE_MISS_CHECK}
  1829. gl.GetIntegerv(GL_ALPHA_TEST_FUNC, @I);
  1830. if cGLComparisonFunctionToGLEnum[FAlphaFunc] <> I then
  1831. GLSLogger.LogError(strStateCashMissing + 'AlphaTest function');
  1832. gl.GetFloatv(GL_ALPHA_TEST_REF, @E);
  1833. if FAlphaRef <> E then
  1834. GLSLogger.LogError(strStateCashMissing + 'AlphaTest reference');
  1835. {$ENDIF}
  1836. if (FAlphaFunc <> func) or (FAlphaRef <> ref) or FInsideList then
  1837. begin
  1838. if FInsideList then
  1839. Include(FListStates[FCurrentList], sttColorBuffer)
  1840. else
  1841. begin
  1842. FAlphaFunc := func;
  1843. FAlphaRef := ref;
  1844. end;
  1845. gl.AlphaFunc(cGLComparisonFunctionToGLEnum[func], ref);
  1846. end;
  1847. end;
  1848. function TGLStateCache.GetColorWriteMask(index: Integer): TGLColorMask;
  1849. begin
  1850. Result := FColorWriteMask[Index];
  1851. end;
  1852. function TGLStateCache.GetCurrentQuery(index: TGLQueryType): Cardinal;
  1853. begin
  1854. Result := FCurrentQuery[Index];
  1855. end;
  1856. function TGLStateCache.GetCurrentVertexAttrib(index: Integer): TGLVector;
  1857. begin
  1858. Result := FCurrentVertexAttrib[Index];
  1859. end;
  1860. function TGLStateCache.GetDepthRangeFar: TGLclampd;
  1861. begin
  1862. Result := FDepthRange[1];
  1863. end;
  1864. function TGLStateCache.GetDepthRangeNear: TGLclampd;
  1865. begin
  1866. Result := FDepthRange[0];
  1867. end;
  1868. function TGLStateCache.GetEnableBlend(index: Integer): TGLboolean;
  1869. begin
  1870. Result := FEnableBlend[Index];
  1871. end;
  1872. function TGLStateCache.GetEnableClipDistance(ClipDistance: Cardinal): TGLboolean;
  1873. begin
  1874. Result := FEnableClipDistance[ClipDistance];
  1875. end;
  1876. function TGLStateCache.GetSampleMaskValue(index: Integer): TGLbitfield;
  1877. begin
  1878. Result := FSampleMaskValue[Index];
  1879. end;
  1880. function TGLStateCache.GetMaxTextureSize: Cardinal;
  1881. begin
  1882. if FMaxTextureSize = 0 then
  1883. gl.GetIntegerv(GL_MAX_TEXTURE_SIZE, @FMaxTextureSize);
  1884. Result := FMaxTextureSize;
  1885. end;
  1886. function TGLStateCache.GetMaterialAmbient(const aFace: TGLCullFaceMode): TGLVector;
  1887. begin
  1888. Result := FFrontBackColors[ord(aFace)][1];
  1889. end;
  1890. function TGLStateCache.GetMaterialDiffuse(const aFace: TGLCullFaceMode): TGLVector;
  1891. begin
  1892. Result := FFrontBackColors[ord(aFace)][2];
  1893. end;
  1894. function TGLStateCache.GetMaterialEmission(const aFace: TGLCullFaceMode): TGLVector;
  1895. begin
  1896. Result := FFrontBackColors[ord(aFace)][0];
  1897. end;
  1898. function TGLStateCache.GetMaterialShininess(const aFace: TGLCullFaceMode): Integer;
  1899. begin
  1900. Result := FFrontBackShininess[ord(aFace)];
  1901. end;
  1902. function TGLStateCache.GetMaterialSpecular(const aFace: TGLCullFaceMode): TGLVector;
  1903. begin
  1904. Result := FFrontBackColors[ord(aFace)][3];
  1905. end;
  1906. function TGLStateCache.GetMax3DTextureSize: Cardinal;
  1907. begin
  1908. if FMax3DTextureSize = 0 then
  1909. gl.GetIntegerv(GL_MAX_3D_TEXTURE_SIZE, @FMax3DTextureSize);
  1910. Result := FMax3DTextureSize;
  1911. end;
  1912. function TGLStateCache.GetMaxCubeTextureSize: Cardinal;
  1913. begin
  1914. if FMaxCubeTextureSize = 0 then
  1915. gl.GetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @FMaxCubeTextureSize);
  1916. Result := FMaxCubeTextureSize;
  1917. end;
  1918. function TGLStateCache.GetMaxArrayTextureSize: Cardinal;
  1919. begin
  1920. if FMaxArrayTextureSize = 0 then
  1921. gl.GetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, @FMaxArrayTextureSize);
  1922. Result := FMaxArrayTextureSize;
  1923. end;
  1924. function TGLStateCache.GetMaxTextureImageUnits: Cardinal;
  1925. begin
  1926. if FMaxTextureImageUnits = 0 then
  1927. gl.GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, @FMaxTextureImageUnits);
  1928. Result := FMaxTextureImageUnits;
  1929. end;
  1930. function TGLStateCache.GetMaxTextureAnisotropy: Cardinal;
  1931. begin
  1932. if (FMaxTextureAnisotropy = 0) and GL.EXT_texture_filter_anisotropic then
  1933. gl.GetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @FMaxTextureAnisotropy);
  1934. Result := FMaxTextureAnisotropy;
  1935. end;
  1936. function TGLStateCache.GetMaxSamples: Cardinal;
  1937. begin
  1938. if (FMaxSamples = 0) and GL.EXT_multisample then
  1939. gl.GetIntegerv(GL_MAX_SAMPLES, @FMaxSamples);
  1940. Result := FMaxSamples;
  1941. end;
  1942. function TGLStateCache.GetTextureBinding(index: Integer; target: TGLTextureTarget): Cardinal;
  1943. begin
  1944. Result := FTextureBinding[Index, target];
  1945. end;
  1946. function TGLStateCache.GetTextureBindingTime(index: Integer; target: TGLTextureTarget): Double;
  1947. begin
  1948. Result := FTextureBindingTime[Index, target];
  1949. end;
  1950. function TGLStateCache.GetSamplerBinding(index: Cardinal): Cardinal;
  1951. begin
  1952. Result := FSamplerBinding[Index];
  1953. end;
  1954. procedure TGLStateCache.SetSamplerBinding(index: Cardinal; const Value: Cardinal);
  1955. begin
  1956. if Index > High(FSamplerBinding) then
  1957. exit;
  1958. if (Value <> FSamplerBinding[Index]) or FInsideList then
  1959. begin
  1960. if FInsideList then
  1961. Include(FListStates[FCurrentList], sttTexture)
  1962. else
  1963. FSamplerBinding[Index] := Value;
  1964. gl.BindSampler(Index, Value);
  1965. end;
  1966. end;
  1967. procedure TGLStateCache.SetTextureMatrix(const matrix: TGLMatrix);
  1968. begin
  1969. { if FForwardContext then
  1970. exit; }
  1971. if FInsideList then
  1972. Include(FListStates[FCurrentList], sttTransform)
  1973. else
  1974. FTextureMatrixIsIdentity[ActiveTexture] := False;
  1975. gl.MatrixMode(GL_TEXTURE);
  1976. gl.LoadMatrixf(PGLFloat(@matrix.V[0].X));
  1977. gl.MatrixMode(GL_MODELVIEW);
  1978. end;
  1979. procedure TGLStateCache.ResetTextureMatrix;
  1980. begin
  1981. { if FForwardContext then
  1982. exit; }
  1983. gl.MatrixMode(GL_TEXTURE);
  1984. gl.LoadIdentity;
  1985. FTextureMatrixIsIdentity[ActiveTexture] := True;
  1986. gl.MatrixMode(GL_MODELVIEW);
  1987. end;
  1988. procedure TGLStateCache.ResetAllTextureMatrix;
  1989. var
  1990. I: Integer;
  1991. lastActiveTexture: Cardinal;
  1992. begin
  1993. { if FForwardContext then
  1994. exit; }
  1995. lastActiveTexture := ActiveTexture;
  1996. gl.MatrixMode(GL_TEXTURE);
  1997. for I := High(FTextureMatrixIsIdentity) downto 0 do
  1998. if not FTextureMatrixIsIdentity[I] then
  1999. begin
  2000. ActiveTexture := I;
  2001. gl.LoadIdentity;
  2002. FTextureMatrixIsIdentity[I] := True;
  2003. end;
  2004. gl.MatrixMode(GL_MODELVIEW);
  2005. ActiveTexture := lastActiveTexture;
  2006. end;
  2007. procedure TGLStateCache.SetLineSmoothHint(const Value: TGLHintType);
  2008. begin
  2009. if (Value <> FLineSmoothHint) or FInsideList then
  2010. begin
  2011. if FInsideList then
  2012. Include(FListStates[FCurrentList], sttHint)
  2013. else
  2014. FLineSmoothHint := Value;
  2015. gl.Hint(GL_LINE_SMOOTH_HINT, cGLHintToGLEnum[Value]);
  2016. end;
  2017. end;
  2018. procedure TGLStateCache.SetLineWidth(const Value: TGLfloat);
  2019. begin
  2020. // note: wide lines no longer deprecated (see OpenGL spec)
  2021. if (Value <> FLineWidth) or FInsideList then
  2022. begin
  2023. if FInsideList then
  2024. Include(FListStates[FCurrentList], sttLine)
  2025. else
  2026. FLineWidth := Value;
  2027. gl.LineWidth(Value);
  2028. end;
  2029. end;
  2030. procedure TGLStateCache.SetLineStippleFactor(const Value: TGLint);
  2031. begin
  2032. if (Value <> FLineStippleFactor) or FInsideList then
  2033. begin
  2034. if FInsideList then
  2035. Include(FListStates[FCurrentList], sttLine)
  2036. else
  2037. FLineStippleFactor := Value;
  2038. gl.LineStipple(Value, FLineStipplePattern);
  2039. end;
  2040. end;
  2041. procedure TGLStateCache.SetLineStipplePattern(const Value: TGLushort);
  2042. begin
  2043. if (Value <> FLineStipplePattern) or FInsideList then
  2044. begin
  2045. if FInsideList then
  2046. Include(FListStates[FCurrentList], sttLine)
  2047. else
  2048. FLineStipplePattern := Value;
  2049. gl.LineStipple(FLineStippleFactor, Value);
  2050. end;
  2051. end;
  2052. procedure TGLStateCache.SetLogicOpMode(const Value: TGLLogicOp);
  2053. begin
  2054. if (Value <> FLogicOpMode) or FInsideList then
  2055. begin
  2056. if FInsideList then
  2057. Include(FListStates[FCurrentList], sttColorBuffer)
  2058. else
  2059. FLogicOpMode := Value;
  2060. gl.LogicOp(cGLLogicOpToGLEnum[Value]);
  2061. end;
  2062. end;
  2063. procedure TGLStateCache.SetPackAlignment(const Value: Cardinal);
  2064. begin
  2065. if Value <> FPackAlignment then
  2066. begin
  2067. FPackAlignment := Value;
  2068. gl.PixelStoref(GL_PACK_ALIGNMENT, Value);
  2069. end;
  2070. end;
  2071. procedure TGLStateCache.SetPackImageHeight(const Value: Cardinal);
  2072. begin
  2073. if Value <> FPackImageHeight then
  2074. begin
  2075. FPackImageHeight := Value;
  2076. gl.PixelStoref(GL_PACK_IMAGE_HEIGHT, Value);
  2077. end;
  2078. end;
  2079. procedure TGLStateCache.SetPackLSBFirst(const Value: TGLboolean);
  2080. begin
  2081. if Value <> FPackLSBFirst then
  2082. begin
  2083. FPackLSBFirst := Value;
  2084. gl.PixelStorei(GL_PACK_LSB_FIRST, byte(Value));
  2085. end;
  2086. end;
  2087. procedure TGLStateCache.SetPackRowLength(const Value: Cardinal);
  2088. begin
  2089. if Value <> FPackRowLength then
  2090. begin
  2091. FPackRowLength := Value;
  2092. gl.PixelStoref(GL_PACK_ROW_LENGTH, Value);
  2093. end;
  2094. end;
  2095. procedure TGLStateCache.SetPackSkipImages(const Value: Cardinal);
  2096. begin
  2097. if Value <> FPackSkipImages then
  2098. begin
  2099. FPackSkipImages := Value;
  2100. gl.PixelStoref(GL_PACK_SKIP_IMAGES, Value);
  2101. end;
  2102. end;
  2103. procedure TGLStateCache.SetPackSkipPixels(const Value: Cardinal);
  2104. begin
  2105. if Value <> FPackSkipPixels then
  2106. begin
  2107. FPackSkipPixels := Value;
  2108. gl.PixelStoref(GL_PACK_SKIP_PIXELS, Value);
  2109. end;
  2110. end;
  2111. procedure TGLStateCache.SetPackSkipRows(const Value: Cardinal);
  2112. begin
  2113. if Value <> FPackSkipRows then
  2114. begin
  2115. FPackSkipRows := Value;
  2116. gl.PixelStoref(GL_PACK_SKIP_ROWS, Value);
  2117. end;
  2118. end;
  2119. procedure TGLStateCache.SetPackSwapBytes(const Value: TGLboolean);
  2120. begin
  2121. if Value <> FPackSwapBytes then
  2122. begin
  2123. FPackSwapBytes := Value;
  2124. gl.PixelStorei(GL_PACK_SWAP_BYTES, byte(Value));
  2125. end;
  2126. end;
  2127. procedure TGLStateCache.SetPixelPackBufferBinding(const Value: Cardinal);
  2128. begin
  2129. if Value <> FPixelPackBufferBinding then
  2130. begin
  2131. FPixelPackBufferBinding := Value;
  2132. gl.BindBuffer(GL_PIXEL_PACK_BUFFER, Value);
  2133. end;
  2134. end;
  2135. procedure TGLStateCache.SetPixelUnpackBufferBinding(const Value: Cardinal);
  2136. begin
  2137. if Value <> FPixelUnpackBufferBinding then
  2138. begin
  2139. FPixelUnpackBufferBinding := Value;
  2140. gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, Value);
  2141. end;
  2142. end;
  2143. procedure TGLStateCache.SetPointFadeThresholdSize(const Value: TGLfloat);
  2144. begin
  2145. if (Value <> FPointFadeThresholdSize) or FInsideList then
  2146. begin
  2147. if FInsideList then
  2148. Include(FListStates[FCurrentList], sttPoint)
  2149. else
  2150. FPointFadeThresholdSize := Value;
  2151. gl.PointParameterf(GL_POINT_FADE_THRESHOLD_SIZE, Value);
  2152. end;
  2153. end;
  2154. procedure TGLStateCache.SetPointSize(const Value: TGLfloat);
  2155. begin
  2156. if (Value <> FPointSize) or FInsideList then
  2157. begin
  2158. if FInsideList then
  2159. Include(FListStates[FCurrentList], sttPoint)
  2160. else
  2161. FPointSize := Value;
  2162. gl.PointSize(Value);
  2163. end;
  2164. end;
  2165. procedure TGLStateCache.SetPointSpriteCoordOrigin(const Value: Cardinal);
  2166. begin
  2167. if (Value <> FPointSpriteCoordOrigin) or FInsideList then
  2168. begin
  2169. if FInsideList then
  2170. Include(FListStates[FCurrentList], sttPoint)
  2171. else
  2172. FPointSpriteCoordOrigin := Value;
  2173. gl.PointParameterf(GL_POINT_SPRITE_COORD_ORIGIN, Value);
  2174. end;
  2175. end;
  2176. procedure TGLStateCache.SetPolygonMode(const Value: TGLPolygonMode);
  2177. begin
  2178. if (Value <> FPolygonMode) or FInsideList then
  2179. begin
  2180. if FInsideList then
  2181. Include(FListStates[FCurrentList], sttPolygon)
  2182. else
  2183. begin
  2184. FPolygonMode := Value;
  2185. FPolygonBackMode := Value;
  2186. end;
  2187. gl.PolygonMode(GL_FRONT_AND_BACK, cGLPolygonModeToGLEnum[Value]);
  2188. end;
  2189. end;
  2190. procedure TGLStateCache.SetPolygonOffset(const factor, units: TGLfloat);
  2191. begin
  2192. if (factor <> FPolygonOffsetFactor) or (units <> FPolygonOffsetUnits) or FInsideList then
  2193. begin
  2194. if FInsideList then
  2195. Include(FListStates[FCurrentList], sttPolygon)
  2196. else
  2197. begin
  2198. FPolygonOffsetFactor := factor;
  2199. FPolygonOffsetUnits := units;
  2200. end;
  2201. gl.PolygonOffset(factor, units);
  2202. end;
  2203. end;
  2204. procedure TGLStateCache.SetPolygonOffsetFactor(const Value: TGLfloat);
  2205. begin
  2206. if (Value <> FPolygonOffsetFactor) or FInsideList then
  2207. begin
  2208. if FInsideList then
  2209. Include(FListStates[FCurrentList], sttPolygon)
  2210. else
  2211. FPolygonOffsetFactor := Value;
  2212. gl.PolygonOffset(Value, FPolygonOffsetUnits);
  2213. end;
  2214. end;
  2215. procedure TGLStateCache.SetPolygonOffsetUnits(const Value: TGLfloat);
  2216. begin
  2217. if (Value <> FPolygonOffsetUnits) or FInsideList then
  2218. begin
  2219. if FInsideList then
  2220. Include(FListStates[FCurrentList], sttPolygon)
  2221. else
  2222. FPolygonOffsetUnits := Value;
  2223. gl.PolygonOffset(FPolygonOffsetFactor, Value);
  2224. end;
  2225. end;
  2226. procedure TGLStateCache.SetPolygonSmoothHint(const Value: TGLHintType);
  2227. begin
  2228. if (Value <> FPolygonSmoothHint) or FInsideList then
  2229. begin
  2230. if FInsideList then
  2231. Include(FListStates[FCurrentList], sttHint)
  2232. else
  2233. FPolygonSmoothHint := Value;
  2234. gl.Hint(GL_POLYGON_SMOOTH_HINT, cGLHintToGLEnum[Value]);
  2235. end;
  2236. end;
  2237. procedure TGLStateCache.SetProvokingVertex(const Value: Cardinal);
  2238. begin
  2239. if Value <> FProvokingVertex then
  2240. begin
  2241. FProvokingVertex := Value;
  2242. gl.ProvokingVertex(Value);
  2243. end;
  2244. end;
  2245. procedure TGLStateCache.SetReadFrameBuffer(const Value: Cardinal);
  2246. begin
  2247. if Value <> FReadFrameBuffer then
  2248. begin
  2249. FReadFrameBuffer := Value;
  2250. gl.BindFramebuffer(GL_READ_FRAMEBUFFER, Value);
  2251. end;
  2252. end;
  2253. procedure TGLStateCache.SetRenderBuffer(const Value: Cardinal);
  2254. begin
  2255. if Value <> FRenderBuffer then
  2256. begin
  2257. FRenderBuffer := Value;
  2258. gl.BindRenderbuffer(GL_RENDERBUFFER, Value);
  2259. end;
  2260. end;
  2261. procedure TGLStateCache.SetSampleCoverage(const Value: TGLfloat; invert: TGLboolean);
  2262. begin
  2263. if (Value <> FSampleCoverageValue) or (invert <> FSampleCoverageInvert) or FInsideList then
  2264. begin
  2265. if FInsideList then
  2266. Include(FListStates[FCurrentList], sttMultisample)
  2267. else
  2268. begin
  2269. FSampleCoverageValue := Value;
  2270. FSampleCoverageInvert := invert;
  2271. end;
  2272. gl.SampleCoverage(Value, invert);
  2273. end;
  2274. end;
  2275. procedure TGLStateCache.SetSampleCoverageInvert(const Value: TGLboolean);
  2276. begin
  2277. if (Value <> FSampleCoverageInvert) or FInsideList then
  2278. begin
  2279. if FInsideList then
  2280. Include(FListStates[FCurrentList], sttMultisample)
  2281. else
  2282. FSampleCoverageInvert := Value;
  2283. gl.SampleCoverage(FSampleCoverageValue, Value);
  2284. end;
  2285. end;
  2286. procedure TGLStateCache.SetSampleCoverageValue(const Value: TGLfloat);
  2287. begin
  2288. if (Value <> FSampleCoverageValue) or FInsideList then
  2289. begin
  2290. if FInsideList then
  2291. Include(FListStates[FCurrentList], sttMultisample)
  2292. else
  2293. FSampleCoverageValue := Value;
  2294. gl.SampleCoverage(Value, FSampleCoverageInvert);
  2295. end;
  2296. end;
  2297. procedure TGLStateCache.SetSampleMaskValue(index: Integer; const Value: TGLbitfield);
  2298. begin
  2299. if (FSampleMaskValue[Index] <> Value) or FInsideList then
  2300. begin
  2301. if FInsideList then
  2302. Include(FListStates[FCurrentList], sttMultisample)
  2303. else
  2304. FSampleMaskValue[Index] := Value;
  2305. gl.SampleMaski(Index, Value);
  2306. end;
  2307. end;
  2308. procedure TGLStateCache.SetScissorBox(const Value: TVector4i);
  2309. begin
  2310. if not VectorEquals(FScissorBox, Value) or FInsideList then
  2311. begin
  2312. if FInsideList then
  2313. Include(FListStates[FCurrentList], sttScissor)
  2314. else
  2315. FScissorBox := Value;
  2316. gl.Scissor(Value.X, Value.Y, Value.Z, Value.W);
  2317. end;
  2318. end;
  2319. procedure TGLStateCache.SetStencilBackWriteMask(const Value: Cardinal);
  2320. begin
  2321. if (Value <> FStencilBackWriteMask) or FInsideList then
  2322. begin
  2323. if FInsideList then
  2324. Include(FListStates[FCurrentList], sttStencilBuffer)
  2325. else
  2326. FStencilBackWriteMask := Value;
  2327. // DONE: ignore if unsupported
  2328. if gl.VERSION_2_0 then
  2329. gl.StencilMaskSeparate(GL_BACK, Value);
  2330. end;
  2331. end;
  2332. procedure TGLStateCache.SetStencilClearValue(const Value: Cardinal);
  2333. {$IFDEF USE_CACHE_MISS_CHECK}
  2334. var
  2335. I: Cardinal;
  2336. {$ENDIF}
  2337. begin
  2338. {$IFDEF USE_CACHE_MISS_CHECK}
  2339. gl.GetIntegerv(GL_STENCIL_CLEAR_VALUE, @I);
  2340. if FStencilClearValue <> I then
  2341. GLSLogger.LogError(strStateCashMissing + 'Stencil clear value');
  2342. {$ENDIF}
  2343. if (Value <> FStencilClearValue) or FInsideList then
  2344. begin
  2345. if FInsideList then
  2346. Include(FListStates[FCurrentList], sttStencilBuffer)
  2347. else
  2348. FStencilClearValue := Value;
  2349. gl.ClearStencil(Value);
  2350. end;
  2351. end;
  2352. procedure TGLStateCache.SetColorClearValue(const Value: TGLVector);
  2353. begin
  2354. if not VectorEquals(Value, FColorClearValue) or FInsideList then
  2355. begin
  2356. if FInsideList then
  2357. Include(FListStates[FCurrentList], sttColorBuffer)
  2358. else
  2359. FColorClearValue := Value;
  2360. gl.ClearColor(Value.X, Value.Y, Value.Z, Value.W);
  2361. end;
  2362. end;
  2363. procedure TGLStateCache.SetColorMask(mask: TGLColorMask);
  2364. var
  2365. I: Integer;
  2366. begin
  2367. // it might be faster to keep track of whether all draw buffers are same
  2368. // value or not, since using this is probably more common than setting
  2369. // the color write mask for individual draw buffers
  2370. if FInsideList then
  2371. Include(FListStates[FCurrentList], sttColorBuffer)
  2372. else
  2373. for I := low(FColorWriteMask) to high(FColorWriteMask) do
  2374. begin
  2375. FColorWriteMask[I] := mask;
  2376. end;
  2377. gl.ColorMask(ccRed in mask, ccGreen in mask, ccBlue in mask, ccAlpha in mask);
  2378. end;
  2379. procedure TGLStateCache.SetStencilFuncSeparate(const face: TGLCullFaceMode; const func: TGLStencilFunction; const ref: TGLint;
  2380. const mask: Cardinal);
  2381. {$IFDEF USE_CACHE_MISS_CHECK}
  2382. var
  2383. UI: Cardinal;
  2384. I: TGLint;
  2385. {$ENDIF}
  2386. begin
  2387. // if (func<>FStencilFunc) or (ref<>FStencilRef) or (mask<>FStencilValueMask)
  2388. // or FInsideList then
  2389. {$IFDEF USE_CACHE_MISS_CHECK}
  2390. gl.GetIntegerv(GL_STENCIL_FUNC, @UI);
  2391. if cGLComparisonFunctionToGLEnum[FStencilFunc] <> UI then
  2392. GLSLogger.LogError(strStateCashMissing + 'Stencil function');
  2393. gl.GetIntegerv(GL_STENCIL_REF, @I);
  2394. if FStencilRef <> I then
  2395. GLSLogger.LogError(strStateCashMissing + 'Stencil reference');
  2396. GLSLogger.LogError(strStateCashMissing + 'Stencil function');
  2397. gl.GetIntegerv(GL_STENCIL_VALUE_MASK, @UI);
  2398. if FStencilValueMask <> UI then
  2399. GLSLogger.LogError(strStateCashMissing + 'Stencil value mask');
  2400. {$ENDIF}
  2401. begin
  2402. if FInsideList then
  2403. Include(FListStates[FCurrentList], sttStencilBuffer)
  2404. else
  2405. case face of
  2406. cmFront:
  2407. begin
  2408. FStencilFunc := func;
  2409. FStencilRef := ref;
  2410. FStencilValueMask := mask;
  2411. end;
  2412. cmBack:
  2413. begin
  2414. FStencilBackFunc := func;
  2415. FStencilBackRef := ref;
  2416. FStencilBackValueMask := mask;
  2417. end;
  2418. cmFrontAndBack:
  2419. begin
  2420. FStencilFunc := func;
  2421. FStencilRef := ref;
  2422. FStencilValueMask := mask;
  2423. FStencilBackFunc := func;
  2424. FStencilBackRef := ref;
  2425. FStencilBackValueMask := mask;
  2426. end;
  2427. end;
  2428. gl.StencilFuncSeparate(cGLCullFaceModeToGLEnum[face], cGLComparisonFunctionToGLEnum[func], ref, mask);
  2429. end;
  2430. end;
  2431. procedure TGLStateCache.SetStencilFunc(const func: TGLStencilFunction; const ref: TGLint; const mask: Cardinal);
  2432. begin
  2433. if (func <> FStencilFunc) or (ref <> FStencilRef) or (mask <> FStencilValueMask) or FInsideList then
  2434. begin
  2435. if FInsideList then
  2436. Include(FListStates[FCurrentList], sttStencilBuffer)
  2437. else
  2438. begin
  2439. FStencilFunc := func;
  2440. FStencilRef := ref;
  2441. FStencilValueMask := mask;
  2442. end;
  2443. gl.StencilFunc(cGLComparisonFunctionToGLEnum[func], ref, mask);
  2444. end;
  2445. end;
  2446. procedure TGLStateCache.SetStencilOp(const fail, zfail, zpass: TGLStencilOp);
  2447. {$IFDEF USE_CACHE_MISS_CHECK}
  2448. var
  2449. I: Cardinal;
  2450. {$ENDIF}
  2451. begin
  2452. {$IFDEF USE_CACHE_MISS_CHECK}
  2453. gl.GetIntegerv(GL_STENCIL_FAIL, @I);
  2454. if cGLStencilOpToGLEnum[FStencilFail] <> I then
  2455. GLSLogger.LogError(strStateCashMissing + 'Stencil fail');
  2456. gl.GetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, @I);
  2457. if cGLStencilOpToGLEnum[FStencilPassDepthFail] <> I then
  2458. GLSLogger.LogError(strStateCashMissing + 'Stencil zfail');
  2459. gl.GetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, @I);
  2460. if cGLStencilOpToGLEnum[FStencilPassDepthPass] <> I then
  2461. GLSLogger.LogError(strStateCashMissing + 'Stencil zpass');
  2462. {$ENDIF}
  2463. if (fail <> FStencilFail) or (zfail <> FStencilPassDepthFail) or (zpass <> FStencilPassDepthPass) or FInsideList then
  2464. begin
  2465. if FInsideList then
  2466. Include(FListStates[FCurrentList], sttStencilBuffer)
  2467. else
  2468. begin
  2469. FStencilFail := fail;
  2470. FStencilPassDepthFail := zfail;
  2471. FStencilPassDepthPass := zpass;
  2472. end;
  2473. gl.StencilOp(cGLStencilOpToGLEnum[fail],
  2474. cGLStencilOpToGLEnum[zfail],
  2475. cGLStencilOpToGLEnum[zpass]);
  2476. end;
  2477. end;
  2478. procedure TGLStateCache.SetStencilOpSeparate(const face: TGLCullFaceMode; const sfail, dpfail, dppass: TGLStencilOp);
  2479. begin
  2480. if FInsideList then
  2481. Include(FListStates[FCurrentList], sttStencilBuffer)
  2482. else
  2483. case face of
  2484. cmFront:
  2485. begin
  2486. FStencilFail := sfail;
  2487. FStencilPassDepthFail := dpfail;
  2488. FStencilPassDepthPass := dppass;
  2489. end;
  2490. cmBack:
  2491. begin
  2492. FStencilBackFail := sfail;
  2493. FStencilBackPassDepthFail := dpfail;
  2494. FStencilBackPassDepthPass := dppass;
  2495. end;
  2496. cmFrontAndBack:
  2497. begin
  2498. FStencilFail := sfail;
  2499. FStencilPassDepthFail := dpfail;
  2500. FStencilPassDepthPass := dppass;
  2501. FStencilBackFail := sfail;
  2502. FStencilBackPassDepthFail := dpfail;
  2503. FStencilBackPassDepthPass := dppass;
  2504. end;
  2505. end;
  2506. gl.StencilOpSeparate(cGLCullFaceModeToGLEnum[face], cGLStencilOpToGLEnum[sfail], cGLStencilOpToGLEnum[dpfail],
  2507. cGLStencilOpToGLEnum[dppass]);
  2508. end;
  2509. procedure TGLStateCache.SetStencilWriteMask(const Value: Cardinal);
  2510. {$IFDEF USE_CACHE_MISS_CHECK}
  2511. var
  2512. I: Cardinal;
  2513. {$ENDIF}
  2514. begin
  2515. {$IFDEF USE_CACHE_MISS_CHECK}
  2516. gl.GetIntegerv(GL_STENCIL_WRITEMASK, @I);
  2517. if FStencilWriteMask <> I then
  2518. GLSLogger.LogError(strStateCashMissing + 'Stencil write mask');
  2519. {$ENDIF}
  2520. if (Value <> FStencilWriteMask) or FInsideList then
  2521. begin
  2522. if FInsideList then
  2523. Include(FListStates[FCurrentList], sttStencilBuffer)
  2524. else
  2525. FStencilWriteMask := Value;
  2526. gl.StencilMaskSeparate(GL_FRONT, Value);
  2527. end;
  2528. end;
  2529. procedure TGLStateCache.SetTextureBinding(index: Integer; target: TGLTextureTarget; const Value: Cardinal);
  2530. var
  2531. lastActiveTexture: Cardinal;
  2532. begin
  2533. if target = ttNoShape then
  2534. exit;
  2535. if (Value <> FTextureBinding[Index, target]) or FInsideList then
  2536. begin
  2537. if FInsideList then
  2538. Include(FListStates[FCurrentList], sttTexture)
  2539. else
  2540. FTextureBinding[Index, target] := Value;
  2541. lastActiveTexture := ActiveTexture;
  2542. ActiveTexture := Index;
  2543. gl.BindTexture(cGLTexTypeToGLEnum[target], Value);
  2544. ActiveTexture := lastActiveTexture;
  2545. end;
  2546. FTextureBindingTime[Index, target] := AppTime;
  2547. end;
  2548. function TGLStateCache.GetActiveTextureEnabled(target: TGLTextureTarget): Boolean;
  2549. begin
  2550. Result := FActiveTextureEnabling[FActiveTexture][target];
  2551. end;
  2552. procedure TGLStateCache.SetActiveTextureEnabled(target: TGLTextureTarget; const Value: Boolean);
  2553. var
  2554. glTarget: Cardinal;
  2555. begin
  2556. glTarget := DecodeTextureTarget(target);
  2557. if { FForwardContext or } not IsTargetSupported(glTarget) then
  2558. exit;
  2559. if (Value <> FActiveTextureEnabling[FActiveTexture][target]) or FInsideList then
  2560. begin
  2561. if FInsideList then
  2562. Include(FListStates[FCurrentList], sttEnable)
  2563. else
  2564. FActiveTextureEnabling[FActiveTexture][target] := Value;
  2565. if Value then
  2566. gl.Enable(glTarget)
  2567. else
  2568. gl.Disable(glTarget);
  2569. end;
  2570. end;
  2571. procedure TGLStateCache.SetTextureCompressionHint(const Value: TGLHintType);
  2572. begin
  2573. if (Value <> FTextureCompressionHint) or FInsideList then
  2574. begin
  2575. if FInsideList then
  2576. Include(FListStates[FCurrentList], sttHint)
  2577. else
  2578. FTextureCompressionHint := Value;
  2579. gl.Hint(GL_TEXTURE_COMPRESSION_HINT, cGLHintToGLEnum[Value]);
  2580. end;
  2581. end;
  2582. procedure TGLStateCache.SetTransformFeedbackBufferBinding(const Value: Cardinal);
  2583. begin
  2584. if (Value <> FTransformFeedbackBufferBinding) or FInsideList then
  2585. begin
  2586. FTransformFeedbackBufferBinding := Value;
  2587. gl.BindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, Value);
  2588. end;
  2589. end;
  2590. procedure TGLStateCache.SetEnableTextureCubeMapSeamless(const Value: TGLboolean);
  2591. begin
  2592. if Value <> FEnableTextureCubeMapSeamless then
  2593. begin
  2594. FEnableTextureCubeMapSeamless := Value;
  2595. if Value = True then
  2596. gl.Enable(GL_TEXTURE_CUBE_MAP_SEAMLESS)
  2597. else
  2598. gl.Disable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
  2599. end;
  2600. end;
  2601. procedure TGLStateCache.NewList(list: Cardinal; mode: Cardinal);
  2602. var
  2603. I: Cardinal;
  2604. begin
  2605. Assert(mode = GL_COMPILE, 'Compile & executing not supported by TGLStateCache');
  2606. FCurrentList := list - 1;
  2607. // while High(FListStates) < Integer(FCurrentList) do
  2608. // SetLength(FListStates, 2 * Length(FListStates));
  2609. FListStates[FCurrentList] := [];
  2610. FInsideList := True;
  2611. // Reset VBO binding and client attribute
  2612. begin
  2613. if GL.ARB_vertex_buffer_object then
  2614. begin
  2615. ArrayBufferBinding := 0;
  2616. ElementBufferBinding := 0;
  2617. for I := 0 to 15 do
  2618. gl.DisableVertexAttribArray(I);
  2619. end;
  2620. gl.NewList(list, mode);
  2621. end;
  2622. end;
  2623. procedure TGLStateCache.EndList;
  2624. begin
  2625. gl.EndList;
  2626. FInsideList := False;
  2627. end;
  2628. procedure TGLStateCache.CallList(list: Cardinal);
  2629. begin
  2630. // while High(FListStates) < Integer(list) do
  2631. // SetLength(FListStates, 2 * Length(FListStates));
  2632. if FListStates[list - 1] <> [] then
  2633. begin
  2634. PushAttrib(FListStates[list - 1]);
  2635. gl.CallList(list);
  2636. PopAttrib;
  2637. end
  2638. else
  2639. gl.CallList(list);
  2640. end;
  2641. procedure TGLStateCache.SetUniformBufferBinding(const Value: Cardinal);
  2642. begin
  2643. Assert(not FInsideList);
  2644. if Value <> FUniformBufferBinding then
  2645. begin
  2646. FUniformBufferBinding := Value;
  2647. gl.BindBuffer(GL_UNIFORM_BUFFER, Value);
  2648. end;
  2649. end;
  2650. procedure TGLStateCache.SetBufferIndexedBinding(const Value: Cardinal;
  2651. ATarget: TGLBufferBindingTarget; AIndex: Cardinal; ABufferSize: TGLsizeiptr);
  2652. begin
  2653. Assert(not FInsideList);
  2654. if (FUBOStates[ATarget, AIndex].FUniformBufferBinding <> Value)
  2655. or (FUBOStates[ATarget, AIndex].FOffset > 0)
  2656. or (FUBOStates[ATarget, AIndex].FSize <> ABufferSize) then
  2657. begin
  2658. case ATarget of
  2659. bbtUniform:
  2660. FUniformBufferBinding := Value;
  2661. bbtTransformFeedBack:
  2662. FTransformFeedbackBufferBinding := Value;
  2663. end;
  2664. FUBOStates[ATarget, AIndex].FUniformBufferBinding := Value;
  2665. FUBOStates[ATarget, AIndex].FOffset := 0;
  2666. FUBOStates[ATarget, AIndex].FSize := ABufferSize;
  2667. gl.BindBufferBase(cGLBufferBindingTarget[ATarget], AIndex, Value);
  2668. end
  2669. else
  2670. case ATarget of
  2671. bbtUniform: SetUniformBufferBinding(Value);
  2672. bbtTransformFeedBack: SetTransformFeedbackBufferBinding(Value);
  2673. end;
  2674. end;
  2675. procedure TGLStateCache.SetBufferIndexedBinding(const Value: Cardinal; ATarget: TGLBufferBindingTarget; AIndex: Cardinal;
  2676. AOffset: TGLintptr; ARangeSize: TGLsizeiptr);
  2677. begin
  2678. Assert(not FInsideList);
  2679. if (FUBOStates[ATarget, AIndex].FUniformBufferBinding <> Value)
  2680. or (FUBOStates[ATarget, AIndex].FOffset <> AOffset)
  2681. or (FUBOStates[ATarget, AIndex].FSize <> ARangeSize) then
  2682. begin
  2683. case ATarget of
  2684. bbtUniform: FUniformBufferBinding := Value;
  2685. bbtTransformFeedBack: FTransformFeedbackBufferBinding := Value;
  2686. end;
  2687. FUBOStates[ATarget, AIndex].FUniformBufferBinding := Value;
  2688. FUBOStates[ATarget, AIndex].FOffset := AOffset;
  2689. FUBOStates[ATarget, AIndex].FSize := ARangeSize;
  2690. gl.BindBufferRange(cGLBufferBindingTarget[ATarget], AIndex, Value, AOffset, ARangeSize);
  2691. end;
  2692. end;
  2693. function TGLStateCache.GetMaxTextureUnits: Cardinal;
  2694. begin
  2695. if FMaxTextureUnits = 0 then
  2696. gl.GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, @FMaxTextureUnits);
  2697. Result := FMaxTextureUnits;
  2698. end;
  2699. procedure TGLStateCache.SetUnpackAlignment(const Value: Cardinal);
  2700. begin
  2701. if Value <> FUnpackAlignment then
  2702. begin
  2703. FUnpackAlignment := Value;
  2704. gl.PixelStoref(GL_UNPACK_ALIGNMENT, Value);
  2705. end;
  2706. end;
  2707. procedure TGLStateCache.SetUnpackImageHeight(const Value: Cardinal);
  2708. begin
  2709. if Value <> FUnpackImageHeight then
  2710. begin
  2711. FUnpackImageHeight := Value;
  2712. gl.PixelStoref(GL_UNPACK_IMAGE_HEIGHT, Value);
  2713. end;
  2714. end;
  2715. procedure TGLStateCache.SetUnpackLSBFirst(const Value: TGLboolean);
  2716. begin
  2717. if Value <> FUnpackLSBFirst then
  2718. begin
  2719. FUnpackLSBFirst := Value;
  2720. gl.PixelStorei(GL_UNPACK_LSB_FIRST, byte(Value));
  2721. end;
  2722. end;
  2723. procedure TGLStateCache.SetUnpackRowLength(const Value: Cardinal);
  2724. begin
  2725. if Value <> FUnpackRowLength then
  2726. begin
  2727. FUnpackRowLength := Value;
  2728. gl.PixelStoref(GL_UNPACK_ROW_LENGTH, Value);
  2729. end;
  2730. end;
  2731. procedure TGLStateCache.SetUnpackSkipImages(const Value: Cardinal);
  2732. begin
  2733. if Value <> FUnpackSkipImages then
  2734. begin
  2735. FUnpackSkipImages := Value;
  2736. gl.PixelStoref(GL_UNPACK_SKIP_IMAGES, Value);
  2737. end;
  2738. end;
  2739. procedure TGLStateCache.SetUnpackSkipPixels(const Value: Cardinal);
  2740. begin
  2741. if Value <> FUnpackSkipPixels then
  2742. begin
  2743. FUnpackSkipPixels := Value;
  2744. gl.PixelStoref(GL_UNPACK_SKIP_PIXELS, Value);
  2745. end;
  2746. end;
  2747. procedure TGLStateCache.SetUnpackSkipRows(const Value: Cardinal);
  2748. begin
  2749. if Value <> FUnpackSkipRows then
  2750. begin
  2751. FUnpackSkipRows := Value;
  2752. gl.PixelStoref(GL_UNPACK_SKIP_ROWS, Value);
  2753. end;
  2754. end;
  2755. procedure TGLStateCache.SetUnpackSwapBytes(const Value: TGLboolean);
  2756. begin
  2757. if Value <> FUnpackSwapBytes then
  2758. begin
  2759. FUnpackSwapBytes := Value;
  2760. gl.PixelStorei(GL_UNPACK_SWAP_BYTES, byte(Value));
  2761. end;
  2762. end;
  2763. procedure TGLStateCache.SetViewPort(const Value: TVector4i);
  2764. begin
  2765. if not VectorEquals(Value, FViewPort) or FInsideList then
  2766. begin
  2767. if FInsideList then
  2768. Include(FListStates[FCurrentList], sttViewport)
  2769. else
  2770. FViewPort := Value;
  2771. gl.ViewPort(Value.X, Value.Y, Value.Z, Value.W);
  2772. end;
  2773. end;
  2774. procedure TGLStateCache.SetFFPLight(Value: Boolean);
  2775. begin
  2776. FFFPLight := Value { and not FForwardContext };
  2777. end;
  2778. function TGLStateCache.GetMaxLights: Integer;
  2779. begin
  2780. if FMaxLights = 0 then
  2781. { if FForwardContext then
  2782. FMaxLights := MAX_HARDWARE_LIGHT
  2783. else }
  2784. gl.GetIntegerv(GL_MAX_LIGHTS, @FMaxLights);
  2785. Result := FMaxLights;
  2786. end;
  2787. function TGLStateCache.GetLightEnabling(I: Integer): Boolean;
  2788. begin
  2789. Result := FLightEnabling[I];
  2790. end;
  2791. procedure TGLStateCache.SetLightEnabling(I: Integer; Value: Boolean);
  2792. var
  2793. J, K: Integer;
  2794. begin
  2795. if (FLightEnabling[I] <> Value) or FInsideList then
  2796. begin
  2797. if FInsideList then
  2798. Include(FListStates[FCurrentList], sttLighting)
  2799. else
  2800. FLightEnabling[I] := Value;
  2801. if FFFPLight then
  2802. begin
  2803. if Value then
  2804. gl.Enable(GL_LIGHT0 + I)
  2805. else
  2806. gl.Disable(GL_LIGHT0 + I);
  2807. end;
  2808. K := 0;
  2809. for J := 0 to MAX_HARDWARE_LIGHT - 1 do
  2810. if FLightEnabling[J] then
  2811. begin
  2812. FLightIndices[K] := J;
  2813. Inc(K);
  2814. end;
  2815. FLightNumber := K;
  2816. FShaderLightStatesChanged := True;
  2817. if Assigned(FOnLightsChanged) then
  2818. FOnLightsChanged(Self);
  2819. end;
  2820. end;
  2821. function TGLStateCache.GetLightIndicesAsAddress: PGLInt;
  2822. begin
  2823. Result := @FLightIndices[0];
  2824. end;
  2825. function TGLStateCache.GetLightStateAsAddress: Pointer;
  2826. var
  2827. I, J, C: Integer;
  2828. begin
  2829. C := MinInteger(FLightNumber, MAX_SHADER_LIGHT);
  2830. if FShaderLightStatesChanged then
  2831. begin
  2832. if C > 0 then
  2833. begin
  2834. if GL.VERSION_3_0 then
  2835. begin
  2836. Move(FLightStates.Position,
  2837. FShaderLightStates.Position,
  2838. SizeOf(FShaderLightStates.Position));
  2839. Move(FLightStates.Ambient,
  2840. FShaderLightStates.Ambient,
  2841. SizeOf(FShaderLightStates.Ambient));
  2842. Move(FLightStates.Diffuse,
  2843. FShaderLightStates.Diffuse,
  2844. SizeOf(FShaderLightStates.Diffuse));
  2845. Move(FLightStates.Specular,
  2846. FShaderLightStates.Specular,
  2847. SizeOf(FShaderLightStates.Specular));
  2848. Move(FLightStates.SpotDirection,
  2849. FShaderLightStates.SpotDirection,
  2850. SizeOf(FShaderLightStates.SpotDirection));
  2851. Move(FLightStates.SpotCosCutoffExponent,
  2852. FShaderLightStates.SpotCosCutoffExponent,
  2853. SizeOf(FShaderLightStates.SpotCosCutoffExponent));
  2854. Move(FLightStates.Attenuation,
  2855. FShaderLightStates.Attenuation,
  2856. SizeOf(FShaderLightStates.Attenuation));
  2857. end
  2858. else
  2859. begin
  2860. for I := C - 1 downto 0 do
  2861. begin
  2862. J := FLightIndices[I];
  2863. FShaderLightStates.Position[I] := FLightStates.Position[J];
  2864. FShaderLightStates.Ambient[I] := FLightStates.Ambient[J];
  2865. FShaderLightStates.Diffuse[I] := FLightStates.Diffuse[J];
  2866. FShaderLightStates.Specular[I] := FLightStates.Specular[J];
  2867. FShaderLightStates.SpotDirection[I] := FLightStates.SpotDirection[J];
  2868. FShaderLightStates.SpotCosCutoffExponent[I] := FLightStates.SpotCosCutoffExponent[J];
  2869. FShaderLightStates.Attenuation[I] := FLightStates.Attenuation[J];
  2870. end;
  2871. end;
  2872. end
  2873. else
  2874. FillChar(FShaderLightStatesChanged, SizeOf(FShaderLightStatesChanged), $00);
  2875. FShaderLightStatesChanged := False;
  2876. end;
  2877. Result := @FShaderLightStates;
  2878. end;
  2879. function TGLStateCache.GetLightPosition(I: Integer): TGLVector;
  2880. begin
  2881. Result := FLightStates.Position[I];
  2882. end;
  2883. procedure TGLStateCache.SetLightPosition(I: Integer; const Value: TGLVector);
  2884. begin
  2885. if not VectorEquals(Value, FLightStates.Position[I]) then
  2886. begin
  2887. FLightStates.Position[I] := Value;
  2888. FShaderLightStatesChanged := True;
  2889. if Assigned(FOnLightsChanged) then
  2890. FOnLightsChanged(Self);
  2891. end;
  2892. end;
  2893. function TGLStateCache.GetLightSpotDirection(I: Integer): TAffineVector;
  2894. begin
  2895. Result := AffineVectorMake(FLightStates.SpotDirection[I]);
  2896. end;
  2897. procedure TGLStateCache.SetLightSpotDirection(I: Integer; const Value: TAffineVector);
  2898. begin
  2899. if not VectorEquals(Value, AffineVectorMake(FLightStates.SpotDirection[I])) then
  2900. begin
  2901. FLightStates.SpotDirection[I] := VectorMake(Value);
  2902. FShaderLightStatesChanged := True;
  2903. if Assigned(FOnLightsChanged) then
  2904. FOnLightsChanged(Self);
  2905. end;
  2906. end;
  2907. function TGLStateCache.GetLightAmbient(I: Integer): TGLVector;
  2908. begin
  2909. Result := FLightStates.Ambient[I];
  2910. end;
  2911. procedure TGLStateCache.SetLightAmbient(I: Integer; const Value: TGLVector);
  2912. begin
  2913. if not VectorEquals(Value, FLightStates.Ambient[I]) or FInsideList then
  2914. begin
  2915. if FInsideList then
  2916. Include(FListStates[FCurrentList], sttLighting)
  2917. else
  2918. FLightStates.Ambient[I] := Value;
  2919. if FFFPLight then
  2920. gl.Lightfv(GL_LIGHT0 + I, GL_AMBIENT, @Value);
  2921. FShaderLightStatesChanged := True;
  2922. if Assigned(FOnLightsChanged) then
  2923. FOnLightsChanged(Self);
  2924. end;
  2925. end;
  2926. function TGLStateCache.GetLightDiffuse(I: Integer): TGLVector;
  2927. begin
  2928. Result := FLightStates.Diffuse[I];
  2929. end;
  2930. procedure TGLStateCache.SetLightDiffuse(I: Integer; const Value: TGLVector);
  2931. begin
  2932. if not VectorEquals(Value, FLightStates.Diffuse[I]) or FInsideList then
  2933. begin
  2934. if FInsideList then
  2935. Include(FListStates[FCurrentList], sttLighting)
  2936. else
  2937. FLightStates.Diffuse[I] := Value;
  2938. if FFFPLight then
  2939. gl.Lightfv(GL_LIGHT0 + I, GL_DIFFUSE, @Value);
  2940. FShaderLightStatesChanged := True;
  2941. if Assigned(FOnLightsChanged) then
  2942. FOnLightsChanged(Self);
  2943. end;
  2944. end;
  2945. function TGLStateCache.GetLightSpecular(I: Integer): TGLVector;
  2946. begin
  2947. Result := FLightStates.Specular[I];
  2948. end;
  2949. procedure TGLStateCache.SetLightSpecular(I: Integer; const Value: TGLVector);
  2950. begin
  2951. if not VectorEquals(Value, FLightStates.Specular[I]) or FInsideList then
  2952. begin
  2953. if FInsideList then
  2954. Include(FListStates[FCurrentList], sttLighting)
  2955. else
  2956. FLightStates.Specular[I] := Value;
  2957. if FFFPLight then
  2958. gl.Lightfv(GL_LIGHT0 + I, GL_SPECULAR, @Value);
  2959. FShaderLightStatesChanged := True;
  2960. if Assigned(FOnLightsChanged) then
  2961. FOnLightsChanged(Self);
  2962. end;
  2963. end;
  2964. function TGLStateCache.GetSpotCutoff(I: Integer): Single;
  2965. begin
  2966. Result := FSpotCutoff[I];
  2967. end;
  2968. procedure TGLStateCache.SetSpotCutoff(I: Integer; const Value: Single);
  2969. begin
  2970. if (Value <> FSpotCutoff[I]) or FInsideList then
  2971. begin
  2972. if FInsideList then
  2973. Include(FListStates[FCurrentList], sttLighting)
  2974. else
  2975. begin
  2976. FSpotCutoff[I] := Value;
  2977. FLightStates.SpotCosCutoffExponent[I].X := cos(DegToRadian(Value));
  2978. end;
  2979. if FFFPLight then
  2980. gl.Lightfv(GL_LIGHT0 + I, GL_SPOT_CUTOFF, @Value);
  2981. FShaderLightStatesChanged := True;
  2982. if Assigned(FOnLightsChanged) then
  2983. FOnLightsChanged(Self);
  2984. end;
  2985. end;
  2986. function TGLStateCache.GetSpotExponent(I: Integer): Single;
  2987. begin
  2988. Result := FLightStates.SpotCosCutoffExponent[I].Y;
  2989. end;
  2990. procedure TGLStateCache.SetSpotExponent(I: Integer; const Value: Single);
  2991. begin
  2992. if (Value <> FLightStates.SpotCosCutoffExponent[I].Y) or FInsideList then
  2993. begin
  2994. if FInsideList then
  2995. Include(FListStates[FCurrentList], sttLighting)
  2996. else
  2997. FLightStates.SpotCosCutoffExponent[I].Y := Value;
  2998. if FFFPLight then
  2999. gl.Lightfv(GL_LIGHT0 + I, GL_SPOT_EXPONENT, @Value);
  3000. FShaderLightStatesChanged := True;
  3001. if Assigned(FOnLightsChanged) then
  3002. FOnLightsChanged(Self);
  3003. end;
  3004. end;
  3005. function TGLStateCache.GetConstantAtten(I: Integer): Single;
  3006. begin
  3007. Result := FLightStates.Attenuation[I].X;
  3008. end;
  3009. procedure TGLStateCache.SetConstantAtten(I: Integer; const Value: Single);
  3010. begin
  3011. if (Value <> FLightStates.Attenuation[I].X) or FInsideList then
  3012. begin
  3013. if FInsideList then
  3014. Include(FListStates[FCurrentList], sttLighting)
  3015. else
  3016. FLightStates.Attenuation[I].X := Value;
  3017. if FFFPLight then
  3018. gl.Lightfv(GL_LIGHT0 + I, GL_CONSTANT_ATTENUATION, @Value);
  3019. FShaderLightStatesChanged := True;
  3020. if Assigned(FOnLightsChanged) then
  3021. FOnLightsChanged(Self);
  3022. end;
  3023. end;
  3024. function TGLStateCache.GetLinearAtten(I: Integer): Single;
  3025. begin
  3026. Result := FLightStates.Attenuation[I].Y;
  3027. end;
  3028. procedure TGLStateCache.SetLinearAtten(I: Integer; const Value: Single);
  3029. begin
  3030. if (Value <> FLightStates.Attenuation[I].Y) or FInsideList then
  3031. begin
  3032. if FInsideList then
  3033. Include(FListStates[FCurrentList], sttLighting)
  3034. else
  3035. FLightStates.Attenuation[I].Y := Value;
  3036. if FFFPLight then
  3037. gl.Lightfv(GL_LIGHT0 + I, GL_LINEAR_ATTENUATION, @Value);
  3038. FShaderLightStatesChanged := True;
  3039. if Assigned(FOnLightsChanged) then
  3040. FOnLightsChanged(Self);
  3041. end;
  3042. end;
  3043. function TGLStateCache.GetQuadAtten(I: Integer): Single;
  3044. begin
  3045. Result := FLightStates.Attenuation[I].Z;
  3046. end;
  3047. procedure TGLStateCache.SetQuadAtten(I: Integer; const Value: Single);
  3048. begin
  3049. if (Value <> FLightStates.Attenuation[I].Z) or FInsideList then
  3050. begin
  3051. if FInsideList then
  3052. Include(FListStates[FCurrentList], sttLighting)
  3053. else
  3054. FLightStates.Attenuation[I].Z := Value;
  3055. if FFFPLight then
  3056. gl.Lightfv(GL_LIGHT0 + I, GL_QUADRATIC_ATTENUATION, @Value);
  3057. FShaderLightStatesChanged := True;
  3058. if Assigned(FOnLightsChanged) then
  3059. FOnLightsChanged(Self);
  3060. end;
  3061. end;
  3062. procedure TGLStateCache.SetForwardContext(Value: Boolean);
  3063. begin
  3064. { if Value <> FForwardContext then
  3065. begin
  3066. FForwardContext := Value;
  3067. if Value then
  3068. begin
  3069. SetFFPlight(False);
  3070. end;
  3071. end;
  3072. }
  3073. end;
  3074. procedure TGLStateCache.SetColorWriting(flag: Boolean);
  3075. begin
  3076. if (FColorWriting <> flag) or FInsideList then
  3077. begin
  3078. if FInsideList then
  3079. Include(FListStates[FCurrentList], sttColorBuffer)
  3080. else
  3081. FColorWriting := flag;
  3082. gl.ColorMask(flag, flag, flag, flag);
  3083. end;
  3084. end;
  3085. procedure TGLStateCache.InvertFrontFace;
  3086. begin
  3087. if FFrontFace = fwCounterClockWise then
  3088. FrontFace := fwClockWise
  3089. else
  3090. FrontFace := fwCounterClockWise;
  3091. end;
  3092. procedure TGLStateCache.SetGLState(const aState: TGLState);
  3093. begin
  3094. Enable(aState);
  3095. end;
  3096. procedure TGLStateCache.UnSetGLState(const aState: TGLState);
  3097. begin
  3098. Disable(aState);
  3099. end;
  3100. procedure TGLStateCache.ResetGLPolygonMode;
  3101. begin
  3102. gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  3103. FPolygonMode := pmFill;
  3104. FPolygonBackMode := pmFill;
  3105. end;
  3106. procedure TGLStateCache.ResetGLMaterialColors;
  3107. begin
  3108. gl.Materialfv(GL_FRONT_AND_BACK, GL_AMBIENT, @clrGray20);
  3109. gl.Materialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, @clrGray80);
  3110. gl.Materialfv(GL_FRONT_AND_BACK, GL_SPECULAR, @clrBlack);
  3111. gl.Materialfv(GL_FRONT_AND_BACK, GL_EMISSION, @clrBlack);
  3112. gl.Materiali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
  3113. FillChar(FFrontBackColors, SizeOf(FFrontBackColors), 127);
  3114. FFrontBackShininess[0] := 0;
  3115. FFrontBackShininess[1] := 0;
  3116. end;
  3117. procedure TGLStateCache.ResetGLTexture(const TextureUnit: Integer);
  3118. var
  3119. t: TGLTextureTarget;
  3120. glTarget: Cardinal;
  3121. begin
  3122. gl.ActiveTexture(GL_TEXTURE0 + TextureUnit);
  3123. for t := Low(TGLTextureTarget) to High(TGLTextureTarget) do
  3124. begin
  3125. glTarget := DecodeTextureTarget(t);
  3126. if IsTargetSupported(glTarget) then
  3127. begin
  3128. gl.BindTexture(glTarget, 0);
  3129. FTextureBinding[TextureUnit, t] := 0;
  3130. end;
  3131. end;
  3132. gl.ActiveTexture(GL_TEXTURE0);
  3133. FActiveTexture := 0;
  3134. end;
  3135. procedure TGLStateCache.ResetGLCurrentTexture;
  3136. var
  3137. a: TGLint;
  3138. t: TGLTextureTarget;
  3139. glTarget: Cardinal;
  3140. begin
  3141. if GL.ARB_multitexture then
  3142. begin
  3143. for a := MaxTextureImageUnits - 1 to 0 do
  3144. begin
  3145. gl.ActiveTexture(GL_TEXTURE0 + a);
  3146. for t := Low(TGLTextureTarget) to High(TGLTextureTarget) do
  3147. begin
  3148. glTarget := DecodeTextureTarget(t);
  3149. if IsTargetSupported(glTarget) then
  3150. begin
  3151. gl.BindTexture(glTarget, 0);
  3152. FTextureBinding[a, t] := 0;
  3153. end;
  3154. end;
  3155. end;
  3156. end
  3157. else
  3158. for t := Low(TGLTextureTarget) to High(TGLTextureTarget) do
  3159. begin
  3160. glTarget := DecodeTextureTarget(t);
  3161. if IsTargetSupported(glTarget) then
  3162. begin
  3163. gl.BindTexture(glTarget, 0);
  3164. FTextureBinding[0, t] := 0;
  3165. end;
  3166. end;
  3167. end;
  3168. procedure TGLStateCache.ResetGLFrontFace;
  3169. begin
  3170. gl.FrontFace(GL_CCW);
  3171. FFrontFace := fwCounterClockWise;
  3172. end;
  3173. procedure TGLStateCache.SetGLFrontFaceCW;
  3174. begin
  3175. if FFrontFace = fwCounterClockWise then
  3176. begin
  3177. gl.FrontFace(GL_CW);
  3178. FFrontFace := fwClockWise;
  3179. end;
  3180. end;
  3181. procedure TGLStateCache.ResetAll;
  3182. begin
  3183. {$WARN SYMBOL_DEPRECATED OFF}
  3184. ResetGLPolygonMode;
  3185. ResetGLMaterialColors;
  3186. ResetGLCurrentTexture;
  3187. ResetGLFrontFace;
  3188. {$WARN SYMBOL_DEPRECATED ON}
  3189. end;
  3190. end.