본문 바로가기
C++ 200제/코딩 IT 정보

[OpenGL ES] 12. Uniform, attribute 활성화, 비활성화

by vicddory 2017. 10. 30.

[OpenGL ES] 12. Uniform, attribute 활성화, 비활성화


OpenGL ES 배열을 설정하려면 마지막 추론 과정에서 "v(vector)"만 붙여주면 된다(glUniform{1234}{if}v). Shader의 uniform에 값을 설정하는 방법은 이게 끝이다. OpenGL ES에서 2가지 중요한 사실을 기억해라)


같은 uniform이 2개의 shader에서 사용될 수 있다는 것(양쪽에 다 선언해서)과 uniform은 현재의 program object에 설정된다는 것, 이 두 가지 말이다.


그래서 uniform과 attribute를 설정하기 전에 program 사용을 시작해야 한다. OpenGL ES, program object를 사용하려면 glUseProgram을 호출한다. 자 이제 attribute를 설정하는 방법을 보자. Attribute는 float, vec2 ~ 4, mat2 ~ 4의 데이터 타입만 가능하다.


OpenGL ES, Uniform[[OpenGL ES] 12. Uniform, attribute 활성화, 비활성화]


구조체나 배열은 안 된다.


OpenGL ES Defining the Attributes Values


GLvoid glVertexAttrib{1234}f(GLuint index, GLfloat value[N])

index: The attribute's location retrieved by the glGetAttribLocation function or defined with glBindAttribLocation.


value[N]: The value you want to set. You must repeat this parameter N times, according to the number specified in the function name {1234}.


GLvoid glVertexAttrib{1234}fv(GLuint index, const GLfloat* values)

index: The attribute's location retrieved by the glGetAttribLocation function or defined with glBindAttribLocation.


values: A pointer to an array containing the values you want to set up.

Only the necessary elements in the array will be used, for example, in case of setting a vec3 if you inform an array of 4 elements, only the first three elements will be used.


If the shader need to make automatically fills, it will use the identity of vec4 (x = 0, y = 0, z = 0, z = 1), for example, in case you setting a vec3 if you inform an array of 2 elements, the third elements will be filled with value 0.


To matrices, the auto fill will use the matrix identity.


OpenGL ES GLvoid glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)


index: The attribute's location retrieved by the glGetAttribLocation function or defined with glBindAttribLocation.


size: This is the size of each element. Here the values can be:

1: to set up float in shader.

2: to set up vec2 in shader.

3: to set up vec3 in shader.

4: to set up vec4 in shader.


type: Specify the OpenGL ES data type used in the informed array. Valid values are:

GL_BYTE

GL_UNSIGNED_BYTE

GL_SHORT

GL_UNSIGNED_SHORT

GL_FIXED

GL_FLOAT


normalized: If set to true (GL_TRUE) this will normalize the non-floating point data type. The normalize process will place the converted float number in the range 0.0 - 1.0. If this is set to false (GL_FALSE) the non-floating point data type will be converted directly to floating points.


stride: It means the interval of elements in the informed array. If this is 0, then the array elements will be used sequentially. If this value is greater than 0, the elements in the array will be used respecting this stride. This values must be in the basic machine units (bytes).


ptr: The pointer to an array containing your data.


OpenGL ES uniform때와 규칙은 같다.


9개의 함수 중, 8개는 상수값을 넣고, 하나만 dynamic 값을 넣는다. (glVertexAttribPointer만 dynamic용이다)


glVertexAttrib1f(GLuint index, GLfloat x)

glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)

glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)

glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)

glVertexAttrib1fv(GLuint index, const GLfloat* values)

glVertexAttrib2fv(GLuint index, const GLfloat* values)

glVertexAttrib3fv(GLuint index, const GLfloat* values)

glVertexAttrib4fv(GLuint index, const GLfloat* values)

glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)


shader의 기본이 상수라는 게 짜증 난다.


만약 dynamic 값을 OpenGL ES attribute에 넣으려면 활성화해야 한다. Dynamic 값은 꼭지점마다 적용된다.


아래의 함수를 써서 dynamic 값을 활성화/비활성화 할 수 있다.


Variable Values Feature


GLvoid glEnableVertexAttribArray(GLuint index)

index: The attribute's location retrieved by the glGetAttribLocation function or defined with glBindAttribLocation.


GLvoid glDisableVertexAttribArray(GLuint index)

index: The attribute's location retrieved by the glGetAttribLocation function or defined with glBindAttribLocation.


OpenGL ES vertex[[OpenGL ES] 12. Uniform, attribute 활성화, 비활성화]


OpenGL ES, glVertexAttribPointer로 꼭지점마다 값을 넣으려면 그전에 glEnableVertexAttribArray 함수로 해당 위치의 attribute가 dynamic 값을 받을 수 있도록 활성화해야 한다(vsh, fsh 둘 다).


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// Assume which _program defined early in another code example.
 
GLuint mvpLoc, mapsLoc, vertexLoc, textureLoc;
 
// Gets the locations to uniforms.
mvpLoc = glGetUniformLocation(_program, "u_mvpMatrix");  
mapsLoc = glGetUniformLocation(_program, "u_maps");
 
// Gets the locations to attributes.
vertexLoc = glGetAttribLocation(_program, "a_vertex");  
textureLoc = glGetAttribLocation(_program, "a_texture");
 
// ...
// Later, in the render time...
// ...
 
// Sets the ModelViewProjection Matrix.
// Assume which "matrix" variable is an array with
// 16 elements defined, matrix[16].
glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, matrix);
 
// Assume which _texture1 and _texture2 are two texture names/ids.
// The order is very important, first you activate
// the texture unit and then you bind the texture name/id.
glActiveTexture(GL_TEXTURE0);  
glBindTexture(GL_TEXTURE_2D, _texture1);  
glActiveTexture(GL_TEXTURE1);  
glBindTexture(GL_TEXTURE_2D, _texture2);
 
// The {0,1} correspond to the activated textures units.
int textureUnits[2= {0,1};
 
// Sets the texture units to an uniform.
glUniform1iv(mapsLoc, 2&textureUnits);
 
// Enables the following attributes to use dynamic values.
glEnableVertexAttribArray(vertexLoc);  
glEnableVertexAttribArray(textureLoc);
 
// Assume which "vertexArray" variable is an array of vertices
// composed by several sequences of 3 elements (X,Y,Z)
// Something like {0.0,0.0,0.0, 1.0,2.0,1.0, -1.0,-2.0,-1.0, ...}
glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, 0, vertexArray);
 
// Assume which "textureArray" is an array of texture coordinates
// composed by several sequences of 2 elements (S,T)
// Something like {0.0,0.0, 0.3,0.2,  0.6, 0.3,  0.3,0.7, ...}
glVertexAttribPointer(textureLoc, 2, GL_FLOAT, GL_FALSE, 0, textureArray);
 
// Assume which "indexArray" is an array of indices
// Something like {1,2,3,  1,3,4,  3,4,5,  3,5,6,  ...}
glDrawElements(GL_TRIANGLES, 64, GL_UNSIGNED_SHORT, indexArray);
 
// Disables the vertices attributes.
glDisableVertexAttribArray(vertexLoc);  
glDisableVertexAttribArray(textureLoc);  
cs


위 소스에선 활성화 이후 attribute에 dynamic 값을 넣고, 다시 비활성화시켰다.


어떻게 사용하는지 보여주는 예제다.


내가 전에도 말했지만, 활성화 / 비활성화 작업은 부하가 크다. 나는 활성화를 딱 한 번만 하는 것이 좋다고 생각한다.


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

[OpenGL ES] 12. Uniform, attribute 활성화, 비활성화

댓글