2009年8月31日星期一

(3)第一個GLSL程式 part[下]

video

先來分享一首老歌~Bon Jovi的All About Loving You~
覺得這MV老歸老,但是屌到掉渣!

------------------------------------------------------------------------------------------

上一篇的Hello World解壓縮後,其主程式(ogl3.cpp)裡用OpenGL API來設置GLSL的function如下: (有解釋錯誤的地方,請不吝指教 @@)

void setShaders() {
char *vs = NULL,*fs = NULL;

/*GLuint glCreateShader(GLenum shaderTypr)
顧名思義,就是建立存放shader的變數囉*/
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);

/*讀取vertex shader 和 fragment shader的內容*/
vs = textFileRead("minimal.vert");
fs = textFileRead("minimal.frag");

const char * vv = vs;
const char * ff = fs;

/*void glShaderSource(GLuint shader,
GLsizei count,
const GLchar **string,
const GLint *length)
◎將shader的source code設成string(array of strings)的內容,而在string
這個string array中有幾個string是由count 決定.
◎如果length = NULL,則每個string的結尾為null,否則其皆為指定string
中每個元素的長度
◎每個在
length 這個array中的元素,皆為其所對應的string的長度,若其
值小於0,則說明所對應的string的結尾為null
*/
glShaderSource(v, 1, &vv,NULL);
glShaderSource(f, 1, &ff,NULL);

free(vs);
free(fs);

/*void glCompileShader(GLuint shader)
shader為所要compile的shader object*/
glCompileShader(v);
glCompileShader(f);

printShaderInfoLog(v);
printShaderInfoLog(f);

/*GLuint glCreateProgram(void)
◎glCreateProgram建置一個空的program object及傳回一個non-zero
value來reference用
◎其所建置的program object可用來給shader object attach*/

p = glCreateProgram();

glAttachShader(p,v);
glAttachShader(p,f);

/*void glLinkProgram(GLuint program)
◎如shader object為GL_VERTEX_SHADER且已attach在program上,
則此function在programmable vertex processer上是可執行的
◎program是程序容器,在此function執行後,可以任意修改shader的
原代碼,對shader重新compile不會影響整個程序,除非重新連接程序*/
glLinkProgram(p);

printProgramInfoLog(p);

/*void UseProgram(GLuint program)
用來加載並使用連接好的程序*/

glUseProgram(p);
}

接著來小小介紹一下vertex shader和fragment shader吧~

對於要顯示出來的物件(ex:teapot, cube, sphere...etx),GPU會對其頂點(vertex)進行處理,並將之轉換成螢幕空間幾何體(screen-space geometry),該幾何體透過光柵化(rasterization)過程依次被劃分為畫素片段(pixel-sized fragment)。每一片段與螢幕上的一個畫素位置相關。最後,這些片段被處理並組合到由畫素組成的影像中。

而vertex shader和fragment shader,分別為GPU越來處理vertex以及pixel-sized fragment所用的code。

最後來看看這個範例的vertex shader和fragment shader裡寫了些什麼吧~

Vertex Shader:


// minimal vertex shader
// http://www.lighthouse3d.com/
void main(){
// the following three lines provide the same result
/*
#更新gl_Position的內容,就是在告知GPU某個頂點轉換到螢幕座標系上的結

#讀取gl_Vertex就可以取得頂點的位置
#glModelViewProjectionMatrix是內建變數,它可以取得經由C/C++呼叫
glLoadMatrixf等矩陣操作函式所設定的矩陣內容
*/
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
/*gl_ProjectionMatrix*gl_ModelViewMatrix=gl_ModelViewProjectionMatrix*/
//gl_Position=gl_ProjectionMatrix*gl_ModelViewMatrix*gl_Vertex;
/*上面兩個等號右邊的東西,可以用一個內建function:ftransform();來取代*/
//gl_Position = ftransform();
}

Fragment Shader:


// minimal fragment shader
// http://www.lighthouse3d.com/
void main(){
/*gl_FragColor代表物件在畫面上所要顯示的顏色*/
gl_FragColor = vec4(0.4,0.4,0.8,1.0);
}

0 意見:

張貼意見