Guest User

Untitled

a guest
Mar 8th, 2012
40
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×