視頻特效學(xué)習(xí)04-OpenGL基礎(chǔ)變化

學(xué)習(xí)目標(biāo):
    1. 向量、矩陣和基礎(chǔ)變化(了解)
    1. 使用矩陣/向量移動幾何圖形(實(shí)踐)
    1. 矩陣堆棧(理解)

1. 向量與矩陣

  • 向量:向量是研究2D、3D數(shù)學(xué)的標(biāo)準(zhǔn)工具。向量V是一個既有大小又有方向的量(聯(lián)系位移和速度的概念)。在數(shù)學(xué)上,常用一條有方向的線段來表示向量。
  • 理解向量把握:
    • 1.向量的大小就是向量的長度(模)。向量的長度非負(fù)。
    • 2.向量的方向描述了向量的指向。
    • 3.向量是沒有位置的,與點(diǎn)是不同的。
    • 4.向量與標(biāo)量不同,標(biāo)量是只有大小而沒有方向的量,例如位移是向量,而距離是標(biāo)量。
  • OpenGL中向量的使用:
    math3d中,有兩個數(shù)據(jù)類型,能夠表示三維或四維。M3DVector3f可以表示一個三維向量(x,y,z),而M3DVector4f則可以表示一個四維向量(x,y,z,w),w稱為縮放因子。在典型情況下,w坐標(biāo)設(shè)為1.0。x,y,z值通過除以w,來進(jìn)?行縮放。?除以1.0則本質(zhì)上不改變x,y,z值。
//聲明一個三分量頂點(diǎn)數(shù)組,例如生成一個三角形
M3DVector3f vVerts[] = {
    -0.5f,0.0f,0.0f,
    0.5f,0.0f,0.0f,
    0.0f,0.5f,0.0f
};
  • 向量點(diǎn)乘和叉乘
    • 點(diǎn)乘
    //實(shí)現(xiàn)點(diǎn)乘方法:
    //?法1:返回的是-1,1之間的值。它代表這2個向量的余弦值。
    float m3dDotProduct3(const M3DVector3f u,const M3DVector3f v);
    //?法2:返回2個向量之間的弧度值。
    float m3dGetAngleBetweenVector3(const M3DVector3f u,const M3DVector3f v);
    
    • 叉乘
    //result 為法向量
    void m3dCrossProduct3(M3DVector3f result,const M3DVector3f u ,const M3DVector3f v);
    
  • 矩陣:從形式上就是一個數(shù)字表,以行和列的形式呈現(xiàn),簡單的矩陣如下圖所示:


    矩陣.png
    • 定義矩陣
    //定義4*4矩陣
    M3DMatrix44f mCamera;
    
  • OpenGL中的基礎(chǔ)變化:


    OpenGL變換術(shù)語概況.png

2. 使用矩陣/向量移動幾何圖形

  • 核心:
    • 平移之后的坐標(biāo),該函數(shù)主動賦值到參數(shù)1中
       //參數(shù)1:平移之后的坐標(biāo),該函數(shù)主動賦值到參數(shù)1中
       //參數(shù)2:平移的x
       //參數(shù)3:平移的y
       //參數(shù)4:平移的z
       m3dTranslationMatrix44(translationMatrix, xPos, yPos, 0);
      
    • 旋轉(zhuǎn)換后的坐標(biāo),該函數(shù)主動賦值到參數(shù)1中
      //參數(shù)1:旋轉(zhuǎn)換后的坐標(biāo),該函數(shù)主動賦值到參數(shù)1中
      //參數(shù)2:旋轉(zhuǎn)的角度 需要把弧度轉(zhuǎn)化為角度
      //參數(shù)3/4/5:圍繞哪個軸旋轉(zhuǎn)
      static float yRot = 0.0f;
      yRot += 5.0f;
      m3dRotationMatrix44(rotationMatrix, m3dDegToRad(yRot), 0, 0, 1);
      
    • 把平移和旋轉(zhuǎn)合并(乘)起來
      //把平移和旋轉(zhuǎn)合并(乘)起來
      //參數(shù)1:合并后的坐標(biāo)
      //參數(shù)2/3:需要合并的兩個坐標(biāo)
      m3dMatrixMultiply44(finalTransform, translationMatrix, rotationMatrix);
      
      //召喚場景
      void renderScene(void){
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
        M3DMatrix44f rotationMatrix,translationMatrix,finalTransform;
        //參數(shù)1:平移之后的坐標(biāo),該函數(shù)主動賦值到參數(shù)1中
        //參數(shù)2:平移的x
        //參數(shù)3:平移的y
        //參數(shù)4:平移的z
        m3dTranslationMatrix44(translationMatrix, xPos, yPos, 0);
        //參數(shù)1:旋轉(zhuǎn)換后的坐標(biāo),該函數(shù)主動賦值到參數(shù)1中
        //參數(shù)2:旋轉(zhuǎn)的角度 需要把弧度轉(zhuǎn)化為角度
        //參數(shù)3/4/5:圍繞哪個軸旋轉(zhuǎn)
        static float yRot = 0.0f;
        yRot += 5.0f;
         m3dRotationMatrix44(rotationMatrix, m3dDegToRad(yRot), 0, 0, 1);
    
        //把平移和旋轉(zhuǎn)合并(乘)起來
        //參數(shù)1:合并后的坐標(biāo)
        //參數(shù)2/3:需要合并的兩個坐標(biāo)
        m3dMatrixMultiply44(finalTransform, translationMatrix, rotationMatrix);
        GLfloat vColor[] = { 1.0f, 0.8f, 0.9f, 1.0f };
        shaderManaget.UseStockShader(GLT_SHADER_FLAT,finalTransform,vColor);
        squareBatch.Draw();
        glutSwapBuffers();
    }
    

3.矩陣堆棧

  • 使用矩陣堆棧的原因:我們在使用矩陣對渲染的視圖做圖形變換(如平移、旋轉(zhuǎn)、縮放)時,需要對矩陣進(jìn)行點(diǎn)乘或者叉乘計(jì)算,將計(jì)算的結(jié)果使用GLMatrixStack存儲,保證了每一次的變換都是獨(dú)立進(jìn)行的。
  • 模型矩陣:將頂點(diǎn)由局部坐標(biāo)系轉(zhuǎn)換到世界坐標(biāo)系;
  • 視圖矩陣:將頂點(diǎn)由世界坐標(biāo)系轉(zhuǎn)換到視圖坐標(biāo)系;
  • 投影矩陣:將頂點(diǎn)由視圖坐標(biāo)系轉(zhuǎn)換到屏幕中。
  • 模型視圖投影矩陣 = 投影矩陣 * 模型視圖矩陣(注意這里不能寫成 模型視圖矩陣 * 投影矩陣,矩陣乘法不滿足交換)。
  • 使用方法:
    • 初始化矩陣堆棧:通過看他具體實(shí)現(xiàn)我們可以看到,它會創(chuàng)建一個棧結(jié)構(gòu)的存儲控件,iStackDepth表示該??臻g的深度為64,就是說我們可以對它進(jìn)行64次的push操作,同時會在棧頂添加一個單元矩陣.
      GLMatrixStack::GLMatrixStack(int iStackDepth = 64)
      
      //創(chuàng)建一個矩陣堆棧,初始化時會在創(chuàng)建時在棧頂加入一個單元矩陣 (FILO:先進(jìn)后出)
      GLMatrixStack modelViewMatrix;
      
      //在棧頂載入一個單元矩陣
      modelViewMatrix.LoadIdentity();
      
      //在棧頂載入任何矩陣,參數(shù):4*4矩陣
      modelViewMatrix.LoadMatrix(<#const float *mMatrix#>)
      
      //矩陣乘以矩陣堆棧頂部矩陣,相乘結(jié)果存儲到堆棧的頂部
      modelViewMatrix.MultMatrix(const M3DMatrix44f);
      //將指定矩陣壓入矩陣堆棧
      modelViewMatrix.PushMatrix(<#const float *mMatrix#>)
      
      //將當(dāng)前矩陣壓入矩陣堆棧,就是將當(dāng)前矩陣堆棧的頂部矩陣copy一份 加到矩陣堆棧的頂部
      modelViewMatrix.PushMatrix(); 
      //將M3DMatrix44f 矩陣對象壓入當(dāng)前矩陣堆棧
      modelViewMatrix.PushMatrix(<#GLFrame &frame#>)
      
      //出棧
      modelViewMatrix.PopMatrix();
      
      //獲取矩陣棧頂?shù)闹?modelViewMatrix.GetMatrix();
      
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容