2009-11-12 65 views
2

我遇到了DirectX 9地形引擎的問題。它工作正常,除了一件事情,它沒有以適當的方式加載高度圖。 你可以在這裏看到問題的屏幕截圖:alt text http://img682.imageshack.us/img682/240/problemc.png 正如你所看到的那樣,整個地圖都有一條對角線的裂縫。一面應該被鏡像來正確渲染地圖。DirectX 9地形引擎問題C++

我幾乎可以肯定問題不在文件內,因爲其他程序似乎沒有問題。

我加載我的高度圖以這種方式(類的頭在前):

class Terrain 
{ 
public: 
Terrain(const char* fileName); 
~Terrain(); 
void Update(int x, int y); 
void Render(LPDIRECT3DDEVICE9 Device); 

private: 
float* Data; 
int Width; 
int TileWidth; 
bool isRendering; 
bool isSwapping; 
std::vector<Chunk*> RenderChunks; 
}; 

和構造:

Terrain::Terrain(const char* fileName) 
{ 
std::fstream File(fileName, std::ios::in | std::ios::binary); 

File.seekg(0, std::ios::end); 
int Length = File.tellg(); 
File.seekg(0, std::ios::beg); 

int w = (int)sqrt((float)Length/4.0)-1; 
Data = new float[Length/4]; 
File.read((char*)Data, Length); 
File.close(); 

Width = w; 
int dataWidth = w+1; 

TileWidth = w/16; 
for (int y=0; y<TileWidth; y++) 
{ 
    for (int x=0; x<TileWidth; x++) 
    { 
     Chunk* c = new Chunk(x*16, y*16, 16, 512, Data); 
     RenderChunks.push_back(c); 
    } 
} 
} 

每當我在調用高度圖的高度,我使用它是這樣的:Data [x + y * dataWidth](只是通常的方式) Chunk類是一個類,它只是呈現高度圖的一部分,只是隨着與相機距離的增加細節減少。

所以我的問題是:什麼會導致我的問題?

編輯:渲染代碼:(?或者您正在使用其他類型的原語)

void Terrain::Render(LPDIRECT3DDEVICE9 Device) 
{ 
for (unsigned int i=0; i<RenderChunks.size(); ++i) 
{ 
    RenderChunks[i]->Render(Device); 
} 
} 
Chunk::Chunk(int cX, int cY, int cW, int dW, float* Data): 
    Pos(cX, 0, cY) 
{ 
Heights = new float[(cW + 1) * (cW + 1)]; 
ParentH = Data; 
ParentOffset = cX + cY*dW; 
ParentW = dW; 
Width = cW + 1; 

for (int y=0; y<Width; ++y) 
{ 
    memcpy(Heights + y*Width, Data + cX + (y+cY)*dW, sizeof(float)*Width); 
} 

Vertices = NULL; 
Calculate(16, 16, 16, 16, 16); 
} 
void Chunk::Calculate(int L, int lod_L, int lod_R, int lod_U, int lod_D) 
{ 
Detail = L; 
if (Vertices) delete[] Vertices; 

Vertices = new Vertex[(Width-1)*(Width-1)*6/(L*L)]; 
Count  = (Width-1)*(Width-1)*2/(L*L); 

float Height = 100.0f; 
for (int y=0; y<Width-1; y += L) 
{ 
    for (int x=0; x<Width-1; x += L) 
    { 
     Vertex* thisQuad = Vertices + (y/L)*((Width-1)/L)*6 + (x/L)*6; 
     float heights[4] = { 
      Heights[(x ) + (y )*Width] * Height, 
      Heights[(x ) + (y + L)*Width] * Height, 
      Heights[(x + L) + (y )*Width] * Height, 
      Heights[(x + L) + (y + L)*Width] * Height}; 

     float bonus[8] = { 
      heights[0], 
      heights[2], 
      heights[0], 
      heights[2], 
      heights[1], 
      heights[3], 
      heights[1], 
      heights[3]}; 
     if (Pos.z + y > 0) 
     { 
      bonus[0] = ParentH[((int)Pos.x + x ) + ((int)Pos.z + y - L)*ParentW] * Height; 
      bonus[1] = ParentH[((int)Pos.x + x + L) + ((int)Pos.z + y - L)*ParentW] * Height; 
     } 
     if (Pos.x + x > 0) 
     { 
      bonus[2] = ParentH[((int)Pos.x + x - L) + ((int)Pos.z + y )*ParentW] * Height; 
      bonus[4] = ParentH[((int)Pos.x + x - L) + ((int)Pos.z + y + L)*ParentW] * Height; 
     } 
     if (Pos.x + x < ParentW-L-L) 
     { 
      bonus[3] = ParentH[((int)Pos.x + x+L+L) + ((int)Pos.z + y )*ParentW] * Height; 
      bonus[5] = ParentH[((int)Pos.x + x+L+L) + ((int)Pos.z + y + L)*ParentW] * Height; 
     } 
     if (Pos.z + y < ParentW-L-L) 
     { 
      bonus[6] = ParentH[((int)Pos.x + x ) + ((int)Pos.z + y+L+L)*ParentW] * Height; 
      bonus[7] = ParentH[((int)Pos.x + x + L) + ((int)Pos.z + y+L+L)*ParentW] * Height; 
     } 

     if (x == 0 && lod_L>L) 
     { 
      heights[0] = lerp(
       Heights[(x ) + (((y )/lod_L)*lod_L  )*Width], 
       Heights[(x ) + (((y )/lod_L)*lod_L + lod_L)*Width], 
       (float)((y ) % lod_L)/(float)lod_L) * Height; 

      heights[1] = lerp(
       Heights[(x ) + (((y + L)/lod_L)*lod_L  )*Width], 
       Heights[(x ) + (((y + L)/lod_L)*lod_L + lod_L)*Width], 
       (float)((y+L) % lod_L)/(float)lod_L) * Height; 
     } 
     if (x >= Width-2 && lod_R>L) 
     { 
      heights[2] = lerp(
       Heights[(x + L) + (((y )/lod_R)*lod_R  )*Width], 
       Heights[(x + L) + (((y )/lod_R)*lod_R + lod_R)*Width], 
       (float)((y ) % lod_R)/(float)lod_R) * Height; 

      heights[3] = lerp(
       Heights[(x + L) + (((y + L)/lod_R)*lod_R  )*Width], 
       Heights[(x + L) + (((y + L)/lod_R)*lod_R + lod_R)*Width], 
       (float)((y+L) % lod_R)/(float)lod_R) * Height; 
     }//*/ 
     if (y == 0 && lod_U>L) 
     { 
      heights[0] = lerp(
       Heights[(((x )/lod_U)*lod_U  ) + (y )*Width], 
       Heights[(((x )/lod_U)*lod_U + lod_U) + (y )*Width], 
       (float)((x ) % lod_U)/(float)lod_U) * Height; 

      heights[2] = lerp(
       Heights[(((x + L)/lod_U)*lod_U  ) + (y )*Width], 
       Heights[(((x + L)/lod_U)*lod_U + lod_U) + (y )*Width], 
       (float)((x+L) % lod_U)/(float)lod_U) * Height; 
     } 
     if (y >= Width-2 && lod_D>L) 
     { 
      heights[1] = lerp(
       Heights[(((x )/lod_D)*lod_D  ) + (y + L)*Width], 
       Heights[(((x )/lod_D)*lod_D + lod_D) + (y + L)*Width], 
       (float)((x ) % lod_D)/(float)lod_D) * Height; 

      heights[3] = lerp(
       Heights[(((x + L)/lod_D)*lod_D  ) + (y + L)*Width], 
       Heights[(((x + L)/lod_D)*lod_D + lod_D) + (y + L)*Width], 
       (float)((x+L) % lod_D)/(float)lod_D) * Height; 
     }//*/ 

     D3DXVECTOR3 fake(0,0,0); 
     Vertex p1(D3DXVECTOR3(x,  heights[0], y ) + Pos, CalcNormal(bonus[2], heights[2], bonus[0], heights[1])); 
     Vertex p2(D3DXVECTOR3(x,  heights[1], y + L) + Pos, CalcNormal(bonus[4], heights[3], heights[0], bonus[6])); 
     Vertex p3(D3DXVECTOR3(x + L, heights[2], y ) + Pos, CalcNormal(heights[0], bonus[3], bonus[1], heights[3])); 
     Vertex p4(D3DXVECTOR3(x + L, heights[3], y + L) + Pos, CalcNormal(heights[1], bonus[5], heights[2], bonus[7])); 

     thisQuad[0] = p1; 
     thisQuad[1] = p2; 
     thisQuad[2] = p3; 

     thisQuad[3] = p3; 
     thisQuad[4] = p2; 
     thisQuad[5] = p4; 
    } 
} 
} 
void Chunk::Render(LPDIRECT3DDEVICE9 Device) 
{ 
Device->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL); 

Device->DrawPrimitiveUP(
    D3DPT_TRIANGLELIST, 
    Count, 
    Vertices, 
    sizeof(Vertex)); 
} 

回答

2

我猜你的問題是你的塊類需要一個寬度(cW),然後你指定該值+ 1的寬度。進一步假設cW是高度貼圖中紋素的數量(即,在一個1024x1024高度圖cW是1024)。如果那是正確的,那麼每增加一個後續行將會向左偏移1.當你繼續下去時,你會讓問題變得更糟,所以512行會在512行左邊(或者在紋理的中間開始)。這會讓你看到對角線的剪切力。

+0

哇,很好的分析 –

+0

這是dW參數給出的問題 – Brammie

0

它看起來很像在其中正在建設的三角形帶(S)的順序有問題。你能發佈渲染循環的相關部分嗎?

編輯:我的直覺是當你鏡像你的地形數據時,你會在對角線上創建一個縱橫交錯的幾何圖形,因爲你的地形四邊形的角落(如果你想像它們那樣)連接到角落對角地跨越而不是直接跨越。我希望某些DirectX /渲染專家可以根據您發佈的代碼給出更準確的答案。

+0

編輯開始帖子 – Brammie

0

這似乎是一個「關1」的錯誤,但帖子說,似乎被刪除某種.. 無論如何這是正確的解決方案。