GL02-02:OpenGL球體繪制

球體的渲染效果比較突出爽航,所以本主題完成一個球體的繪制彪见,并利用一些基本的渲染技巧實現(xiàn)渲染。
??1. 球體繪制的數(shù)學(xué)模型嘉竟;
??2. 球體繪制的實現(xiàn);
??3. 球體的渲染的改進效果;


球體繪制的數(shù)學(xué)模型

球體繪制的數(shù)學(xué)模型
  1. 第一步:計算z坐標(biāo)

    • 球面繪制舍扰,首先按z方向倦蚪,切分成多節(jié),每節(jié)就是一個圓周边苹;就是上圖的1截出來的部分就是2所示的圓周陵且。
    • 截出的圓周有一個高,就是z-坐標(biāo)个束;
    • 圓周的高慕购,其實就是這個圓周與圓心形成的錐形的角度決定了圓周的截斷高度。這樣可以輕松計算出z = cos u
  2. 第二步:等高截的圓周的半徑r

    • 這個圓周半徑也容易計算r= sin u
  3. 第三步:計算圓周上的x茬底,y

    • 圓周半徑確定的情況下沪悲,x,y容易計算
      • x = sin u \cdot cos v
      • y = sin u \cdot sin v

代碼實現(xiàn)

線計算u桩警,v確定下的球面點坐標(biāo)

  • 代碼中添加了一個球面總得半徑可训,這個半徑不影響上面的球面坐標(biāo)的計算原理,但決定了球的大小捶枢。
glm::vec3  getPoint(GLfloat u, GLfloat v){
    GLfloat r = 0.9f;
    GLfloat pi = glm::pi<GLfloat>();
    GLfloat z = r * std::cos(pi * u);
    GLfloat x = r * std::sin(pi * u) * std::cos(2 * pi * v);
    GLfloat y = r * std::sin(pi * u) * std::sin(2 * pi * v);
    // std::cout << x << "," << y << "," << z << std::endl;
    return glm::vec3(x, y, z); 
}

循環(huán)u握截,v計算球面上的多個點

  • 注意:
    • u的取值區(qū)間[0,180],v的取值區(qū)間[0,360]烂叔。
    • 計算的4個點谨胞,形成兩個三角形的6個點。
    • 我們假設(shè)u蒜鸡,v是[0, 1]胯努,然后轉(zhuǎn)換為[0, 180][0, 360]
    • 計算出來的點放入數(shù)組(其中內(nèi)存拷貝的時候逢防,內(nèi)存地址的偏移基本單位與指針類型有關(guān))
void createSphere(GLfloat *sphere, GLuint Longitude, GLuint Latitude){
    // Longitude:經(jīng)線切分個數(shù)
    // Latitude:緯線切分個數(shù)
    GLfloat lon_step = 1.0f/Longitude;
    GLfloat lat_step = 1.0f/Latitude;
    GLuint offset = 0;
    for(int lat = 0; lat < Latitude; lat++){  // 緯線u
        for(int lon = 0;lon < Longitude; lon++){ // 經(jīng)線v
            // 一次構(gòu)造4個點叶沛,兩個三角形,
            glm::vec3 point1 = getPoint(lat * lat_step, lon * lon_step);
            glm::vec3 point2 = getPoint((lat + 1) * lat_step, lon * lon_step);
            glm::vec3 point3 = getPoint((lat + 1) * lat_step, (lon + 1) * lon_step);
            glm::vec3 point4 = getPoint(lat * lat_step, (lon + 1) * lon_step);
            memcpy(sphere + offset, glm::value_ptr(point1), 3 * sizeof(GLfloat));
            offset += 3;
            memcpy(sphere + offset, glm::value_ptr(point4), 3 * sizeof(GLfloat));
            offset += 3;
            memcpy(sphere + offset, glm::value_ptr(point3), 3 * sizeof(GLfloat));
            offset += 3;

            memcpy(sphere + offset, glm::value_ptr(point1), 3 * sizeof(GLfloat));
            offset += 3;
            memcpy(sphere + offset, glm::value_ptr(point3), 3 * sizeof(GLfloat));
            offset += 3;
            memcpy(sphere + offset, glm::value_ptr(point2), 3 * sizeof(GLfloat));
            offset += 3;
        } 
    }
    // std::cout<<"offset:" << offset << std::endl;
}

調(diào)用代碼

  • 其中z等分忘朝,這里定義為:
    • GLuint lats = 30;
  • 每個圓周上的點的個數(shù)定義為:
    • GLuint lons = 60;
    GLfloat vertices[6 * 3 * lats * lons ]; 
    std::cout<< "total:" << sizeof(vertices) << std::endl;
    createSphere(vertices, lons, lats);
    data.addData(vertices, sizeof(vertices), 0, 3);     // 開啟Shader第一個參數(shù)位置灰署,頂點3個一組。
  • 頂點著色器是缺省的
    • 其中添加了簡單的世界坐標(biāo)變換mode局嘁,照相機坐標(biāo)view溉箕,與透視變換perspective。
#version 410 core
layout (location = 0) in vec3 aPos;

uniform mat4 model;
uniform mat4 view;
uniform mat4 perspective;

void main(){

    gl_Position = perspective * view * model * vec4(aPos, 1.0);
}

  • 片著色器是缺省的
#version 410 core
out vec4 FragColor;

void main(){
    FragColor =  vec4(1.0f, 0.0f, 0.0f, 1.0f);
}

  • 效果- 繪制方式:glDrawArrays(GL_LINE_LOOP, 0, 6 * lats * lons);
    球體的網(wǎng)格線繪制
  • 效果-繪制方式:glDrawArrays(GL_POINTS, 0, 6 * lats * lons);
    球體的網(wǎng)格點繪制
  • 效果-繪制方式:glDrawArrays(GL_TRIANGLES, 0, 6 * lats * lons);
    球體的三角面繪制

改進與變化

顏色

  • 使用球面坐標(biāo)作為顏色
    GLfloat vertices[6 * 3 * lats * lons ]; 
    std::cout<< "total:" << sizeof(vertices) << std::endl;
    createSphere(vertices, lons, lats);
    data.addData(vertices, sizeof(vertices), 0, 3);     // 開啟Shader第一個參數(shù)位置悦昵,頂點3個一組蒿赢。
    // 直接使用切面坐標(biāo)做顏色坐標(biāo)
    data.addData(vertices, sizeof(vertices), 1, 3);     // 開啟Shader第一個參數(shù)位置互捌,頂點3個一組。
  • 效果:代碼中做了一個Model的縮小矩陣變換model = glm::scale(model, glm::vec3(0.5f, 0.5f, 0.5f));
球體的顏色渲染

紋理

  1. 頂點著色器
#version 410 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
uniform mat4 model;
uniform mat4 view;
uniform mat4 perspective;
out vec4 vColor;
void main(){
    vColor = vec4(aColor, 1.0f);
    gl_Position = perspective * view * model * vec4(aPos, 1.0);
}

  1. 片著色器
#version 410 core
uniform sampler2D aTexture;
out vec4 FragColor;
in vec4 vColor;
void main(){
    // FragColor = vColor;
    vec2 vTexture = vec2(vColor.x, vColor.y);  // 因為x,y有正負(fù),這個這里不處理,就形成對稱紋理效果
    FragColor = texture(aTexture, vTexture) * vColor;
}

  1. 紋理添加代碼
   ///////////////////////////////////////////////////
    // 添加紋理對象
    GLint w = 0, h = 0, d = 0;
    data.addTexture("texture.png",&w, &h, &d);
    ///////////////////////////////////////////////////
    shader.initProgram();
    shader.compileShaderFromFile("./glsl_script/glsl04_v_sphere_texture.glsl", GL_VERTEX_SHADER);
    shader.compileShaderFromFile("./glsl_script/glsl04_f_sphere_texture.glsl", GL_FRAGMENT_SHADER);
    shader.link();
    shader.setUniform_1i("aTexture",0);
  1. 效果


    球體的紋理渲染

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子谓谦,更是在濱河造成了極大的恐慌,老刑警劉巖贪婉,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件反粥,死亡現(xiàn)場離奇詭異,居然都是意外死亡疲迂,警方通過查閱死者的電腦和手機才顿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來尤蒿,“玉大人郑气,你說我怎么就攤上這事⊙兀” “怎么了尾组?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長示弓。 經(jīng)常有香客問我讳侨,道長,這世上最難降的妖魔是什么奏属? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任跨跨,我火速辦了婚禮,結(jié)果婚禮上囱皿,老公的妹妹穿的比我還像新娘勇婴。我一直安慰自己,他們只是感情好嘱腥,可當(dāng)我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布耕渴。 她就那樣靜靜地躺著,像睡著了一般齿兔。 火紅的嫁衣襯著肌膚如雪萨螺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天愧驱,我揣著相機與錄音,去河邊找鬼椭盏。 笑死组砚,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的掏颊。 我是一名探鬼主播糟红,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼艾帐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了盆偿?” 一聲冷哼從身側(cè)響起柒爸,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎事扭,沒想到半個月后捎稚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡求橄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年今野,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罐农。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡条霜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涵亏,到底是詐尸還是另有隱情宰睡,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布气筋,位于F島的核電站拆内,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏裆悄。R本人自食惡果不足惜矛纹,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望光稼。 院中可真熱鬧或南,春花似錦、人聲如沸艾君。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冰垄。三九已至蹬癌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間虹茶,已是汗流浹背逝薪。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蝴罪,地道東北人董济。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像要门,于是被迫代替她去往敵國和親虏肾。 傳聞我的和親對象是個殘疾皇子廓啊,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容