QT Opengl ES2 0顯示立方體

2021-08-09 13:45:10 字數 3757 閱讀 8856

好嘞,這一次是乙個不錯的突破。前幾次的文章中已經將點雲用qt結合opengl顯示出來了,但是所用的opengl為固定管線繪製方式。這種方式效率低下,比方說你有一塊100w的點雲,那麼每次paint的時候都要迴圈繪製100w個點在螢幕上,這也就是為什麼傳統opengl顯示800w的點雲就開始卡b了。

筆者寄希望於qt中的opengles2.0,這種採用頂點快取和索引快取的繪製方式大大提公升了效率。

無奈的是,opengles2.0的繪製管線本來就十分複雜,再加上qt這個虛架子,網上的例子少而又少,導致很多人望而卻步。

筆者研究了qt creator自帶的所有的opengl例程,這些例程無一例外地使用了opengles2.0的可程式設計管線,但是卻沒有乙個例子符合我的要求,它們全部都進行了紋理載入和顯示,因此著色器也顯得相當複雜,而在這之前作者一點著色器的程式設計經驗也沒有。我們知道繪製點雲是不需要紋理座標的,那麼就有必要官方例子進行改進。

筆者這才決定,先把官方的紋理立方體修改為彩色立方體,然後再從彩色立方體過渡到點雲。實際上修改為彩色立方體之後,再修改為顯示點雲已經是小菜一碟了。

但這時我發現噩夢才剛剛開始。我必須先須學習glsl語言,然後重新定義頂點快取和索引快取進行繪製,只要有微小的錯誤都有可能導致錯誤的結果。

為了這點事情,作者不得不每天下班坐乙個多小時的車回寢室然後開始研究。本人查遍了網上幾乎所有相關博文,但是一篇能用的都沒有。作者在這一點上是很失望的。

還好本人有著打不死的小強精神,經過線索的拼湊,這一問題終於在第四個夜晚——今天告破了。

qt+opengl es 2.0的彩色立方體終於被本人無情地顯示出來了。同時也感嘆求學不易,少年仍需努力。

下面我就把**全部分享出來,打上必要的注釋。

老規矩,我們先上效果。

這個gif是不是顯示有點問題啊。。。不過不管了。關鍵的地方我用紅色標註了。

上**。

首先是乙個點雲發動機,我們在這裡面進行索引和快取的定義,它繼承自qopenglfunctions

class qscarlet_glcloudengin_es2 : protected qopenglfunctions

;

它的cpp對應如下:

qscarlet_glcloudengin_es2::qscarlet_glcloudengin_es2()

: indexbuf(qopenglbuffer::indexbuffer)

qscarlet_glcloudengin_es2::~qscarlet_glcloudengin_es2()

void qscarlet_glcloudengin_es2::initcubegeometry()

, // v0

, // v1

, // v2

, // v3

// vertex data for face 1

, // v4

, // v5

, // v6

, // v7

};//它們的索引快取。

glushort indices = ;

// transfer vertex data to vbo 0

arraybuf.bind();

arraybuf.allocate(vertices, 8 * sizeof(cubevertexdata));//這裡放置頂點快取的個數,立方體一共有八個頂點,而不是六個。。。

// transfer index data to vbo 1

indexbuf.bind();

indexbuf.allocate(indices, 36 * sizeof(glushort));//麵片有3*2*6一共36個頂點。}

void qscarlet_glcloudengin_es2::drawcubegeometry(qopenglshaderprogram *program)

然後是乙個用於顯示和控制旋轉縮放的wildget,這個借鑑了官方例子的相機,因為我覺得它的控制做得滿足我的要求。

class qscarlet_glwidget_es2 : public qopenglwidget, protected qopenglfunctions

;

它的cpp檔案對應如下: 

qscarlet_glwidget_es2::qscarlet_glwidget_es2(qwidget *parent) :

qopenglwidget(parent),

geometries(0),

texture(0),

angularspeed(0)

qscarlet_glwidget_es2::~qscarlet_glwidget_es2()

void qscarlet_glwidget_es2::mousepressevent(qmouseevent *e)

void qscarlet_glwidget_es2::mousemoveevent(qmouseevent *e)

void qscarlet_glwidget_es2::mousereleaseevent(qmouseevent *e)

void qscarlet_glwidget_es2::timerevent(qtimerevent *)

else

update();

}void qscarlet_glwidget_es2::initializegl()

void qscarlet_glwidget_es2::initshaders()//載入shader,這裡必須注意,新加入glsl檔案後必須把qtcreator生成的release資料夾刪掉然後重新編譯一下才會識別,作者為這個問題活活憋了乙個晚上才知道,原來這是qt的bug。馬丹。。。。

void qscarlet_glwidget_es2::inittextures()

void qscarlet_glwidget_es2::resizegl(int w, int h)

void qscarlet_glwidget_es2::paintgl()

void qscarlet_glwidget_es2::wheelevent(qwheelevent *e)

最後把兩個最關鍵的shader放上來:

頂點著色器:

#ifdef gl_es

precision mediump int;

precision mediump float;

#endif

uniform mat4 mvp_matrix;

attribute vec4 a_position; //解釋一下,attribute代表這是乙個可由外部傳入的變數

attribute lowp vec4 colattr;

varying lowp vec4 col;//varying代表opengl的傳出變數,這個變數會由頂點著色器傳出,然後傳入畫素著色器。

void main()

然後下面是畫素著色器。簡單一句話就沒了,但是記住這個傳出的col的名字一定要和上面相同才行。

#ifdef gl_es

precision mediump int;

precision mediump float;

#endif

varying lowp vec4 col;

void main()

//至此所有**完畢。

探路者 第四周立會報告1(總第20次)

探路者 組成員及各位部落格位址。1藺依銘 2張恩聚 3公尺赫 4徐劭斌 5賈雅傑 6吳雨丹 7代秋彤 本次會議master 藺依銘 要求1工作 要求2時間跨度 2017年11月09日17 01分 當日17 35分。共計34分。要求3地點 計算機樓一層階梯教室 要求4立會內容 昨天的成績 1.無會議完...

6 3 分詞並顯示 20 分 pta

程式的功能是 呼叫input函式讀入乙個長度不超過81的字串,字串中只含字母和空格,遇到讀滿或者回車結束讀入字元,空格用於分隔單詞。請將字串中用空格分隔的單詞在螢幕上輸出來。要求用指標完成函式中各引數的傳遞與訪問,自定義函式頭和函式體中不得出現陣列下標形式的表示法。void input char s...

金立手機創始人 山寨手機商兩年後或只剩20家

cfp供圖 如果說原來有一千家山寨機,現在應該只有不到兩百家,再過一兩年,至少再去個零。作為金立手機創始人兼董事長,劉立榮同時也是深圳手機行業協會會長,長期扎根於深圳這片全球手機產業的熱土。在他看來,山寨機的路將越走越窄。事實上,隨著手機成本不斷下降,山寨機賴以生存的功能機市場進一步萎縮。同時,今年...