2012-04-23 114 views
2

我正在使用OpenGL ES fluid simulation,它使用紋理貼圖來保存網格值。我需要遍歷直通模仿下面的循環電網:內插紋理座標

for (int r = 0; r < 128; r++) 
    for (int c = 0; c < 128; c++) 
     process grid element at (c,r) 

要通過網格迭代我只是填補這導致調用每個片段我的片段程序的四邊形。紋理座標(0,0),(1,0),(0,1),(1,1) 與頂點(-1,-1),(+ 1,-1), 1,+ 1),(+ 1,+ 1)和I呈現四邊形(如三角形帶)插入連接到FBO作爲128×128紋理貼圖如下:

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, texFrameBuffer); 
glViewport(0, 0, TEX_IMAGE_WIDTH, TEX_IMAGE_HEIGHT); // 128 x 128 

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); 
glEnableVertexAttribArray(positionAttr); 
glVertexAttribPointer(positionAttr, 2, GL_FLOAT, GL_FALSE, 0, 0); 

glBindBuffer(GL_ARRAY_BUFFER, texCoordBuffer); 
glEnableVertexAttribArray(texCoordAttr); 
glVertexAttribPointer(texCoordAttr, 2, GL_FLOAT, GL_FALSE, 0, 0); 

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

頂點着色器僅經過位置並通過未修改的紋理座標。爲了理解生成的紋理座標,我決定將紋理座標捕捉到圖像中。該片段程序分配其給定2D紋理座標爲輸出顏色的紅色和綠色通道:

varying vec4 texCoord; 
void main() { 
    gl_FragColor = vec4(texCoord.st,0,1); 
} 

我然後使用glGetTexImage()讀出紋理圖像回客戶端的空間。 以下是圖像中的每個像素所生成的紋理座標(S,T)的樣品:

(column, row) = [s, t] -> (128*s, 128*t) 

(0,0) = [0.00392157, 0.00392157] -> (0,0) 
(1,0) = [0.01176471, 0.00392157] -> (1,0) 
(2,0) = [0.01960784, 0.00392157] -> (2,0) 
(3,0) = [0.02745098, 0.00392157] -> (3,0) 
(4,0) = [0.03529412, 0.00392157] -> (4,0) 
(5,0) = [0.04313726, 0.00392157] -> (5,0) 
(6,0) = [0.05098040, 0.00392157] -> (6,0) 
(7,0) = [0.05882353, 0.00392157] -> (7,0) 
(8,0) = [0.06666667, 0.00392157] -> (8,0) 
(9,0) = [0.07450981, 0.00392157] -> (9,0) 
(10,0) = [0.08235294, 0.00392157] -> (10,0) 
<snip> 
(125,0) = [0.98039222, 0.00392157] -> (125,0) 
(126,0) = [0.98823535, 0.00392157] -> (126,0) 
(127,0) = [0.99607849, 0.00392157] -> (127,0) 
(0,1) = [0.00392157, 0.01176471] -> (0,1) 
(1,1) = [0.01176471, 0.01176471] -> (1,1) 
(2,1) = [0.01960784, 0.01176471] -> (2,1) 
<snip> 
(124,127) = [0.97254908, 0.99607849] -> (124,127) 
(125,127) = [0.98039222, 0.99607849] -> (125,127) 
(126,127) = [0.98823535, 0.99607849] -> (126,127) 
(127,127) = [0.99607849, 0.99607849] -> (127,127) 

我們的問題。我想了解這些生成的座標。 魔術值​​是(0.5 * 1/127.5)。我理解這個0.5因子是一個預先加入的舍入值,但爲什麼是127.5? (0.5 * 1/128.0)會更有意義嗎?誰能解釋這些座標嗎?我只想從紋理座標生成整數網格座標(OpenGL ES中沒有sampler2Drect)。

回答

3

我總是爲此而鬥爭,所以讓我們看看我能否解釋它。

想象一下你的網格。在下面的圖片中,我已經對該行中的每個片段(0-127)進行了編號。我也在像素下面放置了一些紋理座標。請注意,最左邊緣是0.0,最右邊緣是1.0。

+-----------+-----------+-----------+-----------+--- ---+-----------+ 
|   |   |   |   |   |   | 
|   |   |   |   |   |   | 
|  0  |  1  |  2  |  3  | . . . | 127 | 
|   |   |   |   |   |   | 
|   |   |   |   |   |   | 
+-----------+-----------+-----------+-----------+--- ---+-----------+ 
^   ^  ^  ^     ^  ^
|   |   |   |      |   | 
|   |   |   |      |   | 
0/128  1/128  2/128  3/128    127/128  128/128 

當渲染要紋理片段,它使用片段的中心的紋理座標 - 其中的數字。請注意片段0的中心位於0/128(又名0)和1/128(又名.0078125)之間的中間位置。那是1/256(又名.00390625)。

所以,我認爲該公式將得到更好的表述爲:

coordinate = (pixelId + 0.5)/128 

下面是一些蟒蛇是得到答案類似到你:

for i in range(128): 
    print (0.5 + i)/128 


0.00390625 
0.01171875 
0.01953125 
0.02734375 
0.03515625 
0.04296875 
... 
0.97265625 
0.98046875 
0.98828125 
0.99609375 

我懷疑我的結果之間的差異並且你的結果與你的值被擠壓成一個[8位]顏色通道以從着色器返回它們的事實有關。

我希望這會有所幫助。

+0

你能澄清這句話嗎?「想象一下你的網格有128行。」請? – 2012-05-10 17:23:52

+0

謝謝,@JohnFisher。我修復了我亂碼的句子。 – certainmagic 2012-05-11 04:58:47