2013-04-08 3 views
0

제가 쓰고있는 C 프로그램에서 이상한 메모리 문제가 있습니다. 텍스처로드 시스템과 관련된 것이 원인이라고 생각합니다.OpenGL 텍스처로 인해 메모리 문제가 발생했습니다.

문제는 내가 만든 텍스처의 수에 따라 다른 문제가 생기기 시작한다는 것입니다. 텍스처가 적 으면 프로그램의 다른 변수가 약간 변경되는 경향이 있습니다. 포함시키고 자하는 모든 텍스처를 포함 시키면, 프로그램은 "* 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); 
} 

I은 ​​또한 다중 텍스처로 간단한 스프라이트 시트를 분할하는 것을 제외하고 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는 출력/PokeEngine 감지 : 무료() : 잘못된 포인터를 : 0x01010101 * *"뿐만 아니라, 프로그램을 종료 가정 후에는 할 수 있어요 제대로 시작하십시오. 여기에 을뿐만 아니라 d_loadBMP에 대한 코드입니다 :

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

편집 2 : 역 추적은 다음과 같습니다. 희망이 도움이됩니다!

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

+0

@ radical7 그 가능성은 내 마음을 넘어 섰지 만, 나는 그것을 테스트했습니다. 나는'd_loadBMP'에 대한 코드를 포함 시키겠다. 그러나 나는 그 밖의 무엇을 포함해야하는지 정말로 생각할 수 없다. – Velovix

답변

0

BMP 파일을로드하는 방식이 잘못되었습니다. 컴파일러가 구조체에 대해 선택한 메모리 레이아웃이 파일의 데이터 레이아웃과 크게 다를 수 있기 때문에 매우 신뢰할 수없는 구조체를 읽고있는 중입니다. 또한 코드에 오류 체크가 없습니다. 교양있는 추측을해야만한다면 이것이 당신의 문제가있는 곳이라고 말할 수 있습니다.

BTW. glEnable(GL_TEXTURE_…)은 텍스처 타겟을 렌더링 용 데이터 소스로 사용합니다. 텍스처 생성 및 업로드는 완전히 불필요합니다. 로딩 코드에서 브레이 싱 glEnable(GL_TEXTURE_2D); ... glDisable(GL_TEXTURE_2D) 블록을 생략 할 수 있습니다. 또한 gluBuildMipmaps2D을 사용하지 않을 것입니다. 임의의 텍스처 크기를 지원하지 않으므로 어쨌든 밉 매핑을 비활성화하고 glTexImage2D으로 직접 업로드하십시오.

또한 텍스처 관리자가 필요하지 않습니다. 아니면 적어도 텍스쳐 매니저가 왜 이렇게 생겼는지는 아닙니다.더 나은 접근법은 해시 맵파일 경로 → 텍스처 ID과 참조 횟수를 사용하는 것입니다.

+0

텍스처링이 실제로 문제의 원인이 아니라는 사실이 밝혀졌습니다. 프로그램의 다른 부분에 있습니다. 아직도, 당신은 나에게 좋은 충고를주었습니다. 감사합니다! – Velovix

관련 문제