OpenGL纹理导致内存问题

时间:2013-04-08 03:22:51

标签: c++ c opengl

我正在编写的C程序中有一些奇怪的内存问题,我认为与纹理加载系统相关的问题是原因。

问题在于,根据我制作的纹理数量,会出现不同的问题。较少的纹理往往会轻微改变程序中的其他变量。如果我包含我想要包含的所有纹理,程序可能会抛出一系列不同的“ * glibc检测到* ”类型错误,偶尔会出现分段错误。 踢球者偶尔也可以使用该程序。这是抽奖的全部运气。

此时我的代码非常繁重,所以我只发布我认为相关的部分。

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_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检测到 out / PokeEngine:free():指针无效:0x01010101 * < / em> *“关闭程序后,假设它能够正常开始。回溯看起来像这样:

/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;
}

1 个答案:

答案 0 :(得分:0)

您加载BMP文件的方式是错误的。您正在阅读结构,这是非常不可靠的,因为编译器为结构选择的内存布局可能与文件中的数据布局有很大不同。您的代码也包含零错误检查。如果我必须做出有根据的猜测,我会说这就是你的问题所在。

顺便说一句。 glEnable(GL_TEXTURE_…)使纹理目标成为渲染的数据源。仅生成和上传纹理完全没有必要。您可以在加载代码中省略支撑glEnable(GL_TEXTURE_2D); ... glDisable(GL_TEXTURE_2D)块。另外,我不会使用gluBuildMipmaps2D - 它不支持任意纹理尺寸,并且您无论如何都要禁用mipmapping - 只需直接使用glTexImage2D上传。

此外,我不需要纹理管理器。或者至少不是为什么你的纹理管理器看起来像这样。更好的方法是使用哈希映射 文件路径→纹理ID 和引用计数。