用鼠标旋转(矩阵和着色器)

时间:2014-05-06 07:52:04

标签: c# opengl matrix shader sharpgl

我试图用鼠标旋转我的模型。结果我看起来像旋转,但它很奇怪,出乎意料的表现。

我建议错误在我的矩阵设置或鼠标事件处理程序中的某处。但我无法弄清楚在哪里。

我的初始化代码:

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

鼠标移动和鼠标按下处理程序:

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

显示屏:

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

1 个答案:

答案 0 :(得分:1)

没有更多信息我认为问题可能是viewMatrix乘法顺序,试试这个:

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

通常,您希望首先执行缩放,然后执行旋转,然后执行平移。如果您更改订单,您将得到奇怪的结果。

您可能还想在着色器之外进行MVP矩阵乘法:

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

然后在着色器中:

gl_Position = MVP * vec4(in_Position, 1.0);

这样你只在着色器中计算一个矩阵乘法而不是3,这只是一个优化,而不是问题的原因。