GPUImage에서 조각 셰이더에 배열을 전달하는 방법

13624 단어 iOSObjective-Cgpuimage
2016-11-14 NSArray용 추가

어쩌면 당연 너무 아무도 쓰지 않았겠지만, GPUImage에서는 처음으로 셰이더 만지는 내가 고생했기 때문에 정리했습니다.
뭔가 더 좋은 방법이 있으면 알려주세요.

GPUImageFilter를 상속한 클래스



GPUImageArrayTestFilter.h
#import <GPUImage/GPUImage.h>

@interface GPUImageArrayTestFilter : GPUImageFilter
{
  //配列のユニフォーム
  GLint testUniform;
  //長さのユニフォーム
  GLint sizeUniform;
}

//配列データを受け取るプロパティ
@property(readwrite, nonatomic) GLfloat *test;

//配列の長さも同時に指定するセッタ
-(void)setTest:(GLfloat *)test withSize:(GLsizei)size;

@end

GPUImageArrayTestFilter.m
#import "GPUImageArrayTestFilter.h"

//シェーダーをNSStringの文字列として用意する
NSString *const kGPUImageArrayTestShaderString = SHADER_STRING
(
 varying highp vec2 textureCoordinate;
 uniform sampler2D inputImageTexture;

//固定長しかダメ?
 uniform highp float test[256];
//実際に使う配列の長さ
 uniform highp int size;

 void main()
 {
  //基本は黒
   lowp vec3 color = vec3(0.0, 0.0, 0.0);

   //配列内で指定された矩形だけ赤くする
   for(int i = 0 ; i < size; i+=4){
     if(test[i] < textureCoordinate.x
        && textureCoordinate.x < test[i] + test[i + 2]
        && test[i+1] < textureCoordinate.y
        && textureCoordinate.y < test[i+1] + test[i+3]
        ){
       color = vec3(1.0, 0.0, 0.0);
       break;
     }
   }
   gl_FragColor = vec4(color, 1);
 }
 );

@implementation GPUImageArrayTestFilter

- (id)init{
  if (!(self = [super initWithFragmentShaderFromString:kGPUImageArrayTestShaderString]))
  {
    return nil;
  }
  //配列のuniformIndexを登録
  testUniform = [filterProgram uniformIndex:@"test"];
  //長さのuniformIndexを登録
  sizeUniform = [filterProgram uniformIndex:@"size"];

  return self;
}

//C言語の配列とその長さも同時に指定するセッタ
-(void)setTestCArr:(GLfloat *)test withSize:(GLsizei)size{
  _test = test;
  //配列のポインタをセット
  [self setFloatArray:_test length:size forUniform:testUniform program:filterProgram];
  //実際のデータのサイズをセット
  [self setInteger:size forUniform:_sizeUniform program:filterProgram];
}

//NSArrayを代入するセッタ
-(void)setTestNSArr:(NSArray*)test{
  float *cArr = (float*)malloc(sizeof(float*)*test.size);
  for(int i = 0 ; i < test.size ; i++){
   cArr[i] = [test[i] floatValue];
  }
  [self setTestCArr:cArr withSize:test.size];
  free(cArr);
}

//デフォルトのセッタは配列の長さを0としておく
-(void)setTest:(GLfloat *)test{
  [self setTest:test withSize:0];
}

@end

사용법



test.m

  //矩形表示用のテストデータ
  float test[8] = {
    //x,y,width,heightの順で入れている
    0.2, 0.2, 0.1, 0.1
    ,0.6, 0.2, 0.1, 0.1
  };

  GPUImageArrayTestFilter *filter = [GPUImageArrayTestFilter new];

  [filter setTestCArr:test withSize:8];

//あとはGPUImageのフィルタとして実行

실행 결과



이런 이미지를 할 수 있습니다.


마지막



이제 감지 된 각 얼굴 정보에 대해 뭔가를 처리하는 것처럼 보일 수 있습니다.

좋은 웹페이지 즐겨찾기