4

そこで、ジオメトリ シェーダーを使用して立方体として描画される 100x100x100 ポイントを描画する、非常に単純な OpenGL プログラムを作成しました。DirectX11を使用して現在できることと比較してベンチマークするためにそれをやりたかった.

DirectX11 を使用すると、これらのキューブを 60fps (vsync) で簡単にレンダリングできます。ただし、OpenGL では 40fps にとどまっています。


両方のアプリケーションで、私は:

  • ポイント トポロジを使用して立方体の位置のみを表します (ストライド = 12 バイト)。
  • 初期化関数で Vertex Buffer にマッピングするのは一度だけです。
  • 合計で 2 つの描画呼び出しのみを使用します。1 つはキューブをレンダリングするため、もう 1 つはフレームタイムをレンダリングするためです。
  • バック フェース カリングと深度テストの使用。
  • キューブを描画するために必要な最小限の状態変更を制限します (VBO/シェーダー プログラム)。

ここに私のドローコールがあります:

    GLboolean CCubeApplication::Draw()
    {
        auto program = m_ppBatches[0]->GetShaders()->GetProgram(0);

        program->Bind();
        {
            glUniformMatrix4fv(program->GetUniform("g_uWVP"), 1, false, glm::value_ptr(m_matMatrices[MATRIX_WVP]));
            glDrawArrays(GL_POINTS, 0, m_uiTotal);
        }

        return true;
    }

この関数は、glBindVertexArray と glUseProgram を呼び出します。

program->Bind();

そして残りは簡単です。My Update 関数は、カメラの位置とビュー マトリックスを更新するだけで、DirectX/OpenGL バージョンでも同じです。


頂点シェーダーはパススルーで、フラグメント シェーダーは一定の色を返します。これは私のジオメトリ シェーダーです。

#version 440 core

// GS_LAYOUT
layout(points) in;
layout(triangle_strip, max_vertices = 36) out;

// GS_IN
in vec4 vOut_pos[];

// GS_OUT

// UNIFORMS
uniform mat4 g_uWVP;
const float f = 0.1f;

const int elements[] = int[]
(
    0,2,1,
    2,3,1,

    1,3,5,
    3,7,5,

    5,7,4,
    7,6,4,

    4,6,0,
    6,2,0,

    3,2,7,
    2,6,7,

    5,4,1,
    4,0,1
);

// GS
void main()
{
    vec4 vertices[] = vec4[]
    (
        g_uWVP * (vOut_pos[0] + vec4(-f,-f,-f, 0)),
        g_uWVP * (vOut_pos[0] + vec4(-f,-f,+f, 0)), 
        g_uWVP * (vOut_pos[0] + vec4(-f,+f,-f, 0)), 
        g_uWVP * (vOut_pos[0] + vec4(-f,+f,+f, 0)), 
        g_uWVP * (vOut_pos[0] + vec4(+f,-f,-f, 0)), 
        g_uWVP * (vOut_pos[0] + vec4(+f,-f,+f, 0)), 
        g_uWVP * (vOut_pos[0] + vec4(+f,+f,-f, 0)), 
        g_uWVP * (vOut_pos[0] + vec4(+f,+f,+f, 0))
    );

    uint uiIndex = 0;
    for(uint uiTri = 0; uiTri < 12; ++uiTri)
    {
        for(uint uiVert = 0; uiVert < 3; ++uiVert)
        {
            gl_Position = vertices[elements[uiIndex++]];
            EmitVertex();
        }

        EndPrimitive();
    }
}

インスタンス化やその他のレンダリング方法について人々が話しているのを見てきましたが、私が主に興味を持っているのは、OpenGL から DirectX と同じパフォーマンスを得ることができない理由を理解することです。私とほとんど同じようです。同一のデータ、同一のシェーダー。ヘルプ?


更新 だから私はgDEBuggerをダウンロードしました.1フレームのコールスタックは次のとおりです。

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

// Drawing cubes
glBindVertexArray(1)
glUseProgram(1)

glUniformMatrix4fv(0, 1, FALSE, {matrixData})

glDrawArrays(GL_POINTS, 0, 1000000)

// Drawing text
glBindVertexArray(2);
glUseProgram(5);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 2);

glBindBuffer(GL_ARRAY_BUFFER, 2);
glBufferData(GL_ARRAY_BUFFER, 212992, {textData}, GL_DYNAMIC_DRAW);

glDrawArrays(GL_POINTS, 0, 34);

// Swap buffers
wglSwapBuffers();
4

0 に答える 0