1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462 |
- //
- // FUOpenGLView.m
- // FULiveDemo
- //
- // Created by 刘洋 on 2017/8/15.
- // Copyright © 2017年 刘洋. All rights reserved.
- //
- #import "FUOpenGLView.h"
- #import <CoreVideo/CoreVideo.h>
- #import <OpenGLES/ES3/gl.h>
- #import <OpenGLES/ES3/glext.h>
- //#define use_capture
- #ifdef use_capture
- #import <libCNamaSDK/FURenderer.h>
- #else
- #endif
- #define STRINGIZE(x) #x
- #define STRINGIZE2(x) STRINGIZE(x)
- #define SHADER_STRING(text) @ STRINGIZE2(text)
- NSString *const FUYUVToRGBAFragmentShaderString = SHADER_STRING
- (
- varying highp vec2 textureCoordinate;
-
- uniform sampler2D luminanceTexture;
- uniform sampler2D chrominanceTexture;
- uniform mediump mat3 colorConversionMatrix;
-
- void main()
- {
- mediump vec3 yuv;
- lowp vec3 rgb;
-
- yuv.x = texture2D(luminanceTexture, textureCoordinate).r;
- yuv.yz = texture2D(chrominanceTexture, textureCoordinate).ra - vec2(0.5, 0.5);
- rgb = colorConversionMatrix * yuv;
-
- gl_FragColor = vec4(rgb, 1.0);
- }
- );
- NSString *const FURGBAFragmentShaderString = SHADER_STRING
- (
- uniform sampler2D inputImageTexture;
-
- varying highp vec2 textureCoordinate;
-
- void main()
- {
- gl_FragColor = vec4(texture2D(inputImageTexture, textureCoordinate).rgb,1.0);
- }
- );
- NSString *const FUVertexShaderString = SHADER_STRING
- (
- attribute vec4 position;
- attribute vec4 inputTextureCoordinate;
-
- varying vec2 textureCoordinate;
-
- void main()
- {
- gl_Position = position;
- textureCoordinate = inputTextureCoordinate.xy;
- }
- );
- NSString *const FUPointsFrgShaderString = SHADER_STRING
- (
- precision mediump float;
-
- varying highp vec4 fragmentColor;
-
- void main()
- {
- if (-smoothstep(0.48, 0.5, length(gl_PointCoord - vec2(0.5))) + 1.0 == 0.0) {
- discard;
- }
- gl_FragColor = fragmentColor;
- }
-
- );
- NSString *const FUPointsVtxShaderString = SHADER_STRING
- (
- attribute vec4 position;
-
- attribute float point_size;
-
- attribute vec4 inputColor;
-
- varying vec4 fragmentColor;
-
- void main()
- {
- gl_Position = position;
-
- gl_PointSize = point_size;
-
- fragmentColor = inputColor;
- }
- );
- enum
- {
- furgbaPositionAttribute,
- furgbaTextureCoordinateAttribute,
- fuPointSize,
- fuPointColor,
- };
- enum
- {
- fuyuvConversionPositionAttribute,
- fuyuvConversionTextureCoordinateAttribute
- };
- @interface FUOpenGLView(){
- dispatch_semaphore_t semaphore;
- }
- @property (nonatomic, strong) EAGLContext *glContext;
- @property(nonatomic) dispatch_queue_t contextQueue;
- @end
- @implementation FUOpenGLView
- {
- GLuint rgbaProgram;
- GLuint rgbaToYuvProgram;
- GLuint pointProgram;
-
- CVOpenGLESTextureCacheRef videoTextureCache;
-
- GLuint frameBufferHandle;
- GLuint renderBufferHandle;
-
- GLint yuvConversionLuminanceTextureUniform, yuvConversionChrominanceTextureUniform;
- GLint yuvConversionMatrixUniform;
- GLint displayInputTextureUniform;
-
- GLfloat vertices[8];
-
- int frameWidth;
- int frameHeight;
- int backingWidth;
- int backingHeight;
-
- CGSize boundsSizeAtFrameBufferEpoch;
-
- GLuint texture;
- }
- + (Class)layerClass
- {
- return [CAEAGLLayer class];
- }
- - (instancetype)initWithCoder:(NSCoder *)aDecoder
- {
- if (self = [super initWithCoder:aDecoder]) {
-
- self.disapplePointIndex = -1 ;
- _contextQueue = dispatch_queue_create("com.faceunity.contextQueue", DISPATCH_QUEUE_SERIAL);
-
- self.contentScaleFactor = [[UIScreen mainScreen] scale];
-
- CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
-
- eaglLayer.opaque = TRUE;
- eaglLayer.drawableProperties = @{ kEAGLDrawablePropertyRetainedBacking :[NSNumber numberWithBool:NO],
- kEAGLDrawablePropertyColorFormat : kEAGLColorFormatRGBA8};
-
- #ifdef use_capture
- [[FURenderer shareRenderer] setUpCurrentContext];
- _glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
- _glContext = [EAGLContext currentContext];
- #else
- _glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
- if (!_glContext) {
- NSLog(@"This devicde is not support OpenGLES3,try to create OpenGLES2");
- _glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
- }
- if (!self.glContext) {
- NSLog(@"failed to create context");
- }
- #endif
-
-
- if (!videoTextureCache) {
- CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, self.glContext, NULL, &videoTextureCache);
- if (err != noErr) {
- NSLog(@"Error at CVOpenGLESTextureCacheCreate %d", err);
- }
- }
- self.origintation = FUOpenGLViewOrientationPortrait ;
- self.contentMode = FUOpenGLViewContentModeScaleAspectFill;
- }
-
- return self;
- }
- - (instancetype)initWithFrame:(CGRect)frame{
- if (self = [super initWithFrame:frame] ) {
- self.disapplePointIndex = -1 ;
- _contextQueue = dispatch_queue_create("com.faceunity.contextQueue", DISPATCH_QUEUE_SERIAL);
-
- self.contentScaleFactor = [[UIScreen mainScreen] scale];
-
- CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
-
- eaglLayer.opaque = TRUE;
- eaglLayer.drawableProperties = @{ kEAGLDrawablePropertyRetainedBacking :[NSNumber numberWithBool:NO],
- kEAGLDrawablePropertyColorFormat : kEAGLColorFormatRGBA8};
-
- #ifdef use_capture
- [[FURenderer shareRenderer] setUpCurrentContext];
- _glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
- _glContext = [EAGLContext currentContext];
- #else
- _glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
- if (!_glContext) {
- NSLog(@"This devicde is not support OpenGLES3,try to create OpenGLES2");
- _glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
- }
- if (!self.glContext) {
- NSLog(@"failed to create context");
- }
- #endif
-
- if (!videoTextureCache) {
- CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, self.glContext, NULL, &videoTextureCache);
- if (err != noErr) {
- NSLog(@"Error at CVOpenGLESTextureCacheCreate %d", err);
- }
- }
- self.origintation = FUOpenGLViewOrientationPortrait ;
- self.contentMode = FUOpenGLViewContentModeScaleAspectFill;
- }
- return self;
- }
- - (void)layoutSubviews{
-
- [super layoutSubviews];
-
- // The frame buffer needs to be trashed and re-created when the view size changes.
- if (!CGSizeEqualToSize(self.bounds.size, boundsSizeAtFrameBufferEpoch) &&
- !CGSizeEqualToSize(self.bounds.size, CGSizeZero)) {
-
- boundsSizeAtFrameBufferEpoch = self.bounds.size;
-
- dispatch_async(_contextQueue, ^{
- [self destroyDisplayFramebuffer];
- [self createDisplayFramebuffer];
- [self updateVertices];
- });
- }
- }
- - (void)dealloc
- {
-
- dispatch_sync(_contextQueue, ^{
- [self destroyDisplayFramebuffer];
- [self destoryProgram];
- if(self->videoTextureCache) {
- CVOpenGLESTextureCacheFlush(self->videoTextureCache, 0);
- CFRelease(self->videoTextureCache);
- self->videoTextureCache = NULL;
-
- }
- });
- }
- - (void)createDisplayFramebuffer
- {
- NSLog(@"createDisplayFramebuffer -----");
- [EAGLContext setCurrentContext:self.glContext];
-
- glDisable(GL_DEPTH_TEST);
-
- glGenFramebuffers(1, &frameBufferHandle);
- glBindFramebuffer(GL_FRAMEBUFFER, frameBufferHandle);
-
- glGenRenderbuffers(1, &renderBufferHandle);
- glBindRenderbuffer(GL_RENDERBUFFER, renderBufferHandle);
- dispatch_sync(dispatch_get_main_queue(), ^{
- [self.glContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
- });
- glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
- if ( (backingWidth == 0) || (backingHeight == 0) )
- {
- [self destroyDisplayFramebuffer];
- return;
- }
-
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBufferHandle);
-
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
- NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
- }
- }
- - (void)destroyDisplayFramebuffer;
- {
- [EAGLContext setCurrentContext:self.glContext];
-
- if (frameBufferHandle)
- {
- glDeleteFramebuffers(1, &frameBufferHandle);
- frameBufferHandle = 0;
- }
-
- if (renderBufferHandle)
- {
- glDeleteRenderbuffers(1, &renderBufferHandle);
- renderBufferHandle = 0;
- }
- }
- - (void)setDisplayFramebuffer;
- {
- if (!frameBufferHandle)
- {
- [self createDisplayFramebuffer];
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER, frameBufferHandle);
-
- glViewport(0, 0, (GLint)backingWidth, (GLint)backingHeight);
- }
- - (void)setImageDisplayFramebuffer;
- {
- if (!frameBufferHandle)
- {
- [self createDisplayFramebuffer];
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER, frameBufferHandle);
-
- float bw = self.frame.size.width * [UIScreen mainScreen].scale ;
- float bh = self.frame.size.height * [UIScreen mainScreen].scale ;
- glViewport(0, 0, (GLint)bw, (GLint)bh);
- }
- - (void)destoryProgram{
- if (rgbaProgram) {
- glDeleteProgram(rgbaProgram);
- rgbaProgram = 0;
- }
-
- if (rgbaToYuvProgram) {
- glDeleteProgram(rgbaToYuvProgram);
- rgbaToYuvProgram = 0;
- }
-
- if (pointProgram) {
- glDeleteProgram(pointProgram);
- pointProgram = 0;
- }
- }
- - (void)presentFramebuffer;
- {
- glBindRenderbuffer(GL_RENDERBUFFER, renderBufferHandle);
- [self.glContext presentRenderbuffer:GL_RENDERBUFFER];
- // glFinish();
- }
- - (void)displayPixelBuffer:(CVPixelBufferRef)pixelBuffer
- {
- [self displayPixelBuffer:pixelBuffer withLandmarks:NULL count:0 MAX:NO];
- }
- - (void)displayPixelBuffer:(CVPixelBufferRef)pixelBuffer withLandmarks:(float *)landmarks count:(int)count MAX:(BOOL)max
- {
- #ifdef use_capture
- if (pixelBuffer == NULL) return;
-
- CVPixelBufferRetain(pixelBuffer);
- CVPixelBufferLockBaseAddress(pixelBuffer, 0);
- // dispatch_async(_contextQueue, ^{ //dispatch_sync iphone8p 可能死锁
- self->frameWidth = (int)CVPixelBufferGetWidth(pixelBuffer);
- self->frameHeight = (int)CVPixelBufferGetHeight(pixelBuffer);
-
- if ([EAGLContext currentContext] != self.glContext) {
- if (![EAGLContext setCurrentContext:self.glContext]) {
- NSLog(@"fail to setCurrentContext");
- }
- }
-
- [self setDisplayFramebuffer];
-
- OSType type = CVPixelBufferGetPixelFormatType(pixelBuffer);
- if (type == kCVPixelFormatType_32BGRA)
- {
- [self prepareToDrawBGRAPixelBuffer:pixelBuffer];
-
- }else{
- [self prepareToDrawYUVPixelBuffer:pixelBuffer];
- }
-
- if (landmarks) {
- [self prepareToDrawLandmarks:landmarks count:count MAX:max zoomScale:1];
- }
-
- [self presentFramebuffer];
-
- CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
- CVPixelBufferRelease(pixelBuffer);
- // });
- #else
- if (pixelBuffer == NULL) return;
-
- CVPixelBufferRetain(pixelBuffer);
- CVPixelBufferLockBaseAddress(pixelBuffer, 0);
- dispatch_async(_contextQueue, ^{ //dispatch_sync iphone8p 可能死锁
- self->frameWidth = (int)CVPixelBufferGetWidth(pixelBuffer);
- self->frameHeight = (int)CVPixelBufferGetHeight(pixelBuffer);
-
- if ([EAGLContext currentContext] != self.glContext) {
- if (![EAGLContext setCurrentContext:self.glContext]) {
- NSLog(@"fail to setCurrentContext");
- }
- }
-
- [self setDisplayFramebuffer];
-
- OSType type = CVPixelBufferGetPixelFormatType(pixelBuffer);
- if (type == kCVPixelFormatType_32BGRA)
- {
- [self prepareToDrawBGRAPixelBuffer:pixelBuffer];
-
- }else{
- [self prepareToDrawYUVPixelBuffer:pixelBuffer];
- }
-
- if (landmarks) {
- [self prepareToDrawLandmarks:landmarks count:count MAX:max zoomScale:1];
- }
-
- [self presentFramebuffer];
-
- CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
- CVPixelBufferRelease(pixelBuffer);
- });
- #endif
-
- }
- - (void)displaySyncPixelBuffer:(CVPixelBufferRef)pixelBuffer
- {
- if (pixelBuffer == NULL) return;
-
- CVPixelBufferRetain(pixelBuffer);
- CVPixelBufferLockBaseAddress(pixelBuffer, 0);
- // dispatch_async(_contextQueue, ^{ //dispatch_sync iphone8p 可能死锁
- self->frameWidth = (int)CVPixelBufferGetWidth(pixelBuffer);
- self->frameHeight = (int)CVPixelBufferGetHeight(pixelBuffer);
-
- if ([EAGLContext currentContext] != self.glContext) {
- if (![EAGLContext setCurrentContext:self.glContext]) {
- NSLog(@"fail to setCurrentContext");
- }
- }
-
- [self setDisplayFramebuffer];
-
- OSType type = CVPixelBufferGetPixelFormatType(pixelBuffer);
- if (type == kCVPixelFormatType_32BGRA)
- {
- [self prepareToDrawBGRAPixelBuffer:pixelBuffer];
-
- }else{
- [self prepareToDrawYUVPixelBuffer:pixelBuffer];
- }
-
- [self presentFramebuffer];
-
- CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
- CVPixelBufferRelease(pixelBuffer);
- // });
- }
- - (void)displayImageData:(void *)imageData withSize:(CGSize)size{
-
- frameWidth = (int)size.width;
- frameHeight = (int)size.height;
-
- if ([EAGLContext currentContext] != self.glContext) {
- if (![EAGLContext setCurrentContext:self.glContext]) {
- NSLog(@"fail to setCurrentContext");
- }
- }
- [self setDisplayFramebuffer];
-
- if (!rgbaProgram) {
- [self loadShadersRGBA];
- }
-
- if (texture == 0) {
- glGenTextures(1, &texture);
- }
-
- glBindTexture(GL_TEXTURE_2D, texture);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width, size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glUseProgram(rgbaProgram);
-
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, texture);
- glUniform1i(displayInputTextureUniform, 1);
-
- [self updateVertices];
-
- // 更新顶点数据
- glVertexAttribPointer(furgbaPositionAttribute, 2, GL_FLOAT, 0, 0, vertices);
- glEnableVertexAttribArray(furgbaPositionAttribute);
-
- GLfloat quadTextureData[] = {
- 0.0f, 1.0f,
- 1.0f, 1.0f,
- 0.0f, 0.0f,
- 1.0f, 0.0f,
- };
-
- glVertexAttribPointer(furgbaTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, quadTextureData);
- glEnableVertexAttribArray(furgbaTextureCoordinateAttribute);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- [self presentFramebuffer];
- }
- - (void)displayImageData:(void *)imageData withSize:(CGSize)size Center:(CGPoint)center Landmarks:(float *)landmarks count:(int)count {
-
- frameWidth = (int)size.width;
- frameHeight = (int)size.height;
-
- if ([EAGLContext currentContext] != self.glContext) {
- if (![EAGLContext setCurrentContext:self.glContext]) {
- NSLog(@"fail to setCurrentContext");
- }
- }
- [self setImageDisplayFramebuffer];
-
- if (!rgbaProgram) {
- [self loadShadersRGBA];
- }
-
- if (texture == 0) {
- glGenTextures(1, &texture);
- }
-
- glBindTexture(GL_TEXTURE_2D, texture);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width, size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glUseProgram(rgbaProgram);
-
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);;
- glClear(GL_COLOR_BUFFER_BIT);
-
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, texture);
- glUniform1i(displayInputTextureUniform, 1);
-
- [self updateVertices];
-
- // 更新顶点数据
- glVertexAttribPointer(furgbaPositionAttribute, 2, GL_FLOAT, 0, 0, vertices);
- glEnableVertexAttribArray(furgbaPositionAttribute);
-
- GLfloat quadTextureData[] = {
- center.x - 0.1, center.y + 0.1,
- center.x + 0.1, center.y + 0.1,
- center.x - 0.1, center.y - 0.1,
- center.x + 0.1, center.y - 0.1,
- };
-
- glVertexAttribPointer(furgbaTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, quadTextureData);
- glEnableVertexAttribArray(furgbaTextureCoordinateAttribute);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- if (landmarks) {
- [self drawImageLandmarks:landmarks count:count center:center];
- }
-
- [self presentFramebuffer];
- }
- - (void)drawImageLandmarks:(float *)landmarks count:(int)count center:(CGPoint)center
- {
- if (!pointProgram) {
- [self loadPointsShaders];
- }
-
- glUseProgram(pointProgram);
-
- count = count;
-
- float sizeData[count];
-
- float colorData[count * 4];
-
- float newLandmarks[count *2];
-
- float bw = self.frame.size.width * [UIScreen mainScreen].scale ;
- float bh = self.frame.size.height * [UIScreen mainScreen].scale ;
-
- const float width = frameWidth;
- const float height = frameHeight;
- const float dH = bh / height;
- const float dW = bw / width;
- const float dd = MAX(dH, dW);
- const float h = (height * dd / (float)bw) * 10/2;
- const float w = (width * dd / (float)bw) * 10/2;
-
- for (int i = 0; i < count/2; i++)
- {
- if (self.disapplePointIndex == i) {
- continue ;
- }
- //点的大小
- sizeData[i] = [UIScreen mainScreen].scale * 5;
-
- //点的颜色
- colorData[4 * i] = 1.0;
- colorData[4 * i + 1] = .0;
- colorData[4 * i + 2] = .0;
- colorData[4 * i + 3] = .0;
-
- //转化坐标
- newLandmarks[2 * i] = (float)((2 * landmarks[2 * i] / frameWidth - 1)) * w - (center.x - 0.5) * 2 * w;
-
- newLandmarks[2 * i + 1] = (float)(1 - 2 * landmarks[2 * i + 1] / frameHeight ) * h - (0.5 - center.y) * 2 * h;
- }
-
- for (int i = count/2; i < count; i++)
- {
- sizeData[i] = [UIScreen mainScreen].scale * 3;
-
- colorData[4 * i ] = 1.0;
- colorData[4 * i + 1] = 1.0;
- colorData[4 * i + 2] = 1.0;
- colorData[4 * i + 3] = 1.0;
-
- newLandmarks[2 * i] = (float)((2 * landmarks[2 * i - count] / frameWidth - 1)) * w - (center.x - 0.5) * 2 * w;
- newLandmarks[2 * i + 1] = (float)(1 - 2 * landmarks[2 * i + 1 - count] / frameHeight ) * h - (0.5 - center.y) * 2 * h;
- }
-
- glEnableVertexAttribArray(fuPointSize);
- glVertexAttribPointer(fuPointSize, 1, GL_FLOAT, GL_FALSE, 0, sizeData);
-
- glEnableVertexAttribArray(GLKVertexAttribPosition);
- glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, (GLfloat *)newLandmarks);
-
- glEnableVertexAttribArray(fuPointColor);
- glVertexAttribPointer(fuPointColor, 4, GL_FLOAT, GL_FALSE, 0, colorData);
-
- glDrawArrays(GL_POINTS, 0, count);
- }
- - (void)displayImageData:(void *)imageData Size:(CGSize)size Landmarks:(float *)landmarks count:(int)count zoomScale:(float)zoomScale{
-
- frameWidth = (int)size.width;
- frameHeight = (int)size.height;
-
- if ([EAGLContext currentContext] != self.glContext) {
- if (![EAGLContext setCurrentContext:self.glContext]) {
- NSLog(@"fail to setCurrentContext");
- }
- }
- [self setDisplayFramebuffer];
-
- if (!rgbaProgram) {
- [self loadShadersRGBA];
- }
-
- if (texture == 0) {
- glGenTextures(1, &texture);
- }
-
- glBindTexture(GL_TEXTURE_2D, texture);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width, size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glUseProgram(rgbaProgram);
-
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);;
- glClear(GL_COLOR_BUFFER_BIT);
-
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, texture);
- glUniform1i(displayInputTextureUniform, 1);
-
- [self updateVertices];
-
- // 更新顶点数据
- glVertexAttribPointer(furgbaPositionAttribute, 2, GL_FLOAT, 0, 0, vertices);
- glEnableVertexAttribArray(furgbaPositionAttribute);
-
- GLfloat quadTextureData[] = {
- 0.0f, 1.0f,
- 1.0f, 1.0f,
- 0.0f, 0.0f,
- 1.0f, 0.0f,
- };
-
- glVertexAttribPointer(furgbaTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, quadTextureData);
- glEnableVertexAttribArray(furgbaTextureCoordinateAttribute);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- if (landmarks) {
- [self prepareToDrawLandmarks:landmarks count:count MAX:NO zoomScale:zoomScale];
- }
-
- [self presentFramebuffer];
- }
- //- (void)updateVerticesRenderImage
- //{
- // const float width = frameWidth;
- // const float height = frameHeight;
- // const float dH = (float)backingHeight / height;
- // const float dW = (float)backingWidth / width;
- // const float dd = MIN(dH, dW);
- // const float h = (height * dd / (float)backingHeight);
- // const float w = (width * dd / (float)backingWidth );
- //
- // imageVertices[0] = - w;
- // imageVertices[1] = - h;
- // imageVertices[2] = w;
- // imageVertices[3] = - h;
- // imageVertices[4] = - w;
- // imageVertices[5] = h;
- // imageVertices[6] = w;
- // imageVertices[7] = h;
- //}
- - (void)prepareToDrawLandmarks:(float *)landmarks count:(int)count MAX:(BOOL)max zoomScale:(float)zoomScale
- {
- if (!pointProgram) {
- [self loadPointsShaders];
- }
-
- glUseProgram(pointProgram);
-
- count = count;
-
- float sizeData[count];
-
- float colorData[count * 4];
-
- float newLandmarks[count * 2];
-
- float width = frameWidth;
- float height = frameHeight;
- float dH = (float)backingHeight / height;
- float dW = (float)backingWidth / width;
- float dd = 0;
- if (max) {
- dd = MAX(dH, dW);
- }else {
- dd = MIN(dH, dW) ;
- }
- float h = (height * dd / (float)backingHeight);
- float w = (width * dd / (float)backingWidth );
-
- for (int i = 0; i < count / 2; i++)
- {
- //点的大小
- sizeData[i] = [UIScreen mainScreen].scale * 2 / zoomScale;
-
- colorData[4 * i ] = 1.0;
- colorData[4 * i + 1] = 0.0;
- colorData[4 * i + 2] = 0.0;
- colorData[4 * i + 3] = 0.0;
-
- //转化坐标
- newLandmarks[2 * i] = (float)((2 * landmarks[2 * i] / frameWidth - 1))*w;
- newLandmarks[2 * i + 1] = (float)(1 - 2 * landmarks[2 * i + 1] / frameHeight)*h;
- }
-
- for (int i = count/2; i < count; i++)
- {
- sizeData[i] = [UIScreen mainScreen].scale / zoomScale;
- colorData[4 * i ] = 1.0;
- colorData[4 * i + 1] = 1.0;
- colorData[4 * i + 2] = 1.0;
- colorData[4 * i + 3] = 1.0;
- newLandmarks[2 * i] = (float)((2 * landmarks[2 * i - count] / frameWidth - 1))*w;
- newLandmarks[2 * i + 1] = (float)(1 - 2 * landmarks[2 * i + 1 - count] / frameHeight)*h;
- }
-
- glEnableVertexAttribArray(fuPointSize);
- glVertexAttribPointer(fuPointSize, 1, GL_FLOAT, GL_FALSE, 0, sizeData);
-
- glEnableVertexAttribArray(GLKVertexAttribPosition);
- glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, (GLfloat *)newLandmarks);
-
- glEnableVertexAttribArray(fuPointColor);
- glVertexAttribPointer(fuPointColor, 4, GL_FLOAT, GL_FALSE, 0, colorData);
-
- glDrawArrays(GL_POINTS, 0, count);
- }
- - (void)prepareToDrawBGRAPixelBuffer:(CVPixelBufferRef)pixelBuffer
- {
- if (!rgbaProgram) {
- [self loadShadersRGBA];
- }
-
- CVOpenGLESTextureRef rgbaTexture = NULL;
- CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, videoTextureCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_RGBA, frameWidth, frameHeight, GL_BGRA, GL_UNSIGNED_BYTE, 0, &rgbaTexture);
-
- if (!rgbaTexture || err) {
-
- NSLog(@"Camera CVOpenGLESTextureCacheCreateTextureFromImage failed (error: %d)", err);
- return;
- }
-
- glBindTexture(GL_TEXTURE_2D, CVOpenGLESTextureGetName(rgbaTexture));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glUseProgram(rgbaProgram);
-
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glActiveTexture(GL_TEXTURE4);
- glBindTexture(GL_TEXTURE_2D, CVOpenGLESTextureGetName(rgbaTexture));
- glUniform1i(displayInputTextureUniform, 4);
-
- [self updateVertices];
-
- // 更新顶点数据
- glVertexAttribPointer(furgbaPositionAttribute, 2, GL_FLOAT, 0, 0, vertices);
- glEnableVertexAttribArray(furgbaPositionAttribute);
-
- GLfloat quadTextureData[] = {
- 0.0f, 1.0f,
- 1.0f, 1.0f,
- 0.0f, 0.0f,
- 1.0f, 0.0f,
- };
-
- if (_origintation == FUOpenGLViewOrientationPortrait) {
- float quadTextureData0[] = {
- 0.0f, 1.0f,
- 1.0f, 1.0f,
- 0.0f, 0.0f,
- 1.0f, 0.0f,
- };
- memcpy(quadTextureData, quadTextureData0, sizeof(quadTextureData));
- }
-
- if (_origintation == FUOpenGLViewOrientationLandscapeRight) {
- float quadTextureData0[] = {
- 1.0f, 1.0f,
- 1.0f, 0.0f,
- 0.0f, 1.0f,
- 0.0f, 0.0f,
- };
-
- memcpy(quadTextureData, quadTextureData0, sizeof(quadTextureData));
- }
-
- if (_origintation == FUOpenGLViewOrientationPortraitUpsideDown) {
- float quadTextureData0[] = {
- 1.0f, 0.0f,
- 0.0f, 0.0f,
- 1.0f, 1.0f,
- 0.0f, 1.0f,
- };
-
- memcpy(quadTextureData, quadTextureData0, sizeof(quadTextureData));
- }
-
- if (_origintation == FUOpenGLViewOrientationLandscapeLeft) {
- float quadTextureData0[] = {
- 0.0f, 0.0f,
- 0.0f, 1.0f,
- 1.0f, 0.0f,
- 1.0f, 1.0f,
- };
- memcpy(quadTextureData, quadTextureData0, sizeof(quadTextureData));
- }
-
-
- glVertexAttribPointer(furgbaTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, quadTextureData);
- glEnableVertexAttribArray(furgbaTextureCoordinateAttribute);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- if (rgbaTexture) {
- CFRelease(rgbaTexture);
- rgbaTexture = NULL;
- }
- }
- - (void)prepareToDrawYUVPixelBuffer:(CVPixelBufferRef)pixelBuffer
- {
- if (!rgbaToYuvProgram) {
- [self loadShadersYUV];
- }
-
- CVReturn err;
- CVOpenGLESTextureRef luminanceTextureRef = NULL;
- CVOpenGLESTextureRef chrominanceTextureRef = NULL;
-
- /*
- CVOpenGLESTextureCacheCreateTextureFromImage will create GLES texture optimally from CVPixelBufferRef.
- */
-
- /*
- Create Y and UV textures from the pixel buffer. These textures will be drawn on the frame buffer Y-plane.
- */
- glActiveTexture(GL_TEXTURE0);
- err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
- videoTextureCache,
- pixelBuffer,
- NULL,
- GL_TEXTURE_2D,
- GL_LUMINANCE,
- frameWidth,
- frameHeight,
- GL_LUMINANCE,
- GL_UNSIGNED_BYTE,
- 0,
- &luminanceTextureRef);
- if (err) {
- NSLog(@"Error at CVOpenGLESTextureCacheCreateTextureFromImage %d", err);
- }
-
- glBindTexture(GL_TEXTURE_2D, CVOpenGLESTextureGetName(luminanceTextureRef));
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- // UV-plane.
- glActiveTexture(GL_TEXTURE1);
- err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
- videoTextureCache,
- pixelBuffer,
- NULL,
- GL_TEXTURE_2D,
- GL_LUMINANCE_ALPHA,
- frameWidth / 2,
- frameHeight / 2,
- GL_LUMINANCE_ALPHA,
- GL_UNSIGNED_BYTE,
- 1,
- &chrominanceTextureRef);
- if (err) {
- NSLog(@"Error at CVOpenGLESTextureCacheCreateTextureFromImage %d", err);
- }
-
- glBindTexture(GL_TEXTURE_2D, CVOpenGLESTextureGetName(chrominanceTextureRef));
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glClearColor(0.1f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- // Use shader program.
- glUseProgram(rgbaToYuvProgram);
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, CVOpenGLESTextureGetName(luminanceTextureRef));
- glUniform1i(yuvConversionLuminanceTextureUniform, 0);
-
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, CVOpenGLESTextureGetName(chrominanceTextureRef));
- glUniform1i(yuvConversionChrominanceTextureUniform, 1);
-
- GLfloat kColorConversion601FullRange[] = {
- 1.0, 1.0, 1.0,
- 0.0, -0.343, 1.765,
- 1.4, -0.711, 0.0,
- };
-
- glUniformMatrix3fv(yuvConversionMatrixUniform, 1, GL_FALSE, kColorConversion601FullRange);
-
- // 更新顶点数据
- [self updateVertices];
-
- glVertexAttribPointer(fuyuvConversionPositionAttribute, 2, GL_FLOAT, 0, 0, vertices);
- glEnableVertexAttribArray(fuyuvConversionPositionAttribute);
-
- GLfloat quadTextureData[] = {
- 0.0f, 1.0f,
- 1.0f, 1.0f,
- 0.0f, 0.0f,
- 1.0f, 0.0f,
- };
-
- if (_origintation == FUOpenGLViewOrientationPortrait) {
- float quadTextureData0[] = {
- 0.0f, 1.0f,
- 1.0f, 1.0f,
- 0.0f, 0.0f,
- 1.0f, 0.0f,
- };
- memcpy(quadTextureData, quadTextureData0, sizeof(quadTextureData));
- }
-
- if (_origintation == FUOpenGLViewOrientationLandscapeRight) {
- float quadTextureData0[] = {
- 1.0f, 1.0f,
- 1.0f, 0.0f,
- 0.0f, 1.0f,
- 0.0f, 0.0f,
- };
-
- memcpy(quadTextureData, quadTextureData0, sizeof(quadTextureData));
- }
-
- if (_origintation == FUOpenGLViewOrientationPortraitUpsideDown) {
- float quadTextureData0[] = {
- 1.0f, 0.0f,
- 0.0f, 0.0f,
- 1.0f, 1.0f,
- 0.0f, 1.0f,
- };
-
- memcpy(quadTextureData, quadTextureData0, sizeof(quadTextureData));
- }
-
- if (_origintation == FUOpenGLViewOrientationLandscapeLeft) {
- float quadTextureData0[] = {
- 0.0f, 0.0f,
- 0.0f, 1.0f,
- 1.0f, 0.0f,
- 1.0f, 1.0f,
- };
- memcpy(quadTextureData, quadTextureData0, sizeof(quadTextureData));
- }
-
-
- glVertexAttribPointer(fuyuvConversionTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, quadTextureData);
- glEnableVertexAttribArray(fuyuvConversionTextureCoordinateAttribute);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- if (luminanceTextureRef) {
- CFRelease(luminanceTextureRef);
- luminanceTextureRef = NULL;
- }
-
- if (chrominanceTextureRef) {
- CFRelease(chrominanceTextureRef);
- chrominanceTextureRef = NULL;
- }
-
- }
- - (void)updateVertices
- {
- float height = frameHeight;
- float width = frameWidth;
- if (_origintation == FUOpenGLViewOrientationLandscapeRight || _origintation == FUOpenGLViewOrientationLandscapeLeft) {
- height = frameWidth;
- width = frameHeight;
- }
-
- float dH = (float)backingHeight / height;
- float dW = (float)backingWidth / width;
-
- if(_contentMode == FUOpenGLViewContentModeScaleToFill){
- vertices[0] = - 1;
- vertices[1] = - 1;
- vertices[2] = 1;
- vertices[3] = - 1;
- vertices[4] = - 1;
- vertices[5] = 1;
- vertices[6] = 1;
- vertices[7] = 1;
- }
-
- if (_contentMode == FUOpenGLViewContentModeScaleAspectFill) {
- float dd = MAX(dH, dW) ;
- float h = (height * dd / (float)backingHeight);
- float w = (width * dd / (float)backingWidth );
-
- vertices[0] = - w;
- vertices[1] = - h;
- vertices[2] = w;
- vertices[3] = - h;
- vertices[4] = - w;
- vertices[5] = h;
- vertices[6] = w;
- vertices[7] = h;
- }
-
- if (_contentMode == FUOpenGLViewContentModeScaleAspectFit) {
- float dd = MIN(dH, dW) ;
- float h = (height * dd / (float)backingHeight);
- float w = (width * dd / (float)backingWidth );
-
- vertices[0] = - w;
- vertices[1] = - h;
- vertices[2] = w;
- vertices[3] = - h;
- vertices[4] = - w;
- vertices[5] = h;
- vertices[6] = w;
- vertices[7] = h;
- }
- }
- #pragma mark - OpenGL ES 2 shader compilation
- - (BOOL)loadShadersRGBA
- {
- GLuint vertShader, fragShader;
-
- if (!rgbaProgram) {
- rgbaProgram = glCreateProgram();
- }
-
- // Create and compile the vertex shader.
- if (![self compileShader:&vertShader type:GL_VERTEX_SHADER string:FUVertexShaderString]) {
- NSLog(@"Failed to compile vertex shader");
- return NO;
- }
-
- // Create and compile fragment shader.
- if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER string:FURGBAFragmentShaderString]) {
- NSLog(@"Failed to compile fragment shader");
- return NO;
- }
-
- // Attach vertex shader to program.
- glAttachShader(rgbaProgram, vertShader);
-
- // Attach fragment shader to program.
- glAttachShader(rgbaProgram, fragShader);
-
- // Bind attribute locations. This needs to be done prior to linking.
- glBindAttribLocation(rgbaProgram, furgbaPositionAttribute, "position");
- glBindAttribLocation(rgbaProgram, furgbaTextureCoordinateAttribute, "inputTextureCoordinate");
-
- // Link the program.
- if (![self linkProgram:rgbaProgram]) {
- NSLog(@"Failed to link program: %d", rgbaProgram);
-
- if (vertShader) {
- glDeleteShader(vertShader);
- vertShader = 0;
- }
- if (fragShader) {
- glDeleteShader(fragShader);
- fragShader = 0;
- }
- if (rgbaProgram) {
- glDeleteProgram(rgbaProgram);
- rgbaProgram = 0;
- }
-
- return NO;
- }
-
- // Get uniform locations.
- displayInputTextureUniform = glGetUniformLocation(rgbaProgram, "inputImageTexture");
-
- // Release vertex and fragment shaders.
- if (vertShader) {
- glDetachShader(rgbaProgram, vertShader);
- glDeleteShader(vertShader);
- }
- if (fragShader) {
- glDetachShader(rgbaProgram, fragShader);
- glDeleteShader(fragShader);
- }
-
- return YES;
- }
- - (BOOL)loadShadersYUV
- {
- GLuint vertShader, fragShader;
-
- if (!rgbaToYuvProgram) {
- rgbaToYuvProgram = glCreateProgram();
- }
-
- // Create and compile the vertex shader.
- if (![self compileShader:&vertShader type:GL_VERTEX_SHADER string:FUVertexShaderString]) {
- NSLog(@"Failed to compile vertex shader");
- return NO;
- }
-
- // Create and compile fragment shader.
- if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER string:FUYUVToRGBAFragmentShaderString]) {
- NSLog(@"Failed to compile fragment shader");
- return NO;
- }
-
- // Attach vertex shader to rgbaToYuvProgram.
- glAttachShader(rgbaToYuvProgram, vertShader);
-
- // Attach fragment shader to rgbaToYuvProgram.
- glAttachShader(rgbaToYuvProgram, fragShader);
-
- // Bind attribute locations. This needs to be done prior to linking.
- glBindAttribLocation(rgbaToYuvProgram, fuyuvConversionPositionAttribute, "position");
- glBindAttribLocation(rgbaToYuvProgram, fuyuvConversionTextureCoordinateAttribute, "inputTextureCoordinate");
-
- // Link the rgbaToYuvProgram.
- if (![self linkProgram:rgbaToYuvProgram]) {
- NSLog(@"Failed to link program: %d", rgbaToYuvProgram);
-
- if (vertShader) {
- glDeleteShader(vertShader);
- vertShader = 0;
- }
- if (fragShader) {
- glDeleteShader(fragShader);
- fragShader = 0;
- }
- if (rgbaToYuvProgram) {
- glDeleteProgram(rgbaToYuvProgram);
- rgbaToYuvProgram = 0;
- }
-
- return NO;
- }
-
- // Get uniform locations.
- yuvConversionLuminanceTextureUniform = glGetUniformLocation(rgbaToYuvProgram, "luminanceTexture");
- yuvConversionChrominanceTextureUniform = glGetUniformLocation(rgbaToYuvProgram, "chrominanceTexture");
- yuvConversionMatrixUniform = glGetUniformLocation(rgbaToYuvProgram, "colorConversionMatrix");
-
- // Release vertex and fragment shaders.
- if (vertShader) {
- glDetachShader(rgbaToYuvProgram, vertShader);
- glDeleteShader(vertShader);
- }
- if (fragShader) {
- glDetachShader(rgbaToYuvProgram, fragShader);
- glDeleteShader(fragShader);
- }
-
- glUseProgram(rgbaToYuvProgram);
-
- return YES;
- }
- - (BOOL)loadPointsShaders
- {
- GLuint vertShader, fragShader;
-
- pointProgram = glCreateProgram();
-
- // Create and compile the vertex shader.
- if (![self compileShader:&vertShader type:GL_VERTEX_SHADER string:FUPointsVtxShaderString]) {
- NSLog(@"Failed to compile vertex shader");
- return NO;
- }
-
- // Create and compile fragment shader.
- if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER string:FUPointsFrgShaderString]) {
- NSLog(@"Failed to compile fragment shader");
- return NO;
- }
-
- // Attach vertex shader to program.
- glAttachShader(pointProgram, vertShader);
-
- // Attach fragment shader to program.
- glAttachShader(pointProgram, fragShader);
-
- // Bind attribute locations. This needs to be done prior to linking.
- glBindAttribLocation(pointProgram, fuPointSize, "point_size");
- glBindAttribLocation(pointProgram, fuPointColor, "inputColor");
-
- // Link the program.
- if (![self linkProgram:pointProgram]) {
- NSLog(@"Failed to link program: %d", pointProgram);
-
- if (vertShader) {
- glDeleteShader(vertShader);
- vertShader = 0;
- }
- if (fragShader) {
- glDeleteShader(fragShader);
- fragShader = 0;
- }
- if (pointProgram) {
- glDeleteProgram(pointProgram);
- pointProgram = 0;
- }
-
- return NO;
- }
-
- // Release vertex and fragment shaders.
- if (vertShader) {
- glDetachShader(pointProgram, vertShader);
- glDeleteShader(vertShader);
- }
- if (fragShader) {
- glDetachShader(pointProgram, fragShader);
- glDeleteShader(fragShader);
- }
-
- return YES;
- }
- - (BOOL)compileShader:(GLuint *)shader type:(GLenum)type string:(NSString *)shaderString
- {
- GLint status;
- const GLchar *source;
- source = (GLchar *)[shaderString UTF8String];
-
- *shader = glCreateShader(type);
- glShaderSource(*shader, 1, &source, NULL);
- glCompileShader(*shader);
-
- #if defined(DEBUG)
- GLint logLength;
- glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
- if (logLength > 0) {
- GLchar *log = (GLchar *)malloc(logLength);
- glGetShaderInfoLog(*shader, logLength, &logLength, log);
- NSLog(@"Shader compile log:\n%s", log);
- free(log);
- }
- #endif
-
- glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
- if (status == 0) {
- glDeleteShader(*shader);
- return NO;
- }
-
- return YES;
- }
- - (BOOL)linkProgram:(GLuint)prog
- {
- GLint status;
- glLinkProgram(prog);
-
- #if defined(DEBUG)
- GLint logLength;
- glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
- if (logLength > 0) {
- GLchar *log = (GLchar *)malloc(logLength);
- glGetProgramInfoLog(prog, logLength, &logLength, log);
- NSLog(@"Program link log:\n%s", log);
- free(log);
- }
- #endif
-
- glGetProgramiv(prog, GL_LINK_STATUS, &status);
- if (status == 0) {
- return NO;
- }
-
- return YES;
- }
- - (BOOL)validateProgram:(GLuint)prog
- {
- GLint logLength, status;
-
- glValidateProgram(prog);
- glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
- if (logLength > 0) {
- GLchar *log = (GLchar *)malloc(logLength);
- glGetProgramInfoLog(prog, logLength, &logLength, log);
- NSLog(@"Program validate log:\n%s", log);
- free(log);
- }
-
- glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
- if (status == 0) {
- return NO;
- }
-
- return YES;
- }
- - (UIColor*)getColorWithPoint:(CGPoint)point{
- __block UIColor *color = nil;
- semaphore = dispatch_semaphore_create(0);
- float imageW = frameWidth;
- float imageH = frameHeight;
-
- point = CGPointMake(point.x/self.bounds.size.width,point.y/self.bounds.size.height);
- point.x = point.x * backingWidth;
- point.y = (1- point.y)* backingHeight;
- dispatch_async(_contextQueue, ^{
- if ([EAGLContext currentContext] != self.glContext) {
- if (![EAGLContext setCurrentContext:self.glContext]) {
- NSLog(@"fail to setCurrentContext");
- }
- }
-
- [self setDisplayFramebuffer];
-
- GLubyte aa[4] = {0};
- GLint aaa = (GLint)point.x;
- GLint bb = (GLint)point.y;
- glReadPixels(aaa,bb,1, 1, GL_BGRA, GL_UNSIGNED_BYTE, aa);
- color = [UIColor colorWithRed:(aa[2]/255.0f) green:(aa[1]/255.0f) blue:(aa[0]/255.0f) alpha:(aa[3]/255.0f)];
-
- dispatch_semaphore_signal(semaphore);
- });
- dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
- return color;
- }
- @end
|