PDA

View Full Version : avoid loosing Stacked Transformations on Load identity matrix



Phil15
08-21-2015, 04:50 AM
Hi guys,

I am pretty new to opengl.
When I use to code in regular old opengl it had glLoadIdentity() which would help me translate my object , load Identity matrix and then rotate it around its own axis.(which I do not want to use now because I want to understand what it does exactly besides it is not supported in GL 4.xx)

when stacking translation and rotation together an object will not rotate around it`s own origin, but rather (around the initial point it was translated from).(which according to matrix math it is supposed to)

How do I translate an object and then rotatate it about it`s own origin using glm library or even better manually since I want to understand how it can be done. I presume loadIdentity resets the model matrix to identity matrix but then you will loose your previous translation .. I cannot seem to figure out how you could do it manually here is my code:

RenderScene

void renderScene()
{
glm::mat4 ModelViewProject;

glm::mat4 View;

glm::mat4 Model;

glm::mat4 Projection = glm::perspective(45.0f, 1024.0f / 768.0f, 0.1f, 10.0f);


glm::mat4 rotation = glm::rotate(Model, angle, glm::vec3(1, 0, 0));

Model *= rotation;

rotation = loadIdentity();

glm::mat4 transRotation = glm::translate(rotation, glm::vec3(xCh, yCh, zCh));


Model *= transRotation;
View = glm::lookAt(glm::vec3(0, 0, 2), glm::vec3(0, 0, 0), glm::vec3(0.0, 1.0, 0.0));

ModelViewProject = Projection * View * Model;

GLint transform = glGetUniformLocation(programId, "ModelViewProject");

glUniformMatrix4fv(transform, 1, false, glm::value_ptr(ModelViewProject));;


glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glClearColor(0.0, 0.0, 0.0, 1.0);

glDrawArrays(GL_TRIANGLES, 0, 6);

glutSwapBuffers();
}


Vertex Initial position





void init()
{
int z = 1.0f;

GLfloat vertices[] =
{

0.999999f, 1.000000f, 1.0f,
0.0f, 0.0f, 1.0f,
-1.000000f, 1.000000f, 1.0f,
1.0f, 1.0f, 0.0f,
-1.000000f, -1.000000f, 1.0f,
0.0f, 1.0f, 1.0f, // colors

1.000000f, -1.000000f, 1.0f,
1.0f, 1.0f, 0.4f,
0.999999f, 1.000000f, 1.0f,
1.0f, 0.8f, 0.4f,
-1.000000f, -1.000000f, 1.0f,
0.7f, 0.8f, 0.4f,
};

GLint FragmentShaderColorId;
GLint VertexId;

VertexId = glGetAttribLocation(programId, "position");

FragmentShaderColorId = glGetAttribLocation(programId, "ColorIn");
glEnable(GL_DEPTH_TEST);


GLuint myBuffId = 0;

glGenBuffers(1, &myBuffId);

glEnableVertexAttribArray(VertexId);

glBindBuffer(GL_ARRAY_BUFFER, myBuffId);

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glVertexAttribPointer(VertexId, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, 0);

glEnableVertexAttribArray(FragmentShaderColorId);

glVertexAttribPointer(FragmentShaderColorId, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (char *)(sizeof(float) * 3)); // stride of 5 floats describing my colors starting at position 2



keys




void keyboard(unsigned char key, int x, int y)
{
if (key == 'a')
{
xCh -= 0.1;
}

if (key == 'd')
{
xCh += 0.1;
}


if (key == 'w')
{
yCh += 0.1;
}

if (key == 's')
{
yCh -= 0.1;
}


if (key == 'o')
{
zCh += 0.1;
}

if (key == 'l')
{
zCh -= 0.1;
}


if (key == 'm')
{
angle += 0.1;
}


if (key == 'n')
{
angle -= 0.1;
}



glutPostRedisplay();
}

Dark Photon
08-21-2015, 05:33 AM
Try swapping the translate and rotate.

Read the Viewing chapter in the OpenGL Programming Guide to save yourself a lot of headache going forward.

GClements
08-21-2015, 11:30 AM
You can construct a rotation which rotates around an arbitrary point (x,y,z) as


M = translate(x,y,z) * rotate(...) * translate(-x,-y,-z)

If you consider the effect of applying this transformation to the point (x,y,z):


translate(-x,-y,-z) * (x,y,z) = (0,0,0)
rotate(...) * translate(-x,-y,-z) * (x,y,z) = rotate(...) * (0,0,0) = (0,0,0)
translate(x,y,z) * rotate(...) * translate(-x,-y,-z) * (x,y,z) = translate(x,y,z) * (0,0,0) = (x,y,z)

I.e. the point (x,y,z) is invariant under the transformation.

If you want to use legacy OpenGL functions to temporarily construct a matrix from scratch, you can use glPushMatrix() and glPopMatrix() to save and restore the current matrix.

Phil15
08-22-2015, 06:54 AM
Thank you that put me in the right direction