renderer_gl.cpp 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593
  1. /*
  2. * Copyright 2011-2012 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #include "bgfx_p.h"
  6. #if (BGFX_CONFIG_RENDERER_OPENGLES2|BGFX_CONFIG_RENDERER_OPENGL)
  7. # include "renderer_gl.h"
  8. # include <bx/timer.h>
  9. # include <bx/uint32_t.h>
  10. #if BGFX_CONFIG_RENDERER_OPENGL
  11. # define glClearDepthf(_depth) glClearDepth(_depth)
  12. #endif // BGFX_CONFIG_RENDERER_OPENGL
  13. namespace bgfx
  14. {
  15. #if BGFX_USE_WGL
  16. PFNWGLGETPROCADDRESSPROC wglGetProcAddress;
  17. PFNWGLMAKECURRENTPROC wglMakeCurrent;
  18. PFNWGLCREATECONTEXTPROC wglCreateContext;
  19. PFNWGLDELETECONTEXTPROC wglDeleteContext;
  20. #endif // BGFX_USE_WGL
  21. #define GL_IMPORT(_optional, _proto, _func) _proto _func
  22. #include "glimports.h"
  23. #undef GL_IMPORT
  24. static void GL_APIENTRY stubVertexAttribDivisor(GLuint /*_index*/, GLuint /*_divisor*/)
  25. {
  26. }
  27. static void GL_APIENTRY stubDrawArraysInstanced(GLenum _mode, GLint _first, GLsizei _count, GLsizei /*_primcount*/)
  28. {
  29. glDrawArrays(_mode, _first, _count);
  30. }
  31. static void GL_APIENTRY stubDrawElementsInstanced(GLenum _mode, GLsizei _count, GLenum _type, const GLvoid* _indices, GLsizei /*_primcount*/)
  32. {
  33. glDrawElements(_mode, _count, _type, _indices);
  34. }
  35. static PFNGLVERTEXATTRIBDIVISORBGFXPROC s_vertexAttribDivisor = stubVertexAttribDivisor;
  36. static PFNGLDRAWARRAYSINSTANCEDBGFXPROC s_drawArraysInstanced = stubDrawArraysInstanced;
  37. static PFNGLDRAWELEMENTSINSTANCEDBGFXPROC s_drawElementsInstanced = stubDrawElementsInstanced;
  38. typedef void (*PostSwapBuffersFn)(uint32_t _width, uint32_t _height);
  39. #if BX_PLATFORM_NACL
  40. void naclSwapCompleteCb(void* _data, int32_t _result);
  41. PP_CompletionCallback naclSwapComplete =
  42. {
  43. naclSwapCompleteCb,
  44. NULL,
  45. PP_COMPLETIONCALLBACK_FLAG_NONE
  46. };
  47. #endif // BX_PLATFORM_NACL
  48. struct RendererContext
  49. {
  50. RendererContext()
  51. : m_dxtSupport(false)
  52. , m_flip(false)
  53. , m_postSwapBuffers(NULL)
  54. , m_hash( (BX_PLATFORM_WINDOWS<<1) | BX_ARCH_64BIT)
  55. #if BX_PLATFORM_NACL
  56. , m_context(0)
  57. , m_instance(0)
  58. , m_instInterface(NULL)
  59. , m_graphicsInterface(NULL)
  60. #elif BGFX_USE_WGL
  61. , m_context(NULL)
  62. , m_hdc(NULL)
  63. #elif BGFX_USE_EGL
  64. , m_context(NULL)
  65. , m_display(NULL)
  66. , m_surface(NULL)
  67. #elif BX_PLATFORM_LINUX
  68. , m_context(0)
  69. , m_window(0)
  70. , m_display(NULL)
  71. #endif // BX_PLATFORM_
  72. {
  73. memset(&m_resolution, 0, sizeof(m_resolution) );
  74. }
  75. void updateResolution(const Resolution& _resolution)
  76. {
  77. if (m_resolution.m_width != _resolution.m_width
  78. || m_resolution.m_height != _resolution.m_height
  79. || m_resolution.m_flags != _resolution.m_flags)
  80. {
  81. m_textVideoMem.resize(false, _resolution.m_width, _resolution.m_height);
  82. m_textVideoMem.clear();
  83. m_resolution = _resolution;
  84. setRenderContextSize(_resolution.m_width, _resolution.m_height);
  85. }
  86. }
  87. void setRenderContextSize(uint32_t _width, uint32_t _height)
  88. {
  89. if (_width != 0
  90. || _height != 0)
  91. {
  92. #if BX_PLATFORM_NACL
  93. if (0 == m_context)
  94. {
  95. BX_TRACE("create context");
  96. int32_t attribs[] =
  97. {
  98. PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
  99. PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 24,
  100. PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 8,
  101. PP_GRAPHICS3DATTRIB_SAMPLES, 0,
  102. PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0,
  103. PP_GRAPHICS3DATTRIB_WIDTH, _width,
  104. PP_GRAPHICS3DATTRIB_HEIGHT, _height,
  105. PP_GRAPHICS3DATTRIB_NONE
  106. };
  107. m_context = m_graphicsInterface->Create(m_instance, 0, attribs);
  108. m_instInterface->BindGraphics(m_instance, m_context);
  109. glSetCurrentContextPPAPI(m_context);
  110. m_graphicsInterface->SwapBuffers(m_context, naclSwapComplete);
  111. #if 0
  112. # define GL_IMPORT(_optional, _proto, _func) \
  113. { \
  114. _func = (_proto)eglGetProcAddress(#_func); \
  115. BGFX_FATAL(_optional || NULL != _func, Fatal::OPENGL_UnableToCreateContext, "Failed to create OpenGL context. eglGetProcAddress(\"%s\")", #_func); \
  116. }
  117. # include "glimports.h"
  118. # undef GL_IMPORT
  119. #endif
  120. }
  121. else
  122. {
  123. m_graphicsInterface->ResizeBuffers(m_context, _width, _height);
  124. }
  125. #elif BGFX_USE_WGL
  126. if (NULL == m_hdc)
  127. {
  128. m_opengl32dll = LoadLibrary("opengl32.dll");
  129. BGFX_FATAL(NULL != m_opengl32dll, Fatal::OPENGL_UnableToCreateContext, "Failed to load opengl32.dll.");
  130. wglGetProcAddress = (PFNWGLGETPROCADDRESSPROC)GetProcAddress(m_opengl32dll, "wglGetProcAddress");
  131. BGFX_FATAL(NULL != wglGetProcAddress, Fatal::OPENGL_UnableToCreateContext, "Failed get wglGetProcAddress.");
  132. wglMakeCurrent = (PFNWGLMAKECURRENTPROC)GetProcAddress(m_opengl32dll, "wglMakeCurrent");
  133. BGFX_FATAL(NULL != wglMakeCurrent, Fatal::OPENGL_UnableToCreateContext, "Failed get wglMakeCurrent.");
  134. wglCreateContext = (PFNWGLCREATECONTEXTPROC)GetProcAddress(m_opengl32dll, "wglCreateContext");
  135. BGFX_FATAL(NULL != wglCreateContext, Fatal::OPENGL_UnableToCreateContext, "Failed get wglCreateContext.");
  136. wglDeleteContext = (PFNWGLDELETECONTEXTPROC)GetProcAddress(m_opengl32dll, "wglDeleteContext");
  137. BGFX_FATAL(NULL != wglDeleteContext, Fatal::OPENGL_UnableToCreateContext, "Failed get wglDeleteContext.");
  138. m_hdc = GetDC(g_bgfxHwnd);
  139. BGFX_FATAL(NULL != m_hdc, Fatal::OPENGL_UnableToCreateContext, "GetDC failed!");
  140. PIXELFORMATDESCRIPTOR pfd;
  141. memset(&pfd, 0, sizeof(pfd) );
  142. pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
  143. pfd.nVersion = 1;
  144. pfd.iPixelType = PFD_TYPE_RGBA;
  145. pfd.cColorBits = 32;
  146. pfd.cAlphaBits = 8;
  147. pfd.cDepthBits = 24;
  148. pfd.cStencilBits = 8;
  149. pfd.iLayerType = PFD_MAIN_PLANE;
  150. int pixelFormat = ChoosePixelFormat(m_hdc, &pfd);
  151. BGFX_FATAL(0 != pixelFormat, Fatal::OPENGL_UnableToCreateContext, "ChoosePixelFormat failed!");
  152. DescribePixelFormat(m_hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
  153. int result;
  154. result = SetPixelFormat(m_hdc, pixelFormat, &pfd);
  155. BGFX_FATAL(0 != result, Fatal::OPENGL_UnableToCreateContext, "SetPixelFormat failed!");
  156. m_context = wglCreateContext(m_hdc);
  157. BGFX_FATAL(NULL != m_context, Fatal::OPENGL_UnableToCreateContext, "wglCreateContext failed!");
  158. result = wglMakeCurrent(m_hdc, m_context);
  159. BGFX_FATAL(0 != result, Fatal::OPENGL_UnableToCreateContext, "wglMakeCurrent failed!");
  160. # define GL_IMPORT(_optional, _proto, _func) \
  161. { \
  162. _func = (_proto)wglGetProcAddress(#_func); \
  163. if (_func == NULL) \
  164. { \
  165. _func = (_proto)GetProcAddress(m_opengl32dll, #_func); \
  166. } \
  167. BGFX_FATAL(_optional || NULL != _func, Fatal::OPENGL_UnableToCreateContext, "Failed to create OpenGL context. wglGetProcAddress(\"%s\")", #_func); \
  168. }
  169. # include "glimports.h"
  170. # undef GL_IMPORT
  171. }
  172. #elif BX_PLATFORM_LINUX
  173. if (0 == m_display)
  174. {
  175. Display* display = XOpenDisplay(0);
  176. XLockDisplay(display);
  177. BGFX_FATAL(display, Fatal::OPENGL_UnableToCreateContext, "Failed to open X display (0).");
  178. int glxMajor, glxMinor;
  179. if (!glXQueryVersion(display, &glxMajor, &glxMinor))
  180. {
  181. BGFX_FATAL(false, Fatal::OPENGL_UnableToCreateContext, "Failed to query GLX version");
  182. }
  183. BGFX_FATAL((glxMajor == 1 && glxMinor >= 3) || glxMajor > 1, Fatal::OPENGL_UnableToCreateContext, "GLX version is not >=1.3 (%d.%d).", glxMajor, glxMinor);
  184. const int glxAttribs[] =
  185. {
  186. GLX_X_RENDERABLE, True,
  187. GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
  188. GLX_RENDER_TYPE, GLX_RGBA_BIT,
  189. GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
  190. GLX_RED_SIZE, 8,
  191. GLX_BLUE_SIZE, 8,
  192. GLX_GREEN_SIZE, 8,
  193. GLX_ALPHA_SIZE, 8,
  194. GLX_DEPTH_SIZE, 24,
  195. GLX_STENCIL_SIZE, 8,
  196. GLX_DOUBLEBUFFER, True,
  197. None,
  198. };
  199. // Find suitable config
  200. GLXFBConfig bestconfig = NULL;
  201. int nconfigs;
  202. GLXFBConfig* configs = glXChooseFBConfig(display, DefaultScreen(display), glxAttribs, &nconfigs);
  203. XVisualInfo* visualInfo = 0;
  204. for (int ii = 0; ii < nconfigs; ++ii)
  205. {
  206. visualInfo = glXGetVisualFromFBConfig(display, configs[ii]);
  207. if (visualInfo)
  208. {
  209. // Check if meets min spec
  210. bool validconfig = true;
  211. for (uint32_t attridx = 0; attridx < countof(glxAttribs)-1 && glxAttribs[attridx] != None; attridx += 2)
  212. {
  213. int value;
  214. glXGetFBConfigAttrib(display, configs[ii], glxAttribs[attridx], &value);
  215. if (value < glxAttribs[attridx + 1])
  216. {
  217. validconfig = false;
  218. break;
  219. }
  220. }
  221. if (validconfig)
  222. {
  223. bestconfig = configs[ii];
  224. break;
  225. }
  226. }
  227. XFree(visualInfo);
  228. visualInfo = 0;
  229. }
  230. XFree(configs);
  231. BGFX_FATAL(visualInfo, Fatal::OPENGL_UnableToCreateContext, "Failed to find a suitable X11 display configuration.");
  232. // Generate colormaps
  233. XSetWindowAttributes windowAttrs;
  234. windowAttrs.colormap = XCreateColormap(display, RootWindow(display, visualInfo->screen), visualInfo->visual, AllocNone);
  235. windowAttrs.background_pixmap = None;
  236. windowAttrs.border_pixel = 0;
  237. Window window = XCreateWindow(
  238. display
  239. , RootWindow(display, visualInfo->screen)
  240. , 0, 0
  241. , _width, _height, 0, visualInfo->depth
  242. , InputOutput
  243. , visualInfo->visual
  244. , CWBorderPixel|CWColormap
  245. , &windowAttrs
  246. );
  247. BGFX_FATAL(window, Fatal::OPENGL_UnableToCreateContext, "Failed to create X11 window.");
  248. XMapRaised(display, window);
  249. XFlush(display);
  250. XFree(visualInfo);
  251. BX_TRACE("create context");
  252. typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
  253. glXCreateContextAttribsARBProc glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
  254. BGFX_FATAL(glXCreateContextAttribsARB, Fatal::OPENGL_UnableToCreateContext, "Failed to get glXCreateContextAttribsARB.");
  255. const int contextArrib[] =
  256. {
  257. GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
  258. GLX_CONTEXT_MINOR_VERSION_ARB, 0,
  259. None,
  260. };
  261. m_context = glXCreateContextAttribsARB(display, bestconfig, 0, True, contextArrib);
  262. BGFX_FATAL(m_context, Fatal::OPENGL_UnableToCreateContext, "Failed to create GLX context.");
  263. glXMakeCurrent(display, window, m_context);
  264. # define GL_IMPORT(_optional, _proto, _func) \
  265. { \
  266. _func = (_proto)glXGetProcAddress((const GLubyte*)#_func); \
  267. BGFX_FATAL(_optional || NULL != _func, Fatal::OPENGL_UnableToCreateContext, "Failed to create OpenGL context. glXGetProcAddress %s", #_func); \
  268. }
  269. # include "glimports.h"
  270. # undef GL_IMPORT
  271. glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  272. glClear(GL_COLOR_BUFFER_BIT);
  273. glXSwapBuffers(display, window);
  274. m_display = display;
  275. m_window = window;
  276. XUnlockDisplay(display);
  277. }
  278. else
  279. {
  280. XResizeWindow(m_display, m_window, _width, _height);
  281. }
  282. #elif BGFX_USE_EGL
  283. if (NULL == m_context)
  284. {
  285. m_display = eglGetDisplay(NULL);
  286. BGFX_FATAL(m_display != EGL_NO_DISPLAY, Fatal::OPENGL_UnableToCreateContext, "Failed to create display 0x%08x", m_display);
  287. EGLint major = 0;
  288. EGLint minor = 0;
  289. EGLBoolean success = eglInitialize(m_display, &major, &minor);
  290. BGFX_FATAL(success && major >= 1 && minor >= 4, Fatal::OPENGL_UnableToCreateContext, "Failed to initialize %d.%d", major, minor);
  291. EGLint attrs[] =
  292. {
  293. # if BX_PLATFORM_ANDROID
  294. EGL_DEPTH_SIZE, 16,
  295. # else
  296. EGL_DEPTH_SIZE, 24,
  297. # endif // BX_PLATFORM_
  298. EGL_NONE
  299. };
  300. EGLint numConfig = 0;
  301. EGLConfig config = 0;
  302. success = eglChooseConfig(m_display, attrs, &config, 1, &numConfig);
  303. BGFX_FATAL(success, Fatal::OPENGL_UnableToCreateContext, "eglChooseConfig");
  304. m_surface = eglCreateWindowSurface(m_display, config, (EGLNativeWindowType)g_bgfxHwnd, NULL);
  305. BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::OPENGL_UnableToCreateContext, "Failed to create surface.");
  306. m_context = eglCreateContext(m_display, config, EGL_NO_CONTEXT, NULL);
  307. BGFX_FATAL(m_context != EGL_NO_CONTEXT, Fatal::OPENGL_UnableToCreateContext, "Failed to create context.");
  308. success = eglMakeCurrent(m_display, m_surface, m_surface, m_context);
  309. BGFX_FATAL(success, Fatal::OPENGL_UnableToCreateContext, "Failed to set context.");
  310. # define GL_IMPORT(_optional, _proto, _func) \
  311. { \
  312. _func = (_proto)eglGetProcAddress(#_func); \
  313. BGFX_FATAL(_optional || NULL != _func, Fatal::OPENGL_UnableToCreateContext, "Failed to create OpenGLES context. eglGetProcAddress(\"%s\")", #_func); \
  314. }
  315. # include "glimports.h"
  316. # undef GL_IMPORT
  317. }
  318. #endif // BX_PLATFORM_
  319. }
  320. if (NULL != glVertexAttribDivisor
  321. && NULL != glDrawArraysInstanced
  322. && NULL != glDrawElementsInstanced)
  323. {
  324. s_vertexAttribDivisor = glVertexAttribDivisor;
  325. s_drawArraysInstanced = glDrawArraysInstanced;
  326. s_drawElementsInstanced = glDrawElementsInstanced;
  327. }
  328. else
  329. {
  330. s_vertexAttribDivisor = stubVertexAttribDivisor;
  331. s_drawArraysInstanced = stubDrawArraysInstanced;
  332. s_drawElementsInstanced = stubDrawElementsInstanced;
  333. }
  334. m_flip = true;
  335. }
  336. void flip()
  337. {
  338. if (m_flip)
  339. {
  340. #if BX_PLATFORM_NACL
  341. glSetCurrentContextPPAPI(m_context);
  342. m_graphicsInterface->SwapBuffers(m_context, naclSwapComplete);
  343. #elif BGFX_USE_WGL
  344. wglMakeCurrent(m_hdc, m_context);
  345. SwapBuffers(m_hdc);
  346. #elif BGFX_USE_EGL
  347. eglMakeCurrent(m_display, m_surface, m_surface, m_context);
  348. eglSwapBuffers(m_display, m_surface);
  349. #elif BX_PLATFORM_LINUX
  350. glXSwapBuffers(m_display, m_window);
  351. #endif // BX_PLATFORM_
  352. }
  353. if (NULL != m_postSwapBuffers)
  354. {
  355. m_postSwapBuffers(m_resolution.m_width, m_resolution.m_height);
  356. }
  357. }
  358. void saveScreenShot(Memory* _mem)
  359. {
  360. #if BGFX_CONFIG_RENDERER_OPENGL
  361. void* data = g_realloc(NULL, m_resolution.m_width*m_resolution.m_height*4);
  362. glReadPixels(0, 0, m_resolution.m_width, m_resolution.m_height, GL_RGBA, GL_UNSIGNED_BYTE, data);
  363. uint8_t* rgba = (uint8_t*)data;
  364. for (uint32_t ii = 0, num = m_resolution.m_width*m_resolution.m_height; ii < num; ++ii)
  365. {
  366. uint8_t temp = rgba[0];
  367. rgba[0] = rgba[2];
  368. rgba[2] = temp;
  369. rgba += 4;
  370. }
  371. saveTga( (const char*)_mem->data, m_resolution.m_width, m_resolution.m_height, m_resolution.m_width*4, data, false, true);
  372. g_free(data);
  373. #endif // BGFX_CONFIG_RENDERER_OPENGL
  374. }
  375. void init()
  376. {
  377. setRenderContextSize(BGFX_DEFAULT_WIDTH, BGFX_DEFAULT_HEIGHT);
  378. #if BGFX_CONFIG_RENDERER_OPENGL
  379. m_queries.create();
  380. #endif // BGFX_CONFIG_RENDERER_OPENGL
  381. }
  382. void shutdown()
  383. {
  384. #if BGFX_CONFIG_RENDERER_OPENGL
  385. m_queries.destroy();
  386. #endif // BGFX_CONFIG_RENDERER_OPENGL
  387. #if BGFX_USE_WGL
  388. if (NULL != m_hdc)
  389. {
  390. wglMakeCurrent(NULL, NULL);
  391. wglDeleteContext(m_context);
  392. m_context = NULL;
  393. }
  394. FreeLibrary(m_opengl32dll);
  395. #elif BGFX_USE_EGL
  396. eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
  397. eglDestroyContext(m_display, m_context);
  398. eglDestroySurface(m_display, m_surface);
  399. eglTerminate(m_display);
  400. m_context = NULL;
  401. #endif // BGFX_USE_
  402. }
  403. IndexBuffer m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS];
  404. VertexBuffer m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
  405. Shader m_vertexShaders[BGFX_CONFIG_MAX_VERTEX_SHADERS];
  406. Shader m_fragmentShaders[BGFX_CONFIG_MAX_FRAGMENT_SHADERS];
  407. Material m_materials[BGFX_CONFIG_MAX_MATERIALS];
  408. Texture m_textures[BGFX_CONFIG_MAX_TEXTURES];
  409. VertexDecl m_vertexDecls[BGFX_CONFIG_MAX_VERTEX_DECLS];
  410. RenderTarget m_renderTargets[BGFX_CONFIG_MAX_RENDER_TARGETS];
  411. UniformRegistry m_uniformReg;
  412. void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
  413. #if BGFX_CONFIG_RENDERER_OPENGL
  414. Queries m_queries;
  415. #endif // BGFX_CONFIG_RENDERER_OPENGL
  416. TextVideoMem m_textVideoMem;
  417. Resolution m_resolution;
  418. bool m_dxtSupport;
  419. bool m_flip;
  420. PostSwapBuffersFn m_postSwapBuffers;
  421. uint64_t m_hash;
  422. #if BX_PLATFORM_NACL
  423. PP_Resource m_context;
  424. PP_Instance m_instance;
  425. const PPB_Instance* m_instInterface;
  426. const PPB_Graphics3D* m_graphicsInterface;
  427. #elif BGFX_USE_WGL
  428. HMODULE m_opengl32dll;
  429. HGLRC m_context;
  430. HDC m_hdc;
  431. #elif BGFX_USE_EGL
  432. EGLContext m_context;
  433. EGLDisplay m_display;
  434. EGLSurface m_surface;
  435. #elif BX_PLATFORM_LINUX
  436. GLXContext m_context;
  437. Window m_window;
  438. Display* m_display;
  439. #endif // BX_PLATFORM_NACL
  440. };
  441. RendererContext s_renderCtx;
  442. #if BX_PLATFORM_NACL
  443. void naclSetIntefraces(PP_Instance _instance, const PPB_Instance* _instInterface, const PPB_Graphics3D* _graphicsInterface, PostSwapBuffersFn _postSwapBuffers)
  444. {
  445. s_renderCtx.m_instance = _instance;
  446. s_renderCtx.m_instInterface = _instInterface;
  447. s_renderCtx.m_graphicsInterface = _graphicsInterface;
  448. s_renderCtx.m_postSwapBuffers = _postSwapBuffers;
  449. s_renderCtx.setRenderContextSize(BGFX_DEFAULT_WIDTH, BGFX_DEFAULT_HEIGHT);
  450. }
  451. void naclSwapCompleteCb(void* /*_data*/, int32_t /*_result*/)
  452. {
  453. renderFrame();
  454. }
  455. #elif BX_PLATFORM_LINUX
  456. bool linuxGetDisplay(Display** _display, Window* _window)
  457. {
  458. if (!s_renderCtx.m_display)
  459. {
  460. return false;
  461. }
  462. *_display = s_renderCtx.m_display;
  463. *_window = s_renderCtx.m_window;
  464. return true;
  465. }
  466. #endif // BX_PLATFORM_
  467. struct Extension
  468. {
  469. enum Enum
  470. {
  471. EXT_texture_format_BGRA8888,
  472. EXT_texture_compression_s3tc,
  473. EXT_texture_compression_dxt1,
  474. CHROMIUM_texture_compression_dxt3,
  475. CHROMIUM_texture_compression_dxt5,
  476. OES_standard_derivatives,
  477. ARB_get_program_binary,
  478. OES_get_program_binary,
  479. EXT_framebuffer_blit,
  480. ARB_timer_query,
  481. EXT_timer_query,
  482. EXT_texture_sRGB,
  483. ARB_framebuffer_sRGB,
  484. EXT_framebuffer_sRGB,
  485. ARB_multisample,
  486. CHROMIUM_framebuffer_multisample,
  487. ANGLE_translated_shader_source,
  488. ARB_instanced_arrays,
  489. ANGLE_instanced_arrays,
  490. OES_texture_float,
  491. OES_texture_float_linear,
  492. OES_texture_half_float,
  493. OES_texture_half_float_linear,
  494. EXT_occlusion_query_boolean,
  495. ATI_meminfo,
  496. NVX_gpu_memory_info,
  497. Count
  498. };
  499. const char* m_name;
  500. bool m_supported;
  501. bool m_initialize;
  502. };
  503. static Extension s_extension[Extension::Count] =
  504. {
  505. // Nvidia BGRA on Linux bug:
  506. // https://groups.google.com/a/chromium.org/forum/?fromgroups#!topic/chromium-reviews/yFfbUdyeUCQ
  507. { "GL_EXT_texture_format_BGRA8888", false, !BX_PLATFORM_LINUX },
  508. { "GL_EXT_texture_compression_s3tc", false, true },
  509. { "GL_EXT_texture_compression_dxt1", false, true },
  510. { "GL_CHROMIUM_texture_compression_dxt3", false, true },
  511. { "GL_CHROMIUM_texture_compression_dxt5", false, true },
  512. { "GL_OES_standard_derivatives", false, true },
  513. { "GL_ARB_get_program_binary", false, true },
  514. { "GL_OES_get_program_binary", false, false },
  515. { "GL_EXT_framebuffer_blit", false, true },
  516. { "GL_ARB_timer_query", false, true },
  517. { "GL_EXT_timer_query", false, true },
  518. { "GL_EXT_texture_sRGB", false, true },
  519. { "GL_ARB_framebuffer_sRGB", false, true },
  520. { "GL_EXT_framebuffer_sRGB", false, true },
  521. { "GL_ARB_multisample", false, true },
  522. { "GL_CHROMIUM_framebuffer_multisample", false, true },
  523. { "GL_ANGLE_translated_shader_source", false, true },
  524. { "GL_ARB_instanced_arrays", false, true },
  525. { "GL_ANGLE_instanced_arrays", false, true },
  526. { "GL_OES_texture_float", false, true },
  527. { "GL_OES_texture_float_linear", false, true },
  528. { "GL_OES_texture_half_float", false, true },
  529. { "GL_OES_texture_half_float_linear", false, true },
  530. { "GL_EXT_occlusion_query_boolean", false, true },
  531. { "GL_ATI_meminfo", false, true },
  532. { "GL_NVX_gpu_memory_info", false, true },
  533. };
  534. static const GLenum s_primType[] =
  535. {
  536. GL_TRIANGLES,
  537. GL_LINES,
  538. GL_POINTS,
  539. };
  540. static const uint32_t s_primNumVerts[] =
  541. {
  542. 3,
  543. 2,
  544. 1,
  545. };
  546. static const char* s_attribName[Attrib::Count] =
  547. {
  548. "a_position",
  549. "a_normal",
  550. "a_color",
  551. "a_color1",
  552. "a_indices",
  553. "a_weight",
  554. "a_texcoord0",
  555. "a_texcoord1",
  556. "a_texcoord2",
  557. "a_texcoord3",
  558. "a_texcoord4",
  559. "a_texcoord5",
  560. "a_texcoord6",
  561. "a_texcoord7",
  562. };
  563. static const char* s_instanceDataName[BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT] =
  564. {
  565. "i_data0",
  566. "i_data1",
  567. "i_data2",
  568. "i_data3",
  569. "i_data4",
  570. };
  571. static const GLenum s_attribType[AttribType::Count] =
  572. {
  573. GL_UNSIGNED_BYTE,
  574. GL_UNSIGNED_SHORT,
  575. GL_FLOAT,
  576. };
  577. static const GLenum s_blendFactor[][2] =
  578. {
  579. { 0, 0 }, // ignored
  580. { GL_ZERO, GL_ZERO },
  581. { GL_ONE, GL_ONE },
  582. { GL_SRC_COLOR, GL_SRC_COLOR },
  583. { GL_ONE_MINUS_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR },
  584. { GL_SRC_ALPHA, GL_SRC_ALPHA },
  585. { GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA },
  586. { GL_DST_ALPHA, GL_DST_ALPHA },
  587. { GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA },
  588. { GL_DST_COLOR, GL_DST_COLOR },
  589. { GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_DST_COLOR },
  590. { GL_SRC_ALPHA_SATURATE, GL_ONE },
  591. };
  592. static const GLenum s_depthFunc[] =
  593. {
  594. 0, // ignored
  595. GL_LESS,
  596. GL_LEQUAL,
  597. GL_EQUAL,
  598. GL_GEQUAL,
  599. GL_GREATER,
  600. GL_NOTEQUAL,
  601. GL_NEVER,
  602. GL_ALWAYS,
  603. };
  604. // Specifies the internal format of the texture.
  605. // Must be one of the following symbolic constants:
  606. // GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA.
  607. static const GLenum s_colorFormat[] =
  608. {
  609. 0, // ignored
  610. GL_RGBA,
  611. GL_RGBA,
  612. };
  613. static const GLenum s_depthFormat[] =
  614. {
  615. 0, // ignored
  616. 0,
  617. };
  618. static const GLenum s_textureAddress[] =
  619. {
  620. GL_REPEAT,
  621. GL_MIRRORED_REPEAT,
  622. GL_CLAMP_TO_EDGE,
  623. };
  624. static const GLenum s_textureFilter[] =
  625. {
  626. GL_LINEAR,
  627. GL_NEAREST,
  628. };
  629. struct TextureFormatInfo
  630. {
  631. GLenum m_internalFmt;
  632. GLenum m_format;
  633. GLenum m_type;
  634. uint8_t m_bpp;
  635. };
  636. static const TextureFormatInfo s_textureFormat[TextureFormat::Count] =
  637. {
  638. { GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_ZERO, GL_ZERO, 4 },
  639. { GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_ZERO, GL_ZERO, 4 },
  640. { GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_ZERO, GL_ZERO, 4 },
  641. { GL_ZERO, GL_ZERO, GL_ZERO, 0 },
  642. { GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1 },
  643. { GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 4 },
  644. { GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 4 },
  645. #if BGFX_CONFIG_RENDERER_OPENGL
  646. { GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, 8 },
  647. #else
  648. { GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 8 },
  649. #endif // BGFX_CONFIG_RENDERER_OPENGL
  650. };
  651. const char* glslTypeName(GLuint _type)
  652. {
  653. #define GLSL_TYPE(_ty) case _ty: return #_ty
  654. switch (_type)
  655. {
  656. GLSL_TYPE(GL_FLOAT);
  657. GLSL_TYPE(GL_FLOAT_VEC2);
  658. GLSL_TYPE(GL_FLOAT_VEC3);
  659. GLSL_TYPE(GL_FLOAT_VEC4);
  660. GLSL_TYPE(GL_FLOAT_MAT2);
  661. GLSL_TYPE(GL_FLOAT_MAT3);
  662. GLSL_TYPE(GL_FLOAT_MAT4);
  663. // GLSL_TYPE(GL_FLOAT_MAT2x3);
  664. // GLSL_TYPE(GL_FLOAT_MAT2x4);
  665. // GLSL_TYPE(GL_FLOAT_MAT3x2);
  666. // GLSL_TYPE(GL_FLOAT_MAT3x4);
  667. // GLSL_TYPE(GL_FLOAT_MAT4x2);
  668. // GLSL_TYPE(GL_FLOAT_MAT4x3);
  669. // GLSL_TYPE(GL_SAMPLER_1D);
  670. GLSL_TYPE(GL_SAMPLER_2D);
  671. // GLSL_TYPE(GL_SAMPLER_3D);
  672. GLSL_TYPE(GL_SAMPLER_CUBE);
  673. // GLSL_TYPE(GL_SAMPLER_1D_SHADOW);
  674. // GLSL_TYPE(GL_SAMPLER_2D_SHADOW);
  675. }
  676. #undef GLSL_TYPE
  677. return "UNKNOWN GLSL TYPE!";
  678. }
  679. const char* glEnumName(GLenum _enum)
  680. {
  681. #define GLENUM(_ty) case _ty: return #_ty
  682. switch (_enum)
  683. {
  684. GLENUM(GL_TEXTURE);
  685. GLENUM(GL_RENDERBUFFER);
  686. }
  687. #undef GLENUM
  688. return "UNKNOWN GLENUM!";
  689. }
  690. ConstantType::Enum convertGlType(GLenum _type)
  691. {
  692. switch (_type)
  693. {
  694. case GL_FLOAT:
  695. return ConstantType::Uniform1fv;
  696. case GL_FLOAT_VEC2:
  697. return ConstantType::Uniform2fv;
  698. case GL_FLOAT_VEC3:
  699. return ConstantType::Uniform3fv;
  700. case GL_FLOAT_VEC4:
  701. return ConstantType::Uniform4fv;
  702. case GL_FLOAT_MAT2:
  703. break;
  704. case GL_FLOAT_MAT3:
  705. return ConstantType::Uniform3x3fv;
  706. case GL_FLOAT_MAT4:
  707. return ConstantType::Uniform4x4fv;
  708. // case GL_FLOAT_MAT2x3:
  709. // case GL_FLOAT_MAT2x4:
  710. // case GL_FLOAT_MAT3x2:
  711. // case GL_FLOAT_MAT3x4:
  712. // case GL_FLOAT_MAT4x2:
  713. // case GL_FLOAT_MAT4x3:
  714. // break;
  715. case GL_SAMPLER_2D:
  716. case GL_SAMPLER_CUBE:
  717. // case GL_SAMPLER_1D:
  718. // case GL_SAMPLER_3D:
  719. // case GL_SAMPLER_1D_SHADOW:
  720. // case GL_SAMPLER_2D_SHADOW:
  721. return ConstantType::Uniform1iv;
  722. };
  723. return ConstantType::End;
  724. }
  725. void Material::create(const Shader& _vsh, const Shader& _fsh)
  726. {
  727. m_id = glCreateProgram();
  728. BX_TRACE("material create: %d: %d, %d", m_id, _vsh.m_id, _fsh.m_id);
  729. bool cached = false;
  730. #if BGFX_CONFIG_RENDERER_OPENGL
  731. uint64_t id = (uint64_t(_vsh.m_hash)<<32) | _fsh.m_hash;
  732. id ^= s_renderCtx.m_hash;
  733. if (s_extension[Extension::ARB_get_program_binary].m_supported)
  734. {
  735. uint32_t length;
  736. g_cache(id, false, NULL, length);
  737. cached = length > 0;
  738. if (cached)
  739. {
  740. void* data = g_realloc(NULL, length);
  741. g_cache(id, false, data, length);
  742. StreamRead stream(data, length);
  743. GLenum format;
  744. stream.read(format);
  745. GL_CHECK(glProgramBinary(m_id, format, stream.getDataPtr(), stream.remaining() ) );
  746. g_free(data);
  747. }
  748. else
  749. {
  750. GL_CHECK(glProgramParameteri(m_id, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE) );
  751. }
  752. }
  753. #endif // BGFX_CONFIG_RENDERER_OPENGL
  754. if (!cached)
  755. {
  756. GL_CHECK(glAttachShader(m_id, _vsh.m_id) );
  757. GL_CHECK(glAttachShader(m_id, _fsh.m_id) );
  758. GL_CHECK(glLinkProgram(m_id) );
  759. GLint linked = 0;
  760. GL_CHECK(glGetProgramiv(m_id, GL_LINK_STATUS, &linked) );
  761. if (0 == linked)
  762. {
  763. char log[1024];
  764. GL_CHECK(glGetProgramInfoLog(m_id, sizeof(log), NULL, log) );
  765. BX_TRACE("%d: %s", linked, log);
  766. GL_CHECK(glDeleteProgram(m_id) );
  767. return;
  768. }
  769. #if BGFX_CONFIG_RENDERER_OPENGL
  770. if (s_extension[Extension::ARB_get_program_binary].m_supported)
  771. {
  772. GLint programLength;
  773. GLenum format;
  774. GL_CHECK(glGetProgramiv(m_id, GL_PROGRAM_BINARY_LENGTH, &programLength) );
  775. uint32_t length = programLength + 4;
  776. uint8_t* data = (uint8_t*)g_realloc(NULL, length);
  777. GL_CHECK(glGetProgramBinary(m_id, programLength, NULL, &format, &data[4]) );
  778. *(uint32_t*)data = format;
  779. g_cache(id, true, data, length);
  780. g_free(data);
  781. }
  782. #endif // BGFX_CONFIG_RENDERER_OPENGL
  783. }
  784. init();
  785. }
  786. void Material::destroy()
  787. {
  788. GL_CHECK(glUseProgram(0) );
  789. GL_CHECK(glDeleteProgram(m_id) );
  790. }
  791. void Material::init()
  792. {
  793. GLint activeAttribs;
  794. GLint activeUniforms;
  795. GL_CHECK(glGetProgramiv(m_id, GL_ACTIVE_ATTRIBUTES, &activeAttribs) );
  796. GL_CHECK(glGetProgramiv(m_id, GL_ACTIVE_UNIFORMS, &activeUniforms) );
  797. GLint max0, max1;
  798. GL_CHECK(glGetProgramiv(m_id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max0) );
  799. GL_CHECK(glGetProgramiv(m_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max1) );
  800. GLint maxLength = uint32_max(max0, max1);
  801. char* name = (char*)g_realloc(NULL, maxLength + 1);
  802. BX_TRACE("Program %d", m_id);
  803. BX_TRACE("Attributes:");
  804. for (int32_t ii = 0; ii < activeAttribs; ++ii)
  805. {
  806. GLint size;
  807. GLenum type;
  808. GL_CHECK(glGetActiveAttrib(m_id, ii, maxLength + 1, NULL, &size, &type, name) );
  809. BX_TRACE("\t%s %s is at location %d"
  810. , glslTypeName(type)
  811. , name
  812. , glGetAttribLocation(m_id, name)
  813. );
  814. }
  815. m_numPredefined = 0;
  816. m_constantBuffer = ConstantBuffer::create(1024);
  817. m_numSamplers = 0;
  818. BX_TRACE("Uniforms:");
  819. for (int32_t ii = 0; ii < activeUniforms; ++ii)
  820. {
  821. GLint num;
  822. GLenum gltype;
  823. GL_CHECK(glGetActiveUniform(m_id, ii, maxLength + 1, NULL, &num, &gltype, name) );
  824. GLint loc = glGetUniformLocation(m_id, name);
  825. int offset = 0;
  826. char* array = strchr(name, '[');
  827. if (NULL != array)
  828. {
  829. BX_TRACE("--- %s", name);
  830. *array = '\0';
  831. array++;
  832. char* end = strchr(array, ']');
  833. *end = '\0';
  834. offset = atoi(array);
  835. }
  836. if (GL_SAMPLER_2D == gltype)
  837. {
  838. BX_TRACE("Sampler %d at %d.", m_numSamplers, loc);
  839. m_sampler[m_numSamplers] = loc;
  840. m_numSamplers++;
  841. }
  842. const void* data = NULL;
  843. PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
  844. if (PredefinedUniform::Count != predefined)
  845. {
  846. m_predefined[m_numPredefined].m_loc = loc;
  847. m_predefined[m_numPredefined].m_type = predefined;
  848. m_predefined[m_numPredefined].m_count = num;
  849. m_numPredefined++;
  850. }
  851. else
  852. {
  853. const UniformInfo* info = s_renderCtx.m_uniformReg.find(name);
  854. if (NULL != info)
  855. {
  856. data = info->m_data;
  857. ConstantType::Enum type = convertGlType(gltype);
  858. m_constantBuffer->writeUniformRef(type, loc, data, num);
  859. BX_TRACE("store %s %p", name, data);
  860. }
  861. }
  862. BX_TRACE("\tuniform %s %s%s is at location %d, size %d (%p), offset %d"
  863. , glslTypeName(gltype)
  864. , name
  865. , PredefinedUniform::Count != predefined ? "*" : ""
  866. , loc
  867. , num
  868. , data
  869. , offset
  870. );
  871. BX_UNUSED(offset);
  872. }
  873. m_constantBuffer->finish();
  874. g_free(name);
  875. memset(m_attributes, 0xff, sizeof(m_attributes) );
  876. uint32_t used = 0;
  877. for (uint32_t ii = 0; ii < Attrib::Count; ++ii)
  878. {
  879. GLuint loc = glGetAttribLocation(m_id, s_attribName[ii]);
  880. if (GLuint(-1) != loc )
  881. {
  882. BX_TRACE("attr %s: %d", s_attribName[ii], loc);
  883. m_attributes[ii] = loc;
  884. m_used[used++] = ii;
  885. }
  886. }
  887. m_used[used] = Attrib::Count;
  888. used = 0;
  889. for (uint32_t ii = 0; ii < countof(s_instanceDataName); ++ii)
  890. {
  891. GLuint loc = glGetAttribLocation(m_id, s_instanceDataName[ii]);
  892. if (GLuint(-1) != loc )
  893. {
  894. BX_TRACE("instance data %s: %d", s_instanceDataName[ii], loc);
  895. m_instanceData[used++] = loc;
  896. }
  897. }
  898. m_instanceData[used] = 0xffff;
  899. }
  900. void Material::bindAttributes(const VertexDecl& _vertexDecl, uint32_t _baseVertex) const
  901. {
  902. uint32_t enabled = 0;
  903. for (uint32_t ii = 0; Attrib::Count != m_used[ii]; ++ii)
  904. {
  905. Attrib::Enum attr = Attrib::Enum(m_used[ii]);
  906. GLuint loc = m_attributes[attr];
  907. uint8_t num;
  908. AttribType::Enum type;
  909. bool normalized;
  910. _vertexDecl.decode(attr, num, type, normalized);
  911. if (0xffff != loc
  912. && 0xff != _vertexDecl.m_attributes[attr])
  913. {
  914. GL_CHECK(glEnableVertexAttribArray(loc) );
  915. enabled |= 1<<attr;
  916. GL_CHECK(s_vertexAttribDivisor(loc, 0) );
  917. uint32_t baseVertex = _baseVertex*_vertexDecl.m_stride + _vertexDecl.m_offset[attr];
  918. GL_CHECK(glVertexAttribPointer(loc, num, s_attribType[type], normalized, _vertexDecl.m_stride, (void*)(uintptr_t)baseVertex) );
  919. }
  920. else
  921. {
  922. GL_CHECK(glDisableVertexAttribArray(loc) );
  923. switch (num)
  924. {
  925. case 1:
  926. GL_CHECK(glVertexAttrib1f(loc, 0.0f) );
  927. break;
  928. case 2:
  929. GL_CHECK(glVertexAttrib2f(loc, 0.0f, 0.0f) );
  930. break;
  931. case 3:
  932. GL_CHECK(glVertexAttrib3f(loc, 0.0f, 0.0f, 0.0f) );
  933. break;
  934. case 4:
  935. GL_CHECK(glVertexAttrib4f(loc, 0.0f, 0.0f, 0.0f, 0.0f) );
  936. break;
  937. default:
  938. BX_CHECK(false, "You should not be here!");
  939. break;
  940. }
  941. }
  942. }
  943. }
  944. void Material::bindInstanceData(uint32_t _stride, uint32_t _baseVertex) const
  945. {
  946. uint32_t baseVertex = _baseVertex;
  947. for (uint32_t ii = 0; 0xffff != m_instanceData[ii]; ++ii)
  948. {
  949. GLuint loc = m_instanceData[ii];
  950. GL_CHECK(glEnableVertexAttribArray(loc) );
  951. GL_CHECK(glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, _stride, (void*)(uintptr_t)baseVertex) );
  952. GL_CHECK(s_vertexAttribDivisor(loc, 1) );
  953. baseVertex += 16;
  954. }
  955. }
  956. void Texture::create(const Memory* _mem, uint32_t _flags)
  957. {
  958. Dds dds;
  959. uint8_t numMips = 0;
  960. if (parseDds(dds, _mem) )
  961. {
  962. numMips = dds.m_numMips;
  963. if (dds.m_cubeMap)
  964. {
  965. m_target = GL_TEXTURE_CUBE_MAP;
  966. }
  967. #if BGFX_CONFIG_RENDERER_OPENGL
  968. else if (dds.m_depth > 1)
  969. {
  970. m_target = GL_TEXTURE_3D;
  971. }
  972. #endif // BGFX_CONFIG_RENDERER_OPENGL
  973. else
  974. {
  975. m_target = GL_TEXTURE_2D;
  976. }
  977. GL_CHECK(glGenTextures(1, &m_id) );
  978. BX_CHECK(0 != m_id, "Failed to generate texture id.");
  979. GL_CHECK(glBindTexture(m_target, m_id) );
  980. const TextureFormatInfo& tfi = s_textureFormat[dds.m_type];
  981. GLenum internalFmt = tfi.m_internalFmt;
  982. GLenum fmt = tfi.m_format;
  983. GLenum target = m_target;
  984. if (dds.m_cubeMap)
  985. {
  986. target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
  987. }
  988. if (!s_renderCtx.m_dxtSupport
  989. || TextureFormat::Unknown < dds.m_type)
  990. {
  991. bool decompress = TextureFormat::Unknown > dds.m_type;
  992. if (GL_RGBA == internalFmt
  993. || decompress)
  994. {
  995. internalFmt = s_extension[Extension::EXT_texture_format_BGRA8888].m_supported ? GL_BGRA_EXT : GL_RGBA;
  996. fmt = internalFmt;
  997. }
  998. GLenum type = tfi.m_type;
  999. if (decompress)
  1000. {
  1001. type = GL_UNSIGNED_BYTE;
  1002. }
  1003. uint8_t* bits = (uint8_t*)g_realloc(NULL, dds.m_width*dds.m_height*tfi.m_bpp);
  1004. for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
  1005. {
  1006. uint32_t width = dds.m_width;
  1007. uint32_t height = dds.m_height;
  1008. uint32_t depth = dds.m_depth;
  1009. for (uint32_t lod = 0, num = dds.m_numMips; lod < num; ++lod)
  1010. {
  1011. width = uint32_max(1, width);
  1012. height = uint32_max(1, height);
  1013. depth = uint32_max(1, depth);
  1014. Mip mip;
  1015. if (getRawImageData(dds, 0, lod, _mem, mip) )
  1016. {
  1017. mip.decode(bits);
  1018. if (GL_RGBA == internalFmt)
  1019. {
  1020. uint32_t dstpitch = width*4;
  1021. for (uint32_t yy = 0; yy < height; ++yy)
  1022. {
  1023. uint8_t* dst = &bits[yy*dstpitch];
  1024. for (uint32_t xx = 0; xx < width; ++xx)
  1025. {
  1026. uint8_t tmp = dst[0];
  1027. dst[0] = dst[2];
  1028. dst[2] = tmp;
  1029. dst += 4;
  1030. }
  1031. }
  1032. }
  1033. #if BGFX_CONFIG_RENDERER_OPENGL
  1034. if (target == GL_TEXTURE_3D)
  1035. {
  1036. GL_CHECK(glTexImage3D(target
  1037. , lod
  1038. , internalFmt
  1039. , width
  1040. , height
  1041. , depth
  1042. , 0
  1043. , fmt
  1044. , type
  1045. , bits
  1046. ) );
  1047. }
  1048. else
  1049. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1050. {
  1051. GL_CHECK(glTexImage2D(target+side
  1052. , lod
  1053. , internalFmt
  1054. , width
  1055. , height
  1056. , 0
  1057. , fmt
  1058. , type
  1059. , bits
  1060. ) );
  1061. }
  1062. }
  1063. width >>= 1;
  1064. height >>= 1;
  1065. depth >>= 1;
  1066. }
  1067. }
  1068. g_free(bits);
  1069. }
  1070. else
  1071. {
  1072. for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
  1073. {
  1074. uint32_t width = dds.m_width;
  1075. uint32_t height = dds.m_height;
  1076. uint32_t depth = dds.m_depth;
  1077. for (uint32_t ii = 0, num = dds.m_numMips; ii < num; ++ii)
  1078. {
  1079. width = uint32_max(1, width);
  1080. height = uint32_max(1, height);
  1081. depth = uint32_max(1, depth);
  1082. Mip mip;
  1083. if (getRawImageData(dds, 0, ii, _mem, mip) )
  1084. {
  1085. #if BGFX_CONFIG_RENDERER_OPENGL
  1086. if (m_target == GL_TEXTURE_3D)
  1087. {
  1088. GL_CHECK(glCompressedTexImage3D(target
  1089. , ii
  1090. , internalFmt
  1091. , width
  1092. , height
  1093. , depth
  1094. , 0
  1095. , mip.m_size
  1096. , mip.m_data
  1097. ) );
  1098. }
  1099. else
  1100. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1101. {
  1102. GL_CHECK(glCompressedTexImage2D(target+side
  1103. , ii
  1104. , internalFmt
  1105. , width
  1106. , height
  1107. , 0
  1108. , mip.m_size
  1109. , mip.m_data
  1110. ) );
  1111. }
  1112. }
  1113. width >>= 1;
  1114. height >>= 1;
  1115. depth >>= 1;
  1116. }
  1117. }
  1118. }
  1119. }
  1120. else
  1121. {
  1122. m_target = GL_TEXTURE_2D;
  1123. GL_CHECK(glGenTextures(1, &m_id) );
  1124. BX_CHECK(0 != m_id, "Failed to generate texture id.");
  1125. GL_CHECK(glBindTexture(m_target, m_id) );
  1126. StreamRead stream(_mem->data, _mem->size);
  1127. uint32_t magic;
  1128. stream.read(magic);
  1129. if (BGFX_MAGIC == magic)
  1130. {
  1131. uint16_t width;
  1132. stream.read(width);
  1133. uint16_t height;
  1134. stream.read(height);
  1135. uint8_t bpp;
  1136. stream.read(bpp);
  1137. stream.read(numMips);
  1138. stream.align(16);
  1139. for (uint8_t mip = 0; mip < numMips; ++mip)
  1140. {
  1141. width = uint32_max(width, 1);
  1142. height = uint32_max(height, 1);
  1143. const uint8_t* data = stream.getDataPtr();
  1144. stream.skip(width*height*bpp);
  1145. GL_CHECK(glTexImage2D(m_target
  1146. , mip
  1147. , 1 == bpp ? GL_LUMINANCE : GL_RGBA
  1148. , width
  1149. , height
  1150. , 0
  1151. , 1 == bpp ? GL_LUMINANCE : GL_RGBA
  1152. , GL_UNSIGNED_BYTE
  1153. , data
  1154. ) );
  1155. width >>= 1;
  1156. height >>= 1;
  1157. }
  1158. }
  1159. else
  1160. {
  1161. //
  1162. }
  1163. }
  1164. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_S, s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT]) );
  1165. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_T, s_textureAddress[(_flags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT]) );
  1166. #if BGFX_CONFIG_RENDERER_OPENGL
  1167. if (m_target == GL_TEXTURE_3D)
  1168. {
  1169. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_R, s_textureAddress[(_flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT]) );
  1170. }
  1171. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1172. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, s_textureFilter[(_flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT]) );
  1173. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, s_textureFilter[(_flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT]) );
  1174. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, 1 < numMips ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) );
  1175. GL_CHECK(glBindTexture(m_target, 0) );
  1176. }
  1177. void Texture::createColor(uint32_t _width, uint32_t _height, GLenum _min, GLenum _mag)
  1178. {
  1179. GLenum internalFormat = /*_fp ? GL_RGBA16F_ARB :*/ GL_RGBA;
  1180. GLenum type = /*_fp ? GL_HALF_FLOAT_ARB :*/ GL_UNSIGNED_BYTE;
  1181. m_target = /*0 != _depth ? GL_TEXTURE_3D :*/ GL_TEXTURE_2D;
  1182. GL_CHECK(glGenTextures(1, &m_id) );
  1183. BX_CHECK(0 != m_id, "Failed to generate texture id.");
  1184. GL_CHECK(glBindTexture(m_target, m_id) );
  1185. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, _min) );
  1186. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, _mag) );
  1187. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) );
  1188. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
  1189. GL_CHECK(glTexImage2D(m_target
  1190. , 0
  1191. , internalFormat
  1192. , _width
  1193. , _height
  1194. , 0
  1195. , GL_RGBA
  1196. , type
  1197. , NULL
  1198. ) );
  1199. GL_CHECK(glBindTexture(m_target, 0) );
  1200. }
  1201. void Texture::createDepth(uint32_t _width, uint32_t _height)
  1202. {
  1203. m_target = GL_TEXTURE_2D;
  1204. GL_CHECK(glGenTextures(1, &m_id) );
  1205. BX_CHECK(0 != m_id, "Failed to generate texture id.");
  1206. GL_CHECK(glBindTexture(m_target, m_id) );
  1207. // glTexParameteri(m_target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
  1208. // glTexParameteri(m_target, GL_DEPTH_TEXTURE_MODE, GL_NONE);
  1209. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR) );
  1210. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
  1211. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) );
  1212. GL_CHECK(glTexParameteri(m_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
  1213. // OpenGL ES 2.0 doesn't support GL_DEPTH_COMPONENT... this will fail.
  1214. GL_CHECK(glTexImage2D(m_target
  1215. , 0
  1216. , GL_DEPTH_COMPONENT
  1217. , _width
  1218. , _height
  1219. , 0
  1220. , GL_DEPTH_COMPONENT
  1221. , GL_FLOAT
  1222. , NULL
  1223. ) );
  1224. GL_CHECK(glBindTexture(m_target, 0) );
  1225. }
  1226. void Texture::destroy()
  1227. {
  1228. if (0 != m_id)
  1229. {
  1230. GL_CHECK(glBindTexture(m_target, 0) );
  1231. GL_CHECK(glDeleteTextures(1, &m_id) );
  1232. m_id = 0;
  1233. }
  1234. }
  1235. void RenderTarget::create(uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags)
  1236. {
  1237. BX_TRACE("Create render target %dx%d 0x%02x", _width, _height, _flags);
  1238. m_width = _width;
  1239. m_height = _height;
  1240. // m_msaa = s_msaa[(m_flags&BGFX_RENDER_TARGET_MSAA_MASK)>>BGFX_RENDER_TARGET_MSAA_SHIFT];
  1241. uint32_t colorFormat = (_flags&BGFX_RENDER_TARGET_COLOR_MASK)>>BGFX_RENDER_TARGET_COLOR_SHIFT;
  1242. uint32_t depthFormat = (_flags&BGFX_RENDER_TARGET_DEPTH_MASK)>>BGFX_RENDER_TARGET_DEPTH_SHIFT;
  1243. GLenum minFilter = s_textureFilter[(_textureFlags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT];
  1244. GLenum magFilter = s_textureFilter[(_textureFlags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT];
  1245. if (0 < colorFormat)
  1246. {
  1247. m_color.createColor(_width, _height, minFilter, magFilter);
  1248. }
  1249. #if 0 // GLES can't create texture with depth texture format...
  1250. if (0 < depthFormat)
  1251. {
  1252. m_depth.createDepth(_width, _height);
  1253. }
  1254. #endif //
  1255. GL_CHECK(glGenFramebuffers(1, &m_fbo) );
  1256. BX_CHECK(0 != m_fbo, "Failed to generate framebuffer id.");
  1257. GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo) );
  1258. if (0 < colorFormat)
  1259. {
  1260. GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER
  1261. , GL_COLOR_ATTACHMENT0
  1262. , m_color.m_target
  1263. , m_color.m_id
  1264. , 0
  1265. ) );
  1266. }
  1267. if (0 < depthFormat)
  1268. {
  1269. if (0 < colorFormat)
  1270. {
  1271. #if BGFX_CONFIG_RENDERER_OPENGL
  1272. GLenum depthComponent = GL_DEPTH_COMPONENT32;
  1273. #else
  1274. GLenum depthComponent = GL_DEPTH_COMPONENT16;
  1275. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1276. GL_CHECK(glGenRenderbuffers(1, &m_rbo) );
  1277. BX_CHECK(0 != m_rbo, "Failed to generate renderbuffer id.");
  1278. GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_rbo) );
  1279. GL_CHECK(glRenderbufferStorage(GL_RENDERBUFFER, depthComponent, _width, _height) );
  1280. GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, 0) );
  1281. GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER
  1282. , GL_DEPTH_ATTACHMENT
  1283. , GL_RENDERBUFFER
  1284. , m_rbo
  1285. ) );
  1286. }
  1287. else
  1288. {
  1289. GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER
  1290. , GL_DEPTH_ATTACHMENT
  1291. , m_depth.m_target
  1292. , m_depth.m_id
  1293. , 0
  1294. ) );
  1295. }
  1296. }
  1297. BX_CHECK(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER)
  1298. , "glCheckFramebufferStatus failed 0x%08x"
  1299. , glCheckFramebufferStatus(GL_FRAMEBUFFER)
  1300. );
  1301. GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
  1302. }
  1303. void RenderTarget::destroy()
  1304. {
  1305. GL_CHECK(glDeleteFramebuffers(1, &m_fbo) );
  1306. if (0 != m_rbo)
  1307. {
  1308. GL_CHECK(glDeleteRenderbuffers(1, &m_rbo) );
  1309. }
  1310. m_color.destroy();
  1311. m_depth.destroy();
  1312. }
  1313. void ConstantBuffer::commit()
  1314. {
  1315. reset();
  1316. do
  1317. {
  1318. uint32_t opcode = read();
  1319. if (ConstantType::End == opcode)
  1320. {
  1321. break;
  1322. }
  1323. ConstantType::Enum type;
  1324. uint16_t loc;
  1325. uint16_t num;
  1326. uint16_t copy;
  1327. decodeOpcode(opcode, type, loc, num, copy);
  1328. const char* data;
  1329. if (copy)
  1330. {
  1331. data = read(g_constantTypeSize[type]*num);
  1332. }
  1333. else
  1334. {
  1335. memcpy(&data, read(sizeof(void*) ), sizeof(void*) );
  1336. }
  1337. #define CASE_IMPLEMENT_UNIFORM(_uniform, _glsuffix, _dxsuffix, _type) \
  1338. case ConstantType::_uniform: \
  1339. { \
  1340. _type* value = (_type*)data; \
  1341. GL_CHECK(glUniform##_glsuffix(loc, num, value) ); \
  1342. } \
  1343. break;
  1344. #define CASE_IMPLEMENT_UNIFORM_T(_uniform, _glsuffix, _dxsuffix, _type) \
  1345. case ConstantType::_uniform: \
  1346. { \
  1347. _type* value = (_type*)data; \
  1348. GL_CHECK(glUniform##_glsuffix(loc, num, GL_FALSE, value) ); \
  1349. } \
  1350. break;
  1351. switch (type)
  1352. {
  1353. // case ConstantType::Uniform1iv:
  1354. // {
  1355. // int* value = (int*)data;
  1356. // BX_TRACE("Uniform1iv sampler %d, loc %d (num %d, copy %d)", *value, loc, num, copy);
  1357. // GL_CHECK(glUniform1iv(loc, num, value) );
  1358. // }
  1359. // break;
  1360. CASE_IMPLEMENT_UNIFORM(Uniform1i, 1iv, I, int);
  1361. CASE_IMPLEMENT_UNIFORM(Uniform1f, 1fv, F, float);
  1362. CASE_IMPLEMENT_UNIFORM(Uniform1iv, 1iv, I, int);
  1363. CASE_IMPLEMENT_UNIFORM(Uniform1fv, 1fv, F, float);
  1364. CASE_IMPLEMENT_UNIFORM(Uniform2fv, 2fv, F, float);
  1365. CASE_IMPLEMENT_UNIFORM(Uniform3fv, 3fv, F, float);
  1366. CASE_IMPLEMENT_UNIFORM(Uniform4fv, 4fv, F, float);
  1367. CASE_IMPLEMENT_UNIFORM_T(Uniform3x3fv, Matrix3fv, F, float);
  1368. CASE_IMPLEMENT_UNIFORM_T(Uniform4x4fv, Matrix4fv, F, float);
  1369. case ConstantType::End:
  1370. break;
  1371. default:
  1372. BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", m_pos, opcode, type, loc, num, copy);
  1373. break;
  1374. }
  1375. #undef CASE_IMPLEMENT_UNIFORM
  1376. #undef CASE_IMPLEMENT_UNIFORM_T
  1377. } while (true);
  1378. }
  1379. void TextVideoMemBlitter::setup()
  1380. {
  1381. uint32_t width = s_renderCtx.m_resolution.m_width;
  1382. uint32_t height = s_renderCtx.m_resolution.m_height;
  1383. GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
  1384. GL_CHECK(glViewport(0, 0, width, height) );
  1385. GL_CHECK(glDisable(GL_DEPTH_TEST) );
  1386. GL_CHECK(glDepthFunc(GL_ALWAYS) );
  1387. GL_CHECK(glDisable(GL_CULL_FACE) );
  1388. GL_CHECK(glDisable(GL_BLEND) );
  1389. GL_CHECK(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE) );
  1390. #if BGFX_CONFIG_RENDERER_OPENGL
  1391. GL_CHECK(glDisable(GL_ALPHA_TEST) );
  1392. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1393. Material& material = s_renderCtx.m_materials[m_material.idx];
  1394. GL_CHECK(glUseProgram(material.m_id) );
  1395. GL_CHECK(glUniform1i(material.m_sampler[0], 0) );
  1396. float proj[16];
  1397. matrix_ortho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f);
  1398. GL_CHECK(glUniformMatrix4fv(material.m_predefined[0].m_loc
  1399. , 1
  1400. , GL_FALSE
  1401. , proj
  1402. ) );
  1403. GL_CHECK(glActiveTexture(GL_TEXTURE0) );
  1404. GL_CHECK(glBindTexture(GL_TEXTURE_2D, s_renderCtx.m_textures[m_texture.idx].m_id) );
  1405. }
  1406. void TextVideoMemBlitter::render(uint32_t _numIndices)
  1407. {
  1408. uint32_t numVertices = _numIndices*4/6;
  1409. s_renderCtx.m_indexBuffers[m_ib->handle.idx].update(0, _numIndices*2, m_ib->data);
  1410. s_renderCtx.m_vertexBuffers[m_vb->handle.idx].update(0, numVertices*m_decl.m_stride, m_vb->data);
  1411. VertexBuffer& vb = s_renderCtx.m_vertexBuffers[m_vb->handle.idx];
  1412. GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vb.m_id) );
  1413. IndexBuffer& ib = s_renderCtx.m_indexBuffers[m_ib->handle.idx];
  1414. GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib.m_id) );
  1415. Material& material = s_renderCtx.m_materials[m_material.idx];
  1416. material.bindAttributes(m_decl, 0);
  1417. GL_CHECK(glDrawElements(GL_TRIANGLES
  1418. , _numIndices
  1419. , GL_UNSIGNED_SHORT
  1420. , (void*)0
  1421. ) );
  1422. }
  1423. void Context::flip()
  1424. {
  1425. s_renderCtx.flip();
  1426. }
  1427. GLint glGet(GLenum _pname)
  1428. {
  1429. GLint result;
  1430. GL_CHECK(glGetIntegerv(_pname, &result) );
  1431. return result;
  1432. }
  1433. void Context::rendererInit()
  1434. {
  1435. s_renderCtx.init();
  1436. #if BGFX_CONFIG_DEBUG
  1437. GLint numCmpFormats;
  1438. GL_CHECK(glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numCmpFormats) );
  1439. BX_TRACE("GL_NUM_COMPRESSED_TEXTURE_FORMATS %d", numCmpFormats);
  1440. GLint* formats = (GLint*)alloca(sizeof(GLint)*numCmpFormats);
  1441. glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
  1442. for (GLint ii = 0; ii < numCmpFormats; ++ii)
  1443. {
  1444. BX_TRACE("\t%3d: %8x", ii, formats[ii]);
  1445. }
  1446. # define GL_GET(_pname, _min) BX_TRACE(#_pname " %d (min: %d)", glGet(_pname), _min)
  1447. GL_GET(GL_MAX_FRAGMENT_UNIFORM_VECTORS, 16);
  1448. GL_GET(GL_MAX_VERTEX_UNIFORM_VECTORS, 128);
  1449. GL_GET(GL_MAX_VARYING_VECTORS, 8);
  1450. GL_GET(GL_MAX_VERTEX_ATTRIBS, 8);
  1451. GL_GET(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, 8);
  1452. GL_GET(GL_MAX_CUBE_MAP_TEXTURE_SIZE, 16);
  1453. GL_GET(GL_MAX_TEXTURE_IMAGE_UNITS, 8);
  1454. GL_GET(GL_MAX_TEXTURE_SIZE, 64);
  1455. GL_GET(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, 0);
  1456. GL_GET(GL_MAX_RENDERBUFFER_SIZE, 1);
  1457. #endif // BGFX_CONFIG_DEBUG
  1458. const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
  1459. char name[1024];
  1460. const char* pos = extensions;
  1461. const char* end = extensions + strlen(extensions);
  1462. while (pos < end)
  1463. {
  1464. uint32_t len;
  1465. const char* space = strchr(pos, ' ');
  1466. if (NULL != space)
  1467. {
  1468. len = uint32_min(sizeof(name), (uint32_t)(space - pos) );
  1469. }
  1470. else
  1471. {
  1472. len = uint32_min(sizeof(name), (uint32_t)strlen(pos) );
  1473. }
  1474. strncpy(name, pos, len);
  1475. name[len] = '\0';
  1476. bool supported = false;
  1477. for (uint32_t ii = 0; ii < Extension::Count; ++ii)
  1478. {
  1479. Extension& extension = s_extension[ii];
  1480. if (!extension.m_supported
  1481. && extension.m_initialize)
  1482. {
  1483. if (0 == strcmp(name, extension.m_name) )
  1484. {
  1485. extension.m_supported = true;
  1486. supported = true;
  1487. break;
  1488. }
  1489. }
  1490. }
  1491. BX_TRACE("GL_EXTENSION%s: %s", supported ? " (supported)" : "", name);
  1492. BX_UNUSED(supported);
  1493. pos += len+1;
  1494. }
  1495. BX_TRACE("Supported extensions:");
  1496. for (uint32_t ii = 0; ii < Extension::Count; ++ii)
  1497. {
  1498. if (s_extension[ii].m_supported)
  1499. {
  1500. BX_TRACE("\t%2d: %s", ii, s_extension[ii].m_name);
  1501. }
  1502. }
  1503. s_renderCtx.m_dxtSupport = true
  1504. && s_extension[Extension::EXT_texture_compression_dxt1].m_supported
  1505. && s_extension[Extension::CHROMIUM_texture_compression_dxt3].m_supported
  1506. && s_extension[Extension::CHROMIUM_texture_compression_dxt5].m_supported
  1507. ;
  1508. s_renderCtx.m_dxtSupport |=
  1509. s_extension[Extension::EXT_texture_compression_s3tc].m_supported
  1510. ;
  1511. }
  1512. void Context::rendererShutdown()
  1513. {
  1514. s_renderCtx.shutdown();
  1515. }
  1516. void Context::rendererCreateIndexBuffer(IndexBufferHandle _handle, Memory* _mem)
  1517. {
  1518. s_renderCtx.m_indexBuffers[_handle.idx].create(_mem->size, _mem->data);
  1519. }
  1520. void Context::rendererDestroyIndexBuffer(IndexBufferHandle _handle)
  1521. {
  1522. s_renderCtx.m_indexBuffers[_handle.idx].destroy();
  1523. }
  1524. void Context::rendererCreateVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl)
  1525. {
  1526. VertexDecl& decl = s_renderCtx.m_vertexDecls[_handle.idx];
  1527. memcpy(&decl, &_decl, sizeof(VertexDecl) );
  1528. dump(decl);
  1529. }
  1530. void Context::rendererDestroyVertexDecl(VertexDeclHandle /*_handle*/)
  1531. {
  1532. }
  1533. void Context::rendererCreateVertexBuffer(VertexBufferHandle _handle, Memory* _mem, VertexDeclHandle _declHandle)
  1534. {
  1535. s_renderCtx.m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _declHandle);
  1536. }
  1537. void Context::rendererDestroyVertexBuffer(VertexBufferHandle _handle)
  1538. {
  1539. s_renderCtx.m_vertexBuffers[_handle.idx].destroy();
  1540. }
  1541. void Context::rendererCreateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size)
  1542. {
  1543. s_renderCtx.m_indexBuffers[_handle.idx].create(_size, NULL);
  1544. }
  1545. void Context::rendererUpdateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem)
  1546. {
  1547. s_renderCtx.m_indexBuffers[_handle.idx].update(_offset, uint32_min(_size, _mem->size), _mem->data);
  1548. }
  1549. void Context::rendererDestroyDynamicIndexBuffer(IndexBufferHandle _handle)
  1550. {
  1551. s_renderCtx.m_indexBuffers[_handle.idx].destroy();
  1552. }
  1553. void Context::rendererCreateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size)
  1554. {
  1555. VertexDeclHandle decl = BGFX_INVALID_HANDLE;
  1556. s_renderCtx.m_vertexBuffers[_handle.idx].create(_size, NULL, decl);
  1557. }
  1558. void Context::rendererUpdateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem)
  1559. {
  1560. s_renderCtx.m_vertexBuffers[_handle.idx].update(_offset, uint32_min(_size, _mem->size), _mem->data);
  1561. }
  1562. void Context::rendererDestroyDynamicVertexBuffer(VertexBufferHandle _handle)
  1563. {
  1564. s_renderCtx.m_vertexBuffers[_handle.idx].destroy();
  1565. }
  1566. void Context::rendererCreateVertexShader(VertexShaderHandle _handle, Memory* _mem)
  1567. {
  1568. s_renderCtx.m_vertexShaders[_handle.idx].create(GL_VERTEX_SHADER, _mem->data);
  1569. }
  1570. void Context::rendererDestroyVertexShader(VertexShaderHandle _handle)
  1571. {
  1572. s_renderCtx.m_vertexShaders[_handle.idx].destroy();
  1573. }
  1574. void Context::rendererCreateFragmentShader(FragmentShaderHandle _handle, Memory* _mem)
  1575. {
  1576. s_renderCtx.m_fragmentShaders[_handle.idx].create(GL_FRAGMENT_SHADER, _mem->data);
  1577. }
  1578. void Context::rendererDestroyFragmentShader(FragmentShaderHandle _handle)
  1579. {
  1580. s_renderCtx.m_fragmentShaders[_handle.idx].destroy();
  1581. }
  1582. void Context::rendererCreateMaterial(MaterialHandle _handle, VertexShaderHandle _vsh, FragmentShaderHandle _fsh)
  1583. {
  1584. s_renderCtx.m_materials[_handle.idx].create(s_renderCtx.m_vertexShaders[_vsh.idx], s_renderCtx.m_fragmentShaders[_fsh.idx]);
  1585. }
  1586. void Context::rendererDestroyMaterial(FragmentShaderHandle _handle)
  1587. {
  1588. s_renderCtx.m_materials[_handle.idx].destroy();
  1589. }
  1590. void Context::rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags)
  1591. {
  1592. s_renderCtx.m_textures[_handle.idx].create(_mem, _flags);
  1593. }
  1594. void Context::rendererDestroyTexture(TextureHandle _handle)
  1595. {
  1596. s_renderCtx.m_textures[_handle.idx].destroy();
  1597. }
  1598. void Context::rendererCreateRenderTarget(RenderTargetHandle _handle, uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags)
  1599. {
  1600. s_renderCtx.m_renderTargets[_handle.idx].create(_width, _height, _flags, _textureFlags);
  1601. }
  1602. void Context::rendererDestroyRenderTarget(RenderTargetHandle _handle)
  1603. {
  1604. s_renderCtx.m_renderTargets[_handle.idx].destroy();
  1605. }
  1606. void Context::rendererCreateUniform(UniformHandle _handle, ConstantType::Enum _type, uint16_t _num, const char* _name)
  1607. {
  1608. uint32_t size = g_constantTypeSize[_type]*_num;
  1609. void* data = g_realloc(NULL, size);
  1610. memset(data, 0, size);
  1611. s_renderCtx.m_uniforms[_handle.idx] = data;
  1612. s_renderCtx.m_uniformReg.reg(_name, s_renderCtx.m_uniforms[_handle.idx]);
  1613. }
  1614. void Context::rendererDestroyUniform(UniformHandle _handle)
  1615. {
  1616. g_free(s_renderCtx.m_uniforms[_handle.idx]);
  1617. }
  1618. void Context::rendererSaveScreenShot(Memory* _mem)
  1619. {
  1620. s_renderCtx.saveScreenShot(_mem);
  1621. }
  1622. void Context::rendererUpdateUniform(uint16_t _loc, const void* _data, uint32_t _size)
  1623. {
  1624. memcpy(s_renderCtx.m_uniforms[_loc], _data, _size);
  1625. }
  1626. void Context::rendererSubmit()
  1627. {
  1628. s_renderCtx.updateResolution(m_render->m_resolution);
  1629. int64_t elapsed = -bx::getHPCounter();
  1630. #if BGFX_CONFIG_RENDERER_OPENGL
  1631. if (m_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
  1632. {
  1633. s_renderCtx.m_queries.begin(0, GL_TIME_ELAPSED);
  1634. }
  1635. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1636. if (0 < m_render->m_iboffset)
  1637. {
  1638. TransientIndexBuffer* ib = m_render->m_transientIb;
  1639. s_renderCtx.m_indexBuffers[ib->handle.idx].update(0, m_render->m_iboffset, ib->data);
  1640. }
  1641. if (0 < m_render->m_vboffset)
  1642. {
  1643. TransientVertexBuffer* vb = m_render->m_transientVb;
  1644. s_renderCtx.m_vertexBuffers[vb->handle.idx].update(0, m_render->m_vboffset, vb->data);
  1645. }
  1646. m_render->sort();
  1647. RenderState currentState;
  1648. currentState.reset();
  1649. currentState.m_flags = BGFX_STATE_NONE;
  1650. Matrix4 viewProj[BGFX_CONFIG_MAX_VIEWS];
  1651. for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
  1652. {
  1653. matrix_mul(viewProj[ii].val, m_render->m_view[ii].val, m_render->m_proj[ii].val);
  1654. }
  1655. uint16_t materialIdx = invalidHandle;
  1656. SortKey key;
  1657. uint8_t view = 0xff;
  1658. RenderTargetHandle rt = BGFX_INVALID_HANDLE;
  1659. int32_t height = m_render->m_resolution.m_height;
  1660. float alphaRef = 0.0f;
  1661. GLenum primType = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? GL_LINES : GL_TRIANGLES;
  1662. uint32_t primNumVerts = 3;
  1663. uint32_t baseVertex = 0;
  1664. GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
  1665. uint32_t statsNumPrimsSubmitted = 0;
  1666. uint32_t statsNumIndices = 0;
  1667. uint32_t statsNumInstances = 0;
  1668. uint32_t statsNumPrimsRendered = 0;
  1669. if (0 == (m_render->m_debug&BGFX_DEBUG_IFH) )
  1670. {
  1671. for (uint32_t item = 0, numItems = m_render->m_num; item < numItems; ++item)
  1672. {
  1673. key.decode(m_render->m_sortKeys[item]);
  1674. const RenderState& state = m_render->m_renderState[m_render->m_sortValues[item] ];
  1675. const uint64_t newFlags = state.m_flags;
  1676. uint64_t changedFlags = currentState.m_flags ^ state.m_flags;
  1677. currentState.m_flags = newFlags;
  1678. if (key.m_view != view)
  1679. {
  1680. currentState.clear();
  1681. changedFlags = BGFX_STATE_MASK;
  1682. currentState.m_flags = newFlags;
  1683. GREMEDY_SETMARKER("view");
  1684. view = key.m_view;
  1685. materialIdx = invalidHandle;
  1686. if (m_render->m_rt[view].idx != rt.idx)
  1687. {
  1688. rt = m_render->m_rt[view];
  1689. if (rt.idx == invalidHandle)
  1690. {
  1691. GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
  1692. height = m_render->m_resolution.m_height;
  1693. }
  1694. else
  1695. {
  1696. RenderTarget& renderTarget = s_renderCtx.m_renderTargets[rt.idx];
  1697. GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, renderTarget.m_fbo) );
  1698. height = renderTarget.m_height;
  1699. }
  1700. }
  1701. Rect& rect = m_render->m_rect[view];
  1702. GL_CHECK(glViewport(rect.m_x, height-rect.m_height-rect.m_y, rect.m_width, rect.m_height) );
  1703. Clear& clear = m_render->m_clear[view];
  1704. if (BGFX_CLEAR_NONE != clear.m_flags)
  1705. {
  1706. GLuint flags = 0;
  1707. if (BGFX_CLEAR_COLOR_BIT & clear.m_flags)
  1708. {
  1709. flags |= GL_COLOR_BUFFER_BIT;
  1710. uint32_t rgba = clear.m_rgba;
  1711. float rr = (rgba>>24)/255.0f;
  1712. float gg = ( (rgba>>16)&0xff)/255.0f;
  1713. float bb = ( (rgba>>8)&0xff)/255.0f;
  1714. float aa = (rgba&0xff)/255.0f;
  1715. GL_CHECK(glClearColor(rr, gg, bb, aa) );
  1716. GL_CHECK(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE) );
  1717. }
  1718. if (BGFX_CLEAR_DEPTH_BIT & clear.m_flags)
  1719. {
  1720. flags |= GL_DEPTH_BUFFER_BIT;
  1721. GL_CHECK(glClearDepthf(clear.m_depth) );
  1722. GL_CHECK(glDepthMask(GL_TRUE) );
  1723. }
  1724. if (BGFX_CLEAR_STENCIL_BIT & clear.m_flags)
  1725. {
  1726. flags |= GL_STENCIL_BUFFER_BIT;
  1727. GL_CHECK(glClearStencil(clear.m_stencil) );
  1728. }
  1729. if (0 != flags)
  1730. {
  1731. GL_CHECK(glEnable(GL_SCISSOR_TEST) );
  1732. GL_CHECK(glScissor(rect.m_x, height-rect.m_height-rect.m_y, rect.m_width, rect.m_height) );
  1733. GL_CHECK(glClear(flags) );
  1734. GL_CHECK(glDisable(GL_SCISSOR_TEST) );
  1735. }
  1736. }
  1737. GL_CHECK(glEnable(GL_DEPTH_TEST) );
  1738. GL_CHECK(glDepthFunc(GL_LESS) );
  1739. GL_CHECK(glEnable(GL_CULL_FACE) );
  1740. GL_CHECK(glDisable(GL_BLEND) );
  1741. }
  1742. if ( (BGFX_STATE_CULL_MASK|BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK
  1743. |BGFX_STATE_ALPHA_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE
  1744. |BGFX_STATE_BLEND_MASK|BGFX_STATE_ALPHA_REF_MASK|BGFX_STATE_PT_MASK
  1745. |BGFX_STATE_POINT_SIZE_MASK) & changedFlags)
  1746. {
  1747. if (BGFX_STATE_CULL_MASK & changedFlags)
  1748. {
  1749. if (BGFX_STATE_CULL_CW & newFlags)
  1750. {
  1751. GL_CHECK(glEnable(GL_CULL_FACE) );
  1752. GL_CHECK(glCullFace(GL_BACK) );
  1753. }
  1754. else if (BGFX_STATE_CULL_CCW & newFlags)
  1755. {
  1756. GL_CHECK(glEnable(GL_CULL_FACE) );
  1757. GL_CHECK(glCullFace(GL_FRONT) );
  1758. }
  1759. else
  1760. {
  1761. GL_CHECK(glDisable(GL_CULL_FACE) );
  1762. }
  1763. }
  1764. if (BGFX_STATE_DEPTH_WRITE & changedFlags)
  1765. {
  1766. GL_CHECK(glDepthMask(!!(BGFX_STATE_DEPTH_WRITE & newFlags) ) );
  1767. }
  1768. if (BGFX_STATE_DEPTH_TEST_MASK & changedFlags)
  1769. {
  1770. uint32_t func = (newFlags&BGFX_STATE_DEPTH_TEST_MASK)>>BGFX_STATE_DEPTH_TEST_SHIFT;
  1771. if (0 != func)
  1772. {
  1773. GL_CHECK(glEnable(GL_DEPTH_TEST) );
  1774. GL_CHECK(glDepthFunc(s_depthFunc[func]) );
  1775. }
  1776. else
  1777. {
  1778. GL_CHECK(glDisable(GL_DEPTH_TEST) );
  1779. }
  1780. }
  1781. if ( (BGFX_STATE_ALPHA_TEST|BGFX_STATE_ALPHA_REF_MASK) & changedFlags)
  1782. {
  1783. uint32_t ref = (newFlags&BGFX_STATE_ALPHA_REF_MASK)>>BGFX_STATE_ALPHA_REF_SHIFT;
  1784. alphaRef = ref/255.0f;
  1785. #if BGFX_CONFIG_RENDERER_OPENGL
  1786. if (BGFX_STATE_ALPHA_TEST & newFlags)
  1787. {
  1788. GL_CHECK(glEnable(GL_ALPHA_TEST) );
  1789. }
  1790. else
  1791. {
  1792. GL_CHECK(glDisable(GL_ALPHA_TEST) );
  1793. }
  1794. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1795. }
  1796. #if BGFX_CONFIG_RENDERER_OPENGL
  1797. if ( (BGFX_STATE_PT_POINTS|BGFX_STATE_POINT_SIZE_MASK) & changedFlags)
  1798. {
  1799. float pointSize = (float)(uint32_max(1, (newFlags&BGFX_STATE_POINT_SIZE_MASK)>>BGFX_STATE_POINT_SIZE_SHIFT) );
  1800. GL_CHECK(glPointSize(pointSize) );
  1801. }
  1802. #endif // BGFX_CONFIG_RENDERER_OPENGL
  1803. if ( (BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE) & changedFlags)
  1804. {
  1805. GLboolean alpha = !!(newFlags&BGFX_STATE_ALPHA_WRITE);
  1806. GLboolean rgb = !!(newFlags&BGFX_STATE_RGB_WRITE);
  1807. GL_CHECK(glColorMask(rgb, rgb, rgb, alpha) );
  1808. }
  1809. if (BGFX_STATE_BLEND_MASK & changedFlags)
  1810. {
  1811. if (BGFX_STATE_BLEND_MASK & newFlags)
  1812. {
  1813. uint32_t blend = (newFlags&BGFX_STATE_BLEND_MASK)>>BGFX_STATE_BLEND_SHIFT;
  1814. uint32_t src = blend&0xf;
  1815. uint32_t dst = (blend>>4)&0xf;
  1816. GL_CHECK(glEnable(GL_BLEND) );
  1817. GL_CHECK(glBlendFunc(s_blendFactor[src][0], s_blendFactor[dst][1]) );
  1818. }
  1819. else
  1820. {
  1821. GL_CHECK(glDisable(GL_BLEND) );
  1822. }
  1823. }
  1824. uint8_t primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT);
  1825. primType = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? GL_LINES : s_primType[primIndex];
  1826. primNumVerts = s_primNumVerts[primIndex];
  1827. }
  1828. bool materialChanged = false;
  1829. bool constantsChanged = state.m_constBegin < state.m_constEnd;
  1830. bool bindAttribs = false;
  1831. rendererUpdateUniforms(m_render->m_constantBuffer, state.m_constBegin, state.m_constEnd);
  1832. if (key.m_material != materialIdx)
  1833. {
  1834. materialIdx = key.m_material;
  1835. GLuint id = invalidHandle == materialIdx ? 0 : s_renderCtx.m_materials[materialIdx].m_id;
  1836. GL_CHECK(glUseProgram(id) );
  1837. materialChanged =
  1838. constantsChanged =
  1839. bindAttribs = true;
  1840. }
  1841. if (invalidHandle != materialIdx)
  1842. {
  1843. Material& material = s_renderCtx.m_materials[materialIdx];
  1844. if (constantsChanged)
  1845. {
  1846. material.m_constantBuffer->commit();
  1847. }
  1848. for (uint32_t ii = 0, num = material.m_numPredefined; ii < num; ++ii)
  1849. {
  1850. PredefinedUniform& predefined = material.m_predefined[ii];
  1851. switch (predefined.m_type)
  1852. {
  1853. case PredefinedUniform::ViewRect:
  1854. {
  1855. float rect[4];
  1856. rect[0] = m_render->m_rect[view].m_x;
  1857. rect[1] = m_render->m_rect[view].m_y;
  1858. rect[2] = m_render->m_rect[view].m_width;
  1859. rect[3] = m_render->m_rect[view].m_height;
  1860. GL_CHECK(glUniform4fv(predefined.m_loc
  1861. , 1
  1862. , &rect[0]
  1863. ) );
  1864. }
  1865. break;
  1866. case PredefinedUniform::ViewTexel:
  1867. {
  1868. float rect[4];
  1869. rect[0] = 1.0f/float(m_render->m_rect[view].m_width);
  1870. rect[1] = 1.0f/float(m_render->m_rect[view].m_height);
  1871. GL_CHECK(glUniform4fv(predefined.m_loc
  1872. , 1
  1873. , &rect[0]
  1874. ) );
  1875. }
  1876. break;
  1877. case PredefinedUniform::View:
  1878. {
  1879. GL_CHECK(glUniformMatrix4fv(predefined.m_loc
  1880. , 1
  1881. , GL_FALSE
  1882. , m_render->m_view[view].val
  1883. ) );
  1884. }
  1885. break;
  1886. case PredefinedUniform::ViewProj:
  1887. {
  1888. GL_CHECK(glUniformMatrix4fv(predefined.m_loc
  1889. , 1
  1890. , GL_FALSE
  1891. , viewProj[view].val
  1892. ) );
  1893. }
  1894. break;
  1895. case PredefinedUniform::Model:
  1896. {
  1897. const Matrix4& model = m_render->m_matrixCache.m_cache[state.m_matrix];
  1898. GL_CHECK(glUniformMatrix4fv(predefined.m_loc
  1899. , uint32_min(predefined.m_count, state.m_num)
  1900. , GL_FALSE
  1901. , model.val
  1902. ) );
  1903. }
  1904. break;
  1905. case PredefinedUniform::ModelViewProj:
  1906. {
  1907. Matrix4 modelViewProj;
  1908. const Matrix4& model = m_render->m_matrixCache.m_cache[state.m_matrix];
  1909. matrix_mul(modelViewProj.val, model.val, viewProj[view].val);
  1910. GL_CHECK(glUniformMatrix4fv(predefined.m_loc
  1911. , 1
  1912. , GL_FALSE
  1913. , modelViewProj.val
  1914. ) );
  1915. }
  1916. break;
  1917. case PredefinedUniform::ModelViewProjX:
  1918. {
  1919. const Matrix4& model = m_render->m_matrixCache.m_cache[state.m_matrix];
  1920. static const BX_ALIGN_STRUCT_16(float) s_bias[16] =
  1921. {
  1922. 0.5f, 0.0f, 0.0f, 0.0f,
  1923. 0.0f, 0.5f, 0.0f, 0.0f,
  1924. 0.0f, 0.0f, 0.5f, 0.0f,
  1925. 0.5f, 0.5f, 0.5f, 1.0f,
  1926. };
  1927. uint8_t other = m_render->m_other[view];
  1928. Matrix4 viewProjBias;
  1929. matrix_mul(viewProjBias.val, viewProj[other].val, s_bias);
  1930. Matrix4 modelViewProj;
  1931. matrix_mul(modelViewProj.val, model.val, viewProjBias.val);
  1932. GL_CHECK(glUniformMatrix4fv(predefined.m_loc
  1933. , 1
  1934. , GL_FALSE
  1935. , modelViewProj.val
  1936. ) );
  1937. }
  1938. break;
  1939. case PredefinedUniform::ViewProjX:
  1940. {
  1941. static const BX_ALIGN_STRUCT_16(float) s_bias[16] =
  1942. {
  1943. 0.5f, 0.0f, 0.0f, 0.0f,
  1944. 0.0f, 0.5f, 0.0f, 0.0f,
  1945. 0.0f, 0.0f, 0.5f, 0.0f,
  1946. 0.5f, 0.5f, 0.5f, 1.0f,
  1947. };
  1948. uint8_t other = m_render->m_other[view];
  1949. Matrix4 viewProjBias;
  1950. matrix_mul(viewProjBias.val, viewProj[other].val, s_bias);
  1951. GL_CHECK(glUniformMatrix4fv(predefined.m_loc
  1952. , 1
  1953. , GL_FALSE
  1954. , viewProjBias.val
  1955. ) );
  1956. }
  1957. break;
  1958. case PredefinedUniform::AlphaRef:
  1959. {
  1960. GL_CHECK(glUniform1f(predefined.m_loc, alphaRef) );
  1961. }
  1962. break;
  1963. case PredefinedUniform::Count:
  1964. break;
  1965. }
  1966. }
  1967. // if (BGFX_STATE_TEX_MASK & changedFlags)
  1968. {
  1969. uint64_t flag = BGFX_STATE_TEX0;
  1970. for (uint32_t stage = 0; stage < BGFX_STATE_TEX_COUNT; ++stage)
  1971. {
  1972. const Sampler& sampler = state.m_sampler[stage];
  1973. Sampler& current = currentState.m_sampler[stage];
  1974. if (current.m_idx != sampler.m_idx
  1975. || current.m_flags != sampler.m_flags
  1976. || materialChanged)
  1977. {
  1978. if (invalidHandle != sampler.m_idx)
  1979. {
  1980. GL_CHECK(glActiveTexture(GL_TEXTURE0+stage) );
  1981. switch (sampler.m_flags&BGFX_SAMPLER_TYPE_MASK)
  1982. {
  1983. case BGFX_SAMPLER_TEXTURE:
  1984. {
  1985. const Texture& texture = s_renderCtx.m_textures[sampler.m_idx];
  1986. GL_CHECK(glBindTexture(texture.m_target, texture.m_id) );
  1987. }
  1988. break;
  1989. case BGFX_SAMPLER_RENDERTARGET_COLOR:
  1990. {
  1991. const RenderTarget& rt = s_renderCtx.m_renderTargets[sampler.m_idx];
  1992. GL_CHECK(glBindTexture(rt.m_color.m_target, rt.m_color.m_id) );
  1993. }
  1994. break;
  1995. case BGFX_SAMPLER_RENDERTARGET_DEPTH:
  1996. {
  1997. const RenderTarget& rt = s_renderCtx.m_renderTargets[sampler.m_idx];
  1998. GL_CHECK(glBindTexture(rt.m_depth.m_target, rt.m_depth.m_id) );
  1999. }
  2000. break;
  2001. }
  2002. }
  2003. }
  2004. current = sampler;
  2005. flag <<= 1;
  2006. }
  2007. }
  2008. if (currentState.m_vertexBuffer.idx != state.m_vertexBuffer.idx || materialChanged)
  2009. {
  2010. currentState.m_vertexBuffer = state.m_vertexBuffer;
  2011. uint16_t handle = state.m_vertexBuffer.idx;
  2012. if (invalidHandle != handle)
  2013. {
  2014. VertexBuffer& vb = s_renderCtx.m_vertexBuffers[handle];
  2015. GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vb.m_id) );
  2016. bindAttribs = true;
  2017. }
  2018. else
  2019. {
  2020. GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0) );
  2021. }
  2022. }
  2023. if (currentState.m_indexBuffer.idx != state.m_indexBuffer.idx)
  2024. {
  2025. currentState.m_indexBuffer = state.m_indexBuffer;
  2026. uint16_t handle = state.m_indexBuffer.idx;
  2027. if (invalidHandle != handle)
  2028. {
  2029. IndexBuffer& ib = s_renderCtx.m_indexBuffers[handle];
  2030. GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib.m_id) );
  2031. }
  2032. else
  2033. {
  2034. GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) );
  2035. }
  2036. }
  2037. if (invalidHandle != currentState.m_vertexBuffer.idx)
  2038. {
  2039. if (baseVertex != state.m_startVertex
  2040. || bindAttribs)
  2041. {
  2042. baseVertex = state.m_startVertex;
  2043. VertexBuffer& vb = s_renderCtx.m_vertexBuffers[state.m_vertexBuffer.idx];
  2044. uint16_t decl = vb.m_decl.idx == invalidHandle ? state.m_vertexDecl.idx : vb.m_decl.idx;
  2045. const Material& material = s_renderCtx.m_materials[materialIdx];
  2046. material.bindAttributes(s_renderCtx.m_vertexDecls[decl], state.m_startVertex);
  2047. if (invalidHandle != state.m_instanceDataBuffer.idx)
  2048. {
  2049. GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, s_renderCtx.m_vertexBuffers[state.m_instanceDataBuffer.idx].m_id) );
  2050. material.bindInstanceData(state.m_instanceDataStride, state.m_instanceDataOffset);
  2051. }
  2052. }
  2053. uint32_t numIndices = 0;
  2054. uint32_t numPrimsSubmitted = 0;
  2055. uint32_t numInstances = 0;
  2056. uint32_t numPrimsRendered = 0;
  2057. if (invalidHandle != state.m_indexBuffer.idx)
  2058. {
  2059. if (BGFX_DRAW_WHOLE_INDEX_BUFFER == state.m_startIndex)
  2060. {
  2061. numIndices = s_renderCtx.m_indexBuffers[state.m_indexBuffer.idx].m_size/2;
  2062. numPrimsSubmitted = numIndices/primNumVerts;
  2063. numInstances = state.m_numInstances;
  2064. numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
  2065. GL_CHECK(s_drawElementsInstanced(primType
  2066. , numIndices
  2067. , GL_UNSIGNED_SHORT
  2068. , (void*)0
  2069. , state.m_numInstances
  2070. ) );
  2071. }
  2072. else if (primNumVerts <= state.m_numIndices)
  2073. {
  2074. numIndices = state.m_numIndices;
  2075. numPrimsSubmitted = numIndices/primNumVerts;
  2076. numInstances = state.m_numInstances;
  2077. numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
  2078. GL_CHECK(s_drawElementsInstanced(primType
  2079. , numIndices
  2080. , GL_UNSIGNED_SHORT
  2081. , (void*)(uintptr_t)(state.m_startIndex*2)
  2082. , state.m_numInstances
  2083. ) );
  2084. }
  2085. }
  2086. else
  2087. {
  2088. numPrimsSubmitted = state.m_numVertices/primNumVerts;
  2089. numInstances = state.m_numInstances;
  2090. numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
  2091. GL_CHECK(s_drawArraysInstanced(primType
  2092. , 0
  2093. , state.m_numVertices
  2094. , state.m_numInstances
  2095. ) );
  2096. }
  2097. statsNumPrimsSubmitted += numPrimsSubmitted;
  2098. statsNumIndices += numIndices;
  2099. statsNumInstances += numInstances;
  2100. statsNumPrimsRendered += numPrimsRendered;
  2101. }
  2102. }
  2103. }
  2104. }
  2105. int64_t now = bx::getHPCounter();
  2106. elapsed += now;
  2107. static int64_t last = now;
  2108. int64_t frameTime = now - last;
  2109. last = now;
  2110. static int64_t min = frameTime;
  2111. static int64_t max = frameTime;
  2112. min = min > frameTime ? frameTime : min;
  2113. max = max < frameTime ? frameTime : max;
  2114. if (m_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
  2115. {
  2116. double elapsedGpuMs = 0.0;
  2117. #if BGFX_CONFIG_RENDERER_OPENGL
  2118. s_renderCtx.m_queries.end(GL_TIME_ELAPSED);
  2119. uint64_t elapsedGl = s_renderCtx.m_queries.getResult(0);
  2120. elapsedGpuMs = double(elapsedGl)/1e6;
  2121. #endif // BGFX_CONFIG_RENDERER_OPENGL
  2122. TextVideoMem& tvm = s_renderCtx.m_textVideoMem;
  2123. static int64_t next = now;
  2124. if (now >= next)
  2125. {
  2126. next = now + bx::getHPFrequency();
  2127. double freq = double(bx::getHPFrequency() );
  2128. double toMs = 1000.0/freq;
  2129. double elapsedCpuMs = double(elapsed)*toMs;
  2130. tvm.clear();
  2131. uint16_t pos = 10;
  2132. tvm.printf(0, 0, 0x8f, " " BGFX_RENDERER_NAME " ");
  2133. tvm.printf(10, pos++, 0x8e, " Frame CPU: %7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] / % 6.2f FPS"
  2134. , double(frameTime)*toMs
  2135. , double(min)*toMs
  2136. , double(max)*toMs
  2137. , freq/frameTime
  2138. );
  2139. tvm.printf(10, pos++, 0x8e, " Draw calls: %4d / CPU %3.4f [ms] %c GPU %3.4f [ms]"
  2140. , m_render->m_num
  2141. , elapsedCpuMs
  2142. , elapsedCpuMs > elapsedGpuMs ? '>' : '<'
  2143. , elapsedGpuMs
  2144. );
  2145. tvm.printf(10, pos++, 0x8e, " Prims: %7d (#inst: %5d), submitted: %7d"
  2146. , statsNumPrimsRendered
  2147. , statsNumInstances
  2148. , statsNumPrimsSubmitted
  2149. );
  2150. tvm.printf(10, pos++, 0x8e, " Indices: %7d", statsNumIndices);
  2151. tvm.printf(10, pos++, 0x8e, " DVB size: %7d", m_render->m_vboffset);
  2152. tvm.printf(10, pos++, 0x8e, " DIB size: %7d", m_render->m_iboffset);
  2153. #if BGFX_CONFIG_RENDERER_OPENGL
  2154. if (s_extension[Extension::ATI_meminfo].m_supported)
  2155. {
  2156. GLint vboFree[4];
  2157. GL_CHECK(glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, vboFree) );
  2158. GLint texFree[4];
  2159. GL_CHECK(glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, texFree) );
  2160. GLint rbfFree[4];
  2161. GL_CHECK(glGetIntegerv(GL_RENDERBUFFER_FREE_MEMORY_ATI, rbfFree) );
  2162. pos++;
  2163. tvm.printf(10, pos++, 0x8c, " -------------| free| free b| aux| aux fb");
  2164. tvm.printf(10, pos++, 0x8e, " VBO: %7d, %7d, %7d, %7d", vboFree[0], vboFree[1], vboFree[2], vboFree[3]);
  2165. tvm.printf(10, pos++, 0x8e, " Texture: %7d, %7d, %7d, %7d", texFree[0], texFree[1], texFree[2], texFree[3]);
  2166. tvm.printf(10, pos++, 0x8e, " Render Buffer: %7d, %7d, %7d, %7d", rbfFree[0], rbfFree[1], rbfFree[2], rbfFree[3]);
  2167. }
  2168. else if (s_extension[Extension::NVX_gpu_memory_info].m_supported)
  2169. {
  2170. GLint dedicated;
  2171. GL_CHECK(glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated) );
  2172. GLint totalAvail;
  2173. GL_CHECK(glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &totalAvail) );
  2174. GLint currAvail;
  2175. GL_CHECK(glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &currAvail) );
  2176. GLint evictedCount;
  2177. GL_CHECK(glGetIntegerv(GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX, &evictedCount) );
  2178. GLint evictedMemory;
  2179. GL_CHECK(glGetIntegerv(GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX, &evictedMemory) );
  2180. pos++;
  2181. tvm.printf(10, pos++, 0x8c, "----------|");
  2182. tvm.printf(10, pos++, 0x8e, " Dedicated: %7d", dedicated);
  2183. tvm.printf(10, pos++, 0x8e, " Available: %7d (%7d)", currAvail, totalAvail);
  2184. tvm.printf(10, pos++, 0x8e, " Eviction: %7d / %7d", evictedCount, evictedMemory);
  2185. }
  2186. #endif // BGFX_CONFIG_RENDERER_OPENGL
  2187. uint8_t attr[2] = { 0x89, 0x8a };
  2188. uint8_t attrIndex = m_render->m_waitSubmit < m_render->m_waitRender;
  2189. pos++;
  2190. tvm.printf(10, pos++, attr[attrIndex&1], "Submit wait: %3.4f [ms]", double(m_render->m_waitSubmit)*toMs);
  2191. tvm.printf(10, pos++, attr[(attrIndex+1)&1], "Render wait: %3.4f [ms]", double(m_render->m_waitRender)*toMs);
  2192. min = frameTime;
  2193. max = frameTime;
  2194. }
  2195. m_textVideoMemBlitter.blit(tvm);
  2196. }
  2197. else if (m_render->m_debug & BGFX_DEBUG_TEXT)
  2198. {
  2199. m_textVideoMemBlitter.blit(m_render->m_textVideoMem);
  2200. }
  2201. GREMEDY_FRAMETERMINATOR();
  2202. }
  2203. }
  2204. #endif // (BGFX_CONFIG_RENDERER_OPENGLES|BGFX_CONFIG_RENDERER_OPENGL)