본문 바로가기

OpenGL ES

Shader와 Uniform으로 데이터 공유하기

Shader와 Uniform을 이용하여 데이터를 공유하는 방법을 소개한다.

 

Vertex shader/fragment shader 모두에 적용이 가능하다.

 

1. default uniform block을 이용하는 방법

 

예제 Vertex shader의 코드는 다음과 같다.

 

#version 300 es layout(location = 0) in vec4 vPosition; uniform vec3 shiftLocation; uniform mat4 shiftLocationMat; void main() { gl_Position = shiftLocationMat * (vPosition + vec4(shiftLocation, 0)); } 

 

shiftLocation이라는 x,y,z 벡터와 4x4 행렬인 shiftLocationMat을 이용하여 좌표를 변경하는 간단한 소스이다.

 

glLinkProgram(programObject);

 

위와 같이 코드를 실행하여 shader 준비를 마친 이후 아래와 같이 shiftLocation과 shiftLocationMat에 대한 location을 얻는다.

 

location을 얻기를 성공하면 glUniform*함수를 이용하여 값을 넘겨줄 수 있다.

 

GLint location = glGetUniformLocation(programObject, "shiftLocation"); glUniform4f(location, 0.5, 0.5, 0.5, 0); location = glGetUniformLocation(programObject, "shiftLocationMat"); GLfloat mat[] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.5, -0.5, -0.5, 0.5}; glUniformMatrix4fv(location, 1, GL_FALSE, mat); 

 

 

 

2. Uniform block을 생성하여 이용하는 방법

 

Uniform block을 이용하여 한번에 여러 uniform에 값을 적용할 수 있다.

 

1번과 동일한 동작을 하지만 uniform block을 이용한다.

 

#version 300 es layout(location = 0) in vec4 vPosition; layout (std140) uniform locationBlock { vec3 shiftLocation; mat4 shiftLocationMat; }; void main() { gl_Position = shiftLocationMat * (vPosition + vec4(shiftLocation, 0)); } 

 

Uniform block을 이용하는 데이터를 넘기는 절차는 1번에 비해 복잡하지만, 큰 데이터를 넘길 경우에는 성능적으로 우수하다.

 

GLuint blockIndex = glGetUniformBlockIndex(userData->programObject, "locationBlock"); GLfloat locatoinBlock[] = { 0.5, 0.5, 0.5, 100, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.5, -0.5, -0.5, 0.5 }; GLuint uniformBlockBinding = 1; glUniformBlockBinding(userData->programObject, blockIndex, uniformBlockBinding); GLint blockSize; glGetActiveUniformBlockiv(userData->programObject, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize); GLuint bufferId; glGenBuffers(1, &bufferId); glBindBuffer(GL_UNIFORM_BUFFER, bufferId); glBufferData(GL_UNIFORM_BUFFER, blockSize, locatoinBlock, GL_DYNAMIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, uniformBlockBinding, bufferId); 

 

반응형

'OpenGL ES' 카테고리의 다른 글

glVertexAttribPointer 사용법  (0) 2015.10.15
Fragment란 무엇인가?  (0) 2015.10.07
OpenGL ES 3.0 도서  (0) 2015.10.07