[OpenGL ES] 11. 속성과 유니폼 설정(Attribute, Uniform)

[OpenGL ES] 11. 속성과 유니폼 설정(Attribute, Uniform)


OpenGL ES, shader 안에 있는 변수를 구별하기 위해서, program object는 변수의 위치(index)를 정의한다. 일단 attribute와 uniform의 최종 위치을 알면 그 위치에 값을 설정할 수 있다.


uniform값을 설정할 수 있도록 OpenGL ES는 한 가지 방법을 제공하는데, linking 다음에, shader 내부의 이름을 기반으로 원하는 uniform의 위치를 받아올 수 있다.


attribute 값을 설정할 수 있도록 OpenGL ES는 2가지 방법을 제공하는데, program이 link 된 후 위치를 받아오거나, program이 link 되기 전 위치를 정할 수 있다.


2가지 방법 모두 보여주긴 하겠지만, OpenGL ES에서 link 되기 전 위치를 정하는 방법은 쓸모가 없다. 자 이 쓸모없는 방법부터 확인해보자.


glBindSomthing(take a container)의 예외를 기억하나?


OpenGL ES 속성[[OpenGL ES] 11. 속성과 유니폼 설정(Attribute, Uniform)]


Program이 link 되기 전에 attribute를 설정하려면 glBinidSomething 함수를 쓴다. 하지만 실제 opengl ES에서는 이때 어떠한 것도 잡지 않는다(OpenGL ES Port Crane doesn't take any container). Bind는 program object 안에서 attribute 이름과 위치를 연결하는 내부 처리와 연관이 있다.


Setting Attribute Location before the linkage

GLvoid glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)

program: The program name/id generated by the glCreateProgram function.

index: The location we want to set.

name: The name of attribute inside the vertex shader.


위의 메소드는 program object를 생성한 후 호출되지만, link가 되진 않는다.


내가 이 방법이 쓸모없다고 말하는 이유다. 이건 program object 생성의 중간 단계다. (중간 단계에서 위치를 잡아봐야 어차피 Link를 위한 위치 변화가 일어난다. 그러니 그전에 잡아봐야 ....) 당신은 어플리케이션에 맞는 최상의 방법을 선택할 수야 있겠지만, 나는 다음 방법을 더 좋아한다.


OpenGL ES uniform[[OpenGL ES] 11. 속성과 유니폼 설정(Attribute, Uniform)]


자 이제 linking 후에 attributes와 uniforms의 위치를 얻어내는 방법을 알아보자.

당신이 어떤 방법을 선택하든 당신의 OpenGL ES 어플리케이션에서는 각 shader에 보낼 위치 값을 알고 있어야 한다. 그래야 나중에 이 위치 값을 이용해 이런저런 값들을 설정할 수 있다.


Getting Attribute and Uniform Location


GLint glGetUniformLocation(GLuint program, const GLchar* name)

program: The program name/id generated by the glCreateProgram function.

name: The uniform's name inside the shaders.


GLint glGetAttribLocation(GLuint program, const GLchar* name)

program: The program name/id generated by the glCreateProgram function.

name: The attribute's name inside the vertex shader.


일단 attribute와 uniform의 위치를 알게 되면, 원하는 값으로 설정할 수 있다.


opengl ES는 attribute와 uniform 값을 설정할 수 있는 28가지 함수를 제공한다. 그 함수들은 상수값을 넣을 것인지(attribute, uniform), 변경되는 값을 넣을 것인지(attribute만)에 따라서 나누어진다. (Dynamic attribute를 쓰려면 무언가를 활성화해야 한다)


Uniform은 항상 상수인데 상수 attribute와 무슨 차이가 있는지 궁금할 것이다(정말 궁금하다면 우왕 굳!). 이는, GL_FRONT_AND_BACK culling과 같다. 나도 이걸 왜 쓰는지 이해를 못 하겠다. Uniform과 상수 attribute의 실제 성능상의 차이는 없다.


내가 조언을 하자면, attribute는 dynamic으로만 쓰고 상수는 uniform에 써라. vertex shader는 uniform을 128개 사용할 수 있고, attribute는 8개만 쓸 수 있다. 비록 opengl ES가 attribute를 상수로 사용할 수 있다고 해도, dynamic으로 쓰는 게 좋다.


OpenGL ES attribute[[OpenGL ES] 11. 속성과 유니폼 설정(Attribute, Uniform)]


어쨌든 dynamic attribute와 uniform을 설정하는 법을 보도록 하자. Uniform은 구조체, 배열 등 어떠한 데이터 타입도 가능하다.


OpenGL ES Uniform에 값을 설정하려면 아래의 함수를 써라.


Defining the Uniforms Values


GLvoid glUniform{1234}{if}(GLint location, T value[N])

location: The uniform location retrieved by the glGetUniformLocation function.

value[N]: The value you want to set based on the last letter of the function name, i = GLint, f = GLfloat. You must repeat this parameter N times, according to the number specified in the function name {1234}.


GLvoid glUniform{1234}{if}v(GLint location, GLsizei count, const T* value)

location: The uniform location retrieved by the glGetUniformLocation function.

count: The length of the array which you are setting. This will be 1 if you want to set only a single uniform. Values greater than 1 means you want to set values to an array.


value: A pointer to the data you want to set. If you are setting vector uniforms (vec3, for example), each set of 3 values will represent one vec3 in the shaders. The data type of the values must match with the letter in the function name, i = GLint, f = GLfloat.


GLvoid glUniformMatrix{234}fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)

location: The uniform location retrieved by the glGetUniformLocation function.

count: The number of matrices which you are setting. This will be 1 if you want to set only one mat{234} into the shader. Values greater than 1 means you want to set values to an array of matrices, arrays are defined as mat{234}["count"] in the shaders.


transpose: This parameter must be GL_FALSE, it is an internal convention just to compatibility with desktop version.

value: A pointer to your data.


이쯤 되면 OpenGL ES 질문이 많을 것이다. 차근차근 설명하겠다.


위의 표와 관련된 19개의 함수가 있다.


함수명에서 {1234}는 이 숫자 중 하나를 선택해 사용한다는 뜻이고, {if}는 {1234} 또는 당신이 정의한 숫자 중 하나를 선택해 사용한다는 뜻이다.


OpenGL ES 유니폼[[OpenGL ES] 11. 속성과 유니폼 설정(Attribute, Uniform)]


- glUniform1i(GLint location, GLint x)

- glUniform1f(GLint location, GLfloat x)

- glUniform2i(GLint location, GLint x, GLint y)

- glUniform2f(GLint location, GLfloat x, GLfloat y)

- glUniform3i(GLint location, GLint x, GLint y, GLint z)

- glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)

- glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)

- glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)

- glUniform1iv(GLint location, GLsizei count, const GLint* v)

- glUniform1fv(GLint location, GLsizei count, const GLfloat* v)

- glUniform2iv(GLint location, GLsizei count, const GLint* v)

- glUniform2fv(GLint location, GLsizei count, const GLfloat* v)

- glUniform3iv(GLint location, GLsizei count, const GLint* v)

- glUniform3fv(GLint location, GLsizei count, const GLfloat* v)

- glUniform4iv(GLint location, GLsizei count, const GLint* v)

- glUniform4fv(GLint location, GLsizei count, const GLfloat* v)

- glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)

- glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)

- glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)


만약에 행렬 데이터 타입이 아닌 유니폼을 설정하려면


1 = float/bool/int

2 = vec2/bvec2/ivec2

3 = vec3/bvec3/ivec3

4 = vec4/bvec4/ivec4


위와 같이 설정할 수 있다. 굉장히 간단하지 않은가! OpenGL ES는 이처럼 간단하다.


출처 : All About OpenGL ES 2.X 번역

[OpenGL ES] 11. 속성과 유니폼 설정(Attribute, Uniform)

이 글을 공유하기

댓글(0)

Designed by JB FACTORY