2010-08-23 41 views
1

我在OpenGL中有一個圖像,我試圖應用一個簡單的HSB濾鏡。用戶選擇一個色調值,我適當地遮蔽圖像,顯示它,並且每個人都很開心。我遇到的問題是,我所繼承的代碼在先前的系統(Solaris,假設OpenGL 2.1)上工作,並不適用於我們當前的系統(RHEL 5,OpenGL 3.0)。應用色相/飽和度濾鏡與OpenGL的圖像

現在,無論設置了多少飽和度,圖像都會以灰度顯示。但是,亮度似乎確實適當。相關的代碼已經被轉載如下:

// imageData - unsigned char[3*width*height] 
// (red|green|blue)Channel - unsigned char[width*height] 
// brightnessBias - float in range [-1/3,1/3] 
// hsMatrix - float[4][4] Described by algorithm from 
//   http://www.graficaobscura.com/matrix/index.html 
//   (see Hue Rotation While Preserving Luminance) 

glDrawPixels(width, height, format, GL_UNSIGNED_BYTE, imageData); 

// Split into RGB channels 
glReadPixels(0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, redChannel); 
glReadPixels(0, 0, width, height, GL_GREEN, GL_UNSIGNED_BYTE, greenChannel); 
glReadPixels(0, 0, width, height, GL_BLUE, GL_UNSIGNED_BYTE, blueChannel); 

// Redraw and blend RGB channels with scaling and bias 
glPixelZoom(1.0, 1.0); 
glRasterPos2i(0, height); 

glPixelTransferf(GL_RED_BIAS, brightnessBias); 
glPixelTransferf(GL_GREEN_BIAS, brightnessBias); 
glPixelTransferf(GL_BLUE_BIAS, brightnessBias); 

glDisable(GL_BLEND); 

glPixelTransferf(GL_RED_SCALE, hsMatrix[0][0]); 
glPixelTransferf(GL_GREEN_SCALE, hsMatrix[1][0]); 
glPixelTransferf(GL_BLUE_SCALE, hsMatrix[2][0]); 
glDrawPixels(width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, redChannel); 

glEnable(GL_BLEND); 
glBlendFunc(GL_ONE, GL_ONE); 

glPixelTransferf(GL_RED_SCALE, hsMatrix[0][1]); 
glPixelTransferf(GL_GREEN_SCALE, hsMatrix[1][1]); 
glPixelTransferf(GL_BLUE_SCALE, hsMatrix[2][1]); 
glDrawPixels(width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, greenChannel); 

glPixelTransferf(GL_RED_SCALE, hsMatrix[0][2]); 
glPixelTransferf(GL_GREEN_SCALE, hsMatrix[1][2]); 
glPixelTransferf(GL_BLUE_SCALE, hsMatrix[2][2]); 
glDrawPixels(width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, blueChannel); 

// Reset pixel transfer parameters 
glDisable(GL_BLEND); 
glPixelTransferf(GL_RED_SCALE, 1.0f); 
glPixelTransferf(GL_GREEN_SCALE, 1.0f); 
glPixelTransferf(GL_BLUE_SCALE, 1.0f); 
glPixelTransferf(GL_RED_BIAS, 0.0f); 
glPixelTransferf(GL_GREEN_BIAS, 0.0f); 
glPixelTransferf(GL_BLUE_BIAS, 0.0f); 

亮度控制工程如預期,但是,glPixelTransferf(GL _ * _ SCALE)電話留在的時候,圖像顯示灰度。所有這一切都是因爲我沒有使用過OpenGL的經驗,所以我發現很多鏈接是我認爲更現代的技術,我根本無法理解。

編輯:

我相信背後是做什麼工作的理論是在通過繪製調用做矩陣乘法一個黑客,因爲GL_LUMINANCE對待一個值作爲所有三個組成部分的價值,因此,如果您按照組件通過繪畫,你還指望

// After glDrawPixels(..., redChannel) 
new_red = red*hsMatrix[0][0] 
new_green = red*hsMatrix[1][0] 
new_blue = red*hsMatrix[2][0] 
// After glDrawPixels(..., greenChannel) 
new_red = red*hsMatrix[0][0] + green*hsMatrix[0][1] 
new_green = red*hsMatrix[1][0] + green*hsMatrix[1][1] 
new_blue = red*hsMatrix[2][0] + green*hsMatrix[2][1] 
// After glDrawPixels(..., blueChannel) 
new_red = red*hsMatrix[0][0] + green*hsMatrix[0][1] + blue*hsMatrix[0][2] 
new_green = red*hsMatrix[1][0] + green*hsMatrix[1][1] + blue*hsMatrix[1][2] 
new_blue = red*hsMatrix[2][0] + green*hsMatrix[2][1] + blue*hsMatrix[2][2] 

因爲它無論如何轉向了灰階和類似十歲上下的例子,我曾認爲我可能需要做的glPixelTransfer調用glDrawPixels前調用,但這是非常慢。

+0

作爲附加信息,我可以驗證hsMatrix的值也看起來是正確的(例如,對於hue = 0,飽和度= 1,它是單位矩陣,對於hue = 0,飽和度= 0,它是三排[0.3086,0.6094,0.0820] – Matt 2010-08-23 20:24:49

回答

1

哇,這到底是什麼?

對於你的問題,我會分別用GL_RED,GL_GREEN和GL_BLUE替換3個glDrawPixels中的GL_LUMINANCE。

但是:

glPixelTransfer是

glDrawPixels是

有你爲什麼不使用超級簡單的片段着色器來執行轉換一個原因嗎?這是一個簡單的矩陣乘法,你在ogl3.0 ...

  • 從imageData創建一個紋理,這隻需要做一次。
  • 製作的着色器,其讀取從紋理的顏色,通過顏色轉換矩陣相乘,並顯示它
  • 綁定所計算的色彩矩陣
  • 畫出全屏四邊形。即使是5歲的卡片也能獲得500 fps。
+0

我會希望能稍稍改變一下,但這種證實我的懷疑並不是特別值得的。 此外,我試圖用相應的組件枚舉代替GL_LUMINANCE,但是當完全去飽和時,圖像主要爲綠色。我已經更新了OP來包含我對代碼應該做什麼的解釋。 – Matt 2010-08-24 20:32:41