如何在 Pi 上使用 OpenGL ES 绘制到屏幕之前旋转纹理

Tho*_*mas 5 c c++ opengl-es raspberry-pi

我最近了解到Raspberry Pi的GPU仅支持OpenGL ES。我有一个任务要完成,问题是,每当我搜索 OpenGL ES 时,我都会得到基于 Android 和 IOS 的结果。

值得庆幸的是,我只有一个小问题。我偶然发现了 simple2d 库,它抽象了 pi 上与视频核心 IV GPU 的 OpenGL ES 接口。它是一个开源库,似乎不支持旋转纹理。这是我唯一想要的功能,以便清除我的道路上的所有障碍。这是对 DrawTextures 的调用。我将非常感谢任何帮助我解决这个问题的人。

static void S2D_GLES_DrawTexture(int x, int y, int w, int h,
                                 GLfloat r, GLfloat g, GLfloat b, GLfloat a,
                                 GLfloat tx1, GLfloat ty1, GLfloat tx2, GLfloat ty2,
                                 GLfloat tx3, GLfloat ty3, GLfloat tx4, GLfloat ty4,
                                 GLuint texture_id) {

  GLfloat vertices[] =
  //  x, y coords      | x, y texture coords
    { x,     y,     0.f, tx1, ty1,
      x + w, y,     0.f, tx2, ty2,
      x + w, y + h, 0.f, tx3, ty3,
      x,     y + h, 0.f, tx4, ty4 };

  GLfloat colors[] =
    { r, g, b, a,
      r, g, b, a,
      r, g, b, a,
      r, g, b, a };

  glUseProgram(texShaderProgram);

  // Load the vertex position
  glVertexAttribPointer(texPositionLocation, 3, GL_FLOAT, GL_FALSE,
                        5 * sizeof(GLfloat), vertices);
  glEnableVertexAttribArray(texPositionLocation);

  // Load the colors
  glVertexAttribPointer(texColorLocation, 4, GL_FLOAT, GL_FALSE, 0, colors);
  glEnableVertexAttribArray(texColorLocation);

  // Load the texture coordinate
  glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE,
                        5 * sizeof(GLfloat), &vertices[3]);
  glEnableVertexAttribArray(texCoordLocation);

  // Bind the texture
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, texture_id);

  // Set the sampler texture unit to 0
  glUniform1i(samplerLocation, 0);

  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
}
Run Code Online (Sandbox Code Playgroud)

我的任务是修改上述函数,使其接受额外的旋转参数,以便使其能够在绘制纹理之前旋转它。

我了解 OpenGL 并且我很确定调用 Rotatef 不会有帮助。如果有人告诉我如何在 Pi 的 OpenGL ES 中执行此操作,我会很高兴。

Rab*_*d76 4

您必须设置一个旋转矩阵。根据您的需要,在顶点着色器中通过旋转矩阵变换顶点坐标或纹理坐标。

像这样创建一个顶点着色器:

attribute vec3 texPosition;
....

uniform mat4 u_rotateMat44;

void main()
{
    ....

    vec4 rotPos = u_rotateMat44 * vec4(texPosition, 1.0);
    gl_Position = rotPos;
}
Run Code Online (Sandbox Code Playgroud)

或这个:

attribute vec2 texCoord;
....

varying vec2 outTexCoord:

uniform mat4 u_rotateMat44;

void main()
{
    ....

    vec4 rotCoord = u_rotateMat44 * vec4(texCoord, 0.0, 1.0);
    outTexCoord   = rotCoord.st;

    ....
}
Run Code Online (Sandbox Code Playgroud)

旋转矩阵可以这样设置:

#include <math.h> // sin, cos
Run Code Online (Sandbox Code Playgroud)

float ang_rad ....; // angle in radians

float rotMat[16] =
{
     cos(ang_rad), sin(ang_rad),  0.0f, 0.0f,
    -sin(ang_rad), cos(ang_rad ), 0.0f, 0.0f,
     0.0f,         0.0f,          1.0f, 0.0f,
     0.0f,         0.0f,          0.0f, 1.0f
};
Run Code Online (Sandbox Code Playgroud)

通过以下方式设置制服glUniformMatrix4fv

GLuint program = ....; // the shader program

GLint rotMatLoc = glGetUniformLocation( program, "u_rotateMat44" );

glUniformMatrix4fv( rotMatLoc, 1, GL_FALSE, rotMat );
Run Code Online (Sandbox Code Playgroud)

  • @Thomas 好吧,但这对我对你问题的回答有何影响?注意,GLM 库的部分是可选的。您所需要的只是数组 `float rotMat[16]` (3认同)
  • 这实际上是我的错,我应该只用“c”标记这个问题。我可以使用 c++,但我想我们的团队希望避免 ..extern "C".. 因为我们将把它与 luajit ffi 一起使用。我将与我的团队澄清我们是否可以做到这一点。非常感谢您的回答。如果我没有得到另一个不依赖 c++ 标头的答案,我会接受这个答案。 (2认同)
  • 顺便问一下,这个要求编辑答案并代表我回复的冒名顶替者是谁?虽然我们的名字相同,但我们的头像等有所不同。 (2认同)