【问题标题】:Cube getting squashed and rendering as trapezium立方体被压扁并呈现为梯形
【发布时间】:2021-06-28 12:59:00
【问题描述】:

我正在尝试使用 OpenGL ES 2.0 渲染一个立方体并沿它的 Y 轴旋转它,但是该立方体不会呈现为立方体,而是呈现为某种非常平坦的梯形。一些显示奇怪行为的图片:

很平:

开始旋转:

轮播中:

旋转后:

我不确定是什么导致了这种奇怪的行为。我正在使用Pigs in a Blanket library 在 PS Vita 上进行渲染。

这些是我的立方体顶点。每行前3个值是顶点数据,后2个值是纹理映射

GLfloat vertices[] = {
    -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
    0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
    0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
    0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
    0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
    0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
    0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
    -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

    -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
    -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
    -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

    0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
    0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
    0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
    0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
    0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
    0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

    -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
    0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
    0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
    0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
    0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
    0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
    0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
    -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
};

这是我的初始化函数。 surface_width = 960surface_height = 544aspect = 1.764706

void TestScene::init(EGLint s_width, EGLint s_height)
{
    surface_height = s_height;
    surface_width = s_width;
    model = glm::mat4(1.0f);
    projection = glm::mat4(1.0f);

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);


    texture.load_texture("app0:assets/wall.jpg");

    if (!shader.load_shaders("app0:shaders/vert.cg", "app0:shaders/frag.cg"))
        sceKernelExitProcess(0);
}

这是我的渲染函数

void TestScene::render(EGLDisplay display, EGLSurface surface, double deltaTime)
{
    glViewport(0, 0, surface_width, surface_height);
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glEnable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture.ID);
    glUseProgram(shader.ID);

    GLint mvpLoc = glGetUniformLocation(shader.ID, "mvp");
    GLint position = glGetAttribLocation(shader.ID, "vPosition");
    GLint texLoc = glGetAttribLocation(shader.ID, "vTexCoord");
    
    GLfloat aspect = (GLfloat)surface_width/(GLfloat)surface_height;
    projection = glm::perspective(glm::radians(camera.Zoom), aspect, 0.1f, 100.0f);
   

    view = camera.GetViewMatrix();
    model = glm::rotate(model, glm::radians(1.0f), glm::vec3(0.0f, -1.0f, 0.0f));

    glm::mat4 mvp = projection * view * model;
    glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, glm::value_ptr(mvp));

    // Bind vertex positions
    glEnableVertexAttribArray(position);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
    // Bind texture positions
    glEnableVertexAttribArray(texLoc);
    glVertexAttribPointer(texLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glDisableVertexAttribArray(position);
    glDisableVertexAttribArray(texLoc);
    eglSwapBuffers(display, surface);
}

我的相机缩放值为45.0f,这是 GetViewMatrix 方法:

glm::mat4 Camera::GetViewMatrix()
{
    return glm::lookAt(Position, Position + Front, Up);
}

最后是着色器: vert.cg

void main
(
uniform float4x4 mvp,
float4 vPosition,
float2 vTexCoord: TEXCOORD0,
out float4 oPosition: POSITION,
out float2 fTexCoord: TEXCOORD
)
{
    oPosition = mul(mvp, vPosition);
    fTexCoord = vTexCoord;
};

片段.cg

float4 main
(
in float2 fTexCoord: TEXCOORD0,
uniform sampler2D texture1: TEXUNIT0
)
{
    float4 col;
    col = tex2D(texture1, fTexCoord);
    return col;
}

我感觉这与我的投影矩阵有关,但我不完全确定。非常感谢任何帮助,谢谢

更新

如果我将 glm::perspective 中的近值从0.1f 更新为1.0f,它会产生更好看但仍然错误的结果,所以我很确定问题出在我的投影矩阵中。我在这里做错了什么?

projection = glm::perspective(glm::radians(camera.Zoom), aspect, 0.1f, 100.0f);

变成

projection = glm::perspective(glm::radians(camera.Zoom), aspect, 1.0f, 100.0f);

对于以下结果:

更宽但仍然不正确 另一个角度 再次

【问题讨论】:

  • 为什么要缩放投影矩阵?删除projection = glm::scale(projection, glm::vec3(aspect, 1.0f, 1.0f));
  • 我这样做是为了让它与屏幕的尺寸保持一致,但老实说我忘记了我确实对它进行了缩放。刚刚删除它并注意到无论如何没有缩放它看起来更好。奇怪的渲染问题仍然存在
  • 在透视投影中考虑aspect

标签: c++ opengl-es opengl-es-2.0 egl


【解决方案1】:

我找到了问题所在。我在垂直着色器中错误地乘以模型视图投影矩阵。

oPosition = mul(mvp, vPosition);

应该是

oPosition = mul(vPosition, mvp);

这适用于接近值0.1f

编辑

另外,缺少的面是由于我的顶点的缠绕顺序不正确。这是一组更正的顶点,它们按顺时针顺序排列glFrontFace(GL_CW);

GLfloat vertices[] = {
        // Back face
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f, // Bottom-left
        0.5f, -0.5f, -0.5f,  1.0f, 0.0f, // bottom-right
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f, // top-right
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f, // top-right
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f, // top-left
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f, // bottom-left
        // Front face
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f, // bottom-left
        0.5f,  0.5f,  0.5f,  1.0f, 1.0f, // top-right
        0.5f, -0.5f,  0.5f,  1.0f, 0.0f, // bottom-right
        0.5f,  0.5f,  0.5f,  1.0f, 1.0f, // top-right
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f, // bottom-left
        -0.5f,  0.5f,  0.5f,  0.0f, 1.0f, // top-left
        // Left face
        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f, // top-right
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f, // bottom-left
        -0.5f,  0.5f, -0.5f,  1.0f, 1.0f, // top-left
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f, // bottom-left
        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f, // top-right
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f, // bottom-right
        // Right face
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f, // top-left
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f, // top-right
        0.5f, -0.5f, -0.5f,  0.0f, 1.0f, // bottom-right
        0.5f, -0.5f, -0.5f,  0.0f, 1.0f, // bottom-right
        0.5f, -0.5f,  0.5f,  0.0f, 0.0f, // bottom-left
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f, // top-left
        // Bottom face
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f, // top-right
        0.5f, -0.5f,  0.5f,  1.0f, 0.0f, // bottom-left
        0.5f, -0.5f, -0.5f,  1.0f, 1.0f, // top-left
        0.5f, -0.5f,  0.5f,  1.0f, 0.0f, // bottom-left
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f, // top-right
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f, // bottom-right
        // Top face
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f, // top-left
        0.5f,  0.5f, -0.5f,  1.0f, 1.0f, // top-right
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f, // bottom-right
        0.5f,  0.5f,  0.5f,  1.0f, 0.0f, // bottom-right
        -0.5f,  0.5f,  0.5f,  0.0f, 0.0f, // bottom-left
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f  // top-left
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-11
    • 1970-01-01
    • 1970-01-01
    • 2015-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多