Instanced rendering

shader програмаа үүсгээд авах параметрүүдийг нь тохируулчихсан бол, түүнийг цааш нь дахин дахин олон удаа дуудан ашиглах боломжтой юм.
Дахин дуудахдаа харгалзах байрлал, эргүүлэлт гэх мэтийн uniform утгуудыг өөрчилбөл өмнө рэндэрлэгдсэн объектийг рэндэрлэх мөртөө өөр газар рэндэрлэх боломж бүрдэнэ. GPU дээр upload хийгээд тохируулчихсан өгөгдлүүдийг дахин дахин дуудаж байгаа болохоор их хурдан биелнэ. Яагаад гэвэл төв bus-аар дамжуулж дахин дахин өгөгдөл upload хийхгүй болохоор тэр юм. Жишээ нь програмын үндсэн циклд дараах өөрчлөлтийг хийж болно
int main(int argc, char *argv[]) {
    initialize();
    glfwSetWindowSizeCallback(window, windowSizeChange);
    glfwSetKeyCallback(window, handleKeyboardInput);

    // Z buffering
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    program = Program::Load(vert, NULL, frag);
    mvpUniform = glGetUniformLocation(program, "mvp");
    GLuint modelMatrixUniform = glGetUniformLocation(program, "modelMatrix");
    GLuint viewMatrixUniform = glGetUniformLocation(program, "viewMatrix");
    GLuint lightPositionUniform = glGetUniformLocation(program, "lightPosition_worldspace");

    while (!glfwWindowShouldClose(window)) {
        glfwPollEvents();
        getInput();
        // Clear screen
        glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(program);
        projectionMatrix = glm::perspective(fov, (float) windowWidth / windowHeight, 0.1f, 1000.0f);
        viewMatrix = glm::lookAt(position, position + direction, up);
        modelMatrix = glm::mat4(1.0f);
        glm::mat4 mvp = projectionMatrix * viewMatrix * modelMatrix;
        glUniformMatrix4fv(mvpUniform, 1, GL_FALSE, glm::value_ptr(mvp));
        glUniformMatrix4fv(modelMatrixUniform, 1, GL_FALSE, glm::value_ptr(modelMatrix));
        glUniformMatrix4fv(viewMatrixUniform, 1, GL_FALSE, glm::value_ptr(viewMatrix));
        glm::vec3 lightPosition = glm::vec3(-60, -40, 4);
        glUniform3f(lightPositionUniform, lightPosition.x, lightPosition.y, lightPosition.z);
        glUniform1i(glGetUniformLocation(program, "textureSampler"), 0);
        mesh->render();
        glUseProgram(0);

        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                for (int k = 0; k < 10; k++) {
                    glUseProgram(program);
                    int x_offset = 80;
                    int y_offset = 80;
                    int z_offset = 130;
                    glm::vec3 position1 = position + glm::vec3(i * x_offset, j * y_offset, k * z_offset);
                    viewMatrix = glm::lookAt(position1, position1 + direction, up);
                    modelMatrix = glm::mat4(1.0f);
                    mvp = projectionMatrix * viewMatrix * modelMatrix;
                    glUniformMatrix4fv(mvpUniform, 1, GL_FALSE, glm::value_ptr(mvp));
                    glUniformMatrix4fv(modelMatrixUniform, 1, GL_FALSE, glm::value_ptr(modelMatrix));
                    glUniformMatrix4fv(viewMatrixUniform, 1, GL_FALSE, glm::value_ptr(viewMatrix));
                    glm::vec3 lightPosition1 = lightPosition + glm::vec3(i * x_offset, j * y_offset, k * z_offset);
                    glUniform3f(lightPositionUniform, lightPosition1.x, lightPosition1.y, lightPosition1.z);
                    glUniform1i(glGetUniformLocation(program, "textureSampler"), 0);
                    mesh->render();
                    glUseProgram(0);
                }
            }
        }

        glfwSwapBuffers(window);
    }

    delete mesh;
    glDeleteProgram(program);

    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}






Popular posts from this blog

Apache Spark + Cassandra. Hello World