葵の研究室

HOME


三角形の描画


以下のようになるんですが、こんなものを全て覚える必要はない。 とりあえず気になるのはこのあたり。
    //--------------------------------------------------
    // 頂点シェーダーを登録
    //--------------------------------------------------
    glAttachShader(
        shaderProgram,
        vertexShader
    );

    //--------------------------------------------------
    // フラグメントシェーダーを登録
    //--------------------------------------------------
    glAttachShader(
        shaderProgram,
        fragmentShader
    );
ここは
glAttachShader(
        shaderProgram,
	vertexShader,
        fragmentShader
    );
としたいとこですが、引数三つ取れませんから、二つ書きましょう。
(void*)0
ここもnullptrと同じ意味です。0でもいいですけど先頭から何byte進むかを明示的に示しているだけです。 何を覚えるか。すべて覚える必要はないと書いたけども

OpenGL 三角形で覚えるべき5つ


① vertices

float vertices[]
{
     0.0f,  0.5f, 0.0f,
    -0.5f, -0.5f, 0.0f,
     0.5f, -0.5f, 0.0f
};
役割: 三角形の座標データ 覚えること: x,y,z座標

② glBufferData()

glBufferData(
    GL_ARRAY_BUFFER,
    sizeof(vertices),
    vertices,
    GL_STATIC_DRAW
);
役割: 頂点データをGPUへ送る 覚えること: 「GPUへ送る関数」

③ glVertexAttribPointer()

glVertexAttribPointer(
    0,
    3,
    GL_FLOAT,
    GL_FALSE,
    3*sizeof(float),
    (void*)0
);
役割: 頂点データの読み方を指定 覚えること: 「x,y,zとして読む」

④ glUseProgram()

glUseProgram(shaderProgram);
役割: シェーダーを使う 覚えること: 「GPUプログラム開始」

⑤ glDrawArrays()

glDrawArrays(
    GL_TRIANGLES,
    0,
    3
);
役割: 描画 覚えること: 「実際に描く」
void DrawTriangle()
{
    //--------------------------------------------------
    // 頂点シェーダー
    // GPU上で動くプログラム
    // 頂点の座標を画面へ送る役目
    //--------------------------------------------------
    const char* vertexShaderSource = R"(
    #version 330 core

    // location 0 に頂点座標が入ってくる
    layout (location = 0) in vec3 aPos;

    void main()
    {
        // 頂点座標を画面へ出力
        gl_Position = vec4(aPos, 1.0);
    }
    )";

    //--------------------------------------------------
    // フラグメントシェーダー
    // GPU上で動くプログラム
    // 図形の色を決める役目
    //--------------------------------------------------
    const char* fragmentShaderSource = R"(
    #version 330 core

    // 最終的な色
    out vec4 FragColor;

    void main()
    {
        // 白色
        FragColor = vec4(
            1.0,
            1.0,
            1.0,
            1.0
        );
    }
    )";

    //--------------------------------------------------
    // 頂点シェーダーを作成
    //--------------------------------------------------
    unsigned int vertexShader =
        glCreateShader(GL_VERTEX_SHADER);

    //--------------------------------------------------
    // 頂点シェーダーのソースコードを登録
    //--------------------------------------------------
    glShaderSource(
        vertexShader,
        1,
        &vertexShaderSource,
        nullptr
    );

    //--------------------------------------------------
    // 頂点シェーダーをコンパイル
    //--------------------------------------------------
    glCompileShader(vertexShader);

    //--------------------------------------------------
    // フラグメントシェーダーを作成
    //--------------------------------------------------
    unsigned int fragmentShader =
        glCreateShader(GL_FRAGMENT_SHADER);

    //--------------------------------------------------
    // フラグメントシェーダーのソースコードを登録
    //--------------------------------------------------
    glShaderSource(
        fragmentShader,
        1,
        &fragmentShaderSource,
        nullptr
    );

    //--------------------------------------------------
    // フラグメントシェーダーをコンパイル
    //--------------------------------------------------
    glCompileShader(fragmentShader);

    //--------------------------------------------------
    // シェーダープログラムを作成
    // 頂点シェーダーとフラグメントシェーダーをまとめる
    //--------------------------------------------------
    unsigned int shaderProgram =
        glCreateProgram();

    //--------------------------------------------------
    // 頂点シェーダーを登録
    //--------------------------------------------------
    glAttachShader(
        shaderProgram,
        vertexShader
    );

    //--------------------------------------------------
    // フラグメントシェーダーを登録
    //--------------------------------------------------
    glAttachShader(
        shaderProgram,
        fragmentShader
    );

    //--------------------------------------------------
    // シェーダー同士を結合
    //--------------------------------------------------
    glLinkProgram(shaderProgram);

    //--------------------------------------------------
    // 三角形の頂点座標
    //
    //       (0,0.5)
    //           ▲
    //          / \
    //         /   \
    //        /_____\
    //
    // (-0.5,-0.5)   (0.5,-0.5)
    //--------------------------------------------------
    float vertices[] =
    {
         0.0f,  0.5f, 0.0f,   // 上
        -0.5f, -0.5f, 0.0f,   // 左下
         0.5f, -0.5f, 0.0f    // 右下
    };

    //--------------------------------------------------
    // VAO(Vertex Array Object)
    //
    // 「頂点データの読み方」を保存する箱
    //
    // 例
    // 1頂点は3個のfloat
    // x,y,zの順番
    //
    // といった設定を保存する
    //--------------------------------------------------
    unsigned int VAO;

    //--------------------------------------------------
    // VBO(Vertex Buffer Object)
    //
    // 頂点データ本体を保存する箱
    //
    // 今回だと vertices[] を保存する
    //--------------------------------------------------
    unsigned int VBO;

    //--------------------------------------------------
    // VAOを作成
    //--------------------------------------------------
    glGenVertexArrays(1, &VAO);

    //--------------------------------------------------
    // VBOを作成
    //--------------------------------------------------
    glGenBuffers(1, &VBO);

    //--------------------------------------------------
    // このVAOを使う
    //--------------------------------------------------
    glBindVertexArray(VAO);

    //--------------------------------------------------
    // このVBOを使う
    //--------------------------------------------------
    glBindBuffer(
        GL_ARRAY_BUFFER,
        VBO
    );

    //--------------------------------------------------
    // vertices のデータをGPUへ転送
    //--------------------------------------------------
    glBufferData(
        GL_ARRAY_BUFFER,
        sizeof(vertices),
        vertices,
        GL_STATIC_DRAW
    );

    //--------------------------------------------------
    // 頂点データの読み方を設定
    //
    // location = 0
    //
    // 1頂点 = float 3個
    //
    // x y z
    //--------------------------------------------------
    glVertexAttribPointer(
        0,
        3,
        GL_FLOAT,
        GL_FALSE,
        3 * sizeof(float),
        (void*)0
    );

    //--------------------------------------------------
    // location = 0 を有効化
    //--------------------------------------------------
    glEnableVertexAttribArray(0);

    //--------------------------------------------------
    // このシェーダープログラムを使用
    //--------------------------------------------------
    glUseProgram(shaderProgram);

    //--------------------------------------------------
    // 三角形描画
    //
    // GL_TRIANGLES
    //   三角形として描く
    //
    // 0
    //   頂点0番から開始
    //
    // 3
    //   頂点3個使用
    //--------------------------------------------------
    glDrawArrays(
        GL_TRIANGLES,
        0,
        3
    );
}