GXS.State.pas 114 KB

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