ATMWRIによるUE5の記録

Unreal Engine 5 を使い始めました

C++入門者がOpenGLでハマったポイント〜Hello Triangle辺り

開発環境を構築できたら後はチュートリアルサイトや動画の指示に従えば躓くことは無いはず。ただ理解不足で適当なことをやるとどこが悪いのかわからなくなってハマる。

1. 三角形が表示されなかった

VAOとVBOに対する理解不足でGLuint VAO, VBO;こう一括で宣言してやるのが気に入らずこんな書き方をしてしまった。VAOは頂点データでも入っているんだろうという認識だった。だったらVBOにはUV用のデータでもいれてやれと。

    // Create Vertex Array Object
    GLuint VAO;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5* sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // Create Vertex Buffer Object -- TexCoords
    GLuint VBO;
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void*)(3*sizeof(float)));
    glEnableVertexAttribArray(1);

正しくはその時点でバインドされているVAOに対して生成したVBOに格納したデータを指すポインタglVertexAttribPointerを渡すのでこうなる。VAOは様々な頂点データ(座標・カラー・テクスチャ座標)に対する属性を取りまとめる役割があるようだ。

    // Create Vertex Array Object
    GLuint VAO;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    // Create Vertex Buffer Object: Pos - TexCoords
    GLuint VBO;
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5* sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void*)(3*sizeof(float)));
    glEnableVertexAttribArray(1);

2. テクスチャが表示されなかった

頂点シェーダープログラムのタイプミス

TexCoordのタイプをvec3と無意識にやってしまっていた。VSCode拡張でShader languages support for VS Codeを入れるきっかけになる。がこの手のタイプミスは防げなさそう。

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;  // vec3にしていたら当然動かなかった

コピペミス

エラーは出ていないのにtexture1,2がビルド直後は表示されても次のlaunchでは表示されない imageloaderの不具合を疑ってfilepathを相対から絶対アドレスに変更したりしても徒労に終わった GDBを使おうと思ってCMakeLists.txtへtarget_compile_optionsを追加-Wall -g -O0でビルドすると警告してくれた

warning: ‘texture2’ may be used uninitialized in this function [-Wmaybe-uninitialized]

該当する箇所は2枚目のテクスチャを生成する手前

    GLuint texture2;
    glGenTextures(2, &texture1);    <-------------ここに警告
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

見たまんまtexture2の参照用intを使用せずにtexture1を使ってしまっていた。ただのタイプミスというかコピペミス。

3. まとめ

入門用のコードなら-Wall付けなくてもいいかと面倒くさがっていた。というかCMakeListsでコンパイラオプションを設定するのを後回しにしていた。-Wallがついていれば一瞬で解決するミスを数日掛けて追いかけていた。悲しい。