GLInstancingRenderer.cpp 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856
  1. #ifndef NO_OPENGL3
  2. /*
  3. Copyright (c) 2012 Advanced Micro Devices, Inc.
  4. This software is provided 'as-is', without any express or implied warranty.
  5. In no event will the authors be held liable for any damages arising from the use of this software.
  6. Permission is granted to anyone to use this software for any purpose,
  7. including commercial applications, and to alter it and redistribute it freely,
  8. subject to the following restrictions:
  9. 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
  10. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  11. 3. This notice may not be removed or altered from any source distribution.
  12. */
  13. //Originally written by Erwin Coumans
  14. ///todo: make this configurable in the gui
  15. bool useShadowMap = true;// true;//false;//true;
  16. int shadowMapWidth= 2048;
  17. int shadowMapHeight= 2048;
  18. float shadowMapWorldSize=5;
  19. #define MAX_POINTS_IN_BATCH 1024
  20. #define MAX_LINES_IN_BATCH 1024
  21. #include "OpenGLInclude.h"
  22. #include "../CommonInterfaces/CommonWindowInterface.h"
  23. //#include "Bullet3Common/b3MinMax.h"
  24. #ifndef __APPLE__
  25. #ifndef glVertexAttribDivisor
  26. #define glVertexAttribDivisor glVertexAttribDivisorARB
  27. #endif //glVertexAttribDivisor
  28. #ifndef GL_COMPARE_REF_TO_TEXTURE
  29. #define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE
  30. #endif //GL_COMPARE_REF_TO_TEXTURE
  31. #ifndef glDrawElementsInstanced
  32. #define glDrawElementsInstanced glDrawElementsInstancedARB
  33. #endif
  34. #endif //__APPLE__
  35. #include "GLInstancingRenderer.h"
  36. #include <string.h>
  37. //#include "DemoSettings.h"
  38. #include <stdio.h>
  39. #include "Bullet3Common/b3Vector3.h"
  40. #include "Bullet3Common/b3Quaternion.h"
  41. #include "Bullet3Common/b3Matrix3x3.h"
  42. #include "LoadShader.h"
  43. #include "GLInstanceRendererInternalData.h"
  44. //GLSL shader strings, embedded using build3/stringify
  45. #include "Shaders/pointSpriteVS.h"
  46. #include "Shaders/pointSpritePS.h"
  47. #include "Shaders/instancingVS.h"
  48. #include "Shaders/instancingPS.h"
  49. #include "Shaders/createShadowMapInstancingVS.h"
  50. #include "Shaders/createShadowMapInstancingPS.h"
  51. #include "Shaders/useShadowMapInstancingVS.h"
  52. #include "Shaders/useShadowMapInstancingPS.h"
  53. #include "Shaders/linesPS.h"
  54. #include "Shaders/linesVS.h"
  55. #include "GLRenderToTexture.h"
  56. //#include "../../opencl/gpu_rigidbody_pipeline/b3GpuNarrowphaseAndSolver.h"//for m_maxNumObjectCapacity
  57. static InternalDataRenderer* sData2;
  58. GLint lineWidthRange[2]={1,1};
  59. static b3Vector3 gLightPos=b3MakeVector3(-5,12,-4);
  60. struct b3GraphicsInstance
  61. {
  62. GLuint m_cube_vao;
  63. GLuint m_index_vbo;
  64. GLuint m_texturehandle;
  65. int m_numIndices;
  66. int m_numVertices;
  67. int m_numGraphicsInstances;
  68. int m_instanceOffset;
  69. int m_vertexArrayOffset;
  70. int m_primitiveType;
  71. b3GraphicsInstance()
  72. :m_cube_vao(-1),
  73. m_index_vbo(-1),
  74. m_texturehandle(0),
  75. m_numIndices(-1),
  76. m_numVertices(-1),
  77. m_numGraphicsInstances(0),
  78. m_instanceOffset(0),
  79. m_vertexArrayOffset(0),
  80. m_primitiveType(B3_GL_TRIANGLES)
  81. {
  82. }
  83. };
  84. bool m_ortho = false;
  85. //static GLfloat depthLightModelviewMatrix[16];
  86. static void checkError(const char *functionName)
  87. {
  88. GLenum error;
  89. while (( error = glGetError() ) != GL_NO_ERROR)
  90. {
  91. fprintf (stderr, "GL error 0x%X detected in %s\n", error, functionName);
  92. }
  93. }
  94. extern int gShapeIndex;
  95. struct InternalTextureHandle
  96. {
  97. GLuint m_glTexture;
  98. int m_width;
  99. int m_height;
  100. };
  101. struct InternalDataRenderer : public GLInstanceRendererInternalData
  102. {
  103. SimpleCamera m_defaultCamera1;
  104. CommonCameraInterface* m_activeCamera;
  105. GLfloat m_projectionMatrix[16];
  106. GLfloat m_viewMatrix[16];
  107. GLuint m_defaultTexturehandle;
  108. b3AlignedObjectArray<InternalTextureHandle> m_textureHandles;
  109. GLRenderToTexture* m_shadowMap;
  110. GLuint m_shadowTexture;
  111. GLuint m_renderFrameBuffer;
  112. InternalDataRenderer() :
  113. m_shadowMap(0),
  114. m_shadowTexture(0),
  115. m_renderFrameBuffer(0),
  116. m_activeCamera(&m_defaultCamera1)
  117. {
  118. //clear to zero to make it obvious if the matrix is used uninitialized
  119. for (int i=0;i<16;i++)
  120. {
  121. m_projectionMatrix[i]=0;
  122. m_viewMatrix[i]=0;
  123. }
  124. }
  125. };
  126. struct GLInstanceRendererInternalData* GLInstancingRenderer::getInternalData()
  127. {
  128. return m_data;
  129. }
  130. static GLuint linesShader; // The line renderer
  131. static GLuint useShadowMapInstancingShader; // The shadow instancing renderer
  132. static GLuint createShadowMapInstancingShader; // The shadow instancing renderer
  133. static GLuint instancingShader; // The instancing renderer
  134. static GLuint instancingShaderPointSprite; // The point sprite instancing renderer
  135. //static bool done = false;
  136. static GLint lines_ModelViewMatrix=0;
  137. static GLint lines_ProjectionMatrix=0;
  138. static GLint lines_position=0;
  139. static GLint lines_colour=0;
  140. GLuint lineVertexBufferObject=0;
  141. GLuint lineVertexArrayObject=0;
  142. GLuint lineIndexVbo = 0;
  143. GLuint linesVertexBufferObject=0;
  144. GLuint linesVertexArrayObject=0;
  145. GLuint linesIndexVbo = 0;
  146. static GLint useShadow_ModelViewMatrix=0;
  147. static GLint useShadow_MVP=0;
  148. static GLint useShadow_lightDirIn=0;
  149. static GLint useShadow_ProjectionMatrix=0;
  150. static GLint useShadow_DepthBiasModelViewMatrix=0;
  151. static GLint useShadow_uniform_texture_diffuse = 0;
  152. static GLint useShadow_shadowMap = 0;
  153. static GLint createShadow_depthMVP=0;
  154. static GLint ModelViewMatrix=0;
  155. static GLint ProjectionMatrix=0;
  156. static GLint regularLightDirIn=0;
  157. static GLint uniform_texture_diffuse = 0;
  158. static GLint screenWidthPointSprite=0;
  159. static GLint ModelViewMatrixPointSprite=0;
  160. static GLint ProjectionMatrixPointSprite=0;
  161. //static GLint uniform_texture_diffusePointSprite= 0;
  162. GLInstancingRenderer::GLInstancingRenderer(int maxNumObjectCapacity, int maxShapeCapacityInBytes)
  163. :
  164. m_textureenabled(true),
  165. m_textureinitialized(false),
  166. m_screenWidth(0),
  167. m_screenHeight(0),
  168. m_upAxis(1),
  169. m_enableBlend(false)
  170. {
  171. m_data = new InternalDataRenderer;
  172. m_data->m_maxNumObjectCapacity = maxNumObjectCapacity;
  173. m_data->m_maxShapeCapacityInBytes=maxShapeCapacityInBytes;
  174. m_data->m_totalNumInstances = 0;
  175. sData2 = m_data;
  176. m_data->m_instance_positions_ptr.resize(m_data->m_maxNumObjectCapacity*4);
  177. m_data->m_instance_quaternion_ptr.resize(m_data->m_maxNumObjectCapacity*4);
  178. m_data->m_instance_colors_ptr.resize(m_data->m_maxNumObjectCapacity*4);
  179. m_data->m_instance_scale_ptr.resize(m_data->m_maxNumObjectCapacity*3);
  180. }
  181. void GLInstancingRenderer::removeAllInstances()
  182. {
  183. m_data->m_totalNumInstances = 0;
  184. for (int i=0;i<m_graphicsInstances.size();i++)
  185. {
  186. if (m_graphicsInstances[i]->m_index_vbo)
  187. {
  188. glDeleteBuffers(1,&m_graphicsInstances[i]->m_index_vbo);
  189. }
  190. if (m_graphicsInstances[i]->m_cube_vao)
  191. {
  192. glDeleteVertexArrays(1,&m_graphicsInstances[i]->m_cube_vao);
  193. }
  194. delete m_graphicsInstances[i];
  195. }
  196. m_graphicsInstances.clear();
  197. }
  198. GLInstancingRenderer::~GLInstancingRenderer()
  199. {
  200. delete m_data->m_shadowMap;
  201. glDeleteTextures(1,&m_data->m_shadowTexture);
  202. glDeleteTextures(1,&m_data->m_defaultTexturehandle);
  203. removeAllInstances();
  204. sData2=0;
  205. if (m_data)
  206. {
  207. if (m_data->m_vbo)
  208. glDeleteBuffers(1,&m_data->m_vbo);
  209. }
  210. delete m_data;
  211. }
  212. void GLInstancingRenderer::writeSingleInstanceTransformToCPU(const float* position, const float* orientation, int srcIndex)
  213. {
  214. b3Assert(srcIndex<m_data->m_totalNumInstances);
  215. b3Assert(srcIndex>=0);
  216. m_data->m_instance_positions_ptr[srcIndex*4+0]=position[0];
  217. m_data->m_instance_positions_ptr[srcIndex*4+1]=position[1];
  218. m_data->m_instance_positions_ptr[srcIndex*4+2]=position[2];
  219. m_data->m_instance_positions_ptr[srcIndex*4+3]=1;
  220. m_data->m_instance_quaternion_ptr[srcIndex*4+0]=orientation[0];
  221. m_data->m_instance_quaternion_ptr[srcIndex*4+1]=orientation[1];
  222. m_data->m_instance_quaternion_ptr[srcIndex*4+2]=orientation[2];
  223. m_data->m_instance_quaternion_ptr[srcIndex*4+3]=orientation[3];
  224. /* m_data->m_instance_colors_ptr[srcIndex*4+0]=color[0];
  225. m_data->m_instance_colors_ptr[srcIndex*4+1]=color[1];
  226. m_data->m_instance_colors_ptr[srcIndex*4+2]=color[2];
  227. m_data->m_instance_colors_ptr[srcIndex*4+3]=color[3];
  228. */
  229. }
  230. void GLInstancingRenderer::readSingleInstanceTransformFromCPU(int srcIndex, float* position, float* orientation)
  231. {
  232. b3Assert(srcIndex<m_data->m_totalNumInstances);
  233. b3Assert(srcIndex>=0);
  234. position[0] = m_data->m_instance_positions_ptr[srcIndex*4+0];
  235. position[1] = m_data->m_instance_positions_ptr[srcIndex*4+1];
  236. position[2] = m_data->m_instance_positions_ptr[srcIndex*4+2];
  237. orientation[0] = m_data->m_instance_quaternion_ptr[srcIndex*4+0];
  238. orientation[1] = m_data->m_instance_quaternion_ptr[srcIndex*4+1];
  239. orientation[2] = m_data->m_instance_quaternion_ptr[srcIndex*4+2];
  240. orientation[3] = m_data->m_instance_quaternion_ptr[srcIndex*4+3];
  241. }
  242. void GLInstancingRenderer::writeSingleInstanceColorToCPU(double* color, int srcIndex)
  243. {
  244. m_data->m_instance_colors_ptr[srcIndex*4+0]=float(color[0]);
  245. m_data->m_instance_colors_ptr[srcIndex*4+1]=float(color[1]);
  246. m_data->m_instance_colors_ptr[srcIndex*4+2]=float(color[2]);
  247. m_data->m_instance_colors_ptr[srcIndex*4+3]=float(color[3]);
  248. }
  249. void GLInstancingRenderer::writeSingleInstanceColorToCPU(float* color, int srcIndex)
  250. {
  251. m_data->m_instance_colors_ptr[srcIndex*4+0]=color[0];
  252. m_data->m_instance_colors_ptr[srcIndex*4+1]=color[1];
  253. m_data->m_instance_colors_ptr[srcIndex*4+2]=color[2];
  254. m_data->m_instance_colors_ptr[srcIndex*4+3]=color[3];
  255. }
  256. void GLInstancingRenderer::writeSingleInstanceScaleToCPU(float* scale, int srcIndex)
  257. {
  258. m_data->m_instance_scale_ptr[srcIndex*3+0]=scale[0];
  259. m_data->m_instance_scale_ptr[srcIndex*3+1]=scale[1];
  260. m_data->m_instance_scale_ptr[srcIndex*3+2]=scale[2];
  261. }
  262. void GLInstancingRenderer::writeSingleInstanceScaleToCPU(double* scale, int srcIndex)
  263. {
  264. m_data->m_instance_scale_ptr[srcIndex*3+0]=scale[0];
  265. m_data->m_instance_scale_ptr[srcIndex*3+1]=scale[1];
  266. m_data->m_instance_scale_ptr[srcIndex*3+2]=scale[2];
  267. }
  268. void GLInstancingRenderer::writeSingleInstanceTransformToGPU(float* position, float* orientation, int objectIndex)
  269. {
  270. glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
  271. //glFlush();
  272. char* orgBase = (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_READ_WRITE);
  273. //b3GraphicsInstance* gfxObj = m_graphicsInstances[k];
  274. int totalNumInstances= 0;
  275. for (int k=0;k<m_graphicsInstances.size();k++)
  276. {
  277. b3GraphicsInstance* gfxObj = m_graphicsInstances[k];
  278. totalNumInstances+=gfxObj->m_numGraphicsInstances;
  279. }
  280. int POSITION_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4);
  281. char* base = orgBase;
  282. float* positions = (float*)(base+m_data->m_maxShapeCapacityInBytes);
  283. float* orientations = (float*)(base+m_data->m_maxShapeCapacityInBytes + POSITION_BUFFER_SIZE);
  284. positions[objectIndex*4] = position[0];
  285. positions[objectIndex*4+1] = position[1];
  286. positions[objectIndex*4+2] = position[2];
  287. positions[objectIndex*4+3] = position[3];
  288. orientations [objectIndex*4] = orientation[0];
  289. orientations [objectIndex*4+1] = orientation[1];
  290. orientations [objectIndex*4+2] = orientation[2];
  291. orientations [objectIndex*4+3] = orientation[3];
  292. glUnmapBuffer( GL_ARRAY_BUFFER);
  293. //glFlush();
  294. }
  295. void GLInstancingRenderer::writeTransforms()
  296. {
  297. {
  298. B3_PROFILE("b3Assert(glGetError() 1");
  299. b3Assert(glGetError() ==GL_NO_ERROR);
  300. }
  301. {
  302. B3_PROFILE("glBindBuffer");
  303. glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
  304. }
  305. {
  306. B3_PROFILE("glFlush()");
  307. //without the flush, the glBufferSubData can spike to really slow (seconds slow)
  308. glFlush();
  309. }
  310. {
  311. B3_PROFILE("b3Assert(glGetError() 2");
  312. b3Assert(glGetError() ==GL_NO_ERROR);
  313. }
  314. #ifdef B3_DEBUG
  315. {
  316. //B3_PROFILE("m_data->m_totalNumInstances == totalNumInstances");
  317. int totalNumInstances= 0;
  318. for (int k=0;k<m_graphicsInstances.size();k++)
  319. {
  320. b3GraphicsInstance* gfxObj = m_graphicsInstances[k];
  321. totalNumInstances+=gfxObj->m_numGraphicsInstances;
  322. }
  323. b3Assert(m_data->m_totalNumInstances == totalNumInstances);
  324. }
  325. #endif//B3_DEBUG
  326. int POSITION_BUFFER_SIZE = (m_data->m_totalNumInstances*sizeof(float)*4);
  327. int ORIENTATION_BUFFER_SIZE = (m_data->m_totalNumInstances*sizeof(float)*4);
  328. int COLOR_BUFFER_SIZE = (m_data->m_totalNumInstances*sizeof(float)*4);
  329. // int SCALE_BUFFER_SIZE = (totalNumInstances*sizeof(float)*3);
  330. #if 1
  331. {
  332. // printf("m_data->m_totalNumInstances = %d\n", m_data->m_totalNumInstances);
  333. {
  334. B3_PROFILE("glBufferSubData pos");
  335. glBufferSubData( GL_ARRAY_BUFFER,m_data->m_maxShapeCapacityInBytes,m_data->m_totalNumInstances*sizeof(float)*4,
  336. &m_data->m_instance_positions_ptr[0]);
  337. }
  338. {
  339. B3_PROFILE("glBufferSubData orn");
  340. glBufferSubData( GL_ARRAY_BUFFER,m_data->m_maxShapeCapacityInBytes+POSITION_BUFFER_SIZE,m_data->m_totalNumInstances*sizeof(float)*4,
  341. &m_data->m_instance_quaternion_ptr[0]);
  342. }
  343. {
  344. B3_PROFILE("glBufferSubData color");
  345. glBufferSubData( GL_ARRAY_BUFFER,m_data->m_maxShapeCapacityInBytes+ POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE, m_data->m_totalNumInstances*sizeof(float)*4,
  346. &m_data->m_instance_colors_ptr[0]);
  347. }
  348. {
  349. B3_PROFILE("glBufferSubData scale");
  350. glBufferSubData( GL_ARRAY_BUFFER, m_data->m_maxShapeCapacityInBytes+POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE+COLOR_BUFFER_SIZE,m_data->m_totalNumInstances*sizeof(float)*3,
  351. &m_data->m_instance_scale_ptr[0]);
  352. }
  353. }
  354. #else
  355. char* orgBase = (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_READ_WRITE);
  356. if (orgBase)
  357. {
  358. for (int k=0;k<m_graphicsInstances.size();k++)
  359. {
  360. //int k=0;
  361. b3GraphicsInstance* gfxObj = m_graphicsInstances[k];
  362. char* base = orgBase;
  363. float* positions = (float*)(base+m_data->m_maxShapeCapacityInBytes);
  364. float* orientations = (float*)(base+m_data->m_maxShapeCapacityInBytes + POSITION_BUFFER_SIZE);
  365. float* colors= (float*)(base+m_data->m_maxShapeCapacityInBytes + POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE);
  366. float* scaling= (float*)(base+m_data->m_maxShapeCapacityInBytes + POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE+COLOR_BUFFER_SIZE);
  367. //static int offset=0;
  368. //offset++;
  369. for (int i=0;i<gfxObj->m_numGraphicsInstances;i++)
  370. {
  371. int srcIndex=i+gfxObj->m_instanceOffset;
  372. positions[srcIndex*4] = m_data->m_instance_positions_ptr[srcIndex*4];
  373. positions[srcIndex*4+1] = m_data->m_instance_positions_ptr[srcIndex*4+1];
  374. positions[srcIndex*4+2] = m_data->m_instance_positions_ptr[srcIndex*4+2];
  375. positions[srcIndex*4+3] = m_data->m_instance_positions_ptr[srcIndex*4+3];
  376. orientations[srcIndex*4]=m_data->m_instance_quaternion_ptr[srcIndex*4];
  377. orientations[srcIndex*4+1]=m_data->m_instance_quaternion_ptr[srcIndex*4+1];
  378. orientations[srcIndex*4+2]=m_data->m_instance_quaternion_ptr[srcIndex*4+2];
  379. orientations[srcIndex*4+3]=m_data->m_instance_quaternion_ptr[srcIndex*4+3];
  380. colors[srcIndex*4]=m_data->m_instance_colors_ptr[srcIndex*4];
  381. colors[srcIndex*4+1]=m_data->m_instance_colors_ptr[srcIndex*4+1];
  382. colors[srcIndex*4+2]=m_data->m_instance_colors_ptr[srcIndex*4+2];
  383. colors[srcIndex*4+3]=m_data->m_instance_colors_ptr[srcIndex*4+3];
  384. scaling[srcIndex*3]=m_data->m_instance_scale_ptr[srcIndex*3];
  385. scaling[srcIndex*3+1]=m_data->m_instance_scale_ptr[srcIndex*3+1];
  386. scaling[srcIndex*3+2]=m_data->m_instance_scale_ptr[srcIndex*3+2];
  387. }
  388. }
  389. } else
  390. {
  391. b3Error("ERROR glMapBuffer failed\n");
  392. }
  393. b3Assert(glGetError() ==GL_NO_ERROR);
  394. glUnmapBuffer( GL_ARRAY_BUFFER);
  395. //if this glFinish is removed, the animation is not always working/blocks
  396. //@todo: figure out why
  397. //glFlush();
  398. #endif
  399. {
  400. B3_PROFILE("glBindBuffer 2");
  401. glBindBuffer(GL_ARRAY_BUFFER, 0);//m_data->m_vbo);
  402. }
  403. {
  404. B3_PROFILE("b3Assert(glGetError() 4");
  405. b3Assert(glGetError() ==GL_NO_ERROR);
  406. }
  407. }
  408. int GLInstancingRenderer::registerGraphicsInstance(int shapeIndex, const double* pos1, const double* orn1, const double* color1, const double* scaling1)
  409. {
  410. float pos[4] = {(float)pos1[0],(float)pos1[1],(float)pos1[2],(float)pos1[3]};
  411. float orn[4] = {(float)orn1[0],(float)orn1[1],(float)orn1[2],(float)orn1[3]};
  412. float color[4] = {(float)color1[0],(float)color1[1],(float)color1[2],(float)color1[3]};
  413. float scaling[4] = {(float)scaling1[0],(float)scaling1[1],(float)scaling1[2],(float)scaling1[3]};
  414. return registerGraphicsInstance(shapeIndex,pos,orn,color,scaling);
  415. }
  416. int GLInstancingRenderer::registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling)
  417. {
  418. b3Assert(shapeIndex == (m_graphicsInstances.size()-1));
  419. b3Assert(m_graphicsInstances.size()<m_data->m_maxNumObjectCapacity-1);
  420. b3GraphicsInstance* gfxObj = m_graphicsInstances[shapeIndex];
  421. int index = gfxObj->m_numGraphicsInstances + gfxObj->m_instanceOffset;
  422. int maxElements = m_data->m_instance_positions_ptr.size();
  423. if (index*4<maxElements)
  424. {
  425. m_data->m_instance_positions_ptr[index*4]=position[0];
  426. m_data->m_instance_positions_ptr[index*4+1]=position[1];
  427. m_data->m_instance_positions_ptr[index*4+2]=position[2];
  428. m_data->m_instance_positions_ptr[index*4+3]=1;
  429. m_data->m_instance_quaternion_ptr[index*4]=quaternion[0];
  430. m_data->m_instance_quaternion_ptr[index*4+1]=quaternion[1];
  431. m_data->m_instance_quaternion_ptr[index*4+2]=quaternion[2];
  432. m_data->m_instance_quaternion_ptr[index*4+3]=quaternion[3];
  433. m_data->m_instance_colors_ptr[index*4]=color[0];
  434. m_data->m_instance_colors_ptr[index*4+1]=color[1];
  435. m_data->m_instance_colors_ptr[index*4+2]=color[2];
  436. m_data->m_instance_colors_ptr[index*4+3]=color[3];
  437. m_data->m_instance_scale_ptr[index*3] = scaling[0];
  438. m_data->m_instance_scale_ptr[index*3+1] = scaling[1];
  439. m_data->m_instance_scale_ptr[index*3+2] = scaling[2];
  440. gfxObj->m_numGraphicsInstances++;
  441. m_data->m_totalNumInstances++;
  442. } else
  443. {
  444. b3Error("registerGraphicsInstance out of range, %d\n", maxElements);
  445. return -1;
  446. }
  447. return index;//gfxObj->m_numGraphicsInstances;
  448. }
  449. int GLInstancingRenderer::registerTexture(const unsigned char* texels, int width, int height)
  450. {
  451. b3Assert(glGetError() ==GL_NO_ERROR);
  452. glActiveTexture(GL_TEXTURE0);
  453. int textureIndex = m_data->m_textureHandles.size();
  454. const GLubyte* image= (const GLubyte*)texels;
  455. GLuint textureHandle;
  456. glGenTextures(1,(GLuint*)&textureHandle);
  457. glBindTexture(GL_TEXTURE_2D,textureHandle);
  458. b3Assert(glGetError() ==GL_NO_ERROR);
  459. InternalTextureHandle h;
  460. h.m_glTexture = textureHandle;
  461. h.m_width = width;
  462. h.m_height = height;
  463. m_data->m_textureHandles.push_back(h);
  464. updateTexture(textureIndex, texels);
  465. return textureIndex;
  466. }
  467. void GLInstancingRenderer::updateTexture(int textureIndex, const unsigned char* texels)
  468. {
  469. if (textureIndex>=0)
  470. {
  471. glActiveTexture(GL_TEXTURE0);
  472. b3Assert(glGetError() ==GL_NO_ERROR);
  473. InternalTextureHandle& h = m_data->m_textureHandles[textureIndex];
  474. //textures need to be flipped for OpenGL...
  475. b3AlignedObjectArray<unsigned char> flippedTexels;
  476. flippedTexels.resize(h.m_width* h.m_height * 3);
  477. for (int i = 0; i < h.m_width; i++)
  478. {
  479. for (int j = 0; j < h.m_height; j++)
  480. {
  481. flippedTexels[(i + j*h.m_width) * 3] = texels[(i + (h.m_height - 1 -j )*h.m_width) * 3];
  482. flippedTexels[(i + j*h.m_width) * 3+1] = texels[(i + (h.m_height - 1 - j)*h.m_width) * 3+1];
  483. flippedTexels[(i + j*h.m_width) * 3+2] = texels[(i + (h.m_height - 1 - j)*h.m_width) * 3+2];
  484. }
  485. }
  486. glBindTexture(GL_TEXTURE_2D,h.m_glTexture);
  487. b3Assert(glGetError() ==GL_NO_ERROR);
  488. const GLubyte* image= (const GLubyte*)texels;
  489. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, h.m_width,h.m_height,0,GL_RGB,GL_UNSIGNED_BYTE,&flippedTexels[0]);
  490. b3Assert(glGetError() ==GL_NO_ERROR);
  491. glGenerateMipmap(GL_TEXTURE_2D);
  492. b3Assert(glGetError() ==GL_NO_ERROR);
  493. }
  494. }
  495. void GLInstancingRenderer::activateTexture(int textureIndex)
  496. {
  497. glActiveTexture(GL_TEXTURE0);
  498. if (textureIndex>=0)
  499. {
  500. glBindTexture(GL_TEXTURE_2D,m_data->m_textureHandles[textureIndex].m_glTexture);
  501. } else
  502. {
  503. glBindTexture(GL_TEXTURE_2D,0);
  504. }
  505. }
  506. void GLInstancingRenderer::updateShape(int shapeIndex, const float* vertices)
  507. {
  508. b3GraphicsInstance* gfxObj = m_graphicsInstances[shapeIndex];
  509. int numvertices = gfxObj->m_numVertices;
  510. glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
  511. char* dest= (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_WRITE_ONLY);//GL_WRITE_ONLY
  512. int vertexStrideInBytes = 9*sizeof(float);
  513. int sz = numvertices*vertexStrideInBytes;
  514. memcpy(dest+vertexStrideInBytes*gfxObj->m_vertexArrayOffset,vertices,sz);
  515. glUnmapBuffer( GL_ARRAY_BUFFER);
  516. }
  517. int GLInstancingRenderer::registerShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId)
  518. {
  519. b3GraphicsInstance* gfxObj = new b3GraphicsInstance;
  520. if (textureId>=0)
  521. {
  522. gfxObj->m_texturehandle = m_data->m_textureHandles[textureId].m_glTexture;
  523. }
  524. gfxObj->m_primitiveType = primitiveType;
  525. if (m_graphicsInstances.size())
  526. {
  527. b3GraphicsInstance* prevObj = m_graphicsInstances[m_graphicsInstances.size()-1];
  528. gfxObj->m_instanceOffset = prevObj->m_instanceOffset + prevObj->m_numGraphicsInstances;
  529. gfxObj->m_vertexArrayOffset = prevObj->m_vertexArrayOffset + prevObj->m_numVertices;
  530. } else
  531. {
  532. gfxObj->m_instanceOffset = 0;
  533. }
  534. m_graphicsInstances.push_back(gfxObj);
  535. gfxObj->m_numIndices = numIndices;
  536. gfxObj->m_numVertices = numvertices;
  537. glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
  538. int vertexStrideInBytes = 9*sizeof(float);
  539. int sz = numvertices*vertexStrideInBytes;
  540. #if 0
  541. char* dest= (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_WRITE_ONLY);//GL_WRITE_ONLY
  542. #ifdef B3_DEBUG
  543. int totalUsed = vertexStrideInBytes*gfxObj->m_vertexArrayOffset+sz;
  544. b3Assert(totalUsed<m_data->m_maxShapeCapacityInBytes);
  545. #endif//B3_DEBUG
  546. memcpy(dest+vertexStrideInBytes*gfxObj->m_vertexArrayOffset,vertices,sz);
  547. glUnmapBuffer( GL_ARRAY_BUFFER);
  548. #else
  549. glBufferSubData( GL_ARRAY_BUFFER,vertexStrideInBytes*gfxObj->m_vertexArrayOffset,sz,
  550. vertices);
  551. #endif
  552. glGenBuffers(1, &gfxObj->m_index_vbo);
  553. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gfxObj->m_index_vbo);
  554. int indexBufferSizeInBytes = gfxObj->m_numIndices*sizeof(int);
  555. glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSizeInBytes, NULL, GL_STATIC_DRAW);
  556. glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,0,indexBufferSizeInBytes,indices);
  557. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  558. glGenVertexArrays(1, &gfxObj->m_cube_vao);
  559. glBindVertexArray(gfxObj->m_cube_vao);
  560. glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
  561. glBindVertexArray(0);
  562. glBindBuffer(GL_ARRAY_BUFFER,0);
  563. glBindVertexArray(0);
  564. return m_graphicsInstances.size()-1;
  565. }
  566. void GLInstancingRenderer::InitShaders()
  567. {
  568. int POSITION_BUFFER_SIZE = (m_data->m_maxNumObjectCapacity*sizeof(float)*4);
  569. int ORIENTATION_BUFFER_SIZE = (m_data->m_maxNumObjectCapacity*sizeof(float)*4);
  570. int COLOR_BUFFER_SIZE = (m_data->m_maxNumObjectCapacity*sizeof(float)*4);
  571. int SCALE_BUFFER_SIZE = (m_data->m_maxNumObjectCapacity*sizeof(float)*3);
  572. linesShader = gltLoadShaderPair(linesVertexShader,linesFragmentShader);
  573. lines_ModelViewMatrix = glGetUniformLocation(linesShader, "ModelViewMatrix");
  574. lines_ProjectionMatrix = glGetUniformLocation(linesShader, "ProjectionMatrix");
  575. lines_colour=glGetUniformLocation(linesShader, "colour");
  576. lines_position=glGetAttribLocation(linesShader, "position");
  577. glLinkProgram(linesShader);
  578. glUseProgram(linesShader);
  579. {
  580. glGenVertexArrays(1, &linesVertexArrayObject);
  581. glBindVertexArray(linesVertexArrayObject);
  582. glGenBuffers(1, &linesVertexBufferObject);
  583. glGenBuffers(1, &linesIndexVbo);
  584. int sz = MAX_LINES_IN_BATCH*sizeof(b3Vector3);
  585. glBindVertexArray(linesVertexArrayObject);
  586. glBindBuffer(GL_ARRAY_BUFFER, linesVertexBufferObject);
  587. glBufferData(GL_ARRAY_BUFFER, sz, 0, GL_DYNAMIC_DRAW);
  588. glBindVertexArray(0);
  589. }
  590. {
  591. glGenVertexArrays(1, &lineVertexArrayObject);
  592. glBindVertexArray(lineVertexArrayObject);
  593. glGenBuffers(1, &lineVertexBufferObject);
  594. glGenBuffers(1, &lineIndexVbo);
  595. int sz = MAX_POINTS_IN_BATCH*sizeof(b3Vector3);
  596. glBindVertexArray(lineVertexArrayObject);
  597. glBindBuffer(GL_ARRAY_BUFFER, lineVertexBufferObject);
  598. glBufferData(GL_ARRAY_BUFFER, sz, 0, GL_DYNAMIC_DRAW);
  599. glBindVertexArray(0);
  600. }
  601. //glGetIntegerv(GL_ALIASED_LINE_WIDTH_RANGE, range);
  602. glGetIntegerv(GL_SMOOTH_LINE_WIDTH_RANGE, lineWidthRange);
  603. useShadowMapInstancingShader = gltLoadShaderPair(useShadowMapInstancingVertexShader,useShadowMapInstancingFragmentShader);
  604. glLinkProgram(useShadowMapInstancingShader);
  605. glUseProgram(useShadowMapInstancingShader);
  606. useShadow_ModelViewMatrix = glGetUniformLocation(useShadowMapInstancingShader, "ModelViewMatrix");
  607. useShadow_MVP = glGetUniformLocation(useShadowMapInstancingShader, "MVP");
  608. useShadow_ProjectionMatrix = glGetUniformLocation(useShadowMapInstancingShader, "ProjectionMatrix");
  609. useShadow_DepthBiasModelViewMatrix = glGetUniformLocation(useShadowMapInstancingShader, "DepthBiasModelViewProjectionMatrix");
  610. useShadow_uniform_texture_diffuse = glGetUniformLocation(useShadowMapInstancingShader, "Diffuse");
  611. useShadow_shadowMap = glGetUniformLocation(useShadowMapInstancingShader,"shadowMap");
  612. useShadow_lightDirIn = glGetUniformLocation(useShadowMapInstancingShader,"lightDirIn");
  613. createShadowMapInstancingShader = gltLoadShaderPair(createShadowMapInstancingVertexShader,createShadowMapInstancingFragmentShader);
  614. glLinkProgram(createShadowMapInstancingShader);
  615. glUseProgram(createShadowMapInstancingShader);
  616. createShadow_depthMVP = glGetUniformLocation(createShadowMapInstancingShader, "depthMVP");
  617. glUseProgram(0);
  618. instancingShader = gltLoadShaderPair(instancingVertexShader,instancingFragmentShader);
  619. glLinkProgram(instancingShader);
  620. glUseProgram(instancingShader);
  621. ModelViewMatrix = glGetUniformLocation(instancingShader, "ModelViewMatrix");
  622. ProjectionMatrix = glGetUniformLocation(instancingShader, "ProjectionMatrix");
  623. uniform_texture_diffuse = glGetUniformLocation(instancingShader, "Diffuse");
  624. regularLightDirIn = glGetUniformLocation(instancingShader,"lightDirIn");
  625. glUseProgram(0);
  626. instancingShaderPointSprite = gltLoadShaderPair(pointSpriteVertexShader,pointSpriteFragmentShader);
  627. glUseProgram(instancingShaderPointSprite);
  628. ModelViewMatrixPointSprite = glGetUniformLocation(instancingShaderPointSprite, "ModelViewMatrix");
  629. ProjectionMatrixPointSprite = glGetUniformLocation(instancingShaderPointSprite, "ProjectionMatrix");
  630. screenWidthPointSprite = glGetUniformLocation(instancingShaderPointSprite, "screenWidth");
  631. glUseProgram(0);
  632. //GLuint offset = 0;
  633. glGenBuffers(1, &m_data->m_vbo);
  634. checkError("glGenBuffers");
  635. glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
  636. int size = m_data->m_maxShapeCapacityInBytes + POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE+COLOR_BUFFER_SIZE+SCALE_BUFFER_SIZE;
  637. m_data->m_vboSize = size;
  638. glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);//GL_STATIC_DRAW);
  639. glBindBuffer(GL_ARRAY_BUFFER,0);
  640. glBindVertexArray(0);
  641. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  642. }
  643. void GLInstancingRenderer::init()
  644. {
  645. b3Assert(glGetError() ==GL_NO_ERROR);
  646. glEnable(GL_DEPTH_TEST);
  647. glDepthFunc(GL_LESS);
  648. b3Assert(glGetError() ==GL_NO_ERROR);
  649. // glClearColor(float(0.),float(0.),float(0.4),float(0));
  650. b3Assert(glGetError() ==GL_NO_ERROR);
  651. b3Assert(glGetError() ==GL_NO_ERROR);
  652. {
  653. B3_PROFILE("texture");
  654. if(m_textureenabled)
  655. {
  656. if(!m_textureinitialized)
  657. {
  658. glActiveTexture(GL_TEXTURE0);
  659. GLubyte* image=new GLubyte[256*256*3];
  660. for(int y=0;y<256;++y)
  661. {
  662. // const int t=y>>5;
  663. GLubyte* pi=image+y*256*3;
  664. for(int x=0;x<256;++x)
  665. {
  666. if (x<2||y<2||x>253||y>253)
  667. {
  668. pi[0]=255;//0;
  669. pi[1]=255;//0;
  670. pi[2]=255;//0;
  671. } else
  672. {
  673. pi[0]=255;
  674. pi[1]=255;
  675. pi[2]=255;
  676. }
  677. /*
  678. const int s=x>>5;
  679. const GLubyte b=180;
  680. GLubyte c=b+((s+t&1)&1)*(255-b);
  681. pi[0]=c;
  682. pi[1]=c;
  683. pi[2]=c;
  684. */
  685. pi+=3;
  686. }
  687. }
  688. glGenTextures(1,(GLuint*)&m_data->m_defaultTexturehandle);
  689. glBindTexture(GL_TEXTURE_2D,m_data->m_defaultTexturehandle);
  690. b3Assert(glGetError() ==GL_NO_ERROR);
  691. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256,256,0,GL_RGB,GL_UNSIGNED_BYTE,image);
  692. glGenerateMipmap(GL_TEXTURE_2D);
  693. b3Assert(glGetError() ==GL_NO_ERROR);
  694. delete[] image;
  695. m_textureinitialized=true;
  696. }
  697. b3Assert(glGetError() ==GL_NO_ERROR);
  698. glBindTexture(GL_TEXTURE_2D,m_data->m_defaultTexturehandle);
  699. b3Assert(glGetError() ==GL_NO_ERROR);
  700. } else
  701. {
  702. glDisable(GL_TEXTURE_2D);
  703. b3Assert(glGetError() ==GL_NO_ERROR);
  704. }
  705. }
  706. //glEnable(GL_COLOR_MATERIAL);
  707. b3Assert(glGetError() ==GL_NO_ERROR);
  708. // glEnable(GL_CULL_FACE);
  709. // glCullFace(GL_BACK);
  710. }
  711. void GLInstancingRenderer::resize(int width, int height)
  712. {
  713. m_screenWidth = width;
  714. m_screenHeight = height;
  715. }
  716. const CommonCameraInterface* GLInstancingRenderer::getActiveCamera() const
  717. {
  718. return m_data->m_activeCamera;
  719. }
  720. CommonCameraInterface* GLInstancingRenderer::getActiveCamera()
  721. {
  722. return m_data->m_activeCamera;
  723. }
  724. void GLInstancingRenderer::setActiveCamera(CommonCameraInterface* cam)
  725. {
  726. m_data->m_activeCamera = cam;
  727. }
  728. void GLInstancingRenderer::updateCamera(int upAxis)
  729. {
  730. b3Assert(glGetError() ==GL_NO_ERROR);
  731. m_upAxis = upAxis;
  732. switch (upAxis)
  733. {
  734. case 1:
  735. gLightPos = b3MakeVector3(-50.f,100,30);
  736. break;
  737. case 2:
  738. gLightPos = b3MakeVector3(-50.f,30,100);
  739. break;
  740. default:
  741. b3Assert(0);
  742. };
  743. m_data->m_activeCamera->setCameraUpAxis(upAxis);
  744. m_data->m_activeCamera->setAspectRatio((float)m_screenWidth/(float)m_screenHeight);
  745. m_data->m_defaultCamera1.update();
  746. m_data->m_activeCamera->getCameraProjectionMatrix(m_data->m_projectionMatrix);
  747. m_data->m_activeCamera->getCameraViewMatrix(m_data->m_viewMatrix);
  748. }
  749. //#define STB_IMAGE_WRITE_IMPLEMENTATION
  750. #include "stb_image_write.h"
  751. void writeTextureToPng(int textureWidth, int textureHeight, const char* fileName, int numComponents)
  752. {
  753. b3Assert(glGetError() ==GL_NO_ERROR);
  754. glPixelStorei(GL_PACK_ALIGNMENT,4);
  755. glReadBuffer(GL_NONE);
  756. float* orgPixels = (float*)malloc(textureWidth*textureHeight*numComponents*4);
  757. char* pixels = (char*)malloc(textureWidth*textureHeight*numComponents*4);
  758. glReadPixels(0,0,textureWidth, textureHeight, GL_DEPTH_COMPONENT, GL_FLOAT, orgPixels);
  759. b3Assert(glGetError() ==GL_NO_ERROR);
  760. for (int j=0;j<textureHeight;j++)
  761. {
  762. for (int i=0;i<textureWidth;i++)
  763. {
  764. float val = orgPixels[(j*textureWidth+i)];
  765. if (val!=1.f)
  766. {
  767. //printf("val[%d,%d]=%f\n", i,j,val);
  768. }
  769. pixels[(j*textureWidth+i)*numComponents]=char(orgPixels[(j*textureWidth+i)]*255.f);
  770. pixels[(j*textureWidth+i)*numComponents+1]=0;//255.f;
  771. pixels[(j*textureWidth+i)*numComponents+2]=0;//255.f;
  772. pixels[(j*textureWidth+i)*numComponents+3]=127;
  773. //pixels[(j*textureWidth+i)*+1]=val;
  774. //pixels[(j*textureWidth+i)*numComponents+2]=val;
  775. //pixels[(j*textureWidth+i)*numComponents+3]=255;
  776. }
  777. /* pixels[(j*textureWidth+j)*numComponents]=255;
  778. pixels[(j*textureWidth+j)*numComponents+1]=0;
  779. pixels[(j*textureWidth+j)*numComponents+2]=0;
  780. pixels[(j*textureWidth+j)*numComponents+3]=255;
  781. */
  782. }
  783. if (0)
  784. {
  785. //swap the pixels
  786. unsigned char tmp;
  787. for (int j=0;j<textureHeight/2;j++)
  788. {
  789. for (int i=0;i<textureWidth;i++)
  790. {
  791. for (int c=0;c<numComponents;c++)
  792. {
  793. tmp = pixels[(j*textureWidth+i)*numComponents+c];
  794. pixels[(j*textureWidth+i)*numComponents+c]=
  795. pixels[((textureHeight-j-1)*textureWidth+i)*numComponents+c];
  796. pixels[((textureHeight-j-1)*textureWidth+i)*numComponents+c] = tmp;
  797. }
  798. }
  799. }
  800. }
  801. stbi_write_png(fileName, textureWidth,textureHeight, numComponents, pixels, textureWidth*numComponents);
  802. free(pixels);
  803. }
  804. void GLInstancingRenderer::renderScene()
  805. {
  806. //avoid some Intel driver on a Macbook Pro to lock-up
  807. //todo: figure out what is going on on that machine
  808. //glFlush();
  809. if (useShadowMap)
  810. {
  811. renderSceneInternal(B3_CREATE_SHADOWMAP_RENDERMODE);
  812. //glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  813. renderSceneInternal(B3_USE_SHADOWMAP_RENDERMODE);
  814. } else
  815. {
  816. renderSceneInternal();
  817. }
  818. }
  819. void GLInstancingRenderer::drawPoint(const double* position, const double color[4], double pointDrawSize)
  820. {
  821. float pos[4]={(float)position[0],(float)position[1],(float)position[2],0};
  822. float clr[4] = {(float)color[0],(float)color[1],(float)color[2],(float)color[3]};
  823. drawPoints(pos,clr,1,3*sizeof(float),float(pointDrawSize));
  824. }
  825. void GLInstancingRenderer::drawPoint(const float* positions, const float color[4], float pointDrawSize)
  826. {
  827. drawPoints(positions,color,1,3*sizeof(float),pointDrawSize);
  828. }
  829. void GLInstancingRenderer::drawPoints(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, float pointDrawSize)
  830. {
  831. glActiveTexture(GL_TEXTURE0);
  832. glBindTexture(GL_TEXTURE_2D,0);
  833. b3Assert(glGetError() ==GL_NO_ERROR);
  834. glUseProgram(linesShader);
  835. glUniformMatrix4fv(lines_ProjectionMatrix, 1, false, &m_data->m_projectionMatrix[0]);
  836. glUniformMatrix4fv(lines_ModelViewMatrix, 1, false, &m_data->m_viewMatrix[0]);
  837. glUniform4f(lines_colour,color[0],color[1],color[2],color[3]);
  838. glPointSize(pointDrawSize);
  839. glBindVertexArray(lineVertexArrayObject);
  840. glBindBuffer(GL_ARRAY_BUFFER, lineVertexBufferObject);
  841. int maxPointsInBatch = MAX_POINTS_IN_BATCH;
  842. int remainingPoints = numPoints;
  843. int offsetNumPoints= 0;
  844. while (1)
  845. {
  846. int curPointsInBatch = b3Min(maxPointsInBatch, remainingPoints);
  847. if (curPointsInBatch)
  848. {
  849. glBufferSubData(GL_ARRAY_BUFFER, 0, curPointsInBatch*pointStrideInBytes, positions + offsetNumPoints*(pointStrideInBytes / sizeof(float)));
  850. glEnableVertexAttribArray(0);
  851. int numFloats = 3;// pointStrideInBytes / sizeof(float);
  852. glVertexAttribPointer(0, numFloats, GL_FLOAT, GL_FALSE, pointStrideInBytes, 0);
  853. glDrawArrays(GL_POINTS, 0, curPointsInBatch);
  854. remainingPoints -= curPointsInBatch;
  855. offsetNumPoints += curPointsInBatch;
  856. }
  857. else
  858. {
  859. break;
  860. }
  861. }
  862. glBindVertexArray(0);
  863. glPointSize(1);
  864. glUseProgram(0);
  865. }
  866. void GLInstancingRenderer::drawLines(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, const unsigned int* indices, int numIndices, float lineWidthIn)
  867. {
  868. glActiveTexture(GL_TEXTURE0);
  869. glBindTexture(GL_TEXTURE_2D,0);
  870. float lineWidth = lineWidthIn;
  871. b3Clamp(lineWidth,(float)lineWidthRange[0],(float)lineWidthRange[1]);
  872. glLineWidth(lineWidth);
  873. glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
  874. b3Assert(glGetError() ==GL_NO_ERROR);
  875. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  876. glActiveTexture(GL_TEXTURE0);
  877. glBindTexture(GL_TEXTURE_2D,0);
  878. b3Assert(glGetError() ==GL_NO_ERROR);
  879. glUseProgram(linesShader);
  880. glUniformMatrix4fv(lines_ProjectionMatrix, 1, false, &m_data->m_projectionMatrix[0]);
  881. glUniformMatrix4fv(lines_ModelViewMatrix, 1, false, &m_data->m_viewMatrix[0]);
  882. glUniform4f(lines_colour,color[0],color[1],color[2],color[3]);
  883. // glPointSize(pointDrawSize);
  884. glBindVertexArray(linesVertexArrayObject);
  885. b3Assert(glGetError() ==GL_NO_ERROR);
  886. glBindBuffer(GL_ARRAY_BUFFER, linesVertexBufferObject);
  887. {
  888. glBufferData(GL_ARRAY_BUFFER, numPoints*pointStrideInBytes, 0,GL_DYNAMIC_DRAW);
  889. glBufferSubData(GL_ARRAY_BUFFER, 0, numPoints*pointStrideInBytes, positions);
  890. b3Assert(glGetError() ==GL_NO_ERROR);
  891. glBindBuffer(GL_ARRAY_BUFFER, 0);
  892. glBindBuffer(GL_ARRAY_BUFFER, linesVertexBufferObject);
  893. glEnableVertexAttribArray(0);
  894. b3Assert(glGetError() ==GL_NO_ERROR);
  895. int numFloats = 3;
  896. glVertexAttribPointer(0, numFloats, GL_FLOAT, GL_FALSE, pointStrideInBytes, 0);
  897. b3Assert(glGetError() ==GL_NO_ERROR);
  898. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, linesIndexVbo);
  899. int indexBufferSizeInBytes = numIndices*sizeof(int);
  900. glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSizeInBytes, NULL, GL_DYNAMIC_DRAW);
  901. glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indexBufferSizeInBytes, indices);
  902. glDrawElements(GL_LINES, numIndices, GL_UNSIGNED_INT, 0);
  903. }
  904. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  905. glBindBuffer(GL_ARRAY_BUFFER, 0);
  906. // for (int i=0;i<numIndices;i++)
  907. // printf("indicec[i]=%d]\n",indices[i]);
  908. b3Assert(glGetError() ==GL_NO_ERROR);
  909. glBindVertexArray(0);
  910. b3Assert(glGetError() ==GL_NO_ERROR);
  911. glPointSize(1);
  912. b3Assert(glGetError() ==GL_NO_ERROR);
  913. glUseProgram(0);
  914. }
  915. void GLInstancingRenderer::drawLine(const double fromIn[4], const double toIn[4], const double colorIn[4], double lineWidthIn)
  916. {
  917. float from[4]={float(fromIn[0]),float(fromIn[1]),float(fromIn[2]),float(fromIn[3])};
  918. float to[4]={float(toIn[0]),float(toIn[1]),float(toIn[2]),float(toIn[3])};
  919. float color[4]={float(colorIn[0]),float(colorIn[1]),float(colorIn[2]),float(colorIn[3])};
  920. float lineWidth=float(lineWidthIn);
  921. drawLine(from,to,color,lineWidth);
  922. }
  923. void GLInstancingRenderer::drawLine(const float from[4], const float to[4], const float color[4], float lineWidth)
  924. {
  925. b3Assert(glGetError() ==GL_NO_ERROR);
  926. glActiveTexture(GL_TEXTURE0);
  927. glBindTexture(GL_TEXTURE_2D,0);
  928. b3Assert(glGetError() ==GL_NO_ERROR);
  929. glUseProgram(linesShader);
  930. b3Assert(glGetError() ==GL_NO_ERROR);
  931. glUniformMatrix4fv(lines_ProjectionMatrix, 1, false, &m_data->m_projectionMatrix[0]);
  932. glUniformMatrix4fv(lines_ModelViewMatrix, 1, false, &m_data->m_viewMatrix[0]);
  933. glUniform4f(lines_colour,color[0],color[1],color[2],color[3]);
  934. b3Assert(glGetError() ==GL_NO_ERROR);
  935. const float vertexPositions[] = {
  936. from[0],from[1],from[2],1,
  937. to[0],to[1],to[2],1
  938. };
  939. int sz = sizeof(vertexPositions);
  940. b3Assert(glGetError() ==GL_NO_ERROR);
  941. b3Clamp(lineWidth,(float)lineWidthRange[0],(float)lineWidthRange[1]);
  942. glLineWidth(lineWidth);
  943. b3Assert(glGetError() ==GL_NO_ERROR);
  944. glBindVertexArray(lineVertexArrayObject);
  945. b3Assert(glGetError() ==GL_NO_ERROR);
  946. glBindBuffer(GL_ARRAY_BUFFER, lineVertexBufferObject);
  947. b3Assert(glGetError() ==GL_NO_ERROR);
  948. {
  949. glBufferSubData(GL_ARRAY_BUFFER, 0,sz, vertexPositions);
  950. }
  951. b3Assert(glGetError() ==GL_NO_ERROR);
  952. glBindBuffer(GL_ARRAY_BUFFER, 0);
  953. glBindBuffer(GL_ARRAY_BUFFER, lineVertexBufferObject);
  954. b3Assert(glGetError() ==GL_NO_ERROR);
  955. glEnableVertexAttribArray(0);
  956. glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
  957. b3Assert(glGetError() ==GL_NO_ERROR);
  958. glDrawArrays(GL_LINES, 0, 2);
  959. b3Assert(glGetError() ==GL_NO_ERROR);
  960. glBindVertexArray(0);
  961. glLineWidth(1);
  962. b3Assert(glGetError() ==GL_NO_ERROR);
  963. glUseProgram(0);
  964. }
  965. struct PointerCaster
  966. {
  967. union {
  968. int m_baseIndex;
  969. GLvoid* m_pointer;
  970. };
  971. PointerCaster()
  972. :m_pointer(0)
  973. {
  974. }
  975. };
  976. #if 0
  977. static void b3CreateFrustum(
  978. float left,
  979. float right,
  980. float bottom,
  981. float top,
  982. float nearVal,
  983. float farVal,
  984. float frustum[16])
  985. {
  986. frustum[0*4+0] = (float(2) * nearVal) / (right - left);
  987. frustum[0*4+1] = float(0);
  988. frustum[0*4+2] = float(0);
  989. frustum[0*4+3] = float(0);
  990. frustum[1*4+0] = float(0);
  991. frustum[1*4+1] = (float(2) * nearVal) / (top - bottom);
  992. frustum[1*4+2] = float(0);
  993. frustum[1*4+3] = float(0);
  994. frustum[2*4+0] = (right + left) / (right - left);
  995. frustum[2*4+1] = (top + bottom) / (top - bottom);
  996. frustum[2*4+2] = -(farVal + nearVal) / (farVal - nearVal);
  997. frustum[2*4+3] = float(-1);
  998. frustum[3*4+0] = float(0);
  999. frustum[3*4+1] = float(0);
  1000. frustum[3*4+2] = -(float(2) * farVal * nearVal) / (farVal - nearVal);
  1001. frustum[3*4+3] = float(0);
  1002. }
  1003. #endif
  1004. static void b3Matrix4x4Mul(GLfloat aIn[4][4], GLfloat bIn[4][4], GLfloat result[4][4])
  1005. {
  1006. for (int j=0;j<4;j++)
  1007. for (int i=0;i<4;i++)
  1008. result[j][i] = aIn[0][i] * bIn[j][0] + aIn[1][i] * bIn[j][1] + aIn[2][i] * bIn[j][2] + aIn[3][i] * bIn[j][3];
  1009. }
  1010. static void b3Matrix4x4Mul16(GLfloat aIn[16], GLfloat bIn[16], GLfloat result[16])
  1011. {
  1012. for (int j=0;j<4;j++)
  1013. for (int i=0;i<4;i++)
  1014. result[j*4+i] = aIn[0*4+i] * bIn[j*4+0] + aIn[1*4+i] * bIn[j*4+1] + aIn[2*4+i] * bIn[j*4+2] + aIn[3*4+i] * bIn[j*4+3];
  1015. }
  1016. static void b3CreateDiagonalMatrix(GLfloat value, GLfloat result[4][4])
  1017. {
  1018. for (int i=0;i<4;i++)
  1019. {
  1020. for (int j=0;j<4;j++)
  1021. {
  1022. if (i==j)
  1023. {
  1024. result[i][j] = value;
  1025. } else
  1026. {
  1027. result[i][j] = 0.f;
  1028. }
  1029. }
  1030. }
  1031. }
  1032. static void b3CreateOrtho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar, GLfloat result[4][4])
  1033. {
  1034. b3CreateDiagonalMatrix(1.f,result);
  1035. result[0][0] = 2.f / (right - left);
  1036. result[1][1] = 2.f / (top - bottom);
  1037. result[2][2] = - 2.f / (zFar - zNear);
  1038. result[3][0] = - (right + left) / (right - left);
  1039. result[3][1] = - (top + bottom) / (top - bottom);
  1040. result[3][2] = - (zFar + zNear) / (zFar - zNear);
  1041. }
  1042. static void b3CreateLookAt(const b3Vector3& eye, const b3Vector3& center,const b3Vector3& up, GLfloat result[16])
  1043. {
  1044. b3Vector3 f = (center - eye).normalized();
  1045. b3Vector3 u = up.normalized();
  1046. b3Vector3 s = (f.cross(u)).normalized();
  1047. u = s.cross(f);
  1048. result[0*4+0] = s.x;
  1049. result[1*4+0] = s.y;
  1050. result[2*4+0] = s.z;
  1051. result[0*4+1] = u.x;
  1052. result[1*4+1] = u.y;
  1053. result[2*4+1] = u.z;
  1054. result[0*4+2] =-f.x;
  1055. result[1*4+2] =-f.y;
  1056. result[2*4+2] =-f.z;
  1057. result[0*4+3] = 0.f;
  1058. result[1*4+3] = 0.f;
  1059. result[2*4+3] = 0.f;
  1060. result[3*4+0] = -s.dot(eye);
  1061. result[3*4+1] = -u.dot(eye);
  1062. result[3*4+2] = f.dot(eye);
  1063. result[3*4+3] = 1.f;
  1064. }
  1065. void GLInstancingRenderer::renderSceneInternal(int renderMode)
  1066. {
  1067. // glEnable(GL_DEPTH_TEST);
  1068. GLint dims[4];
  1069. glGetIntegerv(GL_VIEWPORT, dims);
  1070. //we need to get the viewport dims, because on Apple Retina the viewport dimension is different from screenWidth
  1071. //printf("dims=%d,%d,%d,%d\n",dims[0],dims[1],dims[2],dims[3]);
  1072. // Accept fragment if it closer to the camera than the former one
  1073. //glDepthFunc(GL_LESS);
  1074. // Cull triangles which normal is not towards the camera
  1075. glEnable(GL_CULL_FACE);
  1076. B3_PROFILE("GLInstancingRenderer::RenderScene");
  1077. {
  1078. B3_PROFILE("init");
  1079. init();
  1080. }
  1081. b3Assert(glGetError() ==GL_NO_ERROR);
  1082. float depthProjectionMatrix[4][4];
  1083. GLfloat depthModelViewMatrix[4][4];
  1084. //GLfloat depthModelViewMatrix2[4][4];
  1085. // Compute the MVP matrix from the light's point of view
  1086. if (renderMode==B3_CREATE_SHADOWMAP_RENDERMODE)
  1087. {
  1088. glEnable(GL_CULL_FACE);
  1089. glCullFace(GL_FRONT);
  1090. if (!m_data->m_shadowMap)
  1091. {
  1092. glActiveTexture(GL_TEXTURE0);
  1093. glGenTextures(1,&m_data->m_shadowTexture);
  1094. glBindTexture(GL_TEXTURE_2D,m_data->m_shadowTexture);
  1095. //glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT16,m_screenWidth,m_screenHeight,0,GL_DEPTH_COMPONENT,GL_FLOAT,0);
  1096. //glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT32,m_screenWidth,m_screenHeight,0,GL_DEPTH_COMPONENT,GL_FLOAT,0);
  1097. #ifdef OLD_SHADOWMAP_INIT
  1098. glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT16, shadowMapWidth, shadowMapHeight, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0);
  1099. #else//OLD_SHADOWMAP_INIT
  1100. //Reduce size of shadowMap if glTexImage2D call fails as may happen in some cases
  1101. //https://github.com/bulletphysics/bullet3/issues/40
  1102. int size;
  1103. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size);
  1104. if (size < shadowMapWidth){
  1105. shadowMapWidth = size;
  1106. }
  1107. if (size < shadowMapHeight){
  1108. shadowMapHeight = size;
  1109. }
  1110. GLuint err;
  1111. do {
  1112. glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16,
  1113. shadowMapWidth, shadowMapHeight,
  1114. 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
  1115. err = glGetError();
  1116. if (err!=GL_NO_ERROR){
  1117. shadowMapHeight >>= 1;
  1118. shadowMapWidth >>= 1;
  1119. }
  1120. } while (err != GL_NO_ERROR && shadowMapWidth > 0);
  1121. #endif//OLD_SHADOWMAP_INIT
  1122. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1123. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1124. float l_ClampColor[] = {1.0, 1.0, 1.0, 1.0};
  1125. glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, l_ClampColor);
  1126. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
  1127. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
  1128. // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  1129. // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  1130. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
  1131. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
  1132. m_data->m_shadowMap=new GLRenderToTexture();
  1133. m_data->m_shadowMap->init(shadowMapWidth, shadowMapHeight,m_data->m_shadowTexture,RENDERTEXTURE_DEPTH);
  1134. }
  1135. m_data->m_shadowMap->enable();
  1136. glViewport(0,0,shadowMapWidth,shadowMapHeight);
  1137. //glClearColor(1,1,1,1);
  1138. glClear(GL_DEPTH_BUFFER_BIT);
  1139. //glClearColor(0.3,0.3,0.3,1);
  1140. // m_data->m_shadowMap->disable();
  1141. // return;
  1142. glEnable(GL_CULL_FACE);
  1143. glCullFace(GL_FRONT); // Cull back-facing triangles -> draw only front-facing triangles
  1144. b3Assert(glGetError() ==GL_NO_ERROR);
  1145. } else
  1146. {
  1147. //glDisable(GL_CULL_FACE);
  1148. glCullFace(GL_BACK);
  1149. }
  1150. b3CreateOrtho(-shadowMapWorldSize,shadowMapWorldSize,-shadowMapWorldSize,shadowMapWorldSize,1,300,depthProjectionMatrix);//-14,14,-14,14,1,200, depthProjectionMatrix);
  1151. float depthViewMatrix[4][4];
  1152. b3Vector3 center = b3MakeVector3(0,0,0);
  1153. float upf[3];
  1154. m_data->m_activeCamera->getCameraUpVector(upf);
  1155. b3Vector3 up = b3MakeVector3(upf[0],upf[1],upf[2]);
  1156. b3CreateLookAt(gLightPos,center,up,&depthViewMatrix[0][0]);
  1157. //b3CreateLookAt(lightPos,m_data->m_cameraTargetPosition,b3Vector3(0,1,0),(float*)depthModelViewMatrix2);
  1158. GLfloat depthModelMatrix[4][4];
  1159. b3CreateDiagonalMatrix(1.f,depthModelMatrix);
  1160. b3Matrix4x4Mul(depthViewMatrix, depthModelMatrix, depthModelViewMatrix);
  1161. GLfloat depthMVP[4][4];
  1162. b3Matrix4x4Mul(depthProjectionMatrix,depthModelViewMatrix,depthMVP);
  1163. GLfloat biasMatrix[4][4]={
  1164. { 0.5, 0.0, 0.0, 0.0 },
  1165. { 0.0, 0.5, 0.0, 0.0 },
  1166. { 0.0, 0.0, 0.5, 0.0 },
  1167. { 0.5, 0.5, 0.5, 1.0 }
  1168. };
  1169. GLfloat depthBiasMVP[4][4];
  1170. b3Matrix4x4Mul(biasMatrix,depthMVP,depthBiasMVP);
  1171. //float m_frustumZNear=0.1;
  1172. //float m_frustumZFar=100.f;
  1173. //b3CreateFrustum(-m_frustumZNear, m_frustumZNear, -m_frustumZNear, m_frustumZNear, m_frustumZNear, m_frustumZFar,(float*)depthProjectionMatrix);
  1174. //b3CreateLookAt(lightPos,m_data->m_cameraTargetPosition,b3Vector3(0,0,1),(float*)depthModelViewMatrix);
  1175. {
  1176. B3_PROFILE("updateCamera");
  1177. // updateCamera();
  1178. m_data->m_activeCamera->getCameraProjectionMatrix(m_data->m_projectionMatrix);
  1179. m_data->m_activeCamera->getCameraViewMatrix(m_data->m_viewMatrix);
  1180. }
  1181. b3Assert(glGetError() ==GL_NO_ERROR);
  1182. // glBindBuffer(GL_ARRAY_BUFFER, 0);
  1183. {
  1184. B3_PROFILE("glFlush2");
  1185. glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
  1186. //glFlush();
  1187. }
  1188. b3Assert(glGetError() ==GL_NO_ERROR);
  1189. int totalNumInstances = 0;
  1190. for (int i=0;i<m_graphicsInstances.size();i++)
  1191. {
  1192. totalNumInstances+=m_graphicsInstances[i]->m_numGraphicsInstances;
  1193. }
  1194. int curOffset = 0;
  1195. //GLuint lastBindTexture = 0;
  1196. for (int i=0;i<m_graphicsInstances.size();i++)
  1197. {
  1198. b3GraphicsInstance* gfxObj = m_graphicsInstances[i];
  1199. if (gfxObj->m_numGraphicsInstances)
  1200. {
  1201. glActiveTexture(GL_TEXTURE0);
  1202. GLuint curBindTexture = 0;
  1203. if (gfxObj->m_texturehandle)
  1204. curBindTexture = gfxObj->m_texturehandle;
  1205. else
  1206. curBindTexture = m_data->m_defaultTexturehandle;
  1207. //disable lazy evaluation, it just leads to bugs
  1208. //if (lastBindTexture != curBindTexture)
  1209. {
  1210. glBindTexture(GL_TEXTURE_2D,curBindTexture);
  1211. }
  1212. //lastBindTexture = curBindTexture;
  1213. b3Assert(glGetError() ==GL_NO_ERROR);
  1214. // int myOffset = gfxObj->m_instanceOffset*4*sizeof(float);
  1215. int POSITION_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4);
  1216. int ORIENTATION_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4);
  1217. int COLOR_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4);
  1218. // int SCALE_BUFFER_SIZE = (totalNumInstances*sizeof(float)*3);
  1219. glBindVertexArray(gfxObj->m_cube_vao);
  1220. int vertexStride = 9*sizeof(float);
  1221. PointerCaster vertex;
  1222. vertex.m_baseIndex = gfxObj->m_vertexArrayOffset*vertexStride;
  1223. glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 9*sizeof(float), vertex.m_pointer);
  1224. glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(curOffset*4*sizeof(float)+m_data->m_maxShapeCapacityInBytes));
  1225. glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(curOffset*4*sizeof(float)+m_data->m_maxShapeCapacityInBytes+POSITION_BUFFER_SIZE));
  1226. PointerCaster uv;
  1227. uv.m_baseIndex = 7*sizeof(float)+vertex.m_baseIndex;
  1228. PointerCaster normal;
  1229. normal.m_baseIndex = 4*sizeof(float)+vertex.m_baseIndex;
  1230. glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 9*sizeof(float), uv.m_pointer);
  1231. glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 9*sizeof(float), normal.m_pointer);
  1232. glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(curOffset*4*sizeof(float)+m_data->m_maxShapeCapacityInBytes+POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE));
  1233. glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(curOffset*3*sizeof(float)+m_data->m_maxShapeCapacityInBytes+POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE+COLOR_BUFFER_SIZE));
  1234. glEnableVertexAttribArray(0);
  1235. glEnableVertexAttribArray(1);
  1236. glEnableVertexAttribArray(2);
  1237. glEnableVertexAttribArray(3);
  1238. glEnableVertexAttribArray(4);
  1239. glEnableVertexAttribArray(5);
  1240. glEnableVertexAttribArray(6);
  1241. glVertexAttribDivisor(0, 0);
  1242. glVertexAttribDivisor(1, 1);
  1243. glVertexAttribDivisor(2, 1);
  1244. glVertexAttribDivisor(3, 0);
  1245. glVertexAttribDivisor(4, 0);
  1246. glVertexAttribDivisor(5, 1);
  1247. glVertexAttribDivisor(6, 1);
  1248. int indexCount = gfxObj->m_numIndices;
  1249. GLvoid* indexOffset = 0;
  1250. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gfxObj->m_index_vbo);
  1251. {
  1252. B3_PROFILE("glDrawElementsInstanced");
  1253. if (gfxObj->m_primitiveType==B3_GL_POINTS)
  1254. {
  1255. glUseProgram(instancingShaderPointSprite);
  1256. glUniformMatrix4fv(ProjectionMatrixPointSprite, 1, false, &m_data->m_projectionMatrix[0]);
  1257. glUniformMatrix4fv(ModelViewMatrixPointSprite, 1, false, &m_data->m_viewMatrix[0]);
  1258. glUniform1f(screenWidthPointSprite,float(m_screenWidth));
  1259. //glUniform1i(uniform_texture_diffusePointSprite, 0);
  1260. b3Assert(glGetError() ==GL_NO_ERROR);
  1261. glPointSize(20);
  1262. #ifndef __APPLE__
  1263. glEnable(GL_POINT_SPRITE_ARB);
  1264. // glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
  1265. #endif
  1266. glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
  1267. glDrawElementsInstanced(GL_POINTS, indexCount, GL_UNSIGNED_INT, indexOffset, gfxObj->m_numGraphicsInstances);
  1268. } else
  1269. {
  1270. switch (renderMode)
  1271. {
  1272. case B3_DEFAULT_RENDERMODE:
  1273. {
  1274. glUseProgram(instancingShader);
  1275. glUniformMatrix4fv(ProjectionMatrix, 1, false, &m_data->m_projectionMatrix[0]);
  1276. glUniformMatrix4fv(ModelViewMatrix, 1, false, &m_data->m_viewMatrix[0]);
  1277. b3Vector3 gLightDir = gLightPos;
  1278. gLightDir.normalize();
  1279. glUniform3f(regularLightDirIn,gLightDir[0],gLightDir[1],gLightDir[2]);
  1280. glUniform1i(uniform_texture_diffuse, 0);
  1281. glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, indexOffset, gfxObj->m_numGraphicsInstances);
  1282. break;
  1283. }
  1284. case B3_CREATE_SHADOWMAP_RENDERMODE:
  1285. {
  1286. /*printf("createShadowMapInstancingShader=%d\n",createShadowMapInstancingShader);
  1287. printf("createShadow_depthMVP=%d\n",createShadow_depthMVP);
  1288. printf("indexOffset=%d\n",indexOffset);
  1289. printf("gfxObj->m_numGraphicsInstances=%d\n",gfxObj->m_numGraphicsInstances);
  1290. printf("indexCount=%d\n",indexCount);
  1291. */
  1292. glUseProgram(createShadowMapInstancingShader);
  1293. glUniformMatrix4fv(createShadow_depthMVP, 1, false, &depthMVP[0][0]);
  1294. glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, indexOffset, gfxObj->m_numGraphicsInstances);
  1295. break;
  1296. }
  1297. case B3_USE_SHADOWMAP_RENDERMODE:
  1298. {
  1299. if (m_enableBlend)
  1300. {
  1301. glEnable (GL_BLEND);
  1302. glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1303. }
  1304. glUseProgram(useShadowMapInstancingShader);
  1305. glUniformMatrix4fv(useShadow_ProjectionMatrix, 1, false, &m_data->m_projectionMatrix[0]);
  1306. glUniformMatrix4fv(useShadow_ModelViewMatrix, 1, false, &m_data->m_viewMatrix[0]);
  1307. float MVP[16];
  1308. b3Matrix4x4Mul16(m_data->m_projectionMatrix,m_data->m_viewMatrix,MVP);
  1309. glUniformMatrix4fv(useShadow_MVP, 1, false, &MVP[0]);
  1310. b3Vector3 gLightDir = gLightPos;
  1311. gLightDir.normalize();
  1312. glUniform3f(useShadow_lightDirIn,gLightDir[0],gLightDir[1],gLightDir[2]);
  1313. glUniformMatrix4fv(useShadow_DepthBiasModelViewMatrix, 1, false, &depthBiasMVP[0][0]);
  1314. glActiveTexture(GL_TEXTURE1);
  1315. glBindTexture(GL_TEXTURE_2D, m_data->m_shadowTexture);
  1316. glUniform1i(useShadow_shadowMap,1);
  1317. glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, indexOffset, gfxObj->m_numGraphicsInstances);
  1318. if (m_enableBlend)
  1319. {
  1320. glDisable (GL_BLEND);
  1321. }
  1322. glActiveTexture(GL_TEXTURE0);
  1323. glBindTexture(GL_TEXTURE_2D,0);
  1324. break;
  1325. }
  1326. default:
  1327. {
  1328. // b3Assert(0);
  1329. }
  1330. };
  1331. }
  1332. //glDrawElementsInstanced(GL_LINE_LOOP, indexCount, GL_UNSIGNED_INT, (void*)indexOffset, gfxObj->m_numGraphicsInstances);
  1333. }
  1334. }
  1335. curOffset+= gfxObj->m_numGraphicsInstances;
  1336. }
  1337. {
  1338. B3_PROFILE("glFlush");
  1339. //glFlush();
  1340. }
  1341. if (renderMode==B3_CREATE_SHADOWMAP_RENDERMODE)
  1342. {
  1343. // writeTextureToPng(shadowMapWidth,shadowMapHeight,"shadowmap.png",4);
  1344. m_data->m_shadowMap->disable();
  1345. glBindFramebuffer( GL_FRAMEBUFFER, m_data->m_renderFrameBuffer);
  1346. glViewport(dims[0],dims[1],dims[2],dims[3]);
  1347. }
  1348. b3Assert(glGetError() ==GL_NO_ERROR);
  1349. {
  1350. B3_PROFILE("glUseProgram(0);");
  1351. glUseProgram(0);
  1352. glBindBuffer(GL_ARRAY_BUFFER,0);
  1353. glBindVertexArray(0);
  1354. }
  1355. glDisable(GL_CULL_FACE);
  1356. b3Assert(glGetError() ==GL_NO_ERROR);
  1357. }
  1358. void GLInstancingRenderer::CleanupShaders()
  1359. {
  1360. }
  1361. void GLInstancingRenderer::enableShadowMap()
  1362. {
  1363. glActiveTexture(GL_TEXTURE0);
  1364. //glEnable(GL_TEXTURE_2D);
  1365. glBindTexture(GL_TEXTURE_2D, m_data->m_shadowTexture);
  1366. //glBindTexture(GL_TEXTURE_2D, m_data->m_defaultTexturehandle);
  1367. }
  1368. void GLInstancingRenderer::clearZBuffer()
  1369. {
  1370. glClear(GL_DEPTH_BUFFER_BIT);
  1371. }
  1372. int GLInstancingRenderer::getMaxShapeCapacity() const
  1373. {
  1374. return m_data->m_maxShapeCapacityInBytes;
  1375. }
  1376. int GLInstancingRenderer::getInstanceCapacity() const
  1377. {
  1378. return m_data->m_maxNumObjectCapacity;
  1379. }
  1380. void GLInstancingRenderer::setRenderFrameBuffer(unsigned int renderFrameBuffer)
  1381. {
  1382. m_data->m_renderFrameBuffer = (GLuint) renderFrameBuffer;
  1383. }
  1384. int GLInstancingRenderer::getTotalNumInstances() const
  1385. {
  1386. return m_data->m_totalNumInstances;
  1387. }
  1388. #endif //NO_OPENGL3