简体   繁体   中英

How to Rotate a Texture before drawing to the screen using OpenGL ES on the Pi

I recently came to know that the Raspberry Pi's GPU only supports OpenGL ES. I have a task to complete and the problem is, whenever I search for OpenGL ES, I get results based on Android and IOS.

Thankfully, I have only a small problem. I had stumbled onto simple2d library which abstracts the OpenGL ES interfacing with Video core IV GPU on pi. Its an open source library which does not seem to support Rotating textures. This is the only feature I want so as to clear my path from all obstacles. This is the call to DrawTextures. I would be very thankful to anyone who helps me regarding this problem.

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);
}

My task is to modify the above function such that it accepts additional rotation parameter so as to enable it to rotate it before drawing the texture.

I know OpenGL and I am pretty sure that a call to Rotatef won't be helpful. I would be glad if someone would tell me how to do this in OpenGL ES for Pi.

You have to setup a rotation matrix. Depending on what you want, either transform the vertex coordinates or the texture coordinates by the rotation matrix, in the vertex shader.

Create a vertex shader like this:

attribute vec3 texPosition;
....

uniform mat4 u_rotateMat44;

void main()
{
    ....

    vec4 rotPos = u_rotateMat44 * vec4(texPosition, 1.0);
    gl_Position = rotPos;
}

or this:

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;

    ....
}

The rotation matrix can be setup like this:

#include <math.h> // sin, cos

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
};

Set the uniform by glUniformMatrix4fv :

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

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

glUniformMatrix4fv( rotMatLoc, 1, GL_FALSE, rotMat );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM