Advertisement
Guest User

Untitled

a guest
Mar 8th, 2012
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.74 KB | None | 0 0
  1.  
  2. void Scene3D::Render(
  3. float dt,
  4. IDirect3DDevice9* device,
  5. IDirect3DVertexDeclaration9* VertexDecl,
  6. ID3DXEffect* RenderOnlyAmbientLightEffect
  7. ) const {
  8. auto SetRenderTargetToDevice = [&] {
  9. std::unique_ptr<IDirect3DSurface9, COMDeleter> RenderTargetSurface;
  10. D3DCALL(RenderTarget->GetSurfaceLevel(0, PointerToPointer(RenderTargetSurface)));
  11. D3DCALL(device->SetRenderTarget(0, RenderTargetSurface.get()));
  12. D3DCALL(device->SetDepthStencilSurface(DepthBuffer.get()));
  13. };
  14.  
  15. auto SetMeshSpecificDataToEffect = [&](ID3DXEffect* effect, const Direct3D9::Mesh* mesh) {
  16. auto RenData = mesh->GetRenderData();
  17. /*if (auto handle = effect->GetParameterByName(0, "ColourMap")) {
  18. effect->SetTexture(handle, RenData.Texture);
  19. }*/
  20. if (auto handle = effect->GetParameterByName(0, "AmbientMaterial")) {
  21. effect->SetVector(handle, reinterpret_cast<D3DXVECTOR4*>(&RenData.AmbientMaterial));
  22. }
  23. if (auto handle = effect->GetParameterByName(0, "DiffuseMaterial")) {
  24. effect->SetVector(handle, reinterpret_cast<D3DXVECTOR4*>(&RenData.DiffuseMaterial));
  25. }
  26. if (auto handle = effect->GetParameterByName(0, "SpecularMaterial")) {
  27. effect->SetVector(handle, reinterpret_cast<D3DXVECTOR4*>(&RenData.SpecularMaterial));
  28. }
  29. };
  30.  
  31. auto SetCameraSpecificDataToEffect = [&](ID3DXEffect* effect) {
  32. if (auto handle = effect->GetParameterByName(0, "CameraVP")) {
  33. D3DXMATRIX Projection;
  34. D3DXMATRIX View;
  35. D3DXMatrixLookAtLH(
  36. &View,
  37. &D3DVector(camera.Position),
  38. &D3DVector(camera.LookingAt),
  39. &D3DVector(camera.Up)
  40. );
  41. #pragma warning(disable : 4244)
  42. D3DXMatrixPerspectiveLH(
  43. &Projection,
  44. GetDimensions().x,
  45. GetDimensions().y,
  46. camera.NearPlane,
  47. camera.FarPlane
  48. );
  49. #pragma warning(default : 4244)
  50. effect->SetMatrix(handle, &(View * Projection));
  51. }
  52. };
  53.  
  54. // Define a couple variables the helpers can use
  55. auto SendAllVerticesToPipeline = [&, this](ID3DXEffect* effect, const std::unordered_map<const Direct3D9::Mesh*, std::unordered_set<Object*>>& ObjectsByMesh) {
  56. std::for_each(ObjectsByMesh.begin(), ObjectsByMesh.end(), [&, this](const decltype(*ObjectsByMesh.begin())& group) {
  57. // Set all per-mesh data - first to the pipeline
  58. auto RenData = group.first->GetRenderData();
  59. D3DCALL(device->SetStreamSource(
  60. 0,
  61. RenData.VertexBuffer,
  62. 0,
  63. sizeof(Render::InputMesh::Vertex)
  64. ));
  65. D3DCALL(device->SetStreamSource(
  66. 1,
  67. InstanceBuffer.get(),
  68. 0,
  69. sizeof(D3DXMATRIX)
  70. ));
  71. D3DCALL(device->SetIndices(
  72. RenData.IndexBuffer
  73. ));
  74.  
  75. // then to the effect
  76. SetMeshSpecificDataToEffect(effect, group.first);
  77. auto handle = effect->GetTechniqueByName("PrimaryTechnique");
  78. D3DCALL(effect->SetTechnique(handle));
  79.  
  80. unsigned int passes;
  81. D3DCALL(effect->Begin(&passes, 0));
  82. auto bones = group.first->GetBones();
  83. std::for_each(bones.begin(), bones.end(), [&](const decltype(*bones.begin())& bone) {
  84. std::vector<Direct3D9::Bone*> bones;
  85. std::for_each(group.second.begin(), group.second.end(), [&](const Wide::Direct3D9::Object* obj) {
  86. bones.push_back(obj->GetBoneByName(bone->Name));
  87. });
  88. D3DXMATRIXA16* matrices;
  89. InstanceBuffer->Lock(0, bones.size() * sizeof(D3DXMATRIXA16), reinterpret_cast<void**>(&matrices), D3DLOCK_DISCARD);
  90. std::for_each(bones.begin(), bones.end(), [&, this](Direct3D9::Bone* bone) {
  91. *matrices = bone->World;
  92. matrices++; // Guaranteed not to overflow because we already made the size as large as we needed it
  93. });
  94. for(unsigned int i = 0; i < passes; i++) {
  95. D3DCALL(effect->BeginPass(i));
  96. D3DCALL(device->DrawIndexedPrimitive(
  97. D3DPRIMITIVETYPE::D3DPT_TRIANGLESTRIP,
  98. bone->VertBegin,
  99. 0,
  100. bone->NumVerts,
  101. bone->IndexBegin,
  102. bone->NumIndices / 3
  103. ));
  104. D3DCALL(effect->EndPass());
  105. }
  106. });
  107. D3DCALL(effect->End());
  108. });
  109. };
  110.  
  111. // Save the original back buffer and depth stencil
  112. std::unique_ptr<IDirect3DSurface9, COMDeleter> BackBuffer;
  113. std::unique_ptr<IDirect3DSurface9, COMDeleter> DepthStencil;
  114. D3DCALL(device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, PointerToPointer(BackBuffer)));
  115. D3DCALL(device->GetDepthStencilSurface(PointerToPointer(DepthStencil)));
  116.  
  117.  
  118. // Sort the objects by mesh, and compute the world matrices whilst you're at it.
  119. std::unordered_map<const Direct3D9::Mesh*, std::unordered_set<Object*>> ObjectsByMesh;
  120. std::for_each(Objects.begin(), Objects.end(), [&](Wide::Render::Object* ptr) {
  121. auto d3dptr = static_cast<Wide::Direct3D9::Object*>(ptr);
  122. d3dptr->ComputeWorldMatrices();
  123. ObjectsByMesh[d3dptr->GetMesh().get()].insert(d3dptr);
  124. });
  125.  
  126. // Resize the buffer, if it's not big enough to hold what we're doin here.
  127. unsigned int maxsize = 0;
  128. std::for_each(ObjectsByMesh.begin(), ObjectsByMesh.end(), [&](const decltype(*ObjectsByMesh.begin())& group) {
  129. maxsize = std::max(maxsize, group.second.size());
  130. });
  131. if (InstanceBufferSize < maxsize) {
  132. InstanceBufferSize = maxsize;
  133. ResetInstanceBuffer(device);
  134. }
  135.  
  136. // Set the mesh-independent stuff to the device
  137. D3DCALL(device->SetVertexDeclaration(VertexDecl));
  138. D3DCALL(device->SetStreamSource(1, InstanceBuffer.get(), 0, sizeof(D3DXMATRIXA16)));
  139.  
  140. // If there is only ambient light, then just render directly to BB with no shadow mapping
  141. if (Lights.empty()) {
  142. // Render ambient only- no shadowmapping needed
  143. SetRenderTargetToDevice();
  144. SetCameraSpecificDataToEffect(RenderOnlyAmbientLightEffect);
  145. SendAllVerticesToPipeline(RenderOnlyAmbientLightEffect, ObjectsByMesh);
  146. }
  147.  
  148. // Restore the previous backbuffer and depth stencil
  149. D3DCALL(device->SetRenderTarget(0, BackBuffer.get()));
  150. D3DCALL(device->SetDepthStencilSurface(DepthStencil.get()));
  151. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement