OpenGL形状仅在初始位置为(0,0,0)时绘制

时间:2014-11-26 22:56:16

标签: c++ opengl graphics

我有一个从OBJ文件加载的多维数据集。当我的位置(0,0,0)一切正常。立方体渲染,我的赋予它速度的函数将立方体移动到屏幕上。但是,如果在进入我渲染和计算速度变化的while循环之前将立方体的位置更改为(0,0,0)以外的其他位置,则立方体永远不会渲染。这是我第一次尝试在每次渲染帧时重新加载顶点,而我假设我搞砸了一些东西 - 但是我已经查看了其他代码并且无法弄清楚是什么。 / p>

这是我的主要功能:

int main()
{
#ifdef TESTING
    testing();
    exit(0);
#endif

    setupAndInitializeWindow(768, 480, "Final Project");

    TriangleTriangleCollision collisionDetector;

    Asset cube1("cube.obj", "vertexShader.txt", "fragmentShader.txt");

    cube1.position = glm::vec3(0.0, 2.0, 0.0);
    cube1.velocity = glm::vec3(0.0, -0.004, 0.0);

    MVP = projection * view * model;

    do{
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        moveAsset(cube1);

        renderAsset(cube1);

        glfwSwapBuffers(window);
        glfwPollEvents();

    } while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
        glfwWindowShouldClose(window) == 0);

    glfwTerminate();

    return 0;
}

我的moveAsset功能:

void moveAsset(Asset &asset)
{
    double currentTime = glfwGetTime();

    asset.position.x += (asset.velocity.x * (currentTime - asset.lastTime));
    asset.position.y += (asset.velocity.y * (currentTime - asset.lastTime));
    asset.position.z += (asset.velocity.z * (currentTime - asset.lastTime));

    for (glm::vec3 &vertex : asset.vertices)
    {
        glm::vec4 transformedVector = glm::translate(glm::mat4(1.0f), asset.position) * glm::vec4(vertex.x, vertex.y, vertex.z, 1);
        vertex = glm::vec3(transformedVector.x, transformedVector.y, transformedVector.z);
    }

    asset.lastTime = glfwGetTime();
}

void renderAsset(Asset asset)
{   
    glUseProgram(asset.programID);

    GLuint MatrixID = glGetUniformLocation(asset.programID, "MVP");
    glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, asset.vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, asset.vertices.size() * sizeof(glm::vec3), &asset.vertices[0], GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glDrawArrays(GL_TRIANGLES, 0, asset.vertices.size());

    glDisableVertexAttribArray(0);
}

我的模型,视图和投影矩阵定义为:

glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = glm::lookAt(glm::vec3(5, 5, 10),
                            glm::vec3(0, 0, 0),
                            glm::vec3(0, 1, 0));
glm::mat4 projection = glm::perspective(45.0f, (float) _windowWidth / _windowHeight, 0.1f, 100.0f);

最后,我的Asset struct:

struct Asset
{
    Asset() { }
    Asset(std::string assetOBJFile, std::string vertexShader, std::string fragmentShader)
    {
        glGenVertexArrays(1, &vertexArrayID);
        glBindVertexArray(vertexArrayID);

        programID = LoadShaders(vertexShader.c_str(), fragmentShader.c_str());

        // Read our .obj file
        std::vector<glm::vec2> uvs;
        std::vector<glm::vec3> normals;
        loadOBJ(assetOBJFile.c_str(), vertices, uvs, normals);

        // Load it into a VBO
        glGenBuffers(1, &vertexbuffer);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);

        //velocity = glm::vec3(0.0, 1.0, 1.0);
        velocity = glm::vec3(0.0, 0.0, 0.0);
        position = glm::vec3(0.0, 0.0, 0.0);

        lastTime = glfwGetTime();
    }

    GLuint vertexArrayID;
    GLuint programID;

    GLuint vertexbuffer;

    std::vector<glm::vec3> faces;
    std::vector<glm::vec3> vertices;

    glm::vec3 velocity;

    double lastTime;
    glm::vec3 position;
};

1 个答案:

答案 0 :(得分:0)

您似乎在每次迭代时将当前asset.position添加到顶点位置 ,替换之前的位置。来自moveAsset()函数:

for (glm::vec3 &vertex : asset.vertices)
{
    glm::vec4 transformedVector = glm::translate(glm::mat4(1.0f), asset.position) *
                                  glm::vec4(vertex.x, vertex.y, vertex.z, 1);
    vertex = glm::vec3(transformedVector.x, transformedVector.y, transformedVector.z);
}

暂时忽略速度,并假设原始顶点位于(0,0,0),您将在第一次迭代时将其移动到asset.position。然后在第二次迭代时再次添加asset.position,将其置于2 * asset.position。然后在第三次迭代中,再次将asset.position添加到此当前位置,结果为3 * asset.position。因此,在n步后,顶点将在n * asset.position附近。即使您的对象最初可见,它也会在您可以闪烁之前移出可见范围。

要使原始策略有效,最直接的方法是拥有两个顶点列表。一个列表包含您永远不会更改的原始对象坐标。然后在绘制之前,构建第二个顶点列表,计算为原始顶点加上当前asset.position的总和,并使用第二个列表进行渲染。

整个事情是......不是很OpenGL。实际上不需要修改CPU上的顶点坐标。您可以在顶点着色器中应用变换的平移部分。您已经有了模型矩阵。您可以简单地将asset.position的翻译放入模型矩阵中,然后重新计算MVP矩阵。您已经有glUniformMatix4fv()调用将新矩阵传递到renderAsset()函数中的着色器程序。