이미지 조작을 위해 Brad Larson's wonderful GPUImage library을 사용 중입니다. 지금까지는 훌륭했습니다. 그러나 메쉬 변형을 허용하는 필터를 추가하고 꽤 많은 문제가 발생합니다. 특히, VBO를 사용하여 쿼드를 렌더링하는 필터를 사용하여 궁극적으로 변형의 정점을 변경할 수 있습니다.iOS : GPUImage 라이브러리 및 VBO
VBO를 사용하는 첫 번째 단계에서 충돌이 발생합니다.
하위 클래스를 생성하여 - (void)newFrameReadyAtTime:(CMTime)frameTime
메서드를 재정 의하여 VBO를 통해 쿼드를 렌더링했습니다. 참고 : 풀 메쉬가 아닌 단일 쿼드를 렌더링하려하고 있으므로 한 번에 하나의 문제 만 해결할 수 있습니다.
@implementation GPUMeshImageFilter {
GLuint _positionVBO;
GLuint _texcoordVBO;
GLuint _indexVBO;
BOOL isSetup_;
}
- (void)setupBuffers
{
static const GLsizeiptr verticesSize = 4 * 2 * sizeof(GLfloat);
static const GLfloat squareVertices[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
static const GLsizeiptr textureSize = 4 * 2 * sizeof(GLfloat);
static const GLfloat squareTextureCoordinates[] = {
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
};
static const GLsizeiptr indexSize = 4 * sizeof(GLushort);
static const GLushort indices[] = {
0,1,2,3,
};
glGenBuffers(1, &_indexVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexVBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize, indices, GL_STATIC_DRAW);
glGenBuffers(1, &_positionVBO);
glBindBuffer(GL_ARRAY_BUFFER, _positionVBO);
glBufferData(GL_ARRAY_BUFFER, verticesSize, squareVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), 0);
glGenBuffers(1, &_texcoordVBO);
glBindBuffer(GL_ARRAY_BUFFER, _texcoordVBO);
glBufferData(GL_ARRAY_BUFFER, textureSize, squareTextureCoordinates, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), 0);
NSLog(@"Setup complete");
}
- (void)newFrameReadyAtTime:(CMTime)frameTime;
{
if (!isSetup_) {
[self setupBuffers];
isSetup_ = YES;
}
if (self.preventRendering)
{
return;
}
[GPUImageOpenGLESContext useImageProcessingContext];
[self setFilterFBO];
[filterProgram use];
glClearColor(backgroundColorRed, backgroundColorGreen, backgroundColorBlue, backgroundColorAlpha);
glClear(GL_COLOR_BUFFER_BIT);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, filterSourceTexture);
glUniform1i(filterInputTextureUniform, 2);
if (filterSourceTexture2 != 0)
{
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, filterSourceTexture2);
glUniform1i(filterInputTextureUniform2, 3);
}
NSLog(@"Draw VBO");
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0);
[self informTargetsAboutNewFrameAtTime:frameTime];
}
@end
이 필터를 연결하면 "설치 완료"및 "VBO 그리기"가 콘솔에 표시됩니다. 그러나 대상 (이 경우 GPUImageView
)을 호출 한 후 glDrawArrays
을 사용하는 대상의 그리기 호출에서 충돌합니다.
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
다음은이 행을 포함하는 완전한 방법입니다.
- (void)newFrameReadyAtTime:(CMTime)frameTime;
{
[GPUImageOpenGLESContext useImageProcessingContext];
[self setDisplayFramebuffer];
[displayProgram use];
glClearColor(backgroundColorRed, backgroundColorGreen, backgroundColorBlue, backgroundColorAlpha);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
static const GLfloat textureCoordinates[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
};
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, inputTextureForDisplay);
glUniform1i(displayInputTextureUniform, 4);
glVertexAttribPointer(displayPositionAttribute, 2, GL_FLOAT, 0, 0, imageVertices);
glVertexAttribPointer(displayTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, textureCoordinates);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
[self presentFramebuffer];
}
어떤 도움을 주시면 감사하겠습니다. 잠시 머리를 숙였습니다.
죄송합니다. 붙여 넣기위한 것이 아닙니다. 나는 몇 가지 일로 어지럽 혔다. 원래 원래 0과 1이었습니다. 게시물 수정 중입니다. – MarkPowell