HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Quaternion rotations and preparing matrices for a shader

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
shaderpreparingquaternionrotationsformatricesand

Problem

I am implementing an OpenGL ES 2.0 renderer in c. I want to use quaternions for rotations. Please take a look at the way I am implementing the rotation math. Everything looks as expected when the program runs, but since I am very new to using quaternions, I am wondering if I am doing things in a sub-optimal way. The idea is that the program logic will determine the current angle of rotation for a 3d object and inform the renderer. The renderer will then find the sin and cos of that angle, form a quaternion based on a unit vector representing the rotation axis (fixed for now), and then create a rotation matrix from the quaternion. This whole process would take place for each object on each frame. I have no idea if this approach is wildly inefficient.

Also, I have been reading that I should combine all matrix transformations before uploading them to a vertex shader in order to avoid calculating the combined transformation repeatedly for each vertex. Therefore I made a function that specifically multiplies 4x4 matrices, and I do all the matrix multiplication in the c code, and I'm wondering if there is some way to use the graphics hardware for these calculations.

I am posting the renderer. For running this in iOS, I am using glkit, and on android, I am using the GLsurfaceView. These wrappers are only used to handle setting up the gl context and the displaying and switching of frame buffers. (I can post the xcode and android studio projects if anyone wants to run the code.)

```
#define pi 3.14159265358979323846264338327
#define PI_OVER_360 0.0087266

GLuint _positionSlot;
GLuint _colorSlot;
GLuint _modelUniform;

GLfloat screenWidthInPixels;
GLfloat screenHeightInPixels;

float timeDiff = 0;
float lastTimeStamp = 0;

float modelMatrix[16] = {0};
float perspectiveMatrix[16] = {0};
float translationMatrix[16] = {0};
float rotationMatrix[16] = {0};
float transRotMatrix[16] = {0}; //To store the result of the translation matrix multiplied by the rotation matrix
float ang

Solution

I don't see why you have so many global variables. For example modelMatrix is only used renderScene() which inside its body, will pass the matrix to two other functions. Probably there are other global variables with this nature in your code.

float timeDiff = 0; is unused for example, but maybe you see it in code you don't show.

Inside buildPerspProjMat(), you have:

float ymin = -xymax;
float height = xymax - ymin;


I think that ymin variable is redundant here, since you don't use it anywhere else in the function. Change the above to this:

float height = xymax + xymax;


You have many variables that are of the same nature as ymin.

You have this:

void matMult4x4by4x4(float* m, float* a, float* b)
{
    m[0]  = a[0]*b[0]  + a[4]*b[1]  + a[8]* b[2]  + a[12]*b[3];
    m[1]  = a[1]*b[0]  + a[5]*b[1]  + a[9]* b[2]  + a[13]*b[3];
    ...
}


Here you could use a loop, with the following logic:

int i, j, z = 0;
  for(i = 0; i < 4; ++i) {
    for(j = 0; j < 4; ++j) {
      printf("m[%d]  = a[%d]*b[%d]  + a[%d]*b[%d]  + a[%d]* b[%d]  + a[%d]*b[%d];\n",
             z, j, i * 4, j + 4, (i * 4) + 1, j + 8, (i * 4) + 2, (j + 12), (i * 4) + 3);
      ++z;
    }
  }


Maybe counter z is redundant, I am not sure.

Code Snippets

float ymin = -xymax;
float height = xymax - ymin;
float height = xymax + xymax;
void matMult4x4by4x4(float* m, float* a, float* b)
{
    m[0]  = a[0]*b[0]  + a[4]*b[1]  + a[8]* b[2]  + a[12]*b[3];
    m[1]  = a[1]*b[0]  + a[5]*b[1]  + a[9]* b[2]  + a[13]*b[3];
    ...
}
int i, j, z = 0;
  for(i = 0; i < 4; ++i) {
    for(j = 0; j < 4; ++j) {
      printf("m[%d]  = a[%d]*b[%d]  + a[%d]*b[%d]  + a[%d]* b[%d]  + a[%d]*b[%d];\n",
             z, j, i * 4, j + 4, (i * 4) + 1, j + 8, (i * 4) + 2, (j + 12), (i * 4) + 3);
      ++z;
    }
  }

Context

StackExchange Code Review Q#75053, answer score: 2

Revisions (0)

No revisions yet.