Неправильный поворот с использованием openGL GLM и шейдеров

Цель моей программы - отобразить простой цветной треугольник, вращающийся по оси Y без какого-либо перевода. Я использую библиотеку GLM. Проблема в том, что преобразования моего треугольника некорректны: он ведет себя странно и нелогично. Вот мой код на C ++ плюс код вершинного шейдера и фрагментного шейдера:

Код C ++:

float angle = 0.0f;

struct Vertex
{
    float x, y, z;
};

static Vertex vertices[9] =
{
    -1.000000f, 0.000000f, 0.000000f,
    0.000000f, 1.000000f, 0.000000f,
    1.000000f, 0.000000f, 0.000000f
};

static Vertex colors[9] =
{
    1.000000f, 0.000000f, 0.000000f,
    0.000000f, 1.000000f, 0.000000f,
    0.000000f, 0.000000f, 1.000000f
};

[...]

int                 
main(int ac, char **av)
{
    bool            continuer = true;
    SDL_Event       event;
    GLuint          vboID[2];
    GLuint          programID = 0;

    //SDL window initialization

    SDL_Init(SDL_INIT_VIDEO);
    SDL_WM_SetCaption("VBO tests",NULL);
    SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_OPENGL);

    //Viewport initialization

    glViewport(0, 0, WIDTH, HEIGHT);

    //Projection initialization

    glm::mat4 projection = glm::mat4(1.0f);
    projection = glm::perspective<GLfloat>(60.0f, (float)(WIDTH/HEIGHT), 1.0f, 1000.0f);

    //View initialization

    glm::mat4 view = glm::lookAt<GLfloat>(glm::vec3(0.0f, 0.0f, 8.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

    glewInit();

    //Shaders initialization

    programID = initShaders("triangle.vert", "triangle.frag");

    //Main loop

    while (continuer)
    {
        eventListener(&event, &continuer);

        glClearDepth(1.0f);
        glClearColor(0.13f, 0.12f, 0.13f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(programID);

        //Model transformations

        glm::mat4 model = glm::mat4(1.0f);
        model *= glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));
        model *= glm::rotate(model, angle, glm::vec3(0.0f, 1.0f, 0.0f));

        glm::mat4 ModelViewMatrix = model * view;
        glm::mat4 ModelViewProjectionMatrix = projection * ModelViewMatrix;

        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, colors);

        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);

        glUniformMatrix4fv(glGetUniformLocation(programID, "ModelView"), 1, GL_TRUE, glm::value_ptr(ModelViewMatrix));
        glUniformMatrix4fv(glGetUniformLocation(programID, "MVP"), 1, GL_TRUE, glm::value_ptr(ModelViewProjectionMatrix));

        glDrawArrays(GL_TRIANGLES, 0, 3);

        glDisableVertexAttribArray(1);
        glDisableVertexAttribArray(0);

        glUseProgram(0);

        angle += 0.020f;

        glFlush();
        SDL_GL_SwapBuffers();
    }

    SDL_Quit();
    return (0);
}

Код вершинного шейдера:

#version 330

in vec3 VertexPosition;
in vec3 VertexColor;

uniform mat4 ModelViewMatrix;
uniform mat4 MVP;

out vec3 Color;

void main()
{
    Color = VertexColor;

    gl_Position = MVP * vec4(VertexPosition, 1.0f);
}

Код фрагментного шейдера:

#version 330

in vec3 Color;
out vec4 FragColor;

void main() {
    FragColor = vec4(Color, 1.0);
}

Когда я объявляю простой поворот матрицы для модели, я отправляю его в вершинный шейдер, использую как MVP, и он работает. Но когда я добавляю матрицу проекции + матрицу просмотра, она работает некорректно. Вот картинка:

введите описание изображения здесь

Обычно треугольник должен находиться в центре экрана.

Кто-нибудь может мне помочь?


person user1364743    schedule 04.04.2013    source источник
comment
Что вы имеете в виду, когда говорите, что когда я добавляю матрицу проекции + матрицу просмотра, она работает неправильно? К чему это добавить? Что не работает правильно? Что ты видишь на экране?   -  person PowerApp101    schedule 05.04.2013
comment
Я хотел сказать, что когда я объединяю вид, проекцию и матрицу модели вместе, у меня на картинке выше плохой рендер. Но когда я стираю представление и проекцию в своем коде и оставляю только матрицу преобразования модели, все работает. Треугольник, конечно, ближе, потому что у меня нет обзора и проекции, но он правильно вращается вокруг оси Y. Я хочу иметь такое же поведение, но с матрицей проекции и вида. Мне кажется, мой код вам подходит? (c ++ и вершинный шейдер)   -  person user1364743    schedule 05.04.2013
comment
Не могли бы вы опубликовать код, в котором вы создаете свои матрицы вида и проекции и где вы умножаете свои матрицы вместе?   -  person bwroga    schedule 05.04.2013


Ответы (1)


Эта строка:

glm::mat4 ModelViewMatrix = model * view;

Вероятно, следует прочитать:

glm::mat4 ModelViewMatrix = view * model;

Вычисления матриц выполняются в обратном порядке, и вы хотите сначала умножить свою вершину на матрицу модели, а не на представление.

Вы также можете взглянуть на мой другой ответ, немного объясняя эти концепции.

person Bartek Banachewicz    schedule 05.04.2013