精华内容
下载资源
问答
  • GLKView
    2021-02-08 19:53:59

    与其控制GLKView的大小,或是在游戏层面避开“刘海”,不如直接控制window大小剔除“刘海”区域,view层使用通用的绘制方案。

    class AppDelegate: UIResponder, UIApplicationDelegate {
        var window: UIWindow?
    
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    		
    		// 判断是否有刘海
            if (window?.safeAreaInsets.bottom ?? 0 > 0)
            {
                var bounds         = UIScreen.main.bounds
                // 直接把刘海剔除
                bounds.size.width -= 44
                window?.frame      = bounds
            }
            
            return true
        }
    }
    
    更多相关内容
  • iOS OpenGL GLKView GLKit 详解

    万次阅读 2016-08-06 20:29:02
    GLKView *glkView = (GLKView *)self.view; glkView.context = self.context; // drawableColorFormat // 你的OpenGL上下文有一个缓冲区,它用以存储将在屏幕中显示的颜色。你可以使用其属性来设置缓冲区中每个...


    //
    //  ViewController.m
    //  test_opengl_02
    //
    //  Created by jeffasd on 16/8/5.
    //  Copyright © 2016年 jeffasd. All rights reserved.
    //
    
    #import "ViewController.h"
    
     顶点坐标既法线和纹理
    //GLfloat squareVertexData[48] = {
    //    
    //    0.5f, 0.5f, -0.9f,     0.0f, 0.0f, 1.0f,   1.0f, 1.0f,//0
    //    -0.5f, 0.5f, -0.9f,     0.0f, 0.0f, 1.0f,   0.0f, 1.0f,//1
    //    0.5f, -0.5f, -0.9f,     0.0f, 0.0f, 0.0f,   1.0f, 0.0f,//2
    //    0.5f, -0.5f, -0.9f,     0.0f, 0.0f, 0.0f,   1.0f, 0.0f,//2
    //    -0.5f, 0.5f, -0.9f,     0.0f, 0.0f, 1.0f,   0.0f, 1.0f,//1
    //    -0.5f, -0.5f, -0.9f,     0.0f, 0.0f, 1.0f,   0.0f, 0.0f//3
    //};
    
    // 顶点坐标既法线和纹理
    //GLfloat squareVertexData[48] = {
    //    
    //    0.5f, 0.5f, -0.9f,     0.0f, 0.0f, 1.0f,   1.0f, 1.0f,//0
    //    -0.5f, 0.5f, -0.9f,     0.0f, 0.0f, 1.0f,   0.0f, 1.0f,//1
    //    0.5f, -0.5f, -0.9f,     0.0f, 0.0f, 0.0f,   1.0f, 0.0f,//2
    //    -0.5f, -0.5f, -0.9f,     0.0f, 0.0f, 1.0f,   0.0f, 0.0f,//3
    //    0.5f, -0.5f, -0.9f,     0.0f, 0.0f, 0.0f,   1.0f, 0.0f,//2
    //    -0.5f, 0.5f, -0.9f,     0.0f, 0.0f, 1.0f,   0.0f, 1.0f//1
    //    
    //};
    
    typedef struct {
        GLfloat Positon[3];//位置
        GLfloat Normal[3];//法线
        GLfloat Color[4];//颜色
        GLfloat TexCoord[2];//纹理
    } Vertex;
    
    // 顶点坐标既法线和纹理
    const Vertex squareVertexData[] = {
        
        {0.5f, 0.5f, -0.9f, 0.0f, 0.0f, 1.0f,  1.0f, 0.0f, 0.0f, 1.0f,  1.0f, 1.0f},//0
        {-0.5f, 0.5f, -0.9f, 0.0f, 0.0f, 1.0f,  1.0f, 0.0f, 0.0f, 1.0f,  0.0f, 1.0f},//1
        {0.5f, -0.5f, -0.9f, 0.0f, 0.0f, 0.0f,  1.0f, 0.0f, 0.0f, 1.0f,  1.0f, 0.0f},//2
        {-0.5f, -0.5f, -0.9f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,  0.0f, 0.0f}//3
        
    };
    
    
    const GLubyte Indices[] = {
        0, 1, 2,
        2, 1, 3
    };
    
    //每行顶点数据的排列含义是:
    //
    //顶点X、顶点Y,顶点Z、法线X、法线Y、法线Z、纹理S、纹理T。
    //
    //在后面解析此数组时,将参考此规则。
    //
    //顶点位置用于确定在什么地方显示,法线用于光照模型计算,纹理则用在贴图中。
    //
    //一般约定为“顶点以逆时针次序出现在屏幕上的面”为“正面”。
    //
    //世界坐标是OpenGL中用来描述场景的坐标,Z+轴垂直屏幕向外,X+从左到右,Y+轴从下到上,是右手笛卡尔坐标系统。我们用这个坐标系来描述物体及光源的位置。
    
    @interface ViewController ()
    
    @property (nonatomic, strong) EAGLContext *context;
    @property (nonatomic, strong) GLKBaseEffect *effect;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
    //    self.view.backgroundColor = [UIColor whiteColor];
        
        
        self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
        
        if (!_context) {
            NSLog(@"faile to init context");
        }
        
        GLKView *glkView = (GLKView *)self.view;
        glkView.context = self.context;
        
    //    drawableColorFormat
    //    你的OpenGL上下文有一个缓冲区,它用以存储将在屏幕中显示的颜色。你可以使用其属性来设置缓冲区中每个像素的颜色格式。
    //    缺省值是GLKViewDrawableColorFormatRGBA8888,即缓冲区的每个像素的最小组成部分(-个像素有四个元素组成 RGBA)使用8个bit(如R使用8个bit)(所以每个像素4个字节 既 4*8 个bit)。这非常好,因为它给了你提供了最广泛的颜色范围,让你的app看起来更好。
    //    但是如果你的app允许更小范围的颜色,你可以设置为GLKViewDrawableColorFormatRGB565,从而使你的app消耗更少的资源(内存和处理时间)。
        glkView.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
        
        
    //    drawableDepthFormat
    //    你的OpenGL上下文还可以(可选地)有另一个缓冲区,称为深度缓冲区。这帮助我们确保更接近观察者的对象显示在远一些的对象的前面(意思就是离观察者近一些的对象会挡住在它后面的对象)。
    //    其缺省的工作方式是:OpenGL把接近观察者的对象的所有像素存储到深度缓冲区,当开始绘制一个像素时,它(OpenGL)首先检查深度缓冲区,看是否已经绘制了更接近观察者的什么东西,如果是则忽略它(要绘制的像素,就是说,在绘制一个像素之前,看看前面有没有挡着它的东西,如果有那就不用绘制了)。否则,把它增加到深度缓冲区和颜色缓冲区。
    //    你可以设置这个属性,以选择深度缓冲区的格式。缺省值是GLKViewDrawableDepthFormatNone,意味着完全没有深度缓冲区。
    //    但是如果你要使用这个属性(一般用于3D游戏),你应该选择GLKViewDrawableDepthFormat16或GLKViewDrawableDepthFormat24。这里的差别是使用GLKViewDrawableDepthFormat16将消耗更少的资源,但是当对象非常接近彼此时,你可能存在渲染问题()。
        glkView.drawableDepthFormat = GLKViewDrawableDepthFormat24;
        
    //    将此“EAGLContext”实例设置为OpenGL的“当前激活”的“Context”。这样,以后所有“GL”的指令均作用在这个“Context”上。随后,发送第一个“GL”指令:激活“深度检测”。
        [EAGLContext setCurrentContext:_context];
        glEnable(GL_DEPTH_TEST);//发送第一个“GL”指令:激活“深度检测”。
        
    //    创建一个GLK内置的“着色效果”,并给它提供一个光源,光的颜色为绿色。
        
    //    iOS的OpenGL中里有2个着色器,
    //    一个是GLKBaseEffect,为了方便OpenGL ES 1.0转移到2.0的通用着色器。
    //    一个是OpenGL ES 2.0新添加的可编程着色器,使用跨平台的着色语言
        //    //实例化基础效果实例,如果没有GLKit与GLKBaseEffect类,就需要为这个简单的例子编写一个小的GPU程序,使用2.0的Shading Language,而GLKBaseEffect会在需要的时候自动的构建GPU程序。
        
        self.effect = [[GLKBaseEffect alloc] init];
        self.effect.light0.enabled = GL_TRUE;
    //    self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
        self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.0f, 0.0f, 1.0f);
        
    //    //实例化基础效果实例,如果没有GLKit与GLKBaseEffect类,就需要为这个简单的例子编写一个小的GPU程序,使用2.0的Shading Language,而GLKBaseEffect会在需要的时候自动的构建GPU程序。
    //    self.baseEffect = [[GLKBaseEffect alloc] init];
    //    self.baseEffect.useConstantColor = GL_TRUE;
    //    
    //    //控制渲染像素颜色的方式有多种。这个应用的GLKBaseEffect实例使用一个恒定不变的白色来渲染三角形。
    //    //下面代码中使用的再GLKit中定义的用于保存4个颜色元素值的C数据结构体GLKVector4来设置这个恒定值。
    //    self.baseEffect.constantColor = GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f);
        
        
    //    将顶点数据写入通用的顶点属性存储区
    //
        //1.写入过程
    //    首先将数据保存进GUP的一个缓冲区中,然后再按一定规则,将数据取出,复制到各个通用顶点属性中。
    //    注:如果顶点数据只有一种类型(如单纯的位置坐标),换言之,在读数据时,不需要确定第一个数据的内存位置(总是从0开始),则不必事先保存进缓冲区。
    //    
    //    2.顶点数组保存进缓冲区
        //Vertex Data
        GLuint buffer;
        glGenBuffers(1, &buffer);
        glBindBuffer(GL_ARRAY_BUFFER, buffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(squareVertexData), squareVertexData, GL_STATIC_DRAW);
        //    这几行代码表示的含义是:声明一个缓冲区的标识(GLuint类型)à让OpenGL自动分配一个缓冲区并且返回这个标识的值à绑定这个缓冲区到当前“Context”à最后,将我们前面预先定义的顶点数据“squareVertexData”复制进这个缓冲区中。
        
    //    注:参数“GL_STATIC_DRAW”,它表示此缓冲区内容只能被修改一次,但可以无限次读取。
        
        GLuint elementBuffer;
        glGenBuffers(1, &elementBuffer);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
        
        
    //    3、将缓冲区的数据复制进通用顶点属性中
        glEnableVertexAttribArray(GLKVertexAttribPosition);
    //    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 4*8, 0);
        glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
    //    首先,激活顶点属性(默认它的关闭的)。“GLKVertexAttribPosition”是顶点属性集中“位置Position”属性的索引。
    //    
    //    顶点属性集中包含五种属性:位置、法线、颜色、纹理0,纹理1。
    //    
    //    它们的索引值是0到4。
    //    
    //    激活后,接下来使用“glVertexAttribPointer”方法填充数据。
    //    
    //    参数含义分别为:
    //    
    //    顶点属性索引(这里是位置)、3个分量的矢量、类型是浮点(GL_FLOAT)、填充时不需要单位化(GL_FALSE)、在数据数组中每行的跨度是32个字节(4*8=32。从预定义的数组中可看出,每行有8个GL_FLOAT浮点值,而GL_FLOAT占4个字节,因此每一行的跨度是4*8)。
    //    
    //    最后一个参数是一个偏移量的指针,用来确定“第一个数据”将从内存数据块的什么地方开始。
        
        
    //    在前面预定义的顶点数据数组中,还包含了法线和纹理坐标,所以参照上面的方法,将剩余的数据分别复制进通用顶点属性中。
        glEnableVertexAttribArray(GLKVertexAttribNormal);
        glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid *) (sizeof(GLfloat) * 3));
    //    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 4*8, (char *) + 12);
        
        
    //    GLKVertexAttribColor
        
        glEnableVertexAttribArray(GLKVertexAttribColor);
        //glVertexAttribPointer 指定了渲染时索引值为 GLKVertexAttribColor 的顶点属性数组的数据格式和位置
        glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid *) (sizeof(GLfloat) * 6));
        
        glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    //    glVertexAttribPointer(GLKVertexAttribTexCoord0, 3, GL_FLOAT, GL_FALSE, 4*8, (char *) + 24);
        //glVertexAttribPointer 指定了渲染时索引值为 GLKVertexAttribTexCoord0 的顶点属性数组的数据格式和位置
        glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid *) (sizeof(GLfloat) * 10));
        
    }
    
    
    //这两个方法每帧都执行一次(循环执行),一般执行频率与屏幕刷新率相同(但也可以更改)。
    //
    //第一次循环时,先调用“glkView”再调用“update”。
    //
    //一般,将场景数据变化放在“update”中,而渲染代码则放在“glkView”中。
    
    //一般,将场景数据变化放在“update”中,而渲染代码则放在“glkView”中。
    - (void)update{
        
    }
    
    //渲染场景
    //一般,将场景数据变化放在“update”中,而渲染代码则放在“glkView”中。
    - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
        
    //    glClearColor(0.0, 1.0, 0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
        //    iOS的OpenGL中里有2个着色器,
        //    一个是GLKBaseEffect,为了方便OpenGL ES 1.0转移到2.0的通用着色器。
        //    一个是OpenGL ES 2.0新添加的可编程着色器,使用跨平台的着色语言
        //    //实例化基础效果实例,如果没有GLKit与GLKBaseEffect类,就需要为这个简单的例子编写一个小的GPU程序,使用2.0的Shading Language,而GLKBaseEffect会在需要的时候自动的构建GPU程序。
        [self.effect prepareToDraw];
    
    //    这里使用GLKBaseEffect来做着色器
        
        
    //    triangle 三角形
    //    glDrawArrays(GL_TRIANGLES, 0, 6);//GL_ARRAY_BUFFER
        
        int count = sizeof(Indices) / sizeof(Indices[0]);
        
        glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_BYTE, 0);
        
    //    前两行为渲染前的“清除”操作,清除颜色缓冲区和深度缓冲区中的内容,并且填充淡蓝色背景(默认背景是黑色)。
    //    
    //    “prepareToDraw”方法,是让“效果Effect”针对当前“Context”的状态进行一些配置,它始终把“GL_TEXTURE_PROGRAM”状态定位到“Effect”对象的着色器上。此外,如果Effect使用了纹理,它也会修改“GL_TEXTURE_BINDING_2D”。
    //    
    //    
    //    
    //    接下来,用“glDrawArrays”指令,让OpenGL“画出”两个三角形(拼合为一个正方形)。OpenGL会自动从通用顶点属性中取出这些数据、组装、再用“Effect”内置的着色器渲染。
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
    


    展开全文
  • 在这里就简单的介绍在如何通过手动调用GLKView的display方法去控制glkView:drawInRect的调用。先来看下一个GLKViewDelegate的代理方法,我们在使用GLKViewController的时候如果我们没有给GLKView设置代...

    一、简单介绍

    在ios平台下,苹果给我们封装好了GLKViewController这样的一个类,简化了我们通过OpenGL ES渲染图形的工作。在这里就简单的介绍在如何通过手动调用GLKView的display方法去控制glkView:drawInRect的调用。

    先来看下一个GLKViewDelegate的代理方法,我们在使用GLKViewController的时候如果我们没有给GLKView设置代理,那么GLKViewController就会自动成为其的代理。

    如果我们在GLKViewController中实现下面的这个代理方法,在GLKViewController中会被自动的调用

    官方文档对于这个方法的描述是该方法的语义与drawRect:方法相同,用来绘制view的内容的

    - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect;

    对于调用这个方法的刷新频率我们是可以设置的,通过GLKViewController的preferredFramesPerSecond属性来设置的

    关于preferredFramesPerSecond的描述,官方文档是这么说的

    当您的应用程序设置它的首选帧率时,视图控制器会根据屏幕上显示的视图的功能选择一个尽可能接近的帧速率。实际的帧速率通常是屏幕最大刷新速率的一个因素,以提供一致的帧速率。例如,如果屏幕的最大刷新率是每秒60帧,那也是最高帧速率,视图控制器设置为实际帧速率。然而,如果你要求一个较低的帧率,它可能会选择30、20、15或其他一些因素来作为实际帧速率。您的应用程序应该选择一个可以持续维护的帧速率。默认值是每秒30帧。

    就比如说如果我们设置了这个属性为1,就会1秒中去调用一次-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect方法

    self.preferredFramesPerSecond=1;

    二、代码实现控制

    其实实现手动控制glkView:drawInRect的调用很简单,其实我们只需要用到几行代码就可以了,比如说GLKViewController中有一个属性,用于控制渲染循环是否暂停。

    @property (nonatomic, getter=isPaused) BOOL paused;

    所以我们其实可以在glkView:(GLKView *)view drawInRect:(CGRect)rect方法中进行设置

    -(void)glkView:(GLKView *)view drawInRect:(CGRect)rect
    {
    self.paused=YES;
    }

    然后在一个按钮的点击事件中进行设置其恢复为NO,这样的话就可以进行控制了。

    - (IBAction)change:(UIButton *)sender {
    self.paused=NO; 
    } 

    当然我们还可以在button的点击方法中调用GLKView的display方法也是可以的。

    - (IBAction)change:(UIButton *)sender {
    [view display];
    } 

    调用display方法就会去立即重新绘制视图的内容。该方法会立即调用您的绘图方法,然后将呈现的图像呈现给屏幕,这个方法会去调用-drawRect:方法,然后在drawRect方法中会去判断delegate有没有实现-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect方法,如果实现了就会去调用。

    还有需要注意的是千万不要在绘图方法中去调用display方法,什么是绘图方法,比如说UIView的drawRect:(CGRect)rect方法还有glkView:(GLKView *)view drawInRect:(CGRect)rect。因为会循环调用,循环调用导致崩溃。

    通过函数堆栈调用其实我们可以发现display方法中会去调用了glkView:(GLKView *)view drawInRect:(CGRect)rect方法,而且还去调用了setFrameBuffer的方法和setCurrentContext的方法。




    展开全文
  • 在屏幕上拖动手指以查看断断续续。 如果它不是断断续续的,请按 kill 并重试。 当它断断续续时,按下播放/停止按钮以查看启动音序器如何​​以某种方式修复它。
  • Opengl ES初使用 ...3、将ViewController的view类型修改为”GLKView”,ViewController.h文件内容 #import <UIKit/UIKit.h> #import <GLKit/GLKit.h> @interface ViewCo...

    Opengl ES初使用

    一、环境搭建

    1、用Xcode创建一个单控制器工程;
    2、将一张图片拖到工程内,后续使用;
    3、将ViewController的view类型修改为”GLKView”,ViewController.h文件内容

    #import <UIKit/UIKit.h>
    #import <GLKit/GLKit.h>
    
    @interface ViewController : GLKViewController
    
    @end

    4、修改ViewController.m文件

    #import "ViewController.h"
    #import <OpenGLES/ES3/gl.h>
    #import <OpenGLES/ES3/glext.h>
    
    @interface ViewController ()<GLKViewDelegate>
    {
        EAGLContext *context;
        GLKBaseEffect *mEffect;//着色器或者光照
    }
    @end
    

    二、编码实现用OpenGL ES加载图片函数块

    1、OpneGL ES 配置

    //1、设置opengl es 配置
    - (void)setupConfig {
        EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES3;
        EAGLContext *ctx = [[EAGLContext alloc]initWithAPI:api];
        if (!ctx) {
            NSLog(@"EAGLContext init error!");
            return;
        }
        [EAGLContext setCurrentContext:ctx];
    
        GLKView *gView = (GLKView *)self.view;
        gView.context = ctx;
        gView.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
        gView.drawableDepthFormat = GLKViewDrawableDepthFormat24;
        //开启深度测试
        glEnable(GL_DEPTH_TEST);
        //清除背景色
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    }
    

    2、加载顶点数据

    //2、加载顶点数据
    - (void)uploadVertexArray {
        //OpenGL ES
        //顶点数据(x,y,z) 纹理(x,y)
        //剧中半屏显示
        GLfloat vertexData[] = {
            0.5f,-0.5f,0.0f,      1.0f,0.0f,
            0.5f,0.5f,0.0f,       1.0f,1.0f,
            -0.5f,0.5f,0.0f,      0.0f,1.0f,
    
            0.5f,-0.5f,0.0f,      1.0f,0.0f,
            -0.5f,0.5f,0.0f,      0.0f,1.0f,
            -0.5f,-0.5f,0.0f,     0.0f,0.0f,
        };
        /*
        //---全屏显示
        GLfloat vertexData[] = {
            1.0f,-1.0f,0.0f,      1.0f,0.0f,
            1.0f,1.0f,0.0f,       1.0f,1.0f,
            -1.0f,1.0f,0.0f,      0.0f,1.0f,
    
            1.0f,-1.0f,0.0f,      1.0f,0.0f,
            -1.0f,1.0f,0.0f,      0.0f,1.0f,
            -1.0f,-1.0f,0.0f,     0.0f,0.0f,
        };
         */
    
        //开启顶点缓存区
        GLuint buffer;
        //产生buffer标记
        glGenBuffers(1, &buffer);
        //绑定buffer
        glBindBuffer(GL_ARRAY_BUFFER, buffer);
        //加载数据
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
    
        //GLSL gl_position
        glEnableVertexAttribArray(GLKVertexAttribPosition);
    
        //读取顶点数据到顶点着色器中(GLKit)
        /* 数据参数定义(纹理同理):
            1、读取顶点数据
            2、读取数据个数(每个顶点数据几个数据)
            3、顶点数据类型
            4、是否规格化 no
            5、每次读取的偏移量
            6、指针起点
         */
        glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*5, (GLfloat *)NULL);
        //读取纹理数据
        glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    
        glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*5, (GLfloat *)NULL + 3);
    }

    3、加载纹理

    //3、加载纹理
    - (void)uploadTexture {
        NSString *filePath = [[NSBundle mainBundle]pathForResource:@"c" ofType:@"png"];
    
        //纹理是反的
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@1,GLKTextureLoaderOriginBottomLeft, nil];
    
        GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:NULL];
        mEffect = [[GLKBaseEffect alloc]init];
        mEffect.texture2d0.enabled = GL_TRUE;
        mEffect.texture2d0.name = textureInfo.name;
    }
    

    4、实现GLKViewdelegate

    #pragma mark
    #pragma mark - delegate
    - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
        glClearColor(0.3, 0.3, 0.6, 1.0f);
        //清除surface内容,恢复至初始状态
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        //启动着色器
        [mEffect prepareToDraw];
        /*
         1、着色模式
         2、开始位置
         3、数目
         */
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }

    三、ViewController.m 实现部分

    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        //1、设置opengl es 配置
        [self setupConfig];
    
        //2、加载顶点数据
        [self uploadVertexArray];
    
        //3、加载纹理
        [self uploadTexture];
    
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    //1、设置opengl es 配置
    - (void)setupConfig {
        EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES3;
        EAGLContext *ctx = [[EAGLContext alloc]initWithAPI:api];
        if (!ctx) {
            NSLog(@"EAGLContext init error!");
            return;
        }
        [EAGLContext setCurrentContext:ctx];
    
        GLKView *gView = (GLKView *)self.view;
        gView.context = ctx;
        gView.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
        gView.drawableDepthFormat = GLKViewDrawableDepthFormat24;
        //开启深度测试
        glEnable(GL_DEPTH_TEST);
        //清除背景色
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    }
    
    //2、加载顶点数据
    - (void)uploadVertexArray {
        //OpenGL ES
        //顶点数据(x,y,z) 纹理(x,y)
        //剧中半屏显示
        GLfloat vertexData[] = {
            0.5f,-0.5f,0.0f,      1.0f,0.0f,
            0.5f,0.5f,0.0f,       1.0f,1.0f,
            -0.5f,0.5f,0.0f,      0.0f,1.0f,
    
            0.5f,-0.5f,0.0f,      1.0f,0.0f,
            -0.5f,0.5f,0.0f,      0.0f,1.0f,
            -0.5f,-0.5f,0.0f,     0.0f,0.0f,
        };
        /*
        //---全屏显示
        GLfloat vertexData[] = {
            1.0f,-1.0f,0.0f,      1.0f,0.0f,
            1.0f,1.0f,0.0f,       1.0f,1.0f,
            -1.0f,1.0f,0.0f,      0.0f,1.0f,
    
            1.0f,-1.0f,0.0f,      1.0f,0.0f,
            -1.0f,1.0f,0.0f,      0.0f,1.0f,
            -1.0f,-1.0f,0.0f,     0.0f,0.0f,
        };
         */
    
        //开启顶点缓存区
        GLuint buffer;
        //产生buffer标记
        glGenBuffers(1, &buffer);
        //绑定buffer
        glBindBuffer(GL_ARRAY_BUFFER, buffer);
        //加载数据
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
    
        //GLSL gl_position
        glEnableVertexAttribArray(GLKVertexAttribPosition);
    
        //读取顶点数据到顶点着色器中(GLKit)
        /* 数据参数定义(纹理同理):
            1、读取顶点数据
            2、读取数据个数(每个顶点数据几个数据)
            3、顶点数据类型
            4、是否规格化 no
            5、每次读取的偏移量
            6、指针起点
         */
        glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*5, (GLfloat *)NULL);
        //读取纹理数据
        glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    
        glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*5, (GLfloat *)NULL + 3);
    }
    //3、加载纹理
    - (void)uploadTexture {
        NSString *filePath = [[NSBundle mainBundle]pathForResource:@"c" ofType:@"png"];
    
        //纹理是反的
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@1,GLKTextureLoaderOriginBottomLeft, nil];
    
        GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:NULL];
        mEffect = [[GLKBaseEffect alloc]init];
        mEffect.texture2d0.enabled = GL_TRUE;
        mEffect.texture2d0.name = textureInfo.name;
    }
    
    #pragma mark
    #pragma mark - delegate
    - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
        glClearColor(0.3, 0.3, 0.6, 1.0f);
        //清除surface内容,恢复至初始状态
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        //启动着色器
        [mEffect prepareToDraw];
        /*
         1、着色模式
         2、开始位置
         3、数目
         */
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    
    @end
    

    四、运行看效果

    展开全文
  • OpenGLES:: GLKView是如何工作的

    千次阅读 2016-05-07 01:04:33
    本篇通过一个AGLKView的示例来深入了解一下上篇中GLKView的工作原理,目的是为了消除GLKView、Core Animation、OpenGLES间交互的神秘感; 本例位于,建议将例子下下来,边看本文解析,边自己实现该例子;+ (Class)...
  • 首先我们去创建这个一个AGLKView去继承自UIView类,然后我们进行自定义操作,主要就是去模仿GLKView中的定义 #import &amp;amp;amp;lt;UIKit/UIKit.h&amp;amp;amp;gt; #import &amp;amp;amp;lt;...
  • 想将摄像头预览AVCaptureVideoPreviewLayer层 放到GLKit View上面,然后再在上面操控openGL 进行绘制。 但发现我把AVCaptureVideoPreviewLayer加到GLKit View上之后 绘制的东西就看不见了。 请问该怎么实现,只要能...
  • OPenGL ES - 简介、iOS中GLKit简单应用 一、OPenGL ES 1、简介: OpenGL ES 是以手持和嵌入式为目标的高级的3D图形...获取GLKView & 设置context GLKView *view =(GLKView *) self.view; view.context = context; /*...
  • //设置GLKView背景透明 glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); [self.m_glkView setBackgroundColor:[UIColor clearColor]]; 转载于:...
  • } -(void)glkView:(GLKView *)view drawInRect:(CGRect)rect{ glClearColor(1,0, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GLKMatrix4 cubeMode1 =[self _getModeMatrix4Location:GLKVector3...
  • iOS 相机开发总结

    2019-09-19 00:19:36
    4. 显示图像流方法二:通过AVCaptureVideoDataOutput从输出数据流捕捉单一的图像帧,并使用 OpenGL 手动地把它们显示在 view(GLKView) 上。   特效滤镜(美颜、美型、颜色等实时处理的滤镜) 粒子   ...
  • GLKit也有GLKView和GLKViewController等控件。 一般来说,GLKit能满足部分的开发需求,但是GLKit有个缺点就是:只能在屏幕上渲染3个点光源和2个纹理。 如果超过这个需求,就可以用GLSL来实现其业务了。 1....
  • GLKit框架提供view和view controller类,他们移除了setup和...GLKView class管理OpenGL ES的基础施设,为你的绘制代码提供一个地方,GLKViewController class为一个GLKit view中的平滑启动OpenGL ES content提供一个渲
  • .glkView = [[GLKView alloc] initWithFrame:frame context:context]; self .glkView.backgroundColor = [ UIColor  clearColor]; self .glkView.delegate =  self ; [ self .view addSubview: self ....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 661
精华内容 264
关键字:

GLKView