OpenGL Shader – 13

GLSL을 위한 OpenGL 설정 – Attribute 변수
원문 : http://www.lighthouse3d.com/opengl/glsl/index.php?oglattribute

이전의 Uniform 변수 섹션에서 언급했듯이,  Uniform 변수는 오직 프리미티브에 의해서만 설정할 수 있다. 즉, Uniform 변수는 glBegin~glEnd 사이에서는 설정할 수 없다.

만약에 프리미티브를 구성하는 버텍스 당위로 변수를 설정하려고 한다면 Attribute 변수를 사용해야만 한다. 사실 Attribute 변수는 아무때나 설정될 수 있다. Attribute 변수는 버텍스 쉐이더에서만 읽힐 수(쓸수는 없다) 있다. 왜냐하면 Attribute 변수는 버텍스 데이터를 가지고 있어서, 프레그먼트 쉐이더에 사용하기는 적당하지 않다. (이 부분에 대해서는 추후에 varying 변수를 살펴보겠다) uniform 변수처럼, 변수에 대한 메모리 주소값을 읽어오는 것이 필요하다. 쉐이더 프로그램은 먼저 링크되어져야하며 몇몇 그래픽 카드는 쉐이더 프로그램이 사용중이여야 변수에 대한 주소값을 읽어올 수 있다.

다음은 OpenGL 2.0에서 Attribute 변수의 메모리 주소를 얻어오는 함수이다.

GLint glGetAttribLocation(GLuint program, char *name);
Parameters:
program –  쉐이더 프로그램의 핸들
name – 변수의 이름

ARB 확장 형태는 다음과 같다.

GLint glGetAttribLocationARB(GLhandleARB program, char *name);
Parameters:
program – 쉐이더 프로그램의 핸들
name – 변수의 이름

메모리의 변수 위치는 위의 함수의 리턴값으로 알수있다. 다음 단계는 값을 지정하는 것인데, uniform 변수처럼, 각 데이터 타입에 대한 함수가 있다.

OpenGL 2.0 문법은 아래와 같다.

void glVertexAttrib1f(GLint location, GLfloat v0);
void glVertexAttrib2f(GLint location, GLfloat v0, GLfloat v1);
void glVertexAttrib3f(GLint location, GLfloat v0, GLfloat v2);
void glVertexAttrib4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);

또는…

GLint glVertexAttrib{1,2,3,4}fv(GLint location, GLfloat *v);

Parameter:
location –  이전에 질의해서 얻은 변수의 메모리 위치
v0, v1, v2, v3 – 실수값
v – 실수 배열

ARB 확장에 대한 문법은 아래와 같다.

void glVertexAttrib1fARB(GLint location, GLfloat v0);
void glVertexAttrib2fARB(GLint location, GLfloat v0, GLfloat v1);
void glVertexAttrib3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
void glVertexAttrib4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);

또는…

GLint glVertexAttrib{1,2,3,4}fvARB(GLint location, GLfloat *v);

Parameter:
location – 이전에 질의한 변수의 위치
v0, v1, v2, v3 – 실수 변수
v – 실수 배열

정수와 몇몇 다른 데이터 타입에 대한 유사한 함수군이 제공되어진다. uniform 변수의 경우에서처럼 벡터 버전에 대한 설정 함수는 제공되지 않는다. 벡터에 대한 경우는 하나의 Attribute 변수의 값으로 지정할 수 있는데, 이것은 OpenGL에서 glColor3f와 glColor3fv 함수의 예와 비슷하다.

아래 간단한 예를 살펴보자. 이 예는 버텍스 쉐이더가 실수형 Attribute 변수로써 “height” 이름으로 선언된 경우이다. 쉐이더 프로그램이 링크된 후에 의미가 있는 예라는 점을 염두해 두길 바란다.

loc = glGetAttribLocation(p, "height");

렌더링 함수에 대한 코드 예는 아래와 같다.

glBegin(GL_TRIANGLE_STRIP);
    glVertexAttrib1f(loc,2.0);
    glVertex2f(-1,1);

    glVertexAttrib1f(loc,2.0);
    glVertex2f(1,1);

    glVertexAttrib1f(loc,-2.0);
    glVertex2f(-1,-1);

    glVertexAttrib1f(loc,-2.0);
    glVertex2f(1,-1);
glEnd();

위의 코드에 대한 ARB 확장은 매우 비슷한데, 단지 함수에 ARB만 붙이기만 하면 된다.

위의 코드에 대한 전체 샘플은 아래를 통해 다운로드 받길 바란다.

버텍스 배열은 Attribute 변수와 함께 사용될 수 있다. 가장 먼저 해야할 것은 Array를 활성화 시키는 것인데, 활성화 시키기 위해서는 다음 OpenGL 2.0 함수를 사용하면 된다.

void glEnableVertexAttribArray(GLint loc);
Parameter:
loc – 변수의 위치

ARB 확장의 경우는 아래와 같다.

void glEnableVertexAttribArrayARB(GLint loc);
Parameter:
loc – 변수의 위치

이제 다음으로 해야할 일은, 다음 함수를 사용해서 배열에 데이터를 제공하는 것이다. OpenGL 2.0 문법이다.

void glVertexAttribPointer(GLint loc, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);
Parameters:
loc – 변수의 위치
size – 배열 요소들의 개수로써, 예를들어, float 인경우 1, vec2인 경우 2, vec3인 경우는 3
type – 데이터 타입으로, 예를들어 GL_FLOAT
normalized – 만약 1인 경우, 배열의 값은 정규되어져 있다(부호있는 경우 -1~1, 부호가 없는 경우는 0~1로 정규화되었다는 의미)
stride – 배열 요소 사이의 간격. OpenGL와 정확히 동일함
pointer – 데이터를 가지고 있는 배열의 포인터

ARB 확장 문법은..

void glVertexAttribPointerARB(GLint loc, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer);
Parameters:
loc – 변수의 위치
size – 배열 요소들의 개수로써, 예를들어, float 인경우 1, vec2인 경우 2, vec3인 경우는 3
type – 데이터 타입으로, 예를들어 GL_FLOAT
normalized – 만약 1인 경우, 배열의 값은 정규되어져 있다(부호있는 경우 -1~1, 부호가 없는 경우는 0~1로 정규화되었다는 의미)
stride – 배열 요소 사이의 간격. OpenGL와 정확히 동일함
pointer – 데이터를 가지고 있는 배열의 포인터

이제 아래에 소스 코드를 살펴보라. 첫번째 초기화 단계에 이어, 2개의 배열이 있는데, 버텍스 배열과 속성 배열이다. “height” 변수는 적당한 위치에 선언되어져 있다고 가정할 수 있는데, 예를들어서 렌더링할때 등과 같은 시기에 접근할 수 있다.

float vertices[8] = {-1,1, 1,1, -1,-1, 1,-1};
float heights[4] = {2,2,-2,-2};
	
...
	
loc = glGetAttribLocationARB(p,"height");

glEnableClientState(GL_VERTEX_ARRAY);
glEnableVertexAttribArrayARB(loc);

glVertexPointer(2,GL_FLOAT,0,vertices);
glVertexAttribPointerARB(loc,1,GL_FLOAT,0,0,heights);

전체 소스 코드는 아래를 통해 다운로드 받기 바란다.

1086297923.zip1121909455.zip

“OpenGL Shader – 13”에 대한 9개의 댓글

  1. 형준님 덕분에… 쉐이더 복습 잘하고 있습니다. ^^

    고맙습니다.. 항상 수고하시네요.. 앞으로도~~ 수고 부탁 드려요

  2. 네~ 복습하시다가 이상한 부분이 있음 얼릉 얼릉 지적도 해주시고, 궁금한거 있음 얼릉 얼릉 물어봐주시고~ 곧 더위가 사그라진다는 기쁜 소식이 있긴한데~~

  3. 아! 곧 저희 랩실에서도 glsl에 대해서 세미나를 할것 같더군요… 필요하시다면 자료 공유해 드리겠습니다. ^^

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다