2013-04-08 57 views
0

我在編寫C程序時出現了一些奇怪的內存問題,我認爲與我的紋理加載系統有關的事情是原因。OpenGL Textures導致內存問題

問題是,根據我製作的紋理數量,不同的問題開始出現。較少的紋理往往會略微改變程序中的其他變量。如果我包含所有我想包含的紋理,程序可能會吐出大量不同的「* glibc檢測到的*」類型的錯誤,偶爾會出現分割錯誤。 踢球者偶爾會覺得這個節目完美無缺。這是平局的好運。

我的代碼在這一點上非常沉重,所以我只是發佈我認爲是它的相關部分。

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

是我調用的將函數加載到OpenGL中的函數。 「紋理」是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_newTextures的名稱,這是相同的d_newTexture,區別在於它分裂一個簡單的精靈表成多個紋理使用的功能。

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的檢測出/ PokeEngine:免費():無效的指針: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; 
} 
+0

你確定'texInc'永遠不會超過'texID'的大小嗎?如果你開始覆蓋你的結構之外的內存,很多不好的事情可能會發生。你的OpenGL看起來很合理,但我懷疑需要更多的信息才能真正發現問題。 – radical7 2013-04-08 04:30:23

+0

@ radical7這個可能性也在我腦海中浮現,但我已經測試過了。我會繼續並且包含'd_loadBMP'的代碼,但是我不能真正想到還有什麼可以包含的。 – Velovix 2013-04-08 04:51:46

回答

0

加載BMP文件的方式是錯誤的。您正在閱讀正確的結構,這是非常不可靠的,因爲您的編譯器爲結構選擇的內存佈局可能與文件中的數據佈局大不相同。你的代碼也包含零錯誤檢查。如果我必須做出有根據的猜測,我會說這是你的問題所在。

順便說一句。 glEnable(GL_TEXTURE_…)使紋理目標成爲渲染的數據源。生成和上傳紋理完全沒有必要。您可以省略加載代碼中的支撐塊glEnable(GL_TEXTURE_2D); ... glDisable(GL_TEXTURE_2D)塊。此外,我不會使用gluBuildMipmaps2D - 它不支持任意紋理尺寸,並且無論如何都會禁用mipmapping - 並直接使用glTexImage2D直接上傳。

另外我不明白你需要紋理管理器。或者至少不是爲什麼你的紋理管理器看起來像這樣。更好的方法是使用哈希映射文件路徑→紋理ID和引用計數。

+0

事實證明,紋理並不是問題的實際來源,而是該程序的另一部分。不過,你給了我很好的建議,所以謝謝你! – Velovix 2013-04-21 20:16:21