GXS.State.pas 114 KB

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