2013-03-10 83 views
1

我正在使用OpenTK在C#中編寫一個簡單的raycaster。 我希望我的視圖每秒刷新60次,所以我有一個計時器調用我的Render()函數,該函數在屏幕上顯示紋理。背景線程渲染紋理

我想使用遞歸函數通過將其分割成更小的矩形並渲染每個直到矩形大小爲1px來渲染我的場景。我的遞歸將像素的顏色寫入字節數組,我需要將其轉換爲紋理。遞歸很慢,所以我想在場景更改時在後臺線程中運行它。

什麼是同步線程的正確方法,以便寫入紋理數組(大約需要一秒),但另一個線程每1/60秒讀取一次並在屏幕上打印?

byte[, ,] texture; 

遞歸:

public void RenderAdaptively(int top, int left, int width, int height) 
    { 
     Color color = getColor(top, left); 
     for (int i = top; i < top + width + 1; i++) 
     { 
      for (int j = left; j < left + height; j++) 
      { 
       texture[i, j, 0] = color.R; 
       texture[i, j, 1] = color.G; 
       texture[i, j, 2] = color.B; 
      } 
     } 

     int halfw = width/2; 
     int halfh = height/2; 
     int newwidth = width - halfw; 
     int newheight = height - halfh; 

     if (width > 1 && height > 1) 
     { 
      RenderAdaptively(top, left, halfw, halfh, false); 
      RenderAdaptively(top + halfw, left + halfh, newwidth, newheight, false); 
      RenderAdaptively(top, left + halfh, halfw, newheight, false); 
      RenderAdaptively(top + halfw, left, newwidth, halfh, false); 
     } 
    } 
在另一個線程

raycasting_texture = TexUtil.CreateRGBTexture(width, height, texture); 
+0

在這裏顯示你的工作.. – 2013-03-10 08:58:28

回答

1

您有幾種選擇來試試,不過我會做這樣的:

  • 有兩個緩衝區用於存儲textu再作爲一個字節數組,說01

  • 做紋理計算在一個緩衝區,

  • 當它完成,由volatile int updated_buffer設置爲更新的緩存索引信號吧。

  • 有其他線程定期讀取updated_buffer,並保留其最新值的副本。當該副本和INT不同步,更新的副本並上傳紋理內存,

注意,該解決方案依賴於幾件事情:

  1. 只有兩個線程處理字節數組緩衝劑,

  2. updated_buffer僅由(紋理)消費者線程讀出並由生產者線程寫入,

  3. ,最重要的是紋理上傳比計算更合理更快

如果#2或#3被打破,你將不得不使用上的紋理緩存更嚴格的同步方法,如互斥體,以確保尚未上傳當紋理緩衝區不會被覆蓋。

最後,通過移動到低於某個閾值(例如8 * 8像素塊)的迭代,您的遞歸計算可以略微提升,而不是一路下降到1px。事實上,所有迭代操作都應該更快(如果在單個內核上的單線程中完成),儘管這取決於計算像素的算法。