기본적으로 지원되는 OpenGL 텍스처 형식을 어떻게 감지합니까? 모드의 “rgba8″과 같은 다른 형식으로

예를 들어, 비디오 카드가 “bgr8″을 지원하지 않는지 감지하고이를 소프트웨어 모드의 “rgba8″과 같은 다른 형식으로 변환하는 방법.

업데이트 : 혼란을 드려 죄송합니다. 이 질문 은 glTexImage2D의 internalFormat 을 “bgra8″과 같은 것으로 설정 했지만 비디오 드라이버는 내부적으로 “rgba8″과 같은 다른 형식으로 데이터를 변환 할 때의 상황에 대한 질문 입니다.



답변

귀하의 질문은 특정 개념을 혼란스럽게하는 것 같으므로 위에서부터 취합시다. 이것은 함수의 정의입니다 glTexImage2D.

void glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, void *data );

“텍스처 형식”이라고 부르는 두 가지가 있습니다. 첫 번째는 internalformat매개 변수입니다. OpenGL이 저장 하는 이미지실제 형식입니다 . 이 format매개 변수 는 매개 변수 와 함께 제공 하는 픽셀 데이터 형식의 일부를 설명 합니다 data.

그것을 다른 방법을 넣어하려면 formattype을 정의 하여 데이터 외모가 좋아합니다. internalformatOpenGL에 데이터 를 저장 하도록 지시하는 방법 입니다. 우리가 전화를하자 formattype하면서 “픽셀 전송 형식” internalformat은 “이미지 형식”입니다.

텍스처의 이미지 형식은 “bgr8″일 수 없습니다 . GL_BGR8 이미지 형식 열거자는 없습니다. 가 이다 GL_BGR 열거는하지만 픽셀 전송 형식이 아닌 이미지 형식입니다.

또는 다른 방법으로 OpenGL에 제공 한 픽셀 데이터를 BGR 순서로 저장할 수 있습니다. 그러나 OpenGL 구현은 해당 픽셀 데이터를 실제로 저장하는 방법을 자체적으로 결정합니다. 아마도 리틀 엔디안 순서로 저장합니다. 어쩌면 빅 엔디안을 저장할 수도 있습니다. 아마도 바이트를 임의로 재정렬 할 수도 있습니다. 당신은 모르고 OpenGL은 찾을 방법을 제공하지 않습니다.

특정 픽셀 전송 형식 매개 변수 세트가 OpenGL 구현이 이미지 형식에서이를 저장하는 방법과 일치하는지 여부를 알 수있는 방법이 없습니다.

방법입니다 지금 말할 수는. 그리고 “지금”은 OpenGL 4.3 및 / 또는 ARB_internalformat_query2를 의미합니다. 가까운 그래픽 카드로 오기 :

GLenum format, type;
glGetInternalformativ(texture_target, GL_RGBA8, GL_TEXTURE_IMAGE_FORMAT, 1, &format);
glGetInternalformativ(texture_target, GL_RGBA8, GL_TEXTURE_IMAGE_TYPE, 1, &type);

format그리고 type지금이 구현의 선호 formattype사용 glTex(Sub)Image에 대한 호출 GL_RGBA8이미지를. 별도 있습니다 formattype대한 쿼리 glReadPixels다운로드.

당신이 할 수 있는 다른 쿼리가 있습니다 .

이것들에 접근 할 수 없다면, 대부분의 하드웨어가 준수 할 일반적인 경험 규칙을 사용할 수 있습니다 :

  • 채널당 8 비트 데이터의 픽셀 데이터를 BGRA 순서로 저장합니다. 당신이 더 빨리 그렇게에 관해서는, 당신의 픽셀 데이터 형식과 일치 텍스처 데이터를 업로드하려는 경우, 당신은 사용할 GL_BGRA을 위해 format, 그리고 GL_UNSIGNED_INT_8888GL_UNSIGNED_BYTE을 위해 type.
  • 실제로 24 비트 색상을 24 비트로 저장하지 않습니다. 항상 32 비트로 채 웁니다. 알파는 데이터를 읽을 때 무시됩니다. 따라서 형식을 일치 시키려면 알파 데이터에 더미 데이터를 넣어야하는 경우에도 항상 이미지 형식 GL_BGRA format과 함께 사용 GL_RGB8하십시오.

답변

일반적으로 대부분의 하드웨어는 3- 컴포넌트 텍스처 형식을 지원하지 않으므로이 특정 예제에서는 변환되었다고 합리적으로 안전하게 가정 할 수 있습니다. 3 성분 OpenGL 텍스처는 실제로 하드웨어에서는 4 성분이지만 알파 성분은 255 / 무엇으로 무시 / 설정됩니다.

https://www.khronos.org/opengl/wiki/Common_Mistakes#Texture_upload_and_pixel_reads
( “일반적인 실수”페이지는 금광입니다-지금 북마크하세요!)

보다 일반적인 경우, glTexSubImage2D 성능은 업로드가 소프트웨어 변환 경로를 거쳐야하는지 여부를 잘 보여줄 수 있습니다. 프로그램 시작 중에이 문제를 해결하려고합니다-NULL 데이터가있는 glTexImage2D를 통해 빈 텍스처를 만든 다음 glTexSubImage2D 호출을 발행하고 각각 완료되면 glFinish가 이어집니다. 캐시 / 상태 / 등이 설정되어 있기 때문에 첫 번째는 무시하고 나머지는 시간을 정하십시오. 몇 가지 다른 형식으로이 작업을 반복하고 가장 빠른 형식을 선택하십시오.

이 질문에 “Windows”라는 태그를 붙인 다른 방법은 시작할 때 (창을 만든 후 OpenGL을 초기화하기 전에) D3D 장치를 만든 다음 D3D를 사용하여 형식 지원을 확인하는 것입니다. OpenGL은 유효한 내부 형식으로 소프트웨어를 변환 할 수 있지만 D3D는 지원하지 않습니다. 하드웨어에서 지원하지 않으면 할 수 없습니다. 그런 다음 D3D를 파괴하고 OpenGL을 불러옵니다. (이 기술은 OpenGL이 직접 쿼리 할 수없는 다른 것들을 쿼리하는 데에도 사용될 수 있습니다).

실제로 D3D 문서를 사용하여 OpenGL에서 수행중인 작업을 교차 확인하는 유용한 규칙입니다. D3D가 무언가를 할 수 없다면, 문제가있는 것이 하드웨어에서 지원되지 않는다는 좋은 증거가 될 수 있습니다. 항상 사실은 아니지만 유용한 출발점입니다.