diff Render.cpp @ 1787:0c4d3c6a9d5a

DrawBuildingsD3D cleared
author Ritor1
date Fri, 04 Oct 2013 17:30:47 +0600
parents 4da5644df18f
children dfafcd39c67b
line wrap: on
line diff
--- a/Render.cpp	Thu Oct 03 18:09:21 2013 +0600
+++ b/Render.cpp	Fri Oct 04 17:30:47 2013 +0600
@@ -8717,4 +8717,268 @@
       assert(false);
     break;
   }
+}
+
+//----- (00424EE0) --------------------------------------------------------
+int BuildingVerticesClipping(unsigned int uNumVertices)
+{
+  signed int previous_vertices_flag; // edi@1
+  double t; // st6@10
+  bool current_vertices_flag; // [sp+Ch] [bp-28h]@6
+  signed int depth_num_vertices; // [sp+18h] [bp-1Ch]@1
+  int pNextVertices;
+  //Доп инфо "Программирование трёхмерных игр для windows" Ламот стр 910
+
+  memcpy(&array_50AC10[uNumVertices], array_50AC10, sizeof(array_50AC10[uNumVertices]));
+  depth_num_vertices = 0;
+  previous_vertices_flag = 0;
+  if ( array_50AC10[0].vWorldViewPosition.x <= pODMRenderParams->shading_dist_mist )
+    previous_vertices_flag = 1;//предыдущая грань меньше границы видимости
+  if ( (signed int)uNumVertices <= 0 )
+    return 0;
+  for ( uint i = 1; i <= uNumVertices; ++i )
+  {
+    current_vertices_flag = pODMRenderParams->shading_dist_mist >= array_50AC10[i].vWorldViewPosition.x;
+    if ( previous_vertices_flag != current_vertices_flag )//одна из граней за границей видимости
+    {
+      if ( current_vertices_flag )//текущая грань меньше границы видимости(предыдущая грань за пределами видимости)
+      {
+        //t = far_clip - v0.x / v1.x - v0.x    (формула получения точки пересечения отрезка с плоскостью)
+        t = (pODMRenderParams->shading_dist_mist - array_50AC10[i - 1].vWorldViewPosition.x) / (array_50AC10[i].vWorldViewPosition.x - array_50AC10[i - 1].vWorldViewPosition.x);
+        array_507D30[depth_num_vertices].vWorldViewPosition.y = (array_50AC10[i].vWorldViewPosition.y - array_50AC10[i - 1].vWorldViewPosition.y) * t + array_50AC10[i - 1].vWorldViewPosition.y;
+        array_507D30[depth_num_vertices].vWorldViewPosition.z = (array_50AC10[i].vWorldViewPosition.z - array_50AC10[i - 1].vWorldViewPosition.z) * t + array_50AC10[i - 1].vWorldViewPosition.z;
+        array_507D30[depth_num_vertices].u = (array_50AC10[i].u - array_50AC10[i - 1].u) * t + array_50AC10[i - 1].u;
+        array_507D30[depth_num_vertices].v = (array_50AC10[i].v - array_50AC10[i - 1].v) * t + array_50AC10[i - 1].v;
+      }
+      else//предыдущая грань меньше границы видимости(текущая грань вышла за пределы видимости)
+      {
+        //t = far_clip - v1.x / v0.x - v1.x
+        t = (pODMRenderParams->shading_dist_mist - array_50AC10[i].vWorldViewPosition.x) / (array_50AC10[i - 1].vWorldViewPosition.x - array_50AC10[i].vWorldViewPosition.x);
+        array_507D30[depth_num_vertices].vWorldViewPosition.y = (array_50AC10[i - 1].vWorldViewPosition.y - array_50AC10[i].vWorldViewPosition.y) * t + array_50AC10[i].vWorldViewPosition.y;
+        array_507D30[depth_num_vertices].vWorldViewPosition.z = (array_50AC10[i - 1].vWorldViewPosition.z - array_50AC10[i].vWorldViewPosition.z) * t + array_50AC10[i].vWorldViewPosition.z;
+        array_507D30[depth_num_vertices].u = (array_50AC10[i - 1].u - array_50AC10[i].u) * t + array_50AC10[i].u;
+        array_507D30[depth_num_vertices].v = (array_50AC10[i - 1].v - array_50AC10[i].v) * t + array_50AC10[i].v;
+      }
+      array_507D30[depth_num_vertices].vWorldViewPosition.x = pODMRenderParams->shading_dist_mist;
+      array_507D30[depth_num_vertices]._rhw = 1.0 / pODMRenderParams->shading_dist_mist;
+      ++depth_num_vertices;
+    }
+    if ( current_vertices_flag )//оба в границе видимости
+    {
+      pNextVertices = depth_num_vertices++;
+      memcpy(&array_507D30[pNextVertices], &array_50AC10[i], 0x30);
+    }
+    previous_vertices_flag = current_vertices_flag;
+  }
+  if ( depth_num_vertices < 3 )
+    return 0;
+  return depth_num_vertices;
+}
+
+//----- (0047840D) --------------------------------------------------------
+void Render::DrawBuildingsD3D()
+{
+  int v9; // ecx@8
+  Texture *pFaceTexture; // eax@10
+  unsigned int v16; // edi@22
+  int v27; // eax@57
+  int vertex_id; // eax@58
+  unsigned int v34; // eax@80
+  int v40; // [sp-4h] [bp-5Ch]@2
+  int v49; // [sp+2Ch] [bp-2Ch]@10
+  int v50; // [sp+30h] [bp-28h]@34
+  int v51; // [sp+34h] [bp-24h]@35
+  int v52; // [sp+38h] [bp-20h]@36
+  int v53; // [sp+3Ch] [bp-1Ch]@8
+  int uNumVertices; // [sp+4Ch] [bp-Ch]@34
+  int unused; // [sp+50h] [bp-8h]@3
+
+  if ( !pRenderer->pRenderD3D )
+  {
+    MessageBoxW(nullptr, L"D3D version of RenderBuildings called in software!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odbuild.cpp:73", 0);
+  }
+
+  unused = 0;
+  if ( (signed int)pOutdoor->uNumBModels > 0 )
+  {
+    for ( uint model_id = 0; model_id < pOutdoor->uNumBModels; model_id++ )
+    {
+      if ( IsBModelVisible(model_id, &unused) )
+      {
+        pOutdoor->pBModels[model_id].field_40 |= 1;
+        if ( pOutdoor->pBModels[model_id].uNumFaces > 0 )
+        {
+          for ( int face_id = 0; face_id < pOutdoor->pBModels[model_id].uNumFaces; face_id++ )
+          {
+            if (!pOutdoor->pBModels[model_id].pFaces[face_id].Invisible())
+            {
+            v53 = 0;
+            array_77EC08[pODMRenderParams->uNumPolygons].flags = 0;
+            array_77EC08[pODMRenderParams->uNumPolygons].field_32 = 0;
+            v9 = pOutdoor->pBModels[model_id].pFaces[face_id].uTextureID;
+            if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_TEXTURE_FRAME)
+              v9 = pTextureFrameTable->GetFrameTexture(v9, pEventTimer->uTotalGameTimeElapsed);
+            pFaceTexture = pBitmaps_LOD->GetTexture(v9);
+            array_77EC08[pODMRenderParams->uNumPolygons].pTexture = pFaceTexture;
+            if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_FLUID)
+              array_77EC08[pODMRenderParams->uNumPolygons].flags |= 2;
+            if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_DO_NOT_LIGHT )
+              HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 4;
+            if ( pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & 4 )
+              HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 4;
+            else
+            {
+              if ( pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & 0x20 )
+                HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 8;
+            }
+            if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & 0x0800)
+              array_77EC08[pODMRenderParams->uNumPolygons].flags |= 0x2000;
+            else
+            {
+              if (pOutdoor->pBModels[model_id].pFaces[face_id].uAttributes & FACE_DONT_CACHE_TEXTURE)
+                HIBYTE(array_77EC08[pODMRenderParams->uNumPolygons].flags) |= 0x10u;
+            }
+            array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU = pOutdoor->pBModels[model_id].pFaces[face_id].sTextureDeltaU;
+            array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV = pOutdoor->pBModels[model_id].pFaces[face_id].sTextureDeltaV;
+            v16 = GetTickCount() >> 4;
+            if ( pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.z && abs(pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.z) >= 59082 )
+            {
+              if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 4 )
+                array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV += v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1;
+              if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 8 )
+                array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV -= v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1;
+            }
+            else
+            {
+              if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 4 )
+                array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV -= v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1;
+              if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 8 )
+                array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV += v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uHeightMinus1;
+            }
+            if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 0x10 )
+              array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU -= v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uWidthMinus1;
+            else
+            {
+              if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 0x20 )
+                array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU += v16 & array_77EC08[pODMRenderParams->uNumPolygons].pTexture->uWidthMinus1;
+            }
+            v50 = 0;
+            v49 = 0;
+            uNumVertices = pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices;
+            if ( pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices > 0 )
+            {
+              for ( uint vertex_id = 1; vertex_id <= pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; vertex_id++ )
+              {
+                array_73D150[vertex_id - 1].vWorldPosition.x = pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[vertex_id - 1]].x;
+                array_73D150[vertex_id - 1].vWorldPosition.y = pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[vertex_id - 1]].y;
+                array_73D150[vertex_id - 1].vWorldPosition.z = pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[vertex_id - 1]].z;
+                array_73D150[vertex_id - 1].u = (array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaU + (signed __int16)pOutdoor->pBModels[model_id].pFaces[face_id].pTextureUIDs[vertex_id - 1]) * (1.0 / (double)pFaceTexture->uTextureWidth);
+                array_73D150[vertex_id - 1].v = (array_77EC08[pODMRenderParams->uNumPolygons].sTextureDeltaV + (signed __int16)pOutdoor->pBModels[model_id].pFaces[face_id].pTextureVIDs[vertex_id - 1]) * (1.0 / (double)pFaceTexture->uTextureHeight);
+              }
+              for ( uint i = 1; i <= pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; i++ )
+              {
+                if ( pOutdoor->pBModels[model_id].pVertices.pVertices[pOutdoor->pBModels[model_id].pFaces[face_id].pVertexIDs[0]].z == array_73D150[i - 1].vWorldPosition.z )
+                  ++v53;
+                pGame->pIndoorCameraD3D->ViewTransform(&array_73D150[i - 1], 1);
+                if ( array_73D150[i - 1].vWorldViewPosition.x < 8.0 || array_73D150[i - 1].vWorldViewPosition.x > pODMRenderParams->shading_dist_mist )
+                {
+                  if ( array_73D150[i - 1].vWorldViewPosition.x >= 8.0 )
+                    v49 = 1;
+                  else
+                    v50 = 1;
+                }
+                else
+                  pGame->pIndoorCameraD3D->Project(&array_73D150[i - 1], 1, 0);
+              }
+            }
+            if ( v53 == pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices )
+              LOBYTE(array_77EC08[pODMRenderParams->uNumPolygons].field_32) |= 1;
+            array_77EC08[pODMRenderParams->uNumPolygons].pODMFace = &pOutdoor->pBModels[model_id].pFaces[face_id];
+            array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices = pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices;
+            array_77EC08[pODMRenderParams->uNumPolygons].field_59 = 5;
+            v51 = (unsigned __int64)(-pOutdoor->vSunlight.x * (signed __int64)pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.x) >> 16;
+            v53 = (unsigned __int64)(-pOutdoor->vSunlight.y * (signed __int64)pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.y) >> 16;
+            v52 = (unsigned __int64)(-pOutdoor->vSunlight.z * (signed __int64)pOutdoor->pBModels[model_id].pFaces[face_id].pFacePlane.vNormal.z) >> 16;
+            array_77EC08[pODMRenderParams->uNumPolygons].dimming_level = 20 - (20 * (signed int)(v51 + v53 + v52) >> 16);
+            if ( array_77EC08[pODMRenderParams->uNumPolygons].dimming_level < 0 )
+              array_77EC08[pODMRenderParams->uNumPolygons].dimming_level = 0;
+            if ( array_77EC08[pODMRenderParams->uNumPolygons].dimming_level > 31 )
+              array_77EC08[pODMRenderParams->uNumPolygons].dimming_level = 31;
+            if ( pODMRenderParams->uNumPolygons >= 1999 + 5000)
+              return;
+            if ( ODMFace::IsBackfaceCulled(&pOutdoor->pBModels[model_id].pFaces[face_id], array_73D150, &array_77EC08[pODMRenderParams->uNumPolygons]) )
+            {
+              pOutdoor->pBModels[model_id].pFaces[face_id].bVisible = 1;
+              array_77EC08[pODMRenderParams->uNumPolygons].uBModelFaceID = face_id;
+              array_77EC08[pODMRenderParams->uNumPolygons].uBModelID = model_id;
+              v27 = 8 * (face_id | (model_id << 6));
+              LOBYTE(v27) = v27 | 6;
+              array_77EC08[pODMRenderParams->uNumPolygons].field_50 = v27;
+              for ( int vertex_id = 0; vertex_id < pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices; ++vertex_id)
+              {
+                memcpy(&array_50AC10[vertex_id], &array_73D150[vertex_id], sizeof(array_50AC10[vertex_id]));
+                array_50AC10[vertex_id]._rhw = 1.0 / (array_73D150[vertex_id].vWorldViewPosition.x + 0.0000001);
+              }
+              static stru154 static_RenderBuildingsD3D_stru_73C834;
+              /*static bool __init_flag = false;
+              if (!__init_flag)
+              {
+                __init_flag = true;
+                static_RenderBuildingsD3D_byte_73C84C_init_flag |= 1u;
+                stru154::stru154(&static_RenderBuildingsD3D_stru_73C834);
+                atexit(loc_4789D4);
+              }*/
+
+              v40 = (int)&pOutdoor->pBModels[model_id].pFaces[face_id];
+              pGame->pLightmapBuilder->ApplyLights_OutdoorFace(&pOutdoor->pBModels[model_id].pFaces[face_id]);
+              pDecalBuilder->ApplyDecals_OutdoorFace(&pOutdoor->pBModels[model_id].pFaces[face_id]);
+              pGame->pLightmapBuilder->std__vector_000004_size = 0;
+              int v31 = 0;
+              if ( stru_F8AD28.uNumLightsApplied > 0 || pDecalBuilder->uNumDecals > 0 )
+              {
+                v31 = v50 ? 3 : v49 != 0 ? 5 : 0;
+                static_RenderBuildingsD3D_stru_73C834.GetFacePlaneAndClassify(&pOutdoor->pBModels[model_id].pFaces[face_id], &pOutdoor->pBModels[model_id].pVertices);
+                if ( pDecalBuilder->uNumDecals > 0 )
+                {
+                  v40 = -1;
+                  pDecalBuilder->ApplyDecals(31 - array_77EC08[pODMRenderParams->uNumPolygons].dimming_level, 2, &static_RenderBuildingsD3D_stru_73C834,
+                                       pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices, array_50AC10, 0, (char)v31, -1);
+                }
+              }
+              if ( stru_F8AD28.uNumLightsApplied > 0 )
+                pGame->pLightmapBuilder->ApplyLights(&stru_F8AD28, &static_RenderBuildingsD3D_stru_73C834, uNumVertices, array_50AC10, 0, (char)v31);
+              if ( v50 )
+              {
+                array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices = sr_424CD7(pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices);
+                uNumVertices = array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices;
+                ODM_Project(array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices);
+              }
+              if ( v49 )
+              {
+                array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices = BuildingVerticesClipping(pOutdoor->pBModels[model_id].pFaces[face_id].uNumVertices);
+                uNumVertices = array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices;
+                ODM_Project(array_77EC08[pODMRenderParams->uNumPolygons].uNumVertices);
+              }
+              if ( uNumVertices )
+              {
+                if ( array_77EC08[pODMRenderParams->uNumPolygons].flags & 2 )
+                {
+                  if ( BYTE1(array_77EC08[pODMRenderParams->uNumPolygons].flags) & 0x3C )
+                    v34 = pRenderer->pHDWaterBitmapIDs[0];
+                  else
+                    v34 = pRenderer->pHDWaterBitmapIDs[pRenderer->hd_water_current_frame];
+                  v40 = (int)pBitmaps_LOD->pHardwareTextures[v34];
+                }
+                else
+                  v40 = (int)pBitmaps_LOD->pHardwareTextures[v9];
+                pRenderer->DrawPolygon(uNumVertices, &array_77EC08[pODMRenderParams->uNumPolygons], &pOutdoor->pBModels[model_id].pFaces[face_id], (IDirect3DTexture2 *)v40);
+              }
+            }
+          }
+          }
+        }
+      }
+    }
+  }
+  return;
 }
\ No newline at end of file