OpenGL es 2.0 实战 - 渲染图形变形

背景

在界面中渲染正方形(由两个三角形组成,6个顶点),渲染的方式为GL_TRIANGLES. 渲染的图形位于XoY平面上.

问题

  1. 当图形绕Z轴转动 0 度;图形已经稍有变形.
  2. 当图形绕Z轴转动 x 度时, 图形变形严重.

问题 1 解决

glViewport(0, 0, width, height);与生成透视投影矩阵mProjMatrix的生成参数

frustumM(GLfloat* rm, GLint offset,
        GLfloat left, GLfloat right,
        GLfloat bottom, GLfloat top,
        GLfloat near, GLfloat far);

变形的原因是(width/height) != (right - left) / (top - bottom)

问题 2 解决(重要)

现象:

旋转过程中变形.

解决过程
  1. 对每个矩阵操作的C函数打印结果,与Java的Matrix类结果对比差异
  2. 发现Java中矩阵运算的步骤不同

问题 2 总结

在一个OpenGL ES 2.0的项目中,如果存在旋转,平移等变换操作
向顶点着色器中传入最终的变换矩阵的整合步骤如下
1. 先初始化变换矩阵,如本例初始化一个在X轴上旋转0度的矩阵
2. 整合平移,旋转等变换
3. 整合观察矩阵即LookAtMatrix,OpenGL ES 2.0里的观察点,摄像机,摄像机方向向量等参数的矩阵.
4. 最后整合透视投影矩阵ProjMatrix.即包含视口左右下上远近等参数的矩阵

不变形的代码


  GLuint pP;
  pP = program;
  if (pP == 0)
    {
      pP = initShader ();
      LOGI("drawFrame() program initShader!");
    }
  if (pP == 0)
    {
      LOGW("drawFrame() program is NULL return!");
      return;
    }
  glUseProgram (pP);
  //初始化变换矩阵
  GLfloat* muMVPMatrix;
  GLfloat* mLookAtMatrix;
  GLfloat* mProjMatrix;
  GLfloat* mRXMatrix;
  GLfloat* mRZMatrix;
  muMVPMatrix = getRotateM(NULL, 0, 0, 1, 0, 0);
  printArray("m1", muMVPMatrix);
  //设置沿Z轴正向移动1
  translateM(muMVPMatrix, 0, 0, 0, 1);
  printArray("mT", muMVPMatrix);
  //设置透视投影矩阵
  float radio = 720.0f / 1134.0f;
  mProjMatrix = frustumM (NULL,//GLfloat* m
              0,//offset
              -radio, radio,//Left, Right
              -1, 1,// bottom, top
              1, 10//near, far
  );
  printArray("mPM", mProjMatrix);
  //设置观察矩阵
  mLookAtMatrix = setLookAtM (NULL,
                  0,
                  0, 0, 3,//eyeX, eyeY, eyeZ
                  0, 0, 0,//targetX, targetY, targetZ
                  0, 1, 0//upX, upY, upZ
  );
  printArray("mVM", mLookAtMatrix);
  //绕X轴旋转
  GLfloat xAngle = 0;
  mRXMatrix = getRotateM(NULL, 0, xAngle, 1, 0, 0);
  //绕Z轴旋转
  static GLfloat zAngle = 60;
  mRZMatrix = getRotateM(NULL, 0, zAngle, 0, 0, 1);
  ++zAngle;
  //整理矩阵
  matrixMM4(muMVPMatrix, mRXMatrix);
  matrixMM4(muMVPMatrix, mRZMatrix);
  matrixMM4(muMVPMatrix, mLookAtMatrix);
  matrixMM4(muMVPMatrix, mProjMatrix);
  //将矩阵传入着色器
  //    1.获取着色器总变换矩阵引用
  GLint muMVPMatrixHandle;
  muMVPMatrixHandle = glGetUniformLocation(pP, "uMVPMatrix");
  //    2.输入变换矩阵数据
  glUniformMatrix4fv(muMVPMatrixHandle, 1, GL_FALSE, muMVPMatrix);

  //    3.释放
  free(mRXMatrix);
  free(mRZMatrix);
  free(mProjMatrix);
  free(mLookAtMatrix);
  free(muMVPMatrix);
  //为顶点着色器输入着色数据
  //    1.获取顶点着色器位置引用
  GLint maPositionHandle;
  maPositionHandle = glGetAttribLocation(pP, "aPosition");
  //    2.输入数据
  glVertexAttribPointer (maPositionHandle,//GLuint indx,
             3,//GLint size,
             GL_FLOAT,//GLenum type,
             GL_FALSE,//GLboolean normalized,
             3 * 4,//GLsizei stride,
             vertices2//const GLvoid* ptr
  );
  //为顶点着色器输入颜色数据
  //    1. 获取顶点着色器颜色引用
  GLint maColorHandle;
  maColorHandle = glGetAttribLocation(pP, "aColor");
  //    2. 输入数据
  glVertexAttribPointer (maColorHandle,//GLuint index,
             4,//GLint size R G B A
             GL_FLOAT,//GLenum type
             GL_FALSE,//GLboolean normalized
             4 * 4,//GLsizei stride
             colors2
  );
  //允许顶点位置数据数组
  glEnableVertexAttribArray(maPositionHandle);
  glEnableVertexAttribArray(maColorHandle);
  //绘制三角形
  glDrawArrays (GL_TRIANGLES,//GLenum mode,
        0,//GLint first,
        6//GLsizei count
  );
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值