旋转时形状会变得拉长

时间:2014-12-25 20:49:04

标签: c++ opengl 2d shader box2d

我正在编写一个游戏引擎,它使用box2d来处理碰撞,然后使用矩阵和着色器将所有形状渲染到屏幕上。一切都完美无缺,直到一个形状旋转,此时它会变得拉长。这意味着屏幕上的图形与box2d世界所处的状态不一致。

这是一个没有旋转方块的场景的屏幕截图,旁边有一个相同的方块,一个是旋转的。 Rotation causes stretching

我不确定导致这些问题的原因。 我像这样设置gluPerspective:

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);

    float ratio = (float)WIDTH / (float)HEIGHT;
    gluPerspective(45, ratio, -1, 1);

我将变换矩阵输入到着色器中,如下所示:

float xTranslated = (e->body->GetPosition().x * 100 / SCREEN_WIDTH);
float yTranslated = (e->body->GetPosition().y * 100 / SCREEN_HEIGHT);
float rotated = e->body->GetAngle();

glm::mat4 transform;
transform = glm::translate(transform, glm::vec3(xTranslated, yTranslated, 0.0f));
transform = glm::rotate(transform, rotated, glm::vec3(0.0f, 0.0f, 1.0f));
transform = glm::scale(transform, glm::vec3(1.0f, 1.0f, 1.0f));

GLint transformLoc = glGetUniformLocation(shaderProgram, "trans");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

我将形状顶点初始化如下:

GLfloat * verts = vertices;
GLfloat floatArray[20] = {
    -0.5f * w, 0.5f* h, 1.0f, 0.0f, 1.0f, 
    0.5f * w, 0.5f* h, 1.0f, 0.0f, 1.0f, 
    0.5f * w, -0.5f* h, 1.0f, 0.0f, 1.0f, 
    -0.5f* w, -0.5f* h, 1.0f, 0.0f, 1.0f 
};
for (GLfloat f : floatArray){
    *verts++ = f;
}

顶点着色器如下:

#version 150

in vec2 position;
in vec3 color;

out vec3 Color;

uniform mat4 trans;

void main() {
    Color = color;
    gl_Position = trans * vec4(position, 0.0, 1.0);
}

有人能发现可能导致此问题的事情吗?

1 个答案:

答案 0 :(得分:0)

我设法通过做一些事情来解决我的问题。

首先,我创建了一个投影矩阵,并将其与我的变换矩阵相乘:

glm::mat4 transform, projection, mvp;
transform = glm::translate(transform, glm::vec3(xTranslated, yTranslated, 0.0f));
transform = glm::rotate(transform, rotated, glm::vec3(0.0f, 0.0f, 1.0f));
transform = glm::scale(transform, glm::vec3(1.0f, 1.0f, 1.0f));

projection = glm::ortho(-ASPECT_RATIO, ASPECT_RATIO, -1.0f, 1.0f, -1.0f, 1.0f);

mvp = projection * transform ;

然后我将这个mvp矩阵传递给我的着色器。

我还将所有顶点的x坐标乘以我的屏幕的宽高比:

float xTranslated = (e->body->GetPosition().x * 100 / SCREEN_WIDTH) * ASPECT_RATIO;

在创建顶点缓冲区时也这样做:

GLfloat floatArray[20] = {
    -0.5f * w * ASPECT_RATIO, 0.5f *h, 1.0f, 0.0f, 1.0f, // Top-left
    0.5f *w* ASPECT_RATIO, 0.5f *h, 1.0f, 0.0f, 1.0f, // Top-right
    0.5f *w* ASPECT_RATIO, -0.5f *h, 1.0f, 0.0f, 1.0f, // Bottom-right
    -0.5f *w* ASPECT_RATIO, -0.5f *h, 1.0f, 0.0f, 1.0f  // Bottom-left
};

tada:

Finally Working