GLS.State.pas 118 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521
  1. //
  2. // The multimedia graphics platform 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.inc}
  22. { .$DEFINE USE_CACHE_MISS_CHECK }
  23. uses
  24. Winapi.OpenGL,
  25. Winapi.OpenGLext,
  26. System.Classes,
  27. System.SysUtils,
  28. GLS.OpenGLTokens,
  29. GLS.VectorTypes,
  30. GLS.VectorGeometry,
  31. GLS.TextureFormat,
  32. GLS.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
  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 SetGLTextureMatrix(const matrix: TGLMatrix); inline;
  858. procedure ResetGLTextureMatrix; inline;
  859. procedure ResetAllGLTextureMatrix; inline;
  860. // note: needs to change to per draw-buffer
  861. procedure SetGLColorWriting(flag: Boolean); inline;
  862. // Inverts front face winding (CCW/CW)
  863. procedure InvertGLFrontFace; 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 = (GL_CURRENT_BIT, GL_POINT_BIT, GL_LINE_BIT, GL_POLYGON_BIT,
  877. GL_POLYGON_STIPPLE_BIT, GL_PIXEL_MODE_BIT, GL_LIGHTING_BIT, GL_FOG_BIT, GL_DEPTH_BUFFER_BIT, GL_ACCUM_BUFFER_BIT,
  878. GL_STENCIL_BUFFER_BIT, GL_VIEWPORT_BIT, GL_TRANSFORM_BIT, GL_ENABLE_BIT, GL_COLOR_BUFFER_BIT, GL_HINT_BIT, GL_EVAL_BIT,
  879. GL_LIST_BIT, GL_TEXTURE_BIT, GL_SCISSOR_BIT, GL_MULTISAMPLE_BIT);
  880. {$WARN SYMBOL_DEPRECATED ON}
  881. cGLStateToGLEnum: array[TGLState] of TStateRecord =
  882. ((GLConst: GL_ALPHA_TEST; GLDeprecated: True),
  883. (GLConst: GL_AUTO_NORMAL; GLDeprecated: True),
  884. (GLConst: GL_BLEND; GLDeprecated: False),
  885. (GLConst: GL_COLOR_MATERIAL; GLDeprecated: True),
  886. (GLConst: GL_CULL_FACE; GLDeprecated: False),
  887. (GLConst: GL_DEPTH_TEST; GLDeprecated: False),
  888. (GLConst: GL_DITHER; GLDeprecated: False),
  889. (GLConst: GL_FOG; GLDeprecated: True),
  890. (GLConst: GL_LIGHTING; GLDeprecated: True),
  891. (GLConst: GL_LINE_SMOOTH; GLDeprecated: True),
  892. (GLConst: GL_LINE_STIPPLE; GLDeprecated: True),
  893. (GLConst: GL_INDEX_LOGIC_OP; GLDeprecated: True),
  894. (GLConst: GL_COLOR_LOGIC_OP; GLDeprecated: False),
  895. (GLConst: GL_NORMALIZE; GLDeprecated: True),
  896. (GLConst: GL_POINT_SMOOTH; GLDeprecated: True),
  897. (GLConst: GL_POINT_SPRITE; GLDeprecated: True),
  898. (GLConst: GL_POLYGON_SMOOTH; GLDeprecated: True),
  899. (GLConst: GL_POLYGON_STIPPLE; GLDeprecated: True),
  900. (GLConst: GL_SCISSOR_TEST; GLDeprecated: False),
  901. (GLConst: GL_STENCIL_TEST; GLDeprecated: False),
  902. (GLConst: GL_POLYGON_OFFSET_POINT; GLDeprecated: False),
  903. (GLConst: GL_POLYGON_OFFSET_LINE; GLDeprecated: False),
  904. (GLConst: GL_POLYGON_OFFSET_FILL; GLDeprecated: False),
  905. (GLConst: GL_DEPTH_CLAMP; GLDeprecated: False)
  906. );
  907. cGLTexTypeToGLEnum: array[TGLTextureTarget] of Cardinal =
  908. (0, GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_1D_ARRAY,
  909. GL_TEXTURE_2D_ARRAY, GL_TEXTURE_RECTANGLE, GL_TEXTURE_BUFFER,
  910. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D_MULTISAMPLE,
  911. GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY);
  912. cGLQueryTypeToGLEnum: array[TGLQueryType] of Cardinal =
  913. (GL_SAMPLES_PASSED, GL_PRIMITIVES_GENERATED,
  914. GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN,
  915. GL_TIME_ELAPSED, GL_ANY_SAMPLES_PASSED);
  916. cGLStencilOpToGLEnum: array[TGLStencilOp] of Cardinal =
  917. (GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT, GL_INCR_WRAP,
  918. GL_DECR_WRAP);
  919. cGLLogicOpToGLEnum: array[TGLLogicOp] of Cardinal =
  920. (GL_CLEAR, GL_AND, GL_AND_REVERSE, GL_COPY, GL_AND_INVERTED, GL_NOOP,
  921. GL_XOR, GL_OR, GL_NOR, GL_EQUIV, GL_INVERT, GL_OR_REVERSE,
  922. GL_COPY_INVERTED, GL_OR_INVERTED, GL_NAND, GL_SET);
  923. cGLComparisonFunctionToGLEnum: array[TGLComparisonFunction] of Cardinal =
  924. (GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GREATER,
  925. GL_NOTEQUAL, GL_GEQUAL);
  926. cGLBlendFunctionToGLEnum: array[TGLBlendFunction] of Cardinal =
  927. (GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR,
  928. GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
  929. GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_CONSTANT_COLOR,
  930. GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_ALPHA,
  931. GL_ONE_MINUS_CONSTANT_ALPHA, GL_SRC_ALPHA_SATURATE {valid for src only});
  932. cGLBlendEquationToGLEnum: array[TGLBlendEquation] of Cardinal =
  933. (GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MIN,
  934. GL_MAX);
  935. cGLFaceWindingToGLEnum: array[TGLFaceWinding] of Cardinal =
  936. (GL_CCW, GL_CW);
  937. cGLPolygonModeToGLEnum: array[TGLPolygonMode] of Cardinal =
  938. (GL_FILL, GL_LINE, GL_POINT);
  939. cGLCullFaceModeToGLEnum: array[TGLCullFaceMode] of Cardinal =
  940. (GL_FRONT, GL_BACK, GL_FRONT_AND_BACK);
  941. cGLHintToGLEnum: array[TGLHintType] of Cardinal =
  942. (GL_DONT_CARE, GL_FASTEST, GL_NICEST);
  943. cGLBufferBindingTarget: array[TGLBufferBindingTarget] of Cardinal =
  944. (GL_UNIFORM_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER);
  945. //------------------------------------------------------
  946. implementation
  947. // ------------------------------------------------------
  948. uses
  949. GLS.Context,
  950. GLS.Color;
  951. // ------------------
  952. // ------------------ TGLStateCache ------------------
  953. // ------------------
  954. procedure TGLStateCache.BeginQuery(const target: TGLQueryType; const Value: Cardinal);
  955. begin
  956. Assert(FCurrentQuery[target] = 0, 'Can only have one query (of each type)' + ' running at a time');
  957. // Assert(glIsQuery(Value), 'Not a valid query');
  958. // if Value<>FCurrentQuery[Target] then
  959. begin
  960. FCurrentQuery[target] := Value;
  961. gl.BeginQuery(cGLQueryTypeToGLEnum[target], Value);
  962. end;
  963. end;
  964. constructor TGLStateCache.Create;
  965. var
  966. I: Integer;
  967. begin
  968. inherited;
  969. SetLength(FListStates, $FFFFF);
  970. FCurrentList := 0;
  971. // Material colors
  972. FFrontBackColors[0][0] := clrBlack;
  973. FFrontBackColors[0][1] := clrGray20;
  974. FFrontBackColors[0][2] := clrGray80;
  975. FFrontBackColors[0][3] := clrBlack;
  976. FFrontBackShininess[0] := 0;
  977. FFrontBackColors[1][0] := clrBlack;
  978. FFrontBackColors[1][1] := clrGray20;
  979. FFrontBackColors[1][2] := clrGray80;
  980. FFrontBackColors[1][3] := clrBlack;
  981. FFrontBackShininess[1] := 0;
  982. FAlphaFunc := cfAlways;
  983. // Lighting
  984. FFFPLight := True;
  985. FMaxLights := 0;
  986. FLightNumber := 0;
  987. for I := High(FLightEnabling) downto 0 do
  988. begin
  989. FLightEnabling[I] := False;
  990. FLightIndices[I] := 0;
  991. FLightStates.Position[I] := NullHmgVector;
  992. FLightStates.Ambient[I] := clrBlack;
  993. FLightStates.Diffuse[I] := clrBlack;
  994. FLightStates.Specular[I] := clrBlack;
  995. FLightStates.SpotDirection[I] := VectorMake(0.0, 0.0, -1.0, 0.0);
  996. FSpotCutoff[I] := 180.0;
  997. FLightStates.SpotCosCutoffExponent[I].X := -1;
  998. FLightStates.SpotCosCutoffExponent[I].Y := 0;
  999. FLightStates.Attenuation[I] := NullHmgVector;
  1000. end;
  1001. FLightStates.Diffuse[0] := clrWhite;
  1002. FLightStates.Specular[0] := clrWhite;
  1003. for I := High(FTextureMatrixIsIdentity) downto 0 do
  1004. FTextureMatrixIsIdentity[I] := False;
  1005. // FForwardContext := False;
  1006. // Vertex Array Data state
  1007. FVertexArrayBinding := 0;
  1008. FTextureBufferBinding := 0;
  1009. // Transformation state
  1010. // FViewPort := Rect(0,0,0,0); // (0, 0, Width, Height)
  1011. FDepthRange[0] := 0.0;
  1012. FDepthRange[1] := 1.0;
  1013. FillChar(FEnableClipDistance, sizeof(FEnableClipDistance), $00);
  1014. FEnableDepthClamp := False;
  1015. // Coloring state
  1016. FClampReadColor := GL_FIXED_ONLY;
  1017. FProvokingVertex := GL_LAST_VERTEX_CONVENTION;
  1018. // Rasterization state
  1019. FPointSize := 1.0;
  1020. FPointFadeThresholdSize := 1.0;
  1021. FPointSpriteCoordOrigin := GL_UPPER_LEFT;
  1022. FLineWidth := 1.0;
  1023. FLineStippleFactor := 1;
  1024. FLineStipplePattern := $FFFF;
  1025. FEnableLineSmooth := False;
  1026. FEnableCullFace := False;
  1027. FCullFaceMode := cmBack;
  1028. FFrontFace := fwCounterClockWise;
  1029. FEnablePolygonSmooth := False;
  1030. FPolygonMode := pmFill;
  1031. FPolygonOffsetFactor := 0.0;
  1032. FPolygonOffsetUnits := 0.0;
  1033. FEnablePolygonOffsetPoint := False;
  1034. FEnablePolygonOffsetLine := False;
  1035. FEnablePolygonOffsetFill := False;
  1036. // Multisample state
  1037. FEnableMultisample := True;
  1038. FEnableSampleAlphaToCoverage := False;
  1039. FEnableSampleAlphaToOne := False;
  1040. FEnableSampleCoverage := False;
  1041. FSampleCoverageValue := 1.0;
  1042. FSampleCoverageInvert := False;
  1043. FEnableSampleMask := False;
  1044. FillChar(FSampleMaskValue, sizeof(FSampleMaskValue), $FF);
  1045. // Texture state
  1046. FillChar(FTextureBinding, sizeof(FTextureBinding), $00);
  1047. FillChar(FActiveTextureEnabling, sizeof(FActiveTextureEnabling), $00);
  1048. // Active texture state
  1049. FActiveTexture := 0;
  1050. // Pixel operation state
  1051. FEnableScissorTest := False;
  1052. // FScissorBox := Rect(0, 0, Width, Height);
  1053. FEnableStencilTest := False;
  1054. FStencilFunc := cfAlways;
  1055. FStencilValueMask := $FFFFFFFF;
  1056. FStencilRef := 0;
  1057. FStencilFail := soKeep;
  1058. FStencilPassDepthFail := soKeep;
  1059. FStencilPassDepthPass := soKeep;
  1060. FStencilBackFunc := cfAlways;
  1061. FStencilBackValueMask := $FFFFFFFF;
  1062. FStencilBackRef := 0;
  1063. FStencilBackFail := soKeep;
  1064. FStencilBackPassDepthPass := soKeep;
  1065. FStencilBackPassDepthFail := soKeep;
  1066. FEnableDepthTest := False;
  1067. FDepthFunc := cfLess;
  1068. FillChar(FEnableBlend, sizeof(FEnableBlend), $0);
  1069. FBlendSrcRGB := bfOne;
  1070. FBlendSrcAlpha := bfOne;
  1071. FBlendDstRGB := bfZero;
  1072. FBlendDstAlpha := bfZero;
  1073. FBlendEquationRGB := beAdd;
  1074. FBlendEquationAlpha := beAdd;
  1075. FBlendColor := NullHmgVector;
  1076. FEnableFramebufferSRGB := False;
  1077. FEnableDither := True;
  1078. FEnableColorLogicOp := False;
  1079. FLogicOpMode := loCopy;
  1080. // Framebuffer control state
  1081. // for I := 0 to Length(FColorWriteMask) - 1 do
  1082. // FColorWriteMask[i] := [ccRed, ccGreen, ccBlue, ccAlpha];
  1083. FillChar(FColorWriteMask, sizeof(FColorWriteMask), $F);
  1084. FDepthWriteMask := True;
  1085. FStencilWriteMask := $FFFFFFFF;
  1086. FStencilBackWriteMask := $FFFFFFFF;
  1087. FColorClearValue := NullHmgVector;
  1088. FDepthClearValue := 1.0;
  1089. FStencilClearValue := 0;
  1090. // Framebuffer state
  1091. FDrawFrameBuffer := 0;
  1092. FReadFrameBuffer := 0;
  1093. // Renderbuffer state
  1094. FRenderBuffer := 0;
  1095. // Pixels state
  1096. FUnpackSwapBytes := False;
  1097. FUnpackLSBFirst := False;
  1098. FUnpackImageHeight := 0;
  1099. FUnpackSkipImages := 0;
  1100. FUnpackRowLength := 0;
  1101. FUnpackSkipRows := 0;
  1102. FUnpackSkipPixels := 0;
  1103. FUnpackAlignment := 4;
  1104. FPackSwapBytes := False;
  1105. FPackLSBFirst := False;
  1106. FPackImageHeight := 0;
  1107. FPackSkipImages := 0;
  1108. FPackRowLength := 0;
  1109. FPackSkipRows := 0;
  1110. FPackSkipPixels := 0;
  1111. FPackAlignment := 4;
  1112. FPixelPackBufferBinding := 0;
  1113. FPixelUnpackBufferBinding := 0;
  1114. // Program state
  1115. FCurrentProgram := 0;
  1116. FUniformBufferBinding := 0;
  1117. FillChar(FUBOStates[bbtUniform][0], sizeof(FUBOStates), $00);
  1118. // Vector + Geometry Shader state
  1119. for I := 0 to Length(FCurrentVertexAttrib) - 1 do
  1120. FCurrentVertexAttrib[I] := NullHmgPoint;
  1121. FEnableProgramPointSize := False;
  1122. // Transform Feedback state
  1123. FTransformFeedbackBufferBinding := 0;
  1124. // Hints state
  1125. FTextureCompressionHint := hintDontCare;
  1126. FPolygonSmoothHint := hintDontCare;
  1127. FFragmentShaderDerivitiveHint := hintDontCare;
  1128. FLineSmoothHint := hintDontCare;
  1129. // Misc state
  1130. FillChar(FCurrentQuery, sizeof(FCurrentQuery), $00);
  1131. FCopyReadBufferBinding := 0;
  1132. FCopyWriteBufferBinding := 0;
  1133. FEnableTextureCubeMapSeamless := False;
  1134. FInsideList := False;
  1135. end;
  1136. destructor TGLStateCache.Destroy;
  1137. begin
  1138. inherited;
  1139. end;
  1140. procedure TGLStateCache.EndQuery(const target: TGLQueryType);
  1141. begin
  1142. Assert(FCurrentQuery[target] <> 0, 'No query running');
  1143. FCurrentQuery[target] := 0;
  1144. gl.EndQuery(cGLQueryTypeToGLEnum[target]);
  1145. end;
  1146. procedure TGLStateCache.Enable(const aState: TGLState);
  1147. begin
  1148. { if cGLStateToGLEnum[aState].GLDeprecated and FForwardContext then
  1149. exit; }
  1150. if not(aState in FStates) or FInsideList then
  1151. begin
  1152. if FInsideList then
  1153. Include(FListStates[FCurrentList], sttEnable)
  1154. else
  1155. Include(FStates, aState);
  1156. {$IFDEF USE_CACHE_MISS_CHECK}
  1157. if gl.IsEnabled(cGLStateToGLEnum[aState].GLConst) then
  1158. GLSLogger.LogError(strStateCashMissing + 'Enable');
  1159. {$ENDIF}
  1160. gl.Enable(cGLStateToGLEnum[aState].GLConst);
  1161. end;
  1162. end;
  1163. procedure TGLStateCache.Disable(const aState: TGLState);
  1164. begin
  1165. { if cGLStateToGLEnum[aState].GLDeprecated and FForwardContext then
  1166. exit; }
  1167. if (aState in FStates) or FInsideList then
  1168. begin
  1169. if FInsideList then
  1170. Include(FListStates[FCurrentList], sttEnable)
  1171. else
  1172. Exclude(FStates, aState);
  1173. {$IFDEF USE_CACHE_MISS_CHECK}
  1174. if not gl.IsEnabled(cGLStateToGLEnum[aState].GLConst) then
  1175. GLSLogger.LogError(strStateCashMissing + 'Disable');
  1176. {$ENDIF}
  1177. gl.Disable(cGLStateToGLEnum[aState].GLConst);
  1178. if aState = stColorMaterial then
  1179. if FInsideList then
  1180. Include(FListStates[FCurrentList], sttLighting)
  1181. else
  1182. begin
  1183. gl.Materialfv(GL_FRONT, GL_EMISSION, @FFrontBackColors[0][0]);
  1184. gl.Materialfv(GL_FRONT, GL_AMBIENT, @FFrontBackColors[0][1]);
  1185. gl.Materialfv(GL_FRONT, GL_DIFFUSE, @FFrontBackColors[0][2]);
  1186. gl.Materialfv(GL_FRONT, GL_SPECULAR, @FFrontBackColors[0][3]);
  1187. gl.Materiali(GL_FRONT, GL_SHININESS, FFrontBackShininess[0]);
  1188. gl.Materialfv(GL_BACK, GL_EMISSION, @FFrontBackColors[1][0]);
  1189. gl.Materialfv(GL_BACK, GL_AMBIENT, @FFrontBackColors[1][1]);
  1190. gl.Materialfv(GL_BACK, GL_DIFFUSE, @FFrontBackColors[1][2]);
  1191. gl.Materialfv(GL_BACK, GL_SPECULAR, @FFrontBackColors[1][3]);
  1192. gl.Materiali(GL_BACK, GL_SHININESS, FFrontBackShininess[1]);
  1193. end;
  1194. end;
  1195. end;
  1196. procedure TGLStateCache.PerformEnable(const aState: TGLState);
  1197. begin
  1198. { if cGLStateToGLEnum[aState].GLDeprecated and FForwardContext then
  1199. exit; }
  1200. Include(FStates, aState);
  1201. gl.Enable(cGLStateToGLEnum[aState].GLConst);
  1202. end;
  1203. procedure TGLStateCache.PerformDisable(const aState: TGLState);
  1204. begin
  1205. { if cGLStateToGLEnum[aState].GLDeprecated and FForwardContext then
  1206. exit; }
  1207. Exclude(FStates, aState);
  1208. gl.Disable(cGLStateToGLEnum[aState].GLConst);
  1209. end;
  1210. procedure TGLStateCache.PopAttrib;
  1211. begin
  1212. // TODO: replace with proper client side push/pop
  1213. gl.PopAttrib();
  1214. end;
  1215. procedure TGLStateCache.PushAttrib(const stateTypes: TGLStateTypes);
  1216. var
  1217. tempFlag: Cardinal;
  1218. I: Integer;
  1219. begin
  1220. // TODO: replace with proper client side push/pop
  1221. tempFlag := 0;
  1222. for I := Integer(Low(TGLStateType)) to Integer(high(TGLStateType)) do
  1223. begin
  1224. if TGLStateType(I) in stateTypes then
  1225. begin
  1226. tempFlag := tempFlag or cGLStateTypeToGLEnum[TGLStateType(I)];
  1227. end;
  1228. end;
  1229. gl.PushAttrib(tempFlag);
  1230. end;
  1231. procedure TGLStateCache.SetGLMaterialColors(const aFace: TGLCullFaceMode;
  1232. const emission, ambient, diffuse, specular: TGLVector;
  1233. const shininess: Integer);
  1234. var
  1235. I: Integer;
  1236. currentFace: Cardinal;
  1237. begin
  1238. { if FForwardContext then
  1239. exit; }
  1240. Assert((aFace = cmFront) or (aFace = cmBack), 'Only cmFront or cmBack supported');
  1241. I := Integer(aFace);
  1242. currentFace := cGLCullFaceModeToGLEnum[aFace];
  1243. if FInsideList then
  1244. begin
  1245. gl.Materiali(currentFace, GL_SHININESS, shininess);
  1246. gl.Materialfv(currentFace, GL_EMISSION, @emission);
  1247. gl.Materialfv(currentFace, GL_AMBIENT, @Ambient);
  1248. gl.Materialfv(currentFace, GL_DIFFUSE, @Diffuse);
  1249. gl.Materialfv(currentFace, GL_SPECULAR, @Specular);
  1250. Include(FListStates[FCurrentList], sttLighting);
  1251. end
  1252. else
  1253. begin
  1254. if (FFrontBackShininess[I] <> shininess) then
  1255. begin
  1256. gl.Materiali(currentFace, GL_SHININESS, shininess);
  1257. FFrontBackShininess[I] := shininess;
  1258. end;
  1259. if not AffineVectorEquals(FFrontBackColors[I][0], emission) then
  1260. begin
  1261. gl.Materialfv(currentFace, GL_EMISSION, @emission);
  1262. SetVector(FFrontBackColors[I][0], emission);
  1263. end;
  1264. if not AffineVectorEquals(FFrontBackColors[I][1], Ambient) then
  1265. begin
  1266. gl.Materialfv(currentFace, GL_AMBIENT, @Ambient);
  1267. SetVector(FFrontBackColors[I][1], Ambient);
  1268. end;
  1269. if not VectorEquals(FFrontBackColors[I][2], Diffuse) then
  1270. begin
  1271. gl.Materialfv(currentFace, GL_DIFFUSE, @Diffuse);
  1272. SetVector(FFrontBackColors[I][2], Diffuse);
  1273. end;
  1274. if not AffineVectorEquals(FFrontBackColors[I][3], Specular) then
  1275. begin
  1276. gl.Materialfv(currentFace, GL_SPECULAR, @Specular);
  1277. SetVector(FFrontBackColors[I][3], Specular);
  1278. end;
  1279. end;
  1280. end;
  1281. procedure TGLStateCache.SetGLMaterialAlphaChannel(const aFace: Cardinal; const alpha: TGLfloat);
  1282. var
  1283. I: Integer;
  1284. color: TVector4f;
  1285. begin
  1286. { if FForwardContext then Exit; }
  1287. if not(stLighting in FStates) then
  1288. begin
  1289. // We need a temp variable, because FColor is cauched.
  1290. gl.GetFloatv(GL_CURRENT_COLOR, @color);
  1291. color.W := alpha;
  1292. gl.Color4fv(@color);
  1293. end
  1294. else
  1295. begin
  1296. I := aFace - GL_FRONT;
  1297. if (FFrontBackColors[I][2].W <> alpha) or FInsideList then
  1298. begin
  1299. if FInsideList then
  1300. begin
  1301. Include(FListStates[FCurrentList], sttLighting);
  1302. gl.Materialfv(aFace, GL_DIFFUSE, @FFrontBackColors[I][2]);
  1303. end
  1304. else
  1305. begin
  1306. FFrontBackColors[I][2].W := alpha;
  1307. gl.Materialfv(aFace, GL_DIFFUSE, @FFrontBackColors[I][2]);
  1308. end;
  1309. end;
  1310. end;
  1311. end;
  1312. procedure TGLStateCache.SetGLMaterialDiffuseColor(const aFace: Cardinal; const Diffuse: TGLVector);
  1313. var
  1314. I: Integer;
  1315. begin
  1316. { if FForwardContext then Exit; }
  1317. if not(stLighting in FStates) then
  1318. begin
  1319. gl.Color4fv(@Diffuse);
  1320. end
  1321. else
  1322. begin
  1323. //
  1324. I := aFace - GL_FRONT;
  1325. if (not VectorEquals(FFrontBackColors[I][2], Diffuse)) or FInsideList then
  1326. begin
  1327. if FInsideList then
  1328. begin
  1329. Include(FListStates[FCurrentList], sttLighting);
  1330. gl.Materialfv(aFace, GL_DIFFUSE, @FFrontBackColors[I][2]);
  1331. end
  1332. else
  1333. begin
  1334. FFrontBackColors[I][2] := Diffuse;
  1335. gl.Materialfv(aFace, GL_DIFFUSE, @Diffuse);
  1336. end;
  1337. end;
  1338. end;
  1339. end;
  1340. procedure TGLStateCache.SetActiveTexture(const Value: TGLint);
  1341. begin
  1342. if gl.ARB_multitexture then
  1343. if (Value <> FActiveTexture) or FInsideList then
  1344. begin
  1345. if FInsideList then
  1346. Include(FListStates[FCurrentList], sttTexture)
  1347. else
  1348. FActiveTexture := Value;
  1349. gl.ActiveTexture(GL_TEXTURE0 + Value);
  1350. end;
  1351. end;
  1352. procedure TGLStateCache.SetVertexArrayBinding(const Value: Cardinal);
  1353. begin
  1354. if Value <> FVertexArrayBinding then
  1355. begin
  1356. FVertexArrayBinding := Value;
  1357. gl.BindVertexArray(Value);
  1358. end;
  1359. end;
  1360. function TGLStateCache.GetArrayBufferBinding: Cardinal;
  1361. begin
  1362. Result := FArrayBufferBinding;
  1363. end;
  1364. procedure TGLStateCache.SetArrayBufferBinding(const Value: Cardinal);
  1365. begin
  1366. if (Value <> FArrayBufferBinding) or (FVertexArrayBinding <> 0) then
  1367. begin
  1368. FArrayBufferBinding := Value;
  1369. gl.BindBuffer(GL_ARRAY_BUFFER, Value);
  1370. end;
  1371. end;
  1372. function TGLStateCache.GetElementBufferBinding: Cardinal;
  1373. begin
  1374. Result := FElementBufferBinding
  1375. end;
  1376. procedure TGLStateCache.SetElementBufferBinding(const Value: Cardinal);
  1377. begin
  1378. if (Value <> FElementBufferBinding) or (FVertexArrayBinding <> 0) then
  1379. begin
  1380. FElementBufferBinding := Value;
  1381. gl.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, Value);
  1382. end;
  1383. end;
  1384. function TGLStateCache.GetEnablePrimitiveRestart: TGLboolean;
  1385. begin
  1386. Result := FEnablePrimitiveRestart;
  1387. end;
  1388. procedure TGLStateCache.SetEnablePrimitiveRestart(const enabled: TGLboolean);
  1389. begin
  1390. if enabled <> FEnablePrimitiveRestart then
  1391. begin
  1392. FEnablePrimitiveRestart := enabled;
  1393. if GL.NV_primitive_restart then
  1394. begin
  1395. if enabled then
  1396. gl.EnableClientState(GL_PRIMITIVE_RESTART_NV)
  1397. else
  1398. gl.DisableClientState(GL_PRIMITIVE_RESTART_NV);
  1399. end
  1400. else
  1401. begin
  1402. if enabled then
  1403. gl.Enable(GL_PRIMITIVE_RESTART)
  1404. else
  1405. gl.Disable(GL_PRIMITIVE_RESTART);
  1406. end;
  1407. end;
  1408. end;
  1409. function TGLStateCache.GetPrimitiveRestartIndex: Cardinal;
  1410. begin
  1411. Result := FPrimitiveRestartIndex;
  1412. end;
  1413. procedure TGLStateCache.SetPrimitiveRestartIndex(const index: Cardinal);
  1414. begin
  1415. if index <> FPrimitiveRestartIndex then
  1416. begin
  1417. if gl.NV_primitive_restart then
  1418. begin
  1419. FPrimitiveRestartIndex := index;
  1420. gl.PrimitiveRestartIndex(index)
  1421. end;
  1422. end;
  1423. end;
  1424. procedure TGLStateCache.SetEnableProgramPointSize(const Value: TGLboolean);
  1425. begin
  1426. if Value <> FEnableProgramPointSize then
  1427. begin
  1428. FEnableProgramPointSize := Value;
  1429. if Value then
  1430. gl.Enable(GL_PROGRAM_POINT_SIZE)
  1431. else
  1432. gl.Disable(GL_PROGRAM_POINT_SIZE);
  1433. end;
  1434. end;
  1435. procedure TGLStateCache.SetBlendColor(const Value: TGLVector);
  1436. begin
  1437. if not VectorEquals(Value, FBlendColor) or FInsideList then
  1438. begin
  1439. if FInsideList then
  1440. Include(FListStates[FCurrentList], sttColorBuffer)
  1441. else
  1442. FBlendColor := Value;
  1443. gl.BlendColor(Value.X, Value.Y, Value.Z, Value.W);
  1444. end;
  1445. end;
  1446. procedure TGLStateCache.SetBlendEquationSeparate(const modeRGB, modeAlpha: TGLBlendEquation);
  1447. begin
  1448. if (modeRGB <> FBlendEquationRGB) or (modeAlpha <> FBlendEquationAlpha) or FInsideList then
  1449. begin
  1450. FBlendEquationRGB := modeRGB;
  1451. FBlendEquationAlpha := modeAlpha;
  1452. gl.BlendEquationSeparate(cGLBlendEquationToGLEnum[modeRGB], cGLBlendEquationToGLEnum[modeAlpha]);
  1453. end;
  1454. if FInsideList then
  1455. Include(FListStates[FCurrentList], sttColorBuffer);
  1456. end;
  1457. procedure TGLStateCache.SetBlendEquation(const mode: TGLBlendEquation);
  1458. begin
  1459. if (mode <> FBlendEquationRGB) or (mode <> FBlendEquationAlpha) or FInsideList then
  1460. begin
  1461. if FInsideList then
  1462. Include(FListStates[FCurrentList], sttColorBuffer)
  1463. else
  1464. begin
  1465. FBlendEquationRGB := mode;
  1466. FBlendEquationAlpha := mode;
  1467. end;
  1468. gl.BlendEquation(cGLBlendEquationToGLEnum[mode]);
  1469. end;
  1470. end;
  1471. procedure TGLStateCache.SetBlendFunc(const Src: TGLBlendFunction; const Dst: TGLDstBlendFunction);
  1472. begin
  1473. if (Src <> FBlendSrcRGB) or (Dst <> FBlendDstRGB) or FInsideList then
  1474. begin
  1475. if FInsideList then
  1476. Include(FListStates[FCurrentList], sttColorBuffer)
  1477. else
  1478. begin
  1479. FBlendSrcRGB := Src;
  1480. FBlendDstRGB := Dst;
  1481. FBlendSrcAlpha := Src;
  1482. FBlendSrcAlpha := Dst;
  1483. end;
  1484. gl.BlendFunc(cGLBlendFunctionToGLEnum[Src], cGLBlendFunctionToGLEnum[Dst]);
  1485. end;
  1486. end;
  1487. procedure TGLStateCache.SetBlendFuncSeparate(const SrcRGB: TGLBlendFunction;
  1488. const DstRGB: TGLDstBlendFunction; const SrcAlpha: TGLBlendFunction; const DstAlpha: TGLDstBlendFunction);
  1489. begin
  1490. if (SrcRGB <> FBlendSrcRGB) or (DstRGB <> FBlendDstRGB) or
  1491. (SrcAlpha <> FBlendSrcAlpha) or (DstAlpha <> FBlendDstAlpha)
  1492. or FInsideList then
  1493. begin
  1494. if FInsideList then
  1495. Include(FListStates[FCurrentList], sttColorBuffer)
  1496. else
  1497. begin
  1498. FBlendSrcRGB := SrcRGB;
  1499. FBlendDstRGB := DstRGB;
  1500. FBlendSrcAlpha := SrcAlpha;
  1501. FBlendDstAlpha := DstAlpha;
  1502. end;
  1503. gl.BlendFuncSeparate(
  1504. cGLBlendFunctionToGLEnum[SrcRGB],
  1505. cGLBlendFunctionToGLEnum[DstRGB],
  1506. cGLBlendFunctionToGLEnum[SrcAlpha],
  1507. cGLBlendFunctionToGLEnum[DstAlpha]);
  1508. end;
  1509. end;
  1510. procedure TGLStateCache.SetClampReadColor(const Value: Cardinal);
  1511. begin
  1512. if (Value <> FClampReadColor) or FInsideList then
  1513. begin
  1514. if FInsideList then
  1515. Include(FListStates[FCurrentList], sttColorBuffer)
  1516. else
  1517. FClampReadColor := Value;
  1518. gl.ClampColor(GL_CLAMP_READ_COLOR, Value);
  1519. end;
  1520. end;
  1521. procedure TGLStateCache.SetColorWriteMask(index: Integer; const Value: TGLColorMask);
  1522. begin
  1523. if FColorWriteMask[Index] <> Value then
  1524. begin
  1525. FColorWriteMask[Index] := Value;
  1526. gl.ColorMaski(Index, ccRed in Value, ccGreen in Value, ccBlue in Value, ccAlpha in Value);
  1527. end;
  1528. end;
  1529. procedure TGLStateCache.SetCopyReadBufferBinding(const Value: Cardinal);
  1530. begin
  1531. if Value <> FCopyReadBufferBinding then
  1532. begin
  1533. FCopyReadBufferBinding := Value;
  1534. gl.BindBuffer(GL_COPY_READ_BUFFER, Value);
  1535. end;
  1536. end;
  1537. procedure TGLStateCache.SetCopyWriteBufferBinding(const Value: Cardinal);
  1538. begin
  1539. if Value <> FCopyWriteBufferBinding then
  1540. begin
  1541. FCopyWriteBufferBinding := Value;
  1542. gl.BindBuffer(GL_COPY_WRITE_BUFFER, Value);
  1543. end;
  1544. end;
  1545. procedure TGLStateCache.SetCullFaceMode(const Value: TGLCullFaceMode);
  1546. begin
  1547. if (Value <> FCullFaceMode) or FInsideList then
  1548. begin
  1549. if FInsideList then
  1550. Include(FListStates[FCurrentList], sttPolygon)
  1551. else
  1552. FCullFaceMode := Value;
  1553. gl.CullFace(cGLCullFaceModeToGLEnum[Value]);
  1554. end;
  1555. end;
  1556. procedure TGLStateCache.SetCurrentProgram(const Value: Cardinal);
  1557. begin
  1558. if Value <> FCurrentProgram then
  1559. begin
  1560. FCurrentProgram := Value;
  1561. gl.UseProgram(Value);
  1562. end;
  1563. end;
  1564. procedure TGLStateCache.SetTextureBufferBinding(const Value: Cardinal);
  1565. begin
  1566. if Value <> FTextureBufferBinding then
  1567. begin
  1568. FTextureBufferBinding := Value;
  1569. gl.BindBuffer(GL_TEXTURE_BUFFER, Value);
  1570. end;
  1571. end;
  1572. procedure TGLStateCache.SetCurrentVertexAttrib(index: Integer; const Value: TGLVector);
  1573. begin
  1574. if not VectorEquals(Value, FCurrentVertexAttrib[Index]) then
  1575. begin
  1576. FCurrentVertexAttrib[Index] := Value;
  1577. gl.VertexAttrib4fv(Index, @Value.X);
  1578. end;
  1579. end;
  1580. procedure TGLStateCache.SetDepthClearValue(const Value: TGLfloat);
  1581. begin
  1582. if (Value <> FDepthClearValue) or FInsideList then
  1583. begin
  1584. if FInsideList then
  1585. Include(FListStates[FCurrentList], sttDepthBuffer)
  1586. else
  1587. FDepthClearValue := Value;
  1588. gl.ClearDepth(Value);
  1589. end;
  1590. end;
  1591. procedure TGLStateCache.SetDepthFunc(const Value: TGLDepthFunction);
  1592. begin
  1593. if (Value <> FDepthFunc) or FInsideList then
  1594. begin
  1595. if FInsideList then
  1596. Include(FListStates[FCurrentList], sttDepthBuffer)
  1597. else
  1598. FDepthFunc := Value;
  1599. gl.DepthFunc(cGLComparisonFunctionToGLEnum[Value]);
  1600. end;
  1601. end;
  1602. procedure TGLStateCache.SetDepthRange(const ZNear, ZFar: TGLclampd);
  1603. begin
  1604. if (ZNear <> FDepthRange[0]) or (ZFar <> FDepthRange[1]) or FInsideList then
  1605. begin
  1606. if FInsideList then
  1607. Include(FListStates[FCurrentList], sttViewport)
  1608. else
  1609. begin
  1610. FDepthRange[0] := ZNear;
  1611. FDepthRange[1] := ZFar;
  1612. end;
  1613. gl.DepthRange(ZNear, ZFar);
  1614. end;
  1615. end;
  1616. procedure TGLStateCache.SetDepthRangeFar(const Value: TGLclampd);
  1617. begin
  1618. if (Value <> FDepthRange[1]) or FInsideList then
  1619. begin
  1620. if FInsideList then
  1621. Include(FListStates[FCurrentList], sttViewport)
  1622. else
  1623. FDepthRange[1] := Value;
  1624. gl.DepthRange(FDepthRange[0], Value);
  1625. end;
  1626. end;
  1627. procedure TGLStateCache.SetDepthRangeNear(const Value: TGLclampd);
  1628. begin
  1629. if (Value <> FDepthRange[0]) or FInsideList then
  1630. begin
  1631. if FInsideList then
  1632. Include(FListStates[FCurrentList], sttViewport)
  1633. else
  1634. FDepthRange[0] := Value;
  1635. gl.DepthRange(Value, FDepthRange[1]);
  1636. end;
  1637. end;
  1638. procedure TGLStateCache.SetDepthWriteMask(const Value: TGLboolean);
  1639. begin
  1640. if (Value <> FDepthWriteMask) or FInsideList then
  1641. begin
  1642. if FInsideList then
  1643. Include(FListStates[FCurrentList], sttDepthBuffer)
  1644. else
  1645. FDepthWriteMask := Value;
  1646. gl.DepthMask(Value);
  1647. end;
  1648. end;
  1649. procedure TGLStateCache.SetDrawFrameBuffer(const Value: Cardinal);
  1650. begin
  1651. if Value <> FDrawFrameBuffer then
  1652. begin
  1653. FDrawFrameBuffer := Value;
  1654. gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, Value);
  1655. end;
  1656. end;
  1657. procedure TGLStateCache.SetEnableBlend(index: Integer; const Value: TGLboolean);
  1658. begin
  1659. if FEnableBlend[Index] <> Value then
  1660. begin
  1661. FEnableBlend[Index] := Value;
  1662. if Value then
  1663. gl.Enablei(GL_BLEND, Index)
  1664. else
  1665. gl.Disablei(GL_BLEND, Index);
  1666. end;
  1667. end;
  1668. procedure TGLStateCache.SetEnableClipDistance(index: Cardinal; const Value: TGLboolean);
  1669. begin
  1670. if FEnableClipDistance[Index] <> Value then
  1671. begin
  1672. FEnableClipDistance[Index] := Value;
  1673. if Value then
  1674. gl.Enable(GL_CLIP_DISTANCE0 + Index)
  1675. else
  1676. gl.Disable(GL_CLIP_DISTANCE0 + Index);
  1677. end;
  1678. end;
  1679. procedure TGLStateCache.SetEnableColorLogicOp(const Value: TGLboolean);
  1680. begin
  1681. if Value <> FEnableColorLogicOp then
  1682. begin
  1683. FEnableColorLogicOp := Value;
  1684. if Value then
  1685. gl.Enable(GL_COLOR_LOGIC_OP)
  1686. else
  1687. gl.Disable(GL_COLOR_LOGIC_OP);
  1688. end;
  1689. end;
  1690. procedure TGLStateCache.SetEnableCullFace(const Value: TGLboolean);
  1691. begin
  1692. end;
  1693. procedure TGLStateCache.SetEnableDepthClamp(const enabled: TGLboolean);
  1694. begin
  1695. end;
  1696. procedure TGLStateCache.SetEnableDepthTest(const Value: TGLboolean);
  1697. begin
  1698. end;
  1699. procedure TGLStateCache.SetEnableDither(const Value: TGLboolean);
  1700. begin
  1701. end;
  1702. procedure TGLStateCache.SetEnableFramebufferSRGB(const Value: TGLboolean);
  1703. begin
  1704. end;
  1705. procedure TGLStateCache.SetEnableLineSmooth(const Value: TGLboolean);
  1706. begin
  1707. end;
  1708. procedure TGLStateCache.SetEnableMultisample(const Value: TGLboolean);
  1709. begin
  1710. end;
  1711. procedure TGLStateCache.SetEnablePolygonOffsetFill(const Value: TGLboolean);
  1712. begin
  1713. end;
  1714. procedure TGLStateCache.SetEnablePolygonOffsetLine(const Value: TGLboolean);
  1715. begin
  1716. end;
  1717. procedure TGLStateCache.SetEnablePolygonOffsetPoint(const Value: TGLboolean);
  1718. begin
  1719. end;
  1720. procedure TGLStateCache.SetEnablePolygonSmooth(const Value: TGLboolean);
  1721. begin
  1722. end;
  1723. procedure TGLStateCache.SetEnableSampleAlphaToCoverage(const Value: TGLboolean);
  1724. begin
  1725. if Value <> FEnableSampleAlphaToCoverage then
  1726. begin
  1727. FEnableSampleAlphaToCoverage := Value;
  1728. if Value then
  1729. gl.Enable(GL_SAMPLE_ALPHA_TO_COVERAGE)
  1730. else
  1731. gl.Disable(GL_SAMPLE_ALPHA_TO_COVERAGE);
  1732. end;
  1733. end;
  1734. procedure TGLStateCache.SetEnableSampleCoverage(const Value: TGLboolean);
  1735. begin
  1736. if Value <> FEnableSampleCoverage then
  1737. begin
  1738. FEnableSampleCoverage := Value;
  1739. if Value then
  1740. gl.Enable(GL_SAMPLE_COVERAGE)
  1741. else
  1742. gl.Disable(GL_SAMPLE_COVERAGE);
  1743. end;
  1744. end;
  1745. procedure TGLStateCache.SetEnableSampleMask(const Value: TGLboolean);
  1746. begin
  1747. if Value <> FEnableSampleMask then
  1748. begin
  1749. FEnableSampleMask := Value;
  1750. if Value then
  1751. gl.Enable(GL_SAMPLE_MASK)
  1752. else
  1753. gl.Disable(GL_SAMPLE_MASK);
  1754. end;
  1755. end;
  1756. procedure TGLStateCache.SetEnableSampleAlphaToOne(const Value: TGLboolean);
  1757. begin
  1758. if Value <> FEnableSampleAlphaToOne then
  1759. begin
  1760. FEnableSampleAlphaToOne := Value;
  1761. if Value then
  1762. gl.Enable(GL_SAMPLE_ALPHA_TO_ONE)
  1763. else
  1764. gl.Disable(GL_SAMPLE_ALPHA_TO_ONE);
  1765. end;
  1766. end;
  1767. procedure TGLStateCache.SetEnableScissorTest(const Value: TGLboolean);
  1768. begin
  1769. end;
  1770. procedure TGLStateCache.SetEnableStencilTest(const Value: TGLboolean);
  1771. begin
  1772. end;
  1773. procedure TGLStateCache.SetFragmentShaderDerivitiveHint(const Value: TGLHintType);
  1774. begin
  1775. if Value <> FFragmentShaderDerivitiveHint then
  1776. begin
  1777. if FInsideList then
  1778. Include(FListStates[FCurrentList], sttHint)
  1779. else
  1780. FFragmentShaderDerivitiveHint := Value;
  1781. gl.Hint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, cGLHintToGLEnum[Value]);
  1782. end;
  1783. end;
  1784. procedure TGLStateCache.SetMultisampleFilterHint(const Value: TGLHintType);
  1785. begin
  1786. if GL.NV_multisample_filter_hint then
  1787. if Value <> FMultisampleFilterHint then
  1788. begin
  1789. if FInsideList then
  1790. Include(FListStates[FCurrentList], sttHint)
  1791. else
  1792. FMultisampleFilterHint := Value;
  1793. gl.Hint(GL_MULTISAMPLE_FILTER_HINT_NV, cGLHintToGLEnum[Value]);
  1794. end;
  1795. end;
  1796. procedure TGLStateCache.SetFrameBuffer(const Value: Cardinal);
  1797. begin
  1798. if (Value <> FDrawFrameBuffer) or (Value <> FReadFrameBuffer) or FInsideList then
  1799. begin
  1800. FDrawFrameBuffer := Value;
  1801. FReadFrameBuffer := Value;
  1802. gl.BindFramebuffer(GL_FRAMEBUFFER, Value);
  1803. end;
  1804. end;
  1805. procedure TGLStateCache.SetFrontFace(const Value: TGLFaceWinding);
  1806. begin
  1807. if (Value <> FFrontFace) or FInsideList then
  1808. begin
  1809. if FInsideList then
  1810. Include(FListStates[FCurrentList], sttPolygon)
  1811. else
  1812. FFrontFace := Value;
  1813. gl.FrontFace(cGLFaceWindingToGLEnum[Value]);
  1814. end;
  1815. end;
  1816. procedure TGLStateCache.SetGLAlphaFunction(func: TGLComparisonFunction; ref: Single);
  1817. {$IFDEF USE_CACHE_MISS_CHECK}
  1818. var
  1819. I: Cardinal;
  1820. E: Single;
  1821. {$ENDIF}
  1822. begin
  1823. { if FForwardContext then
  1824. exit; }
  1825. {$IFDEF USE_CACHE_MISS_CHECK}
  1826. gl.GetIntegerv(GL_ALPHA_TEST_FUNC, @I);
  1827. if cGLComparisonFunctionToGLEnum[FAlphaFunc] <> I then
  1828. GLSLogger.LogError(strStateCashMissing + 'AlphaTest function');
  1829. gl.GetFloatv(GL_ALPHA_TEST_REF, @E);
  1830. if FAlphaRef <> E then
  1831. GLSLogger.LogError(strStateCashMissing + 'AlphaTest reference');
  1832. {$ENDIF}
  1833. if (FAlphaFunc <> func) or (FAlphaRef <> ref) or FInsideList then
  1834. begin
  1835. if FInsideList then
  1836. Include(FListStates[FCurrentList], sttColorBuffer)
  1837. else
  1838. begin
  1839. FAlphaFunc := func;
  1840. FAlphaRef := ref;
  1841. end;
  1842. gl.AlphaFunc(cGLComparisonFunctionToGLEnum[func], ref);
  1843. end;
  1844. end;
  1845. function TGLStateCache.GetColorWriteMask(index: Integer): TGLColorMask;
  1846. begin
  1847. Result := FColorWriteMask[Index];
  1848. end;
  1849. function TGLStateCache.GetCurrentQuery(index: TGLQueryType): Cardinal;
  1850. begin
  1851. Result := FCurrentQuery[Index];
  1852. end;
  1853. function TGLStateCache.GetCurrentVertexAttrib(index: Integer): TGLVector;
  1854. begin
  1855. Result := FCurrentVertexAttrib[Index];
  1856. end;
  1857. function TGLStateCache.GetDepthRangeFar: TGLclampd;
  1858. begin
  1859. Result := FDepthRange[1];
  1860. end;
  1861. function TGLStateCache.GetDepthRangeNear: TGLclampd;
  1862. begin
  1863. Result := FDepthRange[0];
  1864. end;
  1865. function TGLStateCache.GetEnableBlend(index: Integer): TGLboolean;
  1866. begin
  1867. Result := FEnableBlend[Index];
  1868. end;
  1869. function TGLStateCache.GetEnableClipDistance(ClipDistance: Cardinal): TGLboolean;
  1870. begin
  1871. Result := FEnableClipDistance[ClipDistance];
  1872. end;
  1873. function TGLStateCache.GetSampleMaskValue(index: Integer): TGLbitfield;
  1874. begin
  1875. Result := FSampleMaskValue[Index];
  1876. end;
  1877. function TGLStateCache.GetMaxTextureSize: Cardinal;
  1878. begin
  1879. if FMaxTextureSize = 0 then
  1880. gl.GetIntegerv(GL_MAX_TEXTURE_SIZE, @FMaxTextureSize);
  1881. Result := FMaxTextureSize;
  1882. end;
  1883. function TGLStateCache.GetMaterialAmbient(const aFace: TGLCullFaceMode): TGLVector;
  1884. begin
  1885. Result := FFrontBackColors[ord(aFace)][1];
  1886. end;
  1887. function TGLStateCache.GetMaterialDiffuse(const aFace: TGLCullFaceMode): TGLVector;
  1888. begin
  1889. Result := FFrontBackColors[ord(aFace)][2];
  1890. end;
  1891. function TGLStateCache.GetMaterialEmission(const aFace: TGLCullFaceMode): TGLVector;
  1892. begin
  1893. Result := FFrontBackColors[ord(aFace)][0];
  1894. end;
  1895. function TGLStateCache.GetMaterialShininess(const aFace: TGLCullFaceMode): Integer;
  1896. begin
  1897. Result := FFrontBackShininess[ord(aFace)];
  1898. end;
  1899. function TGLStateCache.GetMaterialSpecular(const aFace: TGLCullFaceMode): TGLVector;
  1900. begin
  1901. Result := FFrontBackColors[ord(aFace)][3];
  1902. end;
  1903. function TGLStateCache.GetMax3DTextureSize: Cardinal;
  1904. begin
  1905. if FMax3DTextureSize = 0 then
  1906. gl.GetIntegerv(GL_MAX_3D_TEXTURE_SIZE, @FMax3DTextureSize);
  1907. Result := FMax3DTextureSize;
  1908. end;
  1909. function TGLStateCache.GetMaxCubeTextureSize: Cardinal;
  1910. begin
  1911. if FMaxCubeTextureSize = 0 then
  1912. gl.GetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, @FMaxCubeTextureSize);
  1913. Result := FMaxCubeTextureSize;
  1914. end;
  1915. function TGLStateCache.GetMaxArrayTextureSize: Cardinal;
  1916. begin
  1917. if FMaxArrayTextureSize = 0 then
  1918. gl.GetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, @FMaxArrayTextureSize);
  1919. Result := FMaxArrayTextureSize;
  1920. end;
  1921. function TGLStateCache.GetMaxTextureImageUnits: Cardinal;
  1922. begin
  1923. if FMaxTextureImageUnits = 0 then
  1924. gl.GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, @FMaxTextureImageUnits);
  1925. Result := FMaxTextureImageUnits;
  1926. end;
  1927. function TGLStateCache.GetMaxTextureAnisotropy: Cardinal;
  1928. begin
  1929. if (FMaxTextureAnisotropy = 0) and GL.EXT_texture_filter_anisotropic then
  1930. gl.GetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @FMaxTextureAnisotropy);
  1931. Result := FMaxTextureAnisotropy;
  1932. end;
  1933. function TGLStateCache.GetMaxSamples: Cardinal;
  1934. begin
  1935. if (FMaxSamples = 0) and GL.EXT_multisample then
  1936. gl.GetIntegerv(GL_MAX_SAMPLES, @FMaxSamples);
  1937. Result := FMaxSamples;
  1938. end;
  1939. function TGLStateCache.GetTextureBinding(index: Integer; target: TGLTextureTarget): Cardinal;
  1940. begin
  1941. Result := FTextureBinding[Index, target];
  1942. end;
  1943. function TGLStateCache.GetTextureBindingTime(index: Integer; target: TGLTextureTarget): Double;
  1944. begin
  1945. Result := FTextureBindingTime[Index, target];
  1946. end;
  1947. function TGLStateCache.GetSamplerBinding(index: Cardinal): Cardinal;
  1948. begin
  1949. Result := FSamplerBinding[Index];
  1950. end;
  1951. procedure TGLStateCache.SetSamplerBinding(index: Cardinal; const Value: Cardinal);
  1952. begin
  1953. if Index > High(FSamplerBinding) then
  1954. exit;
  1955. if (Value <> FSamplerBinding[Index]) or FInsideList then
  1956. begin
  1957. if FInsideList then
  1958. Include(FListStates[FCurrentList], sttTexture)
  1959. else
  1960. FSamplerBinding[Index] := Value;
  1961. gl.BindSampler(Index, Value);
  1962. end;
  1963. end;
  1964. procedure TGLStateCache.SetGLTextureMatrix(const matrix: TGLMatrix);
  1965. begin
  1966. { if FForwardContext then
  1967. exit; }
  1968. if FInsideList then
  1969. Include(FListStates[FCurrentList], sttTransform)
  1970. else
  1971. FTextureMatrixIsIdentity[ActiveTexture] := False;
  1972. gl.MatrixMode(GL_TEXTURE);
  1973. gl.LoadMatrixf(PGLFloat(@matrix.V[0].X));
  1974. gl.MatrixMode(GL_MODELVIEW);
  1975. end;
  1976. procedure TGLStateCache.ResetGLTextureMatrix;
  1977. begin
  1978. { if FForwardContext then
  1979. exit; }
  1980. gl.MatrixMode(GL_TEXTURE);
  1981. gl.LoadIdentity;
  1982. FTextureMatrixIsIdentity[ActiveTexture] := True;
  1983. gl.MatrixMode(GL_MODELVIEW);
  1984. end;
  1985. procedure TGLStateCache.ResetAllGLTextureMatrix;
  1986. var
  1987. I: Integer;
  1988. lastActiveTexture: Cardinal;
  1989. begin
  1990. { if FForwardContext then
  1991. exit; }
  1992. lastActiveTexture := ActiveTexture;
  1993. gl.MatrixMode(GL_TEXTURE);
  1994. for I := High(FTextureMatrixIsIdentity) downto 0 do
  1995. if not FTextureMatrixIsIdentity[I] then
  1996. begin
  1997. ActiveTexture := I;
  1998. gl.LoadIdentity;
  1999. FTextureMatrixIsIdentity[I] := True;
  2000. end;
  2001. gl.MatrixMode(GL_MODELVIEW);
  2002. ActiveTexture := lastActiveTexture;
  2003. end;
  2004. procedure TGLStateCache.SetLineSmoothHint(const Value: TGLHintType);
  2005. begin
  2006. if (Value <> FLineSmoothHint) or FInsideList then
  2007. begin
  2008. if FInsideList then
  2009. Include(FListStates[FCurrentList], sttHint)
  2010. else
  2011. FLineSmoothHint := Value;
  2012. gl.Hint(GL_LINE_SMOOTH_HINT, cGLHintToGLEnum[Value]);
  2013. end;
  2014. end;
  2015. procedure TGLStateCache.SetLineWidth(const Value: TGLfloat);
  2016. begin
  2017. // note: wide lines no longer deprecated (see OpenGL spec)
  2018. if (Value <> FLineWidth) or FInsideList then
  2019. begin
  2020. if FInsideList then
  2021. Include(FListStates[FCurrentList], sttLine)
  2022. else
  2023. FLineWidth := Value;
  2024. gl.LineWidth(Value);
  2025. end;
  2026. end;
  2027. procedure TGLStateCache.SetLineStippleFactor(const Value: TGLint);
  2028. begin
  2029. if (Value <> FLineStippleFactor) or FInsideList then
  2030. begin
  2031. if FInsideList then
  2032. Include(FListStates[FCurrentList], sttLine)
  2033. else
  2034. FLineStippleFactor := Value;
  2035. gl.LineStipple(Value, FLineStipplePattern);
  2036. end;
  2037. end;
  2038. procedure TGLStateCache.SetLineStipplePattern(const Value: TGLushort);
  2039. begin
  2040. if (Value <> FLineStipplePattern) or FInsideList then
  2041. begin
  2042. if FInsideList then
  2043. Include(FListStates[FCurrentList], sttLine)
  2044. else
  2045. FLineStipplePattern := Value;
  2046. gl.LineStipple(FLineStippleFactor, Value);
  2047. end;
  2048. end;
  2049. procedure TGLStateCache.SetLogicOpMode(const Value: TGLLogicOp);
  2050. begin
  2051. if (Value <> FLogicOpMode) or FInsideList then
  2052. begin
  2053. if FInsideList then
  2054. Include(FListStates[FCurrentList], sttColorBuffer)
  2055. else
  2056. FLogicOpMode := Value;
  2057. gl.LogicOp(cGLLogicOpToGLEnum[Value]);
  2058. end;
  2059. end;
  2060. procedure TGLStateCache.SetPackAlignment(const Value: Cardinal);
  2061. begin
  2062. if Value <> FPackAlignment then
  2063. begin
  2064. FPackAlignment := Value;
  2065. gl.PixelStoref(GL_PACK_ALIGNMENT, Value);
  2066. end;
  2067. end;
  2068. procedure TGLStateCache.SetPackImageHeight(const Value: Cardinal);
  2069. begin
  2070. if Value <> FPackImageHeight then
  2071. begin
  2072. FPackImageHeight := Value;
  2073. gl.PixelStoref(GL_PACK_IMAGE_HEIGHT, Value);
  2074. end;
  2075. end;
  2076. procedure TGLStateCache.SetPackLSBFirst(const Value: TGLboolean);
  2077. begin
  2078. if Value <> FPackLSBFirst then
  2079. begin
  2080. FPackLSBFirst := Value;
  2081. gl.PixelStorei(GL_PACK_LSB_FIRST, byte(Value));
  2082. end;
  2083. end;
  2084. procedure TGLStateCache.SetPackRowLength(const Value: Cardinal);
  2085. begin
  2086. if Value <> FPackRowLength then
  2087. begin
  2088. FPackRowLength := Value;
  2089. gl.PixelStoref(GL_PACK_ROW_LENGTH, Value);
  2090. end;
  2091. end;
  2092. procedure TGLStateCache.SetPackSkipImages(const Value: Cardinal);
  2093. begin
  2094. if Value <> FPackSkipImages then
  2095. begin
  2096. FPackSkipImages := Value;
  2097. gl.PixelStoref(GL_PACK_SKIP_IMAGES, Value);
  2098. end;
  2099. end;
  2100. procedure TGLStateCache.SetPackSkipPixels(const Value: Cardinal);
  2101. begin
  2102. if Value <> FPackSkipPixels then
  2103. begin
  2104. FPackSkipPixels := Value;
  2105. gl.PixelStoref(GL_PACK_SKIP_PIXELS, Value);
  2106. end;
  2107. end;
  2108. procedure TGLStateCache.SetPackSkipRows(const Value: Cardinal);
  2109. begin
  2110. if Value <> FPackSkipRows then
  2111. begin
  2112. FPackSkipRows := Value;
  2113. gl.PixelStoref(GL_PACK_SKIP_ROWS, Value);
  2114. end;
  2115. end;
  2116. procedure TGLStateCache.SetPackSwapBytes(const Value: TGLboolean);
  2117. begin
  2118. if Value <> FPackSwapBytes then
  2119. begin
  2120. FPackSwapBytes := Value;
  2121. gl.PixelStorei(GL_PACK_SWAP_BYTES, byte(Value));
  2122. end;
  2123. end;
  2124. procedure TGLStateCache.SetPixelPackBufferBinding(const Value: Cardinal);
  2125. begin
  2126. if Value <> FPixelPackBufferBinding then
  2127. begin
  2128. FPixelPackBufferBinding := Value;
  2129. gl.BindBuffer(GL_PIXEL_PACK_BUFFER, Value);
  2130. end;
  2131. end;
  2132. procedure TGLStateCache.SetPixelUnpackBufferBinding(const Value: Cardinal);
  2133. begin
  2134. if Value <> FPixelUnpackBufferBinding then
  2135. begin
  2136. FPixelUnpackBufferBinding := Value;
  2137. gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, Value);
  2138. end;
  2139. end;
  2140. procedure TGLStateCache.SetPointFadeThresholdSize(const Value: TGLfloat);
  2141. begin
  2142. if (Value <> FPointFadeThresholdSize) or FInsideList then
  2143. begin
  2144. if FInsideList then
  2145. Include(FListStates[FCurrentList], sttPoint)
  2146. else
  2147. FPointFadeThresholdSize := Value;
  2148. gl.PointParameterf(GL_POINT_FADE_THRESHOLD_SIZE, Value);
  2149. end;
  2150. end;
  2151. procedure TGLStateCache.SetPointSize(const Value: TGLfloat);
  2152. begin
  2153. if (Value <> FPointSize) or FInsideList then
  2154. begin
  2155. if FInsideList then
  2156. Include(FListStates[FCurrentList], sttPoint)
  2157. else
  2158. FPointSize := Value;
  2159. gl.PointSize(Value);
  2160. end;
  2161. end;
  2162. procedure TGLStateCache.SetPointSpriteCoordOrigin(const Value: Cardinal);
  2163. begin
  2164. if (Value <> FPointSpriteCoordOrigin) or FInsideList then
  2165. begin
  2166. if FInsideList then
  2167. Include(FListStates[FCurrentList], sttPoint)
  2168. else
  2169. FPointSpriteCoordOrigin := Value;
  2170. gl.PointParameterf(GL_POINT_SPRITE_COORD_ORIGIN, Value);
  2171. end;
  2172. end;
  2173. procedure TGLStateCache.SetPolygonMode(const Value: TGLPolygonMode);
  2174. begin
  2175. if (Value <> FPolygonMode) or FInsideList then
  2176. begin
  2177. if FInsideList then
  2178. Include(FListStates[FCurrentList], sttPolygon)
  2179. else
  2180. begin
  2181. FPolygonMode := Value;
  2182. FPolygonBackMode := Value;
  2183. end;
  2184. gl.PolygonMode(GL_FRONT_AND_BACK, cGLPolygonModeToGLEnum[Value]);
  2185. end;
  2186. end;
  2187. procedure TGLStateCache.SetPolygonOffset(const factor, units: TGLfloat);
  2188. begin
  2189. if (factor <> FPolygonOffsetFactor) or (units <> FPolygonOffsetUnits) or FInsideList then
  2190. begin
  2191. if FInsideList then
  2192. Include(FListStates[FCurrentList], sttPolygon)
  2193. else
  2194. begin
  2195. FPolygonOffsetFactor := factor;
  2196. FPolygonOffsetUnits := units;
  2197. end;
  2198. gl.PolygonOffset(factor, units);
  2199. end;
  2200. end;
  2201. procedure TGLStateCache.SetPolygonOffsetFactor(const Value: TGLfloat);
  2202. begin
  2203. if (Value <> FPolygonOffsetFactor) or FInsideList then
  2204. begin
  2205. if FInsideList then
  2206. Include(FListStates[FCurrentList], sttPolygon)
  2207. else
  2208. FPolygonOffsetFactor := Value;
  2209. gl.PolygonOffset(Value, FPolygonOffsetUnits);
  2210. end;
  2211. end;
  2212. procedure TGLStateCache.SetPolygonOffsetUnits(const Value: TGLfloat);
  2213. begin
  2214. if (Value <> FPolygonOffsetUnits) or FInsideList then
  2215. begin
  2216. if FInsideList then
  2217. Include(FListStates[FCurrentList], sttPolygon)
  2218. else
  2219. FPolygonOffsetUnits := Value;
  2220. gl.PolygonOffset(FPolygonOffsetFactor, Value);
  2221. end;
  2222. end;
  2223. procedure TGLStateCache.SetPolygonSmoothHint(const Value: TGLHintType);
  2224. begin
  2225. if (Value <> FPolygonSmoothHint) or FInsideList then
  2226. begin
  2227. if FInsideList then
  2228. Include(FListStates[FCurrentList], sttHint)
  2229. else
  2230. FPolygonSmoothHint := Value;
  2231. gl.Hint(GL_POLYGON_SMOOTH_HINT, cGLHintToGLEnum[Value]);
  2232. end;
  2233. end;
  2234. procedure TGLStateCache.SetProvokingVertex(const Value: Cardinal);
  2235. begin
  2236. if Value <> FProvokingVertex then
  2237. begin
  2238. FProvokingVertex := Value;
  2239. gl.ProvokingVertex(Value);
  2240. end;
  2241. end;
  2242. procedure TGLStateCache.SetReadFrameBuffer(const Value: Cardinal);
  2243. begin
  2244. if Value <> FReadFrameBuffer then
  2245. begin
  2246. FReadFrameBuffer := Value;
  2247. gl.BindFramebuffer(GL_READ_FRAMEBUFFER, Value);
  2248. end;
  2249. end;
  2250. procedure TGLStateCache.SetRenderBuffer(const Value: Cardinal);
  2251. begin
  2252. if Value <> FRenderBuffer then
  2253. begin
  2254. FRenderBuffer := Value;
  2255. gl.BindRenderbuffer(GL_RENDERBUFFER, Value);
  2256. end;
  2257. end;
  2258. procedure TGLStateCache.SetSampleCoverage(const Value: TGLfloat; invert: TGLboolean);
  2259. begin
  2260. if (Value <> FSampleCoverageValue) or (invert <> FSampleCoverageInvert) or FInsideList then
  2261. begin
  2262. if FInsideList then
  2263. Include(FListStates[FCurrentList], sttMultisample)
  2264. else
  2265. begin
  2266. FSampleCoverageValue := Value;
  2267. FSampleCoverageInvert := invert;
  2268. end;
  2269. gl.SampleCoverage(Value, invert);
  2270. end;
  2271. end;
  2272. procedure TGLStateCache.SetSampleCoverageInvert(const Value: TGLboolean);
  2273. begin
  2274. if (Value <> FSampleCoverageInvert) or FInsideList then
  2275. begin
  2276. if FInsideList then
  2277. Include(FListStates[FCurrentList], sttMultisample)
  2278. else
  2279. FSampleCoverageInvert := Value;
  2280. gl.SampleCoverage(FSampleCoverageValue, Value);
  2281. end;
  2282. end;
  2283. procedure TGLStateCache.SetSampleCoverageValue(const Value: TGLfloat);
  2284. begin
  2285. if (Value <> FSampleCoverageValue) or FInsideList then
  2286. begin
  2287. if FInsideList then
  2288. Include(FListStates[FCurrentList], sttMultisample)
  2289. else
  2290. FSampleCoverageValue := Value;
  2291. gl.SampleCoverage(Value, FSampleCoverageInvert);
  2292. end;
  2293. end;
  2294. procedure TGLStateCache.SetSampleMaskValue(index: Integer; const Value: TGLbitfield);
  2295. begin
  2296. if (FSampleMaskValue[Index] <> Value) or FInsideList then
  2297. begin
  2298. if FInsideList then
  2299. Include(FListStates[FCurrentList], sttMultisample)
  2300. else
  2301. FSampleMaskValue[Index] := Value;
  2302. gl.SampleMaski(Index, Value);
  2303. end;
  2304. end;
  2305. procedure TGLStateCache.SetScissorBox(const Value: TVector4i);
  2306. begin
  2307. if not VectorEquals(FScissorBox, Value) or FInsideList then
  2308. begin
  2309. if FInsideList then
  2310. Include(FListStates[FCurrentList], sttScissor)
  2311. else
  2312. FScissorBox := Value;
  2313. gl.Scissor(Value.X, Value.Y, Value.Z, Value.W);
  2314. end;
  2315. end;
  2316. procedure TGLStateCache.SetStencilBackWriteMask(const Value: Cardinal);
  2317. begin
  2318. if (Value <> FStencilBackWriteMask) or FInsideList then
  2319. begin
  2320. if FInsideList then
  2321. Include(FListStates[FCurrentList], sttStencilBuffer)
  2322. else
  2323. FStencilBackWriteMask := Value;
  2324. // DONE: ignore if unsupported
  2325. if gl.VERSION_2_0 then
  2326. gl.StencilMaskSeparate(GL_BACK, Value);
  2327. end;
  2328. end;
  2329. procedure TGLStateCache.SetStencilClearValue(const Value: Cardinal);
  2330. {$IFDEF USE_CACHE_MISS_CHECK}
  2331. var
  2332. I: Cardinal;
  2333. {$ENDIF}
  2334. begin
  2335. {$IFDEF USE_CACHE_MISS_CHECK}
  2336. gl.GetIntegerv(GL_STENCIL_CLEAR_VALUE, @I);
  2337. if FStencilClearValue <> I then
  2338. GLSLogger.LogError(strStateCashMissing + 'Stencil clear value');
  2339. {$ENDIF}
  2340. if (Value <> FStencilClearValue) or FInsideList then
  2341. begin
  2342. if FInsideList then
  2343. Include(FListStates[FCurrentList], sttStencilBuffer)
  2344. else
  2345. FStencilClearValue := Value;
  2346. gl.ClearStencil(Value);
  2347. end;
  2348. end;
  2349. procedure TGLStateCache.SetColorClearValue(const Value: TGLVector);
  2350. begin
  2351. if not VectorEquals(Value, FColorClearValue) or FInsideList then
  2352. begin
  2353. if FInsideList then
  2354. Include(FListStates[FCurrentList], sttColorBuffer)
  2355. else
  2356. FColorClearValue := Value;
  2357. gl.ClearColor(Value.X, Value.Y, Value.Z, Value.W);
  2358. end;
  2359. end;
  2360. procedure TGLStateCache.SetColorMask(mask: TGLColorMask);
  2361. var
  2362. I: Integer;
  2363. begin
  2364. // it might be faster to keep track of whether all draw buffers are same
  2365. // value or not, since using this is probably more common than setting
  2366. // the color write mask for individual draw buffers
  2367. if FInsideList then
  2368. Include(FListStates[FCurrentList], sttColorBuffer)
  2369. else
  2370. for I := low(FColorWriteMask) to high(FColorWriteMask) do
  2371. begin
  2372. FColorWriteMask[I] := mask;
  2373. end;
  2374. gl.ColorMask(ccRed in mask, ccGreen in mask, ccBlue in mask, ccAlpha in mask);
  2375. end;
  2376. procedure TGLStateCache.SetStencilFuncSeparate(const face: TGLCullFaceMode; const func: TGLStencilFunction; const ref: TGLint;
  2377. const mask: Cardinal);
  2378. {$IFDEF USE_CACHE_MISS_CHECK}
  2379. var
  2380. UI: Cardinal;
  2381. I: TGLint;
  2382. {$ENDIF}
  2383. begin
  2384. // if (func<>FStencilFunc) or (ref<>FStencilRef) or (mask<>FStencilValueMask)
  2385. // or FInsideList then
  2386. {$IFDEF USE_CACHE_MISS_CHECK}
  2387. gl.GetIntegerv(GL_STENCIL_FUNC, @UI);
  2388. if cGLComparisonFunctionToGLEnum[FStencilFunc] <> UI then
  2389. GLSLogger.LogError(strStateCashMissing + 'Stencil function');
  2390. gl.GetIntegerv(GL_STENCIL_REF, @I);
  2391. if FStencilRef <> I then
  2392. GLSLogger.LogError(strStateCashMissing + 'Stencil reference');
  2393. GLSLogger.LogError(strStateCashMissing + 'Stencil function');
  2394. gl.GetIntegerv(GL_STENCIL_VALUE_MASK, @UI);
  2395. if FStencilValueMask <> UI then
  2396. GLSLogger.LogError(strStateCashMissing + 'Stencil value mask');
  2397. {$ENDIF}
  2398. begin
  2399. if FInsideList then
  2400. Include(FListStates[FCurrentList], sttStencilBuffer)
  2401. else
  2402. case face of
  2403. cmFront:
  2404. begin
  2405. FStencilFunc := func;
  2406. FStencilRef := ref;
  2407. FStencilValueMask := mask;
  2408. end;
  2409. cmBack:
  2410. begin
  2411. FStencilBackFunc := func;
  2412. FStencilBackRef := ref;
  2413. FStencilBackValueMask := mask;
  2414. end;
  2415. cmFrontAndBack:
  2416. begin
  2417. FStencilFunc := func;
  2418. FStencilRef := ref;
  2419. FStencilValueMask := mask;
  2420. FStencilBackFunc := func;
  2421. FStencilBackRef := ref;
  2422. FStencilBackValueMask := mask;
  2423. end;
  2424. end;
  2425. gl.StencilFuncSeparate(cGLCullFaceModeToGLEnum[face], cGLComparisonFunctionToGLEnum[func], ref, mask);
  2426. end;
  2427. end;
  2428. procedure TGLStateCache.SetStencilFunc(const func: TGLStencilFunction; const ref: TGLint; const mask: Cardinal);
  2429. begin
  2430. if (func <> FStencilFunc) or (ref <> FStencilRef) or (mask <> FStencilValueMask) or FInsideList then
  2431. begin
  2432. if FInsideList then
  2433. Include(FListStates[FCurrentList], sttStencilBuffer)
  2434. else
  2435. begin
  2436. FStencilFunc := func;
  2437. FStencilRef := ref;
  2438. FStencilValueMask := mask;
  2439. end;
  2440. gl.StencilFunc(cGLComparisonFunctionToGLEnum[func], ref, mask);
  2441. end;
  2442. end;
  2443. procedure TGLStateCache.SetStencilOp(const fail, zfail, zpass: TGLStencilOp);
  2444. {$IFDEF USE_CACHE_MISS_CHECK}
  2445. var
  2446. I: Cardinal;
  2447. {$ENDIF}
  2448. begin
  2449. {$IFDEF USE_CACHE_MISS_CHECK}
  2450. gl.GetIntegerv(GL_STENCIL_FAIL, @I);
  2451. if cGLStencilOpToGLEnum[FStencilFail] <> I then
  2452. GLSLogger.LogError(strStateCashMissing + 'Stencil fail');
  2453. gl.GetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, @I);
  2454. if cGLStencilOpToGLEnum[FStencilPassDepthFail] <> I then
  2455. GLSLogger.LogError(strStateCashMissing + 'Stencil zfail');
  2456. gl.GetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, @I);
  2457. if cGLStencilOpToGLEnum[FStencilPassDepthPass] <> I then
  2458. GLSLogger.LogError(strStateCashMissing + 'Stencil zpass');
  2459. {$ENDIF}
  2460. if (fail <> FStencilFail) or (zfail <> FStencilPassDepthFail) or (zpass <> FStencilPassDepthPass) or FInsideList then
  2461. begin
  2462. if FInsideList then
  2463. Include(FListStates[FCurrentList], sttStencilBuffer)
  2464. else
  2465. begin
  2466. FStencilFail := fail;
  2467. FStencilPassDepthFail := zfail;
  2468. FStencilPassDepthPass := zpass;
  2469. end;
  2470. gl.StencilOp(cGLStencilOpToGLEnum[fail],
  2471. cGLStencilOpToGLEnum[zfail],
  2472. cGLStencilOpToGLEnum[zpass]);
  2473. end;
  2474. end;
  2475. procedure TGLStateCache.SetStencilOpSeparate(const face: TGLCullFaceMode; const sfail, dpfail, dppass: TGLStencilOp);
  2476. begin
  2477. if FInsideList then
  2478. Include(FListStates[FCurrentList], sttStencilBuffer)
  2479. else
  2480. case face of
  2481. cmFront:
  2482. begin
  2483. FStencilFail := sfail;
  2484. FStencilPassDepthFail := dpfail;
  2485. FStencilPassDepthPass := dppass;
  2486. end;
  2487. cmBack:
  2488. begin
  2489. FStencilBackFail := sfail;
  2490. FStencilBackPassDepthFail := dpfail;
  2491. FStencilBackPassDepthPass := dppass;
  2492. end;
  2493. cmFrontAndBack:
  2494. begin
  2495. FStencilFail := sfail;
  2496. FStencilPassDepthFail := dpfail;
  2497. FStencilPassDepthPass := dppass;
  2498. FStencilBackFail := sfail;
  2499. FStencilBackPassDepthFail := dpfail;
  2500. FStencilBackPassDepthPass := dppass;
  2501. end;
  2502. end;
  2503. gl.StencilOpSeparate(cGLCullFaceModeToGLEnum[face], cGLStencilOpToGLEnum[sfail], cGLStencilOpToGLEnum[dpfail],
  2504. cGLStencilOpToGLEnum[dppass]);
  2505. end;
  2506. procedure TGLStateCache.SetStencilWriteMask(const Value: Cardinal);
  2507. {$IFDEF USE_CACHE_MISS_CHECK}
  2508. var
  2509. I: Cardinal;
  2510. {$ENDIF}
  2511. begin
  2512. {$IFDEF USE_CACHE_MISS_CHECK}
  2513. gl.GetIntegerv(GL_STENCIL_WRITEMASK, @I);
  2514. if FStencilWriteMask <> I then
  2515. GLSLogger.LogError(strStateCashMissing + 'Stencil write mask');
  2516. {$ENDIF}
  2517. if (Value <> FStencilWriteMask) or FInsideList then
  2518. begin
  2519. if FInsideList then
  2520. Include(FListStates[FCurrentList], sttStencilBuffer)
  2521. else
  2522. FStencilWriteMask := Value;
  2523. gl.StencilMaskSeparate(GL_FRONT, Value);
  2524. end;
  2525. end;
  2526. procedure TGLStateCache.SetTextureBinding(index: Integer; target: TGLTextureTarget; const Value: Cardinal);
  2527. var
  2528. lastActiveTexture: Cardinal;
  2529. begin
  2530. if target = ttNoShape then
  2531. exit;
  2532. if (Value <> FTextureBinding[Index, target]) or FInsideList then
  2533. begin
  2534. if FInsideList then
  2535. Include(FListStates[FCurrentList], sttTexture)
  2536. else
  2537. FTextureBinding[Index, target] := Value;
  2538. lastActiveTexture := ActiveTexture;
  2539. ActiveTexture := Index;
  2540. gl.BindTexture(cGLTexTypeToGLEnum[target], Value);
  2541. ActiveTexture := lastActiveTexture;
  2542. end;
  2543. FTextureBindingTime[Index, target] := AppTime;
  2544. end;
  2545. function TGLStateCache.GetActiveTextureEnabled(target: TGLTextureTarget): Boolean;
  2546. begin
  2547. Result := FActiveTextureEnabling[FActiveTexture][target];
  2548. end;
  2549. procedure TGLStateCache.SetActiveTextureEnabled(target: TGLTextureTarget; const Value: Boolean);
  2550. var
  2551. glTarget: Cardinal;
  2552. begin
  2553. glTarget := DecodeTextureTarget(target);
  2554. if { FForwardContext or } not IsTargetSupported(glTarget) then
  2555. exit;
  2556. if (Value <> FActiveTextureEnabling[FActiveTexture][target]) or FInsideList then
  2557. begin
  2558. if FInsideList then
  2559. Include(FListStates[FCurrentList], sttEnable)
  2560. else
  2561. FActiveTextureEnabling[FActiveTexture][target] := Value;
  2562. if Value then
  2563. gl.Enable(glTarget)
  2564. else
  2565. gl.Disable(glTarget);
  2566. end;
  2567. end;
  2568. procedure TGLStateCache.SetTextureCompressionHint(const Value: TGLHintType);
  2569. begin
  2570. if (Value <> FTextureCompressionHint) or FInsideList then
  2571. begin
  2572. if FInsideList then
  2573. Include(FListStates[FCurrentList], sttHint)
  2574. else
  2575. FTextureCompressionHint := Value;
  2576. gl.Hint(GL_TEXTURE_COMPRESSION_HINT, cGLHintToGLEnum[Value]);
  2577. end;
  2578. end;
  2579. procedure TGLStateCache.SetTransformFeedbackBufferBinding(const Value: Cardinal);
  2580. begin
  2581. if (Value <> FTransformFeedbackBufferBinding) or FInsideList then
  2582. begin
  2583. FTransformFeedbackBufferBinding := Value;
  2584. gl.BindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, Value);
  2585. end;
  2586. end;
  2587. procedure TGLStateCache.SetEnableTextureCubeMapSeamless(const Value: TGLboolean);
  2588. begin
  2589. if Value <> FEnableTextureCubeMapSeamless then
  2590. begin
  2591. FEnableTextureCubeMapSeamless := Value;
  2592. if Value = True then
  2593. gl.Enable(GL_TEXTURE_CUBE_MAP_SEAMLESS)
  2594. else
  2595. gl.Disable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
  2596. end;
  2597. end;
  2598. procedure TGLStateCache.NewList(list: Cardinal; mode: Cardinal);
  2599. var
  2600. I: Cardinal;
  2601. begin
  2602. Assert(mode = GL_COMPILE, 'Compile & executing not supported by TGLStateCache');
  2603. FCurrentList := list - 1;
  2604. // while High(FListStates) < Integer(FCurrentList) do
  2605. // SetLength(FListStates, 2 * Length(FListStates));
  2606. FListStates[FCurrentList] := [];
  2607. FInsideList := True;
  2608. // Reset VBO binding and client attribute
  2609. begin
  2610. if GL.ARB_vertex_buffer_object then
  2611. begin
  2612. ArrayBufferBinding := 0;
  2613. ElementBufferBinding := 0;
  2614. for I := 0 to 15 do
  2615. gl.DisableVertexAttribArray(I);
  2616. end;
  2617. gl.NewList(list, mode);
  2618. end;
  2619. end;
  2620. procedure TGLStateCache.EndList;
  2621. begin
  2622. gl.EndList;
  2623. FInsideList := False;
  2624. end;
  2625. procedure TGLStateCache.CallList(list: Cardinal);
  2626. begin
  2627. // while High(FListStates) < Integer(list) do
  2628. // SetLength(FListStates, 2 * Length(FListStates));
  2629. if FListStates[list - 1] <> [] then
  2630. begin
  2631. PushAttrib(FListStates[list - 1]);
  2632. gl.CallList(list);
  2633. PopAttrib;
  2634. end
  2635. else
  2636. gl.CallList(list);
  2637. end;
  2638. procedure TGLStateCache.SetUniformBufferBinding(const Value: Cardinal);
  2639. begin
  2640. Assert(not FInsideList);
  2641. if Value <> FUniformBufferBinding then
  2642. begin
  2643. FUniformBufferBinding := Value;
  2644. gl.BindBuffer(GL_UNIFORM_BUFFER, Value);
  2645. end;
  2646. end;
  2647. procedure TGLStateCache.SetBufferIndexedBinding(const Value: Cardinal;
  2648. ATarget: TGLBufferBindingTarget; AIndex: Cardinal; ABufferSize: TGLsizeiptr);
  2649. begin
  2650. Assert(not FInsideList);
  2651. if (FUBOStates[ATarget, AIndex].FUniformBufferBinding <> Value)
  2652. or (FUBOStates[ATarget, AIndex].FOffset > 0)
  2653. or (FUBOStates[ATarget, AIndex].FSize <> ABufferSize) then
  2654. begin
  2655. case ATarget of
  2656. bbtUniform:
  2657. FUniformBufferBinding := Value;
  2658. bbtTransformFeedBack:
  2659. FTransformFeedbackBufferBinding := Value;
  2660. end;
  2661. FUBOStates[ATarget, AIndex].FUniformBufferBinding := Value;
  2662. FUBOStates[ATarget, AIndex].FOffset := 0;
  2663. FUBOStates[ATarget, AIndex].FSize := ABufferSize;
  2664. gl.BindBufferBase(cGLBufferBindingTarget[ATarget], AIndex, Value);
  2665. end
  2666. else
  2667. case ATarget of
  2668. bbtUniform: SetUniformBufferBinding(Value);
  2669. bbtTransformFeedBack: SetTransformFeedbackBufferBinding(Value);
  2670. end;
  2671. end;
  2672. procedure TGLStateCache.SetBufferIndexedBinding(const Value: Cardinal; ATarget: TGLBufferBindingTarget; AIndex: Cardinal;
  2673. AOffset: TGLintptr; ARangeSize: TGLsizeiptr);
  2674. begin
  2675. Assert(not FInsideList);
  2676. if (FUBOStates[ATarget, AIndex].FUniformBufferBinding <> Value)
  2677. or (FUBOStates[ATarget, AIndex].FOffset <> AOffset)
  2678. or (FUBOStates[ATarget, AIndex].FSize <> ARangeSize) then
  2679. begin
  2680. case ATarget of
  2681. bbtUniform: FUniformBufferBinding := Value;
  2682. bbtTransformFeedBack: FTransformFeedbackBufferBinding := Value;
  2683. end;
  2684. FUBOStates[ATarget, AIndex].FUniformBufferBinding := Value;
  2685. FUBOStates[ATarget, AIndex].FOffset := AOffset;
  2686. FUBOStates[ATarget, AIndex].FSize := ARangeSize;
  2687. gl.BindBufferRange(cGLBufferBindingTarget[ATarget], AIndex, Value, AOffset, ARangeSize);
  2688. end;
  2689. end;
  2690. function TGLStateCache.GetMaxTextureUnits: Cardinal;
  2691. begin
  2692. if FMaxTextureUnits = 0 then
  2693. gl.GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, @FMaxTextureUnits);
  2694. Result := FMaxTextureUnits;
  2695. end;
  2696. procedure TGLStateCache.SetUnpackAlignment(const Value: Cardinal);
  2697. begin
  2698. if Value <> FUnpackAlignment then
  2699. begin
  2700. FUnpackAlignment := Value;
  2701. gl.PixelStoref(GL_UNPACK_ALIGNMENT, Value);
  2702. end;
  2703. end;
  2704. procedure TGLStateCache.SetUnpackImageHeight(const Value: Cardinal);
  2705. begin
  2706. if Value <> FUnpackImageHeight then
  2707. begin
  2708. FUnpackImageHeight := Value;
  2709. gl.PixelStoref(GL_UNPACK_IMAGE_HEIGHT, Value);
  2710. end;
  2711. end;
  2712. procedure TGLStateCache.SetUnpackLSBFirst(const Value: TGLboolean);
  2713. begin
  2714. if Value <> FUnpackLSBFirst then
  2715. begin
  2716. FUnpackLSBFirst := Value;
  2717. gl.PixelStorei(GL_UNPACK_LSB_FIRST, byte(Value));
  2718. end;
  2719. end;
  2720. procedure TGLStateCache.SetUnpackRowLength(const Value: Cardinal);
  2721. begin
  2722. if Value <> FUnpackRowLength then
  2723. begin
  2724. FUnpackRowLength := Value;
  2725. gl.PixelStoref(GL_UNPACK_ROW_LENGTH, Value);
  2726. end;
  2727. end;
  2728. procedure TGLStateCache.SetUnpackSkipImages(const Value: Cardinal);
  2729. begin
  2730. if Value <> FUnpackSkipImages then
  2731. begin
  2732. FUnpackSkipImages := Value;
  2733. gl.PixelStoref(GL_UNPACK_SKIP_IMAGES, Value);
  2734. end;
  2735. end;
  2736. procedure TGLStateCache.SetUnpackSkipPixels(const Value: Cardinal);
  2737. begin
  2738. if Value <> FUnpackSkipPixels then
  2739. begin
  2740. FUnpackSkipPixels := Value;
  2741. gl.PixelStoref(GL_UNPACK_SKIP_PIXELS, Value);
  2742. end;
  2743. end;
  2744. procedure TGLStateCache.SetUnpackSkipRows(const Value: Cardinal);
  2745. begin
  2746. if Value <> FUnpackSkipRows then
  2747. begin
  2748. FUnpackSkipRows := Value;
  2749. gl.PixelStoref(GL_UNPACK_SKIP_ROWS, Value);
  2750. end;
  2751. end;
  2752. procedure TGLStateCache.SetUnpackSwapBytes(const Value: TGLboolean);
  2753. begin
  2754. if Value <> FUnpackSwapBytes then
  2755. begin
  2756. FUnpackSwapBytes := Value;
  2757. gl.PixelStorei(GL_UNPACK_SWAP_BYTES, byte(Value));
  2758. end;
  2759. end;
  2760. procedure TGLStateCache.SetViewPort(const Value: TVector4i);
  2761. begin
  2762. if not VectorEquals(Value, FViewPort) or FInsideList then
  2763. begin
  2764. if FInsideList then
  2765. Include(FListStates[FCurrentList], sttViewport)
  2766. else
  2767. FViewPort := Value;
  2768. gl.ViewPort(Value.X, Value.Y, Value.Z, Value.W);
  2769. end;
  2770. end;
  2771. procedure TGLStateCache.SetFFPLight(Value: Boolean);
  2772. begin
  2773. FFFPLight := Value { and not FForwardContext };
  2774. end;
  2775. function TGLStateCache.GetMaxLights: Integer;
  2776. begin
  2777. if FMaxLights = 0 then
  2778. { if FForwardContext then
  2779. FMaxLights := MAX_HARDWARE_LIGHT
  2780. else }
  2781. gl.GetIntegerv(GL_MAX_LIGHTS, @FMaxLights);
  2782. Result := FMaxLights;
  2783. end;
  2784. function TGLStateCache.GetLightEnabling(I: Integer): Boolean;
  2785. begin
  2786. Result := FLightEnabling[I];
  2787. end;
  2788. procedure TGLStateCache.SetLightEnabling(I: Integer; Value: Boolean);
  2789. var
  2790. J, K: Integer;
  2791. begin
  2792. if (FLightEnabling[I] <> Value) or FInsideList then
  2793. begin
  2794. if FInsideList then
  2795. Include(FListStates[FCurrentList], sttLighting)
  2796. else
  2797. FLightEnabling[I] := Value;
  2798. if FFFPLight then
  2799. begin
  2800. if Value then
  2801. gl.Enable(GL_LIGHT0 + I)
  2802. else
  2803. gl.Disable(GL_LIGHT0 + I);
  2804. end;
  2805. K := 0;
  2806. for J := 0 to MAX_HARDWARE_LIGHT - 1 do
  2807. if FLightEnabling[J] then
  2808. begin
  2809. FLightIndices[K] := J;
  2810. Inc(K);
  2811. end;
  2812. FLightNumber := K;
  2813. FShaderLightStatesChanged := True;
  2814. if Assigned(FOnLightsChanged) then
  2815. FOnLightsChanged(Self);
  2816. end;
  2817. end;
  2818. function TGLStateCache.GetLightIndicesAsAddress: PGLInt;
  2819. begin
  2820. Result := @FLightIndices[0];
  2821. end;
  2822. function TGLStateCache.GetLightStateAsAddress: Pointer;
  2823. var
  2824. I, J, C: Integer;
  2825. begin
  2826. C := MinInteger(FLightNumber, MAX_SHADER_LIGHT);
  2827. if FShaderLightStatesChanged then
  2828. begin
  2829. if C > 0 then
  2830. begin
  2831. if GL.VERSION_3_0 then
  2832. begin
  2833. Move(FLightStates.Position,
  2834. FShaderLightStates.Position,
  2835. SizeOf(FShaderLightStates.Position));
  2836. Move(FLightStates.Ambient,
  2837. FShaderLightStates.Ambient,
  2838. SizeOf(FShaderLightStates.Ambient));
  2839. Move(FLightStates.Diffuse,
  2840. FShaderLightStates.Diffuse,
  2841. SizeOf(FShaderLightStates.Diffuse));
  2842. Move(FLightStates.Specular,
  2843. FShaderLightStates.Specular,
  2844. SizeOf(FShaderLightStates.Specular));
  2845. Move(FLightStates.SpotDirection,
  2846. FShaderLightStates.SpotDirection,
  2847. SizeOf(FShaderLightStates.SpotDirection));
  2848. Move(FLightStates.SpotCosCutoffExponent,
  2849. FShaderLightStates.SpotCosCutoffExponent,
  2850. SizeOf(FShaderLightStates.SpotCosCutoffExponent));
  2851. Move(FLightStates.Attenuation,
  2852. FShaderLightStates.Attenuation,
  2853. SizeOf(FShaderLightStates.Attenuation));
  2854. end
  2855. else
  2856. begin
  2857. for I := C - 1 downto 0 do
  2858. begin
  2859. J := FLightIndices[I];
  2860. FShaderLightStates.Position[I] := FLightStates.Position[J];
  2861. FShaderLightStates.Ambient[I] := FLightStates.Ambient[J];
  2862. FShaderLightStates.Diffuse[I] := FLightStates.Diffuse[J];
  2863. FShaderLightStates.Specular[I] := FLightStates.Specular[J];
  2864. FShaderLightStates.SpotDirection[I] := FLightStates.SpotDirection[J];
  2865. FShaderLightStates.SpotCosCutoffExponent[I] := FLightStates.SpotCosCutoffExponent[J];
  2866. FShaderLightStates.Attenuation[I] := FLightStates.Attenuation[J];
  2867. end;
  2868. end;
  2869. end
  2870. else
  2871. FillChar(FShaderLightStatesChanged, SizeOf(FShaderLightStatesChanged), $00);
  2872. FShaderLightStatesChanged := False;
  2873. end;
  2874. Result := @FShaderLightStates;
  2875. end;
  2876. function TGLStateCache.GetLightPosition(I: Integer): TGLVector;
  2877. begin
  2878. Result := FLightStates.Position[I];
  2879. end;
  2880. procedure TGLStateCache.SetLightPosition(I: Integer; const Value: TGLVector);
  2881. begin
  2882. if not VectorEquals(Value, FLightStates.Position[I]) then
  2883. begin
  2884. FLightStates.Position[I] := Value;
  2885. FShaderLightStatesChanged := True;
  2886. if Assigned(FOnLightsChanged) then
  2887. FOnLightsChanged(Self);
  2888. end;
  2889. end;
  2890. function TGLStateCache.GetLightSpotDirection(I: Integer): TAffineVector;
  2891. begin
  2892. Result := AffineVectorMake(FLightStates.SpotDirection[I]);
  2893. end;
  2894. procedure TGLStateCache.SetLightSpotDirection(I: Integer; const Value: TAffineVector);
  2895. begin
  2896. if not VectorEquals(Value, AffineVectorMake(FLightStates.SpotDirection[I])) then
  2897. begin
  2898. FLightStates.SpotDirection[I] := VectorMake(Value);
  2899. FShaderLightStatesChanged := True;
  2900. if Assigned(FOnLightsChanged) then
  2901. FOnLightsChanged(Self);
  2902. end;
  2903. end;
  2904. function TGLStateCache.GetLightAmbient(I: Integer): TGLVector;
  2905. begin
  2906. Result := FLightStates.Ambient[I];
  2907. end;
  2908. procedure TGLStateCache.SetLightAmbient(I: Integer; const Value: TGLVector);
  2909. begin
  2910. if not VectorEquals(Value, FLightStates.Ambient[I]) or FInsideList then
  2911. begin
  2912. if FInsideList then
  2913. Include(FListStates[FCurrentList], sttLighting)
  2914. else
  2915. FLightStates.Ambient[I] := Value;
  2916. if FFFPLight then
  2917. gl.Lightfv(GL_LIGHT0 + I, GL_AMBIENT, @Value);
  2918. FShaderLightStatesChanged := True;
  2919. if Assigned(FOnLightsChanged) then
  2920. FOnLightsChanged(Self);
  2921. end;
  2922. end;
  2923. function TGLStateCache.GetLightDiffuse(I: Integer): TGLVector;
  2924. begin
  2925. Result := FLightStates.Diffuse[I];
  2926. end;
  2927. procedure TGLStateCache.SetLightDiffuse(I: Integer; const Value: TGLVector);
  2928. begin
  2929. if not VectorEquals(Value, FLightStates.Diffuse[I]) or FInsideList then
  2930. begin
  2931. if FInsideList then
  2932. Include(FListStates[FCurrentList], sttLighting)
  2933. else
  2934. FLightStates.Diffuse[I] := Value;
  2935. if FFFPLight then
  2936. gl.Lightfv(GL_LIGHT0 + I, GL_DIFFUSE, @Value);
  2937. FShaderLightStatesChanged := True;
  2938. if Assigned(FOnLightsChanged) then
  2939. FOnLightsChanged(Self);
  2940. end;
  2941. end;
  2942. function TGLStateCache.GetLightSpecular(I: Integer): TGLVector;
  2943. begin
  2944. Result := FLightStates.Specular[I];
  2945. end;
  2946. procedure TGLStateCache.SetLightSpecular(I: Integer; const Value: TGLVector);
  2947. begin
  2948. if not VectorEquals(Value, FLightStates.Specular[I]) or FInsideList then
  2949. begin
  2950. if FInsideList then
  2951. Include(FListStates[FCurrentList], sttLighting)
  2952. else
  2953. FLightStates.Specular[I] := Value;
  2954. if FFFPLight then
  2955. gl.Lightfv(GL_LIGHT0 + I, GL_SPECULAR, @Value);
  2956. FShaderLightStatesChanged := True;
  2957. if Assigned(FOnLightsChanged) then
  2958. FOnLightsChanged(Self);
  2959. end;
  2960. end;
  2961. function TGLStateCache.GetSpotCutoff(I: Integer): Single;
  2962. begin
  2963. Result := FSpotCutoff[I];
  2964. end;
  2965. procedure TGLStateCache.SetSpotCutoff(I: Integer; const Value: Single);
  2966. begin
  2967. if (Value <> FSpotCutoff[I]) or FInsideList then
  2968. begin
  2969. if FInsideList then
  2970. Include(FListStates[FCurrentList], sttLighting)
  2971. else
  2972. begin
  2973. FSpotCutoff[I] := Value;
  2974. FLightStates.SpotCosCutoffExponent[I].X := cos(DegToRadian(Value));
  2975. end;
  2976. if FFFPLight then
  2977. gl.Lightfv(GL_LIGHT0 + I, GL_SPOT_CUTOFF, @Value);
  2978. FShaderLightStatesChanged := True;
  2979. if Assigned(FOnLightsChanged) then
  2980. FOnLightsChanged(Self);
  2981. end;
  2982. end;
  2983. function TGLStateCache.GetSpotExponent(I: Integer): Single;
  2984. begin
  2985. Result := FLightStates.SpotCosCutoffExponent[I].Y;
  2986. end;
  2987. procedure TGLStateCache.SetSpotExponent(I: Integer; const Value: Single);
  2988. begin
  2989. if (Value <> FLightStates.SpotCosCutoffExponent[I].Y) or FInsideList then
  2990. begin
  2991. if FInsideList then
  2992. Include(FListStates[FCurrentList], sttLighting)
  2993. else
  2994. FLightStates.SpotCosCutoffExponent[I].Y := Value;
  2995. if FFFPLight then
  2996. gl.Lightfv(GL_LIGHT0 + I, GL_SPOT_EXPONENT, @Value);
  2997. FShaderLightStatesChanged := True;
  2998. if Assigned(FOnLightsChanged) then
  2999. FOnLightsChanged(Self);
  3000. end;
  3001. end;
  3002. function TGLStateCache.GetConstantAtten(I: Integer): Single;
  3003. begin
  3004. Result := FLightStates.Attenuation[I].X;
  3005. end;
  3006. procedure TGLStateCache.SetConstantAtten(I: Integer; const Value: Single);
  3007. begin
  3008. if (Value <> FLightStates.Attenuation[I].X) or FInsideList then
  3009. begin
  3010. if FInsideList then
  3011. Include(FListStates[FCurrentList], sttLighting)
  3012. else
  3013. FLightStates.Attenuation[I].X := Value;
  3014. if FFFPLight then
  3015. gl.Lightfv(GL_LIGHT0 + I, GL_CONSTANT_ATTENUATION, @Value);
  3016. FShaderLightStatesChanged := True;
  3017. if Assigned(FOnLightsChanged) then
  3018. FOnLightsChanged(Self);
  3019. end;
  3020. end;
  3021. function TGLStateCache.GetLinearAtten(I: Integer): Single;
  3022. begin
  3023. Result := FLightStates.Attenuation[I].Y;
  3024. end;
  3025. procedure TGLStateCache.SetLinearAtten(I: Integer; const Value: Single);
  3026. begin
  3027. if (Value <> FLightStates.Attenuation[I].Y) or FInsideList then
  3028. begin
  3029. if FInsideList then
  3030. Include(FListStates[FCurrentList], sttLighting)
  3031. else
  3032. FLightStates.Attenuation[I].Y := Value;
  3033. if FFFPLight then
  3034. gl.Lightfv(GL_LIGHT0 + I, GL_LINEAR_ATTENUATION, @Value);
  3035. FShaderLightStatesChanged := True;
  3036. if Assigned(FOnLightsChanged) then
  3037. FOnLightsChanged(Self);
  3038. end;
  3039. end;
  3040. function TGLStateCache.GetQuadAtten(I: Integer): Single;
  3041. begin
  3042. Result := FLightStates.Attenuation[I].Z;
  3043. end;
  3044. procedure TGLStateCache.SetQuadAtten(I: Integer; const Value: Single);
  3045. begin
  3046. if (Value <> FLightStates.Attenuation[I].Z) or FInsideList then
  3047. begin
  3048. if FInsideList then
  3049. Include(FListStates[FCurrentList], sttLighting)
  3050. else
  3051. FLightStates.Attenuation[I].Z := Value;
  3052. if FFFPLight then
  3053. gl.Lightfv(GL_LIGHT0 + I, GL_QUADRATIC_ATTENUATION, @Value);
  3054. FShaderLightStatesChanged := True;
  3055. if Assigned(FOnLightsChanged) then
  3056. FOnLightsChanged(Self);
  3057. end;
  3058. end;
  3059. procedure TGLStateCache.SetForwardContext(Value: Boolean);
  3060. begin
  3061. { if Value <> FForwardContext then
  3062. begin
  3063. FForwardContext := Value;
  3064. if Value then
  3065. begin
  3066. SetFFPlight(False);
  3067. end;
  3068. end;
  3069. }
  3070. end;
  3071. procedure TGLStateCache.SetGLColorWriting(flag: Boolean);
  3072. begin
  3073. if (FColorWriting <> flag) or FInsideList then
  3074. begin
  3075. if FInsideList then
  3076. Include(FListStates[FCurrentList], sttColorBuffer)
  3077. else
  3078. FColorWriting := flag;
  3079. gl.ColorMask(flag, flag, flag, flag);
  3080. end;
  3081. end;
  3082. procedure TGLStateCache.InvertGLFrontFace;
  3083. begin
  3084. if FFrontFace = fwCounterClockWise then
  3085. FrontFace := fwClockWise
  3086. else
  3087. FrontFace := fwCounterClockWise;
  3088. end;
  3089. procedure TGLStateCache.SetGLState(const aState: TGLState);
  3090. begin
  3091. Enable(aState);
  3092. end;
  3093. procedure TGLStateCache.UnSetGLState(const aState: TGLState);
  3094. begin
  3095. Disable(aState);
  3096. end;
  3097. procedure TGLStateCache.ResetGLPolygonMode;
  3098. begin
  3099. gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  3100. FPolygonMode := pmFill;
  3101. FPolygonBackMode := pmFill;
  3102. end;
  3103. procedure TGLStateCache.ResetGLMaterialColors;
  3104. begin
  3105. gl.Materialfv(GL_FRONT_AND_BACK, GL_AMBIENT, @clrGray20);
  3106. gl.Materialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, @clrGray80);
  3107. gl.Materialfv(GL_FRONT_AND_BACK, GL_SPECULAR, @clrBlack);
  3108. gl.Materialfv(GL_FRONT_AND_BACK, GL_EMISSION, @clrBlack);
  3109. gl.Materiali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
  3110. FillChar(FFrontBackColors, SizeOf(FFrontBackColors), 127);
  3111. FFrontBackShininess[0] := 0;
  3112. FFrontBackShininess[1] := 0;
  3113. end;
  3114. procedure TGLStateCache.ResetGLTexture(const TextureUnit: Integer);
  3115. var
  3116. t: TGLTextureTarget;
  3117. glTarget: Cardinal;
  3118. begin
  3119. gl.ActiveTexture(GL_TEXTURE0 + TextureUnit);
  3120. for t := Low(TGLTextureTarget) to High(TGLTextureTarget) do
  3121. begin
  3122. glTarget := DecodeTextureTarget(t);
  3123. if IsTargetSupported(glTarget) then
  3124. begin
  3125. gl.BindTexture(glTarget, 0);
  3126. FTextureBinding[TextureUnit, t] := 0;
  3127. end;
  3128. end;
  3129. gl.ActiveTexture(GL_TEXTURE0);
  3130. FActiveTexture := 0;
  3131. end;
  3132. procedure TGLStateCache.ResetGLCurrentTexture;
  3133. var
  3134. a: TGLint;
  3135. t: TGLTextureTarget;
  3136. glTarget: Cardinal;
  3137. begin
  3138. if GL.ARB_multitexture then
  3139. begin
  3140. for a := MaxTextureImageUnits - 1 to 0 do
  3141. begin
  3142. gl.ActiveTexture(GL_TEXTURE0 + a);
  3143. for t := Low(TGLTextureTarget) to High(TGLTextureTarget) do
  3144. begin
  3145. glTarget := DecodeTextureTarget(t);
  3146. if IsTargetSupported(glTarget) then
  3147. begin
  3148. gl.BindTexture(glTarget, 0);
  3149. FTextureBinding[a, t] := 0;
  3150. end;
  3151. end;
  3152. end;
  3153. end
  3154. else
  3155. for t := Low(TGLTextureTarget) to High(TGLTextureTarget) do
  3156. begin
  3157. glTarget := DecodeTextureTarget(t);
  3158. if IsTargetSupported(glTarget) then
  3159. begin
  3160. gl.BindTexture(glTarget, 0);
  3161. FTextureBinding[0, t] := 0;
  3162. end;
  3163. end;
  3164. end;
  3165. procedure TGLStateCache.ResetGLFrontFace;
  3166. begin
  3167. gl.FrontFace(GL_CCW);
  3168. FFrontFace := fwCounterClockWise;
  3169. end;
  3170. procedure TGLStateCache.SetGLFrontFaceCW;
  3171. begin
  3172. if FFrontFace = fwCounterClockWise then
  3173. begin
  3174. gl.FrontFace(GL_CW);
  3175. FFrontFace := fwClockWise;
  3176. end;
  3177. end;
  3178. procedure TGLStateCache.ResetAll;
  3179. begin
  3180. {$WARN SYMBOL_DEPRECATED OFF}
  3181. ResetGLPolygonMode;
  3182. ResetGLMaterialColors;
  3183. ResetGLCurrentTexture;
  3184. ResetGLFrontFace;
  3185. {$WARN SYMBOL_DEPRECATED ON}
  3186. end;
  3187. end.