3D Computer Grapihcs Using OpenGL - 07 Passing Data from Vertex to Fragment Shader

來源:互聯網
上載者:User

標籤:draw   技術   str   sha   oat   api   main   opengl   相對   

上節的最後我們實現了兩個綠色的三角形,而綠色是直接在Fragment Shader中指定的。

這節我們將為這兩個三角形進行更加自由的著色——五個頂點各自使用不同的顏色。

要實現這個目的,我們分兩步進行,首先

在頂點數組裡增加資料用來表示顏色

修改sendDataToOpenGL()函數中的verts數組:

 1     GLfloat verts[] = 2     { 3         +0.0f, +0.0f,        //Vertex 0 4         +1.0,  +0.0, +0.0f,    //Color  0 5         +1.0f, +1.0f,        //Vertex 1 6         +0.0,  +1.0, +0.0f,    //Color  1 7         -1.0f, +1.0f,        //Vertex 2 8         +0.0,  +0.0, +1.0f,    //Color  2 9         -1.0f, -1.0f,        //Vertex 310         +0.5f, +0.3f, +0.1f,//Color  311         +1.0f, -1.0f,        //Vertex 412         +0.1f, +0.4f, +0.2f,//Color  413     };

 

增加了5*3=15個元素,穿插在每個頂點位置後,表示顏色的r,g,b值。現在每5個資料描述一個頂點,前兩個表示頂點位置,後三個表示顏色。

為了把這些資料輸入到GPU,我們還需要啟用第二個通道。(我們之前只啟用了一個通道0)

修改sendDataToOpenGL()函數:

 1 void MyGlWindow::sendDataToOpenGL() 2 { 3     GLfloat verts[] = 4     { 5         +0.0f, +0.0f,        //Vertex 0 6         +1.0,  +0.0, +0.0f,    //Color  0 7         +1.0f, +1.0f,        //Vertex 1 8         +0.0,  +1.0, +0.0f,    //Color  1 9         -1.0f, +1.0f,        //Vertex 210         +0.0,  +0.0, +1.0f,    //Color  211         -1.0f, -1.0f,        //Vertex 312         +1.0f, +1.0f, +0.0f,//Color  313         +1.0f, -1.0f,        //Vertex 414         +0.0f, +1.0f, +1.0f,//Color  415     };16 17     GLuint vertexBufferID;18     glGenBuffers(1, &vertexBufferID);19     glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);20     glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);21 22     GLushort indices[] =23     {24         0,1,2,25         0,3,4,26     };27     GLuint indexBufferID;28     glGenBuffers(1, &indexBufferID);29     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);30     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);31 32     glEnableVertexAttribArray(0);33     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, 0);34 35     glEnableVertexAttribArray(1);36     glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (char*)(sizeof(GLfloat) * 2));37 }

注意第33行,函數glVertexAttribPointer函數第三個參數變成了sizeof(GLfloat)*5,原因是Stride變成了5個float,如前所述,5個元素描述一個頂點。

另外增加了第35和36行,35行開啟了通道1,這個1和前面的0是和Shader中的layout (location = x)對應的,稍後進行詳解。

第36行glVertexAttribPoint函數的第一個參數對應35行的1, 第二個參數表示三個元素為一組。

需要特別注意的是最後一個參數,它表示本組資料的起始位移值,本組資料的第一個位置在代碼中的第六行,它前面有2個元素,所以這裡是sizeof(GLfloat)*2,但是由於該函數第四個參數的類型是char*類型,我們只能強制轉換為char * 。

 

然後我們需要

修改Shader
 1 const char* vertexShaderCode = 2 "    #version 430                            \r\n" 3 "                                            \r\n" 4 "    in layout(location=0) vec2 position;    \r\n" 5 "    in layout(location=1) vec3 vertexColor; \r\n" 6 "                                            \r\n" 7 "    out vec3 passingColor;                  \r\n" 8 "                                            \r\n" 9 "    void main()                             \r\n"10 "    {                                       \r\n"11 "      gl_Position= vec4(position,0.0,1.0);  \r\n"12 "      passingColor= vertexColor;            \r\n"13 "    }                                       \r\n"14 "                                            \r\n"15 "                                            \r\n";16 17 const char* fragmentShaderCode =18 "    #version 430                            \r\n"19 "                                            \r\n"20 "    in vec3 passingColor;                   \r\n"21 "    out vec4 finalColor;                    \r\n"22 "                                            \r\n"23 "                                            \r\n"24 "    void main()                             \r\n"25 "    {                                       \r\n"26 "      finalColor = vec4(passingColor,1.0);  \r\n"27 "    }                                       \r\n"28 "                                            \r\n"29 "                                            \r\n";

先看Vertex Shader。

增加了第5行。

仔細看一下第4行和第5行,對比sendDataToOpenGL()函數的33和36行, location=0指定了通道0, vec2說明了需要二維向量(2個float),33行函數的前兩個參數也分別是0(表示通道0),2(表示兩個元素),兩者是相對應的。

ShaderCode的第5行和sendDataToOpenGL()的36行也是對應的。

再對應verts[]數組對比著看,就會發現其工作原理。verts數組每五個元素為一組,每組的前兩個元素將被發送到通道0,後三個元素將被發送到通道1。

 

另外Vertex Shader還增加了第7行,這裡使用了out關鍵字定義了一個三維向量passingColor,說明這個參數將被發送出去,傳遞到渲染管線的下一個環節。而在main中,我們把剛剛從通道2接受到的資料(存在vertexColor裡)傳遞給passingColor。所以說相當於我們沒有對通道2傳遞進來的資料做任何處理,直接發送到下一個環節。

 

觀察Fragment Shader,我們增加了20行,注意看這行和Vertex Shader的第7行非常相似,除了第一個關鍵字改成了in。

這種匹配是GLSL的一種固定模式,上遊的out 變數會傳遞給下遊的in變數,只要兩者保持一致性。

在Fragment Shader的main中,我們把最終的顏色輸出改成了 vec4(passingColor,1.0),也就是我們把這個顏色表現了出來。

 

縱觀全域,我們這次做的修改將把verts數組中新增的一些資訊傳遞先傳遞到Vertex Shader中,然後傳遞到FragmentShader中,最終輸出成頂點的顏色。

編譯運行我們看到兩個彩色的三角形:

3D Computer Grapihcs Using OpenGL - 07 Passing Data from Vertex to Fragment Shader

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.