2011-08-25 82 views
1

當您在三維地圖編輯器(例如Valve的Hammer Editor)中創建畫筆時,對象的紋理默認重複並與世界座標對齊。如何在OpenGL中實現世界座標對齊的重複紋理映射?

如何使用OpenGL實現此功能?

glTexGen可以用來實現這個嗎?

或者我必須以某種方式使用紋理矩陣?

如果我創建3×3盒,那麼它很簡單: 設置GL_TEXTURE_WRAP_T在邊緣GL_REPEAT 設置texturecoords到3,3。

但是,如果對象不是軸對齊的凸起,它會變得有點複雜。

基本上我想從閥門錘面對創建編輯頁面的功能:

Valve Hammer Face Edit tool

回答

2

從技術上講,你可以使用紋理座標生成此。但我建議使用一個頂點着色器,它從變換後的頂點座標中生成紋理座標。更具體一些(我不太瞭解Hammer)。


看完視頻後,我明白你的困惑。我認爲你應該知道,Hammer/Source可能沒有繪圖API生成紋理座標,但在內部產生它們。

因此,您可以看到有紋理投影到X,Y或Z平面上,具體取決於臉部指向哪個主要方向。然後使用本地頂點座標作爲紋理座標。

您可以在將代碼加載到頂點緩衝區對象的代碼中實現此功能(效率更高,因爲計算僅執行一次),也可以在GLSL頂點着色器中實現。我給你的僞代碼:

cross(v1, v2): 
    return { x = v1.y * v2.z - v1.z * v2.y, 
      y = v2.x * v1.z - v2.z * v1.x, // <- "swapped" order! 
      z = v1.x * v2.y - v1.y * v2.x } 

normal(face): 
    return cross(face.position[1] - face.position[0], face.position[2] - face.position[0]) 

foreach face in geometry: 
    n = normal(face) // you'd normally precompute the normals and store them 
    if abs(n.x) > max(abs(n.y), abs(n.z)): // X major axis, project to YZ plane 
     foreach (i, pos) in enumerate(face.position): 
      face.texcoord[i] = { s = pos.y, t = pos.z } 

    if abs(n.y) > max(abs(n.x), abs(n.z)): // Y major axis, project to XZ plane 
     foreach (i, pos) in enumerate(face.position): 
      face.texcoord[i] = { s = pos.x, t = pos.z } 

    if abs(n.z) > max(abs(n.y), abs(n.x)): // Z major axis, project to XY plane 
     foreach (i, pos) in enumerate(face.position): 
      face.texcoord[i] = { s = pos.x, t = pos.y } 

爲了與glTexGen質地這項工作座標生成,你有你的模型分成每個長軸的部分。 glTexGen所做的只是映射步驟face.texcoord[i] = { s = pos.<>, t = pos.<> }。在頂點着色器中,您可以直接進行分支。

+0

問題是:如何在openGL中實現世界座標對齊的重複紋理映射? Valve Hammer只是一個例子(見:http://www.youtube.com/watch?v = 8R4aWvRQP-E) – JBeurer

+0

這可以工作,我會試試這個。我嘗試尋找臉部平面的正交基向量,然後在臉部上投影臉部頂點。 s = Vector.Dot(basis1,vertex); t = Vector.Dot(basis2,vertex);這種方法中的問題是該平面可以具有圍繞平面法線旋轉的多個正交基矢量。而且我不知道如何獲得飛機基礎矢量與原點有什麼不同。 – JBeurer