CmGLRenderSystem.cpp 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358
  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 "CmGLRenderSystem.h"
  25. #include "CmRenderSystem.h"
  26. #include "CmCamera.h"
  27. #include "CmGLTextureManager.h"
  28. #include "CmGLHardwareVertexBuffer.h"
  29. #include "CmGLHardwareIndexBuffer.h"
  30. #include "CmGLDefaultHardwareBufferManager.h"
  31. #include "CmGLUtil.h"
  32. #include "CmGLGpuProgram.h"
  33. #include "CmGLSLGpuProgram.h"
  34. #include "CmGLSLProgram.h"
  35. #include "CmGLGpuProgramManager.h"
  36. #include "CmException.h"
  37. #include "CmGLSLExtSupport.h"
  38. #include "CmGLHardwareOcclusionQuery.h"
  39. #include "CmGLContext.h"
  40. #include "CmAsyncOp.h"
  41. #include "CmBlendState.h"
  42. #include "CmRasterizerState.h"
  43. #include "CmDepthStencilState.h"
  44. #include "CmGLRenderTexture.h"
  45. #include "CmGLRenderWindowManager.h"
  46. #include "CmGpuParams.h"
  47. #include "CmDebug.h"
  48. #if CM_DEBUG_MODE
  49. #define THROW_IF_NOT_RENDER_THREAD throwIfNotRenderThread();
  50. #else
  51. #define THROW_IF_NOT_RENDER_THREAD
  52. #endif
  53. // Convenience macro from ARB_vertex_buffer_object spec
  54. #define VBO_BUFFER_OFFSET(i) ((char *)NULL + (i))
  55. #if CM_THREAD_SUPPORT != 1
  56. GLenum glewContextInit (CamelotEngine::GLSupport *glSupport);
  57. #endif
  58. namespace CamelotEngine
  59. {
  60. /************************************************************************/
  61. /* PUBLIC INTERFACE */
  62. /************************************************************************/
  63. GLRenderSystem::GLRenderSystem()
  64. : mDepthWrite(true),
  65. mGLSLProgramFactory(0),
  66. mCgProgramFactory(0),
  67. mActiveTextureUnit(0),
  68. mScissorTop(0), mScissorBottom(720), mScissorLeft(0), mScissorRight(1280),
  69. mStencilReadMask(0xFFFFFFFF),
  70. mStencilWriteMask(0xFFFFFFFF),
  71. mStencilCompareFront(CMPF_ALWAYS_PASS),
  72. mStencilCompareBack(CMPF_ALWAYS_PASS),
  73. mStencilRefValue(0),
  74. mFragmentTexOffset(0),
  75. mVertexTexOffset(0),
  76. mGeometryTexOffset(0),
  77. mTextureTypes(nullptr)
  78. {
  79. size_t i;
  80. // Get our GLSupport
  81. mGLSupport = CamelotEngine::getGLSupport();
  82. mViewMatrix = Matrix4::IDENTITY;
  83. mColourWrite[0] = mColourWrite[1] = mColourWrite[2] = mColourWrite[3] = true;
  84. mActiveRenderTarget = 0;
  85. mCurrentContext = 0;
  86. mMainContext = 0;
  87. mGLInitialised = false;
  88. mMinFilter = FO_LINEAR;
  89. mMipFilter = FO_POINT;
  90. mCurrentVertexProgram = nullptr;
  91. mCurrentGeometryProgram = nullptr;
  92. mCurrentFragmentProgram = nullptr;
  93. mCurrentHullProgram = nullptr;
  94. mCurrentDomainProgram = nullptr;
  95. }
  96. GLRenderSystem::~GLRenderSystem()
  97. {
  98. destroy_internal();
  99. // Destroy render windows
  100. for (auto i = mRenderTargets.begin(); i != mRenderTargets.end(); ++i)
  101. {
  102. delete *i;
  103. }
  104. mRenderTargets.clear();
  105. if(mGLSupport)
  106. delete mGLSupport;
  107. }
  108. const String& GLRenderSystem::getName(void) const
  109. {
  110. static String strName("GLRenderSystem");
  111. return strName;
  112. }
  113. void GLRenderSystem::initialize_internal()
  114. {
  115. THROW_IF_NOT_RENDER_THREAD;
  116. mGLSupport->start();
  117. RenderWindowManager::startUp(new GLRenderWindowManager(this));
  118. RenderSystem::initialize_internal();
  119. }
  120. void GLRenderSystem::destroy_internal(void)
  121. {
  122. RenderSystem::destroy_internal();
  123. // Deleting the GLSL program factory
  124. if (mGLSLProgramFactory)
  125. {
  126. // Remove from manager safely
  127. HighLevelGpuProgramManager::instance().removeFactory(mGLSLProgramFactory);
  128. delete mGLSLProgramFactory;
  129. mGLSLProgramFactory = 0;
  130. }
  131. // Deleting Cg GLSL program factory
  132. if (mCgProgramFactory)
  133. {
  134. // Remove from manager safely
  135. HighLevelGpuProgramManager::instance().removeFactory(mCgProgramFactory);
  136. delete mCgProgramFactory;
  137. mCgProgramFactory = 0;
  138. }
  139. // Deleting the GPU program manager and hardware buffer manager. Has to be done before the mGLSupport->stop().
  140. GpuProgramManager::shutDown();
  141. HardwareBufferManager::shutDown();
  142. GLRTTManager::shutDown();
  143. // Delete extra threads contexts
  144. for (GLContextList::iterator i = mBackgroundContextList.begin();
  145. i != mBackgroundContextList.end(); ++i)
  146. {
  147. GLContext* pCurContext = *i;
  148. pCurContext->releaseContext();
  149. delete pCurContext;
  150. }
  151. mBackgroundContextList.clear();
  152. mGLSupport->stop();
  153. mStopRendering = true;
  154. TextureManager::shutDown();
  155. RenderWindowManager::shutDown();
  156. // There will be a new initial window and so forth, thus any call to test
  157. // some params will access an invalid pointer, so it is best to reset
  158. // the whole state.
  159. mGLInitialised = 0;
  160. }
  161. //---------------------------------------------------------------------
  162. void GLRenderSystem::bindGpuProgram(GpuProgramHandle prg)
  163. {
  164. THROW_IF_NOT_RENDER_THREAD;
  165. GpuProgram* bindingPrg = prg->getBindingDelegate_internal();
  166. GLSLGpuProgram* glprg = static_cast<GLSLGpuProgram*>(bindingPrg);
  167. // Unbind previous gpu program first.
  168. //
  169. // Note:
  170. // 1. Even if both previous and current are the same object, we can't
  171. // bypass re-bind completely since the object itself maybe modified.
  172. // But we can bypass unbind based on the assumption that object
  173. // internally GL program type shouldn't be changed after it has
  174. // been created. The behavior of bind to a GL program type twice
  175. // should be same as unbind and rebind that GL program type, even
  176. // for difference objects.
  177. // 2. We also assumed that the program's type (vertex or fragment) should
  178. // not be changed during it's in using. If not, the following switch
  179. // statement will confuse GL state completely, and we can't fix it
  180. // here. To fix this case, we must coding the program implementation
  181. // itself, if type is changing (during load/unload, etc), and it's inuse,
  182. // unbind and notify render system to correct for its state.
  183. //
  184. switch (glprg->getType())
  185. {
  186. case GPT_VERTEX_PROGRAM:
  187. if (mCurrentVertexProgram != glprg)
  188. {
  189. unbindGpuProgram(glprg->getType());
  190. mCurrentVertexProgram = glprg;
  191. }
  192. break;
  193. case GPT_FRAGMENT_PROGRAM:
  194. if (mCurrentFragmentProgram != glprg)
  195. {
  196. unbindGpuProgram(glprg->getType());
  197. mCurrentFragmentProgram = glprg;
  198. }
  199. break;
  200. case GPT_GEOMETRY_PROGRAM:
  201. if (mCurrentGeometryProgram != glprg)
  202. {
  203. unbindGpuProgram(glprg->getType());
  204. mCurrentGeometryProgram = glprg;
  205. }
  206. break;
  207. case GPT_DOMAIN_PROGRAM:
  208. if (mCurrentDomainProgram != glprg)
  209. {
  210. unbindGpuProgram(glprg->getType());
  211. mCurrentDomainProgram = glprg;
  212. }
  213. break;
  214. case GPT_HULL_PROGRAM:
  215. if (mCurrentHullProgram != glprg)
  216. {
  217. unbindGpuProgram(glprg->getType());
  218. mCurrentHullProgram = glprg;
  219. }
  220. break;
  221. }
  222. // Bind the program
  223. glprg->bindProgram();
  224. RenderSystem::bindGpuProgram(prg);
  225. }
  226. //---------------------------------------------------------------------
  227. void GLRenderSystem::unbindGpuProgram(GpuProgramType gptype)
  228. {
  229. THROW_IF_NOT_RENDER_THREAD;
  230. if (gptype == GPT_VERTEX_PROGRAM && mCurrentVertexProgram)
  231. {
  232. mActiveVertexGpuProgramParameters = nullptr;
  233. mCurrentVertexProgram->unbindProgram();
  234. mCurrentVertexProgram = 0;
  235. }
  236. else if (gptype == GPT_GEOMETRY_PROGRAM && mCurrentGeometryProgram)
  237. {
  238. mActiveGeometryGpuProgramParameters = nullptr;
  239. mCurrentGeometryProgram->unbindProgram();
  240. mCurrentGeometryProgram = 0;
  241. }
  242. else if (gptype == GPT_FRAGMENT_PROGRAM && mCurrentFragmentProgram)
  243. {
  244. mActiveFragmentGpuProgramParameters = nullptr;
  245. mCurrentFragmentProgram->unbindProgram();
  246. mCurrentFragmentProgram = 0;
  247. }
  248. else if (gptype == GPT_DOMAIN_PROGRAM && mCurrentDomainProgram)
  249. {
  250. mCurrentDomainProgram->unbindProgram();
  251. mCurrentDomainProgram = 0;
  252. }
  253. else if (gptype == GPT_HULL_PROGRAM && mCurrentHullProgram)
  254. {
  255. mCurrentHullProgram->unbindProgram();
  256. mCurrentHullProgram = 0;
  257. }
  258. RenderSystem::unbindGpuProgram(gptype);
  259. }
  260. void GLRenderSystem::bindGpuProgramParameters(GpuProgramType gptype, GpuProgramParametersSharedPtr params, UINT16 mask)
  261. {
  262. THROW_IF_NOT_RENDER_THREAD;
  263. // Set textures
  264. const GpuNamedConstants& consts = params->getConstantDefinitions();
  265. for(auto iter = consts.map.begin(); iter != consts.map.end(); ++iter)
  266. {
  267. const GpuConstantDefinition& def = iter->second;
  268. if(def.variability & mask)
  269. {
  270. if(def.isSampler())
  271. {
  272. TextureHandle curTexture = params->getTexture(def.physicalIndex);
  273. if(!curTexture.isLoaded())
  274. continue;
  275. setTexture(gptype, def.physicalIndex, true, curTexture.getInternalPtr());
  276. SamplerStatePtr samplerState = params->getSamplerState(def.physicalIndex);
  277. if(samplerState == nullptr)
  278. setSamplerState(gptype, def.physicalIndex, SamplerState::getDefault());
  279. else
  280. setSamplerState(gptype, def.physicalIndex, *samplerState);
  281. }
  282. }
  283. }
  284. switch (gptype)
  285. {
  286. case GPT_VERTEX_PROGRAM:
  287. mActiveVertexGpuProgramParameters = params;
  288. mCurrentVertexProgram->bindProgramParameters(params, mask);
  289. break;
  290. case GPT_GEOMETRY_PROGRAM:
  291. mActiveGeometryGpuProgramParameters = params;
  292. mCurrentGeometryProgram->bindProgramParameters(params, mask);
  293. break;
  294. case GPT_FRAGMENT_PROGRAM:
  295. mActiveFragmentGpuProgramParameters = params;
  296. mCurrentFragmentProgram->bindProgramParameters(params, mask);
  297. break;
  298. }
  299. }
  300. //-----------------------------------------------------------------------------
  301. void GLRenderSystem::bindGpuParams(GpuProgramType gptype, GpuParamsPtr params)
  302. {
  303. THROW_IF_NOT_RENDER_THREAD;
  304. params->updateIfDirty();
  305. const GpuParamDesc& paramDesc = params->getParamDesc();
  306. GLSLGpuProgram* activeProgram = getActiveProgram(gptype);
  307. GLuint glProgram = activeProgram->getGLSLProgram()->getGLHandle();
  308. for(auto iter = paramDesc.textures.begin(); iter != paramDesc.textures.end(); ++iter)
  309. {
  310. TextureHandle texture = params->getTexture(iter->second.slot);
  311. if(!texture.isLoaded())
  312. setTexture(gptype, iter->second.slot, false, nullptr);
  313. else
  314. setTexture(gptype, iter->second.slot, true, texture.getInternalPtr());
  315. }
  316. UINT32 texUnit = 0;
  317. for(auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
  318. {
  319. SamplerStatePtr samplerState = params->getSamplerState(iter->second.slot);
  320. if(samplerState == nullptr)
  321. setSamplerState(gptype, iter->second.slot, SamplerState::getDefault());
  322. else
  323. setSamplerState(gptype, iter->second.slot, *samplerState);
  324. glProgramUniform1i(glProgram, iter->second.slot, getGLTextureUnit(gptype, texUnit));
  325. texUnit++;
  326. }
  327. for(auto iter = paramDesc.params.begin(); iter != paramDesc.params.end(); ++iter)
  328. {
  329. const GpuParamMemberDesc& paramDesc = iter->second;
  330. GpuParamBlockPtr paramBlock = params->getParamBlock(paramDesc.paramBlockSlot);
  331. if(paramDesc.paramBlockSlot == 0) // 0 means uniforms are not in a block
  332. {
  333. const UINT8* ptrData = paramBlock->getDataPtr(paramDesc.cpuMemOffset * sizeof(UINT32));
  334. switch(paramDesc.type)
  335. {
  336. case GCT_FLOAT1:
  337. glProgramUniform1fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLfloat*)ptrData);
  338. break;
  339. case GCT_FLOAT2:
  340. glProgramUniform2fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLfloat*)ptrData);
  341. break;
  342. case GCT_FLOAT3:
  343. glProgramUniform3fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLfloat*)ptrData);
  344. break;
  345. case GCT_FLOAT4:
  346. glProgramUniform4fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLfloat*)ptrData);
  347. break;
  348. case GCT_MATRIX_2X2:
  349. glProgramUniformMatrix2fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize,
  350. GL_TRUE, (GLfloat*)ptrData);
  351. break;
  352. case GCT_MATRIX_2X3:
  353. glProgramUniformMatrix2x3fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize,
  354. GL_TRUE, (GLfloat*)ptrData);
  355. break;
  356. case GCT_MATRIX_2X4:
  357. glProgramUniformMatrix2x4fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize,
  358. GL_TRUE, (GLfloat*)ptrData);
  359. break;
  360. case GCT_MATRIX_3X2:
  361. glProgramUniformMatrix3x2fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize,
  362. GL_TRUE, (GLfloat*)ptrData);
  363. break;
  364. case GCT_MATRIX_3X3:
  365. glProgramUniformMatrix3fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize,
  366. GL_TRUE, (GLfloat*)ptrData);
  367. break;
  368. case GCT_MATRIX_3X4:
  369. glProgramUniformMatrix3x4fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize,
  370. GL_TRUE, (GLfloat*)ptrData);
  371. break;
  372. case GCT_MATRIX_4X2:
  373. glProgramUniformMatrix4x2fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize,
  374. GL_TRUE, (GLfloat*)ptrData);
  375. break;
  376. case GCT_MATRIX_4X3:
  377. glProgramUniformMatrix4x3fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize,
  378. GL_TRUE, (GLfloat*)ptrData);
  379. break;
  380. case GCT_MATRIX_4X4:
  381. glProgramUniformMatrix4fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize,
  382. GL_TRUE, (GLfloat*)ptrData);
  383. break;
  384. case GCT_INT1:
  385. glProgramUniform1iv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLint*)ptrData);
  386. break;
  387. case GCT_INT2:
  388. glProgramUniform2iv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLint*)ptrData);
  389. break;
  390. case GCT_INT3:
  391. glProgramUniform3iv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLint*)ptrData);
  392. break;
  393. case GCT_INT4:
  394. glProgramUniform4iv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLint*)ptrData);
  395. break;
  396. case GMT_BOOL:
  397. glProgramUniform1uiv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLuint*)ptrData);
  398. break;
  399. case GCT_UNKNOWN:
  400. break;
  401. }
  402. }
  403. else
  404. {
  405. CM_EXCEPT(NotImplementedException, "Support for uniform blocks not implemented yet");
  406. }
  407. }
  408. }
  409. //-----------------------------------------------------------------------------
  410. void GLRenderSystem::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr)
  411. {
  412. THROW_IF_NOT_RENDER_THREAD;
  413. unit = getGLTextureUnit(gptype, unit);
  414. GLTexturePtr tex = std::static_pointer_cast<GLTexture>(texPtr);
  415. GLenum lastTextureType = mTextureTypes[unit];
  416. if (!activateGLTextureUnit(unit))
  417. return;
  418. if (enabled && tex)
  419. {
  420. mTextureTypes[unit] = tex->getGLTextureTarget();
  421. glBindTexture(mTextureTypes[unit], tex->getGLID());
  422. }
  423. else
  424. {
  425. // TODO - This doesn't actually disable all textures set on this image unit, only the 2D ones
  426. // - If a non-2D sampler is used, the texture will still be displayed
  427. // bind zero texture
  428. glBindTexture(GL_TEXTURE_2D, 0);
  429. }
  430. activateGLTextureUnit(0);
  431. }
  432. //-----------------------------------------------------------------------
  433. void GLRenderSystem::setSamplerState(GpuProgramType gptype, UINT16 unit, const SamplerState& state)
  434. {
  435. THROW_IF_NOT_RENDER_THREAD;
  436. unit = getGLTextureUnit(gptype, unit);
  437. // Set texture layer filtering
  438. setTextureFiltering(unit, FT_MIN, state.getTextureFiltering(FT_MIN));
  439. setTextureFiltering(unit, FT_MAG, state.getTextureFiltering(FT_MAG));
  440. setTextureFiltering(unit, FT_MIP, state.getTextureFiltering(FT_MIP));
  441. // Set texture anisotropy
  442. setTextureAnisotropy(unit, state.getTextureAnisotropy());
  443. // Set mipmap biasing
  444. setTextureMipmapBias(unit, state.getTextureMipmapBias());
  445. // Texture addressing mode
  446. const UVWAddressingMode& uvw = state.getTextureAddressingMode();
  447. setTextureAddressingMode(unit, uvw);
  448. // Set border color
  449. setTextureBorderColor(unit, state.getBorderColor());
  450. }
  451. //-----------------------------------------------------------------------------
  452. void GLRenderSystem::setBlendState(const BlendState& blendState)
  453. {
  454. THROW_IF_NOT_RENDER_THREAD;
  455. // Alpha to coverage
  456. setAlphaToCoverage(blendState.getAlphaToCoverageEnabled());
  457. // Blend states
  458. // DirectX 9 doesn't allow us to specify blend state per render target, so we just use the first one.
  459. if(blendState.getBlendEnabled(0))
  460. {
  461. setSceneBlending(blendState.getSrcBlend(0), blendState.getDstBlend(0), blendState.getAlphaSrcBlend(0), blendState.getAlphaDstBlend(0)
  462. , blendState.getBlendOperation(0), blendState.getAlphaBlendOperation(0));
  463. }
  464. else
  465. {
  466. setSceneBlending(SBF_ONE, SBF_ZERO, SBO_ADD);
  467. }
  468. // Color write mask
  469. UINT8 writeMask = blendState.getRenderTargetWriteMask(0);
  470. setColorBufferWriteEnabled((writeMask & 0x1) != 0, (writeMask & 0x2) != 0, (writeMask & 0x4) != 0, (writeMask & 0x8) != 0);
  471. }
  472. //----------------------------------------------------------------------
  473. void GLRenderSystem::setRasterizerState(const RasterizerState& rasterizerState)
  474. {
  475. THROW_IF_NOT_RENDER_THREAD;
  476. setDepthBias((float)rasterizerState.getDepthBias(), rasterizerState.getSlopeScaledDepthBias());
  477. setCullingMode(rasterizerState.getCullMode());
  478. setPolygonMode(rasterizerState.getPolygonMode());
  479. setScissorTestEnable(rasterizerState.getScissorEnable());
  480. }
  481. //---------------------------------------------------------------------
  482. void GLRenderSystem::setDepthStencilState(const DepthStencilState& depthStencilState)
  483. {
  484. THROW_IF_NOT_RENDER_THREAD;
  485. // Set stencil buffer options
  486. setStencilCheckEnabled(depthStencilState.getStencilEnable());
  487. setStencilBufferOperations(depthStencilState.getStencilFrontFailOp(), depthStencilState.getStencilFrontZFailOp(), depthStencilState.getStencilFrontPassOp(), true);
  488. setStencilBufferFunc(depthStencilState.getStencilFrontCompFunc(), depthStencilState.getStencilReadMask(), true);
  489. setStencilBufferOperations(depthStencilState.getStencilBackFailOp(), depthStencilState.getStencilBackZFailOp(), depthStencilState.getStencilBackPassOp(), false);
  490. setStencilBufferFunc(depthStencilState.getStencilBackCompFunc(), depthStencilState.getStencilReadMask(), false);
  491. setStencilBufferWriteMask(depthStencilState.getStencilWriteMask());
  492. // Set depth buffer options
  493. setDepthBufferCheckEnabled(depthStencilState.getDepthReadEnable());
  494. setDepthBufferWriteEnabled(depthStencilState.getDepthWriteEnable());
  495. setDepthBufferFunction(depthStencilState.getDepthComparisonFunc());
  496. }
  497. //---------------------------------------------------------------------
  498. void GLRenderSystem::setStencilRefValue(UINT32 refValue)
  499. {
  500. THROW_IF_NOT_RENDER_THREAD;
  501. mStencilRefValue = refValue;
  502. glStencilFuncSeparate(GL_FRONT, convertCompareFunction(mStencilCompareFront), mStencilRefValue, mStencilReadMask);
  503. glStencilFuncSeparate(GL_BACK, convertCompareFunction(mStencilCompareBack), mStencilRefValue, mStencilReadMask);
  504. }
  505. //-----------------------------------------------------------------------------
  506. void GLRenderSystem::setViewport(const Viewport& vp)
  507. {
  508. THROW_IF_NOT_RENDER_THREAD;
  509. RenderTargetPtr target;
  510. target = vp.getTarget();
  511. setRenderTarget(target.get());
  512. mActiveViewport = vp;
  513. GLsizei x, y, w, h;
  514. // Calculate the "lower-left" corner of the viewport
  515. w = vp.getActualWidth();
  516. h = vp.getActualHeight();
  517. x = vp.getActualLeft();
  518. y = vp.getActualTop();
  519. if (!target->requiresTextureFlipping())
  520. {
  521. // Convert "upper-left" corner to "lower-left"
  522. y = target->getHeight() - h - y;
  523. }
  524. glViewport(x, y, w, h);
  525. // Configure the viewport clipping
  526. glScissor(x, y, w, h);
  527. }
  528. //---------------------------------------------------------------------
  529. void GLRenderSystem::setRenderTarget(RenderTarget *target)
  530. {
  531. THROW_IF_NOT_RENDER_THREAD;
  532. mActiveRenderTarget = target;
  533. // Switch context if different from current one
  534. GLContext *newContext = 0;
  535. target->getCustomAttribute("GLCONTEXT", &newContext);
  536. if(newContext && mCurrentContext != newContext)
  537. {
  538. switchContext(newContext);
  539. }
  540. GLFrameBufferObject *fbo = 0;
  541. target->getCustomAttribute("FBO", &fbo);
  542. if(fbo)
  543. fbo->bind();
  544. else
  545. // Old style context (window/pbuffer) or copying render texture
  546. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  547. if (GLEW_EXT_framebuffer_sRGB)
  548. {
  549. // Enable / disable sRGB states
  550. if (target->isHardwareGammaEnabled())
  551. {
  552. glEnable(GL_FRAMEBUFFER_SRGB_EXT);
  553. // Note: could test GL_FRAMEBUFFER_SRGB_CAPABLE_EXT here before
  554. // enabling, but GL spec says incapable surfaces ignore the setting
  555. // anyway. We test the capability to enable isHardwareGammaEnabled.
  556. }
  557. else
  558. {
  559. glDisable(GL_FRAMEBUFFER_SRGB_EXT);
  560. }
  561. }
  562. }
  563. //-----------------------------------------------------------------------------
  564. void GLRenderSystem::beginFrame(void)
  565. {
  566. THROW_IF_NOT_RENDER_THREAD;
  567. // Activate the viewport clipping
  568. glEnable(GL_SCISSOR_TEST);
  569. }
  570. //-----------------------------------------------------------------------------
  571. void GLRenderSystem::endFrame(void)
  572. {
  573. THROW_IF_NOT_RENDER_THREAD;
  574. // Deactivate the viewport clipping.
  575. glDisable(GL_SCISSOR_TEST);
  576. // unbind GPU programs at end of frame
  577. // this is mostly to avoid holding bound programs that might get deleted
  578. // outside via the resource manager
  579. unbindGpuProgram(GPT_VERTEX_PROGRAM);
  580. unbindGpuProgram(GPT_FRAGMENT_PROGRAM);
  581. }
  582. //---------------------------------------------------------------------
  583. void GLRenderSystem::setVertexDeclaration(VertexDeclarationPtr decl)
  584. {
  585. THROW_IF_NOT_RENDER_THREAD;
  586. }
  587. //---------------------------------------------------------------------
  588. void GLRenderSystem::setVertexBufferBinding(VertexBufferBinding* binding)
  589. {
  590. THROW_IF_NOT_RENDER_THREAD;
  591. }
  592. //---------------------------------------------------------------------
  593. void GLRenderSystem::render(const RenderOperation& op)
  594. {
  595. THROW_IF_NOT_RENDER_THREAD;
  596. // Call super class
  597. RenderSystem::render(op);
  598. void* pBufferData = 0;
  599. const VertexDeclaration::VertexElementList& decl =
  600. op.vertexData->vertexDeclaration->getElements();
  601. VertexDeclaration::VertexElementList::const_iterator elem, elemEnd;
  602. elemEnd = decl.end();
  603. vector<GLuint>::type attribsBound;
  604. for (elem = decl.begin(); elem != elemEnd; ++elem)
  605. {
  606. if (!op.vertexData->vertexBufferBinding->isBufferBound(elem->getSource()))
  607. continue; // skip unbound elements
  608. HardwareVertexBufferPtr vertexBuffer =
  609. op.vertexData->vertexBufferBinding->getBuffer(elem->getSource());
  610. if(mCurrentCapabilities->hasCapability(RSC_VBO))
  611. {
  612. glBindBufferARB(GL_ARRAY_BUFFER_ARB,
  613. static_cast<const GLHardwareVertexBuffer*>(vertexBuffer.get())->getGLBufferId());
  614. pBufferData = VBO_BUFFER_OFFSET(elem->getOffset());
  615. }
  616. else
  617. {
  618. pBufferData = static_cast<const GLDefaultHardwareVertexBuffer*>(vertexBuffer.get())->getDataPtr(elem->getOffset());
  619. }
  620. if (op.vertexData->vertexStart)
  621. {
  622. pBufferData = static_cast<char*>(pBufferData) + op.vertexData->vertexStart * vertexBuffer->getVertexSize();
  623. }
  624. unsigned int i = 0;
  625. VertexElementSemantic sem = elem->getSemantic();
  626. bool isCustomAttrib = false;
  627. if (mCurrentVertexProgram)
  628. isCustomAttrib = mCurrentVertexProgram->isAttributeValid(sem, elem->getIndex());
  629. // Custom attribute support
  630. // tangents, binormals, blendweights etc always via this route
  631. // builtins may be done this way too
  632. if (isCustomAttrib)
  633. {
  634. GLint attrib = mCurrentVertexProgram->getAttributeIndex(sem, elem->getIndex());
  635. unsigned short typeCount = VertexElement::getTypeCount(elem->getType());
  636. GLboolean normalised = GL_FALSE;
  637. switch(elem->getType())
  638. {
  639. case VET_COLOR:
  640. case VET_COLOR_ABGR:
  641. case VET_COLOR_ARGB:
  642. // Because GL takes these as a sequence of single unsigned bytes, count needs to be 4
  643. // VertexElement::getTypeCount treats them as 1 (RGBA)
  644. // Also need to normalise the fixed-point data
  645. typeCount = 4;
  646. normalised = GL_TRUE;
  647. break;
  648. default:
  649. break;
  650. };
  651. glVertexAttribPointerARB(
  652. attrib,
  653. typeCount,
  654. GLHardwareBufferManager::getGLType(elem->getType()),
  655. normalised,
  656. static_cast<GLsizei>(vertexBuffer->getVertexSize()),
  657. pBufferData);
  658. glEnableVertexAttribArrayARB(attrib);
  659. attribsBound.push_back(attrib);
  660. }
  661. }
  662. // Find the correct type to render
  663. GLint primType;
  664. //Use adjacency if there is a geometry program and it requested adjacency info
  665. bool useAdjacency = (mGeometryProgramBound && mCurrentGeometryProgram->isAdjacencyInfoRequired());
  666. switch (op.operationType)
  667. {
  668. case RenderOperation::OT_POINT_LIST:
  669. primType = GL_POINTS;
  670. break;
  671. case RenderOperation::OT_LINE_LIST:
  672. primType = useAdjacency ? GL_LINES_ADJACENCY_EXT : GL_LINES;
  673. break;
  674. case RenderOperation::OT_LINE_STRIP:
  675. primType = useAdjacency ? GL_LINE_STRIP_ADJACENCY_EXT : GL_LINE_STRIP;
  676. break;
  677. default:
  678. case RenderOperation::OT_TRIANGLE_LIST:
  679. primType = useAdjacency ? GL_TRIANGLES_ADJACENCY_EXT : GL_TRIANGLES;
  680. break;
  681. case RenderOperation::OT_TRIANGLE_STRIP:
  682. primType = useAdjacency ? GL_TRIANGLE_STRIP_ADJACENCY_EXT : GL_TRIANGLE_STRIP;
  683. break;
  684. case RenderOperation::OT_TRIANGLE_FAN:
  685. primType = GL_TRIANGLE_FAN;
  686. break;
  687. }
  688. if (op.useIndexes)
  689. {
  690. if(mCurrentCapabilities->hasCapability(RSC_VBO))
  691. {
  692. glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
  693. static_cast<GLHardwareIndexBuffer*>(
  694. op.indexData->indexBuffer.get())->getGLBufferId());
  695. pBufferData = VBO_BUFFER_OFFSET(
  696. op.indexData->indexStart * op.indexData->indexBuffer->getIndexSize());
  697. }
  698. else
  699. {
  700. pBufferData = static_cast<GLDefaultHardwareIndexBuffer*>(
  701. op.indexData->indexBuffer.get())->getDataPtr(
  702. op.indexData->indexStart * op.indexData->indexBuffer->getIndexSize());
  703. }
  704. GLenum indexType = (op.indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
  705. glDrawElements(primType, op.indexData->indexCount, indexType, pBufferData);
  706. }
  707. else
  708. {
  709. glDrawArrays(primType, 0, op.vertexData->vertexCount);
  710. }
  711. // unbind any custom attributes
  712. for (vector<GLuint>::type::iterator ai = attribsBound.begin(); ai != attribsBound.end(); ++ai)
  713. {
  714. glDisableVertexAttribArrayARB(*ai);
  715. }
  716. glColor4f(1,1,1,1);
  717. }
  718. //---------------------------------------------------------------------
  719. void GLRenderSystem::setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom)
  720. {
  721. THROW_IF_NOT_RENDER_THREAD;
  722. mScissorTop = top;
  723. mScissorBottom = bottom;
  724. mScissorLeft = left;
  725. mScissorRight = right;
  726. }
  727. //---------------------------------------------------------------------
  728. void GLRenderSystem::clearFrameBuffer(unsigned int buffers,
  729. const Color& colour, float depth, unsigned short stencil)
  730. {
  731. THROW_IF_NOT_RENDER_THREAD;
  732. bool colourMask = !mColourWrite[0] || !mColourWrite[1]
  733. || !mColourWrite[2] || !mColourWrite[3];
  734. GLbitfield flags = 0;
  735. if (buffers & FBT_COLOUR)
  736. {
  737. flags |= GL_COLOR_BUFFER_BIT;
  738. // Enable buffer for writing if it isn't
  739. if (colourMask)
  740. {
  741. glColorMask(true, true, true, true);
  742. }
  743. glClearColor(colour.r, colour.g, colour.b, colour.a);
  744. }
  745. if (buffers & FBT_DEPTH)
  746. {
  747. flags |= GL_DEPTH_BUFFER_BIT;
  748. // Enable buffer for writing if it isn't
  749. if (!mDepthWrite)
  750. {
  751. glDepthMask( GL_TRUE );
  752. }
  753. glClearDepth(depth);
  754. }
  755. if (buffers & FBT_STENCIL)
  756. {
  757. flags |= GL_STENCIL_BUFFER_BIT;
  758. // Enable buffer for writing if it isn't
  759. glStencilMask(0xFFFFFFFF);
  760. glClearStencil(stencil);
  761. }
  762. // Should be enable scissor test due the clear region is
  763. // relied on scissor box bounds.
  764. GLboolean scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);
  765. if (!scissorTestEnabled)
  766. {
  767. glEnable(GL_SCISSOR_TEST);
  768. }
  769. // Sets the scissor box as same as viewport
  770. GLint viewport[4] = { 0, 0, 0, 0 };
  771. GLint scissor[4] = { 0, 0, 0, 0 };
  772. glGetIntegerv(GL_VIEWPORT, viewport);
  773. glGetIntegerv(GL_SCISSOR_BOX, scissor);
  774. bool scissorBoxDifference =
  775. viewport[0] != scissor[0] || viewport[1] != scissor[1] ||
  776. viewport[2] != scissor[2] || viewport[3] != scissor[3];
  777. if (scissorBoxDifference)
  778. {
  779. glScissor(viewport[0], viewport[1], viewport[2], viewport[3]);
  780. }
  781. // Clear buffers
  782. glClear(flags);
  783. // Restore scissor box
  784. if (scissorBoxDifference)
  785. {
  786. glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
  787. }
  788. // Restore scissor test
  789. if (!scissorTestEnabled)
  790. {
  791. glDisable(GL_SCISSOR_TEST);
  792. }
  793. // Reset buffer write state
  794. if (!mDepthWrite && (buffers & FBT_DEPTH))
  795. {
  796. glDepthMask( GL_FALSE );
  797. }
  798. if (colourMask && (buffers & FBT_COLOUR))
  799. {
  800. glColorMask(mColourWrite[0], mColourWrite[1], mColourWrite[2], mColourWrite[3]);
  801. }
  802. if (buffers & FBT_STENCIL)
  803. {
  804. glStencilMask(mStencilWriteMask);
  805. }
  806. }
  807. /************************************************************************/
  808. /* PRIVATE */
  809. /************************************************************************/
  810. //-----------------------------------------------------------------------------
  811. void GLRenderSystem::setTextureAddressingMode(UINT16 stage, const UVWAddressingMode& uvw)
  812. {
  813. if (!activateGLTextureUnit(stage))
  814. return;
  815. glTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_S,
  816. getTextureAddressingMode(uvw.u));
  817. glTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_T,
  818. getTextureAddressingMode(uvw.v));
  819. glTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_R,
  820. getTextureAddressingMode(uvw.w));
  821. activateGLTextureUnit(0);
  822. }
  823. //-----------------------------------------------------------------------------
  824. void GLRenderSystem::setTextureBorderColor(UINT16 stage, const Color& colour)
  825. {
  826. GLfloat border[4] = { colour.r, colour.g, colour.b, colour.a };
  827. if (activateGLTextureUnit(stage))
  828. {
  829. glTexParameterfv( mTextureTypes[stage], GL_TEXTURE_BORDER_COLOR, border);
  830. activateGLTextureUnit(0);
  831. }
  832. }
  833. //-----------------------------------------------------------------------------
  834. void GLRenderSystem::setTextureMipmapBias(UINT16 stage, float bias)
  835. {
  836. if (mCurrentCapabilities->hasCapability(RSC_MIPMAP_LOD_BIAS))
  837. {
  838. if (activateGLTextureUnit(stage))
  839. {
  840. glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, bias);
  841. activateGLTextureUnit(0);
  842. }
  843. }
  844. }
  845. void GLRenderSystem::setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op )
  846. {
  847. GLint sourceBlend = getBlendMode(sourceFactor);
  848. GLint destBlend = getBlendMode(destFactor);
  849. if(sourceFactor == SBF_ONE && destFactor == SBF_ZERO)
  850. {
  851. glDisable(GL_BLEND);
  852. }
  853. else
  854. {
  855. glEnable(GL_BLEND);
  856. glBlendFunc(sourceBlend, destBlend);
  857. }
  858. GLint func = GL_FUNC_ADD;
  859. switch(op)
  860. {
  861. case SBO_ADD:
  862. func = GL_FUNC_ADD;
  863. break;
  864. case SBO_SUBTRACT:
  865. func = GL_FUNC_SUBTRACT;
  866. break;
  867. case SBO_REVERSE_SUBTRACT:
  868. func = GL_FUNC_REVERSE_SUBTRACT;
  869. break;
  870. case SBO_MIN:
  871. func = GL_MIN;
  872. break;
  873. case SBO_MAX:
  874. func = GL_MAX;
  875. break;
  876. }
  877. if(GLEW_VERSION_1_4 || GLEW_ARB_imaging)
  878. {
  879. glBlendEquation(func);
  880. }
  881. else if(GLEW_EXT_blend_minmax && (func == GL_MIN || func == GL_MAX))
  882. {
  883. glBlendEquationEXT(func);
  884. }
  885. }
  886. //-----------------------------------------------------------------------------
  887. void GLRenderSystem::setSceneBlending(
  888. SceneBlendFactor sourceFactor, SceneBlendFactor destFactor,
  889. SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha,
  890. SceneBlendOperation op, SceneBlendOperation alphaOp )
  891. {
  892. GLint sourceBlend = getBlendMode(sourceFactor);
  893. GLint destBlend = getBlendMode(destFactor);
  894. GLint sourceBlendAlpha = getBlendMode(sourceFactorAlpha);
  895. GLint destBlendAlpha = getBlendMode(destFactorAlpha);
  896. if(sourceFactor == SBF_ONE && destFactor == SBF_ZERO &&
  897. sourceFactorAlpha == SBF_ONE && destFactorAlpha == SBF_ZERO)
  898. {
  899. glDisable(GL_BLEND);
  900. }
  901. else
  902. {
  903. glEnable(GL_BLEND);
  904. glBlendFuncSeparate(sourceBlend, destBlend, sourceBlendAlpha, destBlendAlpha);
  905. }
  906. GLint func = GL_FUNC_ADD, alphaFunc = GL_FUNC_ADD;
  907. switch(op)
  908. {
  909. case SBO_ADD:
  910. func = GL_FUNC_ADD;
  911. break;
  912. case SBO_SUBTRACT:
  913. func = GL_FUNC_SUBTRACT;
  914. break;
  915. case SBO_REVERSE_SUBTRACT:
  916. func = GL_FUNC_REVERSE_SUBTRACT;
  917. break;
  918. case SBO_MIN:
  919. func = GL_MIN;
  920. break;
  921. case SBO_MAX:
  922. func = GL_MAX;
  923. break;
  924. }
  925. switch(alphaOp)
  926. {
  927. case SBO_ADD:
  928. alphaFunc = GL_FUNC_ADD;
  929. break;
  930. case SBO_SUBTRACT:
  931. alphaFunc = GL_FUNC_SUBTRACT;
  932. break;
  933. case SBO_REVERSE_SUBTRACT:
  934. alphaFunc = GL_FUNC_REVERSE_SUBTRACT;
  935. break;
  936. case SBO_MIN:
  937. alphaFunc = GL_MIN;
  938. break;
  939. case SBO_MAX:
  940. alphaFunc = GL_MAX;
  941. break;
  942. }
  943. if(GLEW_VERSION_2_0) {
  944. glBlendEquationSeparate(func, alphaFunc);
  945. }
  946. else if(GLEW_EXT_blend_equation_separate) {
  947. glBlendEquationSeparateEXT(func, alphaFunc);
  948. }
  949. }
  950. //-----------------------------------------------------------------------------
  951. void GLRenderSystem::setAlphaTest(CompareFunction func, unsigned char value)
  952. {
  953. if(func == CMPF_ALWAYS_PASS)
  954. {
  955. glDisable(GL_ALPHA_TEST);
  956. }
  957. else
  958. {
  959. glEnable(GL_ALPHA_TEST);
  960. glAlphaFunc(convertCompareFunction(func), value / 255.0f);
  961. }
  962. }
  963. //-----------------------------------------------------------------------------
  964. void GLRenderSystem::setAlphaToCoverage(bool enable)
  965. {
  966. static bool lasta2c = false;
  967. if (enable != lasta2c && getCapabilities()->hasCapability(RSC_ALPHA_TO_COVERAGE))
  968. {
  969. if (enable)
  970. glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
  971. else
  972. glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
  973. lasta2c = enable;
  974. }
  975. }
  976. //---------------------------------------------------------------------
  977. void GLRenderSystem::setScissorTestEnable(bool enable)
  978. {
  979. // If request texture flipping, use "upper-left", otherwise use "lower-left"
  980. bool flipping = mActiveRenderTarget->requiresTextureFlipping();
  981. // GL measures from the bottom, not the top
  982. UINT32 targetHeight = mActiveRenderTarget->getHeight();
  983. // Calculate the "lower-left" corner of the viewport
  984. GLsizei x = 0, y = 0, w = 0, h = 0;
  985. if (enable)
  986. {
  987. glEnable(GL_SCISSOR_TEST);
  988. // GL uses width / height rather than right / bottom
  989. x = mScissorLeft;
  990. if (flipping)
  991. y = mScissorTop;
  992. else
  993. y = targetHeight - mScissorBottom;
  994. w = mScissorRight - mScissorLeft;
  995. h = mScissorBottom - mScissorTop;
  996. glScissor(x, y, w, h);
  997. }
  998. else
  999. {
  1000. glDisable(GL_SCISSOR_TEST);
  1001. // GL requires you to reset the scissor when disabling
  1002. w = mActiveViewport.getActualWidth();
  1003. h = mActiveViewport.getActualHeight();
  1004. x = mActiveViewport.getActualLeft();
  1005. if (flipping)
  1006. y = mActiveViewport.getActualTop();
  1007. else
  1008. y = targetHeight - mActiveViewport.getActualTop() - h;
  1009. glScissor(x, y, w, h);
  1010. }
  1011. }
  1012. //-----------------------------------------------------------------------------
  1013. void GLRenderSystem::setCullingMode(CullingMode mode)
  1014. {
  1015. mCullingMode = mode;
  1016. GLenum cullMode;
  1017. switch( mode )
  1018. {
  1019. case CULL_NONE:
  1020. glDisable( GL_CULL_FACE );
  1021. return;
  1022. default:
  1023. case CULL_CLOCKWISE:
  1024. if (mActiveRenderTarget &&
  1025. ((mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) ||
  1026. (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding)))
  1027. {
  1028. cullMode = GL_FRONT;
  1029. }
  1030. else
  1031. {
  1032. cullMode = GL_BACK;
  1033. }
  1034. break;
  1035. case CULL_ANTICLOCKWISE:
  1036. if (mActiveRenderTarget &&
  1037. ((mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) ||
  1038. (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding)))
  1039. {
  1040. cullMode = GL_BACK;
  1041. }
  1042. else
  1043. {
  1044. cullMode = GL_FRONT;
  1045. }
  1046. break;
  1047. }
  1048. glEnable( GL_CULL_FACE );
  1049. glCullFace( cullMode );
  1050. }
  1051. //-----------------------------------------------------------------------------
  1052. void GLRenderSystem::setDepthBufferParams(bool depthTest, bool depthWrite, CompareFunction depthFunction)
  1053. {
  1054. setDepthBufferCheckEnabled(depthTest);
  1055. setDepthBufferWriteEnabled(depthWrite);
  1056. setDepthBufferFunction(depthFunction);
  1057. }
  1058. //-----------------------------------------------------------------------------
  1059. void GLRenderSystem::setDepthBufferCheckEnabled(bool enabled)
  1060. {
  1061. if (enabled)
  1062. {
  1063. glClearDepth(1.0f);
  1064. glEnable(GL_DEPTH_TEST);
  1065. }
  1066. else
  1067. {
  1068. glDisable(GL_DEPTH_TEST);
  1069. }
  1070. }
  1071. //-----------------------------------------------------------------------------
  1072. void GLRenderSystem::setDepthBufferWriteEnabled(bool enabled)
  1073. {
  1074. GLboolean flag = enabled ? GL_TRUE : GL_FALSE;
  1075. glDepthMask( flag );
  1076. // Store for reference in _beginFrame
  1077. mDepthWrite = enabled;
  1078. }
  1079. //-----------------------------------------------------------------------------
  1080. void GLRenderSystem::setDepthBufferFunction(CompareFunction func)
  1081. {
  1082. glDepthFunc(convertCompareFunction(func));
  1083. }
  1084. //-----------------------------------------------------------------------------
  1085. void GLRenderSystem::setDepthBias(float constantBias, float slopeScaleBias)
  1086. {
  1087. if (constantBias != 0 || slopeScaleBias != 0)
  1088. {
  1089. glEnable(GL_POLYGON_OFFSET_FILL);
  1090. glEnable(GL_POLYGON_OFFSET_POINT);
  1091. glEnable(GL_POLYGON_OFFSET_LINE);
  1092. glPolygonOffset(-slopeScaleBias, -constantBias);
  1093. }
  1094. else
  1095. {
  1096. glDisable(GL_POLYGON_OFFSET_FILL);
  1097. glDisable(GL_POLYGON_OFFSET_POINT);
  1098. glDisable(GL_POLYGON_OFFSET_LINE);
  1099. }
  1100. }
  1101. //-----------------------------------------------------------------------------
  1102. void GLRenderSystem::setColorBufferWriteEnabled(bool red, bool green, bool blue, bool alpha)
  1103. {
  1104. glColorMask(red, green, blue, alpha);
  1105. // record this
  1106. mColourWrite[0] = red;
  1107. mColourWrite[1] = blue;
  1108. mColourWrite[2] = green;
  1109. mColourWrite[3] = alpha;
  1110. }
  1111. //---------------------------------------------------------------------
  1112. void GLRenderSystem::setPolygonMode(PolygonMode level)
  1113. {
  1114. GLenum glmode;
  1115. switch(level)
  1116. {
  1117. case PM_POINTS:
  1118. glmode = GL_POINT;
  1119. break;
  1120. case PM_WIREFRAME:
  1121. glmode = GL_LINE;
  1122. break;
  1123. default:
  1124. case PM_SOLID:
  1125. glmode = GL_FILL;
  1126. break;
  1127. }
  1128. glPolygonMode(GL_FRONT_AND_BACK, glmode);
  1129. }
  1130. //---------------------------------------------------------------------
  1131. void GLRenderSystem::setStencilCheckEnabled(bool enabled)
  1132. {
  1133. if (enabled)
  1134. glEnable(GL_STENCIL_TEST);
  1135. else
  1136. glDisable(GL_STENCIL_TEST);
  1137. }
  1138. //---------------------------------------------------------------------
  1139. void GLRenderSystem::setStencilBufferOperations(StencilOperation stencilFailOp,
  1140. StencilOperation depthFailOp, StencilOperation passOp, bool front)
  1141. {
  1142. if (front)
  1143. {
  1144. glStencilOpSeparate(GL_FRONT,
  1145. convertStencilOp(stencilFailOp, mInvertVertexWinding),
  1146. convertStencilOp(depthFailOp, mInvertVertexWinding),
  1147. convertStencilOp(passOp, mInvertVertexWinding));
  1148. }
  1149. else
  1150. {
  1151. glStencilOpSeparate(GL_BACK,
  1152. convertStencilOp(stencilFailOp, !mInvertVertexWinding),
  1153. convertStencilOp(depthFailOp, !mInvertVertexWinding),
  1154. convertStencilOp(passOp, !mInvertVertexWinding));
  1155. }
  1156. }
  1157. //---------------------------------------------------------------------
  1158. void GLRenderSystem::setStencilBufferFunc(CompareFunction func, UINT32 mask, bool front)
  1159. {
  1160. mStencilReadMask = mask;
  1161. if(front)
  1162. {
  1163. mStencilCompareFront = func;
  1164. glStencilFuncSeparate(GL_FRONT, convertCompareFunction(mStencilCompareFront), mStencilRefValue, mStencilReadMask);
  1165. }
  1166. else
  1167. {
  1168. mStencilCompareBack = func;
  1169. glStencilFuncSeparate(GL_BACK, convertCompareFunction(mStencilCompareBack), mStencilRefValue, mStencilReadMask);
  1170. }
  1171. }
  1172. //---------------------------------------------------------------------
  1173. void GLRenderSystem::setStencilBufferWriteMask(UINT32 mask)
  1174. {
  1175. mStencilWriteMask = mask;
  1176. glStencilMask(mask);
  1177. }
  1178. //---------------------------------------------------------------------
  1179. void GLRenderSystem::setTextureFiltering(UINT16 unit,
  1180. FilterType ftype, FilterOptions fo)
  1181. {
  1182. if (!activateGLTextureUnit(unit))
  1183. return;
  1184. switch(ftype)
  1185. {
  1186. case FT_MIN:
  1187. mMinFilter = fo;
  1188. // Combine with existing mip filter
  1189. glTexParameteri(
  1190. mTextureTypes[unit],
  1191. GL_TEXTURE_MIN_FILTER,
  1192. getCombinedMinMipFilter());
  1193. break;
  1194. case FT_MAG:
  1195. switch (fo)
  1196. {
  1197. case FO_ANISOTROPIC: // GL treats linear and aniso the same
  1198. case FO_LINEAR:
  1199. glTexParameteri(
  1200. mTextureTypes[unit],
  1201. GL_TEXTURE_MAG_FILTER,
  1202. GL_LINEAR);
  1203. break;
  1204. case FO_POINT:
  1205. case FO_NONE:
  1206. glTexParameteri(
  1207. mTextureTypes[unit],
  1208. GL_TEXTURE_MAG_FILTER,
  1209. GL_NEAREST);
  1210. break;
  1211. }
  1212. break;
  1213. case FT_MIP:
  1214. mMipFilter = fo;
  1215. // Combine with existing min filter
  1216. glTexParameteri(
  1217. mTextureTypes[unit],
  1218. GL_TEXTURE_MIN_FILTER,
  1219. getCombinedMinMipFilter());
  1220. break;
  1221. }
  1222. activateGLTextureUnit(0);
  1223. }
  1224. //---------------------------------------------------------------------
  1225. void GLRenderSystem::setTextureAnisotropy(UINT16 unit, unsigned int maxAnisotropy)
  1226. {
  1227. if (!mCurrentCapabilities->hasCapability(RSC_ANISOTROPY))
  1228. return;
  1229. if (!activateGLTextureUnit(unit))
  1230. return;
  1231. GLfloat largest_supported_anisotropy = 0;
  1232. glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy);
  1233. if (maxAnisotropy > largest_supported_anisotropy)
  1234. maxAnisotropy = largest_supported_anisotropy ?
  1235. static_cast<UINT32>(largest_supported_anisotropy) : 1;
  1236. if (_getCurrentAnisotropy(unit) != maxAnisotropy)
  1237. glTexParameterf(mTextureTypes[unit], GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)maxAnisotropy);
  1238. activateGLTextureUnit(0);
  1239. }
  1240. //-----------------------------------------------------------------------------
  1241. void GLRenderSystem::setClipPlanesImpl(const PlaneList& clipPlanes)
  1242. {
  1243. // A note on GL user clipping:
  1244. // When an ARB vertex program is enabled in GL, user clipping is completely
  1245. // disabled. There is no way around this, it's just turned off.
  1246. // When using GLSL, user clipping can work but you have to include a
  1247. // glClipVertex command in your vertex shader.
  1248. // Thus the planes set here may not actually be respected.
  1249. size_t i = 0;
  1250. size_t numClipPlanes;
  1251. GLdouble clipPlane[4];
  1252. // Save previous modelview
  1253. glMatrixMode(GL_MODELVIEW);
  1254. glPushMatrix();
  1255. // just load view matrix (identity world)
  1256. GLfloat mat[16];
  1257. makeGLMatrix(mat, mViewMatrix);
  1258. glLoadMatrixf(mat);
  1259. numClipPlanes = clipPlanes.size();
  1260. for (i = 0; i < numClipPlanes; ++i)
  1261. {
  1262. GLenum clipPlaneId = static_cast<GLenum>(GL_CLIP_PLANE0 + i);
  1263. const Plane& plane = clipPlanes[i];
  1264. if (i >= 6/*GL_MAX_CLIP_PLANES*/)
  1265. {
  1266. CM_EXCEPT(RenderingAPIException, "Unable to set clip plane");
  1267. }
  1268. clipPlane[0] = plane.normal.x;
  1269. clipPlane[1] = plane.normal.y;
  1270. clipPlane[2] = plane.normal.z;
  1271. clipPlane[3] = plane.d;
  1272. glClipPlane(clipPlaneId, clipPlane);
  1273. glEnable(clipPlaneId);
  1274. }
  1275. // disable remaining clip planes
  1276. for ( ; i < 6/*GL_MAX_CLIP_PLANES*/; ++i)
  1277. {
  1278. glDisable(static_cast<GLenum>(GL_CLIP_PLANE0 + i));
  1279. }
  1280. // restore matrices
  1281. glPopMatrix();
  1282. }
  1283. //---------------------------------------------------------------------
  1284. void GLRenderSystem::oneTimeContextInitialization()
  1285. {
  1286. if (GLEW_VERSION_1_2)
  1287. {
  1288. // Set nicer lighting model -- d3d9 has this by default
  1289. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
  1290. glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
  1291. }
  1292. if (GLEW_VERSION_1_4)
  1293. {
  1294. glEnable(GL_COLOR_SUM);
  1295. glDisable(GL_DITHER);
  1296. }
  1297. // Check for FSAA
  1298. // Enable the extension if it was enabled by the GLSupport
  1299. if (mGLSupport->checkExtension("GL_ARB_multisample"))
  1300. {
  1301. int fsaa_active = false;
  1302. glGetIntegerv(GL_SAMPLE_BUFFERS_ARB,(GLint*)&fsaa_active);
  1303. if(fsaa_active)
  1304. {
  1305. glEnable(GL_MULTISAMPLE_ARB);
  1306. }
  1307. }
  1308. }
  1309. //---------------------------------------------------------------------
  1310. void GLRenderSystem::switchContext(GLContext *context)
  1311. {
  1312. // Unbind GPU programs and rebind to new context later, because
  1313. // scene manager treat render system as ONE 'context' ONLY, and it
  1314. // cached the GPU programs using state.
  1315. unbindGpuProgram(GPT_VERTEX_PROGRAM);
  1316. unbindGpuProgram(GPT_FRAGMENT_PROGRAM);
  1317. unbindGpuProgram(GPT_GEOMETRY_PROGRAM);
  1318. unbindGpuProgram(GPT_HULL_PROGRAM);
  1319. unbindGpuProgram(GPT_DOMAIN_PROGRAM);
  1320. // It's ready for switching
  1321. if (mCurrentContext)
  1322. mCurrentContext->endCurrent();
  1323. mCurrentContext = context;
  1324. mCurrentContext->setCurrent();
  1325. // Check if the context has already done one-time initialisation
  1326. if(!mCurrentContext->getInitialized())
  1327. {
  1328. oneTimeContextInitialization();
  1329. mCurrentContext->setInitialized();
  1330. }
  1331. // Rebind GPU programs to new context
  1332. if (mCurrentVertexProgram)
  1333. mCurrentVertexProgram->bindProgram();
  1334. if (mCurrentGeometryProgram)
  1335. mCurrentGeometryProgram->bindProgram();
  1336. if (mCurrentFragmentProgram)
  1337. mCurrentFragmentProgram->bindProgram();
  1338. // Must reset depth/colour write mask to according with user desired, otherwise,
  1339. // clearFrameBuffer would be wrong because the value we are recorded may be
  1340. // difference with the really state stored in GL context.
  1341. glDepthMask(mDepthWrite);
  1342. glColorMask(mColourWrite[0], mColourWrite[1], mColourWrite[2], mColourWrite[3]);
  1343. glStencilMask(mStencilWriteMask);
  1344. }
  1345. //---------------------------------------------------------------------
  1346. void GLRenderSystem::registerContext(GLContext* context)
  1347. {
  1348. if (!mGLInitialised)
  1349. {
  1350. // set up glew and GLSupport
  1351. initialiseContext(context);
  1352. std::vector<CamelotEngine::String> tokens = StringUtil::split(mGLSupport->getGLVersion(), ".");
  1353. if (!tokens.empty())
  1354. {
  1355. mDriverVersion.major = parseInt(tokens[0]);
  1356. if (tokens.size() > 1)
  1357. mDriverVersion.minor = parseInt(tokens[1]);
  1358. if (tokens.size() > 2)
  1359. mDriverVersion.release = parseInt(tokens[2]);
  1360. }
  1361. mDriverVersion.build = 0;
  1362. // Initialise GL after the first window has been created
  1363. // TODO: fire this from emulation options, and don't duplicate float and Current capabilities
  1364. mCurrentCapabilities = createRenderSystemCapabilities();
  1365. initialiseFromRenderSystemCapabilities(mCurrentCapabilities);
  1366. // Initialise the main context
  1367. oneTimeContextInitialization();
  1368. if(mCurrentContext)
  1369. mCurrentContext->setInitialized();
  1370. }
  1371. }
  1372. //---------------------------------------------------------------------
  1373. void GLRenderSystem::unregisterContext(GLContext *context)
  1374. {
  1375. if(mCurrentContext == context) {
  1376. // Change the context to something else so that a valid context
  1377. // remains active. When this is the main context being unregistered,
  1378. // we set the main context to 0.
  1379. if(mCurrentContext != mMainContext) {
  1380. switchContext(mMainContext);
  1381. } else {
  1382. /// No contexts remain
  1383. mCurrentContext->endCurrent();
  1384. mCurrentContext = 0;
  1385. mMainContext = 0;
  1386. }
  1387. }
  1388. }
  1389. //---------------------------------------------------------------------
  1390. bool GLRenderSystem::activateGLTextureUnit(UINT16 unit)
  1391. {
  1392. if (mActiveTextureUnit != unit)
  1393. {
  1394. if (unit < getCapabilities()->getNumCombinedTextureUnits())
  1395. {
  1396. glActiveTexture(GL_TEXTURE0 + unit);
  1397. mActiveTextureUnit = unit;
  1398. return true;
  1399. }
  1400. else if (!unit)
  1401. {
  1402. // always ok to use the first unit
  1403. return true;
  1404. }
  1405. else
  1406. {
  1407. LOGWRN("Provided texture unit index is higher than OpenGL supports. Provided: " + toString(unit) +
  1408. ". Supported range: 0 .. " + toString(getCapabilities()->getNumCombinedTextureUnits() - 1));
  1409. return false;
  1410. }
  1411. }
  1412. else
  1413. {
  1414. return true;
  1415. }
  1416. }
  1417. //---------------------------------------------------------------------
  1418. GLfloat GLRenderSystem::_getCurrentAnisotropy(UINT16 unit)
  1419. {
  1420. GLfloat curAniso = 0;
  1421. glGetTexParameterfv(mTextureTypes[unit],
  1422. GL_TEXTURE_MAX_ANISOTROPY_EXT, &curAniso);
  1423. return curAniso ? curAniso : 1;
  1424. }
  1425. //---------------------------------------------------------------------
  1426. GLuint GLRenderSystem::getCombinedMinMipFilter(void) const
  1427. {
  1428. switch(mMinFilter)
  1429. {
  1430. case FO_ANISOTROPIC:
  1431. case FO_LINEAR:
  1432. switch(mMipFilter)
  1433. {
  1434. case FO_ANISOTROPIC:
  1435. case FO_LINEAR:
  1436. // linear min, linear mip
  1437. return GL_LINEAR_MIPMAP_LINEAR;
  1438. case FO_POINT:
  1439. // linear min, point mip
  1440. return GL_LINEAR_MIPMAP_NEAREST;
  1441. case FO_NONE:
  1442. // linear min, no mip
  1443. return GL_LINEAR;
  1444. }
  1445. break;
  1446. case FO_POINT:
  1447. case FO_NONE:
  1448. switch(mMipFilter)
  1449. {
  1450. case FO_ANISOTROPIC:
  1451. case FO_LINEAR:
  1452. // nearest min, linear mip
  1453. return GL_NEAREST_MIPMAP_LINEAR;
  1454. case FO_POINT:
  1455. // nearest min, point mip
  1456. return GL_NEAREST_MIPMAP_NEAREST;
  1457. case FO_NONE:
  1458. // nearest min, no mip
  1459. return GL_NEAREST;
  1460. }
  1461. break;
  1462. }
  1463. // should never get here
  1464. return 0;
  1465. }
  1466. //---------------------------------------------------------------------
  1467. GLint GLRenderSystem::convertStencilOp(StencilOperation op, bool invert) const
  1468. {
  1469. switch(op)
  1470. {
  1471. case SOP_KEEP:
  1472. return GL_KEEP;
  1473. case SOP_ZERO:
  1474. return GL_ZERO;
  1475. case SOP_REPLACE:
  1476. return GL_REPLACE;
  1477. case SOP_INCREMENT:
  1478. return invert ? GL_DECR : GL_INCR;
  1479. case SOP_DECREMENT:
  1480. return invert ? GL_INCR : GL_DECR;
  1481. case SOP_INCREMENT_WRAP:
  1482. return invert ? GL_DECR_WRAP_EXT : GL_INCR_WRAP_EXT;
  1483. case SOP_DECREMENT_WRAP:
  1484. return invert ? GL_INCR_WRAP_EXT : GL_DECR_WRAP_EXT;
  1485. case SOP_INVERT:
  1486. return GL_INVERT;
  1487. };
  1488. // to keep compiler happy
  1489. return SOP_KEEP;
  1490. }
  1491. //---------------------------------------------------------------------
  1492. GLint GLRenderSystem::convertCompareFunction(CompareFunction func) const
  1493. {
  1494. switch(func)
  1495. {
  1496. case CMPF_ALWAYS_FAIL:
  1497. return GL_NEVER;
  1498. case CMPF_ALWAYS_PASS:
  1499. return GL_ALWAYS;
  1500. case CMPF_LESS:
  1501. return GL_LESS;
  1502. case CMPF_LESS_EQUAL:
  1503. return GL_LEQUAL;
  1504. case CMPF_EQUAL:
  1505. return GL_EQUAL;
  1506. case CMPF_NOT_EQUAL:
  1507. return GL_NOTEQUAL;
  1508. case CMPF_GREATER_EQUAL:
  1509. return GL_GEQUAL;
  1510. case CMPF_GREATER:
  1511. return GL_GREATER;
  1512. };
  1513. // to keep compiler happy
  1514. return GL_ALWAYS;
  1515. }
  1516. //-----------------------------------------------------------------------------
  1517. String GLRenderSystem::getErrorDescription(long errCode) const
  1518. {
  1519. const GLubyte *errString = gluErrorString (errCode);
  1520. return (errString != 0) ? String((const char*) errString) : StringUtil::BLANK;
  1521. }
  1522. //-----------------------------------------------------------------------------
  1523. GLint GLRenderSystem::getBlendMode(SceneBlendFactor blendMode) const
  1524. {
  1525. switch(blendMode)
  1526. {
  1527. case SBF_ONE:
  1528. return GL_ONE;
  1529. case SBF_ZERO:
  1530. return GL_ZERO;
  1531. case SBF_DEST_COLOUR:
  1532. return GL_DST_COLOR;
  1533. case SBF_SOURCE_COLOUR:
  1534. return GL_SRC_COLOR;
  1535. case SBF_ONE_MINUS_DEST_COLOUR:
  1536. return GL_ONE_MINUS_DST_COLOR;
  1537. case SBF_ONE_MINUS_SOURCE_COLOUR:
  1538. return GL_ONE_MINUS_SRC_COLOR;
  1539. case SBF_DEST_ALPHA:
  1540. return GL_DST_ALPHA;
  1541. case SBF_SOURCE_ALPHA:
  1542. return GL_SRC_ALPHA;
  1543. case SBF_ONE_MINUS_DEST_ALPHA:
  1544. return GL_ONE_MINUS_DST_ALPHA;
  1545. case SBF_ONE_MINUS_SOURCE_ALPHA:
  1546. return GL_ONE_MINUS_SRC_ALPHA;
  1547. };
  1548. // to keep compiler happy
  1549. return GL_ONE;
  1550. }
  1551. //-----------------------------------------------------------------------------
  1552. GLint GLRenderSystem::getTextureAddressingMode(
  1553. TextureAddressingMode tam) const
  1554. {
  1555. switch(tam)
  1556. {
  1557. default:
  1558. case TAM_WRAP:
  1559. return GL_REPEAT;
  1560. case TAM_MIRROR:
  1561. return GL_MIRRORED_REPEAT;
  1562. case TAM_CLAMP:
  1563. return GL_CLAMP_TO_EDGE;
  1564. case TAM_BORDER:
  1565. return GL_CLAMP_TO_BORDER;
  1566. }
  1567. }
  1568. //-----------------------------------------------------------------------------
  1569. void GLRenderSystem::makeGLMatrix(GLfloat gl_matrix[16], const Matrix4& m)
  1570. {
  1571. size_t x = 0;
  1572. for (size_t i = 0; i < 4; i++)
  1573. {
  1574. for (size_t j = 0; j < 4; j++)
  1575. {
  1576. gl_matrix[x] = m[j][i];
  1577. x++;
  1578. }
  1579. }
  1580. }
  1581. //-----------------------------------------------------------------------
  1582. void GLRenderSystem::initialiseContext(GLContext* primary)
  1583. {
  1584. // Set main and current context
  1585. mMainContext = primary;
  1586. mCurrentContext = mMainContext;
  1587. // Set primary context as active
  1588. if(mCurrentContext)
  1589. mCurrentContext->setCurrent();
  1590. // Setup GLSupport
  1591. mGLSupport->initialiseExtensions();
  1592. // Get extension function pointers
  1593. #if CM_THREAD_SUPPORT != 1
  1594. glewContextInit(mGLSupport);
  1595. #endif
  1596. }
  1597. void GLRenderSystem::initialiseFromRenderSystemCapabilities(RenderSystemCapabilities* caps)
  1598. {
  1599. if(caps->getRenderSystemName() != getName())
  1600. {
  1601. CM_EXCEPT(InvalidParametersException,
  1602. "Trying to initialize GLRenderSystem from RenderSystemCapabilities that do not support OpenGL");
  1603. }
  1604. // set texture the number of texture units
  1605. mFixedFunctionTextureUnits = caps->getNumTextureUnits();
  1606. //In GL there can be less fixed function texture units than general
  1607. //texture units. Get the minimum of the two.
  1608. if (caps->hasCapability(RSC_FRAGMENT_PROGRAM))
  1609. {
  1610. GLint maxTexCoords = 0;
  1611. glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &maxTexCoords);
  1612. if (mFixedFunctionTextureUnits > maxTexCoords)
  1613. {
  1614. mFixedFunctionTextureUnits = maxTexCoords;
  1615. }
  1616. }
  1617. if(caps->hasCapability(RSC_GL1_5_NOVBO))
  1618. {
  1619. // Assign ARB functions same to GL 1.5 version since
  1620. // interface identical
  1621. glBindBufferARB = glBindBuffer;
  1622. glBufferDataARB = glBufferData;
  1623. glBufferSubDataARB = glBufferSubData;
  1624. glDeleteBuffersARB = glDeleteBuffers;
  1625. glGenBuffersARB = glGenBuffers;
  1626. glGetBufferParameterivARB = glGetBufferParameteriv;
  1627. glGetBufferPointervARB = glGetBufferPointerv;
  1628. glGetBufferSubDataARB = glGetBufferSubData;
  1629. glIsBufferARB = glIsBuffer;
  1630. glMapBufferARB = glMapBuffer;
  1631. glUnmapBufferARB = glUnmapBuffer;
  1632. }
  1633. if(caps->hasCapability(RSC_VBO))
  1634. {
  1635. HardwareBufferManager::startUp(new GLHardwareBufferManager);
  1636. }
  1637. else
  1638. {
  1639. HardwareBufferManager::startUp(new GLDefaultHardwareBufferManager);
  1640. }
  1641. // GPU Program Manager setup
  1642. GpuProgramManager::startUp(new GLGpuProgramManager());
  1643. if(caps->isShaderProfileSupported("glsl"))
  1644. {
  1645. // NFZ - check for GLSL vertex and fragment shader support successful
  1646. mGLSLProgramFactory = new GLSLProgramFactory();
  1647. HighLevelGpuProgramManager::instance().addFactory(mGLSLProgramFactory);
  1648. }
  1649. if(caps->isShaderProfileSupported("cg"))
  1650. {
  1651. // NFZ - check for GLSL vertex and fragment shader support successful
  1652. mCgProgramFactory = new CgProgramFactory();
  1653. HighLevelGpuProgramManager::instance().addFactory(mCgProgramFactory);
  1654. }
  1655. if(caps->hasCapability(RSC_HWOCCLUSION))
  1656. {
  1657. if(caps->hasCapability(RSC_GL1_5_NOHWOCCLUSION))
  1658. {
  1659. // Assign ARB functions same to GL 1.5 version since
  1660. // interface identical
  1661. glBeginQueryARB = glBeginQuery;
  1662. glDeleteQueriesARB = glDeleteQueries;
  1663. glEndQueryARB = glEndQuery;
  1664. glGenQueriesARB = glGenQueries;
  1665. glGetQueryObjectivARB = glGetQueryObjectiv;
  1666. glGetQueryObjectuivARB = glGetQueryObjectuiv;
  1667. glGetQueryivARB = glGetQueryiv;
  1668. glIsQueryARB = glIsQuery;
  1669. }
  1670. }
  1671. // Check for framebuffer object extension
  1672. if(caps->hasCapability(RSC_FBO))
  1673. {
  1674. // Before GL version 2.0, we need to get one of the extensions
  1675. if(caps->hasCapability(RSC_FBO_ARB))
  1676. GLEW_GET_FUN(__glewDrawBuffers) = glDrawBuffersARB;
  1677. else if(caps->hasCapability(RSC_FBO_ATI))
  1678. GLEW_GET_FUN(__glewDrawBuffers) = glDrawBuffersATI;
  1679. if(caps->hasCapability(RSC_HWRENDER_TO_TEXTURE))
  1680. {
  1681. // Create FBO manager
  1682. GLRTTManager::startUp(new GLRTTManager());
  1683. }
  1684. }
  1685. else
  1686. {
  1687. CM_EXCEPT(RenderingAPIException, "GPU doesn't support frame buffer objects. OpenGL versions lower than 3.0 are not supported.");
  1688. }
  1689. mFragmentTexOffset = 0;
  1690. mVertexTexOffset = caps->getNumTextureUnits(GPT_FRAGMENT_PROGRAM);
  1691. mGeometryTexOffset = mVertexTexOffset + caps->getNumTextureUnits(GPT_VERTEX_PROGRAM);
  1692. UINT16 numCombinedTexUnits = caps->getNumCombinedTextureUnits();
  1693. if((mFragmentTexOffset + mVertexTexOffset + mGeometryTexOffset) > numCombinedTexUnits)
  1694. CM_EXCEPT(InternalErrorException, "Number of combined texture units less than the number of individual units!?");
  1695. mTextureTypes = new GLenum[numCombinedTexUnits];
  1696. for(UINT16 i = 0; i < numCombinedTexUnits; i++)
  1697. mTextureTypes[i] = 0;
  1698. /// Create the texture manager
  1699. TextureManager::startUp(new GLTextureManager(*mGLSupport));
  1700. mGLInitialised = true;
  1701. }
  1702. RenderSystemCapabilities* GLRenderSystem::createRenderSystemCapabilities() const
  1703. {
  1704. RenderSystemCapabilities* rsc = new RenderSystemCapabilities();
  1705. rsc->setCategoryRelevant(CAPS_CATEGORY_GL, true);
  1706. rsc->setDriverVersion(mDriverVersion);
  1707. const char* deviceName = (const char*)glGetString(GL_RENDERER);
  1708. const char* vendorName = (const char*)glGetString(GL_VENDOR);
  1709. rsc->setDeviceName(deviceName);
  1710. rsc->setRenderSystemName(getName());
  1711. // determine vendor
  1712. if (strstr(vendorName, "NVIDIA"))
  1713. rsc->setVendor(GPU_NVIDIA);
  1714. else if (strstr(vendorName, "ATI"))
  1715. rsc->setVendor(GPU_ATI);
  1716. else if (strstr(vendorName, "Intel"))
  1717. rsc->setVendor(GPU_INTEL);
  1718. else if (strstr(vendorName, "S3"))
  1719. rsc->setVendor(GPU_S3);
  1720. else if (strstr(vendorName, "Matrox"))
  1721. rsc->setVendor(GPU_MATROX);
  1722. else if (strstr(vendorName, "3DLabs"))
  1723. rsc->setVendor(GPU_3DLABS);
  1724. else if (strstr(vendorName, "SiS"))
  1725. rsc->setVendor(GPU_SIS);
  1726. else
  1727. rsc->setVendor(GPU_UNKNOWN);
  1728. // Supports fixed-function
  1729. rsc->setCapability(RSC_FIXED_FUNCTION);
  1730. // Check for hardware mipmapping support.
  1731. if(GLEW_VERSION_1_4 || GLEW_SGIS_generate_mipmap)
  1732. {
  1733. bool disableAutoMip = false;
  1734. #if CM_PLATFORM == CM_PLATFORM_APPLE || CM_PLATFORM == CM_PLATFORM_LINUX
  1735. // Apple & Linux ATI drivers have faults in hardware mipmap generation
  1736. if (rsc->getVendor() == GPU_ATI)
  1737. disableAutoMip = true;
  1738. #endif
  1739. // The Intel 915G frequently corrupts textures when using hardware mip generation
  1740. // I'm not currently sure how many generations of hardware this affects,
  1741. // so for now, be safe.
  1742. if (rsc->getVendor() == GPU_INTEL)
  1743. disableAutoMip = true;
  1744. // SiS chipsets also seem to have problems with this
  1745. if (rsc->getVendor() == GPU_SIS)
  1746. disableAutoMip = true;
  1747. if (!disableAutoMip)
  1748. rsc->setCapability(RSC_AUTOMIPMAP);
  1749. }
  1750. // Check for blending support
  1751. if(GLEW_VERSION_1_3 ||
  1752. GLEW_ARB_texture_env_combine ||
  1753. GLEW_EXT_texture_env_combine)
  1754. {
  1755. rsc->setCapability(RSC_BLENDING);
  1756. }
  1757. // Check for Anisotropy support
  1758. if(GLEW_EXT_texture_filter_anisotropic)
  1759. {
  1760. rsc->setCapability(RSC_ANISOTROPY);
  1761. }
  1762. // Check for DOT3 support
  1763. if(GLEW_VERSION_1_3 ||
  1764. GLEW_ARB_texture_env_dot3 ||
  1765. GLEW_EXT_texture_env_dot3)
  1766. {
  1767. rsc->setCapability(RSC_DOT3);
  1768. }
  1769. // Check for cube mapping
  1770. if(GLEW_VERSION_1_3 ||
  1771. GLEW_ARB_texture_cube_map ||
  1772. GLEW_EXT_texture_cube_map)
  1773. {
  1774. rsc->setCapability(RSC_CUBEMAPPING);
  1775. }
  1776. // Point sprites
  1777. if (GLEW_VERSION_2_0 || GLEW_ARB_point_sprite)
  1778. {
  1779. rsc->setCapability(RSC_POINT_SPRITES);
  1780. }
  1781. // Check for point parameters
  1782. if (GLEW_VERSION_1_4)
  1783. {
  1784. rsc->setCapability(RSC_POINT_EXTENDED_PARAMETERS);
  1785. }
  1786. if (GLEW_ARB_point_parameters)
  1787. {
  1788. rsc->setCapability(RSC_POINT_EXTENDED_PARAMETERS_ARB);
  1789. }
  1790. if (GLEW_EXT_point_parameters)
  1791. {
  1792. rsc->setCapability(RSC_POINT_EXTENDED_PARAMETERS_EXT);
  1793. }
  1794. // Check for hardware stencil support and set bit depth
  1795. GLint stencil;
  1796. glGetIntegerv(GL_STENCIL_BITS,&stencil);
  1797. if(stencil)
  1798. {
  1799. rsc->setCapability(RSC_HWSTENCIL);
  1800. rsc->setStencilBufferBitDepth(stencil);
  1801. }
  1802. if(GLEW_VERSION_1_5 || GLEW_ARB_vertex_buffer_object)
  1803. {
  1804. if (!GLEW_ARB_vertex_buffer_object)
  1805. {
  1806. rsc->setCapability(RSC_GL1_5_NOVBO);
  1807. }
  1808. rsc->setCapability(RSC_VBO);
  1809. }
  1810. rsc->setCapability(RSC_VERTEX_PROGRAM);
  1811. rsc->setCapability(RSC_FRAGMENT_PROGRAM);
  1812. rsc->addShaderProfile("cg");
  1813. // NFZ - Check if GLSL is supported
  1814. if ( GLEW_VERSION_2_0 ||
  1815. (GLEW_ARB_shading_language_100 &&
  1816. GLEW_ARB_shader_objects &&
  1817. GLEW_ARB_fragment_shader &&
  1818. GLEW_ARB_vertex_shader) )
  1819. {
  1820. rsc->addShaderProfile("glsl");
  1821. }
  1822. // Check if geometry shaders are supported
  1823. if (GLEW_VERSION_2_0 &&
  1824. GLEW_EXT_geometry_shader4)
  1825. {
  1826. rsc->setCapability(RSC_GEOMETRY_PROGRAM);
  1827. rsc->addShaderProfile("nvgp4");
  1828. //Also add the CG profiles
  1829. rsc->addShaderProfile("gpu_gp");
  1830. rsc->addShaderProfile("gp4gp");
  1831. rsc->setGeometryProgramConstantBoolCount(0);
  1832. rsc->setGeometryProgramConstantIntCount(0);
  1833. GLint floatConstantCount = 0;
  1834. glGetIntegerv(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT, &floatConstantCount);
  1835. rsc->setGeometryProgramConstantFloatCount(floatConstantCount);
  1836. GLint maxOutputVertices;
  1837. glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT,&maxOutputVertices);
  1838. rsc->setGeometryProgramNumOutputVertices(maxOutputVertices);
  1839. }
  1840. //Check if render to vertex buffer (transform feedback in OpenGL)
  1841. if (GLEW_VERSION_2_0 &&
  1842. GLEW_NV_transform_feedback)
  1843. {
  1844. rsc->setCapability(RSC_HWRENDER_TO_VERTEX_BUFFER);
  1845. }
  1846. // Check for texture compression
  1847. if(GLEW_VERSION_1_3 || GLEW_ARB_texture_compression)
  1848. {
  1849. rsc->setCapability(RSC_TEXTURE_COMPRESSION);
  1850. // Check for dxt compression
  1851. if(GLEW_EXT_texture_compression_s3tc)
  1852. {
  1853. #if defined(__APPLE__) && defined(__PPC__)
  1854. // Apple on ATI & PPC has errors in DXT
  1855. if (mGLSupport->getGLVendor().find("ATI") == std::string::npos)
  1856. #endif
  1857. rsc->setCapability(RSC_TEXTURE_COMPRESSION_DXT);
  1858. }
  1859. // Check for vtc compression
  1860. if(GLEW_NV_texture_compression_vtc)
  1861. {
  1862. rsc->setCapability(RSC_TEXTURE_COMPRESSION_VTC);
  1863. }
  1864. }
  1865. // Scissor test is standard in GL 1.2 (is it emulated on some cards though?)
  1866. rsc->setCapability(RSC_SCISSOR_TEST);
  1867. // As are user clipping planes
  1868. rsc->setCapability(RSC_USER_CLIP_PLANES);
  1869. // 2-sided stencil?
  1870. if (GLEW_VERSION_2_0 || GLEW_EXT_stencil_two_side)
  1871. {
  1872. rsc->setCapability(RSC_TWO_SIDED_STENCIL);
  1873. }
  1874. // stencil wrapping?
  1875. if (GLEW_VERSION_1_4 || GLEW_EXT_stencil_wrap)
  1876. {
  1877. rsc->setCapability(RSC_STENCIL_WRAP);
  1878. }
  1879. // Check for hardware occlusion support
  1880. if(GLEW_VERSION_1_5 || GLEW_ARB_occlusion_query)
  1881. {
  1882. // Some buggy driver claim that it is GL 1.5 compliant and
  1883. // not support ARB_occlusion_query
  1884. if (!GLEW_ARB_occlusion_query)
  1885. {
  1886. rsc->setCapability(RSC_GL1_5_NOHWOCCLUSION);
  1887. }
  1888. rsc->setCapability(RSC_HWOCCLUSION);
  1889. }
  1890. else if (GLEW_NV_occlusion_query)
  1891. {
  1892. // Support NV extension too for old hardware
  1893. rsc->setCapability(RSC_HWOCCLUSION);
  1894. }
  1895. // UBYTE4 always supported
  1896. rsc->setCapability(RSC_VERTEX_FORMAT_UBYTE4);
  1897. // Infinite far plane always supported
  1898. rsc->setCapability(RSC_INFINITE_FAR_PLANE);
  1899. // Check for non-power-of-2 texture support
  1900. if(GLEW_ARB_texture_non_power_of_two)
  1901. {
  1902. rsc->setCapability(RSC_NON_POWER_OF_2_TEXTURES);
  1903. }
  1904. // Check for Float textures
  1905. if(GLEW_ATI_texture_float || GLEW_ARB_texture_float)
  1906. {
  1907. rsc->setCapability(RSC_TEXTURE_FLOAT);
  1908. }
  1909. // 3D textures should always be supported
  1910. rsc->setCapability(RSC_TEXTURE_3D);
  1911. // Check for framebuffer object extension
  1912. if(GLEW_EXT_framebuffer_object)
  1913. {
  1914. // Probe number of draw buffers
  1915. // Only makes sense with FBO support, so probe here
  1916. if(GLEW_VERSION_2_0 ||
  1917. GLEW_ARB_draw_buffers ||
  1918. GLEW_ATI_draw_buffers)
  1919. {
  1920. GLint buffers;
  1921. glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &buffers);
  1922. rsc->setNumMultiRenderTargets(std::min<int>(buffers, (GLint)CM_MAX_MULTIPLE_RENDER_TARGETS));
  1923. rsc->setCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS);
  1924. if(!GLEW_VERSION_2_0)
  1925. {
  1926. // Before GL version 2.0, we need to get one of the extensions
  1927. if(GLEW_ARB_draw_buffers)
  1928. rsc->setCapability(RSC_FBO_ARB);
  1929. if(GLEW_ATI_draw_buffers)
  1930. rsc->setCapability(RSC_FBO_ATI);
  1931. }
  1932. // Set FBO flag for all 3 'subtypes'
  1933. rsc->setCapability(RSC_FBO);
  1934. }
  1935. rsc->setCapability(RSC_HWRENDER_TO_TEXTURE);
  1936. }
  1937. // Check GLSupport for PBuffer support
  1938. if(mGLSupport->supportsPBuffers())
  1939. {
  1940. // Use PBuffers
  1941. rsc->setCapability(RSC_HWRENDER_TO_TEXTURE);
  1942. rsc->setCapability(RSC_PBUFFER);
  1943. }
  1944. // Point size
  1945. float ps;
  1946. glGetFloatv(GL_POINT_SIZE_MAX, &ps);
  1947. rsc->setMaxPointSize(ps);
  1948. // Max number of fragment shader textures
  1949. GLint units;
  1950. glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &units);
  1951. rsc->setNumTextureUnits(GPT_FRAGMENT_PROGRAM, static_cast<UINT16>(units));
  1952. // Max number of vertex shader textures
  1953. GLint vUnits;
  1954. glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &vUnits);
  1955. rsc->setNumTextureUnits(GPT_VERTEX_PROGRAM, static_cast<UINT16>(vUnits));
  1956. if (vUnits > 0)
  1957. {
  1958. rsc->setCapability(RSC_VERTEX_TEXTURE_FETCH);
  1959. }
  1960. if (mGLSupport->checkExtension("ARB_geometry_shader4"))
  1961. {
  1962. GLint geomUnits;
  1963. glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &geomUnits);
  1964. rsc->setNumTextureUnits(GPT_GEOMETRY_PROGRAM, static_cast<UINT16>(geomUnits));
  1965. }
  1966. if (mGLSupport->checkExtension("ARB_tessellation_shader"))
  1967. {
  1968. rsc->setCapability(RSC_TESSELLATION_PROGRAM);
  1969. }
  1970. if (mGLSupport->checkExtension("ARB_compute_shader")) // Enable once I include GL 4.3
  1971. {
  1972. //rsc->setCapability(RSC_COMPUTE_PROGRAM);
  1973. //GLint computeUnits;
  1974. //glGetIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &computeUnits);
  1975. //rsc->setNumTextureUnits(GPT_COMPUTE_PROGRAM, static_cast<UINT16>(computeUnits));
  1976. }
  1977. GLint combinedTexUnits;
  1978. glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &combinedTexUnits);
  1979. rsc->setNumCombinedTextureUnits(static_cast<UINT16>(combinedTexUnits));
  1980. // Mipmap LOD biasing
  1981. rsc->setCapability(RSC_MIPMAP_LOD_BIAS);
  1982. // Alpha to coverage?
  1983. if (mGLSupport->checkExtension("GL_ARB_multisample"))
  1984. {
  1985. // Alpha to coverage always 'supported' when MSAA is available
  1986. // although card may ignore it if it doesn't specifically support A2C
  1987. rsc->setCapability(RSC_ALPHA_TO_COVERAGE);
  1988. }
  1989. // Advanced blending operations
  1990. if(GLEW_VERSION_2_0)
  1991. {
  1992. rsc->setCapability(RSC_ADVANCED_BLEND_OPERATIONS);
  1993. }
  1994. return rsc;
  1995. }
  1996. //---------------------------------------------------------------------
  1997. UINT32 GLRenderSystem::getGLTextureUnit(GpuProgramType gptype, UINT32 unit)
  1998. {
  1999. if(gptype != GPT_VERTEX_PROGRAM && gptype != GPT_FRAGMENT_PROGRAM && gptype != GPT_GEOMETRY_PROGRAM)
  2000. {
  2001. LOGWRN("OpenGL cannot assign textures to this gpu program type: " + toString(gptype));
  2002. return;
  2003. }
  2004. UINT32 numSupportedUnits = mCurrentCapabilities->getNumTextureUnits(gptype);
  2005. if(unit < 0 || unit >= numSupportedUnits)
  2006. {
  2007. LOGWRN("Invalid texture unit index for the provided stage. Unit index: " + toString(unit) + ". Stage: " +
  2008. toString(gptype) + ". Supported range is 0 .. " + toString(numSupportedUnits - 1));
  2009. }
  2010. switch(gptype)
  2011. {
  2012. case GPT_FRAGMENT_PROGRAM:
  2013. return mFragmentTexOffset + unit;
  2014. case GPT_VERTEX_PROGRAM:
  2015. return mVertexTexOffset + unit;
  2016. case GPT_GEOMETRY_PROGRAM:
  2017. return mGeometryTexOffset + unit;
  2018. default:
  2019. CM_EXCEPT(InternalErrorException, "Invalid program type: " + toString(gptype));
  2020. }
  2021. }
  2022. void GLRenderSystem::setActiveProgram(GpuProgramType gptype, GLSLGpuProgram* program)
  2023. {
  2024. switch (gptype)
  2025. {
  2026. case GPT_VERTEX_PROGRAM:
  2027. mCurrentVertexProgram = program;
  2028. break;
  2029. case GPT_FRAGMENT_PROGRAM:
  2030. mCurrentFragmentProgram = program;
  2031. break;
  2032. case GPT_GEOMETRY_PROGRAM:
  2033. mCurrentGeometryProgram = program;
  2034. break;
  2035. case GPT_DOMAIN_PROGRAM:
  2036. mCurrentDomainProgram = program;
  2037. break;
  2038. case GPT_HULL_PROGRAM:
  2039. mCurrentHullProgram = program;
  2040. break;
  2041. }
  2042. }
  2043. GLSLGpuProgram* GLRenderSystem::getActiveProgram(GpuProgramType gptype) const
  2044. {
  2045. switch (gptype)
  2046. {
  2047. case GPT_VERTEX_PROGRAM:
  2048. return mCurrentVertexProgram;
  2049. break;
  2050. case GPT_FRAGMENT_PROGRAM:
  2051. return mCurrentFragmentProgram;
  2052. break;
  2053. case GPT_GEOMETRY_PROGRAM:
  2054. return mCurrentGeometryProgram;
  2055. break;
  2056. case GPT_DOMAIN_PROGRAM:
  2057. return mCurrentDomainProgram;
  2058. break;
  2059. case GPT_HULL_PROGRAM:
  2060. return mCurrentHullProgram;
  2061. break;
  2062. }
  2063. }
  2064. /************************************************************************/
  2065. /* UTILITY */
  2066. /************************************************************************/
  2067. float GLRenderSystem::getMinimumDepthInputValue(void)
  2068. {
  2069. // Range [-1.0f, 1.0f]
  2070. return -1.0f;
  2071. }
  2072. //---------------------------------------------------------------------
  2073. float GLRenderSystem::getMaximumDepthInputValue(void)
  2074. {
  2075. // Range [-1.0f, 1.0f]
  2076. return 1.0f;
  2077. }
  2078. //---------------------------------------------------------------------
  2079. float GLRenderSystem::getHorizontalTexelOffset(void)
  2080. {
  2081. // No offset in GL
  2082. return 0.0f;
  2083. }
  2084. //---------------------------------------------------------------------
  2085. float GLRenderSystem::getVerticalTexelOffset(void)
  2086. {
  2087. // No offset in GL
  2088. return 0.0f;
  2089. }
  2090. VertexElementType GLRenderSystem::getColorVertexElementType(void) const
  2091. {
  2092. return VET_COLOR_ABGR;
  2093. }
  2094. //---------------------------------------------------------------------
  2095. void GLRenderSystem::convertProjectionMatrix(const Matrix4& matrix,
  2096. Matrix4& dest, bool forGpuProgram)
  2097. {
  2098. // no any conversion request for OpenGL
  2099. dest = matrix;
  2100. }
  2101. }
  2102. #undef THROW_IF_NOT_RENDER_THREAD