OgreGLRenderSystem.cpp 100 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469
  1. /*
  2. -----------------------------------------------------------------------------
  3. This source file is part of OGRE
  4. (Object-oriented Graphics Rendering Engine)
  5. For the latest info, see http://www.ogre3d.org
  6. Copyright (c) 2000-2011 Torus Knot Software Ltd
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.s
  22. -----------------------------------------------------------------------------
  23. */
  24. #include "OgreGLRenderSystem.h"
  25. #include "OgreRenderSystem.h"
  26. #include "OgreStringConverter.h"
  27. #include "OgreCamera.h"
  28. #include "OgreGLTextureManager.h"
  29. #include "OgreGLHardwareVertexBuffer.h"
  30. #include "OgreGLHardwareIndexBuffer.h"
  31. #include "OgreGLDefaultHardwareBufferManager.h"
  32. #include "OgreGLUtil.h"
  33. #include "OgreGLGpuProgram.h"
  34. #include "OgreGLGpuNvparseProgram.h"
  35. #include "ATI_FS_GLGpuProgram.h"
  36. #include "OgreGLGpuProgramManager.h"
  37. #include "OgreException.h"
  38. #include "OgreGLSLExtSupport.h"
  39. #include "OgreGLHardwareOcclusionQuery.h"
  40. #include "OgreGLContext.h"
  41. #include "OgreGLFBORenderTexture.h"
  42. #include "OgreGLPBRenderTexture.h"
  43. #include "OgreConfig.h"
  44. // Convenience macro from ARB_vertex_buffer_object spec
  45. #define VBO_BUFFER_OFFSET(i) ((char *)NULL + (i))
  46. #if OGRE_THREAD_SUPPORT != 1
  47. GLenum glewContextInit (Ogre::GLSupport *glSupport);
  48. #endif
  49. namespace Ogre {
  50. // Callback function used when registering GLGpuPrograms
  51. GpuProgram* createGLArbGpuProgram(GpuProgramType gptype, const String& syntaxCode)
  52. {
  53. GLArbGpuProgram* ret = new GLArbGpuProgram();
  54. ret->setType(gptype);
  55. ret->setSyntaxCode(syntaxCode);
  56. return ret;
  57. }
  58. GpuProgram* createGLGpuNvparseProgram(GpuProgramType gptype, const String& syntaxCode)
  59. {
  60. GLGpuNvparseProgram* ret = new GLGpuNvparseProgram();
  61. ret->setType(gptype);
  62. ret->setSyntaxCode(syntaxCode);
  63. return ret;
  64. }
  65. GpuProgram* createGL_ATI_FS_GpuProgram(GpuProgramType gptype, const String& syntaxCode)
  66. {
  67. ATI_FS_GLGpuProgram* ret = new ATI_FS_GLGpuProgram();
  68. ret->setType(gptype);
  69. ret->setSyntaxCode(syntaxCode);
  70. return ret;
  71. }
  72. GLRenderSystem::GLRenderSystem()
  73. : mDepthWrite(true), mStencilMask(0xFFFFFFFF), mHardwareBufferManager(0),
  74. mGpuProgramManager(0),
  75. mGLSLProgramFactory(0),
  76. mRTTManager(0),
  77. mActiveTextureUnit(0)
  78. {
  79. size_t i;
  80. // Get our GLSupport
  81. mGLSupport = getGLSupport();
  82. for( i=0; i<MAX_LIGHTS; i++ )
  83. mLights[i] = NULL;
  84. mWorldMatrix = Matrix4::IDENTITY;
  85. mViewMatrix = Matrix4::IDENTITY;
  86. initConfigOptions();
  87. mColourWrite[0] = mColourWrite[1] = mColourWrite[2] = mColourWrite[3] = true;
  88. for (i = 0; i < OGRE_MAX_TEXTURE_LAYERS; i++)
  89. {
  90. // Dummy value
  91. mTextureCoordIndex[i] = 99;
  92. mTextureTypes[i] = 0;
  93. }
  94. mActiveRenderTarget = 0;
  95. mCurrentContext = 0;
  96. mMainContext = 0;
  97. mGLInitialised = false;
  98. mCurrentLights = 0;
  99. mMinFilter = FO_LINEAR;
  100. mMipFilter = FO_POINT;
  101. mCurrentVertexProgram = 0;
  102. mCurrentGeometryProgram = 0;
  103. mCurrentFragmentProgram = 0;
  104. }
  105. GLRenderSystem::~GLRenderSystem()
  106. {
  107. shutdown();
  108. // Destroy render windows
  109. RenderTargetMap::iterator i;
  110. for (i = mRenderTargets.begin(); i != mRenderTargets.end(); ++i)
  111. {
  112. delete i->second;
  113. }
  114. mRenderTargets.clear();
  115. if(mGLSupport)
  116. delete mGLSupport;
  117. }
  118. const String& GLRenderSystem::getName(void) const
  119. {
  120. static String strName("OpenGL Rendering Subsystem");
  121. return strName;
  122. }
  123. void GLRenderSystem::initConfigOptions(void)
  124. {
  125. mGLSupport->addConfig();
  126. }
  127. ConfigOptionMap& GLRenderSystem::getConfigOptions(void)
  128. {
  129. return mGLSupport->getConfigOptions();
  130. }
  131. void GLRenderSystem::setConfigOption(const String &name, const String &value)
  132. {
  133. mGLSupport->setConfigOption(name, value);
  134. }
  135. String GLRenderSystem::validateConfigOptions(void)
  136. {
  137. // XXX Return an error string if something is invalid
  138. return mGLSupport->validateConfig();
  139. }
  140. RenderWindow* GLRenderSystem::_initialise(bool autoCreateWindow, const String& windowTitle)
  141. {
  142. mGLSupport->start();
  143. RenderWindow* autoWindow = mGLSupport->createWindow(autoCreateWindow, this, windowTitle);
  144. RenderSystem::_initialise(autoCreateWindow, windowTitle);
  145. return autoWindow;
  146. }
  147. RenderSystemCapabilities* GLRenderSystem::createRenderSystemCapabilities() const
  148. {
  149. RenderSystemCapabilities* rsc = new RenderSystemCapabilities();
  150. rsc->setCategoryRelevant(CAPS_CATEGORY_GL, true);
  151. rsc->setDriverVersion(mDriverVersion);
  152. const char* deviceName = (const char*)glGetString(GL_RENDERER);
  153. const char* vendorName = (const char*)glGetString(GL_VENDOR);
  154. rsc->setDeviceName(deviceName);
  155. rsc->setRenderSystemName(getName());
  156. // determine vendor
  157. if (strstr(vendorName, "NVIDIA"))
  158. rsc->setVendor(GPU_NVIDIA);
  159. else if (strstr(vendorName, "ATI"))
  160. rsc->setVendor(GPU_ATI);
  161. else if (strstr(vendorName, "Intel"))
  162. rsc->setVendor(GPU_INTEL);
  163. else if (strstr(vendorName, "S3"))
  164. rsc->setVendor(GPU_S3);
  165. else if (strstr(vendorName, "Matrox"))
  166. rsc->setVendor(GPU_MATROX);
  167. else if (strstr(vendorName, "3DLabs"))
  168. rsc->setVendor(GPU_3DLABS);
  169. else if (strstr(vendorName, "SiS"))
  170. rsc->setVendor(GPU_SIS);
  171. else
  172. rsc->setVendor(GPU_UNKNOWN);
  173. // Supports fixed-function
  174. rsc->setCapability(RSC_FIXED_FUNCTION);
  175. // Check for hardware mipmapping support.
  176. if(GLEW_VERSION_1_4 || GLEW_SGIS_generate_mipmap)
  177. {
  178. bool disableAutoMip = false;
  179. #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_LINUX
  180. // Apple & Linux ATI drivers have faults in hardware mipmap generation
  181. if (rsc->getVendor() == GPU_ATI)
  182. disableAutoMip = true;
  183. #endif
  184. // The Intel 915G frequently corrupts textures when using hardware mip generation
  185. // I'm not currently sure how many generations of hardware this affects,
  186. // so for now, be safe.
  187. if (rsc->getVendor() == GPU_INTEL)
  188. disableAutoMip = true;
  189. // SiS chipsets also seem to have problems with this
  190. if (rsc->getVendor() == GPU_SIS)
  191. disableAutoMip = true;
  192. if (!disableAutoMip)
  193. rsc->setCapability(RSC_AUTOMIPMAP);
  194. }
  195. // Check for blending support
  196. if(GLEW_VERSION_1_3 ||
  197. GLEW_ARB_texture_env_combine ||
  198. GLEW_EXT_texture_env_combine)
  199. {
  200. rsc->setCapability(RSC_BLENDING);
  201. }
  202. // Check for Multitexturing support and set number of texture units
  203. if(GLEW_VERSION_1_3 ||
  204. GLEW_ARB_multitexture)
  205. {
  206. GLint units;
  207. glGetIntegerv( GL_MAX_TEXTURE_UNITS, &units );
  208. if (GLEW_ARB_fragment_program)
  209. {
  210. // Also check GL_MAX_TEXTURE_IMAGE_UNITS_ARB since NV at least
  211. // only increased this on the FX/6x00 series
  212. GLint arbUnits;
  213. glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &arbUnits );
  214. if (arbUnits > units)
  215. units = arbUnits;
  216. }
  217. rsc->setNumTextureUnits(units);
  218. }
  219. else
  220. {
  221. // If no multitexture support then set one texture unit
  222. rsc->setNumTextureUnits(1);
  223. }
  224. // Check for Anisotropy support
  225. if(GLEW_EXT_texture_filter_anisotropic)
  226. {
  227. rsc->setCapability(RSC_ANISOTROPY);
  228. }
  229. // Check for DOT3 support
  230. if(GLEW_VERSION_1_3 ||
  231. GLEW_ARB_texture_env_dot3 ||
  232. GLEW_EXT_texture_env_dot3)
  233. {
  234. rsc->setCapability(RSC_DOT3);
  235. }
  236. // Check for cube mapping
  237. if(GLEW_VERSION_1_3 ||
  238. GLEW_ARB_texture_cube_map ||
  239. GLEW_EXT_texture_cube_map)
  240. {
  241. rsc->setCapability(RSC_CUBEMAPPING);
  242. }
  243. // Point sprites
  244. if (GLEW_VERSION_2_0 || GLEW_ARB_point_sprite)
  245. {
  246. rsc->setCapability(RSC_POINT_SPRITES);
  247. }
  248. // Check for point parameters
  249. if (GLEW_VERSION_1_4)
  250. {
  251. rsc->setCapability(RSC_POINT_EXTENDED_PARAMETERS);
  252. }
  253. if (GLEW_ARB_point_parameters)
  254. {
  255. rsc->setCapability(RSC_POINT_EXTENDED_PARAMETERS_ARB);
  256. }
  257. if (GLEW_EXT_point_parameters)
  258. {
  259. rsc->setCapability(RSC_POINT_EXTENDED_PARAMETERS_EXT);
  260. }
  261. // Check for hardware stencil support and set bit depth
  262. GLint stencil;
  263. glGetIntegerv(GL_STENCIL_BITS,&stencil);
  264. if(stencil)
  265. {
  266. rsc->setCapability(RSC_HWSTENCIL);
  267. rsc->setStencilBufferBitDepth(stencil);
  268. }
  269. if(GLEW_VERSION_1_5 || GLEW_ARB_vertex_buffer_object)
  270. {
  271. if (!GLEW_ARB_vertex_buffer_object)
  272. {
  273. rsc->setCapability(RSC_GL1_5_NOVBO);
  274. }
  275. rsc->setCapability(RSC_VBO);
  276. }
  277. if(GLEW_ARB_vertex_program)
  278. {
  279. rsc->setCapability(RSC_VERTEX_PROGRAM);
  280. // Vertex Program Properties
  281. rsc->setVertexProgramConstantBoolCount(0);
  282. rsc->setVertexProgramConstantIntCount(0);
  283. GLint floatConstantCount;
  284. glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &floatConstantCount);
  285. rsc->setVertexProgramConstantFloatCount(floatConstantCount);
  286. rsc->addShaderProfile("arbvp1");
  287. if (GLEW_NV_vertex_program2_option)
  288. {
  289. rsc->addShaderProfile("vp30");
  290. }
  291. if (GLEW_NV_vertex_program3)
  292. {
  293. rsc->addShaderProfile("vp40");
  294. }
  295. if (GLEW_NV_vertex_program4)
  296. {
  297. rsc->addShaderProfile("gp4vp");
  298. rsc->addShaderProfile("gpu_vp");
  299. }
  300. }
  301. if (GLEW_NV_register_combiners2 &&
  302. GLEW_NV_texture_shader)
  303. {
  304. rsc->setCapability(RSC_FRAGMENT_PROGRAM);
  305. rsc->addShaderProfile("fp20");
  306. }
  307. // NFZ - check for ATI fragment shader support
  308. if (GLEW_ATI_fragment_shader)
  309. {
  310. rsc->setCapability(RSC_FRAGMENT_PROGRAM);
  311. // no boolean params allowed
  312. rsc->setFragmentProgramConstantBoolCount(0);
  313. // no integer params allowed
  314. rsc->setFragmentProgramConstantIntCount(0);
  315. // only 8 Vector4 constant floats supported
  316. rsc->setFragmentProgramConstantFloatCount(8);
  317. rsc->addShaderProfile("ps_1_4");
  318. rsc->addShaderProfile("ps_1_3");
  319. rsc->addShaderProfile("ps_1_2");
  320. rsc->addShaderProfile("ps_1_1");
  321. }
  322. if (GLEW_ARB_fragment_program)
  323. {
  324. rsc->setCapability(RSC_FRAGMENT_PROGRAM);
  325. // Fragment Program Properties
  326. rsc->setFragmentProgramConstantBoolCount(0);
  327. rsc->setFragmentProgramConstantIntCount(0);
  328. GLint floatConstantCount;
  329. glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &floatConstantCount);
  330. rsc->setFragmentProgramConstantFloatCount(floatConstantCount);
  331. rsc->addShaderProfile("arbfp1");
  332. if (GLEW_NV_fragment_program_option)
  333. {
  334. rsc->addShaderProfile("fp30");
  335. }
  336. if (GLEW_NV_fragment_program2)
  337. {
  338. rsc->addShaderProfile("fp40");
  339. }
  340. }
  341. // NFZ - Check if GLSL is supported
  342. if ( GLEW_VERSION_2_0 ||
  343. (GLEW_ARB_shading_language_100 &&
  344. GLEW_ARB_shader_objects &&
  345. GLEW_ARB_fragment_shader &&
  346. GLEW_ARB_vertex_shader) )
  347. {
  348. rsc->addShaderProfile("glsl");
  349. }
  350. // Check if geometry shaders are supported
  351. if (GLEW_VERSION_2_0 &&
  352. GLEW_EXT_geometry_shader4)
  353. {
  354. rsc->setCapability(RSC_GEOMETRY_PROGRAM);
  355. rsc->addShaderProfile("nvgp4");
  356. //Also add the CG profiles
  357. rsc->addShaderProfile("gpu_gp");
  358. rsc->addShaderProfile("gp4gp");
  359. rsc->setGeometryProgramConstantBoolCount(0);
  360. rsc->setGeometryProgramConstantIntCount(0);
  361. GLint floatConstantCount = 0;
  362. glGetIntegerv(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT, &floatConstantCount);
  363. rsc->setGeometryProgramConstantFloatCount(floatConstantCount);
  364. GLint maxOutputVertices;
  365. glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT,&maxOutputVertices);
  366. rsc->setGeometryProgramNumOutputVertices(maxOutputVertices);
  367. }
  368. //Check if render to vertex buffer (transform feedback in OpenGL)
  369. if (GLEW_VERSION_2_0 &&
  370. GLEW_NV_transform_feedback)
  371. {
  372. rsc->setCapability(RSC_HWRENDER_TO_VERTEX_BUFFER);
  373. }
  374. // Check for texture compression
  375. if(GLEW_VERSION_1_3 || GLEW_ARB_texture_compression)
  376. {
  377. rsc->setCapability(RSC_TEXTURE_COMPRESSION);
  378. // Check for dxt compression
  379. if(GLEW_EXT_texture_compression_s3tc)
  380. {
  381. #if defined(__APPLE__) && defined(__PPC__)
  382. // Apple on ATI & PPC has errors in DXT
  383. if (mGLSupport->getGLVendor().find("ATI") == std::string::npos)
  384. #endif
  385. rsc->setCapability(RSC_TEXTURE_COMPRESSION_DXT);
  386. }
  387. // Check for vtc compression
  388. if(GLEW_NV_texture_compression_vtc)
  389. {
  390. rsc->setCapability(RSC_TEXTURE_COMPRESSION_VTC);
  391. }
  392. }
  393. // Scissor test is standard in GL 1.2 (is it emulated on some cards though?)
  394. rsc->setCapability(RSC_SCISSOR_TEST);
  395. // As are user clipping planes
  396. rsc->setCapability(RSC_USER_CLIP_PLANES);
  397. // 2-sided stencil?
  398. if (GLEW_VERSION_2_0 || GLEW_EXT_stencil_two_side)
  399. {
  400. rsc->setCapability(RSC_TWO_SIDED_STENCIL);
  401. }
  402. // stencil wrapping?
  403. if (GLEW_VERSION_1_4 || GLEW_EXT_stencil_wrap)
  404. {
  405. rsc->setCapability(RSC_STENCIL_WRAP);
  406. }
  407. // Check for hardware occlusion support
  408. if(GLEW_VERSION_1_5 || GLEW_ARB_occlusion_query)
  409. {
  410. // Some buggy driver claim that it is GL 1.5 compliant and
  411. // not support ARB_occlusion_query
  412. if (!GLEW_ARB_occlusion_query)
  413. {
  414. rsc->setCapability(RSC_GL1_5_NOHWOCCLUSION);
  415. }
  416. rsc->setCapability(RSC_HWOCCLUSION);
  417. }
  418. else if (GLEW_NV_occlusion_query)
  419. {
  420. // Support NV extension too for old hardware
  421. rsc->setCapability(RSC_HWOCCLUSION);
  422. }
  423. // UBYTE4 always supported
  424. rsc->setCapability(RSC_VERTEX_FORMAT_UBYTE4);
  425. // Infinite far plane always supported
  426. rsc->setCapability(RSC_INFINITE_FAR_PLANE);
  427. // Check for non-power-of-2 texture support
  428. if(GLEW_ARB_texture_non_power_of_two)
  429. {
  430. rsc->setCapability(RSC_NON_POWER_OF_2_TEXTURES);
  431. }
  432. // Check for Float textures
  433. if(GLEW_ATI_texture_float || GLEW_ARB_texture_float)
  434. {
  435. rsc->setCapability(RSC_TEXTURE_FLOAT);
  436. }
  437. // 3D textures should be supported by GL 1.2, which is our minimum version
  438. rsc->setCapability(RSC_TEXTURE_3D);
  439. // Check for framebuffer object extension
  440. if(GLEW_EXT_framebuffer_object)
  441. {
  442. // Probe number of draw buffers
  443. // Only makes sense with FBO support, so probe here
  444. if(GLEW_VERSION_2_0 ||
  445. GLEW_ARB_draw_buffers ||
  446. GLEW_ATI_draw_buffers)
  447. {
  448. GLint buffers;
  449. glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &buffers);
  450. rsc->setNumMultiRenderTargets(std::min<int>(buffers, (GLint)OGRE_MAX_MULTIPLE_RENDER_TARGETS));
  451. rsc->setCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS);
  452. if(!GLEW_VERSION_2_0)
  453. {
  454. // Before GL version 2.0, we need to get one of the extensions
  455. if(GLEW_ARB_draw_buffers)
  456. rsc->setCapability(RSC_FBO_ARB);
  457. if(GLEW_ATI_draw_buffers)
  458. rsc->setCapability(RSC_FBO_ATI);
  459. }
  460. // Set FBO flag for all 3 'subtypes'
  461. rsc->setCapability(RSC_FBO);
  462. }
  463. rsc->setCapability(RSC_HWRENDER_TO_TEXTURE);
  464. }
  465. // Check GLSupport for PBuffer support
  466. if(mGLSupport->supportsPBuffers())
  467. {
  468. // Use PBuffers
  469. rsc->setCapability(RSC_HWRENDER_TO_TEXTURE);
  470. rsc->setCapability(RSC_PBUFFER);
  471. }
  472. // Point size
  473. if (GLEW_VERSION_1_4)
  474. {
  475. float ps;
  476. glGetFloatv(GL_POINT_SIZE_MAX, &ps);
  477. rsc->setMaxPointSize(ps);
  478. }
  479. else
  480. {
  481. GLint vSize[2];
  482. glGetIntegerv(GL_POINT_SIZE_RANGE,vSize);
  483. rsc->setMaxPointSize(vSize[1]);
  484. }
  485. // Vertex texture fetching
  486. if (mGLSupport->checkExtension("GL_ARB_vertex_shader"))
  487. {
  488. GLint vUnits;
  489. glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &vUnits);
  490. rsc->setNumVertexTextureUnits(static_cast<ushort>(vUnits));
  491. if (vUnits > 0)
  492. {
  493. rsc->setCapability(RSC_VERTEX_TEXTURE_FETCH);
  494. }
  495. // GL always shares vertex and fragment texture units (for now?)
  496. rsc->setVertexTextureUnitsShared(true);
  497. }
  498. // Mipmap LOD biasing?
  499. if (GLEW_VERSION_1_4 || GLEW_EXT_texture_lod_bias)
  500. {
  501. rsc->setCapability(RSC_MIPMAP_LOD_BIAS);
  502. }
  503. // Alpha to coverage?
  504. if (mGLSupport->checkExtension("GL_ARB_multisample"))
  505. {
  506. // Alpha to coverage always 'supported' when MSAA is available
  507. // although card may ignore it if it doesn't specifically support A2C
  508. rsc->setCapability(RSC_ALPHA_TO_COVERAGE);
  509. }
  510. // Advanced blending operations
  511. if(GLEW_VERSION_2_0)
  512. {
  513. rsc->setCapability(RSC_ADVANCED_BLEND_OPERATIONS);
  514. }
  515. return rsc;
  516. }
  517. void GLRenderSystem::initialiseFromRenderSystemCapabilities(RenderSystemCapabilities* caps, RenderTarget* primary)
  518. {
  519. if(caps->getRenderSystemName() != getName())
  520. {
  521. OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
  522. "Trying to initialize GLRenderSystem from RenderSystemCapabilities that do not support OpenGL",
  523. "GLRenderSystem::initialiseFromRenderSystemCapabilities");
  524. }
  525. // set texture the number of texture units
  526. mFixedFunctionTextureUnits = caps->getNumTextureUnits();
  527. //In GL there can be less fixed function texture units than general
  528. //texture units. Get the minimum of the two.
  529. if (caps->hasCapability(RSC_FRAGMENT_PROGRAM))
  530. {
  531. GLint maxTexCoords = 0;
  532. glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &maxTexCoords);
  533. if (mFixedFunctionTextureUnits > maxTexCoords)
  534. {
  535. mFixedFunctionTextureUnits = maxTexCoords;
  536. }
  537. }
  538. if(caps->hasCapability(RSC_GL1_5_NOVBO))
  539. {
  540. // Assign ARB functions same to GL 1.5 version since
  541. // interface identical
  542. glBindBufferARB = glBindBuffer;
  543. glBufferDataARB = glBufferData;
  544. glBufferSubDataARB = glBufferSubData;
  545. glDeleteBuffersARB = glDeleteBuffers;
  546. glGenBuffersARB = glGenBuffers;
  547. glGetBufferParameterivARB = glGetBufferParameteriv;
  548. glGetBufferPointervARB = glGetBufferPointerv;
  549. glGetBufferSubDataARB = glGetBufferSubData;
  550. glIsBufferARB = glIsBuffer;
  551. glMapBufferARB = glMapBuffer;
  552. glUnmapBufferARB = glUnmapBuffer;
  553. }
  554. if(caps->hasCapability(RSC_VBO))
  555. {
  556. mHardwareBufferManager = new GLHardwareBufferManager;
  557. }
  558. else
  559. {
  560. mHardwareBufferManager = new GLDefaultHardwareBufferManager;
  561. }
  562. // XXX Need to check for nv2 support and make a program manager for it
  563. // XXX Probably nv1 as well for older cards
  564. // GPU Program Manager setup
  565. mGpuProgramManager = new GLGpuProgramManager();
  566. if(caps->hasCapability(RSC_VERTEX_PROGRAM))
  567. {
  568. if(caps->isShaderProfileSupported("arbvp1"))
  569. {
  570. mGpuProgramManager->registerProgramFactory("arbvp1", createGLArbGpuProgram);
  571. }
  572. if(caps->isShaderProfileSupported("vp30"))
  573. {
  574. mGpuProgramManager->registerProgramFactory("vp30", createGLArbGpuProgram);
  575. }
  576. if(caps->isShaderProfileSupported("vp40"))
  577. {
  578. mGpuProgramManager->registerProgramFactory("vp40", createGLArbGpuProgram);
  579. }
  580. if(caps->isShaderProfileSupported("gp4vp"))
  581. {
  582. mGpuProgramManager->registerProgramFactory("gp4vp", createGLArbGpuProgram);
  583. }
  584. if(caps->isShaderProfileSupported("gpu_vp"))
  585. {
  586. mGpuProgramManager->registerProgramFactory("gpu_vp", createGLArbGpuProgram);
  587. }
  588. }
  589. if(caps->hasCapability(RSC_GEOMETRY_PROGRAM))
  590. {
  591. //TODO : Should these be createGLArbGpuProgram or createGLGpuNVparseProgram?
  592. if(caps->isShaderProfileSupported("nvgp4"))
  593. {
  594. mGpuProgramManager->registerProgramFactory("nvgp4", createGLArbGpuProgram);
  595. }
  596. if(caps->isShaderProfileSupported("gp4gp"))
  597. {
  598. mGpuProgramManager->registerProgramFactory("gp4gp", createGLArbGpuProgram);
  599. }
  600. if(caps->isShaderProfileSupported("gpu_gp"))
  601. {
  602. mGpuProgramManager->registerProgramFactory("gpu_gp", createGLArbGpuProgram);
  603. }
  604. }
  605. if(caps->hasCapability(RSC_FRAGMENT_PROGRAM))
  606. {
  607. if(caps->isShaderProfileSupported("fp20"))
  608. {
  609. mGpuProgramManager->registerProgramFactory("fp20", createGLGpuNvparseProgram);
  610. }
  611. if(caps->isShaderProfileSupported("ps_1_4"))
  612. {
  613. mGpuProgramManager->registerProgramFactory("ps_1_4", createGL_ATI_FS_GpuProgram);
  614. }
  615. if(caps->isShaderProfileSupported("ps_1_3"))
  616. {
  617. mGpuProgramManager->registerProgramFactory("ps_1_3", createGL_ATI_FS_GpuProgram);
  618. }
  619. if(caps->isShaderProfileSupported("ps_1_2"))
  620. {
  621. mGpuProgramManager->registerProgramFactory("ps_1_2", createGL_ATI_FS_GpuProgram);
  622. }
  623. if(caps->isShaderProfileSupported("ps_1_1"))
  624. {
  625. mGpuProgramManager->registerProgramFactory("ps_1_1", createGL_ATI_FS_GpuProgram);
  626. }
  627. if(caps->isShaderProfileSupported("arbfp1"))
  628. {
  629. mGpuProgramManager->registerProgramFactory("arbfp1", createGLArbGpuProgram);
  630. }
  631. if(caps->isShaderProfileSupported("fp40"))
  632. {
  633. mGpuProgramManager->registerProgramFactory("fp40", createGLArbGpuProgram);
  634. }
  635. if(caps->isShaderProfileSupported("fp30"))
  636. {
  637. mGpuProgramManager->registerProgramFactory("fp30", createGLArbGpuProgram);
  638. }
  639. }
  640. if(caps->isShaderProfileSupported("glsl"))
  641. {
  642. // NFZ - check for GLSL vertex and fragment shader support successful
  643. mGLSLProgramFactory = new GLSLProgramFactory();
  644. HighLevelGpuProgramManager::getSingleton().addFactory(mGLSLProgramFactory);
  645. }
  646. if(caps->hasCapability(RSC_HWOCCLUSION))
  647. {
  648. if(caps->hasCapability(RSC_GL1_5_NOHWOCCLUSION))
  649. {
  650. // Assign ARB functions same to GL 1.5 version since
  651. // interface identical
  652. glBeginQueryARB = glBeginQuery;
  653. glDeleteQueriesARB = glDeleteQueries;
  654. glEndQueryARB = glEndQuery;
  655. glGenQueriesARB = glGenQueries;
  656. glGetQueryObjectivARB = glGetQueryObjectiv;
  657. glGetQueryObjectuivARB = glGetQueryObjectuiv;
  658. glGetQueryivARB = glGetQueryiv;
  659. glIsQueryARB = glIsQuery;
  660. }
  661. }
  662. /// Do this after extension function pointers are initialised as the extension
  663. /// is used to probe further capabilities.
  664. ConfigOptionMap::iterator cfi = getConfigOptions().find("RTT Preferred Mode");
  665. // RTT Mode: 0 use whatever available, 1 use PBuffers, 2 force use copying
  666. int rttMode = 0;
  667. if (cfi != getConfigOptions().end())
  668. {
  669. if (cfi->second.currentValue == "PBuffer")
  670. {
  671. rttMode = 1;
  672. }
  673. else if (cfi->second.currentValue == "Copy")
  674. {
  675. rttMode = 2;
  676. }
  677. }
  678. // Check for framebuffer object extension
  679. if(caps->hasCapability(RSC_FBO) && rttMode < 1)
  680. {
  681. // Before GL version 2.0, we need to get one of the extensions
  682. if(caps->hasCapability(RSC_FBO_ARB))
  683. GLEW_GET_FUN(__glewDrawBuffers) = glDrawBuffersARB;
  684. else if(caps->hasCapability(RSC_FBO_ATI))
  685. GLEW_GET_FUN(__glewDrawBuffers) = glDrawBuffersATI;
  686. if(caps->hasCapability(RSC_HWRENDER_TO_TEXTURE))
  687. {
  688. // Create FBO manager
  689. // TODO PORT - Log this somewhere?
  690. //LogManager::getSingleton().logMessage("GL: Using GL_EXT_framebuffer_object for rendering to textures (best)");
  691. mRTTManager = new GLFBOManager(false);
  692. }
  693. }
  694. else
  695. {
  696. // Check GLSupport for PBuffer support
  697. if(caps->hasCapability(RSC_PBUFFER) && rttMode < 2)
  698. {
  699. if(caps->hasCapability(RSC_HWRENDER_TO_TEXTURE))
  700. {
  701. // Use PBuffers
  702. mRTTManager = new GLPBRTTManager(mGLSupport, primary);
  703. // TODO PORT - Log this somewhere?
  704. //LogManager::getSingleton().logMessage("GL: Using PBuffers for rendering to textures");
  705. }
  706. }
  707. else
  708. {
  709. // No pbuffer support either -- fallback to simplest copying from framebuffer
  710. mRTTManager = new GLCopyingRTTManager();
  711. // TODO PORT - Log this somewhere?
  712. //LogManager::getSingleton().logMessage("GL: Using framebuffer copy for rendering to textures (worst)");
  713. //LogManager::getSingleton().logMessage("GL: Warning: RenderTexture size is restricted to size of framebuffer. If you are on Linux, consider using GLX instead of SDL.");
  714. }
  715. // Downgrade number of simultaneous targets
  716. caps->setNumMultiRenderTargets(1);
  717. }
  718. /// Create the texture manager
  719. //mTextureManager = new GLTextureManager(*mGLSupport);
  720. mGLInitialised = true;
  721. }
  722. void GLRenderSystem::reinitialise(void)
  723. {
  724. this->shutdown();
  725. this->_initialise(true);
  726. }
  727. void GLRenderSystem::shutdown(void)
  728. {
  729. RenderSystem::shutdown();
  730. // Deleting the GLSL program factory
  731. if (mGLSLProgramFactory)
  732. {
  733. // Remove from manager safely
  734. if (HighLevelGpuProgramManager::getSingletonPtr())
  735. HighLevelGpuProgramManager::getSingleton().removeFactory(mGLSLProgramFactory);
  736. delete mGLSLProgramFactory;
  737. mGLSLProgramFactory = 0;
  738. }
  739. // Deleting the GPU program manager and hardware buffer manager. Has to be done before the mGLSupport->stop().
  740. delete mGpuProgramManager;
  741. mGpuProgramManager = 0;
  742. delete mHardwareBufferManager;
  743. mHardwareBufferManager = 0;
  744. delete mRTTManager;
  745. mRTTManager = 0;
  746. // Delete extra threads contexts
  747. for (GLContextList::iterator i = mBackgroundContextList.begin();
  748. i != mBackgroundContextList.end(); ++i)
  749. {
  750. GLContext* pCurContext = *i;
  751. pCurContext->releaseContext();
  752. delete pCurContext;
  753. }
  754. mBackgroundContextList.clear();
  755. mGLSupport->stop();
  756. mStopRendering = true;
  757. delete mTextureManager;
  758. mTextureManager = 0;
  759. // There will be a new initial window and so forth, thus any call to test
  760. // some params will access an invalid pointer, so it is best to reset
  761. // the whole state.
  762. mGLInitialised = 0;
  763. }
  764. void GLRenderSystem::setAmbientLight(float r, float g, float b)
  765. {
  766. GLfloat lmodel_ambient[] = {r, g, b, 1.0};
  767. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  768. }
  769. void GLRenderSystem::setShadingType(ShadeOptions so)
  770. {
  771. switch(so)
  772. {
  773. case SO_FLAT:
  774. glShadeModel(GL_FLAT);
  775. break;
  776. default:
  777. glShadeModel(GL_SMOOTH);
  778. break;
  779. }
  780. }
  781. //---------------------------------------------------------------------
  782. bool GLRenderSystem::_createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions,
  783. RenderWindowList& createdWindows)
  784. {
  785. // Call base render system method.
  786. if (false == RenderSystem::_createRenderWindows(renderWindowDescriptions, createdWindows))
  787. return false;
  788. // Simply call _createRenderWindow in a loop.
  789. for (size_t i = 0; i < renderWindowDescriptions.size(); ++i)
  790. {
  791. const RenderWindowDescription& curRenderWindowDescription = renderWindowDescriptions[i];
  792. RenderWindow* curWindow = NULL;
  793. curWindow = _createRenderWindow(curRenderWindowDescription.name,
  794. curRenderWindowDescription.width,
  795. curRenderWindowDescription.height,
  796. curRenderWindowDescription.useFullScreen,
  797. &curRenderWindowDescription.miscParams);
  798. createdWindows.push_back(curWindow);
  799. }
  800. return true;
  801. }
  802. //---------------------------------------------------------------------
  803. RenderWindow* GLRenderSystem::_createRenderWindow(const String &name,
  804. unsigned int width, unsigned int height, bool fullScreen,
  805. const NameValuePairList *miscParams)
  806. {
  807. if (mRenderTargets.find(name) != mRenderTargets.end())
  808. {
  809. OGRE_EXCEPT(
  810. Exception::ERR_INVALIDPARAMS,
  811. "Window with name '" + name + "' already exists",
  812. "GLRenderSystem::_createRenderWindow" );
  813. }
  814. // Create the window
  815. RenderWindow* win = mGLSupport->newWindow(name, width, height,
  816. fullScreen, miscParams);
  817. attachRenderTarget( *win );
  818. if (!mGLInitialised)
  819. {
  820. // set up glew and GLSupport
  821. initialiseContext(win);
  822. StringVector tokens = StringUtil::split(mGLSupport->getGLVersion(), ".");
  823. if (!tokens.empty())
  824. {
  825. mDriverVersion.major = StringConverter::parseInt(tokens[0]);
  826. if (tokens.size() > 1)
  827. mDriverVersion.minor = StringConverter::parseInt(tokens[1]);
  828. if (tokens.size() > 2)
  829. mDriverVersion.release = StringConverter::parseInt(tokens[2]);
  830. }
  831. mDriverVersion.build = 0;
  832. // Initialise GL after the first window has been created
  833. // TODO: fire this from emulation options, and don't duplicate Real and Current capabilities
  834. mRealCapabilities = createRenderSystemCapabilities();
  835. // use real capabilities if custom capabilities are not available
  836. if(!mUseCustomCapabilities)
  837. mCurrentCapabilities = mRealCapabilities;
  838. initialiseFromRenderSystemCapabilities(mCurrentCapabilities, win);
  839. // Initialise the main context
  840. _oneTimeContextInitialization();
  841. if(mCurrentContext)
  842. mCurrentContext->setInitialized();
  843. }
  844. return win;
  845. }
  846. void GLRenderSystem::initialiseContext(RenderWindow* primary)
  847. {
  848. // Set main and current context
  849. mMainContext = 0;
  850. primary->getCustomAttribute("GLCONTEXT", &mMainContext);
  851. mCurrentContext = mMainContext;
  852. // Set primary context as active
  853. if(mCurrentContext)
  854. mCurrentContext->setCurrent();
  855. // Setup GLSupport
  856. mGLSupport->initialiseExtensions();
  857. // Get extension function pointers
  858. #if OGRE_THREAD_SUPPORT != 1
  859. glewContextInit(mGLSupport);
  860. #endif
  861. }
  862. //-----------------------------------------------------------------------
  863. MultiRenderTarget * GLRenderSystem::createMultiRenderTarget(const String & name)
  864. {
  865. MultiRenderTarget *retval = mRTTManager->createMultiRenderTarget(name);
  866. attachRenderTarget( *retval );
  867. return retval;
  868. }
  869. //-----------------------------------------------------------------------
  870. void GLRenderSystem::destroyRenderWindow(RenderWindow* pWin)
  871. {
  872. // Find it to remove from list
  873. RenderTargetMap::iterator i = mRenderTargets.begin();
  874. while (i != mRenderTargets.end())
  875. {
  876. if (i->second == pWin)
  877. {
  878. mRenderTargets.erase(i);
  879. delete pWin;
  880. break;
  881. }
  882. }
  883. }
  884. //---------------------------------------------------------------------
  885. void GLRenderSystem::_useLights(const LightList& lights, unsigned short limit)
  886. {
  887. // TODO PORT - I don't use fixed pipleline lights. Remove this
  888. assert(false);
  889. //// Save previous modelview
  890. //glMatrixMode(GL_MODELVIEW);
  891. //glPushMatrix();
  892. //// just load view matrix (identity world)
  893. //GLfloat mat[16];
  894. //makeGLMatrix(mat, mViewMatrix);
  895. //glLoadMatrixf(mat);
  896. //LightList::const_iterator i, iend;
  897. //iend = lights.end();
  898. //unsigned short num = 0;
  899. //for (i = lights.begin(); i != iend && num < limit; ++i, ++num)
  900. //{
  901. // setGLLight(num, *i);
  902. // mLights[num] = *i;
  903. //}
  904. //// Disable extra lights
  905. //for (; num < mCurrentLights; ++num)
  906. //{
  907. // setGLLight(num, NULL);
  908. // mLights[num] = NULL;
  909. //}
  910. //mCurrentLights = std::min(limit, static_cast<unsigned short>(lights.size()));
  911. //setLights();
  912. //// restore previous
  913. //glPopMatrix();
  914. }
  915. //-----------------------------------------------------------------------------
  916. void GLRenderSystem::makeGLMatrix(GLfloat gl_matrix[16], const Matrix4& m)
  917. {
  918. size_t x = 0;
  919. for (size_t i = 0; i < 4; i++)
  920. {
  921. for (size_t j = 0; j < 4; j++)
  922. {
  923. gl_matrix[x] = m[j][i];
  924. x++;
  925. }
  926. }
  927. }
  928. //-----------------------------------------------------------------------------
  929. void GLRenderSystem::_setWorldMatrix( const Matrix4 &m )
  930. {
  931. GLfloat mat[16];
  932. mWorldMatrix = m;
  933. makeGLMatrix( mat, mViewMatrix * mWorldMatrix );
  934. glMatrixMode(GL_MODELVIEW);
  935. glLoadMatrixf(mat);
  936. }
  937. //-----------------------------------------------------------------------------
  938. void GLRenderSystem::_setViewMatrix( const Matrix4 &m )
  939. {
  940. mViewMatrix = m;
  941. GLfloat mat[16];
  942. makeGLMatrix( mat, mViewMatrix * mWorldMatrix );
  943. glMatrixMode(GL_MODELVIEW);
  944. glLoadMatrixf(mat);
  945. // also mark clip planes dirty
  946. if (!mClipPlanes.empty())
  947. mClipPlanesDirty = true;
  948. }
  949. //-----------------------------------------------------------------------------
  950. void GLRenderSystem::_setProjectionMatrix(const Matrix4 &m)
  951. {
  952. GLfloat mat[16];
  953. makeGLMatrix(mat, m);
  954. if (mActiveRenderTarget->requiresTextureFlipping())
  955. {
  956. // Invert transformed y
  957. mat[1] = -mat[1];
  958. mat[5] = -mat[5];
  959. mat[9] = -mat[9];
  960. mat[13] = -mat[13];
  961. }
  962. glMatrixMode(GL_PROJECTION);
  963. glLoadMatrixf(mat);
  964. glMatrixMode(GL_MODELVIEW);
  965. // also mark clip planes dirty
  966. if (!mClipPlanes.empty())
  967. mClipPlanesDirty = true;
  968. }
  969. //-----------------------------------------------------------------------------
  970. void GLRenderSystem::_setSurfaceParams(const ColourValue &ambient,
  971. const ColourValue &diffuse, const ColourValue &specular,
  972. const ColourValue &emissive, Real shininess,
  973. TrackVertexColourType tracking)
  974. {
  975. // Track vertex colour
  976. if(tracking != TVC_NONE)
  977. {
  978. GLenum gt = GL_DIFFUSE;
  979. // There are actually 15 different combinations for tracking, of which
  980. // GL only supports the most used 5. This means that we have to do some
  981. // magic to find the best match. NOTE:
  982. // GL_AMBIENT_AND_DIFFUSE != GL_AMBIENT | GL__DIFFUSE
  983. if(tracking & TVC_AMBIENT)
  984. {
  985. if(tracking & TVC_DIFFUSE)
  986. {
  987. gt = GL_AMBIENT_AND_DIFFUSE;
  988. }
  989. else
  990. {
  991. gt = GL_AMBIENT;
  992. }
  993. }
  994. else if(tracking & TVC_DIFFUSE)
  995. {
  996. gt = GL_DIFFUSE;
  997. }
  998. else if(tracking & TVC_SPECULAR)
  999. {
  1000. gt = GL_SPECULAR;
  1001. }
  1002. else if(tracking & TVC_EMISSIVE)
  1003. {
  1004. gt = GL_EMISSION;
  1005. }
  1006. glColorMaterial(GL_FRONT_AND_BACK, gt);
  1007. glEnable(GL_COLOR_MATERIAL);
  1008. }
  1009. else
  1010. {
  1011. glDisable(GL_COLOR_MATERIAL);
  1012. }
  1013. // XXX Cache previous values?
  1014. // XXX Front or Front and Back?
  1015. GLfloat f4val[4] = {diffuse.r, diffuse.g, diffuse.b, diffuse.a};
  1016. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, f4val);
  1017. f4val[0] = ambient.r;
  1018. f4val[1] = ambient.g;
  1019. f4val[2] = ambient.b;
  1020. f4val[3] = ambient.a;
  1021. glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, f4val);
  1022. f4val[0] = specular.r;
  1023. f4val[1] = specular.g;
  1024. f4val[2] = specular.b;
  1025. f4val[3] = specular.a;
  1026. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, f4val);
  1027. f4val[0] = emissive.r;
  1028. f4val[1] = emissive.g;
  1029. f4val[2] = emissive.b;
  1030. f4val[3] = emissive.a;
  1031. glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, f4val);
  1032. glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
  1033. }
  1034. //-----------------------------------------------------------------------------
  1035. void GLRenderSystem::_setPointParameters(Real size,
  1036. bool attenuationEnabled, Real constant, Real linear, Real quadratic,
  1037. Real minSize, Real maxSize)
  1038. {
  1039. float val[4] = {1, 0, 0, 1};
  1040. if(attenuationEnabled)
  1041. {
  1042. // Point size is still calculated in pixels even when attenuation is
  1043. // enabled, which is pretty awkward, since you typically want a viewport
  1044. // independent size if you're looking for attenuation.
  1045. // So, scale the point size up by viewport size (this is equivalent to
  1046. // what D3D does as standard)
  1047. size = size * mActiveViewport->getActualHeight();
  1048. minSize = minSize * mActiveViewport->getActualHeight();
  1049. if (maxSize == 0.0f)
  1050. maxSize = mCurrentCapabilities->getMaxPointSize(); // pixels
  1051. else
  1052. maxSize = maxSize * mActiveViewport->getActualHeight();
  1053. // XXX: why do I need this for results to be consistent with D3D?
  1054. // Equations are supposedly the same once you factor in vp height
  1055. Real correction = 0.005;
  1056. // scaling required
  1057. val[0] = constant;
  1058. val[1] = linear * correction;
  1059. val[2] = quadratic * correction;
  1060. val[3] = 1;
  1061. if (mCurrentCapabilities->hasCapability(RSC_VERTEX_PROGRAM))
  1062. glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
  1063. }
  1064. else
  1065. {
  1066. if (maxSize == 0.0f)
  1067. maxSize = mCurrentCapabilities->getMaxPointSize();
  1068. if (mCurrentCapabilities->hasCapability(RSC_VERTEX_PROGRAM))
  1069. glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
  1070. }
  1071. // no scaling required
  1072. // GL has no disabled flag for this so just set to constant
  1073. glPointSize(size);
  1074. if (mCurrentCapabilities->hasCapability(RSC_POINT_EXTENDED_PARAMETERS))
  1075. {
  1076. glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, val);
  1077. glPointParameterf(GL_POINT_SIZE_MIN, minSize);
  1078. glPointParameterf(GL_POINT_SIZE_MAX, maxSize);
  1079. }
  1080. else if (mCurrentCapabilities->hasCapability(RSC_POINT_EXTENDED_PARAMETERS_ARB))
  1081. {
  1082. glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION, val);
  1083. glPointParameterfARB(GL_POINT_SIZE_MIN, minSize);
  1084. glPointParameterfARB(GL_POINT_SIZE_MAX, maxSize);
  1085. }
  1086. else if (mCurrentCapabilities->hasCapability(RSC_POINT_EXTENDED_PARAMETERS_EXT))
  1087. {
  1088. glPointParameterfvEXT(GL_POINT_DISTANCE_ATTENUATION, val);
  1089. glPointParameterfEXT(GL_POINT_SIZE_MIN, minSize);
  1090. glPointParameterfEXT(GL_POINT_SIZE_MAX, maxSize);
  1091. }
  1092. }
  1093. //---------------------------------------------------------------------
  1094. void GLRenderSystem::_setPointSpritesEnabled(bool enabled)
  1095. {
  1096. if (!getCapabilities()->hasCapability(RSC_POINT_SPRITES))
  1097. return;
  1098. if (enabled)
  1099. {
  1100. glEnable(GL_POINT_SPRITE);
  1101. }
  1102. else
  1103. {
  1104. glDisable(GL_POINT_SPRITE);
  1105. }
  1106. // Set sprite texture coord generation
  1107. // Don't offer this as an option since D3D links it to sprite enabled
  1108. for (ushort i = 0; i < mFixedFunctionTextureUnits; ++i)
  1109. {
  1110. activateGLTextureUnit(i);
  1111. glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE,
  1112. enabled ? GL_TRUE : GL_FALSE);
  1113. }
  1114. activateGLTextureUnit(0);
  1115. }
  1116. //-----------------------------------------------------------------------------
  1117. void GLRenderSystem::_setTexture(size_t stage, bool enabled, const TexturePtr &texPtr)
  1118. {
  1119. GLTexturePtr tex = texPtr;
  1120. GLenum lastTextureType = mTextureTypes[stage];
  1121. if (!activateGLTextureUnit(stage))
  1122. return;
  1123. if (enabled)
  1124. {
  1125. if (!tex.isNull())
  1126. {
  1127. // note used
  1128. mTextureTypes[stage] = tex->getGLTextureTarget();
  1129. }
  1130. else
  1131. // assume 2D
  1132. mTextureTypes[stage] = GL_TEXTURE_2D;
  1133. if(lastTextureType != mTextureTypes[stage] && lastTextureType != 0)
  1134. {
  1135. if (stage < mFixedFunctionTextureUnits)
  1136. {
  1137. glDisable( lastTextureType );
  1138. }
  1139. }
  1140. if (stage < mFixedFunctionTextureUnits)
  1141. {
  1142. glEnable( mTextureTypes[stage] );
  1143. }
  1144. if(!tex.isNull())
  1145. glBindTexture( mTextureTypes[stage], tex->getGLID() );
  1146. else
  1147. {
  1148. // TODO PORT - IMPORTANT - This is broken until I add proper TextureManager
  1149. //glBindTexture( mTextureTypes[stage], static_cast<GLTextureManager*>(mTextureManager)->getWarningTextureID() );
  1150. }
  1151. }
  1152. else
  1153. {
  1154. if (stage < mFixedFunctionTextureUnits)
  1155. {
  1156. if (lastTextureType != 0)
  1157. {
  1158. glDisable( mTextureTypes[stage] );
  1159. }
  1160. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  1161. }
  1162. // bind zero texture
  1163. glBindTexture(GL_TEXTURE_2D, 0);
  1164. }
  1165. activateGLTextureUnit(0);
  1166. }
  1167. //-----------------------------------------------------------------------------
  1168. void GLRenderSystem::_setTextureCoordSet(size_t stage, size_t index)
  1169. {
  1170. mTextureCoordIndex[stage] = index;
  1171. }
  1172. //-----------------------------------------------------------------------------
  1173. void GLRenderSystem::_setTextureCoordCalculation(size_t stage, TexCoordCalcMethod m,
  1174. const Frustum* frustum)
  1175. {
  1176. if (stage >= mFixedFunctionTextureUnits)
  1177. {
  1178. // Can't do this
  1179. return;
  1180. }
  1181. GLfloat M[16];
  1182. Matrix4 projectionBias;
  1183. // Default to no extra auto texture matrix
  1184. mUseAutoTextureMatrix = false;
  1185. GLfloat eyePlaneS[] = {1.0, 0.0, 0.0, 0.0};
  1186. GLfloat eyePlaneT[] = {0.0, 1.0, 0.0, 0.0};
  1187. GLfloat eyePlaneR[] = {0.0, 0.0, 1.0, 0.0};
  1188. GLfloat eyePlaneQ[] = {0.0, 0.0, 0.0, 1.0};
  1189. if (!activateGLTextureUnit(stage))
  1190. return;
  1191. switch( m )
  1192. {
  1193. case TEXCALC_NONE:
  1194. glDisable( GL_TEXTURE_GEN_S );
  1195. glDisable( GL_TEXTURE_GEN_T );
  1196. glDisable( GL_TEXTURE_GEN_R );
  1197. glDisable( GL_TEXTURE_GEN_Q );
  1198. break;
  1199. case TEXCALC_ENVIRONMENT_MAP:
  1200. glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
  1201. glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
  1202. glEnable( GL_TEXTURE_GEN_S );
  1203. glEnable( GL_TEXTURE_GEN_T );
  1204. glDisable( GL_TEXTURE_GEN_R );
  1205. glDisable( GL_TEXTURE_GEN_Q );
  1206. // Need to use a texture matrix to flip the spheremap
  1207. mUseAutoTextureMatrix = true;
  1208. memset(mAutoTextureMatrix, 0, sizeof(GLfloat)*16);
  1209. mAutoTextureMatrix[0] = mAutoTextureMatrix[10] = mAutoTextureMatrix[15] = 1.0f;
  1210. mAutoTextureMatrix[5] = -1.0f;
  1211. break;
  1212. case TEXCALC_ENVIRONMENT_MAP_PLANAR:
  1213. // XXX This doesn't seem right?!
  1214. #ifdef GL_VERSION_1_3
  1215. glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
  1216. glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
  1217. glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
  1218. glEnable( GL_TEXTURE_GEN_S );
  1219. glEnable( GL_TEXTURE_GEN_T );
  1220. glEnable( GL_TEXTURE_GEN_R );
  1221. glDisable( GL_TEXTURE_GEN_Q );
  1222. #else
  1223. glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
  1224. glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP );
  1225. glEnable( GL_TEXTURE_GEN_S );
  1226. glEnable( GL_TEXTURE_GEN_T );
  1227. glDisable( GL_TEXTURE_GEN_R );
  1228. glDisable( GL_TEXTURE_GEN_Q );
  1229. #endif
  1230. break;
  1231. case TEXCALC_ENVIRONMENT_MAP_REFLECTION:
  1232. glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
  1233. glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
  1234. glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
  1235. glEnable( GL_TEXTURE_GEN_S );
  1236. glEnable( GL_TEXTURE_GEN_T );
  1237. glEnable( GL_TEXTURE_GEN_R );
  1238. glDisable( GL_TEXTURE_GEN_Q );
  1239. // We need an extra texture matrix here
  1240. // This sets the texture matrix to be the inverse of the view matrix
  1241. mUseAutoTextureMatrix = true;
  1242. makeGLMatrix( M, mViewMatrix);
  1243. // Transpose 3x3 in order to invert matrix (rotation)
  1244. // Note that we need to invert the Z _before_ the rotation
  1245. // No idea why we have to invert the Z at all, but reflection is wrong without it
  1246. mAutoTextureMatrix[0] = M[0]; mAutoTextureMatrix[1] = M[4]; mAutoTextureMatrix[2] = -M[8];
  1247. mAutoTextureMatrix[4] = M[1]; mAutoTextureMatrix[5] = M[5]; mAutoTextureMatrix[6] = -M[9];
  1248. mAutoTextureMatrix[8] = M[2]; mAutoTextureMatrix[9] = M[6]; mAutoTextureMatrix[10] = -M[10];
  1249. mAutoTextureMatrix[3] = mAutoTextureMatrix[7] = mAutoTextureMatrix[11] = 0.0f;
  1250. mAutoTextureMatrix[12] = mAutoTextureMatrix[13] = mAutoTextureMatrix[14] = 0.0f;
  1251. mAutoTextureMatrix[15] = 1.0f;
  1252. break;
  1253. case TEXCALC_ENVIRONMENT_MAP_NORMAL:
  1254. glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP );
  1255. glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP );
  1256. glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP );
  1257. glEnable( GL_TEXTURE_GEN_S );
  1258. glEnable( GL_TEXTURE_GEN_T );
  1259. glEnable( GL_TEXTURE_GEN_R );
  1260. glDisable( GL_TEXTURE_GEN_Q );
  1261. break;
  1262. case TEXCALC_PROJECTIVE_TEXTURE:
  1263. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  1264. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  1265. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  1266. glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  1267. glTexGenfv(GL_S, GL_EYE_PLANE, eyePlaneS);
  1268. glTexGenfv(GL_T, GL_EYE_PLANE, eyePlaneT);
  1269. glTexGenfv(GL_R, GL_EYE_PLANE, eyePlaneR);
  1270. glTexGenfv(GL_Q, GL_EYE_PLANE, eyePlaneQ);
  1271. glEnable(GL_TEXTURE_GEN_S);
  1272. glEnable(GL_TEXTURE_GEN_T);
  1273. glEnable(GL_TEXTURE_GEN_R);
  1274. glEnable(GL_TEXTURE_GEN_Q);
  1275. mUseAutoTextureMatrix = true;
  1276. // Set scale and translation matrix for projective textures
  1277. projectionBias = Matrix4::CLIPSPACE2DTOIMAGESPACE;
  1278. projectionBias = projectionBias * frustum->getProjectionMatrix();
  1279. if(mTexProjRelative)
  1280. {
  1281. Matrix4 viewMatrix;
  1282. frustum->calcViewMatrixRelative(mTexProjRelativeOrigin, viewMatrix);
  1283. projectionBias = projectionBias * viewMatrix;
  1284. }
  1285. else
  1286. {
  1287. projectionBias = projectionBias * frustum->getViewMatrix();
  1288. }
  1289. projectionBias = projectionBias * mWorldMatrix;
  1290. makeGLMatrix(mAutoTextureMatrix, projectionBias);
  1291. break;
  1292. default:
  1293. break;
  1294. }
  1295. activateGLTextureUnit(0);
  1296. }
  1297. //-----------------------------------------------------------------------------
  1298. GLint GLRenderSystem::getTextureAddressingMode(
  1299. TextureUnitState::TextureAddressingMode tam) const
  1300. {
  1301. switch(tam)
  1302. {
  1303. default:
  1304. case TextureUnitState::TAM_WRAP:
  1305. return GL_REPEAT;
  1306. case TextureUnitState::TAM_MIRROR:
  1307. return GL_MIRRORED_REPEAT;
  1308. case TextureUnitState::TAM_CLAMP:
  1309. return GL_CLAMP_TO_EDGE;
  1310. case TextureUnitState::TAM_BORDER:
  1311. return GL_CLAMP_TO_BORDER;
  1312. }
  1313. }
  1314. //-----------------------------------------------------------------------------
  1315. void GLRenderSystem::_setTextureAddressingMode(size_t stage, const TextureUnitState::UVWAddressingMode& uvw)
  1316. {
  1317. if (!activateGLTextureUnit(stage))
  1318. return;
  1319. glTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_S,
  1320. getTextureAddressingMode(uvw.u));
  1321. glTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_T,
  1322. getTextureAddressingMode(uvw.v));
  1323. glTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_R,
  1324. getTextureAddressingMode(uvw.w));
  1325. activateGLTextureUnit(0);
  1326. }
  1327. //-----------------------------------------------------------------------------
  1328. void GLRenderSystem::_setTextureBorderColour(size_t stage, const ColourValue& colour)
  1329. {
  1330. GLfloat border[4] = { colour.r, colour.g, colour.b, colour.a };
  1331. if (activateGLTextureUnit(stage))
  1332. {
  1333. glTexParameterfv( mTextureTypes[stage], GL_TEXTURE_BORDER_COLOR, border);
  1334. activateGLTextureUnit(0);
  1335. }
  1336. }
  1337. //-----------------------------------------------------------------------------
  1338. void GLRenderSystem::_setTextureMipmapBias(size_t stage, float bias)
  1339. {
  1340. if (mCurrentCapabilities->hasCapability(RSC_MIPMAP_LOD_BIAS))
  1341. {
  1342. if (activateGLTextureUnit(stage))
  1343. {
  1344. glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, bias);
  1345. activateGLTextureUnit(0);
  1346. }
  1347. }
  1348. }
  1349. //-----------------------------------------------------------------------------
  1350. void GLRenderSystem::_setTextureMatrix(size_t stage, const Matrix4& xform)
  1351. {
  1352. if (stage >= mFixedFunctionTextureUnits)
  1353. {
  1354. // Can't do this
  1355. return;
  1356. }
  1357. GLfloat mat[16];
  1358. makeGLMatrix(mat, xform);
  1359. if (!activateGLTextureUnit(stage))
  1360. return;
  1361. glMatrixMode(GL_TEXTURE);
  1362. // Load this matrix in
  1363. glLoadMatrixf(mat);
  1364. if (mUseAutoTextureMatrix)
  1365. {
  1366. // Concat auto matrix
  1367. glMultMatrixf(mAutoTextureMatrix);
  1368. }
  1369. glMatrixMode(GL_MODELVIEW);
  1370. activateGLTextureUnit(0);
  1371. }
  1372. //-----------------------------------------------------------------------------
  1373. GLint GLRenderSystem::getBlendMode(SceneBlendFactor ogreBlend) const
  1374. {
  1375. switch(ogreBlend)
  1376. {
  1377. case SBF_ONE:
  1378. return GL_ONE;
  1379. case SBF_ZERO:
  1380. return GL_ZERO;
  1381. case SBF_DEST_COLOUR:
  1382. return GL_DST_COLOR;
  1383. case SBF_SOURCE_COLOUR:
  1384. return GL_SRC_COLOR;
  1385. case SBF_ONE_MINUS_DEST_COLOUR:
  1386. return GL_ONE_MINUS_DST_COLOR;
  1387. case SBF_ONE_MINUS_SOURCE_COLOUR:
  1388. return GL_ONE_MINUS_SRC_COLOR;
  1389. case SBF_DEST_ALPHA:
  1390. return GL_DST_ALPHA;
  1391. case SBF_SOURCE_ALPHA:
  1392. return GL_SRC_ALPHA;
  1393. case SBF_ONE_MINUS_DEST_ALPHA:
  1394. return GL_ONE_MINUS_DST_ALPHA;
  1395. case SBF_ONE_MINUS_SOURCE_ALPHA:
  1396. return GL_ONE_MINUS_SRC_ALPHA;
  1397. };
  1398. // to keep compiler happy
  1399. return GL_ONE;
  1400. }
  1401. void GLRenderSystem::_setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op )
  1402. {
  1403. GLint sourceBlend = getBlendMode(sourceFactor);
  1404. GLint destBlend = getBlendMode(destFactor);
  1405. if(sourceFactor == SBF_ONE && destFactor == SBF_ZERO)
  1406. {
  1407. glDisable(GL_BLEND);
  1408. }
  1409. else
  1410. {
  1411. glEnable(GL_BLEND);
  1412. glBlendFunc(sourceBlend, destBlend);
  1413. }
  1414. GLint func = GL_FUNC_ADD;
  1415. switch(op)
  1416. {
  1417. case SBO_ADD:
  1418. func = GL_FUNC_ADD;
  1419. break;
  1420. case SBO_SUBTRACT:
  1421. func = GL_FUNC_SUBTRACT;
  1422. break;
  1423. case SBO_REVERSE_SUBTRACT:
  1424. func = GL_FUNC_REVERSE_SUBTRACT;
  1425. break;
  1426. case SBO_MIN:
  1427. func = GL_MIN;
  1428. break;
  1429. case SBO_MAX:
  1430. func = GL_MAX;
  1431. break;
  1432. }
  1433. if(GLEW_VERSION_1_4 || GLEW_ARB_imaging)
  1434. {
  1435. glBlendEquation(func);
  1436. }
  1437. else if(GLEW_EXT_blend_minmax && (func == GL_MIN || func == GL_MAX))
  1438. {
  1439. glBlendEquationEXT(func);
  1440. }
  1441. }
  1442. //-----------------------------------------------------------------------------
  1443. void GLRenderSystem::_setSeparateSceneBlending(
  1444. SceneBlendFactor sourceFactor, SceneBlendFactor destFactor,
  1445. SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha,
  1446. SceneBlendOperation op, SceneBlendOperation alphaOp )
  1447. {
  1448. GLint sourceBlend = getBlendMode(sourceFactor);
  1449. GLint destBlend = getBlendMode(destFactor);
  1450. GLint sourceBlendAlpha = getBlendMode(sourceFactorAlpha);
  1451. GLint destBlendAlpha = getBlendMode(destFactorAlpha);
  1452. if(sourceFactor == SBF_ONE && destFactor == SBF_ZERO &&
  1453. sourceFactorAlpha == SBF_ONE && destFactorAlpha == SBF_ZERO)
  1454. {
  1455. glDisable(GL_BLEND);
  1456. }
  1457. else
  1458. {
  1459. glEnable(GL_BLEND);
  1460. glBlendFuncSeparate(sourceBlend, destBlend, sourceBlendAlpha, destBlendAlpha);
  1461. }
  1462. GLint func = GL_FUNC_ADD, alphaFunc = GL_FUNC_ADD;
  1463. switch(op)
  1464. {
  1465. case SBO_ADD:
  1466. func = GL_FUNC_ADD;
  1467. break;
  1468. case SBO_SUBTRACT:
  1469. func = GL_FUNC_SUBTRACT;
  1470. break;
  1471. case SBO_REVERSE_SUBTRACT:
  1472. func = GL_FUNC_REVERSE_SUBTRACT;
  1473. break;
  1474. case SBO_MIN:
  1475. func = GL_MIN;
  1476. break;
  1477. case SBO_MAX:
  1478. func = GL_MAX;
  1479. break;
  1480. }
  1481. switch(alphaOp)
  1482. {
  1483. case SBO_ADD:
  1484. alphaFunc = GL_FUNC_ADD;
  1485. break;
  1486. case SBO_SUBTRACT:
  1487. alphaFunc = GL_FUNC_SUBTRACT;
  1488. break;
  1489. case SBO_REVERSE_SUBTRACT:
  1490. alphaFunc = GL_FUNC_REVERSE_SUBTRACT;
  1491. break;
  1492. case SBO_MIN:
  1493. alphaFunc = GL_MIN;
  1494. break;
  1495. case SBO_MAX:
  1496. alphaFunc = GL_MAX;
  1497. break;
  1498. }
  1499. if(GLEW_VERSION_2_0) {
  1500. glBlendEquationSeparate(func, alphaFunc);
  1501. }
  1502. else if(GLEW_EXT_blend_equation_separate) {
  1503. glBlendEquationSeparateEXT(func, alphaFunc);
  1504. }
  1505. }
  1506. //-----------------------------------------------------------------------------
  1507. void GLRenderSystem::_setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage)
  1508. {
  1509. bool a2c = false;
  1510. static bool lasta2c = false;
  1511. if(func == CMPF_ALWAYS_PASS)
  1512. {
  1513. glDisable(GL_ALPHA_TEST);
  1514. }
  1515. else
  1516. {
  1517. glEnable(GL_ALPHA_TEST);
  1518. a2c = alphaToCoverage;
  1519. glAlphaFunc(convertCompareFunction(func), value / 255.0f);
  1520. }
  1521. if (a2c != lasta2c && getCapabilities()->hasCapability(RSC_ALPHA_TO_COVERAGE))
  1522. {
  1523. if (a2c)
  1524. glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
  1525. else
  1526. glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
  1527. lasta2c = a2c;
  1528. }
  1529. }
  1530. //-----------------------------------------------------------------------------
  1531. void GLRenderSystem::_setViewport(Viewport *vp)
  1532. {
  1533. // Check if viewport is different
  1534. if (vp != mActiveViewport || vp->_isUpdated())
  1535. {
  1536. RenderTarget* target;
  1537. target = vp->getTarget();
  1538. _setRenderTarget(target);
  1539. mActiveViewport = vp;
  1540. GLsizei x, y, w, h;
  1541. // Calculate the "lower-left" corner of the viewport
  1542. w = vp->getActualWidth();
  1543. h = vp->getActualHeight();
  1544. x = vp->getActualLeft();
  1545. y = vp->getActualTop();
  1546. if (!target->requiresTextureFlipping())
  1547. {
  1548. // Convert "upper-left" corner to "lower-left"
  1549. y = target->getHeight() - h - y;
  1550. }
  1551. glViewport(x, y, w, h);
  1552. // Configure the viewport clipping
  1553. glScissor(x, y, w, h);
  1554. vp->_clearUpdatedFlag();
  1555. }
  1556. }
  1557. void GLRenderSystem::setLights()
  1558. {
  1559. // TODO PORT - I'm not using fixed pipeline lights. Remove this later
  1560. //for (size_t i = 0; i < MAX_LIGHTS; ++i)
  1561. //{
  1562. // if (mLights[i] != NULL)
  1563. // {
  1564. // Light* lt = mLights[i];
  1565. // setGLLightPositionDirection(lt, GL_LIGHT0 + i);
  1566. // }
  1567. //}
  1568. }
  1569. //-----------------------------------------------------------------------------
  1570. void GLRenderSystem::_beginFrame(void)
  1571. {
  1572. if (!mActiveViewport)
  1573. OGRE_EXCEPT(Exception::ERR_INVALID_STATE,
  1574. "Cannot begin frame - no viewport selected.",
  1575. "GLRenderSystem::_beginFrame");
  1576. // Activate the viewport clipping
  1577. glEnable(GL_SCISSOR_TEST);
  1578. }
  1579. //-----------------------------------------------------------------------------
  1580. void GLRenderSystem::_endFrame(void)
  1581. {
  1582. // Deactivate the viewport clipping.
  1583. glDisable(GL_SCISSOR_TEST);
  1584. // unbind GPU programs at end of frame
  1585. // this is mostly to avoid holding bound programs that might get deleted
  1586. // outside via the resource manager
  1587. unbindGpuProgram(GPT_VERTEX_PROGRAM);
  1588. unbindGpuProgram(GPT_FRAGMENT_PROGRAM);
  1589. }
  1590. //-----------------------------------------------------------------------------
  1591. void GLRenderSystem::_setCullingMode(CullingMode mode)
  1592. {
  1593. mCullingMode = mode;
  1594. // NB: Because two-sided stencil API dependence of the front face, we must
  1595. // use the same 'winding' for the front face everywhere. As the OGRE default
  1596. // culling mode is clockwise, we also treat anticlockwise winding as front
  1597. // face for consistently. On the assumption that, we can't change the front
  1598. // face by glFrontFace anywhere.
  1599. GLenum cullMode;
  1600. switch( mode )
  1601. {
  1602. case CULL_NONE:
  1603. glDisable( GL_CULL_FACE );
  1604. return;
  1605. default:
  1606. case CULL_CLOCKWISE:
  1607. if (mActiveRenderTarget &&
  1608. ((mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) ||
  1609. (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding)))
  1610. {
  1611. cullMode = GL_FRONT;
  1612. }
  1613. else
  1614. {
  1615. cullMode = GL_BACK;
  1616. }
  1617. break;
  1618. case CULL_ANTICLOCKWISE:
  1619. if (mActiveRenderTarget &&
  1620. ((mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) ||
  1621. (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding)))
  1622. {
  1623. cullMode = GL_BACK;
  1624. }
  1625. else
  1626. {
  1627. cullMode = GL_FRONT;
  1628. }
  1629. break;
  1630. }
  1631. glEnable( GL_CULL_FACE );
  1632. glCullFace( cullMode );
  1633. }
  1634. //-----------------------------------------------------------------------------
  1635. void GLRenderSystem::_setDepthBufferParams(bool depthTest, bool depthWrite, CompareFunction depthFunction)
  1636. {
  1637. _setDepthBufferCheckEnabled(depthTest);
  1638. _setDepthBufferWriteEnabled(depthWrite);
  1639. _setDepthBufferFunction(depthFunction);
  1640. }
  1641. //-----------------------------------------------------------------------------
  1642. void GLRenderSystem::_setDepthBufferCheckEnabled(bool enabled)
  1643. {
  1644. if (enabled)
  1645. {
  1646. glClearDepth(1.0f);
  1647. glEnable(GL_DEPTH_TEST);
  1648. }
  1649. else
  1650. {
  1651. glDisable(GL_DEPTH_TEST);
  1652. }
  1653. }
  1654. //-----------------------------------------------------------------------------
  1655. void GLRenderSystem::_setDepthBufferWriteEnabled(bool enabled)
  1656. {
  1657. GLboolean flag = enabled ? GL_TRUE : GL_FALSE;
  1658. glDepthMask( flag );
  1659. // Store for reference in _beginFrame
  1660. mDepthWrite = enabled;
  1661. }
  1662. //-----------------------------------------------------------------------------
  1663. void GLRenderSystem::_setDepthBufferFunction(CompareFunction func)
  1664. {
  1665. glDepthFunc(convertCompareFunction(func));
  1666. }
  1667. //-----------------------------------------------------------------------------
  1668. void GLRenderSystem::_setDepthBias(float constantBias, float slopeScaleBias)
  1669. {
  1670. if (constantBias != 0 || slopeScaleBias != 0)
  1671. {
  1672. glEnable(GL_POLYGON_OFFSET_FILL);
  1673. glEnable(GL_POLYGON_OFFSET_POINT);
  1674. glEnable(GL_POLYGON_OFFSET_LINE);
  1675. glPolygonOffset(-slopeScaleBias, -constantBias);
  1676. }
  1677. else
  1678. {
  1679. glDisable(GL_POLYGON_OFFSET_FILL);
  1680. glDisable(GL_POLYGON_OFFSET_POINT);
  1681. glDisable(GL_POLYGON_OFFSET_LINE);
  1682. }
  1683. }
  1684. //-----------------------------------------------------------------------------
  1685. void GLRenderSystem::_setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha)
  1686. {
  1687. glColorMask(red, green, blue, alpha);
  1688. // record this
  1689. mColourWrite[0] = red;
  1690. mColourWrite[1] = blue;
  1691. mColourWrite[2] = green;
  1692. mColourWrite[3] = alpha;
  1693. }
  1694. //-----------------------------------------------------------------------------
  1695. String GLRenderSystem::getErrorDescription(long errCode) const
  1696. {
  1697. const GLubyte *errString = gluErrorString (errCode);
  1698. return (errString != 0) ? String((const char*) errString) : StringUtil::BLANK;
  1699. }
  1700. //-----------------------------------------------------------------------------
  1701. void GLRenderSystem::setLightingEnabled(bool enabled)
  1702. {
  1703. if (enabled)
  1704. {
  1705. glEnable(GL_LIGHTING);
  1706. }
  1707. else
  1708. {
  1709. glDisable(GL_LIGHTING);
  1710. }
  1711. }
  1712. //-----------------------------------------------------------------------------
  1713. void GLRenderSystem::_setFog(FogMode mode, const ColourValue& colour, Real density, Real start, Real end)
  1714. {
  1715. GLint fogMode;
  1716. switch (mode)
  1717. {
  1718. case FOG_EXP:
  1719. fogMode = GL_EXP;
  1720. break;
  1721. case FOG_EXP2:
  1722. fogMode = GL_EXP2;
  1723. break;
  1724. case FOG_LINEAR:
  1725. fogMode = GL_LINEAR;
  1726. break;
  1727. default:
  1728. // Give up on it
  1729. glDisable(GL_FOG);
  1730. return;
  1731. }
  1732. glEnable(GL_FOG);
  1733. glFogi(GL_FOG_MODE, fogMode);
  1734. GLfloat fogColor[4] = {colour.r, colour.g, colour.b, colour.a};
  1735. glFogfv(GL_FOG_COLOR, fogColor);
  1736. glFogf(GL_FOG_DENSITY, density);
  1737. glFogf(GL_FOG_START, start);
  1738. glFogf(GL_FOG_END, end);
  1739. // XXX Hint here?
  1740. }
  1741. VertexElementType GLRenderSystem::getColourVertexElementType(void) const
  1742. {
  1743. return VET_COLOUR_ABGR;
  1744. }
  1745. void GLRenderSystem::_convertProjectionMatrix(const Matrix4& matrix,
  1746. Matrix4& dest, bool forGpuProgram)
  1747. {
  1748. // no any conversion request for OpenGL
  1749. dest = matrix;
  1750. }
  1751. void GLRenderSystem::_makeProjectionMatrix(const Radian& fovy, Real aspect, Real nearPlane,
  1752. Real farPlane, Matrix4& dest, bool forGpuProgram)
  1753. {
  1754. Radian thetaY ( fovy / 2.0f );
  1755. Real tanThetaY = Math::Tan(thetaY);
  1756. //Real thetaX = thetaY * aspect;
  1757. //Real tanThetaX = Math::Tan(thetaX);
  1758. // Calc matrix elements
  1759. Real w = (1.0f / tanThetaY) / aspect;
  1760. Real h = 1.0f / tanThetaY;
  1761. Real q, qn;
  1762. if (farPlane == 0)
  1763. {
  1764. // Infinite far plane
  1765. q = Frustum::INFINITE_FAR_PLANE_ADJUST - 1;
  1766. qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 2);
  1767. }
  1768. else
  1769. {
  1770. q = -(farPlane + nearPlane) / (farPlane - nearPlane);
  1771. qn = -2 * (farPlane * nearPlane) / (farPlane - nearPlane);
  1772. }
  1773. // NB This creates Z in range [-1,1]
  1774. //
  1775. // [ w 0 0 0 ]
  1776. // [ 0 h 0 0 ]
  1777. // [ 0 0 q qn ]
  1778. // [ 0 0 -1 0 ]
  1779. dest = Matrix4::ZERO;
  1780. dest[0][0] = w;
  1781. dest[1][1] = h;
  1782. dest[2][2] = q;
  1783. dest[2][3] = qn;
  1784. dest[3][2] = -1;
  1785. }
  1786. void GLRenderSystem::_makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane,
  1787. Real farPlane, Matrix4& dest, bool forGpuProgram)
  1788. {
  1789. Radian thetaY (fovy / 2.0f);
  1790. Real tanThetaY = Math::Tan(thetaY);
  1791. //Real thetaX = thetaY * aspect;
  1792. Real tanThetaX = tanThetaY * aspect; //Math::Tan(thetaX);
  1793. Real half_w = tanThetaX * nearPlane;
  1794. Real half_h = tanThetaY * nearPlane;
  1795. Real iw = 1.0 / half_w;
  1796. Real ih = 1.0 / half_h;
  1797. Real q;
  1798. if (farPlane == 0)
  1799. {
  1800. q = 0;
  1801. }
  1802. else
  1803. {
  1804. q = 2.0 / (farPlane - nearPlane);
  1805. }
  1806. dest = Matrix4::ZERO;
  1807. dest[0][0] = iw;
  1808. dest[1][1] = ih;
  1809. dest[2][2] = -q;
  1810. dest[2][3] = - (farPlane + nearPlane)/(farPlane - nearPlane);
  1811. dest[3][3] = 1;
  1812. }
  1813. void GLRenderSystem::_setPolygonMode(PolygonMode level)
  1814. {
  1815. GLenum glmode;
  1816. switch(level)
  1817. {
  1818. case PM_POINTS:
  1819. glmode = GL_POINT;
  1820. break;
  1821. case PM_WIREFRAME:
  1822. glmode = GL_LINE;
  1823. break;
  1824. default:
  1825. case PM_SOLID:
  1826. glmode = GL_FILL;
  1827. break;
  1828. }
  1829. glPolygonMode(GL_FRONT_AND_BACK, glmode);
  1830. }
  1831. //---------------------------------------------------------------------
  1832. void GLRenderSystem::setStencilCheckEnabled(bool enabled)
  1833. {
  1834. if (enabled)
  1835. {
  1836. glEnable(GL_STENCIL_TEST);
  1837. }
  1838. else
  1839. {
  1840. glDisable(GL_STENCIL_TEST);
  1841. }
  1842. }
  1843. //---------------------------------------------------------------------
  1844. void GLRenderSystem::setStencilBufferParams(CompareFunction func,
  1845. uint32 refValue, uint32 mask, StencilOperation stencilFailOp,
  1846. StencilOperation depthFailOp, StencilOperation passOp,
  1847. bool twoSidedOperation)
  1848. {
  1849. bool flip;
  1850. mStencilMask = mask;
  1851. if (twoSidedOperation)
  1852. {
  1853. if (!mCurrentCapabilities->hasCapability(RSC_TWO_SIDED_STENCIL))
  1854. OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "2-sided stencils are not supported",
  1855. "GLRenderSystem::setStencilBufferParams");
  1856. // NB: We should always treat CCW as front face for consistent with default
  1857. // culling mode. Therefore, we must take care with two-sided stencil settings.
  1858. flip = (mInvertVertexWinding && !mActiveRenderTarget->requiresTextureFlipping()) ||
  1859. (!mInvertVertexWinding && mActiveRenderTarget->requiresTextureFlipping());
  1860. if(GLEW_VERSION_2_0) // New GL2 commands
  1861. {
  1862. // Back
  1863. glStencilMaskSeparate(GL_BACK, mask);
  1864. glStencilFuncSeparate(GL_BACK, convertCompareFunction(func), refValue, mask);
  1865. glStencilOpSeparate(GL_BACK,
  1866. convertStencilOp(stencilFailOp, !flip),
  1867. convertStencilOp(depthFailOp, !flip),
  1868. convertStencilOp(passOp, !flip));
  1869. // Front
  1870. glStencilMaskSeparate(GL_FRONT, mask);
  1871. glStencilFuncSeparate(GL_FRONT, convertCompareFunction(func), refValue, mask);
  1872. glStencilOpSeparate(GL_FRONT,
  1873. convertStencilOp(stencilFailOp, flip),
  1874. convertStencilOp(depthFailOp, flip),
  1875. convertStencilOp(passOp, flip));
  1876. }
  1877. else // EXT_stencil_two_side
  1878. {
  1879. glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  1880. // Back
  1881. glActiveStencilFaceEXT(GL_BACK);
  1882. glStencilMask(mask);
  1883. glStencilFunc(convertCompareFunction(func), refValue, mask);
  1884. glStencilOp(
  1885. convertStencilOp(stencilFailOp, !flip),
  1886. convertStencilOp(depthFailOp, !flip),
  1887. convertStencilOp(passOp, !flip));
  1888. // Front
  1889. glActiveStencilFaceEXT(GL_FRONT);
  1890. glStencilMask(mask);
  1891. glStencilFunc(convertCompareFunction(func), refValue, mask);
  1892. glStencilOp(
  1893. convertStencilOp(stencilFailOp, flip),
  1894. convertStencilOp(depthFailOp, flip),
  1895. convertStencilOp(passOp, flip));
  1896. }
  1897. }
  1898. else
  1899. {
  1900. if(!GLEW_VERSION_2_0)
  1901. glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  1902. flip = false;
  1903. glStencilMask(mask);
  1904. glStencilFunc(convertCompareFunction(func), refValue, mask);
  1905. glStencilOp(
  1906. convertStencilOp(stencilFailOp, flip),
  1907. convertStencilOp(depthFailOp, flip),
  1908. convertStencilOp(passOp, flip));
  1909. }
  1910. }
  1911. //---------------------------------------------------------------------
  1912. GLint GLRenderSystem::convertCompareFunction(CompareFunction func) const
  1913. {
  1914. switch(func)
  1915. {
  1916. case CMPF_ALWAYS_FAIL:
  1917. return GL_NEVER;
  1918. case CMPF_ALWAYS_PASS:
  1919. return GL_ALWAYS;
  1920. case CMPF_LESS:
  1921. return GL_LESS;
  1922. case CMPF_LESS_EQUAL:
  1923. return GL_LEQUAL;
  1924. case CMPF_EQUAL:
  1925. return GL_EQUAL;
  1926. case CMPF_NOT_EQUAL:
  1927. return GL_NOTEQUAL;
  1928. case CMPF_GREATER_EQUAL:
  1929. return GL_GEQUAL;
  1930. case CMPF_GREATER:
  1931. return GL_GREATER;
  1932. };
  1933. // to keep compiler happy
  1934. return GL_ALWAYS;
  1935. }
  1936. //---------------------------------------------------------------------
  1937. GLint GLRenderSystem::convertStencilOp(StencilOperation op, bool invert) const
  1938. {
  1939. switch(op)
  1940. {
  1941. case SOP_KEEP:
  1942. return GL_KEEP;
  1943. case SOP_ZERO:
  1944. return GL_ZERO;
  1945. case SOP_REPLACE:
  1946. return GL_REPLACE;
  1947. case SOP_INCREMENT:
  1948. return invert ? GL_DECR : GL_INCR;
  1949. case SOP_DECREMENT:
  1950. return invert ? GL_INCR : GL_DECR;
  1951. case SOP_INCREMENT_WRAP:
  1952. return invert ? GL_DECR_WRAP_EXT : GL_INCR_WRAP_EXT;
  1953. case SOP_DECREMENT_WRAP:
  1954. return invert ? GL_INCR_WRAP_EXT : GL_DECR_WRAP_EXT;
  1955. case SOP_INVERT:
  1956. return GL_INVERT;
  1957. };
  1958. // to keep compiler happy
  1959. return SOP_KEEP;
  1960. }
  1961. //---------------------------------------------------------------------
  1962. GLuint GLRenderSystem::getCombinedMinMipFilter(void) const
  1963. {
  1964. switch(mMinFilter)
  1965. {
  1966. case FO_ANISOTROPIC:
  1967. case FO_LINEAR:
  1968. switch(mMipFilter)
  1969. {
  1970. case FO_ANISOTROPIC:
  1971. case FO_LINEAR:
  1972. // linear min, linear mip
  1973. return GL_LINEAR_MIPMAP_LINEAR;
  1974. case FO_POINT:
  1975. // linear min, point mip
  1976. return GL_LINEAR_MIPMAP_NEAREST;
  1977. case FO_NONE:
  1978. // linear min, no mip
  1979. return GL_LINEAR;
  1980. }
  1981. break;
  1982. case FO_POINT:
  1983. case FO_NONE:
  1984. switch(mMipFilter)
  1985. {
  1986. case FO_ANISOTROPIC:
  1987. case FO_LINEAR:
  1988. // nearest min, linear mip
  1989. return GL_NEAREST_MIPMAP_LINEAR;
  1990. case FO_POINT:
  1991. // nearest min, point mip
  1992. return GL_NEAREST_MIPMAP_NEAREST;
  1993. case FO_NONE:
  1994. // nearest min, no mip
  1995. return GL_NEAREST;
  1996. }
  1997. break;
  1998. }
  1999. // should never get here
  2000. return 0;
  2001. }
  2002. //---------------------------------------------------------------------
  2003. void GLRenderSystem::_setTextureUnitFiltering(size_t unit,
  2004. FilterType ftype, FilterOptions fo)
  2005. {
  2006. if (!activateGLTextureUnit(unit))
  2007. return;
  2008. switch(ftype)
  2009. {
  2010. case FT_MIN:
  2011. mMinFilter = fo;
  2012. // Combine with existing mip filter
  2013. glTexParameteri(
  2014. mTextureTypes[unit],
  2015. GL_TEXTURE_MIN_FILTER,
  2016. getCombinedMinMipFilter());
  2017. break;
  2018. case FT_MAG:
  2019. switch (fo)
  2020. {
  2021. case FO_ANISOTROPIC: // GL treats linear and aniso the same
  2022. case FO_LINEAR:
  2023. glTexParameteri(
  2024. mTextureTypes[unit],
  2025. GL_TEXTURE_MAG_FILTER,
  2026. GL_LINEAR);
  2027. break;
  2028. case FO_POINT:
  2029. case FO_NONE:
  2030. glTexParameteri(
  2031. mTextureTypes[unit],
  2032. GL_TEXTURE_MAG_FILTER,
  2033. GL_NEAREST);
  2034. break;
  2035. }
  2036. break;
  2037. case FT_MIP:
  2038. mMipFilter = fo;
  2039. // Combine with existing min filter
  2040. glTexParameteri(
  2041. mTextureTypes[unit],
  2042. GL_TEXTURE_MIN_FILTER,
  2043. getCombinedMinMipFilter());
  2044. break;
  2045. }
  2046. activateGLTextureUnit(0);
  2047. }
  2048. //---------------------------------------------------------------------
  2049. GLfloat GLRenderSystem::_getCurrentAnisotropy(size_t unit)
  2050. {
  2051. GLfloat curAniso = 0;
  2052. glGetTexParameterfv(mTextureTypes[unit],
  2053. GL_TEXTURE_MAX_ANISOTROPY_EXT, &curAniso);
  2054. return curAniso ? curAniso : 1;
  2055. }
  2056. //---------------------------------------------------------------------
  2057. void GLRenderSystem::_setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy)
  2058. {
  2059. if (!mCurrentCapabilities->hasCapability(RSC_ANISOTROPY))
  2060. return;
  2061. if (!activateGLTextureUnit(unit))
  2062. return;
  2063. GLfloat largest_supported_anisotropy = 0;
  2064. glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy);
  2065. if (maxAnisotropy > largest_supported_anisotropy)
  2066. maxAnisotropy = largest_supported_anisotropy ?
  2067. static_cast<uint>(largest_supported_anisotropy) : 1;
  2068. if (_getCurrentAnisotropy(unit) != maxAnisotropy)
  2069. glTexParameterf(mTextureTypes[unit], GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy);
  2070. activateGLTextureUnit(0);
  2071. }
  2072. //-----------------------------------------------------------------------------
  2073. void GLRenderSystem::_setTextureBlendMode(size_t stage, const LayerBlendModeEx& bm)
  2074. {
  2075. if (stage >= mFixedFunctionTextureUnits)
  2076. {
  2077. // Can't do this
  2078. return;
  2079. }
  2080. // Check to see if blending is supported
  2081. if(!mCurrentCapabilities->hasCapability(RSC_BLENDING))
  2082. return;
  2083. GLenum src1op, src2op, cmd;
  2084. GLfloat cv1[4], cv2[4];
  2085. if (bm.blendType == LBT_COLOUR)
  2086. {
  2087. cv1[0] = bm.colourArg1.r;
  2088. cv1[1] = bm.colourArg1.g;
  2089. cv1[2] = bm.colourArg1.b;
  2090. cv1[3] = bm.colourArg1.a;
  2091. mManualBlendColours[stage][0] = bm.colourArg1;
  2092. cv2[0] = bm.colourArg2.r;
  2093. cv2[1] = bm.colourArg2.g;
  2094. cv2[2] = bm.colourArg2.b;
  2095. cv2[3] = bm.colourArg2.a;
  2096. mManualBlendColours[stage][1] = bm.colourArg2;
  2097. }
  2098. if (bm.blendType == LBT_ALPHA)
  2099. {
  2100. cv1[0] = mManualBlendColours[stage][0].r;
  2101. cv1[1] = mManualBlendColours[stage][0].g;
  2102. cv1[2] = mManualBlendColours[stage][0].b;
  2103. cv1[3] = bm.alphaArg1;
  2104. cv2[0] = mManualBlendColours[stage][1].r;
  2105. cv2[1] = mManualBlendColours[stage][1].g;
  2106. cv2[2] = mManualBlendColours[stage][1].b;
  2107. cv2[3] = bm.alphaArg2;
  2108. }
  2109. switch (bm.source1)
  2110. {
  2111. case LBS_CURRENT:
  2112. src1op = GL_PREVIOUS;
  2113. break;
  2114. case LBS_TEXTURE:
  2115. src1op = GL_TEXTURE;
  2116. break;
  2117. case LBS_MANUAL:
  2118. src1op = GL_CONSTANT;
  2119. break;
  2120. case LBS_DIFFUSE:
  2121. src1op = GL_PRIMARY_COLOR;
  2122. break;
  2123. // XXX
  2124. case LBS_SPECULAR:
  2125. src1op = GL_PRIMARY_COLOR;
  2126. break;
  2127. default:
  2128. src1op = 0;
  2129. }
  2130. switch (bm.source2)
  2131. {
  2132. case LBS_CURRENT:
  2133. src2op = GL_PREVIOUS;
  2134. break;
  2135. case LBS_TEXTURE:
  2136. src2op = GL_TEXTURE;
  2137. break;
  2138. case LBS_MANUAL:
  2139. src2op = GL_CONSTANT;
  2140. break;
  2141. case LBS_DIFFUSE:
  2142. src2op = GL_PRIMARY_COLOR;
  2143. break;
  2144. // XXX
  2145. case LBS_SPECULAR:
  2146. src2op = GL_PRIMARY_COLOR;
  2147. break;
  2148. default:
  2149. src2op = 0;
  2150. }
  2151. switch (bm.operation)
  2152. {
  2153. case LBX_SOURCE1:
  2154. cmd = GL_REPLACE;
  2155. break;
  2156. case LBX_SOURCE2:
  2157. cmd = GL_REPLACE;
  2158. break;
  2159. case LBX_MODULATE:
  2160. cmd = GL_MODULATE;
  2161. break;
  2162. case LBX_MODULATE_X2:
  2163. cmd = GL_MODULATE;
  2164. break;
  2165. case LBX_MODULATE_X4:
  2166. cmd = GL_MODULATE;
  2167. break;
  2168. case LBX_ADD:
  2169. cmd = GL_ADD;
  2170. break;
  2171. case LBX_ADD_SIGNED:
  2172. cmd = GL_ADD_SIGNED;
  2173. break;
  2174. case LBX_ADD_SMOOTH:
  2175. cmd = GL_INTERPOLATE;
  2176. break;
  2177. case LBX_SUBTRACT:
  2178. cmd = GL_SUBTRACT;
  2179. break;
  2180. case LBX_BLEND_DIFFUSE_COLOUR:
  2181. cmd = GL_INTERPOLATE;
  2182. break;
  2183. case LBX_BLEND_DIFFUSE_ALPHA:
  2184. cmd = GL_INTERPOLATE;
  2185. break;
  2186. case LBX_BLEND_TEXTURE_ALPHA:
  2187. cmd = GL_INTERPOLATE;
  2188. break;
  2189. case LBX_BLEND_CURRENT_ALPHA:
  2190. cmd = GL_INTERPOLATE;
  2191. break;
  2192. case LBX_BLEND_MANUAL:
  2193. cmd = GL_INTERPOLATE;
  2194. break;
  2195. case LBX_DOTPRODUCT:
  2196. cmd = mCurrentCapabilities->hasCapability(RSC_DOT3)
  2197. ? GL_DOT3_RGB : GL_MODULATE;
  2198. break;
  2199. default:
  2200. cmd = 0;
  2201. }
  2202. if (!activateGLTextureUnit(stage))
  2203. return;
  2204. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  2205. if (bm.blendType == LBT_COLOUR)
  2206. {
  2207. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, cmd);
  2208. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, src1op);
  2209. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, src2op);
  2210. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT);
  2211. }
  2212. else
  2213. {
  2214. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, cmd);
  2215. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, src1op);
  2216. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, src2op);
  2217. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_CONSTANT);
  2218. }
  2219. float blendValue[4] = {0, 0, 0, bm.factor};
  2220. switch (bm.operation)
  2221. {
  2222. case LBX_BLEND_DIFFUSE_COLOUR:
  2223. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR);
  2224. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PRIMARY_COLOR);
  2225. break;
  2226. case LBX_BLEND_DIFFUSE_ALPHA:
  2227. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR);
  2228. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PRIMARY_COLOR);
  2229. break;
  2230. case LBX_BLEND_TEXTURE_ALPHA:
  2231. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);
  2232. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_TEXTURE);
  2233. break;
  2234. case LBX_BLEND_CURRENT_ALPHA:
  2235. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PREVIOUS);
  2236. glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PREVIOUS);
  2237. break;
  2238. case LBX_BLEND_MANUAL:
  2239. glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, blendValue);
  2240. break;
  2241. default:
  2242. break;
  2243. };
  2244. switch (bm.operation)
  2245. {
  2246. case LBX_MODULATE_X2:
  2247. glTexEnvi(GL_TEXTURE_ENV, bm.blendType == LBT_COLOUR ?
  2248. GL_RGB_SCALE : GL_ALPHA_SCALE, 2);
  2249. break;
  2250. case LBX_MODULATE_X4:
  2251. glTexEnvi(GL_TEXTURE_ENV, bm.blendType == LBT_COLOUR ?
  2252. GL_RGB_SCALE : GL_ALPHA_SCALE, 4);
  2253. break;
  2254. default:
  2255. glTexEnvi(GL_TEXTURE_ENV, bm.blendType == LBT_COLOUR ?
  2256. GL_RGB_SCALE : GL_ALPHA_SCALE, 1);
  2257. break;
  2258. }
  2259. if (bm.blendType == LBT_COLOUR){
  2260. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
  2261. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
  2262. if (bm.operation == LBX_BLEND_DIFFUSE_COLOUR){
  2263. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
  2264. } else {
  2265. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
  2266. }
  2267. }
  2268. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
  2269. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
  2270. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
  2271. if(bm.source1 == LBS_MANUAL)
  2272. glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, cv1);
  2273. if (bm.source2 == LBS_MANUAL)
  2274. glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, cv2);
  2275. activateGLTextureUnit(0);
  2276. }
  2277. //---------------------------------------------------------------------
  2278. void GLRenderSystem::setVertexDeclaration(VertexDeclaration* decl)
  2279. {
  2280. }
  2281. //---------------------------------------------------------------------
  2282. void GLRenderSystem::setVertexBufferBinding(VertexBufferBinding* binding)
  2283. {
  2284. }
  2285. //---------------------------------------------------------------------
  2286. void GLRenderSystem::_render(const RenderOperation& op)
  2287. {
  2288. // Call super class
  2289. RenderSystem::_render(op);
  2290. void* pBufferData = 0;
  2291. bool multitexturing = (getCapabilities()->getNumTextureUnits() > 1);
  2292. const VertexDeclaration::VertexElementList& decl =
  2293. op.vertexData->vertexDeclaration->getElements();
  2294. VertexDeclaration::VertexElementList::const_iterator elem, elemEnd;
  2295. elemEnd = decl.end();
  2296. vector<GLuint>::type attribsBound;
  2297. for (elem = decl.begin(); elem != elemEnd; ++elem)
  2298. {
  2299. if (!op.vertexData->vertexBufferBinding->isBufferBound(elem->getSource()))
  2300. continue; // skip unbound elements
  2301. HardwareVertexBufferSharedPtr vertexBuffer =
  2302. op.vertexData->vertexBufferBinding->getBuffer(elem->getSource());
  2303. if(mCurrentCapabilities->hasCapability(RSC_VBO))
  2304. {
  2305. glBindBufferARB(GL_ARRAY_BUFFER_ARB,
  2306. static_cast<const GLHardwareVertexBuffer*>(vertexBuffer.get())->getGLBufferId());
  2307. pBufferData = VBO_BUFFER_OFFSET(elem->getOffset());
  2308. }
  2309. else
  2310. {
  2311. pBufferData = static_cast<const GLDefaultHardwareVertexBuffer*>(vertexBuffer.get())->getDataPtr(elem->getOffset());
  2312. }
  2313. if (op.vertexData->vertexStart)
  2314. {
  2315. pBufferData = static_cast<char*>(pBufferData) + op.vertexData->vertexStart * vertexBuffer->getVertexSize();
  2316. }
  2317. unsigned int i = 0;
  2318. VertexElementSemantic sem = elem->getSemantic();
  2319. bool isCustomAttrib = false;
  2320. if (mCurrentVertexProgram)
  2321. isCustomAttrib = mCurrentVertexProgram->isAttributeValid(sem, elem->getIndex());
  2322. // Custom attribute support
  2323. // tangents, binormals, blendweights etc always via this route
  2324. // builtins may be done this way too
  2325. if (isCustomAttrib)
  2326. {
  2327. GLint attrib = mCurrentVertexProgram->getAttributeIndex(sem, elem->getIndex());
  2328. unsigned short typeCount = VertexElement::getTypeCount(elem->getType());
  2329. GLboolean normalised = GL_FALSE;
  2330. switch(elem->getType())
  2331. {
  2332. case VET_COLOUR:
  2333. case VET_COLOUR_ABGR:
  2334. case VET_COLOUR_ARGB:
  2335. // Because GL takes these as a sequence of single unsigned bytes, count needs to be 4
  2336. // VertexElement::getTypeCount treats them as 1 (RGBA)
  2337. // Also need to normalise the fixed-point data
  2338. typeCount = 4;
  2339. normalised = GL_TRUE;
  2340. break;
  2341. default:
  2342. break;
  2343. };
  2344. glVertexAttribPointerARB(
  2345. attrib,
  2346. typeCount,
  2347. GLHardwareBufferManager::getGLType(elem->getType()),
  2348. normalised,
  2349. static_cast<GLsizei>(vertexBuffer->getVertexSize()),
  2350. pBufferData);
  2351. glEnableVertexAttribArrayARB(attrib);
  2352. attribsBound.push_back(attrib);
  2353. }
  2354. else
  2355. {
  2356. // fixed-function & builtin attribute support
  2357. switch(sem)
  2358. {
  2359. case VES_POSITION:
  2360. glVertexPointer(VertexElement::getTypeCount(
  2361. elem->getType()),
  2362. GLHardwareBufferManager::getGLType(elem->getType()),
  2363. static_cast<GLsizei>(vertexBuffer->getVertexSize()),
  2364. pBufferData);
  2365. glEnableClientState( GL_VERTEX_ARRAY );
  2366. break;
  2367. case VES_NORMAL:
  2368. glNormalPointer(
  2369. GLHardwareBufferManager::getGLType(elem->getType()),
  2370. static_cast<GLsizei>(vertexBuffer->getVertexSize()),
  2371. pBufferData);
  2372. glEnableClientState( GL_NORMAL_ARRAY );
  2373. break;
  2374. case VES_DIFFUSE:
  2375. glColorPointer(4,
  2376. GLHardwareBufferManager::getGLType(elem->getType()),
  2377. static_cast<GLsizei>(vertexBuffer->getVertexSize()),
  2378. pBufferData);
  2379. glEnableClientState( GL_COLOR_ARRAY );
  2380. break;
  2381. case VES_SPECULAR:
  2382. if (GLEW_EXT_secondary_color)
  2383. {
  2384. glSecondaryColorPointerEXT(4,
  2385. GLHardwareBufferManager::getGLType(elem->getType()),
  2386. static_cast<GLsizei>(vertexBuffer->getVertexSize()),
  2387. pBufferData);
  2388. glEnableClientState( GL_SECONDARY_COLOR_ARRAY );
  2389. }
  2390. break;
  2391. case VES_TEXTURE_COORDINATES:
  2392. if (mCurrentVertexProgram)
  2393. {
  2394. // Programmable pipeline - direct UV assignment
  2395. glClientActiveTextureARB(GL_TEXTURE0 + elem->getIndex());
  2396. glTexCoordPointer(
  2397. VertexElement::getTypeCount(elem->getType()),
  2398. GLHardwareBufferManager::getGLType(elem->getType()),
  2399. static_cast<GLsizei>(vertexBuffer->getVertexSize()),
  2400. pBufferData);
  2401. glEnableClientState( GL_TEXTURE_COORD_ARRAY );
  2402. }
  2403. else
  2404. {
  2405. // fixed function matching to units based on tex_coord_set
  2406. for (i = 0; i < mDisabledTexUnitsFrom; i++)
  2407. {
  2408. // Only set this texture unit's texcoord pointer if it
  2409. // is supposed to be using this element's index
  2410. if (mTextureCoordIndex[i] == elem->getIndex() && i < mFixedFunctionTextureUnits)
  2411. {
  2412. if (multitexturing)
  2413. glClientActiveTextureARB(GL_TEXTURE0 + i);
  2414. glTexCoordPointer(
  2415. VertexElement::getTypeCount(elem->getType()),
  2416. GLHardwareBufferManager::getGLType(elem->getType()),
  2417. static_cast<GLsizei>(vertexBuffer->getVertexSize()),
  2418. pBufferData);
  2419. glEnableClientState( GL_TEXTURE_COORD_ARRAY );
  2420. }
  2421. }
  2422. }
  2423. break;
  2424. default:
  2425. break;
  2426. };
  2427. } // isCustomAttrib
  2428. }
  2429. if (multitexturing)
  2430. glClientActiveTextureARB(GL_TEXTURE0);
  2431. // Find the correct type to render
  2432. GLint primType;
  2433. //Use adjacency if there is a geometry program and it requested adjacency info
  2434. bool useAdjacency = (mGeometryProgramBound && mCurrentGeometryProgram->isAdjacencyInfoRequired());
  2435. switch (op.operationType)
  2436. {
  2437. case RenderOperation::OT_POINT_LIST:
  2438. primType = GL_POINTS;
  2439. break;
  2440. case RenderOperation::OT_LINE_LIST:
  2441. primType = useAdjacency ? GL_LINES_ADJACENCY_EXT : GL_LINES;
  2442. break;
  2443. case RenderOperation::OT_LINE_STRIP:
  2444. primType = useAdjacency ? GL_LINE_STRIP_ADJACENCY_EXT : GL_LINE_STRIP;
  2445. break;
  2446. default:
  2447. case RenderOperation::OT_TRIANGLE_LIST:
  2448. primType = useAdjacency ? GL_TRIANGLES_ADJACENCY_EXT : GL_TRIANGLES;
  2449. break;
  2450. case RenderOperation::OT_TRIANGLE_STRIP:
  2451. primType = useAdjacency ? GL_TRIANGLE_STRIP_ADJACENCY_EXT : GL_TRIANGLE_STRIP;
  2452. break;
  2453. case RenderOperation::OT_TRIANGLE_FAN:
  2454. primType = GL_TRIANGLE_FAN;
  2455. break;
  2456. }
  2457. if (op.useIndexes)
  2458. {
  2459. if(mCurrentCapabilities->hasCapability(RSC_VBO))
  2460. {
  2461. glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
  2462. static_cast<GLHardwareIndexBuffer*>(
  2463. op.indexData->indexBuffer.get())->getGLBufferId());
  2464. pBufferData = VBO_BUFFER_OFFSET(
  2465. op.indexData->indexStart * op.indexData->indexBuffer->getIndexSize());
  2466. }
  2467. else
  2468. {
  2469. pBufferData = static_cast<GLDefaultHardwareIndexBuffer*>(
  2470. op.indexData->indexBuffer.get())->getDataPtr(
  2471. op.indexData->indexStart * op.indexData->indexBuffer->getIndexSize());
  2472. }
  2473. GLenum indexType = (op.indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
  2474. do
  2475. {
  2476. // Update derived depth bias
  2477. if (mDerivedDepthBias && mCurrentPassIterationNum > 0)
  2478. {
  2479. _setDepthBias(mDerivedDepthBiasBase +
  2480. mDerivedDepthBiasMultiplier * mCurrentPassIterationNum,
  2481. mDerivedDepthBiasSlopeScale);
  2482. }
  2483. glDrawElements(primType, op.indexData->indexCount, indexType, pBufferData);
  2484. } while (updatePassIterationRenderState());
  2485. }
  2486. else
  2487. {
  2488. do
  2489. {
  2490. // Update derived depth bias
  2491. if (mDerivedDepthBias && mCurrentPassIterationNum > 0)
  2492. {
  2493. _setDepthBias(mDerivedDepthBiasBase +
  2494. mDerivedDepthBiasMultiplier * mCurrentPassIterationNum,
  2495. mDerivedDepthBiasSlopeScale);
  2496. }
  2497. glDrawArrays(primType, 0, op.vertexData->vertexCount);
  2498. } while (updatePassIterationRenderState());
  2499. }
  2500. glDisableClientState( GL_VERTEX_ARRAY );
  2501. // only valid up to GL_MAX_TEXTURE_UNITS, which is recorded in mFixedFunctionTextureUnits
  2502. if (multitexturing)
  2503. {
  2504. for (int i = 0; i < mFixedFunctionTextureUnits; i++)
  2505. {
  2506. glClientActiveTextureARB(GL_TEXTURE0 + i);
  2507. glDisableClientState( GL_TEXTURE_COORD_ARRAY );
  2508. }
  2509. glClientActiveTextureARB(GL_TEXTURE0);
  2510. }
  2511. else
  2512. {
  2513. glDisableClientState( GL_TEXTURE_COORD_ARRAY );
  2514. }
  2515. glDisableClientState( GL_NORMAL_ARRAY );
  2516. glDisableClientState( GL_COLOR_ARRAY );
  2517. if (GLEW_EXT_secondary_color)
  2518. {
  2519. glDisableClientState( GL_SECONDARY_COLOR_ARRAY );
  2520. }
  2521. // unbind any custom attributes
  2522. for (vector<GLuint>::type::iterator ai = attribsBound.begin(); ai != attribsBound.end(); ++ai)
  2523. {
  2524. glDisableVertexAttribArrayARB(*ai);
  2525. }
  2526. glColor4f(1,1,1,1);
  2527. if (GLEW_EXT_secondary_color)
  2528. {
  2529. glSecondaryColor3fEXT(0.0f, 0.0f, 0.0f);
  2530. }
  2531. }
  2532. //---------------------------------------------------------------------
  2533. void GLRenderSystem::setNormaliseNormals(bool normalise)
  2534. {
  2535. if (normalise)
  2536. glEnable(GL_NORMALIZE);
  2537. else
  2538. glDisable(GL_NORMALIZE);
  2539. }
  2540. //---------------------------------------------------------------------
  2541. void GLRenderSystem::bindGpuProgram(GpuProgram* prg)
  2542. {
  2543. GLGpuProgram* glprg = static_cast<GLGpuProgram*>(prg);
  2544. // Unbind previous gpu program first.
  2545. //
  2546. // Note:
  2547. // 1. Even if both previous and current are the same object, we can't
  2548. // bypass re-bind completely since the object itself maybe modified.
  2549. // But we can bypass unbind based on the assumption that object
  2550. // internally GL program type shouldn't be changed after it has
  2551. // been created. The behavior of bind to a GL program type twice
  2552. // should be same as unbind and rebind that GL program type, even
  2553. // for difference objects.
  2554. // 2. We also assumed that the program's type (vertex or fragment) should
  2555. // not be changed during it's in using. If not, the following switch
  2556. // statement will confuse GL state completely, and we can't fix it
  2557. // here. To fix this case, we must coding the program implementation
  2558. // itself, if type is changing (during load/unload, etc), and it's inuse,
  2559. // unbind and notify render system to correct for its state.
  2560. //
  2561. switch (glprg->getType())
  2562. {
  2563. case GPT_VERTEX_PROGRAM:
  2564. if (mCurrentVertexProgram != glprg)
  2565. {
  2566. if (mCurrentVertexProgram)
  2567. mCurrentVertexProgram->unbindProgram();
  2568. mCurrentVertexProgram = glprg;
  2569. }
  2570. break;
  2571. case GPT_FRAGMENT_PROGRAM:
  2572. if (mCurrentFragmentProgram != glprg)
  2573. {
  2574. if (mCurrentFragmentProgram)
  2575. mCurrentFragmentProgram->unbindProgram();
  2576. mCurrentFragmentProgram = glprg;
  2577. }
  2578. break;
  2579. case GPT_GEOMETRY_PROGRAM:
  2580. if (mCurrentGeometryProgram != glprg)
  2581. {
  2582. if (mCurrentGeometryProgram)
  2583. mCurrentGeometryProgram->unbindProgram();
  2584. mCurrentGeometryProgram = glprg;
  2585. }
  2586. break;
  2587. }
  2588. // Bind the program
  2589. glprg->bindProgram();
  2590. RenderSystem::bindGpuProgram(prg);
  2591. }
  2592. //---------------------------------------------------------------------
  2593. void GLRenderSystem::unbindGpuProgram(GpuProgramType gptype)
  2594. {
  2595. if (gptype == GPT_VERTEX_PROGRAM && mCurrentVertexProgram)
  2596. {
  2597. mActiveVertexGpuProgramParameters.setNull();
  2598. mCurrentVertexProgram->unbindProgram();
  2599. mCurrentVertexProgram = 0;
  2600. }
  2601. else if (gptype == GPT_GEOMETRY_PROGRAM && mCurrentGeometryProgram)
  2602. {
  2603. mActiveGeometryGpuProgramParameters.setNull();
  2604. mCurrentGeometryProgram->unbindProgram();
  2605. mCurrentGeometryProgram = 0;
  2606. }
  2607. else if (gptype == GPT_FRAGMENT_PROGRAM && mCurrentFragmentProgram)
  2608. {
  2609. mActiveFragmentGpuProgramParameters.setNull();
  2610. mCurrentFragmentProgram->unbindProgram();
  2611. mCurrentFragmentProgram = 0;
  2612. }
  2613. RenderSystem::unbindGpuProgram(gptype);
  2614. }
  2615. //---------------------------------------------------------------------
  2616. void GLRenderSystem::bindGpuProgramParameters(GpuProgramType gptype, GpuProgramParametersSharedPtr params, uint16 mask)
  2617. {
  2618. if (mask & (uint16)GPV_GLOBAL)
  2619. {
  2620. // We could maybe use GL_EXT_bindable_uniform here to produce Dx10-style
  2621. // shared constant buffers, but GPU support seems fairly weak?
  2622. // for now, just copy
  2623. params->_copySharedParams();
  2624. }
  2625. switch (gptype)
  2626. {
  2627. case GPT_VERTEX_PROGRAM:
  2628. mActiveVertexGpuProgramParameters = params;
  2629. mCurrentVertexProgram->bindProgramParameters(params, mask);
  2630. break;
  2631. case GPT_GEOMETRY_PROGRAM:
  2632. mActiveGeometryGpuProgramParameters = params;
  2633. mCurrentGeometryProgram->bindProgramParameters(params, mask);
  2634. break;
  2635. case GPT_FRAGMENT_PROGRAM:
  2636. mActiveFragmentGpuProgramParameters = params;
  2637. mCurrentFragmentProgram->bindProgramParameters(params, mask);
  2638. break;
  2639. }
  2640. }
  2641. //---------------------------------------------------------------------
  2642. void GLRenderSystem::bindGpuProgramPassIterationParameters(GpuProgramType gptype)
  2643. {
  2644. switch (gptype)
  2645. {
  2646. case GPT_VERTEX_PROGRAM:
  2647. mCurrentVertexProgram->bindProgramPassIterationParameters(mActiveVertexGpuProgramParameters);
  2648. break;
  2649. case GPT_GEOMETRY_PROGRAM:
  2650. mCurrentGeometryProgram->bindProgramPassIterationParameters(mActiveGeometryGpuProgramParameters);
  2651. break;
  2652. case GPT_FRAGMENT_PROGRAM:
  2653. mCurrentFragmentProgram->bindProgramPassIterationParameters(mActiveFragmentGpuProgramParameters);
  2654. break;
  2655. }
  2656. }
  2657. //---------------------------------------------------------------------
  2658. void GLRenderSystem::setClipPlanesImpl(const PlaneList& clipPlanes)
  2659. {
  2660. // A note on GL user clipping:
  2661. // When an ARB vertex program is enabled in GL, user clipping is completely
  2662. // disabled. There is no way around this, it's just turned off.
  2663. // When using GLSL, user clipping can work but you have to include a
  2664. // glClipVertex command in your vertex shader.
  2665. // Thus the planes set here may not actually be respected.
  2666. size_t i = 0;
  2667. size_t numClipPlanes;
  2668. GLdouble clipPlane[4];
  2669. // Save previous modelview
  2670. glMatrixMode(GL_MODELVIEW);
  2671. glPushMatrix();
  2672. // just load view matrix (identity world)
  2673. GLfloat mat[16];
  2674. makeGLMatrix(mat, mViewMatrix);
  2675. glLoadMatrixf(mat);
  2676. numClipPlanes = clipPlanes.size();
  2677. for (i = 0; i < numClipPlanes; ++i)
  2678. {
  2679. GLenum clipPlaneId = static_cast<GLenum>(GL_CLIP_PLANE0 + i);
  2680. const Plane& plane = clipPlanes[i];
  2681. if (i >= 6/*GL_MAX_CLIP_PLANES*/)
  2682. {
  2683. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set clip plane",
  2684. "GLRenderSystem::setClipPlanes");
  2685. }
  2686. clipPlane[0] = plane.normal.x;
  2687. clipPlane[1] = plane.normal.y;
  2688. clipPlane[2] = plane.normal.z;
  2689. clipPlane[3] = plane.d;
  2690. glClipPlane(clipPlaneId, clipPlane);
  2691. glEnable(clipPlaneId);
  2692. }
  2693. // disable remaining clip planes
  2694. for ( ; i < 6/*GL_MAX_CLIP_PLANES*/; ++i)
  2695. {
  2696. glDisable(static_cast<GLenum>(GL_CLIP_PLANE0 + i));
  2697. }
  2698. // restore matrices
  2699. glPopMatrix();
  2700. }
  2701. //---------------------------------------------------------------------
  2702. void GLRenderSystem::setScissorTest(bool enabled, size_t left,
  2703. size_t top, size_t right, size_t bottom)
  2704. {
  2705. // If request texture flipping, use "upper-left", otherwise use "lower-left"
  2706. bool flipping = mActiveRenderTarget->requiresTextureFlipping();
  2707. // GL measures from the bottom, not the top
  2708. size_t targetHeight = mActiveRenderTarget->getHeight();
  2709. // Calculate the "lower-left" corner of the viewport
  2710. GLsizei x = 0, y = 0, w = 0, h = 0;
  2711. if (enabled)
  2712. {
  2713. glEnable(GL_SCISSOR_TEST);
  2714. // NB GL uses width / height rather than right / bottom
  2715. x = left;
  2716. if (flipping)
  2717. y = top;
  2718. else
  2719. y = targetHeight - bottom;
  2720. w = right - left;
  2721. h = bottom - top;
  2722. glScissor(x, y, w, h);
  2723. }
  2724. else
  2725. {
  2726. glDisable(GL_SCISSOR_TEST);
  2727. // GL requires you to reset the scissor when disabling
  2728. w = mActiveViewport->getActualWidth();
  2729. h = mActiveViewport->getActualHeight();
  2730. x = mActiveViewport->getActualLeft();
  2731. if (flipping)
  2732. y = mActiveViewport->getActualTop();
  2733. else
  2734. y = targetHeight - mActiveViewport->getActualTop() - h;
  2735. glScissor(x, y, w, h);
  2736. }
  2737. }
  2738. //---------------------------------------------------------------------
  2739. void GLRenderSystem::clearFrameBuffer(unsigned int buffers,
  2740. const ColourValue& colour, Real depth, unsigned short stencil)
  2741. {
  2742. bool colourMask = !mColourWrite[0] || !mColourWrite[1]
  2743. || !mColourWrite[2] || !mColourWrite[3];
  2744. GLbitfield flags = 0;
  2745. if (buffers & FBT_COLOUR)
  2746. {
  2747. flags |= GL_COLOR_BUFFER_BIT;
  2748. // Enable buffer for writing if it isn't
  2749. if (colourMask)
  2750. {
  2751. glColorMask(true, true, true, true);
  2752. }
  2753. glClearColor(colour.r, colour.g, colour.b, colour.a);
  2754. }
  2755. if (buffers & FBT_DEPTH)
  2756. {
  2757. flags |= GL_DEPTH_BUFFER_BIT;
  2758. // Enable buffer for writing if it isn't
  2759. if (!mDepthWrite)
  2760. {
  2761. glDepthMask( GL_TRUE );
  2762. }
  2763. glClearDepth(depth);
  2764. }
  2765. if (buffers & FBT_STENCIL)
  2766. {
  2767. flags |= GL_STENCIL_BUFFER_BIT;
  2768. // Enable buffer for writing if it isn't
  2769. glStencilMask(0xFFFFFFFF);
  2770. glClearStencil(stencil);
  2771. }
  2772. // Should be enable scissor test due the clear region is
  2773. // relied on scissor box bounds.
  2774. GLboolean scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);
  2775. if (!scissorTestEnabled)
  2776. {
  2777. glEnable(GL_SCISSOR_TEST);
  2778. }
  2779. // Sets the scissor box as same as viewport
  2780. GLint viewport[4] = { 0, 0, 0, 0 };
  2781. GLint scissor[4] = { 0, 0, 0, 0 };
  2782. glGetIntegerv(GL_VIEWPORT, viewport);
  2783. glGetIntegerv(GL_SCISSOR_BOX, scissor);
  2784. bool scissorBoxDifference =
  2785. viewport[0] != scissor[0] || viewport[1] != scissor[1] ||
  2786. viewport[2] != scissor[2] || viewport[3] != scissor[3];
  2787. if (scissorBoxDifference)
  2788. {
  2789. glScissor(viewport[0], viewport[1], viewport[2], viewport[3]);
  2790. }
  2791. // Clear buffers
  2792. glClear(flags);
  2793. // Restore scissor box
  2794. if (scissorBoxDifference)
  2795. {
  2796. glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
  2797. }
  2798. // Restore scissor test
  2799. if (!scissorTestEnabled)
  2800. {
  2801. glDisable(GL_SCISSOR_TEST);
  2802. }
  2803. // Reset buffer write state
  2804. if (!mDepthWrite && (buffers & FBT_DEPTH))
  2805. {
  2806. glDepthMask( GL_FALSE );
  2807. }
  2808. if (colourMask && (buffers & FBT_COLOUR))
  2809. {
  2810. glColorMask(mColourWrite[0], mColourWrite[1], mColourWrite[2], mColourWrite[3]);
  2811. }
  2812. if (buffers & FBT_STENCIL)
  2813. {
  2814. glStencilMask(mStencilMask);
  2815. }
  2816. }
  2817. // ------------------------------------------------------------------
  2818. void GLRenderSystem::_makeProjectionMatrix(Real left, Real right,
  2819. Real bottom, Real top, Real nearPlane, Real farPlane, Matrix4& dest,
  2820. bool forGpuProgram)
  2821. {
  2822. Real width = right - left;
  2823. Real height = top - bottom;
  2824. Real q, qn;
  2825. if (farPlane == 0)
  2826. {
  2827. // Infinite far plane
  2828. q = Frustum::INFINITE_FAR_PLANE_ADJUST - 1;
  2829. qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 2);
  2830. }
  2831. else
  2832. {
  2833. q = -(farPlane + nearPlane) / (farPlane - nearPlane);
  2834. qn = -2 * (farPlane * nearPlane) / (farPlane - nearPlane);
  2835. }
  2836. dest = Matrix4::ZERO;
  2837. dest[0][0] = 2 * nearPlane / width;
  2838. dest[0][2] = (right+left) / width;
  2839. dest[1][1] = 2 * nearPlane / height;
  2840. dest[1][2] = (top+bottom) / height;
  2841. dest[2][2] = q;
  2842. dest[2][3] = qn;
  2843. dest[3][2] = -1;
  2844. }
  2845. //---------------------------------------------------------------------
  2846. HardwareOcclusionQuery* GLRenderSystem::createHardwareOcclusionQuery(void)
  2847. {
  2848. GLHardwareOcclusionQuery* ret = new GLHardwareOcclusionQuery();
  2849. mHwOcclusionQueries.push_back(ret);
  2850. return ret;
  2851. }
  2852. //---------------------------------------------------------------------
  2853. Real GLRenderSystem::getHorizontalTexelOffset(void)
  2854. {
  2855. // No offset in GL
  2856. return 0.0f;
  2857. }
  2858. //---------------------------------------------------------------------
  2859. Real GLRenderSystem::getVerticalTexelOffset(void)
  2860. {
  2861. // No offset in GL
  2862. return 0.0f;
  2863. }
  2864. //---------------------------------------------------------------------
  2865. void GLRenderSystem::_applyObliqueDepthProjection(Matrix4& matrix, const Plane& plane,
  2866. bool forGpuProgram)
  2867. {
  2868. // Thanks to Eric Lenyel for posting this calculation at www.terathon.com
  2869. // Calculate the clip-space corner point opposite the clipping plane
  2870. // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
  2871. // transform it into camera space by multiplying it
  2872. // by the inverse of the projection matrix
  2873. Vector4 q;
  2874. q.x = (Math::Sign(plane.normal.x) + matrix[0][2]) / matrix[0][0];
  2875. q.y = (Math::Sign(plane.normal.y) + matrix[1][2]) / matrix[1][1];
  2876. q.z = -1.0F;
  2877. q.w = (1.0F + matrix[2][2]) / matrix[2][3];
  2878. // Calculate the scaled plane vector
  2879. Vector4 clipPlane4d(plane.normal.x, plane.normal.y, plane.normal.z, plane.d);
  2880. Vector4 c = clipPlane4d * (2.0F / (clipPlane4d.dotProduct(q)));
  2881. // Replace the third row of the projection matrix
  2882. matrix[2][0] = c.x;
  2883. matrix[2][1] = c.y;
  2884. matrix[2][2] = c.z + 1.0F;
  2885. matrix[2][3] = c.w;
  2886. }
  2887. //---------------------------------------------------------------------
  2888. void GLRenderSystem::_oneTimeContextInitialization()
  2889. {
  2890. if (GLEW_VERSION_1_2)
  2891. {
  2892. // Set nicer lighting model -- d3d9 has this by default
  2893. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
  2894. glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
  2895. }
  2896. if (GLEW_VERSION_1_4)
  2897. {
  2898. glEnable(GL_COLOR_SUM);
  2899. glDisable(GL_DITHER);
  2900. }
  2901. // Check for FSAA
  2902. // Enable the extension if it was enabled by the GLSupport
  2903. if (mGLSupport->checkExtension("GL_ARB_multisample"))
  2904. {
  2905. int fsaa_active = false;
  2906. glGetIntegerv(GL_SAMPLE_BUFFERS_ARB,(GLint*)&fsaa_active);
  2907. if(fsaa_active)
  2908. {
  2909. glEnable(GL_MULTISAMPLE_ARB);
  2910. }
  2911. }
  2912. }
  2913. //---------------------------------------------------------------------
  2914. void GLRenderSystem::_switchContext(GLContext *context)
  2915. {
  2916. // Unbind GPU programs and rebind to new context later, because
  2917. // scene manager treat render system as ONE 'context' ONLY, and it
  2918. // cached the GPU programs using state.
  2919. if (mCurrentVertexProgram)
  2920. mCurrentVertexProgram->unbindProgram();
  2921. if (mCurrentGeometryProgram)
  2922. mCurrentGeometryProgram->unbindProgram();
  2923. if (mCurrentFragmentProgram)
  2924. mCurrentFragmentProgram->unbindProgram();
  2925. // Disable lights
  2926. for (unsigned short i = 0; i < mCurrentLights; ++i)
  2927. {
  2928. mLights[i] = NULL;
  2929. }
  2930. mCurrentLights = 0;
  2931. // Disable textures
  2932. _disableTextureUnitsFrom(0);
  2933. // It's ready for switching
  2934. if (mCurrentContext)
  2935. mCurrentContext->endCurrent();
  2936. mCurrentContext = context;
  2937. mCurrentContext->setCurrent();
  2938. // Check if the context has already done one-time initialisation
  2939. if(!mCurrentContext->getInitialized())
  2940. {
  2941. _oneTimeContextInitialization();
  2942. mCurrentContext->setInitialized();
  2943. }
  2944. // Rebind GPU programs to new context
  2945. if (mCurrentVertexProgram)
  2946. mCurrentVertexProgram->bindProgram();
  2947. if (mCurrentGeometryProgram)
  2948. mCurrentGeometryProgram->bindProgram();
  2949. if (mCurrentFragmentProgram)
  2950. mCurrentFragmentProgram->bindProgram();
  2951. // Must reset depth/colour write mask to according with user desired, otherwise,
  2952. // clearFrameBuffer would be wrong because the value we are recorded may be
  2953. // difference with the really state stored in GL context.
  2954. glDepthMask(mDepthWrite);
  2955. glColorMask(mColourWrite[0], mColourWrite[1], mColourWrite[2], mColourWrite[3]);
  2956. glStencilMask(mStencilMask);
  2957. }
  2958. //---------------------------------------------------------------------
  2959. void GLRenderSystem::_setRenderTarget(RenderTarget *target)
  2960. {
  2961. // Unbind frame buffer object
  2962. if(mActiveRenderTarget)
  2963. mRTTManager->unbind(mActiveRenderTarget);
  2964. mActiveRenderTarget = target;
  2965. // Switch context if different from current one
  2966. GLContext *newContext = 0;
  2967. target->getCustomAttribute("GLCONTEXT", &newContext);
  2968. if(newContext && mCurrentContext != newContext)
  2969. {
  2970. _switchContext(newContext);
  2971. }
  2972. // Bind frame buffer object
  2973. mRTTManager->bind(target);
  2974. if (GLEW_EXT_framebuffer_sRGB)
  2975. {
  2976. // Enable / disable sRGB states
  2977. if (target->isHardwareGammaEnabled())
  2978. {
  2979. glEnable(GL_FRAMEBUFFER_SRGB_EXT);
  2980. // Note: could test GL_FRAMEBUFFER_SRGB_CAPABLE_EXT here before
  2981. // enabling, but GL spec says incapable surfaces ignore the setting
  2982. // anyway. We test the capability to enable isHardwareGammaEnabled.
  2983. }
  2984. else
  2985. {
  2986. glDisable(GL_FRAMEBUFFER_SRGB_EXT);
  2987. }
  2988. }
  2989. }
  2990. //---------------------------------------------------------------------
  2991. void GLRenderSystem::_unregisterContext(GLContext *context)
  2992. {
  2993. if(mCurrentContext == context) {
  2994. // Change the context to something else so that a valid context
  2995. // remains active. When this is the main context being unregistered,
  2996. // we set the main context to 0.
  2997. if(mCurrentContext != mMainContext) {
  2998. _switchContext(mMainContext);
  2999. } else {
  3000. /// No contexts remain
  3001. mCurrentContext->endCurrent();
  3002. mCurrentContext = 0;
  3003. mMainContext = 0;
  3004. }
  3005. }
  3006. }
  3007. //---------------------------------------------------------------------
  3008. Real GLRenderSystem::getMinimumDepthInputValue(void)
  3009. {
  3010. // Range [-1.0f, 1.0f]
  3011. return -1.0f;
  3012. }
  3013. //---------------------------------------------------------------------
  3014. Real GLRenderSystem::getMaximumDepthInputValue(void)
  3015. {
  3016. // Range [-1.0f, 1.0f]
  3017. return 1.0f;
  3018. }
  3019. //---------------------------------------------------------------------
  3020. void GLRenderSystem::registerThread()
  3021. {
  3022. OGRE_LOCK_MUTEX(mThreadInitMutex)
  3023. // This is only valid once we've created the main context
  3024. if (!mMainContext)
  3025. {
  3026. OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
  3027. "Cannot register a background thread before the main context "
  3028. "has been created.",
  3029. "GLRenderSystem::registerThread");
  3030. }
  3031. // Create a new context for this thread. Cloning from the main context
  3032. // will ensure that resources are shared with the main context
  3033. // We want a separate context so that we can safely create GL
  3034. // objects in parallel with the main thread
  3035. GLContext* newContext = mMainContext->clone();
  3036. mBackgroundContextList.push_back(newContext);
  3037. // Bind this new context to this thread.
  3038. newContext->setCurrent();
  3039. _oneTimeContextInitialization();
  3040. newContext->setInitialized();
  3041. }
  3042. //---------------------------------------------------------------------
  3043. void GLRenderSystem::unregisterThread()
  3044. {
  3045. // nothing to do here?
  3046. // Don't need to worry about active context, just make sure we delete
  3047. // on shutdown.
  3048. }
  3049. //---------------------------------------------------------------------
  3050. void GLRenderSystem::preExtraThreadsStarted()
  3051. {
  3052. OGRE_LOCK_MUTEX(mThreadInitMutex)
  3053. // free context, we'll need this to share lists
  3054. mCurrentContext->endCurrent();
  3055. }
  3056. //---------------------------------------------------------------------
  3057. void GLRenderSystem::postExtraThreadsStarted()
  3058. {
  3059. OGRE_LOCK_MUTEX(mThreadInitMutex)
  3060. // reacquire context
  3061. mCurrentContext->setCurrent();
  3062. }
  3063. //---------------------------------------------------------------------
  3064. bool GLRenderSystem::activateGLTextureUnit(size_t unit)
  3065. {
  3066. if (mActiveTextureUnit != unit)
  3067. {
  3068. if (GLEW_VERSION_1_2 && unit < getCapabilities()->getNumTextureUnits())
  3069. {
  3070. glActiveTextureARB(GL_TEXTURE0 + unit);
  3071. mActiveTextureUnit = unit;
  3072. return true;
  3073. }
  3074. else if (!unit)
  3075. {
  3076. // always ok to use the first unit
  3077. return true;
  3078. }
  3079. else
  3080. {
  3081. return false;
  3082. }
  3083. }
  3084. else
  3085. {
  3086. return true;
  3087. }
  3088. }
  3089. //---------------------------------------------------------------------
  3090. unsigned int GLRenderSystem::getDisplayMonitorCount() const
  3091. {
  3092. return mGLSupport->getDisplayMonitorCount();
  3093. }
  3094. }