0

私が書いている C プログラムで奇妙なメモリの問題が発生しています。テクスチャの読み込みシステムに関連する何かが原因だと思います。

問題は、作成するテクスチャの数に応じて、さまざまな問題が発生し始めることです。テクスチャが少ないほど、プログラム内の他の変数がわずかに変化する傾向があります。含めたいすべてのテクスチャを含めると、プログラムはさまざまな「* glibc detected *」タイプのエラーを吐き出し、場合によってはセグメンテーション フォールトを吐き出すことがあります。キッカーは、時々、プログラムが完全に機能することです。抽選はすべて運次第です。

この時点で私のコードはかなり重いので、関連する部分と思われるものだけを投稿します。

d_newTexture(d_loadBMP("resources/sprites/default.bmp"), &textures);

テクスチャを OpenGL にロードするために呼び出す関数です。「textures」は texMan_t 型の変数で、私が作成した構造体です。

typedef struct {
    GLuint texID[500];
    int texInc;
} texMan_t;

これは、texMan_t がすべてのテクスチャ ID を取り込んで使いやすくするという考え方です。texInc は、texID の次に利用可能なメンバーが何であるかを追跡するだけです。

これは d_newTexture です:

void d_newTexture(imgInfo_t info, texMan_t* tex) {

    glEnable(GL_TEXTURE_2D);

    glGenTextures(1, &tex->texID[tex->texInc]);
    glBindTexture(GL_TEXTURE_2D, tex->texID[tex->texInc]);
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );

    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

    gluBuild2DMipmaps( GL_TEXTURE_2D, 4, info.width, info.height, GL_RGBA, GL_UNSIGNED_BYTE, info.data );

    tex->texInc++;
    glDisable(GL_TEXTURE_2D);
}

また、単純なスプライト シートを複数のテクスチャに分割する点を除いて、d_newTexture と同じ d_newTextures という名前の関数も使用します。

void d_newTextures(imgInfo_t info, int count, texMan_t* tex) {
    glEnable(GL_TEXTURE_2D);

    glGenTextures(count, &tex->texID[tex->texInc]);
    for(int i=0; i<count; i++) {
        glBindTexture(GL_TEXTURE_2D, tex->texID[tex->texInc+i]);
        glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );

        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

        gluBuild2DMipmaps(  GL_TEXTURE_2D, 4, info.width, info.height/count, 
            GL_RGBA, GL_UNSIGNED_BYTE, &info.data[info.width*(info.height/count)*4*i] );
    }

    tex->texInc+=count;
    glDisable(GL_TEXTURE_2D);
}

表示されている問題の原因は何ですか?

編集: 最近、エラーも発生しています " * glibc が検出されましたout/PokeEngine: free(): invalid pointer: 0x01010101 * *" プログラムを閉じた後も、適切に開始できると仮定します。バックトレースは次のようになります。

/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xceeee2]
/usr/lib/nvidia-173/libGLcore.so.1(+0x277c7c)[0x109ac7c]

編集2:これもコードですd_loadBMP。それが役に立てば幸い!

imgInfo_t d_loadBMP(char* filename) {
    imgInfo_t out;

    FILE * bmpFile;
    bmpFile = fopen(filename, "r");
    if(bmpFile == NULL) {
        printf("ERROR: Texture file not found!\n");
    }

    bmp_sign bmpSig;
    bmp_fHeader bmpFileHeader;
    bmp_iHeader bmpInfoHeader;

    fread(&bmpSig, sizeof(bmp_sign), 1, bmpFile);
    fread(&bmpFileHeader, sizeof(bmp_fHeader), 1, bmpFile);
    fread(&bmpInfoHeader, sizeof(bmp_iHeader), 1, bmpFile);

    out.width = bmpInfoHeader.width;
    out.height = bmpInfoHeader.height;
    out.size = bmpInfoHeader.imageSize;

    out.data = (char*)malloc(sizeof(char)*out.width*out.height*4);

    // Loaded backwards because that's how BMPs are stored
    for(int i=out.width*out.height*4; i>0; i-=4) {
        fread(&out.data[i+2], sizeof(char), 1, bmpFile);
        fread(&out.data[i+1], sizeof(char), 1, bmpFile);
        fread(&out.data[i], sizeof(char), 1, bmpFile);

        out.data[i+3] = 255;
    }


    return out;
}
4

1 に答える 1

0

BMP ファイルのロード方法が間違っています。コンパイラが構造体に対して選択するメモリ レイアウトは、ファイル内のデータ レイアウトと大きく異なる可能性があるため、信頼性が非常に低い構造体を直接読み込んでいます。また、コードにはエラーチェックが含まれていません。経験に基づいた推測をしなければならないとしたら、これがあなたの問題があるところだと思います。

ところで。glEnable(GL_TEXTURE_…)レンダリング用のデータ ソースとしてテクスチャ ターゲットを有効にします。テクスチャを生成してアップロードするだけなら、まったく不要です。読み込みコードではブレースglEnable(GL_TEXTURE_2D);…ブロックを省略できます。glDisable(GL_TEXTURE_2D)また、私は使用gluBuildMipmaps2Dしません - 任意のテクスチャ ディメンションをサポートしていないため、とにかくミップマッピングを無効にしています - で直接アップロードするだけですglTexImage2D

また、テクスチャ マネージャーが必要とは思いません。少なくとも、テクスチャ マネージャがこのように見える理由はわかりません。はるかに優れたアプローチは、ハッシュ マップ ファイル パス → テクスチャ IDと参照カウントを使用することです。

于 2013-04-08T08:29:57.177 に答える