OpenGL實例教程02:使用GLEW繪制點
什么是GLEW?
GLEW(OpenGL Extension Wrangler Library)是一個跨平臺的開源C/C++擴展加載庫。GLEW提供了高效的運行時機制,用于確定目標平臺支持哪些OpenGL擴展。OpenGL核心和擴展功能聲明在同一個頭文件中。GLEW已經(jīng)在多種操作系統(tǒng)上進行了測試,包括Windows、Linux、Mac OS X、FreeBSD、Irix和Solaris。
簡單來說,GLEW就是在運行時(動態(tài)的),幫助我們將頭文件中聲明的函數(shù)指針,綁定到顯卡驅(qū)動上的具體內(nèi)存地址,也就時具體的opengl函數(shù)實現(xiàn)。
和glad有什么不同?
本教程采用freegult、glew分別實現(xiàn)窗口和繪制,另一套教程我們采用的是glfw和glad。使用起來大同小異。不必糾結(jié)這些細節(jié),在QT中編寫OpenGL我們甚至不需要使用這些,對我們來說都是透明的。庫的選擇和使用本來就是為了讓我們更專心于實際業(yè)務,還是集中精力在OpenGL本身上。
GLEW編譯
可以下載源碼進行編譯,或是直接下載編譯好的運行庫(windows)。
更過詳細介紹可以參閱官網(wǎng):https://glew.sourceforge.net/
代碼展示:
前面我們已經(jīng)使用freegult創(chuàng)建了支持OpenGL的窗口,有了GLEW的幫助我們就可以很方便的使用OpenGL函數(shù)在窗口上進行繪制了。
#include <stdio.h>//C風格的打印
#include "../include/glew-2.1.0/glew.h"//為了初始化OpenGL核心庫和擴展庫函數(shù)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //必須加載到其他OpenGL頭文件的上面
#include "../include/freeglut3.4/freeglut.h"
#include "../include/ogldev_math_3d.h"//數(shù)學庫
GLuint VBO;//unsigned int;句柄; vertex buffer object(頂點緩沖對象)
? ? ? ? ? //VBO是將頂點加載到GPU最有效的方法。
static void RenderSceneCB()
{
? ?glClear(GL_COLOR_BUFFER_BIT);
? ?
? ?glEnableVertexAttribArray(0); //激活索引0表示的頂點屬性,默認開啟
? ?glBindBuffer(GL_ARRAY_BUFFER, VBO);//再次綁定,在本例中多余,但是個好習慣
? ?/*這個調(diào)用告訴管道如何解釋緩沖區(qū)內(nèi)的數(shù)據(jù)。
? ?參數(shù)1:指定頂點屬性的索引。
? ?參數(shù)2:屬性中的元素的數(shù)量(X、Y和Z)。
? ?參數(shù)3:屬性中的元素的類型
? ?參數(shù)4:是否需要標準化(映射到-1到1之間)
? ?參數(shù)5:屬性之間的步長,目前只有一種屬性且連續(xù)存放所以可以用0表示
? ?參數(shù)6:屬性的偏移量(第幾個屬性,從0開始),目前只有一種屬性所以為0*/
? ?glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0/*sizeof(int)*3*/, 0);
? ?glDrawArrays(GL_POINTS, 0, 1);//這就是GPU真正開始工作的地方。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//按照當前的所有狀態(tài),解析參數(shù),并繪制出來
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//glDrawArrays表示按頂點順序繪制
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//本例:從第0個數(shù)據(jù)開始,拿出一個,繪制點形狀
? ?glDrawArrays(GL_POINTS, 1, 1);//從第1個數(shù)據(jù)開始,拿出一個,繪制點形狀
? ?glDisableVertexAttribArray(0);
? ?glutSwapBuffers(); ? ? ? ?
}
static void InitializeGlutCallbacks()
{
? ?glutDisplayFunc(RenderSceneCB);//注冊回調(diào)函數(shù)
}
static void CreateVertexBuffer()//tutorial2新增
{
? ?Vector3f Vertices[2]; //創(chuàng)建一個頂點數(shù)組
? ?Vertices[0] = Vector3f(-0.5f, 0.0f, 0.0f);//也就是在屏幕中間左邊的一個點
? ?Vertices[1] = Vector3f(0.5f, 0.0f, 0.0f); //也就是在屏幕中間右邊的一個點
? ?glGenBuffers(1, &VBO);//創(chuàng)建1個緩沖,使用VBO作為ID(或句柄)
? ? ? ? ? ? ? ? ? ? ? ? ? //注意:這時候我們并沒有明確該緩沖是用來干什么的
? ?glBindBuffer(GL_ARRAY_BUFFER, VBO);//將GL_ARRAY_BUFFER的狀態(tài)綁定到VBO
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //注意:在這里明確了VBO這塊緩沖的用途
? ?/*現(xiàn)在開始填充數(shù)據(jù)
? ? ?參數(shù)1:目標名稱,這里是我們剛剛綁定的目標
? ? ?參數(shù)2:填充的數(shù)據(jù)大?。▎挝唬鹤止?jié))
? ? ?參數(shù)3:數(shù)據(jù)地址
? ? ?參數(shù)4:指示此數(shù)據(jù)的使用模式的標志,GL_STATIC_DRAW表示我們不打算改變緩沖區(qū)內(nèi)容。
? ? ? ? ? ? 驅(qū)動程序可以依據(jù)它進行優(yōu)化(例如內(nèi)存中存儲緩沖區(qū)的最佳位置)。*/
? ?glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
}
int main(int argc, char** argv)
{
? ?glutInit(&argc, argv);
? ?glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
? ?glutInitWindowSize(1024, 768); ? ?
? ?glutInitWindowPosition(100, 100); ?
? ?glutCreateWindow("Tutorial 02"); ? ?
? ?InitializeGlutCallbacks();
? ?glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
? ?GLenum res = glewInit();//初始化GLEW,必須在GLUT初始化之后。
? ?if (res != GLEW_OK) {
? ? ? ?fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
? ? ? ?return 1;
? ?}
? ?CreateVertexBuffer();
? ?glutMainLoop();
? ?return 0;
}
顯示效果:
一共繪制兩個小點,分別是(-0.5,0,0)和(0.5,0,0),默認只是一個像素太?。ㄏ聢D中用紅色圓圈標出),看不大清楚,以后我們將可以在shader中設(shè)置點的大小。

標簽: