美文网首页
OpenGL-矩阵与向量

OpenGL-矩阵与向量

作者: tp夕阳武士 | 来源:发表于2020-03-02 17:01 被阅读0次
OpenGL的矩阵操作
  • 旋转
  • 平移
  • 缩放
  • 压栈/出栈

单位向量-X轴-(1,0,0) 单位矩阵-X,Y,Z 三轴-(1,0,0,0,1,0,0,0,1)

相关库

GLTools中有一个组件叫做Math3d,其中包含了大量好用的OpenGL一致的3D数学和数据类型.
Math3d库 ,有两个数据类型,能够表示一个三维或者思维向量,M3DVector3f可以表示一个三维向量(x,y,z),而M3DVector4f可以表示一个思维的向量(x,y,z,w)--W表示缩放因子,在典型的情况下W的坐标设为1.0, xyz值除w,进行缩放,而除以1.0本质上不改变xyz值.

typedef float M3DVector3f[3];
typedef float M3DVector4f[4];

//声明一个3分量向量操作:
M3DVector3f vVector3;

//声明一个4分量向量操作:
M3DVector4f vVector4 = {0.0f,0.0f,1.0f,1.0f};

//声明一个3分量顶点数组:
M3DVector3f vVerts[] = { -0.5f,0.0f,0.0f,
                          0.5f,0.0f,0.0f,
                          0.0f,0.5f,0.0f
 }

向量/矩阵 的 点乘
向量点乘
//实现点乘的方法
//方法1:返回值为-1到1区间的值,它代表两个向量的余弦值.
//余弦值:直角三角形中,锐角的 邻边值/斜边值 = 余弦值;
float m3dDotProduct3(const M3DVector3f u,const M3DVector3f v);

//方法2:返回两个向量之间的弧度.
float m3dGetAngleBetweenVetor3(const M3DVector3f u,const M3DVector3f v);
向量/矩阵 的 叉乘
向量/矩阵 叉乘
// result 是结果, 就是上图的V3 ,它是一个向量值
void m3dCrossProduct3(const M3DVector3f result,
                      const M3DVector3f u, 
                      const M3DVector3f v);

//v3是一个垂直于,V1/V2所在面的向量.

//注意,叉乘不满足交换律,  
a*b != b*a;
OpenGL下的矩阵
OpenGL下的矩阵
实现平移/旋转/缩放 叉乘
GLfloat xPos = 0.0f;//x轴平移量
GLfloat yPos = 0.0f;//y轴平移量
GLfloat zRot = 0;//旋转角度 - 需要抓换成弧度才能用于求矩阵
GLfloat xScale = 1;//x轴缩放量 缩放的计算方式是,原边长*缩放因子的绝对值
GLfloat yScale = 1;//y轴缩放量

void SpecialKeys(int key ,int x, int y){
    
    GLfloat stepSize = 0.025;
    
    if (key == GLUT_KEY_UP) {
        yPos += stepSize;
        zRot += 10.0;
        yScale += 0.1;
        xScale += 0.1;
    }
    
    if (key == GLUT_KEY_DOWN) {
        yPos -= stepSize;
        zRot -= 10.0;
        yScale -= 0.1;
        xScale -= 0.1;
    }
    
    if (key == GLUT_KEY_LEFT) {
        xPos -= stepSize;
        zRot -= 10.0;
        xScale -= 0.1;
        yScale -= 0.1;
    }
    
    if (key == GLUT_KEY_RIGHT) {
        xPos += stepSize;
        zRot += 10.0;
        xScale += 0.1;
        yScale += 0.1;
    }
    
    
    //检测边沿碰撞
    if (blockSize+xPos > 1) xPos = 1-blockSize;
    
    if (-blockSize + xPos < -1) xPos = blockSize - 1;

    if (blockSize + yPos > 1)  yPos = 1-blockSize;
    
    if (-blockSize + yPos < -1) yPos = blockSize - 1;
    
    
    glutPostRedisplay();
}

/// 开始渲染
void RenderScence(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    
    GLfloat redColor[] = { 1.0,0.0,0.0,1.0f};
    
    //定义矩阵
    M3DMatrix44f mFinalTranslation , mTranslationMatrix , mRotationMartix ,mScaleMartix;
    
    //计算平移矩阵
    m3dTranslationMatrix44(mTranslationMatrix, xPos, yPos, 0);
    
    //计算旋转矩阵
    m3dRotationMatrix44(mRotationMartix, m3dDegToRad(zRot),0.0, 0.0, 1.0);
    
    //计算缩放矩阵
    m3dScaleMatrix44(mScaleMartix, xScale, yScale, 0);
    
    // 平移 & 旋转 矩阵叉乘
    m3dMatrixMultiply44(mFinalTranslation, mTranslationMatrix, mRotationMartix);
    
    // 平移旋转后再缩放
    m3dMatrixMultiply44(mFinalTranslation, mFinalTranslation, mScaleMartix);
    
    
//    shaderManager.UseStockShader(GLT_SHADER_FLAT,mTranslationMatrix,redColor);//平移
//    shaderManager.UseStockShader(GLT_SHADER_FLAT,mRotationMartix,redColor);//旋转
//    shaderManager.UseStockShader(GLT_SHADER_FLAT,mScaleMartix,redColor);//缩放
    shaderManager.UseStockShader(GLT_SHADER_FLAT,mFinalTranslation,redColor); //叉乘方式

    squareBatch.Draw();
    
    glutSwapBuffers();
}
效果.gif

使用矩阵实现平移/旋转/缩放/矩阵叉乘

矩阵堆栈的压栈/出栈
//模型视图矩阵的压栈 modelViewMatrix属于GLMatrixStack 类型

//写法1;
modelViewMatrix.PushMatrix(); //模型视图矩阵堆栈进行压栈;
M3DMatrix44f mCameraFrame;
cameraFrame.GetCameraMatrix(mCameraFrame);
modelViewMatrix.MultMatrix(mCameraFrame);  //栈顶矩阵叉乘

M3DMatrix44f mObjectFrame;
objectFrame.GetMatrix(mObjectFrame);
modelViewMatrix.MultMatrix(mObjectFrame); //栈顶矩阵叉乘

//上面的代码中, cameraFrame & objectFrame 是提前声明的两个坐标矩阵
//观察者位置
//GLFrame                cameraFrame;
//世界坐标位置
//GLFrame             objectFrame;


//inline void PushMatrix(void) {
//          if(stackPointer < stackDepth) {
//              stackPointer++;
//              m3dCopyMatrix44(pStack[stackPointer], pStack[stackPointer-1]);
//              }
//          else
//              lastError = GLT_STACK_OVERFLOW;
//          }

//我们看看当模型视图矩阵堆栈调用 .PushMatrix(void) 方法的时候的源码,
//压栈的时候是把栈顶的数据copy了一份然后插入到堆栈的栈顶处;

//写法2-> 在SetupRC的时候,直接让物体坐标系向观察者坐标系移动
//在 void SetupRC() {} 中 , 代码 -> cameraFrame.MoveForward(-15.0f); --> objectFrame.MoveForward(15.0f);
//然后在压栈的时候,就可以直接Push(objectFrame)



 //4. pop  push与pop是成对出现的
 modelViewMatrix.PopMatrix();
    
//5. 交换缓存
glutSwapBuffers();

压栈&出栈流程图
压栈出栈流程图

相关文章

  • OpenGL-向量与矩阵

    向量与矩阵的应用场景和相关方法 向量 向量:(也称为欧几里得向量、几何向量、矢量),指具有大小(magnitude...

  • OpenGL-矩阵与向量

    OpenGL的矩阵操作 旋转 平移 缩放 压栈/出栈 单位向量-X轴-(1,0,0) 单位矩阵-X,Y,Z 三轴...

  • OpenGL-向量 & 矩阵

    1.向量 1.1 向量的写法 向量又分为横向量与列向量,横向力与列向量的写法如下图: 1.2 负向量表达式: 如上...

  • R语言-矩阵与行/列等长的向量 作除法

    矩阵与 矩阵列数相等的向量作整除 矩阵与 矩阵行数相等的向量作除法

  • 视频特效学习04-OpenGL基础变化

    学习目标: 向量、矩阵和基础变化(了解) 使用矩阵/向量移动几何图形(实践) 矩阵堆栈(理解) 1. 向量与矩阵 ...

  • OpenGL-向量/矩阵变换/投影

    基本概念 向量 从坐标原点指向这个位置点的一个向量(带箭头的线段) 向量在OpenGL里对应的数据类型M3DVec...

  • 向量,矩阵,张量求导法则

    向量,矩阵,张量求导向量对向量求导向量对矩阵求导矩阵对矩阵求导使用链式法则总结 向量,矩阵,张量求导 参考:htt...

  • R语言编程艺术 第2章 向量(上)

    2.1标量、向量、数组与矩阵 向量长度:length()矩阵、数组本质上是向量。 2.2声明 变量可以直接赋值,无...

  • DL01-4:感知器实现(向量版)

    1.使用numpy做内积运算2.使用向量或者矩阵内积实现感知器 一、向量与矩阵的内积计算 1、向量作为矩阵的注意点...

  • 第2章 矩阵

    矩阵 向量是标量的数组,矩阵是向量的数组。 n维向量 x (N*M的矩阵) = M维向量 矩阵就是映射。...

网友评论

      本文标题:OpenGL-矩阵与向量

      本文链接:https://www.haomeiwen.com/subject/cahpkhtx.html