PDA

View Full Version : OpenGL Transformation Issue



aaa111
01-06-2016, 04:38 AM
I have created a 3x3 matrix class which is then passed over to OpenGL Vertex Shader for transform my Quad. I have been trying to rotate my Quad around Z-Axis. Rotation is working but the Quad getting further away from the screen. Below are my Matrix and Vertex Shader source:

Matrix3x3.cpp

#include "matrix3x3.h"
#include "vector2d.h"
#include <cmath>

Matrix3x3::Matrix3x3()
{
matrix[0][0] = 1.0f;
matrix[0][1] = 0.0f;
matrix[0][2] = 0.0f;

matrix[1][0] = 0.0f;
matrix[1][1] = 1.0f;
matrix[1][2] = 0.0f;

matrix[2][0] = 0.0f;
matrix[2][1] = 0.0f;
matrix[2][2] = 1.0f;
}

void Matrix3x3::setIdentity()
{
matrix[0][0] = 1.0f;
matrix[0][1] = 0.0f;
matrix[0][2] = 0.0f;

matrix[1][0] = 0.0f;
matrix[1][1] = 1.0f;
matrix[1][2] = 0.0f;

matrix[2][0] = 0.0f;
matrix[2][1] = 0.0f;
matrix[2][2] = 1.0f;
}

void Matrix3x3::translate(float tx, float ty, float tz)
{
float tmpMatrix[3][3];

tmpMatrix[0][0] = 1.0f;
tmpMatrix[0][1] = 0.0f;
tmpMatrix[0][2] = 0.0f;

tmpMatrix[1][0] = 0.0f;
tmpMatrix[1][1] = 1.0f;
tmpMatrix[1][2] = 0.0f;

tmpMatrix[2][0] = tx;
tmpMatrix[2][1] = ty;
tmpMatrix[2][2] = tz;

mutliply(tmpMatrix);
}

void Matrix3x3::rotate(float angle)
{
float tmpMatrix[3][3];

const float radian = 3.141593f / 180 ;//(angle * 3.141592653589793 )/ 180.0;// (2 * PI) / (360.0 / cos(angle));

float cs = cos(radian * angle);
float sn = sin(radian * angle);

tmpMatrix[0][0] = cs;
tmpMatrix[0][1] = sn;
tmpMatrix[0][2] = 0.0f;

tmpMatrix[1][0] = -sn;
tmpMatrix[1][1] = cs;
tmpMatrix[1][2] = 0.0f;

tmpMatrix[2][0] = 0.0f;
tmpMatrix[2][1] = 0.0f;
tmpMatrix[2][2] = 1.0f;

mutliply(tmpMatrix);
}

void Matrix3x3::scale(float sx,float sy)
{
float tmpMatrix[3][3];

tmpMatrix[0][0] = sx;
tmpMatrix[0][1] = 0.0f;
tmpMatrix[0][2] = 0.0f;

tmpMatrix[1][0] = 0.0f;
tmpMatrix[1][1] = sy;
tmpMatrix[1][2] = 0.0f;

tmpMatrix[2][0] = 0.0f;
tmpMatrix[2][1] = 0.0f;
tmpMatrix[2][2] = 1.0f;

mutliply(tmpMatrix);
}

void Matrix3x3::transform(vector2d& vec)
{
/*float tx = vec.x * matrix[0][0] + vec.y * matrix[3] + vec.w * matrix[6];
float ty = vec.x * matrix[1] + vec.y * matrix[4] + vec.w * matrix[7];
float tw = vec.x * matrix[2] + vec.y * matrix[5] + vec.w * matrix[8];

vec.x = tx;
vec.y = ty;
vec.w = tw;*/
}

void Matrix3x3::mutliply(const float(&matrixb)[3][3])
{
/*matrix[0] = (matrix[0] * matrixb[0]) + (matrix[1] * matrixb[3]) + (matrix[2] * matrixb[6]);
matrix[1] = (matrix[0] * matrixb[1]) + (matrix[1] * matrixb[4]) + (matrix[2] * matrixb[7]);
matrix[2] = (matrix[0] * matrixb[2]) + (matrix[1] * matrixb[5]) + (matrix[2] * matrixb[8]);

matrix[3] = (matrix[3] * matrixb[0]) + (matrix[4] * matrixb[3]) + (matrix[5] * matrixb[6]);
matrix[4] = (matrix[3] * matrixb[1]) + (matrix[4] * matrixb[4]) + (matrix[5] * matrixb[7]);
matrix[5] = (matrix[3] * matrixb[2]) + (matrix[4] * matrixb[5]) + (matrix[5] * matrixb[8]);

matrix[6] = (matrix[6] * matrixb[0]) + (matrix[7] * matrixb[3]) + (matrix[8] * matrixb[6]);
matrix[7] = (matrix[6] * matrixb[1]) + (matrix[7] * matrixb[4]) + (matrix[8] * matrixb[7]);
matrix[8] = (matrix[6] * matrixb[2]) + (matrix[7] * matrixb[5]) + (matrix[8] * matrixb[8]);*/

for (int x = 0; x<3; ++x)
for (int y = 0; y<3; ++y)
{
float sum = 0;
for (int z = 0; z<3; ++z)
sum += matrix[x][z] * matrixb[z][y];

matrix[x][y] = sum;
}
}

ostream& operator<<(ostream& os,Matrix3x3& matrix)
{
os << matrix.matrix[0][0] << " " << matrix.matrix[0][1] << " " << matrix.matrix[0][2] << std::endl;
os << matrix.matrix[1][0] << " " << matrix.matrix[1][1] << " " << matrix.matrix[1][2] << std::endl;
os << matrix.matrix[2][0] << " " << matrix.matrix[2][1] << " " << matrix.matrix[2][2] << std::endl;

return os;
}


float* Matrix3x3::getPtr()
{
return &matrix[0][0];
}



vertex_shader.glsl


#version 330 core

layout (location = 0) in vec3 position;

uniform mat3 transform;

void main()
{
gl_Position = vec4(transform * vec3(position.x,position.y,0.0) , 1.0);
}

This is where i am using my matrix in the Quad class:


void Quad::rotate(float angle2)
{

glUseProgram(shader->getProgramId());
this->transformMatrix->rotate(angle);

shader->setUniformMatrix3("transform", this->transformMatrix->getPtr());
}


I have also tried to debug my GLSL shader to check the gl_Position . But its shows that my Z-Axis is always zero and W component is always 1. No idea why its getting away from my screen.

GClements
01-06-2016, 06:21 AM
I have created a 3x3 matrix class which is then passed over to OpenGL Vertex Shader for transform my Quad. I have been trying to rotate my Quad around Z-Axis. Rotation is working but the Quad getting further away from the screen. Below are my Matrix and Vertex Shader source:

If you're working in 2D homogeneous coordinates, you don't have a Z axis. You have X, Y and W.





void Matrix3x3::translate(float tx, float ty, float tz)



The tz parameter shouldn't be there.





void Matrix3x3::mutliply(const float(&matrixb)[3][3])
{
for (int x = 0; x<3; ++x)
for (int y = 0; y<3; ++y)
{
float sum = 0;
for (int z = 0; z<3; ++z)
sum += matrix[x][z] * matrixb[z][y];

matrix[x][y] = sum;
}
}


There are two ways to interpret the above. If the two matrices are in row-major order, the multiplication has matrix on the left and matrixb on the right (which is how you'd normally manipulate a "current" transformation). If the matrices are in column-major order, the multiplication is reversed.

By default, OpenGL uses column-major order. To use a row-major matrix, you need to set the transpose parameter to glUniformMatrix() or use the row_major layout qualifier on the variable.





gl_Position = vec4(transform * vec3(position.x,position.y,0.0) , 1.0);


For a position, the W coordinate should be one, i.e.


gl_Position = vec4(transform * vec3(position.x,position.y,1.0) , 1.0);

Otherwise, any translation will be ignored.

aaa111
01-06-2016, 10:12 PM
Thanks for the answer. My Matrix is Row Major order. I also changed the translation portion as you said. Now from other forum i posted my question and they mentioned that i am having Cumalative rounding error with my matrix. So i choose to create the matrix each frame. Now my scaling issue is fixed, but now i am facing another issue, my quad rotates around z-axis for some angle but after a while its started to rotate around other axis also