COGLES2Driver.cpp 97 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225
  1. // Copyright (C) 2013 Patryk Nadrowski
  2. // Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt
  3. // OpenGL ES driver implemented by Christian Stehno and first OpenGL ES 2.0
  4. // driver implemented by Amundis.
  5. // This file is part of the "Irrlicht Engine".
  6. // For conditions of distribution and use, see copyright notice in Irrlicht.h
  7. #include "COGLES2Driver.h"
  8. // needed here also because of the create methods' parameters
  9. #include "CNullDriver.h"
  10. #ifdef _IRR_COMPILE_WITH_OGLES2_
  11. #include "COGLES2Texture.h"
  12. #include "COGLES2MaterialRenderer.h"
  13. #include "COGLES2FixedPipelineRenderer.h"
  14. #include "COGLES2NormalMapRenderer.h"
  15. #include "COGLES2ParallaxMapRenderer.h"
  16. #include "COGLES2Renderer2D.h"
  17. #include "CImage.h"
  18. #include "os.h"
  19. #if defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
  20. #include <OpenGLES/ES2/gl.h>
  21. #include <OpenGLES/ES2/glext.h>
  22. #else
  23. #include <EGL/egl.h>
  24. #include <GLES2/gl2.h>
  25. #endif
  26. namespace irr
  27. {
  28. namespace video
  29. {
  30. bool useCoreContext = true;
  31. //! constructor and init code
  32. COGLES2Driver::COGLES2Driver(const SIrrlichtCreationParameters& params,
  33. const SExposedVideoData& data, io::IFileSystem* io
  34. #if defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
  35. , CIrrDeviceIPhone* device
  36. #endif
  37. )
  38. : CNullDriver(io, params.WindowSize), COGLES2ExtensionHandler(),
  39. BridgeCalls(0), CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
  40. Transformation3DChanged(true), AntiAlias(params.AntiAlias),
  41. RenderTargetTexture(0), CurrentRendertargetSize(0, 0), ColorFormat(ECF_R8G8B8)
  42. #ifdef EGL_VERSION_1_0
  43. , EglDisplay(EGL_NO_DISPLAY)
  44. #endif
  45. #if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
  46. , HDc(0)
  47. #elif defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
  48. , ViewFramebuffer(0)
  49. , ViewRenderbuffer(0)
  50. , ViewDepthRenderbuffer(0)
  51. #endif
  52. , Params(params)
  53. {
  54. #ifdef _DEBUG
  55. setDebugName("COGLES2Driver");
  56. #endif
  57. ExposedData = data;
  58. #if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
  59. EglWindow = (NativeWindowType)data.OpenGLWin32.HWnd;
  60. HDc = GetDC((HWND)EglWindow);
  61. EglDisplay = eglGetDisplay((NativeDisplayType)HDc);
  62. #elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
  63. EglWindow = (NativeWindowType)ExposedData.OpenGLLinux.X11Window;
  64. EglDisplay = eglGetDisplay((NativeDisplayType)ExposedData.OpenGLLinux.X11Display);
  65. #elif defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
  66. Device = device;
  67. #elif defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_)
  68. EglWindow = ((struct android_app *)(params.PrivateData))->window;
  69. EglDisplay = EGL_NO_DISPLAY;
  70. #endif
  71. #ifdef EGL_VERSION_1_0
  72. if (EglDisplay == EGL_NO_DISPLAY)
  73. {
  74. os::Printer::log("Getting OpenGL-ES2 display.");
  75. EglDisplay = eglGetDisplay((NativeDisplayType) EGL_DEFAULT_DISPLAY);
  76. }
  77. if (EglDisplay == EGL_NO_DISPLAY)
  78. {
  79. os::Printer::log("Could not get OpenGL-ES2 display.");
  80. }
  81. EGLint majorVersion, minorVersion;
  82. if (!eglInitialize(EglDisplay, &majorVersion, &minorVersion))
  83. {
  84. os::Printer::log("Could not initialize OpenGL-ES2 display.");
  85. }
  86. else
  87. {
  88. char text[64];
  89. sprintf(text, "EglDisplay initialized. Egl version %d.%d\n", majorVersion, minorVersion);
  90. os::Printer::log(text);
  91. }
  92. EGLint attribs[] =
  93. {
  94. #if defined( _IRR_COMPILE_WITH_ANDROID_DEVICE_ )
  95. EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  96. EGL_BLUE_SIZE, 8,
  97. EGL_GREEN_SIZE, 8,
  98. EGL_RED_SIZE, 8,
  99. EGL_DEPTH_SIZE, 16,
  100. EGL_NONE
  101. #else
  102. EGL_RED_SIZE, 5,
  103. EGL_GREEN_SIZE, 5,
  104. EGL_BLUE_SIZE, 5,
  105. EGL_ALPHA_SIZE, params.WithAlphaChannel ? 1 : 0,
  106. EGL_BUFFER_SIZE, params.Bits,
  107. EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  108. //EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
  109. EGL_DEPTH_SIZE, params.ZBufferBits,
  110. EGL_STENCIL_SIZE, params.Stencilbuffer,
  111. EGL_SAMPLE_BUFFERS, params.AntiAlias ? 1 : 0,
  112. EGL_SAMPLES, params.AntiAlias,
  113. #ifdef EGL_VERSION_1_3
  114. EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
  115. #endif
  116. EGL_NONE, 0
  117. #endif
  118. };
  119. EGLint num_configs;
  120. #if defined( _IRR_COMPILE_WITH_ANDROID_DEVICE_ )
  121. u32 steps=0;
  122. #else
  123. u32 steps=5;
  124. #endif
  125. while (!eglChooseConfig(EglDisplay, attribs, &EglConfig, 1, &num_configs) || !num_configs)
  126. {
  127. switch (steps)
  128. {
  129. case 5: // samples
  130. if (attribs[19]>2)
  131. {
  132. --attribs[19];
  133. }
  134. else
  135. {
  136. attribs[17]=0;
  137. attribs[19]=0;
  138. --steps;
  139. }
  140. break;
  141. case 4: // alpha
  142. if (attribs[7])
  143. {
  144. attribs[7]=0;
  145. if (params.AntiAlias)
  146. {
  147. attribs[17]=1;
  148. attribs[19]=params.AntiAlias;
  149. steps=5;
  150. }
  151. }
  152. else
  153. --steps;
  154. break;
  155. case 3: // stencil
  156. if (attribs[15])
  157. {
  158. attribs[15]=0;
  159. if (params.AntiAlias)
  160. {
  161. attribs[17]=1;
  162. attribs[19]=params.AntiAlias;
  163. steps=5;
  164. }
  165. }
  166. else
  167. --steps;
  168. break;
  169. case 2: // depth size
  170. if (attribs[13]>16)
  171. {
  172. attribs[13]-=8;
  173. }
  174. else
  175. --steps;
  176. break;
  177. case 1: // buffer size
  178. if (attribs[9]>16)
  179. {
  180. attribs[9]-=8;
  181. }
  182. else
  183. --steps;
  184. break;
  185. default:
  186. os::Printer::log("Could not get config for OpenGL-ES2 display.");
  187. return;
  188. }
  189. }
  190. #if !defined( _IRR_COMPILE_WITH_ANDROID_DEVICE_ )
  191. if (params.AntiAlias && !attribs[17])
  192. os::Printer::log("No multisampling.");
  193. if (params.WithAlphaChannel && !attribs[7])
  194. os::Printer::log("No alpha.");
  195. if (params.Stencilbuffer && !attribs[15])
  196. os::Printer::log("No stencil buffer.");
  197. if (params.ZBufferBits > attribs[13])
  198. os::Printer::log("No full depth buffer.");
  199. if (params.Bits > attribs[9])
  200. os::Printer::log("No full color buffer.");
  201. #endif
  202. #if defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_)
  203. /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
  204. * guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
  205. * As soon as we picked a EGLConfig, we can safely reconfigure the
  206. * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
  207. EGLint format;
  208. eglGetConfigAttrib(EglDisplay, EglConfig, EGL_NATIVE_VISUAL_ID, &format);
  209. ANativeWindow_setBuffersGeometry(EglWindow, 0, 0, format);
  210. #endif
  211. os::Printer::log(" Creating EglSurface with nativeWindow...");
  212. EglSurface = eglCreateWindowSurface(EglDisplay, EglConfig, EglWindow, NULL);
  213. if (EGL_NO_SURFACE == EglSurface)
  214. {
  215. os::Printer::log("FAILED\n");
  216. EglSurface = eglCreateWindowSurface(EglDisplay, EglConfig, 0, NULL);
  217. os::Printer::log("Creating EglSurface without nativeWindows...");
  218. }
  219. else
  220. os::Printer::log("SUCCESS\n");
  221. if (EGL_NO_SURFACE == EglSurface)
  222. {
  223. os::Printer::log("FAILED\n");
  224. os::Printer::log("Could not create surface for OpenGL-ES2 display.");
  225. }
  226. else
  227. os::Printer::log("SUCCESS\n");
  228. #ifdef EGL_VERSION_1_2
  229. if (minorVersion>1)
  230. eglBindAPI(EGL_OPENGL_ES_API);
  231. #endif
  232. os::Printer::log("Creating EglContext...");
  233. EglContext = EGL_NO_CONTEXT;
  234. if (!Params.ForceLegacyDevice)
  235. {
  236. os::Printer::log("Trying to create Context for OpenGL-ES3.");
  237. EGLint contextAttrib[] =
  238. {
  239. #ifdef EGL_VERSION_1_3
  240. EGL_CONTEXT_CLIENT_VERSION, 3,
  241. #endif
  242. EGL_NONE, 0
  243. };
  244. EglContext = eglCreateContext(EglDisplay, EglConfig, EGL_NO_CONTEXT, contextAttrib);
  245. }
  246. if (EGL_NO_CONTEXT == EglContext)
  247. {
  248. os::Printer::log("Trying to create Context for OpenGL-ES2.");
  249. useCoreContext = false;
  250. EGLint contextAttrib[] =
  251. {
  252. #ifdef EGL_VERSION_1_3
  253. EGL_CONTEXT_CLIENT_VERSION, 2,
  254. #endif
  255. EGL_NONE, 0
  256. };
  257. EglContext = eglCreateContext(EglDisplay, EglConfig, EGL_NO_CONTEXT, contextAttrib);
  258. if (EGL_NO_CONTEXT == EglContext)
  259. {
  260. os::Printer::log("FAILED\n");
  261. os::Printer::log("Could not create Context for OpenGL-ES2 display.");
  262. }
  263. }
  264. eglMakeCurrent(EglDisplay, EglSurface, EglSurface, EglContext);
  265. if (testEGLError())
  266. {
  267. os::Printer::log("Could not make Context current for OpenGL-ES2 display.");
  268. }
  269. genericDriverInit(params.WindowSize, params.Stencilbuffer);
  270. #ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
  271. int backingWidth;
  272. int backingHeight;
  273. eglQuerySurface(EglDisplay, EglSurface, EGL_WIDTH, &backingWidth);
  274. eglQuerySurface(EglDisplay, EglSurface, EGL_HEIGHT, &backingHeight);
  275. core::dimension2d<u32> WindowSize(backingWidth, backingHeight);
  276. CNullDriver::ScreenSize = WindowSize;
  277. #endif
  278. // set vsync
  279. if (params.Vsync)
  280. eglSwapInterval(EglDisplay, 1);
  281. #elif defined(GL_ES_VERSION_2_0)
  282. glGenFramebuffers(1, &ViewFramebuffer);
  283. glGenRenderbuffers(1, &ViewRenderbuffer);
  284. glBindRenderbuffer(GL_RENDERBUFFER, ViewRenderbuffer);
  285. #if defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
  286. ExposedData.OGLESIPhone.AppDelegate = Device;
  287. Device->displayInitialize(&ExposedData.OGLESIPhone.Context, &ExposedData.OGLESIPhone.View);
  288. #endif
  289. GLint backingWidth;
  290. GLint backingHeight;
  291. glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
  292. glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
  293. glGenRenderbuffers(1, &ViewDepthRenderbuffer);
  294. glBindRenderbuffer(GL_RENDERBUFFER, ViewDepthRenderbuffer);
  295. GLenum depthComponent = GL_DEPTH_COMPONENT16;
  296. if(params.ZBufferBits >= 24)
  297. depthComponent = GL_DEPTH_COMPONENT24_OES;
  298. glRenderbufferStorage(GL_RENDERBUFFER, depthComponent, backingWidth, backingHeight);
  299. glBindFramebuffer(GL_FRAMEBUFFER, ViewFramebuffer);
  300. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, ViewRenderbuffer);
  301. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, ViewDepthRenderbuffer);
  302. core::dimension2d<u32> WindowSize(backingWidth, backingHeight);
  303. CNullDriver::ScreenSize = WindowSize;
  304. CNullDriver::ViewPort = core::rect<s32>(core::position2d<s32>(0,0), core::dimension2di(WindowSize));
  305. genericDriverInit(WindowSize, params.Stencilbuffer);
  306. #endif
  307. }
  308. //! destructor
  309. COGLES2Driver::~COGLES2Driver()
  310. {
  311. deleteMaterialRenders();
  312. delete MaterialRenderer2D;
  313. deleteAllTextures();
  314. if (BridgeCalls)
  315. delete BridgeCalls;
  316. #if defined(EGL_VERSION_1_0)
  317. eglMakeCurrent(EglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
  318. if (EglContext != EGL_NO_CONTEXT)
  319. {
  320. eglDestroyContext(EglDisplay, EglContext);
  321. EglContext = EGL_NO_CONTEXT;
  322. }
  323. if (EglSurface != EGL_NO_SURFACE)
  324. {
  325. eglDestroySurface(EglDisplay, EglSurface);
  326. EglSurface = EGL_NO_SURFACE;
  327. }
  328. if (EglDisplay != EGL_NO_DISPLAY)
  329. {
  330. eglTerminate(EglDisplay);
  331. EglDisplay = EGL_NO_DISPLAY;
  332. }
  333. #if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_)
  334. if (HDc)
  335. ReleaseDC((HWND)EglWindow, HDc);
  336. #endif
  337. #elif defined(GL_ES_VERSION_2_0)
  338. if (0 != ViewFramebuffer)
  339. {
  340. glDeleteFramebuffers(1,&ViewFramebuffer);
  341. ViewFramebuffer = 0;
  342. }
  343. if (0 != ViewRenderbuffer)
  344. {
  345. glDeleteRenderbuffers(1,&ViewRenderbuffer);
  346. ViewRenderbuffer = 0;
  347. }
  348. if (0 != ViewDepthRenderbuffer)
  349. {
  350. glDeleteRenderbuffers(1,&ViewDepthRenderbuffer);
  351. ViewDepthRenderbuffer = 0;
  352. }
  353. #endif
  354. }
  355. // -----------------------------------------------------------------------
  356. // METHODS
  357. // -----------------------------------------------------------------------
  358. void COGLES2Driver::reloadEGLSurface(void* window)
  359. {
  360. os::Printer::log("Reload EGL surface.");
  361. #ifdef EGL_VERSION_1_0
  362. #if defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_)
  363. EglWindow = (ANativeWindow*)window;
  364. #endif
  365. if (!EglWindow)
  366. os::Printer::log("Invalid Egl window.");
  367. eglMakeCurrent(EglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
  368. eglDestroySurface(EglDisplay, EglSurface);
  369. EglSurface = eglCreateWindowSurface(EglDisplay, EglConfig, EglWindow, 0);
  370. if (EGL_NO_SURFACE == EglSurface)
  371. os::Printer::log("Could not create EGL surface.");
  372. eglMakeCurrent(EglDisplay, EglSurface, EglSurface, EglContext);
  373. #endif
  374. }
  375. bool COGLES2Driver::genericDriverInit(const core::dimension2d<u32>& screenSize, bool stencilBuffer)
  376. {
  377. Name = glGetString(GL_VERSION);
  378. printVersion();
  379. #if defined(EGL_VERSION_1_0)
  380. os::Printer::log(eglQueryString(EglDisplay, EGL_CLIENT_APIS));
  381. #endif
  382. // print renderer information
  383. vendorName = glGetString(GL_VENDOR);
  384. os::Printer::log(vendorName.c_str(), ELL_INFORMATION);
  385. u32 i;
  386. for (i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
  387. CurrentTexture[i] = 0;
  388. // load extensions
  389. initExtensions(this,
  390. #if defined(EGL_VERSION_1_0)
  391. EglDisplay,
  392. #endif
  393. stencilBuffer);
  394. if (!BridgeCalls)
  395. BridgeCalls = new COGLES2CallBridge(this);
  396. StencilBuffer = stencilBuffer;
  397. DriverAttributes->setAttribute("MaxTextures", MaxTextureUnits);
  398. DriverAttributes->setAttribute("MaxSupportedTextures", MaxSupportedTextures);
  399. // DriverAttributes->setAttribute("MaxLights", MaxLights);
  400. DriverAttributes->setAttribute("MaxAnisotropy", MaxAnisotropy);
  401. // DriverAttributes->setAttribute("MaxUserClipPlanes", MaxUserClipPlanes);
  402. // DriverAttributes->setAttribute("MaxAuxBuffers", MaxAuxBuffers);
  403. // DriverAttributes->setAttribute("MaxMultipleRenderTargets", MaxMultipleRenderTargets);
  404. DriverAttributes->setAttribute("MaxIndices", (s32)MaxIndices);
  405. DriverAttributes->setAttribute("MaxTextureSize", (s32)MaxTextureSize);
  406. DriverAttributes->setAttribute("MaxTextureLODBias", MaxTextureLODBias);
  407. DriverAttributes->setAttribute("Version", Version);
  408. DriverAttributes->setAttribute("AntiAlias", AntiAlias);
  409. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  410. // Reset The Current Viewport
  411. BridgeCalls->setViewport(core::rect<s32>(0, 0, screenSize.Width, screenSize.Height));
  412. UserClipPlane.reallocate(0);
  413. setAmbientLight(SColorf(0.0f, 0.0f, 0.0f, 0.0f));
  414. glClearDepthf(1.0f);
  415. //TODO : OpenGL ES 2.0 Port : GL_PERSPECTIVE_CORRECTION_HINT
  416. //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  417. glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST);
  418. glDepthFunc(GL_LEQUAL);
  419. glFrontFace(GL_CW);
  420. // create material renderers
  421. createMaterialRenderers();
  422. // set the renderstates
  423. setRenderStates3DMode();
  424. // set fog mode
  425. setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog);
  426. // create matrix for flipping textures
  427. TextureFlipMatrix.buildTextureTransform(0.0f, core::vector2df(0, 0), core::vector2df(0, 1.0f), core::vector2df(1.0f, -1.0f));
  428. // We need to reset once more at the beginning of the first rendering.
  429. // This fixes problems with intermediate changes to the material during texture load.
  430. ResetRenderStates = true;
  431. testGLError();
  432. return true;
  433. }
  434. void COGLES2Driver::createMaterialRenderers()
  435. {
  436. // Load shaders from files (in future shaders will be merged with source code).
  437. // Fixed pipeline.
  438. core::stringc shaders_path = IRR_OGLES2_SHADER_PATH;
  439. if (Params.ShadersPath.size() > 0)
  440. shaders_path = Params.ShadersPath;
  441. core::stringc FPVSPath = shaders_path;
  442. FPVSPath += "COGLES2FixedPipeline.vsh";
  443. core::stringc FPFSPath = shaders_path;
  444. FPFSPath += "COGLES2FixedPipeline.fsh";
  445. io::IReadFile* FPVSFile = FileSystem->createAndOpenFile(FPVSPath);
  446. io::IReadFile* FPFSFile = FileSystem->createAndOpenFile(FPFSPath);
  447. c8* FPVSData = 0;
  448. c8* FPFSData = 0;
  449. long Size = FPVSFile ? FPVSFile->getSize() : 0;
  450. if (Size)
  451. {
  452. FPVSData = new c8[Size+1];
  453. FPVSFile->read(FPVSData, Size);
  454. FPVSData[Size] = 0;
  455. }
  456. Size = FPFSFile ? FPFSFile->getSize() : 0;
  457. if (Size)
  458. {
  459. // if both handles are the same we must reset the file
  460. if (FPFSFile == FPVSFile)
  461. FPFSFile->seek(0);
  462. FPFSData = new c8[Size+1];
  463. FPFSFile->read(FPFSData, Size);
  464. FPFSData[Size] = 0;
  465. }
  466. if (FPVSFile)
  467. FPVSFile->drop();
  468. if (FPFSFile)
  469. FPFSFile->drop();
  470. // Normal Mapping.
  471. core::stringc NMVSPath = shaders_path;
  472. NMVSPath += "COGLES2NormalMap.vsh";
  473. core::stringc NMFSPath = shaders_path;
  474. NMFSPath += "COGLES2NormalMap.fsh";
  475. io::IReadFile* NMVSFile = FileSystem->createAndOpenFile(NMVSPath);
  476. io::IReadFile* NMFSFile = FileSystem->createAndOpenFile(NMFSPath);
  477. c8* NMVSData = 0;
  478. c8* NMFSData = 0;
  479. Size = NMVSFile ? NMVSFile->getSize() : 0;
  480. if (Size)
  481. {
  482. NMVSData = new c8[Size+1];
  483. NMVSFile->read(NMVSData, Size);
  484. NMVSData[Size] = 0;
  485. }
  486. Size = NMFSFile ? NMFSFile->getSize() : 0;
  487. if (Size)
  488. {
  489. // if both handles are the same we must reset the file
  490. if (NMFSFile == NMVSFile)
  491. NMFSFile->seek(0);
  492. NMFSData = new c8[Size+1];
  493. NMFSFile->read(NMFSData, Size);
  494. NMFSData[Size] = 0;
  495. }
  496. if (NMVSFile)
  497. NMVSFile->drop();
  498. if (NMFSFile)
  499. NMFSFile->drop();
  500. // Parallax Mapping.
  501. core::stringc PMVSPath = shaders_path;
  502. PMVSPath += "COGLES2ParallaxMap.vsh";
  503. core::stringc PMFSPath = shaders_path;
  504. PMFSPath += "COGLES2ParallaxMap.fsh";
  505. io::IReadFile* PMVSFile = FileSystem->createAndOpenFile(FPVSPath);
  506. io::IReadFile* PMFSFile = FileSystem->createAndOpenFile(FPFSPath);
  507. c8* PMVSData = 0;
  508. c8* PMFSData = 0;
  509. Size = PMVSFile ? PMVSFile->getSize() : 0;
  510. if (Size)
  511. {
  512. PMVSData = new c8[Size+1];
  513. PMVSFile->read(PMVSData, Size);
  514. PMVSData[Size] = 0;
  515. }
  516. Size = PMFSFile ? PMFSFile->getSize() : 0;
  517. if (Size)
  518. {
  519. // if both handles are the same we must reset the file
  520. if (PMFSFile == PMVSFile)
  521. PMFSFile->seek(0);
  522. PMFSData = new c8[Size+1];
  523. PMFSFile->read(PMFSData, Size);
  524. PMFSData[Size] = 0;
  525. }
  526. if (PMVSFile)
  527. PMVSFile->drop();
  528. if (PMFSFile)
  529. PMFSFile->drop();
  530. // Create materials.
  531. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_SOLID, this));
  532. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_SOLID_2_LAYER, this));
  533. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_LIGHTMAP, this));
  534. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_LIGHTMAP_ADD, this));
  535. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_LIGHTMAP_M2, this));
  536. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_LIGHTMAP_M4, this));
  537. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_LIGHTMAP_LIGHTING, this));
  538. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_LIGHTMAP_LIGHTING_M2, this));
  539. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_LIGHTMAP_LIGHTING_M4, this));
  540. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_DETAIL_MAP, this));
  541. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_SPHERE_MAP, this));
  542. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_REFLECTION_2_LAYER, this));
  543. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_TRANSPARENT_ADD_COLOR, this));
  544. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_TRANSPARENT_ALPHA_CHANNEL, this));
  545. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_TRANSPARENT_ALPHA_CHANNEL_REF, this));
  546. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_TRANSPARENT_VERTEX_ALPHA, this));
  547. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_TRANSPARENT_REFLECTION_2_LAYER, this));
  548. if (!useCoreContext)
  549. {
  550. addAndDropMaterialRenderer(new COGLES2NormalMapRenderer(NMVSData, NMFSData, EMT_NORMAL_MAP_SOLID, this));
  551. addAndDropMaterialRenderer(new COGLES2NormalMapRenderer(NMVSData, NMFSData, EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR, this));
  552. addAndDropMaterialRenderer(new COGLES2NormalMapRenderer(NMVSData, NMFSData, EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA, this));
  553. }
  554. addAndDropMaterialRenderer(new COGLES2ParallaxMapRenderer(PMVSData, PMFSData, EMT_PARALLAX_MAP_SOLID, this));
  555. addAndDropMaterialRenderer(new COGLES2ParallaxMapRenderer(PMVSData, PMFSData, EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR, this));
  556. addAndDropMaterialRenderer(new COGLES2ParallaxMapRenderer(PMVSData, PMFSData, EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA, this));
  557. addAndDropMaterialRenderer(new COGLES2FixedPipelineRenderer(FPVSData, FPFSData, EMT_ONETEXTURE_BLEND, this));
  558. // Create 2D material renderer.
  559. core::stringc R2DVSPath = shaders_path;
  560. R2DVSPath += "COGLES2Renderer2D.vsh";
  561. core::stringc R2DFSPath = shaders_path;
  562. R2DFSPath += "COGLES2Renderer2D.fsh";
  563. io::IReadFile* R2DVSFile = FileSystem->createAndOpenFile(R2DVSPath);
  564. io::IReadFile* R2DFSFile = FileSystem->createAndOpenFile(R2DFSPath);
  565. c8* R2DVSData = 0;
  566. c8* R2DFSData = 0;
  567. Size = R2DVSFile ? R2DVSFile->getSize() : 0;
  568. if (Size)
  569. {
  570. R2DVSData = new c8[Size+1];
  571. R2DVSFile->read(R2DVSData, Size);
  572. R2DVSData[Size] = 0;
  573. }
  574. Size = R2DFSFile ? R2DFSFile->getSize() : 0;
  575. if (Size)
  576. {
  577. // if both handles are the same we must reset the file
  578. if (R2DFSFile == PMVSFile)
  579. R2DFSFile->seek(0);
  580. R2DFSData = new c8[Size+1];
  581. R2DFSFile->read(R2DFSData, Size);
  582. R2DFSData[Size] = 0;
  583. }
  584. if (R2DVSFile)
  585. R2DVSFile->drop();
  586. if (R2DFSFile)
  587. R2DFSFile->drop();
  588. MaterialRenderer2D = new COGLES2Renderer2D(R2DVSData, R2DFSData, this);
  589. }
  590. //! presents the rendered scene on the screen, returns false if failed
  591. bool COGLES2Driver::endScene()
  592. {
  593. CNullDriver::endScene();
  594. #if defined(EGL_VERSION_1_0)
  595. eglSwapBuffers(EglDisplay, EglSurface);
  596. EGLint g = eglGetError();
  597. if (EGL_SUCCESS != g)
  598. {
  599. if (EGL_CONTEXT_LOST == g)
  600. {
  601. // o-oh, ogl-es has lost contexts...
  602. os::Printer::log("Context lost, please restart your app.");
  603. }
  604. else
  605. os::Printer::log("Could not swap buffers for OpenGL-ES2 driver.");
  606. return false;
  607. }
  608. #elif defined(GL_ES_VERSION_2_0)
  609. glFlush();
  610. glBindRenderbuffer(GL_RENDERBUFFER, ViewRenderbuffer);
  611. #if defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
  612. Device->displayEnd();
  613. #endif
  614. #endif
  615. return true;
  616. }
  617. //! clears the zbuffer
  618. bool COGLES2Driver::beginScene(bool backBuffer, bool zBuffer, SColor color,
  619. const SExposedVideoData& videoData, core::rect<s32>* sourceRect)
  620. {
  621. CNullDriver::beginScene(backBuffer, zBuffer, color);
  622. GLbitfield mask = 0;
  623. if (backBuffer)
  624. {
  625. const f32 inv = 1.0f / 255.0f;
  626. glClearColor(color.getRed() * inv, color.getGreen() * inv,
  627. color.getBlue() * inv, color.getAlpha() * inv);
  628. mask |= GL_COLOR_BUFFER_BIT;
  629. }
  630. if (zBuffer)
  631. {
  632. glDepthMask(GL_TRUE);
  633. LastMaterial.ZWriteEnable = true;
  634. mask |= GL_DEPTH_BUFFER_BIT;
  635. }
  636. glClear(mask);
  637. testGLError();
  638. return true;
  639. }
  640. //! Returns the transformation set by setTransform
  641. const core::matrix4& COGLES2Driver::getTransform(E_TRANSFORMATION_STATE state) const
  642. {
  643. return Matrices[state];
  644. }
  645. //! sets transformation
  646. void COGLES2Driver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)
  647. {
  648. Matrices[state] = mat;
  649. Transformation3DChanged = true;
  650. }
  651. bool COGLES2Driver::updateVertexHardwareBuffer(SHWBufferLink_opengl *HWBuffer)
  652. {
  653. if (!HWBuffer)
  654. return false;
  655. const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer;
  656. const void* vertices = mb->getVertices();
  657. const u32 vertexCount = mb->getVertexCount();
  658. const E_VERTEX_TYPE vType = mb->getVertexType();
  659. const u32 vertexSize = getVertexPitchFromType(vType);
  660. //buffer vertex data, and convert colours...
  661. core::array<c8> buffer(vertexSize * vertexCount);
  662. memcpy(buffer.pointer(), vertices, vertexSize * vertexCount);
  663. //get or create buffer
  664. bool newBuffer = false;
  665. if (!HWBuffer->vbo_verticesID)
  666. {
  667. glGenBuffers(1, &HWBuffer->vbo_verticesID);
  668. if (!HWBuffer->vbo_verticesID) return false;
  669. newBuffer = true;
  670. }
  671. else if (HWBuffer->vbo_verticesSize < vertexCount*vertexSize)
  672. {
  673. newBuffer = true;
  674. }
  675. glBindBuffer(GL_ARRAY_BUFFER, HWBuffer->vbo_verticesID);
  676. //copy data to graphics card
  677. glGetError(); // clear error storage
  678. if (!newBuffer)
  679. glBufferSubData(GL_ARRAY_BUFFER, 0, vertexCount * vertexSize, buffer.const_pointer());
  680. else
  681. {
  682. HWBuffer->vbo_verticesSize = vertexCount * vertexSize;
  683. if (HWBuffer->Mapped_Vertex == scene::EHM_STATIC)
  684. glBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, buffer.const_pointer(), GL_STATIC_DRAW);
  685. else
  686. glBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, buffer.const_pointer(), GL_DYNAMIC_DRAW);
  687. }
  688. glBindBuffer(GL_ARRAY_BUFFER, 0);
  689. return (glGetError() == GL_NO_ERROR);
  690. }
  691. bool COGLES2Driver::updateIndexHardwareBuffer(SHWBufferLink_opengl *HWBuffer)
  692. {
  693. if (!HWBuffer)
  694. return false;
  695. const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer;
  696. const void* indices = mb->getIndices();
  697. u32 indexCount = mb->getIndexCount();
  698. GLenum indexSize;
  699. switch (mb->getIndexType())
  700. {
  701. case(EIT_16BIT):
  702. {
  703. indexSize = sizeof(u16);
  704. break;
  705. }
  706. case(EIT_32BIT):
  707. {
  708. indexSize = sizeof(u32);
  709. break;
  710. }
  711. default:
  712. {
  713. return false;
  714. }
  715. }
  716. //get or create buffer
  717. bool newBuffer = false;
  718. if (!HWBuffer->vbo_indicesID)
  719. {
  720. glGenBuffers(1, &HWBuffer->vbo_indicesID);
  721. if (!HWBuffer->vbo_indicesID) return false;
  722. newBuffer = true;
  723. }
  724. else if (HWBuffer->vbo_indicesSize < indexCount*indexSize)
  725. {
  726. newBuffer = true;
  727. }
  728. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, HWBuffer->vbo_indicesID);
  729. //copy data to graphics card
  730. glGetError(); // clear error storage
  731. if (!newBuffer)
  732. glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indexCount * indexSize, indices);
  733. else
  734. {
  735. HWBuffer->vbo_indicesSize = indexCount * indexSize;
  736. if (HWBuffer->Mapped_Index == scene::EHM_STATIC)
  737. glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_STATIC_DRAW);
  738. else
  739. glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_DYNAMIC_DRAW);
  740. }
  741. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  742. return (glGetError() == GL_NO_ERROR);
  743. }
  744. //! updates hardware buffer if needed
  745. bool COGLES2Driver::updateHardwareBuffer(SHWBufferLink *HWBuffer)
  746. {
  747. if (!HWBuffer)
  748. return false;
  749. if (HWBuffer->Mapped_Vertex != scene::EHM_NEVER)
  750. {
  751. if (HWBuffer->ChangedID_Vertex != HWBuffer->MeshBuffer->getChangedID_Vertex()
  752. || !((SHWBufferLink_opengl*)HWBuffer)->vbo_verticesID)
  753. {
  754. HWBuffer->ChangedID_Vertex = HWBuffer->MeshBuffer->getChangedID_Vertex();
  755. if (!updateVertexHardwareBuffer((SHWBufferLink_opengl*)HWBuffer))
  756. return false;
  757. }
  758. }
  759. if (HWBuffer->Mapped_Index != scene::EHM_NEVER)
  760. {
  761. if (HWBuffer->ChangedID_Index != HWBuffer->MeshBuffer->getChangedID_Index()
  762. || !((SHWBufferLink_opengl*)HWBuffer)->vbo_indicesID)
  763. {
  764. HWBuffer->ChangedID_Index = HWBuffer->MeshBuffer->getChangedID_Index();
  765. if (!updateIndexHardwareBuffer((SHWBufferLink_opengl*)HWBuffer))
  766. return false;
  767. }
  768. }
  769. return true;
  770. }
  771. //! Create hardware buffer from meshbuffer
  772. COGLES2Driver::SHWBufferLink *COGLES2Driver::createHardwareBuffer(const scene::IMeshBuffer* mb)
  773. {
  774. if (!mb || (mb->getHardwareMappingHint_Index() == scene::EHM_NEVER && mb->getHardwareMappingHint_Vertex() == scene::EHM_NEVER))
  775. return 0;
  776. SHWBufferLink_opengl *HWBuffer = new SHWBufferLink_opengl(mb);
  777. //add to map
  778. HWBufferMap.insert(HWBuffer->MeshBuffer, HWBuffer);
  779. HWBuffer->ChangedID_Vertex = HWBuffer->MeshBuffer->getChangedID_Vertex();
  780. HWBuffer->ChangedID_Index = HWBuffer->MeshBuffer->getChangedID_Index();
  781. HWBuffer->Mapped_Vertex = mb->getHardwareMappingHint_Vertex();
  782. HWBuffer->Mapped_Index = mb->getHardwareMappingHint_Index();
  783. HWBuffer->LastUsed = 0;
  784. HWBuffer->vbo_verticesID = 0;
  785. HWBuffer->vbo_indicesID = 0;
  786. HWBuffer->vbo_verticesSize = 0;
  787. HWBuffer->vbo_indicesSize = 0;
  788. if (!updateHardwareBuffer(HWBuffer))
  789. {
  790. deleteHardwareBuffer(HWBuffer);
  791. return 0;
  792. }
  793. return HWBuffer;
  794. }
  795. void COGLES2Driver::deleteHardwareBuffer(SHWBufferLink *_HWBuffer)
  796. {
  797. if (!_HWBuffer)
  798. return;
  799. SHWBufferLink_opengl *HWBuffer = (SHWBufferLink_opengl*)_HWBuffer;
  800. if (HWBuffer->vbo_verticesID)
  801. {
  802. glDeleteBuffers(1, &HWBuffer->vbo_verticesID);
  803. HWBuffer->vbo_verticesID = 0;
  804. }
  805. if (HWBuffer->vbo_indicesID)
  806. {
  807. glDeleteBuffers(1, &HWBuffer->vbo_indicesID);
  808. HWBuffer->vbo_indicesID = 0;
  809. }
  810. CNullDriver::deleteHardwareBuffer(_HWBuffer);
  811. }
  812. //! Draw hardware buffer
  813. void COGLES2Driver::drawHardwareBuffer(SHWBufferLink *_HWBuffer)
  814. {
  815. if (!_HWBuffer)
  816. return;
  817. SHWBufferLink_opengl *HWBuffer = (SHWBufferLink_opengl*)_HWBuffer;
  818. updateHardwareBuffer(HWBuffer); //check if update is needed
  819. HWBuffer->LastUsed = 0;//reset count
  820. const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer;
  821. const void *vertices = mb->getVertices();
  822. const void *indexList = mb->getIndices();
  823. if (HWBuffer->Mapped_Vertex != scene::EHM_NEVER)
  824. {
  825. glBindBuffer(GL_ARRAY_BUFFER, HWBuffer->vbo_verticesID);
  826. vertices = 0;
  827. }
  828. if (HWBuffer->Mapped_Index != scene::EHM_NEVER)
  829. {
  830. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, HWBuffer->vbo_indicesID);
  831. indexList = 0;
  832. }
  833. drawVertexPrimitiveList(vertices, mb->getVertexCount(),
  834. indexList, mb->getIndexCount() / 3,
  835. mb->getVertexType(), scene::EPT_TRIANGLES,
  836. mb->getIndexType());
  837. if (HWBuffer->Mapped_Vertex != scene::EHM_NEVER)
  838. glBindBuffer(GL_ARRAY_BUFFER, 0);
  839. if (HWBuffer->Mapped_Index != scene::EHM_NEVER)
  840. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  841. }
  842. // small helper function to create vertex buffer object adress offsets
  843. static inline u8* buffer_offset(const long offset)
  844. {
  845. return ((u8*)0 + offset);
  846. }
  847. //! draws a vertex primitive list
  848. void COGLES2Driver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
  849. const void* indexList, u32 primitiveCount,
  850. E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)
  851. {
  852. testGLError();
  853. if (!checkPrimitiveCount(primitiveCount))
  854. return;
  855. setRenderStates3DMode();
  856. drawVertexPrimitiveList2d3d(vertices, vertexCount, (const u16*)indexList, primitiveCount, vType, pType, iType);
  857. }
  858. void COGLES2Driver::drawVertexPrimitiveList2d3d(const void* vertices, u32 vertexCount,
  859. const void* indexList, u32 primitiveCount,
  860. E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType, bool threed)
  861. {
  862. if (!primitiveCount || !vertexCount)
  863. return;
  864. if (!threed && !checkPrimitiveCount(primitiveCount))
  865. return;
  866. CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType);
  867. //TODO: treat #ifdef GL_OES_point_size_array outside this if
  868. {
  869. glEnableVertexAttribArray(EVA_COLOR);
  870. glEnableVertexAttribArray(EVA_POSITION);
  871. if ((pType != scene::EPT_POINTS) && (pType != scene::EPT_POINT_SPRITES))
  872. {
  873. glEnableVertexAttribArray(EVA_TCOORD0);
  874. }
  875. #ifdef GL_OES_point_size_array
  876. else if (FeatureAvailable[IRR_OES_point_size_array] && (Material.Thickness == 0.0f))
  877. glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
  878. #endif
  879. if (threed && (pType != scene::EPT_POINTS) && (pType != scene::EPT_POINT_SPRITES))
  880. {
  881. glEnableVertexAttribArray(EVA_NORMAL);
  882. }
  883. switch (vType)
  884. {
  885. case EVT_STANDARD:
  886. if (vertices)
  887. {
  888. #ifdef GL_OES_point_size_array
  889. if ((pType == scene::EPT_POINTS) || (pType == scene::EPT_POINT_SPRITES))
  890. {
  891. if (FeatureAvailable[IRR_OES_point_size_array] && (Material.Thickness == 0.0f))
  892. glPointSizePointerOES(GL_FLOAT, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Normal.X);
  893. }
  894. else
  895. #endif
  896. glVertexAttribPointer(EVA_POSITION, (threed ? 3 : 2), GL_FLOAT, false, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Pos);
  897. if (threed)
  898. glVertexAttribPointer(EVA_NORMAL, 3, GL_FLOAT, false, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Normal);
  899. glVertexAttribPointer(EVA_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Color);
  900. glVertexAttribPointer(EVA_TCOORD0, 2, GL_FLOAT, false, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].TCoords);
  901. }
  902. else
  903. {
  904. glVertexAttribPointer(EVA_POSITION, 3, GL_FLOAT, false, sizeof(S3DVertex), 0);
  905. glVertexAttribPointer(EVA_NORMAL, 3, GL_FLOAT, false, sizeof(S3DVertex), buffer_offset(12));
  906. glVertexAttribPointer(EVA_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(S3DVertex), buffer_offset(24));
  907. glVertexAttribPointer(EVA_TCOORD0, 2, GL_FLOAT, false, sizeof(S3DVertex), buffer_offset(28));
  908. }
  909. //if (CurrentTexture[1])
  910. //{
  911. // // There must be some optimisation here as it uses the same texture coord !
  912. // glEnableVertexAttribArray(EVA_TCOORD1);
  913. // if (vertices)
  914. // glVertexAttribPointer(EVA_TCOORD1, 2, GL_FLOAT, false, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].TCoords);
  915. // else
  916. // glVertexAttribPointer(EVA_TCOORD1, 2, GL_FLOAT, false, sizeof(S3DVertex), buffer_offset(28));
  917. //}
  918. break;
  919. case EVT_2TCOORDS:
  920. //glEnableVertexAttribArray(EVA_TCOORD1);
  921. if (vertices)
  922. {
  923. glVertexAttribPointer(EVA_POSITION, (threed ? 3 : 2), GL_FLOAT, false, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].Pos);
  924. if (threed)
  925. glVertexAttribPointer(EVA_NORMAL, 3, GL_FLOAT, false, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].Normal);
  926. glVertexAttribPointer(EVA_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].Color);
  927. glVertexAttribPointer(EVA_TCOORD0, 2, GL_FLOAT, false, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].TCoords);
  928. //glVertexAttribPointer(EVA_TCOORD1, 2, GL_FLOAT, false, sizeof(S3DVertex2TCoords), &(static_cast<const S3DVertex2TCoords*>(vertices))[0].TCoords2);
  929. }
  930. else
  931. {
  932. glVertexAttribPointer(EVA_POSITION, 3, GL_FLOAT, false, sizeof(S3DVertex2TCoords), buffer_offset(0));
  933. glVertexAttribPointer(EVA_NORMAL, 3, GL_FLOAT, false, sizeof(S3DVertex2TCoords), buffer_offset(12));
  934. glVertexAttribPointer(EVA_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(S3DVertex2TCoords), buffer_offset(24));
  935. glVertexAttribPointer(EVA_TCOORD0, 2, GL_FLOAT, false, sizeof(S3DVertex2TCoords), buffer_offset(28));
  936. //glVertexAttribPointer(EVA_TCOORD1, 2, GL_FLOAT, false, sizeof(S3DVertex2TCoords), buffer_offset(36));
  937. }
  938. break;
  939. case EVT_TANGENTS:
  940. glEnableVertexAttribArray(EVA_TANGENT);
  941. glEnableVertexAttribArray(EVA_BINORMAL);
  942. if (vertices)
  943. {
  944. glVertexAttribPointer(EVA_POSITION, (threed ? 3 : 2), GL_FLOAT, false, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Pos);
  945. if (threed)
  946. glVertexAttribPointer(EVA_NORMAL, 3, GL_FLOAT, false, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Normal);
  947. glVertexAttribPointer(EVA_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Color);
  948. glVertexAttribPointer(EVA_TCOORD0, 2, GL_FLOAT, false, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].TCoords);
  949. glVertexAttribPointer(EVA_TANGENT, 3, GL_FLOAT, false, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Tangent);
  950. glVertexAttribPointer(EVA_BINORMAL, 3, GL_FLOAT, false, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Binormal);
  951. }
  952. else
  953. {
  954. glVertexAttribPointer(EVA_POSITION, 3, GL_FLOAT, false, sizeof(S3DVertexTangents), buffer_offset(0));
  955. glVertexAttribPointer(EVA_NORMAL, 3, GL_FLOAT, false, sizeof(S3DVertexTangents), buffer_offset(12));
  956. glVertexAttribPointer(EVA_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(S3DVertexTangents), buffer_offset(24));
  957. glVertexAttribPointer(EVA_TCOORD0, 2, GL_FLOAT, false, sizeof(S3DVertexTangents), buffer_offset(28));
  958. glVertexAttribPointer(EVA_TANGENT, 3, GL_FLOAT, false, sizeof(S3DVertexTangents), buffer_offset(36));
  959. glVertexAttribPointer(EVA_BINORMAL, 3, GL_FLOAT, false, sizeof(S3DVertexTangents), buffer_offset(48));
  960. }
  961. break;
  962. default:
  963. break;
  964. }
  965. }
  966. // draw everything
  967. GLenum indexSize = 0;
  968. switch (iType)
  969. {
  970. case(EIT_16BIT):
  971. {
  972. indexSize = GL_UNSIGNED_SHORT;
  973. break;
  974. }
  975. case(EIT_32BIT):
  976. {
  977. #ifdef GL_OES_element_index_uint
  978. #ifndef GL_UNSIGNED_INT
  979. #define GL_UNSIGNED_INT 0x1405
  980. #endif
  981. if (FeatureAvailable[IRR_OES_element_index_uint])
  982. indexSize = GL_UNSIGNED_INT;
  983. else
  984. #endif
  985. indexSize = GL_UNSIGNED_SHORT;
  986. break;
  987. }
  988. }
  989. switch (pType)
  990. {
  991. case scene::EPT_POINTS:
  992. case scene::EPT_POINT_SPRITES:
  993. {
  994. #ifdef GL_OES_point_sprite
  995. if (pType == scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_OES_point_sprite])
  996. glEnable(GL_POINT_SPRITE_OES);
  997. #endif
  998. // if ==0 we use the point size array
  999. if (Material.Thickness != 0.f)
  1000. {
  1001. // float quadratic[] = {0.0f, 0.0f, 10.01f};
  1002. //TODO : OpenGL ES 2.0 Port GL_POINT_DISTANCE_ATTENUATION
  1003. //glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, quadratic);
  1004. // float maxParticleSize = 1.0f;
  1005. //TODO : OpenGL ES 2.0 Port GL_POINT_SIZE_MAX
  1006. //glGetFloatv(GL_POINT_SIZE_MAX, &maxParticleSize);
  1007. // maxParticleSize=maxParticleSize<Material.Thickness?maxParticleSize:Material.Thickness;
  1008. // glPointParameterf(GL_POINT_SIZE_MAX,maxParticleSize);
  1009. // glPointParameterf(GL_POINT_SIZE_MIN,Material.Thickness);
  1010. //TODO : OpenGL ES 2.0 Port GL_POINT_FADE_THRESHOLD_SIZE
  1011. //glPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE, 60.0f);
  1012. //glPointSize(Material.Thickness);
  1013. }
  1014. #ifdef GL_OES_point_sprite
  1015. if (pType == scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_OES_point_sprite])
  1016. glTexEnvf(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE);
  1017. #endif
  1018. glDrawArrays(GL_POINTS, 0, primitiveCount);
  1019. #ifdef GL_OES_point_sprite
  1020. if (pType == scene::EPT_POINT_SPRITES && FeatureAvailable[IRR_OES_point_sprite])
  1021. {
  1022. glDisable(GL_POINT_SPRITE_OES);
  1023. glTexEnvf(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_FALSE);
  1024. }
  1025. #endif
  1026. }
  1027. break;
  1028. case scene::EPT_LINE_STRIP:
  1029. glDrawElements(GL_LINE_STRIP, primitiveCount + 1, indexSize, indexList);
  1030. break;
  1031. case scene::EPT_LINE_LOOP:
  1032. glDrawElements(GL_LINE_LOOP, primitiveCount, indexSize, indexList);
  1033. break;
  1034. case scene::EPT_LINES:
  1035. glDrawElements(GL_LINES, primitiveCount*2, indexSize, indexList);
  1036. break;
  1037. case scene::EPT_TRIANGLE_STRIP:
  1038. glDrawElements(GL_TRIANGLE_STRIP, primitiveCount + 2, indexSize, indexList);
  1039. break;
  1040. case scene::EPT_TRIANGLE_FAN:
  1041. glDrawElements(GL_TRIANGLE_FAN, primitiveCount + 2, indexSize, indexList);
  1042. break;
  1043. case scene::EPT_TRIANGLES:
  1044. glDrawElements((LastMaterial.Wireframe) ? GL_LINES : (LastMaterial.PointCloud) ? GL_POINTS : GL_TRIANGLES, primitiveCount*3, indexSize, indexList);
  1045. break;
  1046. case scene::EPT_QUAD_STRIP:
  1047. // TODO ogl-es
  1048. // glDrawElements(GL_QUAD_STRIP, primitiveCount*2+2, indexSize, indexList);
  1049. break;
  1050. case scene::EPT_QUADS:
  1051. // TODO ogl-es
  1052. // glDrawElements(GL_QUADS, primitiveCount*4, indexSize, indexList);
  1053. break;
  1054. case scene::EPT_POLYGON:
  1055. // TODO ogl-es
  1056. // glDrawElements(GL_POLYGON, primitiveCount, indexSize, indexList);
  1057. break;
  1058. }
  1059. {
  1060. if (vType == EVT_TANGENTS)
  1061. {
  1062. glDisableVertexAttribArray(EVA_TANGENT);
  1063. glDisableVertexAttribArray(EVA_BINORMAL);
  1064. }
  1065. //if ((vType != EVT_STANDARD) || CurrentTexture[1])
  1066. //{
  1067. // glDisableVertexAttribArray(EVA_TCOORD1);
  1068. //}
  1069. #ifdef GL_OES_point_size_array
  1070. if (FeatureAvailable[IRR_OES_point_size_array] && (Material.Thickness == 0.0f))
  1071. glDisableClientState(GL_POINT_SIZE_ARRAY_OES);
  1072. #endif
  1073. glDisableVertexAttribArray(EVA_POSITION);
  1074. glDisableVertexAttribArray(EVA_NORMAL);
  1075. glDisableVertexAttribArray(EVA_COLOR);
  1076. glDisableVertexAttribArray(EVA_TCOORD0);
  1077. }
  1078. testGLError();
  1079. }
  1080. //! draws a 2d image, using a color and the alpha channel of the texture
  1081. void COGLES2Driver::draw2DImage(const video::ITexture* texture,
  1082. const core::position2d<s32>& pos,
  1083. const core::rect<s32>& sourceRect,
  1084. const core::rect<s32>* clipRect, SColor color,
  1085. bool useAlphaChannelOfTexture)
  1086. {
  1087. if (!texture)
  1088. return;
  1089. if (!sourceRect.isValid())
  1090. return;
  1091. core::position2d<s32> targetPos(pos);
  1092. core::position2d<s32> sourcePos(sourceRect.UpperLeftCorner);
  1093. core::dimension2d<s32> sourceSize(sourceRect.getSize());
  1094. if (clipRect)
  1095. {
  1096. if (targetPos.X < clipRect->UpperLeftCorner.X)
  1097. {
  1098. sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X;
  1099. if (sourceSize.Width <= 0)
  1100. return;
  1101. sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X;
  1102. targetPos.X = clipRect->UpperLeftCorner.X;
  1103. }
  1104. if (targetPos.X + sourceSize.Width > clipRect->LowerRightCorner.X)
  1105. {
  1106. sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X;
  1107. if (sourceSize.Width <= 0)
  1108. return;
  1109. }
  1110. if (targetPos.Y < clipRect->UpperLeftCorner.Y)
  1111. {
  1112. sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y;
  1113. if (sourceSize.Height <= 0)
  1114. return;
  1115. sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y;
  1116. targetPos.Y = clipRect->UpperLeftCorner.Y;
  1117. }
  1118. if (targetPos.Y + sourceSize.Height > clipRect->LowerRightCorner.Y)
  1119. {
  1120. sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y;
  1121. if (sourceSize.Height <= 0)
  1122. return;
  1123. }
  1124. }
  1125. // clip these coordinates
  1126. if (targetPos.X < 0)
  1127. {
  1128. sourceSize.Width += targetPos.X;
  1129. if (sourceSize.Width <= 0)
  1130. return;
  1131. sourcePos.X -= targetPos.X;
  1132. targetPos.X = 0;
  1133. }
  1134. const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
  1135. if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width)
  1136. {
  1137. sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width;
  1138. if (sourceSize.Width <= 0)
  1139. return;
  1140. }
  1141. if (targetPos.Y < 0)
  1142. {
  1143. sourceSize.Height += targetPos.Y;
  1144. if (sourceSize.Height <= 0)
  1145. return;
  1146. sourcePos.Y -= targetPos.Y;
  1147. targetPos.Y = 0;
  1148. }
  1149. if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height)
  1150. {
  1151. sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height;
  1152. if (sourceSize.Height <= 0)
  1153. return;
  1154. }
  1155. // ok, we've clipped everything.
  1156. // now draw it.
  1157. // texcoords need to be flipped horizontally for RTTs
  1158. const bool isRTT = texture->isRenderTarget();
  1159. const core::dimension2d<u32>& ss = texture->getSize();
  1160. const f32 invW = 1.f / static_cast<f32>(ss.Width);
  1161. const f32 invH = 1.f / static_cast<f32>(ss.Height);
  1162. const core::rect<f32> tcoords(
  1163. sourcePos.X * invW,
  1164. (isRTT ? (sourcePos.Y + sourceSize.Height) : sourcePos.Y) * invH,
  1165. (sourcePos.X + sourceSize.Width) * invW,
  1166. (isRTT ? sourcePos.Y : (sourcePos.Y + sourceSize.Height)) * invH);
  1167. const core::rect<s32> poss(targetPos, sourceSize);
  1168. disableTextures(1);
  1169. if (!setActiveTexture(0, texture))
  1170. return;
  1171. setRenderStates2DMode(color.getAlpha() < 255, true, useAlphaChannelOfTexture);
  1172. u16 indices[] = {0, 1, 2, 3};
  1173. S3DVertex vertices[4];
  1174. vertices[0] = S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.UpperLeftCorner.Y, 0, 0, 0, 1, color, tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
  1175. vertices[1] = S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.UpperLeftCorner.Y, 0, 0, 0, 1, color, tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
  1176. vertices[2] = S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.LowerRightCorner.Y, 0, 0, 0, 1, color, tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
  1177. vertices[3] = S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.LowerRightCorner.Y, 0, 0, 0, 1, color, tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
  1178. drawVertexPrimitiveList2d3d(vertices, 4, indices, 2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN, EIT_16BIT, false);
  1179. }
  1180. void COGLES2Driver::draw2DImageBatch(const video::ITexture* texture,
  1181. const core::array<core::position2d<s32> >& positions,
  1182. const core::array<core::rect<s32> >& sourceRects,
  1183. const core::rect<s32>* clipRect,
  1184. SColor color, bool useAlphaChannelOfTexture)
  1185. {
  1186. if (!texture)
  1187. return;
  1188. if (!setActiveTexture(0, const_cast<video::ITexture*>(texture)))
  1189. return;
  1190. const irr::u32 drawCount = core::min_<u32>(positions.size(), sourceRects.size());
  1191. core::array<S3DVertex> vtx(drawCount * 4);
  1192. core::array<u16> indices(drawCount * 6);
  1193. for (u32 i = 0; i < drawCount; i++)
  1194. {
  1195. core::position2d<s32> targetPos = positions[i];
  1196. core::position2d<s32> sourcePos = sourceRects[i].UpperLeftCorner;
  1197. // This needs to be signed as it may go negative.
  1198. core::dimension2d<s32> sourceSize(sourceRects[i].getSize());
  1199. if (clipRect)
  1200. {
  1201. if (targetPos.X < clipRect->UpperLeftCorner.X)
  1202. {
  1203. sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X;
  1204. if (sourceSize.Width <= 0)
  1205. continue;
  1206. sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X;
  1207. targetPos.X = clipRect->UpperLeftCorner.X;
  1208. }
  1209. if (targetPos.X + (s32)sourceSize.Width > clipRect->LowerRightCorner.X)
  1210. {
  1211. sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X;
  1212. if (sourceSize.Width <= 0)
  1213. continue;
  1214. }
  1215. if (targetPos.Y < clipRect->UpperLeftCorner.Y)
  1216. {
  1217. sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y;
  1218. if (sourceSize.Height <= 0)
  1219. continue;
  1220. sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y;
  1221. targetPos.Y = clipRect->UpperLeftCorner.Y;
  1222. }
  1223. if (targetPos.Y + (s32)sourceSize.Height > clipRect->LowerRightCorner.Y)
  1224. {
  1225. sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y;
  1226. if (sourceSize.Height <= 0)
  1227. continue;
  1228. }
  1229. }
  1230. // clip these coordinates
  1231. if (targetPos.X < 0)
  1232. {
  1233. sourceSize.Width += targetPos.X;
  1234. if (sourceSize.Width <= 0)
  1235. continue;
  1236. sourcePos.X -= targetPos.X;
  1237. targetPos.X = 0;
  1238. }
  1239. const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
  1240. if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width)
  1241. {
  1242. sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width;
  1243. if (sourceSize.Width <= 0)
  1244. continue;
  1245. }
  1246. if (targetPos.Y < 0)
  1247. {
  1248. sourceSize.Height += targetPos.Y;
  1249. if (sourceSize.Height <= 0)
  1250. continue;
  1251. sourcePos.Y -= targetPos.Y;
  1252. targetPos.Y = 0;
  1253. }
  1254. if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height)
  1255. {
  1256. sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height;
  1257. if (sourceSize.Height <= 0)
  1258. continue;
  1259. }
  1260. // ok, we've clipped everything.
  1261. // now draw it.
  1262. core::rect<f32> tcoords;
  1263. tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getSize().Width ;
  1264. tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getSize().Height;
  1265. tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getSize().Width);
  1266. tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getSize().Height);
  1267. const core::rect<s32> poss(targetPos, sourceSize);
  1268. setRenderStates2DMode(color.getAlpha() < 255, true, useAlphaChannelOfTexture);
  1269. vtx.push_back(S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f,
  1270. 0.0f, 0.0f, 0.0f, color,
  1271. tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y));
  1272. vtx.push_back(S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f,
  1273. 0.0f, 0.0f, 0.0f, color,
  1274. tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y));
  1275. vtx.push_back(S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f,
  1276. 0.0f, 0.0f, 0.0f, color,
  1277. tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y));
  1278. vtx.push_back(S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f,
  1279. 0.0f, 0.0f, 0.0f, color,
  1280. tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y));
  1281. const u32 curPos = vtx.size() - 4;
  1282. indices.push_back(0 + curPos);
  1283. indices.push_back(1 + curPos);
  1284. indices.push_back(2 + curPos);
  1285. indices.push_back(0 + curPos);
  1286. indices.push_back(2 + curPos);
  1287. indices.push_back(3 + curPos);
  1288. }
  1289. if (vtx.size())
  1290. {
  1291. drawVertexPrimitiveList2d3d(vtx.pointer(), vtx.size(),
  1292. indices.pointer(), indices.size() / 3,
  1293. EVT_STANDARD, scene::EPT_TRIANGLES,
  1294. EIT_16BIT, false);
  1295. }
  1296. }
  1297. //! The same, but with a four element array of colors, one for each vertex
  1298. void COGLES2Driver::draw2DImage(const video::ITexture* texture,
  1299. const core::rect<s32>& destRect,
  1300. const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
  1301. const video::SColor* const colors, bool useAlphaChannelOfTexture)
  1302. {
  1303. if (!texture)
  1304. return;
  1305. // texcoords need to be flipped horizontally for RTTs
  1306. const bool isRTT = texture->isRenderTarget();
  1307. const core::dimension2du& ss = texture->getSize();
  1308. const f32 invW = 1.f / static_cast<f32>(ss.Width);
  1309. const f32 invH = 1.f / static_cast<f32>(ss.Height);
  1310. const core::rect<f32> tcoords(
  1311. sourceRect.UpperLeftCorner.X * invW,
  1312. (isRTT ? sourceRect.LowerRightCorner.Y : sourceRect.UpperLeftCorner.Y) * invH,
  1313. sourceRect.LowerRightCorner.X * invW,
  1314. (isRTT ? sourceRect.UpperLeftCorner.Y : sourceRect.LowerRightCorner.Y) *invH);
  1315. const video::SColor temp[4] =
  1316. {
  1317. 0xFFFFFFFF,
  1318. 0xFFFFFFFF,
  1319. 0xFFFFFFFF,
  1320. 0xFFFFFFFF
  1321. };
  1322. const video::SColor* const useColor = colors ? colors : temp;
  1323. disableTextures(1);
  1324. setActiveTexture(0, texture);
  1325. setRenderStates2DMode(useColor[0].getAlpha() < 255 || useColor[1].getAlpha() < 255 ||
  1326. useColor[2].getAlpha() < 255 || useColor[3].getAlpha() < 255,
  1327. true, useAlphaChannelOfTexture);
  1328. if (clipRect)
  1329. {
  1330. if (!clipRect->isValid())
  1331. return;
  1332. glEnable(GL_SCISSOR_TEST);
  1333. const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
  1334. glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y,
  1335. clipRect->getWidth(), clipRect->getHeight());
  1336. }
  1337. u16 indices[] = {0, 1, 2, 3};
  1338. S3DVertex vertices[4];
  1339. vertices[0] = S3DVertex((f32)destRect.UpperLeftCorner.X, (f32)destRect.UpperLeftCorner.Y, 0, 0, 0, 1, useColor[0], tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
  1340. vertices[1] = S3DVertex((f32)destRect.LowerRightCorner.X, (f32)destRect.UpperLeftCorner.Y, 0, 0, 0, 1, useColor[3], tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
  1341. vertices[2] = S3DVertex((f32)destRect.LowerRightCorner.X, (f32)destRect.LowerRightCorner.Y, 0, 0, 0, 1, useColor[2], tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
  1342. vertices[3] = S3DVertex((f32)destRect.UpperLeftCorner.X, (f32)destRect.LowerRightCorner.Y, 0, 0, 0, 1, useColor[1], tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
  1343. drawVertexPrimitiveList2d3d(vertices, 4, indices, 2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN, EIT_16BIT, false);
  1344. if (clipRect)
  1345. glDisable(GL_SCISSOR_TEST);
  1346. testGLError();
  1347. }
  1348. //! draws a set of 2d images, using a color and the alpha channel
  1349. void COGLES2Driver::draw2DImageBatch(const video::ITexture* texture,
  1350. const core::position2d<s32>& pos,
  1351. const core::array<core::rect<s32> >& sourceRects,
  1352. const core::array<s32>& indices, s32 kerningWidth,
  1353. const core::rect<s32>* clipRect, SColor color,
  1354. bool useAlphaChannelOfTexture)
  1355. {
  1356. if (!texture)
  1357. return;
  1358. disableTextures(1);
  1359. if (!setActiveTexture(0, texture))
  1360. return;
  1361. setRenderStates2DMode(color.getAlpha() < 255, true, useAlphaChannelOfTexture);
  1362. if (clipRect)
  1363. {
  1364. if (!clipRect->isValid())
  1365. return;
  1366. glEnable(GL_SCISSOR_TEST);
  1367. const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
  1368. glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y,
  1369. clipRect->getWidth(), clipRect->getHeight());
  1370. }
  1371. const core::dimension2du& ss = texture->getSize();
  1372. core::position2d<s32> targetPos(pos);
  1373. // texcoords need to be flipped horizontally for RTTs
  1374. const bool isRTT = texture->isRenderTarget();
  1375. const f32 invW = 1.f / static_cast<f32>(ss.Width);
  1376. const f32 invH = 1.f / static_cast<f32>(ss.Height);
  1377. core::array<S3DVertex> vertices;
  1378. core::array<u16> quadIndices;
  1379. vertices.reallocate(indices.size()*4);
  1380. quadIndices.reallocate(indices.size()*3);
  1381. for (u32 i = 0; i < indices.size(); ++i)
  1382. {
  1383. const s32 currentIndex = indices[i];
  1384. if (!sourceRects[currentIndex].isValid())
  1385. break;
  1386. const core::rect<f32> tcoords(
  1387. sourceRects[currentIndex].UpperLeftCorner.X * invW,
  1388. (isRTT ? sourceRects[currentIndex].LowerRightCorner.Y : sourceRects[currentIndex].UpperLeftCorner.Y) * invH,
  1389. sourceRects[currentIndex].LowerRightCorner.X * invW,
  1390. (isRTT ? sourceRects[currentIndex].UpperLeftCorner.Y : sourceRects[currentIndex].LowerRightCorner.Y) * invH);
  1391. const core::rect<s32> poss(targetPos, sourceRects[currentIndex].getSize());
  1392. const u32 vstart = vertices.size();
  1393. vertices.push_back(S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.UpperLeftCorner.Y, 0, 0, 0, 1, color, tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y));
  1394. vertices.push_back(S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.UpperLeftCorner.Y, 0, 0, 0, 1, color, tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y));
  1395. vertices.push_back(S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.LowerRightCorner.Y, 0, 0, 0, 1, color, tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y));
  1396. vertices.push_back(S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.LowerRightCorner.Y, 0, 0, 0, 1, color, tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y));
  1397. quadIndices.push_back(vstart);
  1398. quadIndices.push_back(vstart+1);
  1399. quadIndices.push_back(vstart+2);
  1400. quadIndices.push_back(vstart);
  1401. quadIndices.push_back(vstart+2);
  1402. quadIndices.push_back(vstart+3);
  1403. targetPos.X += sourceRects[currentIndex].getWidth();
  1404. }
  1405. if (vertices.size())
  1406. drawVertexPrimitiveList2d3d(vertices.pointer(), vertices.size(),
  1407. quadIndices.pointer(), vertices.size()/2,
  1408. video::EVT_STANDARD, scene::EPT_TRIANGLES,
  1409. EIT_16BIT, false);
  1410. if (clipRect)
  1411. glDisable(GL_SCISSOR_TEST);
  1412. testGLError();
  1413. }
  1414. //! draw a 2d rectangle
  1415. void COGLES2Driver::draw2DRectangle(SColor color,
  1416. const core::rect<s32>& position,
  1417. const core::rect<s32>* clip)
  1418. {
  1419. disableTextures();
  1420. setRenderStates2DMode(color.getAlpha() < 255, false, false);
  1421. core::rect<s32> pos = position;
  1422. if (clip)
  1423. pos.clipAgainst(*clip);
  1424. if (!pos.isValid())
  1425. return;
  1426. u16 indices[] = {0, 1, 2, 3};
  1427. S3DVertex vertices[4];
  1428. vertices[0] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.UpperLeftCorner.Y, 0, 0, 0, 1, color, 0, 0);
  1429. vertices[1] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.UpperLeftCorner.Y, 0, 0, 0, 1, color, 0, 0);
  1430. vertices[2] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.LowerRightCorner.Y, 0, 0, 0, 1, color, 0, 0);
  1431. vertices[3] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.LowerRightCorner.Y, 0, 0, 0, 1, color, 0, 0);
  1432. drawVertexPrimitiveList2d3d(vertices, 4, indices, 2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN, EIT_16BIT, false);
  1433. }
  1434. //! draw an 2d rectangle
  1435. void COGLES2Driver::draw2DRectangle(const core::rect<s32>& position,
  1436. SColor colorLeftUp, SColor colorRightUp,
  1437. SColor colorLeftDown, SColor colorRightDown,
  1438. const core::rect<s32>* clip)
  1439. {
  1440. core::rect<s32> pos = position;
  1441. if (clip)
  1442. pos.clipAgainst(*clip);
  1443. if (!pos.isValid())
  1444. return;
  1445. disableTextures();
  1446. setRenderStates2DMode(colorLeftUp.getAlpha() < 255 ||
  1447. colorRightUp.getAlpha() < 255 ||
  1448. colorLeftDown.getAlpha() < 255 ||
  1449. colorRightDown.getAlpha() < 255, false, false);
  1450. u16 indices[] = {0, 1, 2, 3};
  1451. S3DVertex vertices[4];
  1452. vertices[0] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.UpperLeftCorner.Y, 0, 0, 0, 1, colorLeftUp, 0, 0);
  1453. vertices[1] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.UpperLeftCorner.Y, 0, 0, 0, 1, colorRightUp, 0, 0);
  1454. vertices[2] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.LowerRightCorner.Y, 0, 0, 0, 1, colorRightDown, 0, 0);
  1455. vertices[3] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.LowerRightCorner.Y, 0, 0, 0, 1, colorLeftDown, 0, 0);
  1456. drawVertexPrimitiveList2d3d(vertices, 4, indices, 2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN, EIT_16BIT, false);
  1457. }
  1458. //! Draws a 2d line.
  1459. void COGLES2Driver::draw2DLine(const core::position2d<s32>& start,
  1460. const core::position2d<s32>& end, SColor color)
  1461. {
  1462. disableTextures();
  1463. setRenderStates2DMode(color.getAlpha() < 255, false, false);
  1464. u16 indices[] = {0, 1};
  1465. S3DVertex vertices[2];
  1466. vertices[0] = S3DVertex((f32)start.X, (f32)start.Y, 0, 0, 0, 1, color, 0, 0);
  1467. vertices[1] = S3DVertex((f32)end.X, (f32)end.Y, 0, 0, 0, 1, color, 1, 1);
  1468. drawVertexPrimitiveList2d3d(vertices, 2, indices, 1, video::EVT_STANDARD, scene::EPT_LINES, EIT_16BIT, false);
  1469. }
  1470. //! Draws a pixel
  1471. void COGLES2Driver::drawPixel(u32 x, u32 y, const SColor &color)
  1472. {
  1473. const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
  1474. if (x > (u32)renderTargetSize.Width || y > (u32)renderTargetSize.Height)
  1475. return;
  1476. disableTextures();
  1477. setRenderStates2DMode(color.getAlpha() < 255, false, false);
  1478. u16 indices[] = {0};
  1479. S3DVertex vertices[1];
  1480. vertices[0] = S3DVertex((f32)x, (f32)y, 0, 0, 0, 1, color, 0, 0);
  1481. drawVertexPrimitiveList2d3d(vertices, 1, indices, 1, video::EVT_STANDARD, scene::EPT_POINTS, EIT_16BIT, false);
  1482. }
  1483. bool COGLES2Driver::setActiveTexture(u32 stage, const video::ITexture* texture)
  1484. {
  1485. if (stage >= MaxSupportedTextures)
  1486. return false;
  1487. if (CurrentTexture[stage]==texture)
  1488. return true;
  1489. CurrentTexture[stage] = texture;
  1490. if (!texture)
  1491. return true;
  1492. else if (texture->getDriverType() != EDT_OGLES2)
  1493. {
  1494. CurrentTexture[stage] = 0;
  1495. os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
  1496. return false;
  1497. }
  1498. return true;
  1499. }
  1500. bool COGLES2Driver::isActiveTexture(u32 stage)
  1501. {
  1502. return (CurrentTexture[stage]) ? true : false;
  1503. }
  1504. //! disables all textures beginning with the optional fromStage parameter.
  1505. bool COGLES2Driver::disableTextures(u32 fromStage)
  1506. {
  1507. bool result = true;
  1508. for (u32 i = fromStage; i < MaxTextureUnits; ++i)
  1509. result &= setActiveTexture(i, 0);
  1510. return result;
  1511. }
  1512. //! creates a matrix in supplied GLfloat array to pass to OGLES1
  1513. inline void COGLES2Driver::createGLMatrix(float gl_matrix[16], const core::matrix4& m)
  1514. {
  1515. memcpy(gl_matrix, m.pointer(), 16 * sizeof(f32));
  1516. }
  1517. //! creates a opengltexturematrix from a D3D style texture matrix
  1518. inline void COGLES2Driver::createGLTextureMatrix(float *o, const core::matrix4& m)
  1519. {
  1520. o[0] = m[0];
  1521. o[1] = m[1];
  1522. o[2] = 0.f;
  1523. o[3] = 0.f;
  1524. o[4] = m[4];
  1525. o[5] = m[5];
  1526. o[6] = 0.f;
  1527. o[7] = 0.f;
  1528. o[8] = 0.f;
  1529. o[9] = 0.f;
  1530. o[10] = 1.f;
  1531. o[11] = 0.f;
  1532. o[12] = m[8];
  1533. o[13] = m[9];
  1534. o[14] = 0.f;
  1535. o[15] = 1.f;
  1536. }
  1537. //! returns a device dependent texture from a software surface (IImage)
  1538. video::ITexture* COGLES2Driver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData)
  1539. {
  1540. return new COGLES2Texture(surface, name, mipmapData, this);
  1541. }
  1542. //! Sets a material.
  1543. void COGLES2Driver::setMaterial(const SMaterial& material)
  1544. {
  1545. Material = material;
  1546. OverrideMaterial.apply(Material);
  1547. for (u32 i = 0; i < MaxTextureUnits; ++i)
  1548. setActiveTexture(i, material.getTexture(i));
  1549. }
  1550. //! prints error if an error happened.
  1551. bool COGLES2Driver::testGLError()
  1552. {
  1553. #ifdef _DEBUG
  1554. GLenum g = glGetError();
  1555. switch (g)
  1556. {
  1557. case GL_NO_ERROR:
  1558. return false;
  1559. case GL_INVALID_ENUM:
  1560. os::Printer::log("GL_INVALID_ENUM", ELL_ERROR);
  1561. break;
  1562. case GL_INVALID_VALUE:
  1563. os::Printer::log("GL_INVALID_VALUE", ELL_ERROR);
  1564. break;
  1565. case GL_INVALID_OPERATION:
  1566. os::Printer::log("GL_INVALID_OPERATION", ELL_ERROR);
  1567. break;
  1568. case GL_OUT_OF_MEMORY:
  1569. os::Printer::log("GL_OUT_OF_MEMORY", ELL_ERROR);
  1570. break;
  1571. };
  1572. return true;
  1573. #else
  1574. return false;
  1575. #endif
  1576. }
  1577. //! prints error if an error happened.
  1578. bool COGLES2Driver::testEGLError()
  1579. {
  1580. #if defined(EGL_VERSION_1_0) && defined(_DEBUG)
  1581. EGLint g = eglGetError();
  1582. switch (g)
  1583. {
  1584. case EGL_SUCCESS:
  1585. return false;
  1586. case EGL_NOT_INITIALIZED :
  1587. os::Printer::log("Not Initialized", ELL_ERROR);
  1588. break;
  1589. case EGL_BAD_ACCESS:
  1590. os::Printer::log("Bad Access", ELL_ERROR);
  1591. break;
  1592. case EGL_BAD_ALLOC:
  1593. os::Printer::log("Bad Alloc", ELL_ERROR);
  1594. break;
  1595. case EGL_BAD_ATTRIBUTE:
  1596. os::Printer::log("Bad Attribute", ELL_ERROR);
  1597. break;
  1598. case EGL_BAD_CONTEXT:
  1599. os::Printer::log("Bad Context", ELL_ERROR);
  1600. break;
  1601. case EGL_BAD_CONFIG:
  1602. os::Printer::log("Bad Config", ELL_ERROR);
  1603. break;
  1604. case EGL_BAD_CURRENT_SURFACE:
  1605. os::Printer::log("Bad Current Surface", ELL_ERROR);
  1606. break;
  1607. case EGL_BAD_DISPLAY:
  1608. os::Printer::log("Bad Display", ELL_ERROR);
  1609. break;
  1610. case EGL_BAD_SURFACE:
  1611. os::Printer::log("Bad Surface", ELL_ERROR);
  1612. break;
  1613. case EGL_BAD_MATCH:
  1614. os::Printer::log("Bad Match", ELL_ERROR);
  1615. break;
  1616. case EGL_BAD_PARAMETER:
  1617. os::Printer::log("Bad Parameter", ELL_ERROR);
  1618. break;
  1619. case EGL_BAD_NATIVE_PIXMAP:
  1620. os::Printer::log("Bad Native Pixmap", ELL_ERROR);
  1621. break;
  1622. case EGL_BAD_NATIVE_WINDOW:
  1623. os::Printer::log("Bad Native Window", ELL_ERROR);
  1624. break;
  1625. case EGL_CONTEXT_LOST:
  1626. os::Printer::log("Context Lost", ELL_ERROR);
  1627. break;
  1628. };
  1629. return true;
  1630. #else
  1631. return false;
  1632. #endif
  1633. }
  1634. void COGLES2Driver::setRenderStates3DMode()
  1635. {
  1636. if (useCoreContext)
  1637. return;
  1638. if (CurrentRenderMode != ERM_3D)
  1639. {
  1640. // Reset Texture Stages
  1641. BridgeCalls->setBlend(false);
  1642. BridgeCalls->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1643. ResetRenderStates = true;
  1644. }
  1645. if (ResetRenderStates || LastMaterial != Material)
  1646. {
  1647. // unset old material
  1648. // unset last 3d material
  1649. if (CurrentRenderMode == ERM_2D)
  1650. MaterialRenderer2D->OnUnsetMaterial();
  1651. else if (LastMaterial.MaterialType != Material.MaterialType &&
  1652. static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size())
  1653. MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial();
  1654. // set new material.
  1655. if (static_cast<u32>(Material.MaterialType) < MaterialRenderers.size())
  1656. MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial(
  1657. Material, LastMaterial, ResetRenderStates, this);
  1658. LastMaterial = Material;
  1659. ResetRenderStates = false;
  1660. }
  1661. if (static_cast<u32>(Material.MaterialType) < MaterialRenderers.size())
  1662. MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, video::EVT_STANDARD);
  1663. CurrentRenderMode = ERM_3D;
  1664. }
  1665. //! Can be called by an IMaterialRenderer to make its work easier.
  1666. void COGLES2Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, bool resetAllRenderStates)
  1667. {
  1668. if (useCoreContext)
  1669. return;
  1670. // ZBuffer
  1671. if (resetAllRenderStates || lastmaterial.ZBuffer != material.ZBuffer)
  1672. {
  1673. switch (material.ZBuffer)
  1674. {
  1675. case ECFN_NEVER: // it will be ECFN_DISABLED after merge
  1676. BridgeCalls->setDepthTest(false);
  1677. break;
  1678. case ECFN_LESSEQUAL:
  1679. BridgeCalls->setDepthTest(true);
  1680. BridgeCalls->setDepthFunc(GL_LEQUAL);
  1681. break;
  1682. case ECFN_EQUAL:
  1683. BridgeCalls->setDepthTest(true);
  1684. BridgeCalls->setDepthFunc(GL_EQUAL);
  1685. break;
  1686. case ECFN_LESS:
  1687. BridgeCalls->setDepthTest(true);
  1688. BridgeCalls->setDepthFunc(GL_LESS);
  1689. break;
  1690. case ECFN_NOTEQUAL:
  1691. BridgeCalls->setDepthTest(true);
  1692. BridgeCalls->setDepthFunc(GL_NOTEQUAL);
  1693. break;
  1694. case ECFN_GREATEREQUAL:
  1695. BridgeCalls->setDepthTest(true);
  1696. BridgeCalls->setDepthFunc(GL_GEQUAL);
  1697. break;
  1698. case ECFN_GREATER:
  1699. BridgeCalls->setDepthTest(true);
  1700. BridgeCalls->setDepthFunc(GL_GREATER);
  1701. break;
  1702. case ECFN_ALWAYS:
  1703. BridgeCalls->setDepthTest(true);
  1704. BridgeCalls->setDepthFunc(GL_ALWAYS);
  1705. break;
  1706. /*case ECFN_NEVER:
  1707. BridgeCalls->setDepthTest(true);
  1708. BridgeCalls->setDepthFunc(GL_NEVER);
  1709. break;*/
  1710. }
  1711. }
  1712. // ZWrite
  1713. // if (resetAllRenderStates || lastmaterial.ZWriteEnable != material.ZWriteEnable)
  1714. {
  1715. if (material.ZWriteEnable && (AllowZWriteOnTransparent || !material.isTransparent()))
  1716. BridgeCalls->setDepthMask(true);
  1717. else
  1718. BridgeCalls->setDepthMask(false);
  1719. }
  1720. // Back face culling
  1721. if (resetAllRenderStates || (lastmaterial.FrontfaceCulling != material.FrontfaceCulling) || (lastmaterial.BackfaceCulling != material.BackfaceCulling))
  1722. {
  1723. if ((material.FrontfaceCulling) && (material.BackfaceCulling))
  1724. {
  1725. BridgeCalls->setCullFaceFunc(GL_FRONT_AND_BACK);
  1726. BridgeCalls->setCullFace(true);
  1727. }
  1728. else
  1729. if (material.BackfaceCulling)
  1730. {
  1731. BridgeCalls->setCullFaceFunc(GL_BACK);
  1732. BridgeCalls->setCullFace(true);
  1733. }
  1734. else
  1735. if (material.FrontfaceCulling)
  1736. {
  1737. BridgeCalls->setCullFaceFunc(GL_FRONT);
  1738. BridgeCalls->setCullFace(true);
  1739. }
  1740. else
  1741. BridgeCalls->setCullFace(false);
  1742. }
  1743. // Color Mask
  1744. if (resetAllRenderStates || lastmaterial.ColorMask != material.ColorMask)
  1745. {
  1746. glColorMask(
  1747. (material.ColorMask & ECP_RED)?GL_TRUE:GL_FALSE,
  1748. (material.ColorMask & ECP_GREEN)?GL_TRUE:GL_FALSE,
  1749. (material.ColorMask & ECP_BLUE)?GL_TRUE:GL_FALSE,
  1750. (material.ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE);
  1751. }
  1752. // Blend operation
  1753. if (resetAllRenderStates|| lastmaterial.BlendOperation != material.BlendOperation)
  1754. {
  1755. if (material.BlendOperation==EBO_NONE)
  1756. BridgeCalls->setBlend(false);
  1757. else
  1758. {
  1759. BridgeCalls->setBlend(true);
  1760. switch (material.BlendOperation)
  1761. {
  1762. case EBO_ADD:
  1763. glBlendEquation(GL_FUNC_ADD);
  1764. break;
  1765. case EBO_SUBTRACT:
  1766. glBlendEquation(GL_FUNC_SUBTRACT);
  1767. break;
  1768. case EBO_REVSUBTRACT:
  1769. glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
  1770. break;
  1771. default:
  1772. break;
  1773. }
  1774. }
  1775. }
  1776. // Anti aliasing
  1777. if (resetAllRenderStates || lastmaterial.AntiAliasing != material.AntiAliasing)
  1778. {
  1779. if (material.AntiAliasing & EAAM_ALPHA_TO_COVERAGE)
  1780. glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
  1781. else if (lastmaterial.AntiAliasing & EAAM_ALPHA_TO_COVERAGE)
  1782. glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
  1783. }
  1784. // Texture parameters
  1785. setTextureRenderStates(material, resetAllRenderStates);
  1786. }
  1787. //! Compare in SMaterial doesn't check texture parameters, so we should call this on each OnRender call.
  1788. void COGLES2Driver::setTextureRenderStates(const SMaterial& material, bool resetAllRenderstates)
  1789. {
  1790. if (useCoreContext)
  1791. return;
  1792. // Set textures to TU/TIU and apply filters to them
  1793. for (s32 i = MaxTextureUnits-1; i>= 0; --i)
  1794. {
  1795. const COGLES2Texture* tmpTexture = static_cast<const COGLES2Texture*>(CurrentTexture[i]);
  1796. if (CurrentTexture[i])
  1797. BridgeCalls->setTexture(i);
  1798. else
  1799. continue;
  1800. // This code causes issues on some devices with legacy pipeline
  1801. // and also mipmaps should be handled in STK texture manager,
  1802. // so just disable this part of code
  1803. continue;
  1804. if(resetAllRenderstates)
  1805. tmpTexture->getStatesCache().IsCached = false;
  1806. if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter ||
  1807. material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter)
  1808. {
  1809. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
  1810. (material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST);
  1811. tmpTexture->getStatesCache().BilinearFilter = material.TextureLayer[i].BilinearFilter;
  1812. tmpTexture->getStatesCache().TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
  1813. }
  1814. if (material.UseMipMaps && CurrentTexture[i]->hasMipMaps())
  1815. {
  1816. if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter ||
  1817. material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter || !tmpTexture->getStatesCache().MipMapStatus)
  1818. {
  1819. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  1820. material.TextureLayer[i].TrilinearFilter ? GL_LINEAR_MIPMAP_LINEAR :
  1821. material.TextureLayer[i].BilinearFilter ? GL_LINEAR_MIPMAP_NEAREST :
  1822. GL_NEAREST_MIPMAP_NEAREST);
  1823. tmpTexture->getStatesCache().BilinearFilter = material.TextureLayer[i].BilinearFilter;
  1824. tmpTexture->getStatesCache().TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
  1825. tmpTexture->getStatesCache().MipMapStatus = true;
  1826. }
  1827. }
  1828. else
  1829. {
  1830. if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].BilinearFilter != tmpTexture->getStatesCache().BilinearFilter ||
  1831. material.TextureLayer[i].TrilinearFilter != tmpTexture->getStatesCache().TrilinearFilter || tmpTexture->getStatesCache().MipMapStatus)
  1832. {
  1833. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  1834. (material.TextureLayer[i].BilinearFilter || material.TextureLayer[i].TrilinearFilter) ? GL_LINEAR : GL_NEAREST);
  1835. tmpTexture->getStatesCache().BilinearFilter = material.TextureLayer[i].BilinearFilter;
  1836. tmpTexture->getStatesCache().TrilinearFilter = material.TextureLayer[i].TrilinearFilter;
  1837. tmpTexture->getStatesCache().MipMapStatus = false;
  1838. }
  1839. }
  1840. #ifdef GL_EXT_texture_filter_anisotropic
  1841. if (FeatureAvailable[IRR_EXT_texture_filter_anisotropic] &&
  1842. (!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].AnisotropicFilter != tmpTexture->getStatesCache().AnisotropicFilter))
  1843. {
  1844. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
  1845. material.TextureLayer[i].AnisotropicFilter>1 ? core::min_(MaxAnisotropy, material.TextureLayer[i].AnisotropicFilter) : 1);
  1846. tmpTexture->getStatesCache().AnisotropicFilter = material.TextureLayer[i].AnisotropicFilter;
  1847. }
  1848. #endif
  1849. if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].TextureWrapU != tmpTexture->getStatesCache().WrapU)
  1850. {
  1851. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, getTextureWrapMode(material.TextureLayer[i].TextureWrapU));
  1852. tmpTexture->getStatesCache().WrapU = material.TextureLayer[i].TextureWrapU;
  1853. }
  1854. if(!tmpTexture->getStatesCache().IsCached || material.TextureLayer[i].TextureWrapV != tmpTexture->getStatesCache().WrapV)
  1855. {
  1856. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, getTextureWrapMode(material.TextureLayer[i].TextureWrapV));
  1857. tmpTexture->getStatesCache().WrapV = material.TextureLayer[i].TextureWrapV;
  1858. }
  1859. tmpTexture->getStatesCache().IsCached = true;
  1860. }
  1861. }
  1862. // Get OpenGL ES2.0 texture wrap mode from Irrlicht wrap mode.
  1863. GLint COGLES2Driver::getTextureWrapMode(u8 clamp) const
  1864. {
  1865. switch (clamp)
  1866. {
  1867. case ETC_CLAMP:
  1868. case ETC_CLAMP_TO_EDGE:
  1869. case ETC_CLAMP_TO_BORDER:
  1870. return GL_CLAMP_TO_EDGE;
  1871. case ETC_MIRROR:
  1872. return GL_REPEAT;
  1873. default:
  1874. return GL_REPEAT;
  1875. }
  1876. }
  1877. //! sets the needed renderstates
  1878. void COGLES2Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel)
  1879. {
  1880. if (useCoreContext)
  1881. return;
  1882. if (CurrentRenderMode != ERM_2D)
  1883. {
  1884. // unset last 3d material
  1885. if (CurrentRenderMode == ERM_3D)
  1886. {
  1887. if (static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size())
  1888. MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial();
  1889. }
  1890. CurrentRenderMode = ERM_2D;
  1891. }
  1892. if (!OverrideMaterial2DEnabled)
  1893. Material = InitMaterial2D;
  1894. if (OverrideMaterial2DEnabled)
  1895. {
  1896. OverrideMaterial2D.Lighting=false;
  1897. OverrideMaterial2D.ZWriteEnable=false;
  1898. OverrideMaterial2D.ZBuffer=ECFN_NEVER; // it will be ECFN_DISABLED after merge
  1899. OverrideMaterial2D.Lighting=false;
  1900. Material = OverrideMaterial2D;
  1901. }
  1902. if (texture)
  1903. MaterialRenderer2D->setTexture(CurrentTexture[0]);
  1904. else
  1905. MaterialRenderer2D->setTexture(0);
  1906. MaterialRenderer2D->OnSetMaterial(Material, LastMaterial, true, 0);
  1907. LastMaterial = Material;
  1908. // no alphaChannel without texture
  1909. alphaChannel &= texture;
  1910. if (alphaChannel || alpha)
  1911. {
  1912. BridgeCalls->setBlend(true);
  1913. BridgeCalls->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1914. }
  1915. else
  1916. BridgeCalls->setBlend(false);
  1917. MaterialRenderer2D->OnRender(this, video::EVT_STANDARD);
  1918. }
  1919. //! \return Returns the name of the video driver.
  1920. const wchar_t* COGLES2Driver::getName() const
  1921. {
  1922. return Name.c_str();
  1923. }
  1924. //! deletes all dynamic lights there are
  1925. void COGLES2Driver::deleteAllDynamicLights()
  1926. {
  1927. RequestedLights.clear();
  1928. CNullDriver::deleteAllDynamicLights();
  1929. }
  1930. //! adds a dynamic light
  1931. s32 COGLES2Driver::addDynamicLight(const SLight& light)
  1932. {
  1933. CNullDriver::addDynamicLight(light);
  1934. RequestedLights.push_back(RequestedLight(light));
  1935. u32 newLightIndex = RequestedLights.size() - 1;
  1936. return (s32)newLightIndex;
  1937. }
  1938. //! Turns a dynamic light on or off
  1939. //! \param lightIndex: the index returned by addDynamicLight
  1940. //! \param turnOn: true to turn the light on, false to turn it off
  1941. void COGLES2Driver::turnLightOn(s32 lightIndex, bool turnOn)
  1942. {
  1943. if (lightIndex < 0 || lightIndex >= (s32)RequestedLights.size())
  1944. return;
  1945. RequestedLight & requestedLight = RequestedLights[lightIndex];
  1946. requestedLight.DesireToBeOn = turnOn;
  1947. }
  1948. //! returns the maximal amount of dynamic lights the device can handle
  1949. u32 COGLES2Driver::getMaximalDynamicLightAmount() const
  1950. {
  1951. return 8;
  1952. }
  1953. //! Sets the dynamic ambient light color.
  1954. void COGLES2Driver::setAmbientLight(const SColorf& color)
  1955. {
  1956. AmbientLight = color;
  1957. }
  1958. //! returns the dynamic ambient light color.
  1959. const SColorf& COGLES2Driver::getAmbientLight() const
  1960. {
  1961. return AmbientLight;
  1962. }
  1963. // this code was sent in by Oliver Klems, thank you
  1964. void COGLES2Driver::setViewPort(const core::rect<s32>& area)
  1965. {
  1966. core::rect<s32> vp = area;
  1967. core::rect<s32> rendert(0, 0, getCurrentRenderTargetSize().Width, getCurrentRenderTargetSize().Height);
  1968. vp.clipAgainst(rendert);
  1969. if (vp.getHeight() > 0 && vp.getWidth() > 0)
  1970. BridgeCalls->setViewport(core::rect<s32>(vp.UpperLeftCorner.X, getCurrentRenderTargetSize().Height - vp.UpperLeftCorner.Y - vp.getHeight(), vp.getWidth(), vp.getHeight()));
  1971. ViewPort = vp;
  1972. testGLError();
  1973. }
  1974. //! Draws a shadow volume into the stencil buffer.
  1975. void COGLES2Driver::drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail)
  1976. {
  1977. if (!StencilBuffer || !count)
  1978. return;
  1979. // unset last 3d material
  1980. if (CurrentRenderMode == ERM_3D &&
  1981. static_cast<u32>(Material.MaterialType) < MaterialRenderers.size())
  1982. {
  1983. MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial();
  1984. ResetRenderStates = true;
  1985. }
  1986. // store current OGLES state
  1987. const GLboolean cullFaceEnabled = glIsEnabled(GL_CULL_FACE);
  1988. GLint cullFaceMode;
  1989. glGetIntegerv(GL_CULL_FACE_MODE, &cullFaceMode);
  1990. GLint depthFunc;
  1991. glGetIntegerv(GL_DEPTH_FUNC, &depthFunc);
  1992. GLboolean depthMask;
  1993. glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
  1994. glDepthFunc(GL_LEQUAL);
  1995. glDepthMask(GL_FALSE); // no depth buffer writing
  1996. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // no color buffer drawing
  1997. glEnable(GL_STENCIL_TEST);
  1998. glEnable(GL_POLYGON_OFFSET_FILL);
  1999. glPolygonOffset(0.0f, 1.0f);
  2000. glEnableVertexAttribArray(EVA_POSITION);
  2001. glVertexAttribPointer(EVA_POSITION, 3, GL_FLOAT, false, sizeof(core::vector3df), &triangles[0]);
  2002. glStencilMask(~0);
  2003. glStencilFunc(GL_ALWAYS, 0, ~0);
  2004. GLenum decr = GL_DECR;
  2005. GLenum incr = GL_INCR;
  2006. #if defined(GL_OES_stencil_wrap)
  2007. if (FeatureAvailable[IRR_OES_stencil_wrap])
  2008. {
  2009. decr = GL_DECR_WRAP_OES;
  2010. incr = GL_INCR_WRAP_OES;
  2011. }
  2012. #endif
  2013. glEnable(GL_CULL_FACE);
  2014. if (!zfail)
  2015. {
  2016. // ZPASS Method
  2017. glCullFace(GL_BACK);
  2018. glStencilOp(GL_KEEP, GL_KEEP, incr);
  2019. glDrawArrays(GL_TRIANGLES, 0, count);
  2020. glCullFace(GL_FRONT);
  2021. glStencilOp(GL_KEEP, GL_KEEP, decr);
  2022. glDrawArrays(GL_TRIANGLES, 0, count);
  2023. }
  2024. else
  2025. {
  2026. // ZFAIL Method
  2027. glStencilOp(GL_KEEP, incr, GL_KEEP);
  2028. glCullFace(GL_FRONT);
  2029. glDrawArrays(GL_TRIANGLES, 0, count);
  2030. glStencilOp(GL_KEEP, decr, GL_KEEP);
  2031. glCullFace(GL_BACK);
  2032. glDrawArrays(GL_TRIANGLES, 0, count);
  2033. }
  2034. glDisableVertexAttribArray(EVA_POSITION);
  2035. glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  2036. glDisable(GL_STENCIL_TEST);
  2037. if (cullFaceEnabled)
  2038. glEnable(GL_CULL_FACE);
  2039. else
  2040. glDisable(GL_CULL_FACE);
  2041. glCullFace(cullFaceMode);
  2042. glDepthFunc(depthFunc);
  2043. glDepthMask(depthMask);
  2044. testGLError();
  2045. }
  2046. void COGLES2Driver::drawStencilShadow(bool clearStencilBuffer,
  2047. video::SColor leftUpEdge, video::SColor rightUpEdge,
  2048. video::SColor leftDownEdge, video::SColor rightDownEdge)
  2049. {
  2050. if (!StencilBuffer)
  2051. return;
  2052. disableTextures();
  2053. // store attributes
  2054. GLboolean depthMask;
  2055. glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
  2056. // GLint shadeModel;
  2057. //TODO : OpenGL ES 2.0 Port glGetIntegerv
  2058. //glGetIntegerv(GL_SHADE_MODEL, &shadeModel);
  2059. glDepthMask(GL_FALSE);
  2060. //TODO : OpenGL ES 2.0 Port glShadeModel
  2061. //glShadeModel(GL_FLAT);
  2062. glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  2063. glEnable(GL_STENCIL_TEST);
  2064. glStencilFunc(GL_NOTEQUAL, 0, ~0);
  2065. glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  2066. // draw a shadow rectangle covering the entire screen using stencil buffer
  2067. //Wrapper->glMatrixMode(GL_MODELVIEW);
  2068. //TODO : OpenGL ES 2.0 Port glPushMatrix
  2069. //glPushMatrix();
  2070. //Wrapper->glLoadIdentity();
  2071. //Wrapper->glMatrixMode(GL_PROJECTION);
  2072. //TODO : OpenGL ES 2.0 Port glPushMatrix
  2073. //glPushMatrix();
  2074. //Wrapper->glLoadIdentity();
  2075. u16 indices[] = {0, 1, 2, 3};
  2076. S3DVertex vertices[4];
  2077. vertices[0] = S3DVertex(-1.f, -1.f, 0.9f, 0, 0, 1, leftDownEdge, 0, 0);
  2078. vertices[1] = S3DVertex(-1.f, 1.f, 0.9f, 0, 0, 1, leftUpEdge, 0, 0);
  2079. vertices[2] = S3DVertex(1.f, 1.f, 0.9f, 0, 0, 1, rightUpEdge, 0, 0);
  2080. vertices[3] = S3DVertex(1.f, -1.f, 0.9f, 0, 0, 1, rightDownEdge, 0, 0);
  2081. drawVertexPrimitiveList2d3d(vertices, 4, indices, 2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN, EIT_16BIT, false);
  2082. if (clearStencilBuffer)
  2083. glClear(GL_STENCIL_BUFFER_BIT);
  2084. // restore settings
  2085. //TODO : OpenGL ES 2.0 Port glPopMatrix
  2086. //glPopMatrix();
  2087. //Wrapper->glMatrixMode(GL_MODELVIEW);
  2088. //TODO : OpenGL ES 2.0 Port glPopMatrix
  2089. //glPopMatrix();
  2090. glDisable(GL_STENCIL_TEST);
  2091. glDepthMask(depthMask);
  2092. //TODO : OpenGL ES 2.0 Port glShadeModel
  2093. //glShadeModel(shadeModel);
  2094. }
  2095. //! Draws a 3d line.
  2096. void COGLES2Driver::draw3DLine(const core::vector3df& start,
  2097. const core::vector3df& end, SColor color)
  2098. {
  2099. setRenderStates3DMode();
  2100. u16 indices[] = {0, 1};
  2101. S3DVertex vertices[2];
  2102. vertices[0] = S3DVertex(start.X, start.Y, start.Z, 0, 0, 1, color, 0, 0);
  2103. vertices[1] = S3DVertex(end.X, end.Y, end.Z, 0, 0, 1, color, 0, 0);
  2104. drawVertexPrimitiveList2d3d(vertices, 2, indices, 1, video::EVT_STANDARD, scene::EPT_LINES);
  2105. }
  2106. //! Only used by the internal engine. Used to notify the driver that
  2107. //! the window was resized.
  2108. void COGLES2Driver::OnResize(const core::dimension2d<u32>& size)
  2109. {
  2110. CNullDriver::OnResize(size);
  2111. BridgeCalls->setViewport(core::rect<s32>(0, 0, size.Width, size.Height));
  2112. testGLError();
  2113. }
  2114. //! Returns type of video driver
  2115. E_DRIVER_TYPE COGLES2Driver::getDriverType() const
  2116. {
  2117. return EDT_OGLES2;
  2118. }
  2119. //! returns color format
  2120. ECOLOR_FORMAT COGLES2Driver::getColorFormat() const
  2121. {
  2122. return ColorFormat;
  2123. }
  2124. //! Get a vertex shader constant index.
  2125. s32 COGLES2Driver::getVertexShaderConstantID(const c8* name)
  2126. {
  2127. return getPixelShaderConstantID(name);
  2128. }
  2129. //! Get a pixel shader constant index.
  2130. s32 COGLES2Driver::getPixelShaderConstantID(const c8* name)
  2131. {
  2132. os::Printer::log("Error: Please call services->getPixelShaderConstantID(), not VideoDriver->getPixelShaderConstantID().");
  2133. return -1;
  2134. }
  2135. //! Sets a vertex shader constant.
  2136. void COGLES2Driver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
  2137. {
  2138. os::Printer::log("Error: Please call services->setVertexShaderConstant(), not VideoDriver->setPixelShaderConstant().");
  2139. }
  2140. //! Sets a pixel shader constant.
  2141. void COGLES2Driver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
  2142. {
  2143. os::Printer::log("Error: Please call services->setPixelShaderConstant(), not VideoDriver->setPixelShaderConstant().");
  2144. }
  2145. //! Sets a constant for the vertex shader based on an index.
  2146. bool COGLES2Driver::setVertexShaderConstant(s32 index, const f32* floats, int count)
  2147. {
  2148. //pass this along, as in GLSL the same routine is used for both vertex and fragment shaders
  2149. return setPixelShaderConstant(index, floats, count);
  2150. }
  2151. //! Int interface for the above.
  2152. bool COGLES2Driver::setVertexShaderConstant(s32 index, const s32* ints, int count)
  2153. {
  2154. return setPixelShaderConstant(index, ints, count);
  2155. }
  2156. //! Sets a constant for the pixel shader based on an index.
  2157. bool COGLES2Driver::setPixelShaderConstant(s32 index, const f32* floats, int count)
  2158. {
  2159. os::Printer::log("Error: Please call services->setPixelShaderConstant(), not VideoDriver->setPixelShaderConstant().");
  2160. return false;
  2161. }
  2162. //! Int interface for the above.
  2163. bool COGLES2Driver::setPixelShaderConstant(s32 index, const s32* ints, int count)
  2164. {
  2165. os::Printer::log("Error: Please call services->setPixelShaderConstant(), not VideoDriver->setPixelShaderConstant().");
  2166. return false;
  2167. }
  2168. //! Adds a new material renderer to the VideoDriver, using pixel and/or
  2169. //! vertex shaders to render geometry.
  2170. s32 COGLES2Driver::addShaderMaterial(const c8* vertexShaderProgram,
  2171. const c8* pixelShaderProgram,
  2172. IShaderConstantSetCallBack* callback,
  2173. E_MATERIAL_TYPE baseMaterial, s32 userData)
  2174. {
  2175. os::Printer::log("No shader support.");
  2176. return -1;
  2177. }
  2178. //! Adds a new material renderer to the VideoDriver, using GLSL to render geometry.
  2179. s32 COGLES2Driver::addHighLevelShaderMaterial(
  2180. const c8* vertexShaderProgram,
  2181. const c8* vertexShaderEntryPointName,
  2182. E_VERTEX_SHADER_TYPE vsCompileTarget,
  2183. const c8* pixelShaderProgram,
  2184. const c8* pixelShaderEntryPointName,
  2185. E_PIXEL_SHADER_TYPE psCompileTarget,
  2186. const c8* geometryShaderProgram,
  2187. const c8* geometryShaderEntryPointName,
  2188. E_GEOMETRY_SHADER_TYPE gsCompileTarget,
  2189. scene::E_PRIMITIVE_TYPE inType,
  2190. scene::E_PRIMITIVE_TYPE outType,
  2191. u32 verticesOut,
  2192. IShaderConstantSetCallBack* callback,
  2193. E_MATERIAL_TYPE baseMaterial,
  2194. s32 userData, E_GPU_SHADING_LANGUAGE shadingLang)
  2195. {
  2196. s32 nr = -1;
  2197. COGLES2MaterialRenderer* r = new COGLES2MaterialRenderer(
  2198. this, nr, vertexShaderProgram,
  2199. pixelShaderProgram,
  2200. callback, baseMaterial, userData);
  2201. r->drop();
  2202. return nr;
  2203. }
  2204. //! Returns a pointer to the IVideoDriver interface. (Implementation for
  2205. //! IMaterialRendererServices)
  2206. IVideoDriver* COGLES2Driver::getVideoDriver()
  2207. {
  2208. return this;
  2209. }
  2210. //! Returns pointer to the IGPUProgrammingServices interface.
  2211. IGPUProgrammingServices* COGLES2Driver::getGPUProgrammingServices()
  2212. {
  2213. return this;
  2214. }
  2215. ITexture* COGLES2Driver::addRenderTargetTexture(const core::dimension2d<u32>& size,
  2216. const io::path& name,
  2217. const ECOLOR_FORMAT format,
  2218. const bool useStencil)
  2219. {
  2220. //disable mip-mapping
  2221. const bool generateMipLevels = getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
  2222. setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false);
  2223. video::ITexture* rtt = 0;
  2224. rtt = new COGLES2FBOTexture(size, name, this, format);
  2225. if (rtt)
  2226. {
  2227. bool success = false;
  2228. addTexture(rtt);
  2229. ITexture* tex = createDepthTexture(rtt);
  2230. if (tex)
  2231. {
  2232. success = static_cast<video::COGLES2FBODepthTexture*>(tex)->attach(rtt);
  2233. if (!success)
  2234. {
  2235. removeDepthTexture(tex);
  2236. }
  2237. tex->drop();
  2238. }
  2239. rtt->drop();
  2240. if (!success)
  2241. {
  2242. removeTexture(rtt);
  2243. rtt=0;
  2244. }
  2245. }
  2246. //restore mip-mapping
  2247. setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, generateMipLevels);
  2248. return rtt;
  2249. }
  2250. //! Returns the maximum amount of primitives
  2251. u32 COGLES2Driver::getMaximalPrimitiveCount() const
  2252. {
  2253. return 65535;
  2254. }
  2255. //! set or reset render target
  2256. bool COGLES2Driver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
  2257. bool clearZBuffer, SColor color)
  2258. {
  2259. // check for right driver type
  2260. if (texture && texture->getDriverType() != EDT_OGLES2)
  2261. {
  2262. os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
  2263. return false;
  2264. }
  2265. // check if we should set the previous RT back
  2266. setActiveTexture(0, 0);
  2267. ResetRenderStates = true;
  2268. if (RenderTargetTexture != 0)
  2269. {
  2270. RenderTargetTexture->unbindRTT();
  2271. }
  2272. if (texture)
  2273. {
  2274. // we want to set a new target. so do this.
  2275. BridgeCalls->setViewport(core::rect<s32>(0, 0, texture->getSize().Width, texture->getSize().Height));
  2276. RenderTargetTexture = static_cast<COGLES2Texture*>(texture);
  2277. RenderTargetTexture->bindRTT();
  2278. CurrentRendertargetSize = texture->getSize();
  2279. }
  2280. else
  2281. {
  2282. BridgeCalls->setViewport(core::rect<s32>(0, 0, ScreenSize.Width, ScreenSize.Height));
  2283. RenderTargetTexture = 0;
  2284. CurrentRendertargetSize = core::dimension2d<u32>(0, 0);
  2285. }
  2286. GLbitfield mask = 0;
  2287. if (clearBackBuffer)
  2288. {
  2289. const f32 inv = 1.0f / 255.0f;
  2290. glClearColor(color.getRed() * inv, color.getGreen() * inv,
  2291. color.getBlue() * inv, color.getAlpha() * inv);
  2292. mask |= GL_COLOR_BUFFER_BIT;
  2293. }
  2294. if (clearZBuffer)
  2295. {
  2296. glDepthMask(GL_TRUE);
  2297. LastMaterial.ZWriteEnable = true;
  2298. mask |= GL_DEPTH_BUFFER_BIT;
  2299. }
  2300. glClear(mask);
  2301. testGLError();
  2302. return true;
  2303. }
  2304. // returns the current size of the screen or rendertarget
  2305. const core::dimension2d<u32>& COGLES2Driver::getCurrentRenderTargetSize() const
  2306. {
  2307. if (CurrentRendertargetSize.Width == 0)
  2308. return ScreenSize;
  2309. else
  2310. return CurrentRendertargetSize;
  2311. }
  2312. //! Clears the ZBuffer.
  2313. void COGLES2Driver::clearZBuffer()
  2314. {
  2315. GLboolean enabled = GL_TRUE;
  2316. glGetBooleanv(GL_DEPTH_WRITEMASK, &enabled);
  2317. glDepthMask(GL_TRUE);
  2318. glClear(GL_DEPTH_BUFFER_BIT);
  2319. glDepthMask(enabled);
  2320. testGLError();
  2321. }
  2322. //! Returns an image created from the last rendered frame.
  2323. // We want to read the front buffer to get the latest render finished.
  2324. // This is not possible under ogl-es, though, so one has to call this method
  2325. // outside of the render loop only.
  2326. IImage* COGLES2Driver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)
  2327. {
  2328. if (target==video::ERT_MULTI_RENDER_TEXTURES || target==video::ERT_RENDER_TEXTURE || target==video::ERT_STEREO_BOTH_BUFFERS)
  2329. return 0;
  2330. GLint internalformat = GL_RGBA;
  2331. GLint type = GL_UNSIGNED_BYTE;
  2332. {
  2333. // glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &internalformat);
  2334. // glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &type);
  2335. // there's a format we don't support ATM
  2336. if (GL_UNSIGNED_SHORT_4_4_4_4 == type)
  2337. {
  2338. internalformat = GL_RGBA;
  2339. type = GL_UNSIGNED_BYTE;
  2340. }
  2341. }
  2342. IImage* newImage = 0;
  2343. if (GL_RGBA == internalformat)
  2344. {
  2345. if (GL_UNSIGNED_BYTE == type)
  2346. newImage = new CImage(ECF_A8R8G8B8, ScreenSize);
  2347. else
  2348. newImage = new CImage(ECF_A1R5G5B5, ScreenSize);
  2349. }
  2350. else
  2351. {
  2352. if (GL_UNSIGNED_BYTE == type)
  2353. newImage = new CImage(ECF_R8G8B8, ScreenSize);
  2354. else
  2355. newImage = new CImage(ECF_R5G6B5, ScreenSize);
  2356. }
  2357. if (!newImage)
  2358. return 0;
  2359. u8* pixels = static_cast<u8*>(newImage->lock());
  2360. if (!pixels)
  2361. {
  2362. newImage->unlock();
  2363. newImage->drop();
  2364. return 0;
  2365. }
  2366. glReadPixels(0, 0, ScreenSize.Width, ScreenSize.Height, internalformat, type, pixels);
  2367. testGLError();
  2368. // opengl images are horizontally flipped, so we have to fix that here.
  2369. const s32 pitch = newImage->getPitch();
  2370. u8* p2 = pixels + (ScreenSize.Height - 1) * pitch;
  2371. u8* tmpBuffer = new u8[pitch];
  2372. for (u32 i = 0; i < ScreenSize.Height; i += 2)
  2373. {
  2374. memcpy(tmpBuffer, pixels, pitch);
  2375. memcpy(pixels, p2, pitch);
  2376. memcpy(p2, tmpBuffer, pitch);
  2377. pixels += pitch;
  2378. p2 -= pitch;
  2379. }
  2380. delete [] tmpBuffer;
  2381. newImage->unlock();
  2382. if (testGLError())
  2383. {
  2384. newImage->drop();
  2385. return 0;
  2386. }
  2387. testGLError();
  2388. return newImage;
  2389. }
  2390. //! get depth texture for the given render target texture
  2391. ITexture* COGLES2Driver::createDepthTexture(ITexture* texture, bool shared)
  2392. {
  2393. if ((texture->getDriverType() != EDT_OGLES2) || (!texture->isRenderTarget()))
  2394. return 0;
  2395. COGLES2Texture* tex = static_cast<COGLES2Texture*>(texture);
  2396. if (!tex->isFrameBufferObject())
  2397. return 0;
  2398. if (shared)
  2399. {
  2400. for (u32 i = 0; i < DepthTextures.size(); ++i)
  2401. {
  2402. if (DepthTextures[i]->getSize() == texture->getSize())
  2403. {
  2404. DepthTextures[i]->grab();
  2405. return DepthTextures[i];
  2406. }
  2407. }
  2408. DepthTextures.push_back(new COGLES2FBODepthTexture(texture->getSize(), "depth1", this));
  2409. return DepthTextures.getLast();
  2410. }
  2411. return (new COGLES2FBODepthTexture(texture->getSize(), "depth1", this));
  2412. }
  2413. void COGLES2Driver::removeDepthTexture(ITexture* texture)
  2414. {
  2415. for (u32 i = 0; i < DepthTextures.size(); ++i)
  2416. {
  2417. if (texture == DepthTextures[i])
  2418. {
  2419. DepthTextures.erase(i);
  2420. return;
  2421. }
  2422. }
  2423. }
  2424. void COGLES2Driver::deleteFramebuffers(s32 n, const u32 *framebuffers)
  2425. {
  2426. glDeleteFramebuffers(n, framebuffers);
  2427. }
  2428. void COGLES2Driver::deleteRenderbuffers(s32 n, const u32 *renderbuffers)
  2429. {
  2430. glDeleteRenderbuffers(n, renderbuffers);
  2431. }
  2432. //! Set/unset a clipping plane.
  2433. bool COGLES2Driver::setClipPlane(u32 index, const core::plane3df& plane, bool enable)
  2434. {
  2435. if (index >= UserClipPlane.size())
  2436. UserClipPlane.push_back(SUserClipPlane());
  2437. UserClipPlane[index].Plane = plane;
  2438. UserClipPlane[index].Enabled = enable;
  2439. return true;
  2440. }
  2441. //! Enable/disable a clipping plane.
  2442. void COGLES2Driver::enableClipPlane(u32 index, bool enable)
  2443. {
  2444. UserClipPlane[index].Enabled = enable;
  2445. }
  2446. //! Get the ClipPlane Count
  2447. u32 COGLES2Driver::getClipPlaneCount() const
  2448. {
  2449. return UserClipPlane.size();
  2450. }
  2451. const core::plane3df& COGLES2Driver::getClipPlane(irr::u32 index) const
  2452. {
  2453. if (index < UserClipPlane.size())
  2454. return UserClipPlane[index].Plane;
  2455. else
  2456. return *((core::plane3df*)0);
  2457. }
  2458. core::dimension2du COGLES2Driver::getMaxTextureSize() const
  2459. {
  2460. return core::dimension2du(MaxTextureSize, MaxTextureSize);
  2461. }
  2462. GLenum COGLES2Driver::getGLBlend(E_BLEND_FACTOR factor) const
  2463. {
  2464. GLenum r = 0;
  2465. switch (factor)
  2466. {
  2467. case EBF_ZERO: r = GL_ZERO; break;
  2468. case EBF_ONE: r = GL_ONE; break;
  2469. case EBF_DST_COLOR: r = GL_DST_COLOR; break;
  2470. case EBF_ONE_MINUS_DST_COLOR: r = GL_ONE_MINUS_DST_COLOR; break;
  2471. case EBF_SRC_COLOR: r = GL_SRC_COLOR; break;
  2472. case EBF_ONE_MINUS_SRC_COLOR: r = GL_ONE_MINUS_SRC_COLOR; break;
  2473. case EBF_SRC_ALPHA: r = GL_SRC_ALPHA; break;
  2474. case EBF_ONE_MINUS_SRC_ALPHA: r = GL_ONE_MINUS_SRC_ALPHA; break;
  2475. case EBF_DST_ALPHA: r = GL_DST_ALPHA; break;
  2476. case EBF_ONE_MINUS_DST_ALPHA: r = GL_ONE_MINUS_DST_ALPHA; break;
  2477. case EBF_SRC_ALPHA_SATURATE: r = GL_SRC_ALPHA_SATURATE; break;
  2478. }
  2479. return r;
  2480. }
  2481. GLenum COGLES2Driver::getZBufferBits() const
  2482. {
  2483. /*#if defined(GL_OES_depth24)
  2484. if (Driver->queryOpenGLFeature(COGLES2ExtensionHandler::IRR_OES_depth24))
  2485. InternalFormat = GL_DEPTH_COMPONENT24_OES;
  2486. else
  2487. #endif
  2488. #if defined(GL_OES_depth32)
  2489. if (Driver->queryOpenGLFeature(COGLES2ExtensionHandler::IRR_OES_depth32))
  2490. InternalFormat = GL_DEPTH_COMPONENT32_OES;
  2491. else
  2492. #endif*/
  2493. GLenum bits = GL_DEPTH_COMPONENT16;//0;
  2494. /*switch (Params.ZBufferBits)
  2495. {
  2496. case 16:
  2497. bits = GL_DEPTH_COMPONENT16;
  2498. break;
  2499. case 24:
  2500. bits = GL_DEPTH_COMPONENT24;
  2501. break;
  2502. case 32:
  2503. bits = GL_DEPTH_COMPONENT32;
  2504. break;
  2505. default:
  2506. bits = GL_DEPTH_COMPONENT;
  2507. break;
  2508. }*/
  2509. return bits;
  2510. }
  2511. const SMaterial& COGLES2Driver::getCurrentMaterial() const
  2512. {
  2513. return Material;
  2514. }
  2515. COGLES2CallBridge* COGLES2Driver::getBridgeCalls() const
  2516. {
  2517. return BridgeCalls;
  2518. }
  2519. COGLES2CallBridge::COGLES2CallBridge(COGLES2Driver* driver) : Driver(driver),
  2520. BlendSource(GL_ONE), BlendDestination(GL_ZERO), Blend(false),
  2521. CullFaceMode(GL_BACK), CullFace(false),
  2522. DepthFunc(GL_LESS), DepthMask(true), DepthTest(false),
  2523. Program(0), ActiveTexture(GL_TEXTURE0), Viewport(core::rect<s32>(0, 0, 0, 0))
  2524. {
  2525. // Initial OpenGL values from specification.
  2526. for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
  2527. Texture[i] = 0;
  2528. glBlendFunc(GL_ONE, GL_ZERO);
  2529. glDisable(GL_BLEND);
  2530. glCullFace(GL_BACK);
  2531. glDisable(GL_CULL_FACE);
  2532. glDepthFunc(GL_LESS);
  2533. glDepthMask(GL_TRUE);
  2534. glDisable(GL_DEPTH_TEST);
  2535. }
  2536. void COGLES2CallBridge::setBlendFunc(GLenum source, GLenum destination)
  2537. {
  2538. if(BlendSource != source || BlendDestination != destination)
  2539. {
  2540. glBlendFunc(source, destination);
  2541. BlendSource = source;
  2542. BlendDestination = destination;
  2543. }
  2544. }
  2545. void COGLES2CallBridge::setBlend(bool enable)
  2546. {
  2547. if(Blend != enable)
  2548. {
  2549. if (enable)
  2550. glEnable(GL_BLEND);
  2551. else
  2552. glDisable(GL_BLEND);
  2553. Blend = enable;
  2554. }
  2555. }
  2556. void COGLES2CallBridge::setCullFaceFunc(GLenum mode)
  2557. {
  2558. if(CullFaceMode != mode)
  2559. {
  2560. glCullFace(mode);
  2561. CullFaceMode = mode;
  2562. }
  2563. }
  2564. void COGLES2CallBridge::setCullFace(bool enable)
  2565. {
  2566. if(CullFace != enable)
  2567. {
  2568. if (enable)
  2569. glEnable(GL_CULL_FACE);
  2570. else
  2571. glDisable(GL_CULL_FACE);
  2572. CullFace = enable;
  2573. }
  2574. }
  2575. void COGLES2CallBridge::setDepthFunc(GLenum mode)
  2576. {
  2577. if(DepthFunc != mode)
  2578. {
  2579. glDepthFunc(mode);
  2580. DepthFunc = mode;
  2581. }
  2582. }
  2583. void COGLES2CallBridge::setDepthMask(bool enable)
  2584. {
  2585. if(DepthMask != enable)
  2586. {
  2587. if (enable)
  2588. glDepthMask(GL_TRUE);
  2589. else
  2590. glDepthMask(GL_FALSE);
  2591. DepthMask = enable;
  2592. }
  2593. }
  2594. void COGLES2CallBridge::setDepthTest(bool enable)
  2595. {
  2596. if(DepthTest != enable)
  2597. {
  2598. if (enable)
  2599. glEnable(GL_DEPTH_TEST);
  2600. else
  2601. glDisable(GL_DEPTH_TEST);
  2602. DepthTest = enable;
  2603. }
  2604. }
  2605. void COGLES2CallBridge::setProgram(GLuint program)
  2606. {
  2607. if (Program != program)
  2608. {
  2609. glUseProgram(program);
  2610. Program = program;
  2611. }
  2612. }
  2613. void COGLES2CallBridge::setActiveTexture(GLenum texture)
  2614. {
  2615. if (ActiveTexture != texture)
  2616. {
  2617. glActiveTexture(texture);
  2618. ActiveTexture = texture;
  2619. }
  2620. }
  2621. void COGLES2CallBridge::setTexture(u32 stage)
  2622. {
  2623. if (stage < MATERIAL_MAX_TEXTURES)
  2624. {
  2625. if(Texture[stage] != Driver->CurrentTexture[stage])
  2626. {
  2627. setActiveTexture(GL_TEXTURE0 + stage);
  2628. if(Driver->CurrentTexture[stage])
  2629. glBindTexture(GL_TEXTURE_2D, Driver->CurrentTexture[stage]->getOpenGLTextureName());
  2630. Texture[stage] = Driver->CurrentTexture[stage];
  2631. }
  2632. }
  2633. }
  2634. void COGLES2CallBridge::setViewport(const core::rect<s32>& viewport)
  2635. {
  2636. if (Viewport != viewport)
  2637. {
  2638. glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
  2639. Viewport = viewport;
  2640. }
  2641. }
  2642. } // end namespace
  2643. } // end namespace
  2644. #endif // _IRR_COMPILE_WITH_OGLES2_
  2645. namespace irr
  2646. {
  2647. namespace video
  2648. {
  2649. #if !defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_) && (defined(_IRR_COMPILE_WITH_X11_DEVICE_) || defined(_IRR_COMPILE_WITH_SDL_DEVICE_) || defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) || defined(_IRR_COMPILE_WITH_CONSOLE_DEVICE_))
  2650. IVideoDriver* createOGLES2Driver(const SIrrlichtCreationParameters& params,
  2651. video::SExposedVideoData& data, io::IFileSystem* io)
  2652. {
  2653. #ifdef _IRR_COMPILE_WITH_OGLES2_
  2654. return new COGLES2Driver(params, data, io);
  2655. #else
  2656. return 0;
  2657. #endif // _IRR_COMPILE_WITH_OGLES2_
  2658. }
  2659. #endif
  2660. // -----------------------------------
  2661. // MACOSX VERSION
  2662. // -----------------------------------
  2663. #if defined(_IRR_COMPILE_WITH_OSX_DEVICE_)
  2664. IVideoDriver* createOGLES2Driver(const SIrrlichtCreationParameters& params,
  2665. io::IFileSystem* io, CIrrDeviceMacOSX *device)
  2666. {
  2667. #ifdef _IRR_COMPILE_WITH_OGLES2_
  2668. return new COGLES2Driver(params, io, device);
  2669. #else
  2670. return 0;
  2671. #endif // _IRR_COMPILE_WITH_OGLES2_
  2672. }
  2673. #endif // _IRR_COMPILE_WITH_OSX_DEVICE_
  2674. // -----------------------------------
  2675. // IPHONE VERSION
  2676. // -----------------------------------
  2677. #if defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
  2678. IVideoDriver* createOGLES2Driver(const SIrrlichtCreationParameters& params,
  2679. video::SExposedVideoData& data, io::IFileSystem* io,
  2680. CIrrDeviceIPhone* device)
  2681. {
  2682. #ifdef _IRR_COMPILE_WITH_OGLES2_
  2683. return new COGLES2Driver(params, data, io, device);
  2684. #else
  2685. return 0;
  2686. #endif // _IRR_COMPILE_WITH_OGLES2_
  2687. }
  2688. #endif // _IRR_COMPILE_WITH_IPHONE_DEVICE_
  2689. } // end namespace
  2690. } // end namespace