【问题标题】:OpenGL Orthographic Projection and TranslateOpenGL 正交投影和平移
【发布时间】:2016-04-06 22:06:31
【问题描述】:

以下代码使用 OpenGL ES2 在 2D 屏幕空间中绘制一个矩形。如何在不修改顶点的情况下将矩形的绘制向右移动 1 个像素?

具体来说,我要做的是将坐标向右移动 0.5 像素。我之前必须使用 GLES1.x 执行此操作,原因是我无法在正确的位置绘制线条,除非我使用 0.5f 执行 glTranslate()。

我对在下面的代码中使用 glm::translate() 感到困惑。

如果我尝试平移 0.5f,整个矩形会从屏幕左侧移动到中间 - 大约 200 像素的跳跃。

无论我对模型或视图矩阵执行 glm::translate,我都会得到相同的结果。

矩阵乘法的顺序是不是错了,应该是什么?

short g_RectFromTriIndices[] =
{
  0, 1, 2,
  0, 2, 3

}; // The order of vertex rendering.

GLfloat g_AspectRatio = 1.0f;


//--------------------------------------------------------------------------------------------
// LoadTwoTriangleVerticesForRect()
//--------------------------------------------------------------------------------------------
void LoadTwoTriangleVerticesForRect( GLfloat *pfRectVerts, float fLeft, float fTop, float fWidth, float fHeight )
{
  pfRectVerts[  0 ] = fLeft;
  pfRectVerts[  1 ] = fTop;
  pfRectVerts[  2 ] = 0.0;

  pfRectVerts[  3 ] = fLeft + fWidth;
  pfRectVerts[  4 ] = fTop;
  pfRectVerts[  5 ] = 0.0;

  pfRectVerts[  6 ] = fLeft + fWidth;
  pfRectVerts[  7 ] = fTop  + fHeight;
  pfRectVerts[  8 ] = 0.0;

  pfRectVerts[  9 ] = fLeft;
  pfRectVerts[ 10 ] = fTop  + fHeight;
  pfRectVerts[ 11 ] = 0.0;
}

//--------------------------------------------------------------------------------------------
// Draw()
//--------------------------------------------------------------------------------------------
void Draw( void )
{
  GLfloat afRectVerts[ 12 ];

  //LoadTwoTriangleVerticesForRect( afRectVerts, 0, 0, g_ScreenWidth, g_ScreenHeight );
  LoadTwoTriangleVerticesForRect( afRectVerts, 50, 50, 100, 100 );

  // Correct for aspect ratio so squares ARE squares and not rectangular stretchings..
  g_AspectRatio = (GLfloat) g_ScreenWidth / (GLfloat) g_ScreenHeight;

  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

  GLuint hPosition = glGetAttribLocation( g_SolidProgram, "vPosition" );

  // PROJECTION
  glm::mat4 Projection = glm::mat4(1.0);
  //  Projection = glm::perspective( 45.0f, g_AspectRatio, 0.1f, 100.0f );

  // VIEW
  glm::mat4 View = glm::mat4(1.0);

  static GLfloat transValY = 0.5f;
  static GLfloat transValX = 0.5f;

  //View = glm::translate( View, glm::vec3( transValX, transValY, 0.0f ) );

  // MODEL
  glm::mat4 Model = glm::mat4(1.0);

  //  static GLfloat rot = 0.0f;

  //  rot += 0.001f;
  //  Model = glm::rotate( Model, rot, glm::vec3( 0.0f, 0.0f, 1.0f ) ); // where x, y, z is axis of rotation (e.g. 0 1 0)

  glm::mat4 Ortho = glm::ortho( 0.0f, (GLfloat) g_ScreenWidth, (GLfloat) g_ScreenHeight, 0.0f, 0.0f, 1000.0f );

  glm::mat4 MVP;

  MVP = Projection * View * Model * Ortho;

  GLuint hMVP;

  hMVP = glGetUniformLocation( g_SolidProgram, "MVP" );
  glUniformMatrix4fv( hMVP, 1, GL_FALSE, glm::value_ptr( MVP ) );

  glEnableVertexAttribArray( hPosition );

  // Prepare the triangle coordinate data
  glVertexAttribPointer( hPosition, 3, GL_FLOAT, FALSE, 0, afRectVerts );

  // Draw the rectangle using triangles
  glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, g_RectFromTriIndices );

  glDisableVertexAttribArray( hPosition );
}

这是顶点着色器源代码:

attribute vec4 vPosition;

uniform mat4 MVP;

void main()
{
  gl_Position = MVP * vPosition;
}

更新:我发现下面的矩阵乘法给了我更好的结果。我不知道这是否“正确”:

MVP = Ortho * Model * View * Projection;

【问题讨论】:

    标签: opengl-es orthographic


    【解决方案1】:

    那个 MVP 对我来说真的很奇怪,你不应该需要 4 个东西来获得你的 MVP.. 你的投影矩阵应该只是正交矩阵,所以在这种情况下

    MVP = Projection * View * Ortho;

    但我也可以看到您的投影矩阵已经从角度进行了评论,所以我认为它现在没有做太多。

    听上去,既然您希望模型坐标在移动时保持不变,那么您想移动相机对吗?因此(从外观上看,您的顶点使用每像素 1 个单位的坐标范围)将 0.5f 转换为您的视图正在移动您的投影空间的一半。相反,您希望有一个类似Camera 的类,您可以使用相机的XY 位置获得View

    然后您可以使用可以共享您正在使用的世界单位系统的相机位置获取您的视图矩阵,即每像素 1 个单位。

    glm::mat4 view;
    view = glm::lookAt(glm::vec3(camX, camY, 0.0), glm::vec3(0.0, 0.0, 0.0),glm::vec3(0.0, 1.0, 0.0));
    

    我从相机 here 上的一个非常好的 3d 教程中直接撕掉了这条线(减去将 camZ 更改为 camY),但完全相同的概念可以应用于正交相机

    我知道这会增加一些开销,但是拥有一个可以通过这种方式控制的 cmaera 类比手动使用 glm::translate,rotate&scale 来控制视口更好(并且它可以让您确保使用相机和模型坐标点之间更明显的坐标系。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      • 2016-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-14
      相关资源
      最近更新 更多