Page 1 of 6 123 ... LastLast
Results 1 to 10 of 56

Thread: OpenGL 3.x Rotation Problem

  1. #1

    OpenGL 3.x Rotation Problem

    Hello.

    I've been struggling with this problem for about two weeks now and was unable to find a solution. This is my first attempt at OpenGL 3.x programming, so I may be doing something wrong.

    I'm trying to make a simple spinning triangle demo with a camera the user can move and use the mouse to look around the world. Here's how the triangle is created:
    [code=delphi]
    procedure TMainForm.InitializeOpenGL;
    var
    Vert: array[0..8] of Single;
    begin
    { ... }
    Vert[0] := -0.3;
    Vert[1] := 0.5;
    Vert[2] := -1.0;
    Vert[3] := -0.8;
    Vert[4] := -0.5;
    Vert[5] := -1.0;
    Vert[6] := 0.2;
    Vert[7] := -0.5;
    Vert[8] := -1.0;

    TriangleRot := 0.0;

    glGenVertexArrays(1, @TriangleVAO);
    glBindVertexArray(TriangleVAO);
    glGenBuffers(1, @TriangleVBO);
    glBindBuffer(GL_ARRAY_BUFFER, TriangleVBO);
    glBufferData(GL_ARRAY_BUFFER, 9 * SizeOf(Single), @Vert, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, nil);
    glEnableVertexAttribArray(0);
    glBindVertexArray(0);
    end;
    [/code]

    And now here's the Render procedure which renders my scene:
    [code=delphi]
    var
    ProjMat, Cam, ModelView: TMatrix;
    begin
    glViewport(0, 0, ClientWidth, ClientHeight);
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

    // Projection update
    if (ClientHeight <= 0) then
    ClientHeight := 1;
    ProjMat := MatrixProjection(40.0, ClientWidth / ClientHeight, 0.1, 1000.0);
    glUniformMatrix4fv(glGetUniformLocation(ShaderMana ger.GLSLPrograms['minimal'].
    ProgramHandle, 'projectionMatrix'), 1, ByteBool(GL_FALSE), @ProjMat);

    // Camera transformations
    Cam := MatrixTransform(VectorNegate(Camera.Pos), VectorUniform(0.0),
    VectorUniform(1.0));
    ModelView := MatrixTransform(VectorUniform(0.0), VectorCreate(0.0, TriangleRot, 0.0), VectorUniform(1.0));
    ModelView := MatrixMultiply(ModelView, Cam);
    glUniformMatrix4fv(glGetUniformLocation(ShaderMana ger.GLSLPrograms['minimal'].
    ProgramHandle, 'modelViewMatrix'), 1, ByteBool(GL_FALSE), @ModelView);

    glBindVertexArray(TriangleVAO);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glBindVertexArray(0);
    end;
    [/code]

    Here's what gets rendered: http://www.youtube.com/watch?v=o9LDivwjUx0

    But instead, I'd like the triangle to spin around itself. JSoftware provided me with a vector that indicates the center of rotation of the triangle. So, using it here:
    [code=delphi]
    ModelView := MatrixTransform(VectorCreate(0.3, 5.0 / 3.0, 1.0),
    VectorCreate(0.0, TriangleRot, 0.0), VectorUniform(1.0));
    ModelView := MatrixMultiply(ModelView, Cam);
    [/code]
    I get: http://www.youtube.com/watch?v=aQleDlo5li8

    Everything is OK, but the object is not placed at (0,0,0), which is the point I want it to be put at.

    How do I change the code so that it spins around itself and stays at (0,0,0)?

    If you blame my matrix code, here's the whole unit: http://www.nopaste.pl/Source/m6s.txt

  2. #2

    Re: OpenGL 3.x Rotation Problem

    By looking at the coordinates of your triangle, the center is approx. at (-0.3, 0.0, -1.0). Therefore the first video makes sense to me.

    What I would do, is define the triangle with it's center at (0,0,0). You could do the following:
    [pascal]
    //top vertex
    Vert[0] := 0.0;
    Vert[1] := 0.5;
    Vert[2] := 0.0;

    //right vertex (I think LOL )
    Vert[3] := -0.3;
    Vert[4] := -0.5;
    Vert[5] := 0.0;

    //left vertex
    Vert[6] := 0.3;
    Vert[7] := -0.5;
    Vert[8] := 0.0;
    [/pascal]

    It's common to define objects with their center at (0,0,0). If you want them to appear somewhere else, you just change the model matrix.
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  3. #3

    Re: OpenGL 3.x Rotation Problem

    Using your code and this:
    [code=delphi]
    Cam := MatrixTransform(VectorNegate(Camera.Pos), VectorUniform(0.0),
    VectorUniform(1.0));
    ModelView := MatrixTransform(VectorCreate(0.0, 0.0, 1.0), VectorCreate(0.0, TriangleRot, 0.0), VectorUniform(1.0));
    ModelView := MatrixMultiply(ModelView, Cam);
    glUniformMatrix4fv(glGetUniformLocation(ShaderMana ger.GLSLPrograms['minimal'].
    ProgramHandle, 'modelViewMatrix'), 1, ByteBool(GL_FALSE), @ModelView);
    [/code]
    I still have the triangle not spinning around itself.

    What could be the matter? I even tried to use the vertices as given here, but still when I want to place the object at (0,0,0), it rotates wrong.

  4. #4

    Re: OpenGL 3.x Rotation Problem

    Use his coordinates and this:
    [code=delphi]
    Cam := MatrixTransform(VectorNegate(Camera.Pos), VectorUniform(0.0),
    VectorUniform(1.0));
    ModelView := MatrixTransform(VectorCreate(0.0, 0.0, 0.0), VectorCreate(0.0, TriangleRot, 0.0), VectorUniform(1.0));
    ModelView := MatrixMultiply(ModelView, Cam);
    glUniformMatrix4fv(glGetUniformLocation(ShaderMana ger.GLSLPrograms['minimal'].
    ProgramHandle, 'modelViewMatrix'), 1, ByteBool(GL_FALSE), @ModelView);
    [/code]
    Peregrinus, expectavi pedes meos in cymbalis
    Nullus norvegicorum sole urinat

  5. #5

    Re: OpenGL 3.x Rotation Problem

    I tried those coords:
    [code=delphi]
    Vert[0] := 0.0;
    Vert[1] := 1.0;
    Vert[2] := 0.0;
    Vert[3] := -1.0;
    Vert[4] := -1.0;
    Vert[5] := 0.0;
    Vert[6] := 1.0;
    Vert[7] := -1.0;
    Vert[8] := 0.0;
    [/code]
    Matrix code:
    [code=delphi]
    Cam := MatrixTransform(VectorNegate(Camera.Pos), VectorUniform(0.0),
    VectorUniform(1.0));
    ModelView := MatrixTransform(VectorCreate(0.0, 0.0, 0.0),
    VectorCreate(0.0, TriangleRot, 0.0), VectorUniform(0.5));
    ModelView := MatrixMultiply(ModelView, Cam);
    glUniformMatrix4fv(glGetUniformLocation(ShaderMana ger.GLSLPrograms['minimal'].
    ProgramHandle, 'modelViewMatrix'), 1, ByteBool(GL_FALSE), @ModelView);
    [/code]
    And changed the MatrixTransform function back to its original form:
    Code:
    { .: MatrixTransform :. }
    function MatrixTransform(const Position, Rotation, Scale: TVector): TMatrix;
    var
     CosRx, CosRy, CosRz: Single;
     SinRx, SinRy, SinRz: Single;
    begin
     CosRx := Cos(Rotation.X); // Used 6x
     CosRy := Cos(Rotation.Y); // Used 4x
     CosRz := Cos(Rotation.Z); // Used 4x
     SinRx := Sin(Rotation.X); // Used 5x
     SinRy := Sin(Rotation.Y); // Used 5x
     SinRz := Sin(Rotation.Z); // Used 5x
     Result := MatrixIdentity;
    
     with Result do
     begin
      _11 := CosRy * CosRz * Scale.X;
      _12 := CosRy * SinRz * Scale.X;
      _13 := -SinRy * Scale.X;
    
      _21 := (CosRz * SinRx * SinRy * Scale.Y) - (CosRx * SinRz * Scale.Y);
      _22 := (CosRx * CosRz * Scale.Y) + (SinRx * SinRy * SinRz * Scale.Y);
      _23 := CosRy * SinRx * Scale.Y;
    
      _31 := (CosRx * CosRz * SinRy * Scale.Z) + (SinRx * SinRz * Scale.Z);
      _32 := (-CosRz * SinRx * Scale.Z) + (CosRx * SinRy * SinRz * Scale.Z);
      _33 := CosRx * CosRy * Scale.Z;
    
      _41 := Position.X;
      _42 := Position.Y;
      _43 := Position.Z;
     end;
    end;
    And it worked! It even worked when I changed the coordinates to (3,0,0), so this approach seems to be working well.

    Can someone explain why it does work and what I should do to avoid such mistakes in the future?

  6. #6

    Re: OpenGL 3.x Rotation Problem

    You have to understand what MatrixTransform() does. It first translates, then rotates, then translates back and finally it scales. If you use (0,0,0) as the first vector, it will only rotate and scale. If you use (1,1,1) (which is VectorUniform(1.0) ) as the scaling matrix, you will only have rotation left. However, if you only need rotation, using the MatrixTransform() routine is overkill.

    What you want to do, is rotate about the center of something. In that case you have to determine where the center is. Then you have to move your geometry in such a way that the center lies at (0,0,0) before rotating. The code in your startpost seems to look right.

    I'd suggest you to play with this for a while. Understanding matrices is quite hard (for me too). Just start off with the code in your startpost (corresponding to the first youtube movie). Make sure to keep in mind what MatrixTransform() does exactly.

    Good luck.
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  7. #7

    Re: OpenGL 3.x Rotation Problem

    I think the problem was with the center of the triangle I drawn before. After correcting the vertices, the code works ok. Next time, just as you suggested, I must "center" my objects at (0,0,0) and then move them around using appropiate matrix translations.

    Anyway, I think you guys helped me work it out. Thank you very much, I'd not guess the vertices were the case of my problems.

    EDIT
    Nevertheless, getting it all done is tricky. After I'm done with a basic mouse-looking example, I'll post the code on the board.

  8. #8

    Re: OpenGL 3.x Rotation Problem

    Hello again.

    I noticed that the code does not entirely do what I want it to. The thing is that the code doesn't behave like it takes the camera into account.

    I mean the part of the code where the camera transformation is calculated. I changed it a little to include the rotation of the camera. Here's the changed part:
    [code=delphi]
    // Camera transformations
    Cam := MatrixTransform(VectorNegate(Camera.Pos), VectorCreate(Camera.Pitch,
    Camera.Yaw, 0.0), VectorUniform(1.0));
    ModelView := MatrixTransform(VectorCreate(0.0, 0.0, 0.0),
    VectorCreate(0.0, TriangleRot, 0.0), VectorUniform(0.5));
    ModelView := MatrixMultiply(ModelView, Cam);
    ModelView := MatrixMultiply(ModelView, ProjMat);

    // Update the shader
    glUniformMatrix4fv(glGetUniformLocation(ShaderMana ger.GLSLPrograms['minimal'].
    ProgramHandle, 'mvpmatrix'), 1, ByteBool(GL_FALSE), @ModelView);
    [/code]
    The new code of my vertex shader:
    [code=c++]
    #version 150

    precision highp float;

    uniform mat4 mvpmatrix;

    in vec3 in_Position;
    in vec3 in_Color;

    out vec3 ex_Color;
    void main(void) {
    gl_Position = mvpmatrix * vec4(in_Position, 1.0);

    ex_Color = in_Color;
    }
    [/code]

    Changing the values Pitch and Yaw doesn't really rotate the camera, but the object on the contrary. How do I change the code? Any suggestions?

    BTW, before I changed the shader code, it didn't work as well.

  9. #9

    Re: OpenGL 3.x Rotation Problem

    I believe you are doing it in the wrong order. Remember order of matrix operations are critical

    Normally in OpenGL you have:
    ProjectionMatrix*ModelViewMatrix*matrix1*matrix2.. .

    [code=delphi]
    // Camera transformations
    Cam := MatrixTransform(VectorNegate(Camera.Pos), VectorCreate(Camera.Pitch, Camera.Yaw, 0.0), VectorUniform(1.0)); //"Camera" transformation
    ModelView2 := MatrixTransform(VectorCreate(0.0, 0.0, 0.0), VectorCreate(0.0, TriangleRot, 0.0), VectorUniform(0.5)); //Object transformation
    ModelView := MatrixMultiply(ProjMat, MatrixMultiply(ModelView2, Modelview));

    // Update the shader
    glUniformMatrix4fv(glGetUniformLocation(ShaderMana ger.GLSLPrograms['minimal'].
    ProgramHandle, 'mvpmatrix'), 1, ByteBool(GL_FALSE), @ModelView);
    [/code]
    Peregrinus, expectavi pedes meos in cymbalis
    Nullus norvegicorum sole urinat

  10. #10

    Re: OpenGL 3.x Rotation Problem

    Shouldn't this:
    [code=delphi]
    ModelView := MatrixMultiply(ProjMat, MatrixMultiply(ModelView2, Modelview));
    [/code]
    be
    [code=delphi]
    ModelView := MatrixMultiply(ProjMat, MatrixMultiply(ModelView2, Cam));
    [/code]
    instead?

Page 1 of 6 123 ... LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •