opengl 教程 2 在視窗畫點

2021-09-30 10:55:24 字數 3627 閱讀 7864

通常寫opengl程式時候,我們都需要glew庫,該庫包裝了opengl的各種擴充套件,便於我們使用。

我們可以在main函式中呼叫glew初始化函式,之後就可以查詢opengl各種擴充套件能否使用了,對於能夠使用的函式,可以動態的載入。

在這篇教程中,我們首先了解一下頂點緩衝物件(vbo,vertex buffer object)的用法。在計算機圖形學的3d世界中,三維物體物件都是由一系列頂點組成的,比如武士模型、城堡模型等等(注意下面2副圖),這些頂點相連線,組成mesh(三角形)。

顧名思義,頂點緩衝就是儲存頂點的記憶體物件,通常vbo是gpu視訊記憶體中的一塊區域,使用vbo可以加速頂點的讀取速度。

的四邊形對映到螢幕空間),比如螢幕空間是1024*768,則x座標-1,對映到0,+1對映到1023,x和y等於0的點,則被對映到螢幕中心,最終根據draw函式中指定的體元語義,通過光柵化操作,把物體在螢幕空間渲染出來。

下面我們看下程式的部分源**實現:

#include

首先我們要包含glew標頭檔案,注意我們要把這個標頭檔案放在freee_glut.h的前面,否則的話,程式編譯有可能出錯。

#include "math_3d.h"

在這篇教程中,我們畫乙個頂點,頂點結構在math_3d.h中定義。

glenum res = glewinit();

if (res != glew_ok) 

上面是glew初始化的**,如果初始化失敗,則會輸出錯誤資訊,注意:glew初始化**必須在glut初始化之後。

vector3f vertices[1];

vertices[0] = vector3f(0.0f, 0.0f, 0.0f);

我們建立了乙個頂點陣列,該陣列有乙個元素,其座標xyz為0,後面我們將會在螢幕中心顯示這個頂點。

gluint vbo;

我們定義乙個gluint型別的全域性變數vbo來表示頂點緩衝,通常情況下,opengl物件都是用乙個gluint型別的變數表示。

glgenbuffers(1, &vbo);

在opengl中,都是通過glgen*型別的函式產生各種各樣的物件,這類函式有2個引數,第乙個引數指定你要建立物件的數量,第二個引數是乙個gluint型別陣列的位址,該位址中存放著driver分配給你的各種物件控制代碼。driver會保證將來再呼叫該函式不會產生相同的物件控制代碼,除非你呼叫函式gldeletebuffers顯示刪除物件控制代碼。

glbindbuffer(gl_array_buffer, vbo);

在opengl中,通常把乙個物件繫結到乙個target name,比如把vbo物件繫結到gl_array_buffer(表示緩衝是頂點陣列,另乙個常用的target name是gl_element_array_buffer,表示索引陣列),然後在這個target name上執行命令,這些命令將會一直影響繫結的物件,除非我們把該target name繫結到乙個新的物件,此時,在target name上執行命令,將會影響新繫結的物件。

glbufferdata(gl_array_buffer, sizeof(vertices), vertices, gl_static_draw);

繫結物件後,我們開始準備頂點緩衝資料,上面的函式中,我們用vertices中的資料填充頂點緩衝,其中gl_static_draw表示,這些頂點資料渲染過程中不會改變,相對應的是gl_dynamic_draw,driver會根據這些狀態對程式進行一定的優化。

glenablevertexattribarray(0);

在後面的shader程式中,我們將看到更詳細的頂點屬性介紹,在本教程的例子中,我們沒有使用shader,但是我們在頂點緩衝中裝入了頂點位置,位置屬性就作為頂點屬性的index 0(注意:由於沒有shader,我們此時用的是固定管線渲染),所以必須開啟它,否則不能使用,因為所有的頂點屬性在使用前都必須開啟。

glbindbuffer(gl_array_buffer, vbo);

再一次繫結頂點緩衝,當然也可以不繫結,因為我們只有乙個緩衝,前面已經繫結過了,但是在大型3d程式中,可能有很多頂點緩衝,就需要在渲染前,根據實際需要,切換繫結不同的頂點緩衝物件。

glvertexattribpointer(0, 3, gl_float, gl_false, 0, 0);

這個函式告訴管線,怎麼解釋頂點緩衝中的資料。第乙個引數指定屬性的索引,第二個引數是屬性的數量(3,表示,x,y,z),第三個引數是屬性的資料型別,第四個引數是屬性是否是歸一化的,第五個引數是stride,表示屬性的位元組數目, 我們只有乙個屬性,所以該值是0,如果我們有2個屬性,乙個位置,乙個法向,假定它們都是3維float格式的向量,則這個引數要設定為(6*4)=24byte,最後乙個引數offset,如果有2個屬性,那麼對於第乙個屬性,該值為0,沒有偏移,對於第二個屬性為12。

gldrawarrays(gl_points, 0, 1);

最後,我們呼叫draw函式,該函式是gpu開始工作的起始點,gpu將繫結draw函式的引數以及狀態等資料,然後通過driver傳遞到gpu。opengl有幾種形式的draw函式,通常它們可以劃分為ordered draws和indexed draws。ordered draw函式就是把指定的頂點按語義順序畫一遍,比如你指定gl_********s ,則0-2頂點為第乙個三角形,3-5頂點為第二個三角形等等。而index draws要通過索引緩衝來索引頂點資料(實際上,在硬體層次,沒有無索引的draw實現,如果沒有指定索引緩衝,硬體會按照頂點的順序,生成乙個和頂點順序對應的索引),這樣可以重複利用頂點資料,比如我們可以用四個點來表示乙個四邊形(2個三角形組成),其中2個點是2個三角形共享的,索引緩衝中的資料為頂點在頂點緩衝中的位置。

我們呼叫drawarrays函式畫乙個點,第乙個引數指定體元語義,畫的是點,第二個引數是第乙個頂點的索引位置,第三個引數是要渲染的頂點的數量。

gldisablevertexattribarray(0);不使用頂點屬性的時候,記得要關閉它,以免引起未知的一些錯誤。

程式執行後,介面如下,在視窗中心,有乙個小的幾乎看不見的白點。

我們也可以加入下面的**,設定點的大小以及設定點為圓點。

//下面四行**,設定點的大小,以及啟動alpha blend以及多取樣,這樣可以畫圓形的點

opengl 教程 1 建立視窗

本章教程內容主要來自 opengl做為3d圖形介面,本身並不提供任何視窗管理功能,在不同作業系統中,通常都有相關庫做為opengl和os的介面,來實現視窗管理,比如xwindows系統中的glx,windows系統中的wgl,mac os中的cgl等等。在下面的一系列教程中,我們使用glut,這是乙...

opengl教程翻譯 1建立乙個視窗

opengl規範沒有為建立和操作視窗指定任何的api。目前流行的支援opengl的視窗系統,一般包含支援其的子 系統,提供opengl上下文和視窗系統之間的繫結。在x視窗系統中,這樣的介面被稱為glx。微軟為視窗提供 wgl,macos則有cgl。用這些介面無誤地建立乙個顯示圖形的視窗通常是一項繁瑣...

OpenGL基礎教程(2) 著色器

glsl是一種專門為圖形開發的程式語言,但是它與c語言非常類似。1 圖形管線 圖形管線有四個處理階段 頂點著色階段 細分著色階段 可選階段 幾何著色極段 可選階段 片元著色階段 2 gl的型別有 基本型別 float 對應的向量型別 vec2 vec3 vec4 對應的矩陣型別 mat2 mat3 ...