OpenGL 객체에 관한 모든 것
OpenGL 객체의 표준 모델은 다음과 같습니다.
객체에는 상태가 있습니다. 그것들을로 생각하십시오 struct
. 따라서 다음과 같이 정의 된 객체가있을 수 있습니다.
struct Object
{
int count;
float opacity;
char *name;
};
객체에는 특정 값이 저장되어 있으며 상태가 있습니다. OpenGL 객체도 상태가 있습니다.
상태 변경
C / C ++에서 유형의 인스턴스가있는 경우 Object
상태를 다음과 같이 변경합니다. obj.count = 5;
객체의 인스턴스를 직접 참조하고 변경하려는 특정 상태를 가져 와서 값을 입력합니다.
OpenGL에서는이 작업 을 수행하지 않습니다 .
설명 할 수없는 더 나은 왼쪽 레거시 이유는, OpenGL을 객체의 상태를 변경하려면, 먼저해야 바인드 그 문맥에. 이것은 일부 glBind*
전화로 이루어집니다 .
이에 해당하는 C / C ++는 다음과 같습니다.
Object *g_objs[MAX_LOCATIONS] = {NULL};
void BindObject(int loc, Object *obj)
{
g_objs[loc] = obj;
}
질감은 흥미 롭습니다. 그것들은 특별한 바인딩의 경우를 나타냅니다. 많은 glBind*
통화에는 "대상"매개 변수가 있습니다. 이것은 OpenGL 컨텍스트에서 해당 유형의 객체를 바인딩 할 수있는 다른 위치를 나타냅니다. 예를 들어, 읽기 ( GL_READ_FRAMEBUFFER
) 또는 쓰기 ( GL_DRAW_FRAMEBUFFER
) 를 위해 프레임 버퍼 객체를 바인딩 할 수 있습니다 . 이는 OpenGL이 버퍼를 사용하는 방법에 영향을줍니다. 이것이 loc
위 의 매개 변수가 나타내는 것입니다.
텍스처는 대상에 처음 바인딩 할 때 특별한 정보를 얻기 때문에 특별합니다. 텍스처를 처음으로 바인딩하면 GL_TEXTURE_2D
실제로 텍스처에서 특수 상태를 설정하는 것입니다. 이 텍스처는 2D 텍스처입니다. 그리고 항상 2D 텍스처입니다. 이 상태는 변경할 수 없습니다 지금 . 으로 처음 바인딩 된 텍스처가있는 경우 항상 ; 로 바인딩 GL_TEXTURE_2D
해야합니다 . 바인딩을 시도 하면 오류가 발생합니다 (런타임 동안).GL_TEXTURE_2D
GL_TEXTURE_1D
객체가 바인딩되면 상태를 변경할 수 있습니다. 이는 해당 객체에 고유 한 일반 기능을 통해 수행됩니다. 또한 수정할 개체를 나타내는 위치를 사용합니다.
C / C ++에서는 다음과 같습니다.
void ObjectParameteri(int loc, ObjectParameters eParam, int value)
{
if(g_objs[loc] == NULL)
return;
switch(eParam)
{
case OBJECT_COUNT:
g_objs[loc]->count = value;
break;
case OBJECT_OPACITY:
g_objs[loc]->opacity = (float)value;
break;
default:
//INVALID_ENUM error
break;
}
}
이 함수가 현재 바인드 된 loc
값으로 발생하는 것을 어떻게 설정하는지 주목하십시오 .
텍스처 오브젝트의 경우 주요 텍스처 상태 변경 기능은 glTexParameter
입니다. 텍스처 상태를 변경하는 유일한 다른 함수는 glTexImage
함수와 그 변형 ( glCompressedTexImage
,, glCopyTexImage
최근 glTexStorage
)입니다. 다양한 SubImage
버전은 텍스처의 내용을 변경하지만 기술적으로 상태를 변경하지는 않습니다 . Image
기능 텍스쳐 저장 공간을 할당하고 텍스처의 포맷을 설정; SubImage
기능은 픽셀을 주변에 복사합니다. 텍스처 상태로 간주되지 않습니다.
반복하겠습니다 : 텍스처 상태를 수정 하는 유일한 기능입니다. glTexEnv
환경 상태를 수정합니다. 텍스처 오브젝트에 저장된 것에 영향을 미치지 않습니다.
활성 텍스처
텍스처의 상황은 더 복잡하지만, 레거시 이유로 공개되지 않은 것이 가장 많습니다. 여기가 glActiveTexture
온다.
텍스처를 들어, 단지 목표는 (가 아니다 GL_TEXTURE_1D
, GL_TEXTURE_CUBE_MAP
등). 텍스처 단위도 있습니다. C / C ++ 예제와 관련하여 우리가 가진 것은 다음과 같습니다.
Object *g_objs[MAX_OBJECTS][MAX_LOCATIONS] = {NULL};
int g_currObject = 0;
void BindObject(int loc, Object *obj)
{
g_objs[g_currObject][loc] = obj;
}
void ActiveObject(int currObject)
{
g_currObject = currObject;
}
이제 2D 목록 Object
뿐만 아니라 현재 객체의 개념도 있습니다. 현재 개체를 설정하는 기능이 있고, 최대 현재 개체 수라는 개념이 있으며, 모든 개체 조작 기능이 현재 개체에서 선택하도록 조정되었습니다.
현재 활성화 된 객체를 변경하면 전체 대상 위치 세트가 변경됩니다. 따라서 현재 객체 0에 들어가는 것을 바인딩하고 현재 객체 4로 전환하면 완전히 다른 객체를 수정할 수 있습니다.
텍스처 오브젝트와의이 비유는 거의 완벽합니다.
참조 glActiveTexture
정수를하지 않습니다; 열거자가 필요합니다 . 그것에서 아무것도 걸릴 수 있다는 이론 수단에 어떤 GL_TEXTURE0
에가 GL_TEXTURE31
. 그러나 이해해야 할 것이 하나 있습니다.
이것은 거짓입니다!
glActiveTexture
취할 수 있는 실제 범위 는에 의해 결정됩니다 GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
. 이는 구현이 허용하는 최대 동시 다중 텍스처 수입니다. 이들은 각각 다른 셰이더 단계에 대해 서로 다른 그룹으로 나뉩니다. 예를 들어 GL 3.x 클래스 하드웨어에서는 16 개의 정점 셰이더 텍스처, 16 개의 조각 셰이더 텍스처 및 16 개의 지오메트리 셰이더 텍스처가 제공됩니다. 따라서 GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
48입니다.
그러나 48 개의 열거자는 없습니다. 이것이 glActiveTexture
실제로 열거자를 사용하지 않는 이유 입니다. 올바른 호출 방법은 glActiveTexture
다음과 같습니다 :
glActiveTexture(GL_TEXTURE0 + i);
여기서 i
0과 사이의 숫자 GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
입니다.
표현
이 모든 것이 렌더링과 어떤 관련이 있습니까?
셰이더를 사용하는 경우 샘플러 유니폼을 텍스처 이미지 단위 ( glUniform1i(samplerLoc, i)
, 여기서 i
이미지 단위)로 설정하십시오. 사용하는 숫자를 나타냅니다 glActiveTexture
. 샘플러는 샘플러 유형에 따라 대상을 선택합니다. 그래서 목표 sampler2D
에서 선택합니다 GL_TEXTURE_2D
. 이것이 샘플러의 유형이 다른 이유 중 하나입니다.
이제 동일한 텍스처 이미지 단위를 사용하는 유형 이 다른 두 개의 GLSL 샘플러를 사용할 수있는 것처럼 들립니다 . 그러나 당신은 할 수 없습니다; OpenGL은이를 금지하고 렌더링을 시도 할 때 오류를 발생시킵니다.
GL_TEXTURE0 + i
-열거 형 값을 검사하여 그것이 유효한지 아닌지를 확인하는 것이 었습니다. 그리고 마지막 단락-그것이 합법적인지 알지 못했습니다. 우수한! 모든 답변을 북마크에 추가하여 다시 참조 할 수 있습니다.