<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 第四課:彩色立方體 歡迎來到第四課!你將學到: - 畫立方體,代替單調的三角形 - 加上絢麗的色彩 - 學習深度緩存(Z-Buffer) ## 畫立方體 立方體有六個方形表面,而OpenGL只支持畫三角形,因此需要畫12個三角形,每面兩個。我們用定義三角形頂點的方式來定義這些頂點。 ~~~ // Our vertices. Tree consecutive floats give a 3D vertex; Three consecutive vertices give a triangle. // A cube has 6 faces with 2 triangles each, so this makes 6*2=12 triangles, and 12*3 vertices static const GLfloat g_vertex_buffer_data[] = { -1.0f,-1.0f,-1.0f, // triangle 1 : begin -1.0f,-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, // triangle 1 : end 1.0f, 1.0f,-1.0f, // triangle 2 : begin -1.0f,-1.0f,-1.0f, -1.0f, 1.0f,-1.0f, // triangle 2 : end 1.0f,-1.0f, 1.0f, -1.0f,-1.0f,-1.0f, 1.0f,-1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f,-1.0f,-1.0f, -1.0f,-1.0f,-1.0f, -1.0f,-1.0f,-1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f,-1.0f, 1.0f,-1.0f, 1.0f, -1.0f,-1.0f, 1.0f, -1.0f,-1.0f,-1.0f, -1.0f, 1.0f, 1.0f, -1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,-1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,-1.0f, -1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f,-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,-1.0f, 1.0f }; ~~~ OpenGL的緩沖區由一些標準的函數(glGenBuffers, glBindBuffer, glBufferData, glVertexAttribPointer)來創建、綁定、填充和配置;這些可參閱第二課。繪制的函數調用也沒變,只需改繪制的點的個數: ~~~ // Draw the triangle ! glDrawArrays(GL_TRIANGLES, 0, 12*3); // 12*3 indices starting at 0 -> 12 triangles -> 6 squares ~~~ 這段代碼,有幾點要解釋: - 現在為止,三維模型都是固定的:要改就要改源碼,重新編譯,然后祈望不會錯。我們將在第七課中學習如何加載動態模型。 - 實際上,每個頂點至少被寫了三次(在以上代碼中搜索“-1.0f,-1.0f,-1.0f”看看)。這是可怕的內存浪費。我們將在第九課中學習怎樣優化。 現在,你有了畫一個白色立方體的所有必備條件。讓著色器運行起來,至少試試吧:) ## 添加顏色 Adding colors 顏色,從概念上說,像極了位置:它就是數據。OpenGL中,它們都是“屬性”。事實上,之前已在glEnableVertexAttribArray()和glVertexAttribPointer()用過屬性設置了。現在我們加上顏色屬性,代碼很相似的。 首先,聲明顏色:每個頂點一個RGB(紅綠藍)三元組。這里用隨機的方式生成的,所以結果可能看起來不那么好;但你可以調整得更好,例如:把頂點的位置作為顏色值。 ~~~ // One color for each vertex. They were generated randomly. static const GLfloat g_color_buffer_data[] = { 0.583f, 0.771f, 0.014f, 0.609f, 0.115f, 0.436f, 0.327f, 0.483f, 0.844f, 0.822f, 0.569f, 0.201f, 0.435f, 0.602f, 0.223f, 0.310f, 0.747f, 0.185f, 0.597f, 0.770f, 0.761f, 0.559f, 0.436f, 0.730f, 0.359f, 0.583f, 0.152f, 0.483f, 0.596f, 0.789f, 0.559f, 0.861f, 0.639f, 0.195f, 0.548f, 0.859f, 0.014f, 0.184f, 0.576f, 0.771f, 0.328f, 0.970f, 0.406f, 0.615f, 0.116f, 0.676f, 0.977f, 0.133f, 0.971f, 0.572f, 0.833f, 0.140f, 0.616f, 0.489f, 0.997f, 0.513f, 0.064f, 0.945f, 0.719f, 0.592f, 0.543f, 0.021f, 0.978f, 0.279f, 0.317f, 0.505f, 0.167f, 0.620f, 0.077f, 0.347f, 0.857f, 0.137f, 0.055f, 0.953f, 0.042f, 0.714f, 0.505f, 0.345f, 0.783f, 0.290f, 0.734f, 0.722f, 0.645f, 0.174f, 0.302f, 0.455f, 0.848f, 0.225f, 0.587f, 0.040f, 0.517f, 0.713f, 0.338f, 0.053f, 0.959f, 0.120f, 0.393f, 0.621f, 0.362f, 0.673f, 0.211f, 0.457f, 0.820f, 0.883f, 0.371f, 0.982f, 0.099f, 0.879f }; ~~~ 緩沖區的創建、綁定和填充方法和之前一樣: ~~~ GLuint colorbuffer; glGenBuffers(1, &colorbuffer); glBindBuffer(GL_ARRAY_BUFFER, colorbuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW); ~~~ 配置也一樣: ~~~ // 2nd attribute buffer : colors glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, colorbuffer); glVertexAttribPointer( 1, // attribute. No particular reason for 1, but must match the layout in the shader. 3, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void*)0 // array buffer offset ); ~~~ 現在,頂點著色器中,我們已能訪問這個額外的緩沖區: ~~~ // Notice that the "1" here equals the "1" in glVertexAttribPointer layout(location = 1) in vec3 vertexColor; ~~~ 本例將不會在頂點著色器里做花哨的玩意,只是簡單地過渡到片斷著色器: ~~~ // Output data ; will be interpolated for each fragment. out vec3 fragmentColor; void main(){ [...] // The color of each vertex will be interpolated // to produce the color of each fragment fragmentColor = vertexColor; } ~~~ 片斷著色器中,要再次聲明片斷顏色: ~~~ // Interpolated values from the vertex shaders in vec3 fragmentColor; ~~~ …然后把它的值賦給輸出顏色: ~~~ // Output color = color specified in the vertex shader, // interpolated between all 3 surrounding vertices color = fragmentColor; ~~~ 于是得到: ![](https://box.kancloud.cn/2015-11-02_5636f303ab2c9.png) 額,好丑。為了搞清楚,我們先看看各畫一個看起來“遠”和“近”的三角形,會發生什么: ![](https://box.kancloud.cn/2015-11-02_5636f303bd5dc.png) 似乎挺好。現在畫“遠”的三角形: ![](https://box.kancloud.cn/2015-11-02_5636f303ce1b6.png) 它遮住了“近”三角形!它本應該畫在“近”三角形后面的!我們的立方體就有這個問題:一些理應被遮擋的面,因為繪制時間晚,實際可見。我們將用深度緩存(Z-Buffer)算法解決它。 *便簽1*: 如果你沒發現問題,把相機放到(4,3,-3)試試 *便簽2*: 如果“類似于位置,顏色是一種屬性”,那為什么顏色要聲明 vec3 fragmentColor,而位置不需要?實際上,位置有點特殊:它是唯一必須賦初值的(否則OpenGL不知道在哪畫三角形)。所以在頂點著色器里, gl_Position是內置變量。 ## 深度緩存(Z-Buffer)The Z-Buffer 該問題的解決方案是:在緩沖區中存儲每個片斷的深度(即“Z”值);而每次畫片斷時,先確保當前片斷確實比先前畫的片斷更近。 你可以自己實現,但讓硬件自己去做更簡單: ~~~ // Enable depth test glEnable(GL_DEPTH_TEST); // Accept fragment if it closer to the camera than the former one glDepthFunc(GL_LESS); ~~~ 這就解決之前所有問題了。 ![](https://box.kancloud.cn/2015-11-02_5636f303dd9ff.png) ## 練習 - 在不同的位置畫立方體和三角形。你需要生成兩個MVP矩陣,在主循環中做兩次繪制調用,但只需一個著色器。 - 自己生成顏色值。一些提示:隨機生成,使每次運行顏色都不同;依據頂點的位置;將前二者結合;或其他的創新想法。若你不了解C,參考以下語法: ~~~ static GLfloat g_color_buffer_data[12*3*3]; for (int v = 0; v < 12*3 ; v++){ g_color_buffer_data[3*v+0] = your red color here; g_color_buffer_data[3*v+1] = your green color here; g_color_buffer_data[3*v+2] = your blue color here; } ~~~ - 完成上面習題后,試令顏色在每幀都改變。你需要在每一幀都調用glBufferData。請確保已先綁定(glBindBuffer)了合適的緩沖區!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看