跳轉到內容

遊戲開發/渲染與遊戲引擎/OpenGL/繪製幾何體

50% developed
來自華夏公益教科書,自由的教科書

繪製顏色的幾何體

[編輯 | 編輯原始碼]

這是將三角形的頂點資料傳遞給 OpenGL 的方法。

資料在一個數組中指定,每三個頂點表示一個新的三角形。在此格式中,需要按照連線的順序指定資料。

#include <gl\glew.h>
#include <MyGLWindow.h>

void MyGLWindow::initializeGL(){
	GLfloat verts[] =
	{
                //1st Triangle
		+0.0f, +1.0f, +0.0f, //Vertex 1
		-1.0f, -1.0f, -0.5f, //Vertex 2
		+1.0f, -1.0f, +0.5f, //Vertex 3
                //2nd Triangle
		+0.0f, -1.0f, +0.0f, //Vertex 1
		-1.0f, +1.0f, -0.5f, //Vertex 2
		+1.0f, +1.0f, +0.5f, //Vertex 3
	};
	GLuint myBufferID;
	glGenBuffers(1, &myBufferID); //Generate an identifier for the buffer ID
	glBindBuffer(GL_ARRAY_BUFFER, myBufferID); //Bind it to the array buffer binding point
	glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); //Send the size of the data and the data to the buffer assigned to the array buffer binding point.

	//Describing the data
	glEnableVertexAttribArray(0); //The first attribute to send to openGL (later redirected through a vertex shader)
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0,0); //There are 3 floats per vertex...
}

void MyGLWindow::paintGL(){
	glViewport(0, 0, width(), height()); //Fixes the resizing to change ratio of triangle
	glDrawArrays(GL_TRIANGLES, 0, 6); //Connect the 6 vertices into triangles (triangle=3, 6/3 = 2 triangles)
}

這段程式碼很容易修改為只傳遞 2D 資料,為此你需要更改兩件事。

  • 陣列應該只包含 X 和 Y 座標。
  • glVertexAttribPointer 引數 2 需要從 3 更改為 2。

幾何體的最佳化繪製

[編輯 | 編輯原始碼]

此程式的新版本傳遞頂點位置的 ID,以說明如何連線三角形。對於沒有連線的基本三角形,這比之前效率低,但是對於大多數形狀,三角形將共享頂點,這意味著你不需要指定 3 個數據(XYZ,如果新增顏色和光照法線則更多),只需要傳遞一個額外的短整型作為頂點索引。這樣可以節省記憶體,因為需要更少的資料,並且對於動畫幾何體,這意味著需要傳送到 OpenGL 及更遠端的資料副本更少。

#include <gl\glew.h>
#include <MyGLWindow.h>

void MyGLWindow::initializeGL(){
	GLfloat verts[] =
	{
                //1st Triangle
		+0.0f, +1.0f, +0.0f, //Vertex 1
		-1.0f, -1.0f, -0.5f, //Vertex 2
		+1.0f, -1.0f, +0.5f, //Vertex 3
                //2nd Triangle
		+0.0f, -1.0f, +0.0f, //Vertex 1
		-1.0f, +1.0f, -0.5f, //Vertex 2
		+1.0f, +1.0f, +0.5f, //Vertex 3
	};
	GLuint myBufferID;
	glGenBuffers(1, &myBufferID); //Num buffers, BufferID
	glBindBuffer(GL_ARRAY_BUFFER, myBufferID);
	glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);

        //Assigning the positions of the vertices into 2 triangle (triangle 1= {0,1,2}, triangle 2={3,4,5})
        GLushort indices[] = {0,1,2,  3,4,5};
	GLuint indexBufferID;
	glGenBuffers(1, &indexBufferID); //Generate an identifier for the index buffer ID
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID); //Link the index buffer to the element array buffer binding point
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); //Send the size of the data and the data to the index buffer, linked to the element array buffer binding point.

	//Describing the data
	glEnableVertexAttribArray(0); //The first attribute
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0,0); A vertex consists of 3 floats
}

void MyGLWindow::paintGL(){
	glViewport(0, 0, width(), height()); //Fixes the resizing to change ratio of triangle
	glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0); //Notice this is different from above
}

繪製顏色的幾何體(保留之前的最佳化)

[編輯 | 編輯原始碼]

注意:在設定片段著色器之前,顏色不會生效。但是,要設定片段著色器,你需要從頂點著色器傳送顏色資料。

#include <gl\glew.h>
#include <MyGLWindow.h>

void MyGLWindow::initializeGL(){
	GLfloat verts[] =
	{
                //One colourful triangle being drawn
		+0.0f, +1.0f, +0.0f, //Vertex 1
                +1.0f, +0.0f, +0.0f, //Vertex 1's Color (Red)

		-1.0f, -1.0f, -0.5f, //Vertex 2
                +0.0f, +1.0f, +0.0f, //Vertex 2's Color (Green)

		+1.0f, -1.0f, +0.5f, //Vertex 3
                +0.0f, +0.0f, +1.0f, //Vertex 3's Color (Blue)
	};
	GLuint myBufferID;
	glGenBuffers(1, &myBufferID); //Num buffers, BufferID
	glBindBuffer(GL_ARRAY_BUFFER, myBufferID);
	glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);

        GLushort indices[] = {0,1,2};
	GLuint indexBufferID;
	glGenBuffers(1, &indexBufferID);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

	//Describing the data
	glEnableVertexAttribArray(0); //The first attribute (Vertex data)
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) *6,0); //There are 6 floats worth of data from the start of one list of vertices and the next set of vertices
	glEnableVertexAttribArray(1); //The second attribute (Color data)
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) *6, (char*)(sizeof(float)*3)); //There are 6 floats worth of data from the start of one list of vertices and the next set of vertices. The first piece of data starts after 3 floats.
}

void MyGLWindow::paintGL(){
	glViewport(0, 0, width(), height()); //Fixes the resizing to change ratio of triangle
	glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0);
}

參考文獻

[編輯 | 編輯原始碼]
華夏公益教科書