-1

非常に単純な .obj モデル ローダーを C++ で記述しようとしましたが、両方の方法でモデルが正しく表示されず、2 つの方法のどちらが高速で優れているか、またその理由を知りたいです。これは私の最初の方法です:

    //vertices&indices are private members of the class "Model"
    //same with size and indexCount

void Model::loadModel(std::string source)
{
    using namespace std;

    string name = source.substr(0,source.find('.'));
    cout<<"===LOADING: "<<name<<"==="<<endl;

    ifstream file;
    file.open(source);
    string line,v0="",v1="",v2="";
    string v3="",v4="",v5="";
    int indexCount = 0;
    while(file.good())
    {
        getline(file,line);
        if(line[0] =='v') size++;
        if(line[0] =='f') indexCount++;
    }
    file.close();
    size *= 3;
    vertices = new float[size];
    indexSize = indexCount*3;
    indices = new short[indexSize];
    int count = 0;
    int indexCountForFilling =0;
    file.open(source);
    while(file.good())
    {
        getline(file,line);
        if(line[0] == 'v')
        {
            line = line.substr(2,line.length());
            int oldindex =0;

            v0 = line.substr(0,line.find(" "));
            v1 = line.substr(line.find(" "),line.rfind(" ",line.find(" ")));
            v2 = line.substr(line.rfind(" ",line.find(" ")),line.length());
            v2 = v2.substr(line.find(" ")+2,v2.length());

            //1
            float temp = atof(v0.c_str());
            vertices[count] = temp;
            count++;
            //2
            temp = atof(v1.c_str());
            vertices[count] = temp;
            count++;
            //3
            temp = atof(v2.c_str());
            vertices[count] = temp;
            count++;
        }
        else if(line[0] == 'f')
        {
            line = line.substr(2,line.length());

            int firstIndex = line.find(" ");
            v3 = line.substr(0,firstIndex);
            line = line.substr(firstIndex+1,line.length()); //+1 to skip space

            int secondIndex = line.find(" "); 
            v4 = line.substr(0,secondIndex);
            line = line.substr(secondIndex,line.length());

            if(secondIndex+1>=line.length())
                v5 = line.substr(0,line.length()); 
            else
                v5 = line.substr(1,line.length()); //zelfde
            //1
            short temp = atof(v3.c_str());
            indices[indexCountForFilling] = temp;
            indexCountForFilling++;
            //2
            temp = atof(v4.c_str());
            indices[indexCountForFilling] = temp;
            indexCountForFilling++;
            //3
            temp = atof(v5.c_str());
            indices[indexCountForFilling] = temp;
            indexCountForFilling++;
        }
    }
    cout<<"Amount of vertices: "<<size<<endl;
    cout<<"Amount of indexes: "<<indexCountForFilling<<endl;
    cout<<"===ENDED LOADING: "<<name<<"==="<<endl;
    file.close();
}

これは、文字列ストリームを使用する 2 番目の方法です。

void Model::loadModel2(std::string source)
{
    using namespace std;
    string name = source.substr(0,source.find("."));
    cout<<"+++LOADING::"<<name<<"+++"<<endl;

    ifstream file;
    file.open(source);
    string line;
    while(file.good())
    {
        getline(file,line);
        if(line[0]=='v') size++;
        if(line[0]=='f') indexSize++;
    }
    size *= 3;
    vertices = new GLfloat[size];
    indexSize *= 3;
    indices = new GLshort[indexSize];
    cout<<"\tSize: "<<size<<endl;
    cout<<"\tIndexSize:"<<indexSize<<endl;
    file.close();
    file.open(source);
    int count = 0;
    int index = 0;
    while(file.good())
    {
        getline(file,line);
        istringstream in(line);
        string type;
        in>>type;
        if(type=="v")
        { 
            float x,y,z;
            in >> x >> y >> z;
            vertices[count++] = x;
            vertices[count++] = y;
            vertices[count++] = z;
        }
        else if(type == "f")
        {
            float x,y,z;
            in >> x >> y >> z;
            indices[index++] = x;
            indices[index++] = y;
            indices[index++] = z;
        }
    }
    file.close();

    cout<<"+++ENDED LOADING:"<<name<<"+++"<<endl;
}

これは、両方が初期化されるコードです。

glGenBuffers(1,&vbo);
    glBindBuffer(GL_ARRAY_BUFFER,vbo);
    GLfloat model_test[834]; //834
    memset(model_test,0.0f,sizeof(model_test));
    for(unsigned int i=0;i<834;i++) model_test[i] = model.getIndex(i);
    glBufferData(GL_ARRAY_BUFFER,sizeof(model_test),&model_test,GL_STATIC_DRAW);

    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,BUFFER_OFFSET(0));
    glEnableVertexAttribArray(0);

    GLuint ibo;
    glGenBuffers(1,&ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo);
    GLshort indices[1656];//1656
    memset(indices,0,sizeof(indices));
    for(int i=0;i<1656;i++) indices[i] = model.getVertexIndex(i);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),&indices,GL_STATIC_DRAW);

最後に、これがレンダリングされるコードです。

glBindVertexArray(vao);
    if(rasterize)glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
    else glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
    glDrawElements(GL_TRIANGLES,model.getIndexSize(),GL_UNSIGNED_SHORT,0);

これは私が得るべき結果です:

http://imgur.com/OGGDLFq

これは私が得る結果です:

http://imgur.com/U9ZTGsG

ご覧のとおり、最後のいくつかの三角形までほぼ完全にロードされます

結論として、私の2つの質問は次のとおりです。

- Which of the 2 methods is the best way to load from a txt file?

- Am I doing something wrong with the rendering?

編集:間違ったインデックスを使用していると思いますが、頂点/インデックスが少ないより単純なファイルをロードし、各数値の出力を比較したところ、データをアプリケーションに正しくコピーしたようです。私の推測では、openGLの初期化コードで何か間違ったことをしたと思います.誰かがエラーを見つけることができますか? すべてが正常にコンパイルされます...

4

1 に答える 1

1

しないでください。

while (file.good()) { ... }

または同様に、それはあなたが思っていることをしません。

代わりに

while (std::getline(...)) { ... }

これは、入力操作が失敗するまでフラグ ( / / eofetc bad.) が設定されないためです。これは、すべてが適切に見えるためループすることを意味しますが、ファイルの最後にあるため失敗しますが、まだ読み取られていないデータを解析しようとします。std::getline

于 2013-08-08T15:29:39.093 に答える