OpenGL(七) OpenGL綜合學(xué)習(xí)——大球沿盅、小球公轉(zhuǎn)自轉(zhuǎn)

我們先來看看具體效果


運(yùn)行效果

setupRC函數(shù)

該函數(shù)主要是數(shù)據(jù)初始化,包括頂點(diǎn)纫溃、紋理等腰涧。

// 初始化
glClearColor(0.0, 0.0, 0.0, 1.0);
shaderManager.InitializeStockShaders();

// 開啟深度測(cè)試
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);

// 大球數(shù)據(jù)
gltMakeSphere(toursBatch, 0.4, 40, 80);
// 小球數(shù)據(jù)
gltMakeSphere(sphereBatch, 0.1, 26, 13);


//6.設(shè)置地板頂點(diǎn)數(shù)據(jù)&地板紋理(4個(gè)頂點(diǎn))
GLfloat texSize = 10.0f;
floorBatch.Begin(GL_TRIANGLE_FAN, 4, 1);
floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
floorBatch.Vertex3f(-20.f, -0.41f, 20.0f);

floorBatch.MultiTexCoord2f(0, texSize, 0.0f);
floorBatch.Vertex3f(20.0f, -0.41f, 20.f);

floorBatch.MultiTexCoord2f(0, texSize, texSize);
floorBatch.Vertex3f(20.0f, -0.41f, -20.0f);

floorBatch.MultiTexCoord2f(0, 0.0f, texSize);
floorBatch.Vertex3f(-20.0f, -0.41f, -20.0f);
floorBatch.End();


//6. 隨機(jī)位置放置小球球
for (int i = 0; i < NUM_SPHERES; i++) {
    
    //y軸不變,X,Z產(chǎn)生隨機(jī)值
    GLfloat x = ((GLfloat)((rand() % 400) - 200 ) * 0.1f);
    GLfloat z = ((GLfloat)((rand() % 400) - 200 ) * 0.1f);
    
    //在y方向紊浩,將球體設(shè)置為0.0的位置窖铡,這使得它們看起來是飄浮在眼睛的高度
    //對(duì)spheres數(shù)組中的每一個(gè)頂點(diǎn),設(shè)置頂點(diǎn)數(shù)據(jù)
    spheres[i].SetOrigin(x, 0.0f, z);
}


// 分配紋理對(duì)象
glGenTextures(3, uiTextures);

// 綁定紋理
glBindTexture(GL_TEXTURE_2D, uiTextures[0]);
loadTGATexture("Marble.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT); // 加載紋理
//
glBindTexture(GL_TEXTURE_2D, uiTextures[1]);
loadTGATexture("marslike.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE);

glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
loadTGATexture("moonLike.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE);

由于使用了3種紋理坊谁,因此傳入的紋理個(gè)數(shù)為3费彼,并傳入紋理數(shù)組

glGenTextures(3, uiTextures);

loadTGATexture函數(shù)

主要是將TGA文件從內(nèi)存中讀取出來,加載為2D紋理數(shù)據(jù)口芍。

大致步驟:

  • 讀取紋理 -- gltReadTGABits
  • 設(shè)置紋理參數(shù)(S和T的環(huán)繞模式箍铲、放大/縮小的過濾方式) -- glTexParameteri
  • 載入紋理 -- glTexImage2D
  • 釋放
  • 加載Mip
// 讀取TGA紋理數(shù)據(jù)
bool loadTGATexture(const char *fileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode) {
    GLbyte *pBits;
    int nWidth;
    int nHeight;
    int nComponents;
    GLenum eFormat;
    
    // 讀取紋理數(shù)據(jù)
    pBits = gltReadTGABits(fileName, &nWidth, &nHeight, &nComponents, &eFormat);
    if (pBits == NULL) {
        return false;
    }
    
    // 設(shè)置紋理參數(shù)
    // 參數(shù)1:紋理維度
    // 參數(shù)2:為S/T坐標(biāo)設(shè)置模式
    // 參數(shù)3:環(huán)繞模式
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
    
    // 參數(shù)1:紋理維度
    // 參數(shù)2:線性過濾
    // 參數(shù)3:環(huán)繞模式
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
    
    
    // 載入紋理
    glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB, nWidth, nHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBits);
    
    // 釋放
    free(pBits);
    
    
    //
    if (minFilter == GL_LINEAR_MIPMAP_LINEAR ||
        minFilter == GL_LINEAR_MIPMAP_NEAREST ||
        minFilter == GL_NEAREST_MIPMAP_LINEAR ||
        minFilter == GL_NEAREST_MIPMAP_NEAREST) {
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    
    return true;
}

renderScene函數(shù)

主要是做繪制的工作。

流程如下:

image.png

// 繪制
void renderScene() {
    
    static CStopWatch rotTimer;
    float yRot = rotTimer.GetElapsedSeconds() * 60.0;
    
    // 清除顏色緩沖區(qū)和深度緩沖區(qū)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    // 壓棧
    modelViewMatrix.PushMatrix();
    
    
    // 觀察者
    M3DMatrix44f mCamera;
    cameraFrame.GetCameraMatrix(mCamera);
    modelViewMatrix.MultMatrix(mCamera);
    
    
    
    // 綁定地面紋理
    glBindTexture(GL_TEXTURE_2D, uiTextures[0]);
    
    
    
    // 畫地板
    shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE, transformPipeline.GetModelViewProjectionMatrix(), vFloorColor, 0);
    floorBatch.Draw();
    
    
    drawSomething(yRot);
    
    modelViewMatrix.PopMatrix(); // 出棧
    
    
    
    glutSwapBuffers();
    glutPostRedisplay();
}

drawSomething函數(shù)

主要是對(duì)大球鬓椭,小球繪制的封裝虹钮。

包含以下4部分操作:

  • 初始化:光源位置和漫反射顏色
  • 繪制多個(gè)靜態(tài)小球
  • 繪制大球
  • 繪制公轉(zhuǎn)小球
void drawSomething(GLfloat yRot) {
    //1.定義光源位置&漫反射顏色
    static GLfloat vWhite[] = { 1.0f, 1.0f, 1.0f, 1.0f};
    static GLfloat vLightPos[] = { 0.0f, 3.0f, 0.0f, 1.0f};
    
    // 繪制懸浮小球
    glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
    for(int i = 0; i < NUM_SPHERES; i++) {
        modelViewMatrix.PushMatrix();
        modelViewMatrix.MultMatrix(spheres[i]);
        shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
                                     modelViewMatrix.GetMatrix(),
                                     transformPipeline.GetProjectionMatrix(),
                                     vLightPos,
                                     vWhite,
                                     0);
        sphereBatch.Draw();
        modelViewMatrix.PopMatrix();
    }
    
    // 繪制大球
    modelViewMatrix.Translate(0.0f, 0.2f, -2.5f);
    modelViewMatrix.PushMatrix();
    modelViewMatrix.Rotate(yRot, 0.0f, 1.0f, 0.0f);
    glBindTexture(GL_TEXTURE_2D, uiTextures[1]);
    shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
                                 modelViewMatrix.GetMatrix(),
                                 transformPipeline.GetProjectionMatrix(),
                                 vLightPos,
                                 vWhite,
                                 0);
    toursBatch.Draw();
    modelViewMatrix.PopMatrix();
    
    // 繪制公轉(zhuǎn)小球(公轉(zhuǎn)自轉(zhuǎn))
    modelViewMatrix.PushMatrix();
    modelViewMatrix.Rotate(yRot * -2.0f, 0.0f, 1.0f, 0.0f);
    modelViewMatrix.Translate(0.8f, 0.0f, 0.0f);
    glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
    shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
                                 modelViewMatrix.GetMatrix(),
                                 transformPipeline.GetProjectionMatrix(),
                                 vLightPos,
                                 vWhite,
                                 0);
    sphereBatch.Draw();
    modelViewMatrix.PopMatrix();
}

Demo

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末聋庵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子芙粱,更是在濱河造成了極大的恐慌,老刑警劉巖氧映,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件春畔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡岛都,警方通過查閱死者的電腦和手機(jī)律姨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來臼疫,“玉大人择份,你說我怎么就攤上這事√痰蹋” “怎么了荣赶?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)鸽斟。 經(jīng)常有香客問我拔创,道長(zhǎng),這世上最難降的妖魔是什么富蓄? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任剩燥,我火速辦了婚禮,結(jié)果婚禮上立倍,老公的妹妹穿的比我還像新娘灭红。我一直安慰自己,他們只是感情好口注,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布变擒。 她就那樣靜靜地躺著,像睡著了一般疆导。 火紅的嫁衣襯著肌膚如雪赁项。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天澈段,我揣著相機(jī)與錄音悠菜,去河邊找鬼。 笑死败富,一個(gè)胖子當(dāng)著我的面吹牛悔醋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播兽叮,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼芬骄,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼猾愿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起账阻,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤蒂秘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后淘太,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姻僧,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年蒲牧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了撇贺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡冰抢,死狀恐怖松嘶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情挎扰,我是刑警寧澤翠订,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站鼓鲁,受9級(jí)特大地震影響蕴轨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜骇吭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一橙弱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧燥狰,春花似錦棘脐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至目代,卻和暖如春屈梁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背榛了。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工在讶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人霜大。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓构哺,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親战坤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子曙强,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355