CmGLRenderSystem.cpp 76 KB

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