0

I am trying to get my model rotated with mouse. As result I have something looks like rotation, but it is quite strange and unexpected behaved.

I suggest that error is somewhere in my matrices set up or in mouse event handler. But I cannot figure out where.

My initialization code:

    var vertexShaderSource = ManifestResourceLoader.LoadTextFile("Shader.vert");
    var fragmentShaderSource = ManifestResourceLoader.LoadTextFile("Shader.frag");
    shaderProgram = new ShaderProgram();
    shaderProgram.Create(gl, vertexShaderSource, fragmentShaderSource, null);
    shaderProgram.BindAttributeLocation(gl, attributeIndexPosition, "in_Position");
    shaderProgram.BindAttributeLocation(gl, attributeIndexColour, "in_Color");
    shaderProgram.AssertValid(gl);

    //  Create a perspective projection matrix.
    const float rads = (60.0f / 360.0f) * (float)Math.PI * 2.0f;
    projectionMatrix = glm.perspective(rads, Width / Height, 0.1f, 100.0f);

    //  Create a view matrix to move us back a bit.
    viewMatrix =  glm.translate(new mat4(1.0f), new vec3(0.0f, 0.0f, -5.0f));

    //  Create a model matrix to make the model a little bigger.
    modelMatrix = glm.scale(new mat4(1.0f), new vec3(1.0f));

Shader.vert:

#version 150 core

in vec3 in_Position;
in vec3 in_Color;  
out vec3 pass_Color;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;

void main(void) {
    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(in_Position, 1.0);
    pass_Color = in_Color;
}

Mouse move and mouse down handlers:

private int xcursor;
private int ycursor;

private double xrot;
private double yrot;

private void openGLControl_MouseMove(object sender, MouseEventArgs e)
{
    if (MouseButtons == MouseButtons.Left)
    {
        //pressed control and right mouse button
        double dx = 1.0 * (e.X - xcursor) / Width;
        double dy = 1.0 * (e.Y - ycursor) / Height;
        xcursor = e.X;
        ycursor = e.Y;
            xrot += dx * 2;
            yrot += dy * 2;

            viewMatrix =
                glm.rotate(new mat4(1.0f), (float)xrot, new vec3(1.0f, 0.0f, 0.0f)) *
                glm.rotate(new mat4(1.0f), (float)yrot, new vec3(0.0f, 1.0f, 0.0f)) *
                glm.translate(new mat4(1.0f), new vec3(0.0f, 0.0f, -5.0f));

        openGLControl.Invalidate();
    }
}

private void openGLControl_MouseDown(object sender, MouseEventArgs e)
{
    xcursor = e.X;
    ycursor = e.Y;
    openGLControl.Invalidate();
}

On display:

 gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT | OpenGL.GL_STENCIL_BUFFER_BIT);

 shaderProgram.Bind(gl);
 shaderProgram.SetUniformMatrix4(gl, "projectionMatrix", projectionMatrix.to_array());
 shaderProgram.SetUniformMatrix4(gl, "viewMatrix", viewMatrix.to_array());
 shaderProgram.SetUniformMatrix4(gl, "modelMatrix", modelMatrix.to_array());


    gl.BindVertexArray(VAOs[(int)VAO_IDs.Guads]);

    gl.DrawArrays(OpenGL.GL_QUADS, 0, 8);

    shaderProgram.Unbind(gl);
    gl.Flush();
frankie
  • 728
  • 1
  • 10
  • 28
  • Nothing obviously wrong springs out from the code. Can you describe what you are seeing? I know that sometimes the behaviour is sometimes so bizarre that it's hard to describe. – stridecolossus May 06 '14 at 08:54
  • Alternatively, have you tried 'fiddling' the code to test the various parts of the transforms? might help to narrow down the culprit(s), e.g. get rid of the scaling model matrix, does it help? try just hard coding a camera translation, does it work? etc. – stridecolossus May 06 '14 at 08:56

1 Answers1

1

Without more info I think the problem could be the viewMatrix multiplication order, try this:

viewMatrix = glm.translate(new mat4(1.0f), new vec3(0.0f, 0.0f, -5.0f)) *
             glm.rotate(new mat4(1.0f), (float)xrot, new vec3(1.0f, 0.0f, 0.0f)) * 
             glm.rotate(new mat4(1.0f), (float)yrot, new vec3(0.0f, 1.0f, 0.0f));

Normally, you want to perform the scaling first, then the rotation, and then the translation. If you change the order you will get strange results.

You may also want to do your MVP matrix multiplication outside of the shader:

glm::mat4 MVP = projection * view * model;

And then in the shader:

gl_Position = MVP * vec4(in_Position, 1.0);

That way you only compute one matrix multiplication in the shader instead of 3, this is just an optimization, not the cause of the problem.

Luis
  • 678
  • 8
  • 14