【openFrameworks】ofxAssimpModelLoaderで読み込んだCGモデルのテクスチャがうまく表示されない<解決>

目的

  • ofxAssimpModelLoaderで読み込んだCGモデルのテクスチャがうまく表示されない問題を修正する

環境

  • OS: Windows 10 Education
  • oF: of_v0.9.8_vs_release
  • GPU: Quadro 410
  • OpenGL: version 4.1
  • 使用させていただいたCGモデル-> sibenik

サンプルプロジェクト

  • <解法1>テクスチャ読み込み時に正しくWrap設定を行うようにしただけの修正サンプル
  • <解法2>ofMaterialで定義されているシェーダに手を加えてGL_REPEATのような挙動をさせるサンプル

うまく表示されない原因

  • openFrameworksの既定のテクスチャターゲットはTEXTURE_2Dでなく、GL_TEXTURE_RECTANGLE_ARB
  • そしてGL_TEXTURE_RECTANGLE_ARBはNPOT TextureなのでGL_REPEATに対応していない(!)
  • 参考1:ARB_texture_rectangle.txt
6) What texture wrap modes are allowed and what is the default state?

Only the GL_CLAMP, GL_CLAMP_TO_EDGE, and CLAMP_TO_BORDER
wrap modes are allowed. CLAMP_TO_EDGE is the default state.
GL_REPEAT and GL_MIRRORED_REPEAT are not supported with the
GL_TEXTURE_RECTANGLE_ARB texture target.

解法1(GL_TEXTURE_RECTANGLE_ARBを使わない)

  • まずGL_TEXTURE_RECTANGLE_ARBを無効にする(ofApp.cpp)
void setup(){
    ofDisableArbTex();
    <中略>
}
  • 次に、ofxAssimpModelLoaderのテクスチャ読み込み時にGL_TEXTURE_WRAP_*としてGL_REPEATを設定するコードを仕込む(ofxAssimpModelLoaderFix.cpp)
void ofxAssimpModelLoaderFix::loadGLResources() {
    <中略>
    if (AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath)){
        <中略>
        ofTexture texture;
        texture.setTextureWrap(GL_REPEAT, GL_REPEAT);// << added code
        bool bTextureLoadedOk = ofLoadImage(texture, realPath);
        <中略>
    }
    <中略>
}

解法2(GL_TEXTURE_RECTANGLE_ARBを使ったまま)

  • ofMaterialをベースに、そのfragmentShaderを修正してGL_REPEATの機能を持たせる(ofMaterialFix.cpp)
static const string fragmentShaderFixed = R"(// << modified code
    <中略>
    vec2 repeated(in SAMPLER tex, in vec2 texCoord){
        return vec2(mod(texCoord.x,textureSize(tex,0).x),
                    mod(texCoord.y,textureSize(tex,0).y));
    }
    <中略>
    void main (void){
        #ifdef HAS_TEXTURE
            vec4 tex = TEXTURE(tex0, repeated(tex0, outtexcoord));// << added code
        <中略>
    }
    <中略>
);
  • ofxAssimpModelLoaderで"ofMaterial"を使っている部分を、"ofMaterialFix"に置き換える(ofxAssimpModelLoaderFix.*, ofxAssimpMeshHelperFix.h)
  • main.cppでglVersionを上げる(サンプルでは4.1)
int main( ){
    ofGLWindowSettings s;
    s.setGLVersion(4, 1);
    ofCreateWindow(s);

    ofRunApp(new ofApp());
}

おわりに

ヒカテクにコーヒーをおごってみませんか!(投げ銭|Donation

投稿者: hikatech