2013-05-20 4 views
1

Nvidia nv_dds 유틸리티를 사용하여 OpenGL 프로그램에서 사용할 DDS 이미지 파일을로드합니다. Windows에서 작동하지만 Linux (Ubuntu 12.10)에서는 실패합니다. 처음에는 nv_dds 문제를 생각했지만 Linux (GCC 4.7)에서 fread()가 잘못된 오프셋을 사용하여 헤더 바이트를 읽습니다.Linux에서 DDS 이미지 헤더를 읽을 수 없습니다.

DDS 마커를 제출 한 후 DDS 헤더 : 나는 DDS_HEADER 인스턴스의 내용을 통해 볼 때

// open file 
FILE *fp = fopen(filename.c_str(),"rb"); 
if (fp == NULL) { 
    return false; 
} 
// read in file marker, make sure its a DDS file 

char filecode[4]; 
fread(filecode, 1, 4, fp); 
if (strncmp(filecode, "DDS ", 4) != 0) { 
    fclose(fp); 
    return false; 
} 

// read in DDS header 
DDS_HEADER ddsh; 
fread(&ddsh, 1,sizeof(DDS_HEADER) , fp); 

내가 잘못 속성과 나머지에 할당 된 실제 값의 몇 정크입니다 볼 수 있습니다. 나는 "DDS"마커 체크하는 fread()를 주석 경우

그런 :

// open file 
FILE *fp = fopen(filename.c_str(), "rb"); 
if (fp == NULL) { 
    return false; 
} 
// read in file marker, make sure its a DDS file 
/* comment out for test 
char filecode[4]; 
fread(filecode, 1, 4, fp); 
if (strncmp(filecode, "DDS ", 4) != 0) { 
    fclose(fp); 
    return false; 
} 
*/ 
// read in DDS header 
DDS_HEADER ddsh; 
fread(&ddsh, sizeof(DDS_HEADER),1 , fp);//sizeof(DDS_HEADER) 

그럼 난 여전히 정크있는 속성의 DDS_HEADER.The 나머지 imageHeight 속성에 이미지 너비 값을 얻는다.

Windows 컴퓨터에서 테스트 할 때 이러한 일은 발생하지 않습니다. fread()가 Linux GCC에서 MSVC 컴파일러가있는 Windows에서와 다르게 작동 할 수 있습니까?

+0

아무도 실마리가 없나요? 이상하다... –

답변

1

나는 이것을 풀었고 유용한 입력이 제안되지 않았기 때문에 나는이 질문에 스스로 대답 할 것이다.

다른 컴파일러간에 데이터 형식의 차이점에 대해 의심하기 시작했습니다.이 때 post을 발견했습니다. 그 후 나는 DDS 헤더 (GCC로 컴파일)의 크기가 248보다 두 배 더 크다는 것을 발견했다. (MS specs는 정확히 124 바이트라고한다.) .nv_dds dds 헤더는 memebers에 대해 부호없는 long을 사용한다 :

typedef struct 
{ 
    unsigned long dwSize; 
    unsigned long dwFlags; 
    unsigned long dwHeight; 
    unsigned long dwWidth; 
    unsigned long dwPitchOrLinearSize; 
    unsigned long dwDepth; 
    unsigned long dwMipMapCount; 
    unsigned long dwReserved1[11]; 
    DDS_PIXELFORMAT ddspf; 
    unsigned long dwCaps1; 
    unsigned long dwCaps2; 
    unsigned long dwReserved2[3]; 

    }DDS_HEADER; 

MSVC 컴파일러는 부호없는 long을 4 바이트로 처리하는 반면 GCC는 Linux에서 8 바이트로 처리합니다. 여기서 헤더의 이중 크기가 표시됩니다./

typedef struct 
{ 
    unsigned int dwSize; 
    unsigned int dwFlags; 
    unsigned int dwHeight; 
    unsigned int dwWidth; 
    unsigned int dwPitchOrLinearSize; 
    unsigned int dwDepth; 
    unsigned int dwMipMapCount; 
    unsigned int dwReserved1[11]; 
    DDS_PIXELFORMAT ddspf; 
    unsigned int dwCaps1; 
    unsigned int dwCaps2; 
    unsigned int dwReserved2[3]; 


}DDS_HEADER; 

그리고 따라서 보인다, 어떤 장소에서 말했다 것과 달리, 엔비디아 nv_dds는 크로스 플랫폼 모두 작동되지 않습니다 (또는 : 나는 (또한 DDS_PIXELFORMAT 헤더) 부호 INT에 모든 변경! 크로스 컴파일 읽기)이 해킹은 Linux에서 GCC와 함께 작동하도록해야합니다.

2

GCC long은 32 비트 용으로 컴파일 될 때 4 바이트이고 64 비트 용으로 8 바이트입니다. 명시 적으로 32 비트 또는 64 비트를 대상으로 지정하려면 -m32 또는 -m64 옵션을 사용할 수 있습니다.

0

ABI 관련 작업의 경우 int32_t/uint64_t처럼 stdint.h에 정의 된 유형 이름에 설명 된 크기의 유형을 항상 사용해야합니다. 이렇게하면 다른 플랫폼에서 컴파일하는 동안 많은 문제를 줄일 수 있습니다 (큰 경우 제외)./리틀 엔디안 문제)

관련 문제