好嘞,這一次是乙個不錯的突破。前幾次的文章中已經將點雲用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供圖 如果說原來有一千家山寨機,現在應該只有不到兩百家,再過一兩年,至少再去個零。作為金立手機創始人兼董事長,劉立榮同時也是深圳手機行業協會會長,長期扎根於深圳這片全球手機產業的熱土。在他看來,山寨機的路將越走越窄。事實上,隨著手機成本不斷下降,山寨機賴以生存的功能機市場進一步萎縮。同時,今年...