Ticket #3073: Instancing_v1b.patch
File Instancing_v1b.patch, 10.8 KB (added by , 9 years ago) |
---|
-
binaries/data/mods/public/shaders/glsl/model_common.vs
1 1 #version 120 2 #extension GL_ARB_draw_instanced : enable 2 3 3 4 uniform mat4 transform; 4 5 uniform vec3 cameraPos; … … 11 12 #endif 12 13 uniform vec2 losTransform; 13 14 uniform mat4 shadowTransform; 14 uniform mat4 instancingTransform ;15 uniform mat4 instancingTransforms[250]; 15 16 16 17 #if USE_SHADOW_SAMPLER && USE_SHADOW_PCF 17 18 uniform vec4 shadowScale; … … 74 75 75 76 void main() 76 77 { 78 mat4 instancingTransform = instancingTransforms[gl_InstanceIDARB];//mat4(a_instancingTransform0, a_instancingTransform1, a_instancingTransform2, a_instancingTransform3); 79 77 80 #if USE_GPU_SKINNING 78 81 vec3 p = vec3(0.0); 79 82 vec3 n = vec3(0.0); -
source/graphics/ShaderProgram.cpp
484 484 pglUseProgramObjectARB(m_Program); 485 485 486 486 for (std::map<CStrIntern, int>::iterator it = m_VertexAttribs.begin(); it != m_VertexAttribs.end(); ++it) 487 { 487 488 pglEnableVertexAttribArrayARB(it->second); 489 490 if (it->first == str_a_instancingTransform0 491 || it->first == str_a_instancingTransform1 492 || it->first == str_a_instancingTransform2 493 || it->first == str_a_instancingTransform3 494 ) 495 { 496 pglVertexAttribDivisorARB(it->second, 1); 488 497 } 498 } 499 } 489 500 490 501 virtual void Unbind() 491 502 { … … 492 503 pglUseProgramObjectARB(0); 493 504 494 505 for (std::map<CStrIntern, int>::iterator it = m_VertexAttribs.begin(); it != m_VertexAttribs.end(); ++it) 506 { 495 507 pglDisableVertexAttribArrayARB(it->second); 508 pglVertexAttribDivisorARB(it->second, 0); 509 } 496 510 497 511 // TODO: should unbind textures, probably 498 512 } -
source/lib/external_libraries/glext_funcs.h
383 383 FUNC(void, glDeletePerfQueryINTEL, (GLuint id)) 384 384 FUNC(void, glGetPerfQueryDataINTEL, (GLuint id, GLenum requestType, GLuint maxLength, char *buffer, GLuint *length)) 385 385 386 // GL_ARB_draw_instanced 387 FUNC(void, glDrawArraysInstancedARB, (GLenum mode, GLint first, GLsizei count, GLsizei primcount)) 388 FUNC(void, glDrawElementsInstancedARB, (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount)) 389 390 // GL_ARB_instanced_arrays 391 FUNC(void, glVertexAttribDivisorARB, (GLuint index, GLuint divisor)) 392 386 393 #endif // #if CONFIG_GLES2 387 394 388 395 -
source/ps/CStrInternStatic.h
73 73 X(a_splashPosition) 74 74 X(a_tangent) 75 75 X(a_waterInfo) 76 X(a_instancingTransform0) 77 X(a_instancingTransform1) 78 X(a_instancingTransform2) 79 X(a_instancingTransform3) 76 80 X(ambient) 77 81 X(baseTex) 78 82 X(blendTex) … … 99 103 X(hdr) 100 104 X(height) 101 105 X(instancingTransform) 106 X2(instancingTransforms, "instancingTransforms[0]") 102 107 X(losMap) 103 108 X(losMatrix) 104 109 X(losTex) -
source/renderer/ModelVertexRenderer.h
154 154 * succeed. 155 155 */ 156 156 virtual void RenderModel(const CShaderProgramPtr& shader, int streamflags, CModel* model, CModelRData* data) = 0; 157 158 virtual void RenderModelInstanced(const CShaderProgramPtr& shader, int streamflags, CModel* model, size_t count) { }; 159 160 virtual bool IsInstanced() const = 0; 161 157 162 }; 158 163 159 164 -
source/renderer/VertexArray.h
157 157 }; 158 158 159 159 public: 160 VertexArray(GLenum usage , GLenum target = GL_ARRAY_BUFFER);160 VertexArray(GLenum usage = GL_DYNAMIC_DRAW, GLenum target = GL_ARRAY_BUFFER); 161 161 ~VertexArray(); 162 162 163 163 // Set the number of vertices stored in the array -
source/renderer/InstancingModelRenderer.cpp
389 389 g_Renderer.m_Stats.m_ModelTris += numFaces; 390 390 391 391 } 392 393 void InstancingModelRenderer::RenderModelInstanced(const CShaderProgramPtr& shader, int UNUSED(streamflags), CModel* model, size_t count) 394 { 395 CModelDefPtr mdldef = model->GetModelDef(); 396 397 // render the lot 398 size_t numFaces = mdldef->GetNumFaces(); 399 if (!g_Renderer.m_SkipSubmit) 400 { 401 // Draw with DrawRangeElements where available, since it might be more efficient 402 pglDrawElementsInstancedARB(GL_TRIANGLES, (GLsizei)numFaces*3, GL_UNSIGNED_SHORT, m->imodeldefIndexBase, count); 403 // pglDrawRangeElementsEXT(GL_TRIANGLES, 0, (GLuint)m->imodeldef->m_Array.GetNumVertices()-1, 404 // (GLsizei)numFaces*3, GL_UNSIGNED_SHORT, m->imodeldefIndexBase); 405 } 406 407 // bump stats 408 g_Renderer.m_Stats.m_DrawCalls++; 409 g_Renderer.m_Stats.m_ModelTris += numFaces * count; 410 411 } -
source/renderer/HWLightingModelRenderer.h
47 47 void PrepareModelDef(const CShaderProgramPtr& shader, int streamflags, const CModelDef& def); 48 48 void RenderModel(const CShaderProgramPtr& shader, int streamflags, CModel* model, CModelRData* data); 49 49 50 bool IsInstanced() const { return false; }; 51 50 52 protected: 51 53 ShaderModelRendererInternals* m; 52 54 }; -
source/renderer/ModelRenderer.cpp
215 215 216 216 /// List of submitted models for rendering in this frame 217 217 std::vector<CModel*> submissions[CRenderer::CULL_MAX]; 218 219 #define NUM_INSTANCING_ARRAYS 256 220 VertexArray instancingArray[NUM_INSTANCING_ARRAYS]; 221 VertexArray::Attribute instancingTransform[NUM_INSTANCING_ARRAYS][4]; 222 size_t currentInstancingArray; 218 223 }; 219 224 220 225 … … 223 228 { 224 229 m = new ShaderModelRendererInternals(this); 225 230 m->vertexRenderer = vertexrenderer; 231 232 for (size_t j = 0; j < NUM_INSTANCING_ARRAYS; ++j) 233 { 234 for (size_t i = 0; i < 4; ++i) 235 { 236 m->instancingTransform[j][i].type = GL_FLOAT; 237 m->instancingTransform[j][i].elems = 4; 238 m->instancingArray[j].AddAttribute(&m->instancingTransform[j][i]); 239 } 240 241 m->instancingArray[j].SetNumVertices(64); 242 m->instancingArray[j].Layout(); 243 } 244 245 m->currentInstancingArray = 0; 226 246 } 227 247 228 248 ShaderModelRenderer::~ShaderModelRenderer() … … 363 383 } 364 384 }; 365 385 386 bool hasChanged(CModel* lastModel, CModel* newModel) 387 { 388 if (lastModel->GetModelDef().get() != newModel->GetModelDef().get()) 389 return true; 390 return false; 391 } 392 366 393 void ShaderModelRenderer::Render(const RenderModifierPtr& modifier, const CShaderDefines& context, int cullGroup, int flags) 367 394 { 368 395 if (m->submissions[cullGroup].empty()) … … 618 645 typedef ProxyAllocator<CStrIntern, Allocators::DynamicArena> BindingNamesListAllocator; 619 646 std::vector<CStrIntern, BindingNamesListAllocator> texBindingNames((BindingNamesListAllocator(arena))); 620 647 texBindingNames.reserve(64); 621 648 printf("----\n"); 622 649 while (idxTechStart < techBuckets.size()) 623 650 { 624 651 CShaderTechniquePtr currentTech = techBuckets[idxTechStart].tech; … … 655 682 656 683 for (size_t idx = idxTechStart; idx < idxTechEnd; ++idx) 657 684 { 685 int instances = 0; 686 687 std::vector<CMatrix3D> instancingTransforms; 688 658 689 CModel** models = techBuckets[idx].models; 659 690 size_t numModels = techBuckets[idx].numModels; 691 692 if (numModels == 0) 693 continue; 694 695 CModel* newModel = NULL; 696 660 697 for (size_t i = 0; i < numModels; ++i) 661 698 { 662 699 CModel* model = models[i]; 663 700 664 701 if (flags && !(model->GetFlags() & flags)) 665 702 continue; 666 703 704 if (m->vertexRenderer->IsInstanced()) 705 { 706 instances++; 707 CMatrix3D transform = model->GetTransform(); 708 instancingTransforms.push_back(transform); 709 710 if (i < numModels-1) 711 { 712 newModel = models[i+1]; 713 while (i < numModels-1 && instances < 250 && !hasChanged(model, newModel)) { 714 model = models[++i]; 715 instances++; 716 CMatrix3D transform = model->GetTransform(); 717 instancingTransforms.push_back(transform); 718 newModel = models[i+1]; 719 } 720 } 721 } 722 667 723 const CMaterial::SamplersVector& samplers = model->GetMaterial().GetSamplers(); 668 724 size_t samplersNum = samplers.size(); 669 725 … … 730 786 for (size_t q = 0; q < renderQueries.GetSize(); q++) 731 787 { 732 788 CShaderRenderQueries::RenderQuery rq = renderQueries.GetItem(q); 733 if (rq.first == RQUERY_TIME )789 if (rq.first == RQUERY_TIME && i == 0) 734 790 { 735 791 CShaderProgram::Binding binding = shader->GetUniformBinding(rq.second); 736 792 if (binding.Active()) … … 756 812 shader->BindTexture(str_skyCube, g_Renderer.GetSkyManager()->GetSkyCube()); 757 813 } 758 814 } 759 815 760 816 modifier->PrepareModel(shader, model); 761 817 818 if (m->vertexRenderer->IsInstanced()) 819 { 820 shader->Uniform(str_instancingTransforms, instancingTransforms.size(), &instancingTransforms[0]); 821 m->vertexRenderer->RenderModelInstanced(shader, streamflags, model, instances); 822 instances = 0; 823 instancingTransforms.clear(); 824 } 825 else 826 { 762 827 CModelRData* rdata = static_cast<CModelRData*>(model->GetRenderData()); 763 828 ENSURE(rdata->GetKey() == m->vertexRenderer.get()); 764 829 765 830 m->vertexRenderer->RenderModel(shader, streamflags, model, rdata); 766 831 } 767 832 } 833 } 768 834 769 835 m->vertexRenderer->EndPass(streamflags); 770 836 -
source/renderer/InstancingModelRenderer.h
46 46 void EndPass(int streamflags); 47 47 void PrepareModelDef(const CShaderProgramPtr& shader, int streamflags, const CModelDef& def); 48 48 void RenderModel(const CShaderProgramPtr& shader, int streamflags, CModel* model, CModelRData* data); 49 void RenderModelInstanced(const CShaderProgramPtr& shader, int streamflags, CModel* model, size_t count); 49 50 51 bool IsInstanced() const { return true; } 52 50 53 protected: 51 54 InstancingModelRendererInternals* m; 52 55 };