2013-04-08 95 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