使用较少的调用切换着色器程序

时间:2017-07-05 17:03:29

标签: performance opengl

目前,每当我想切换着色器时,我都会调用此函数(简化):

<script>
    var chartData; // globar variable for hold chart data
    google.load("visualization", "1", { packages: ["corechart"] });

    // Here We will fill chartData

    $(document).ready(function () {

        $.ajax({
            url: "../../Pages/Test.aspx/GetSentimentData",
            data: "",
            dataType: "json",
            type: "POST",
            contentType: "application/json; chartset=utf-8",
            success: function (data) {
                chartData = data.d;
            },
            error: function () {
                alert("Error loading data! Please try again.");
            }
        }).done(function () {
            // after complete loading data
            google.setOnLoadCallback(drawChart3);
            drawChart3();
        });
    });


    function drawChart3() {
        var data = google.visualization.arrayToDataTable(chartData);

        var options = {
            title: "Distribution of Sentiment Analysis Results",
            hAxis: { title: 'University'},
            vAxis: { title: 'Number of Tweets' },
            pointSize: 5
        };

        var columnChart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
        columnChart.draw(data, options);

    }
</script>

虽然看起来不必要地效率低下。

请注意,此功能仅用于支持在具有相同属性数组集的程序之间切换。

理想情况下,我的代码看起来更像是这样:

void switchToShader(ShaderProgram* newProg, Mesh& mesh) {
    if(m_currentProg != nullptr) {
        m_currentProg->disableAttributeArray("aPos");
    }
    newProg->enableAttributeArray("aPos");
    mesh.vertexPosBuffer()->bind();
    glVertexAttribPointer(newProg->attributeLocation("aPos"), 2, GL_FLOAT, false, 0, 0);

    newProg->bind();

    mesh.indexBuffer()->bind();

    m_currentProg = newProg;
}

但是由于显而易见的原因,这不起作用。

请注意,我的班级ShaderProgram::ShaderProgram() { // ... enableAttributeArray("aPos"); glVertexAttribPointer(newProg->attributeLocation("aPos"), 2, GL_FLOAT, false, 0, 0); } void switchToShader(ShaderProgram* newProg, Mesh& mesh) { mesh.vertexPosBuffer()->bind(); newProg->bind(); mesh.indexBuffer()->bind(); } 来自Qt的QOpenGLShaderProgram

有关如何提高代码效率的任何提示吗?

我知道我可以在着色器程序初始化时使用ShaderProgram强制attrib数组glBindAttribLocation来使用例如位置aPos,对于我的所有着色器程序,这意味着我每帧只能执行一次1并且可以跳过enableAttributeArray。但这有点不优雅,因为它意味着编写一些额外的代码并传递我随意选择的attrib位置。

我目前正在调查VAO。

编辑:在使用glBindAttribLocation和VAO后,我的问题就解决了。我的代码现在看起来像这样:

disableAttributeArray

我甚至可以在此功能之外将着色器程序和VAO彼此独立地绑定。

1 个答案:

答案 0 :(得分:7)

  

但这有点不雅,因为这意味着要写一些额外的代码

然后将其与layout(location = #)一起放入着色器中。那不是“不优雅”;他说“把信息放在哪里”。

  

并通过我任意选择的attrib位置。

然而,你没有问题“通过我的任意选择属性名称”。从代码的角度来看,“aPos”和1之间没有区别。您必须为VAO获取该属性的某种标识符。在这两种情况下,您都可以将其硬编码为特定值;无论是字符串文字还是整数字面意思都没有。

只是如果你使用一个整数,你就不必在改变程序时不断重新创建你的VAO。

QT的将VAO命令放入着色器对象的API是错误的,现在您可以看到确切的原因。程序不应负责启用哪些属性或来自哪些属性。

您知道如何解决问题。所以解决它。