你这一生中的迷,必须要用其他的迷才能解开,就像有的梦,必须穿过其他的梦才能醒来。你必须一个一个地走过,才能走出这场连环梦。
——《如梦之梦》
OpenGL ES提供了一个纹理贴图对几何图形进行着色。
1、视口(viewport):帧缓存中的像素位置叫做视口。渲染时,GPU会转换纯数学的OpenGL ES坐标系中的X、Y、Z坐标为帧缓存中所对应真实的像素位置。
2、点阵化(rasterizing):转换几何形状数据为帧缓存中的颜色像素的渲染步骤叫做点阵化。
3、片元(fragment):每个颜色像素叫做片元。
4、映射(mapping):指定怎么对其纹理和顶点,以便让GPU知道每个片元的颜色由哪些纹素决定。这通过扩展为每个顶点保存的数据来实现:除了X、Y、Z坐标,每个顶点还给出了U和V坐标值。U坐标映射到S轴的位置,V坐标映射到T轴。不同的是{U,V}坐标可能会超出0.0到1.0的这个范围。
//
// ViewController.m
// OpenGL ES3(第二篇)
//
// Created by 李永飞 on 2018/6/18.
// Copyright © 2018年 李永飞. All rights reserved.
//
#import "ViewController.h"
#import "YFGLVertexAttribArrayBuffer.h"
#import "YFGLContext.h"
@interface ViewController ()<GLKViewDelegate>
@property (strong, nonatomic) GLKBaseEffect
*baseEffect;
@property (strong, nonatomic) YFGLVertexAttribArrayBuffer
*vertexBuffer;
@property (strong, nonatomic) YFGLContext *context;
@end
@implementation ViewController
//此数据类型用于存储每个顶点的信息
typedef struct {
GLKVector3 positionCoords;
GLKVector2 textureCoords;
}SceneVertex;
//定义一个三角形的顶点数据
static const SceneVertex vertices[] =
{
{{0.0, 0.5f, 0.0}, {0.5f, 3.5f}},
{{0.5f, -0.5f, 0.0}, {1.5f, -0.5f}},
{{- 0.5f, -0.5f, 0.0}, {-0.5f, -0.5f}},
};
- (void)viewDidLoad {
[super viewDidLoad];
//创建OpenGL ES 3.0上下文并将其提供给 视图
self.context = [[YFGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
[YFGLContext setCurrentContext:self.context];
// 界面构建器板
GLKView *view=[[GLKView alloc]initWithFrame:self.view.bounds context:self.context];
view.delegate=self;
view.drawableMultisample= GLKViewDrawableMultisample4X;//多重采样是一种抗锯齿,锯齿状边缘平滑,提高图像质量,启用多重采样会花费更多的内存和帧处理时间。
[self.view addSubview:view];
//创建一个提供标准OpenGL ES 3.0的基础效果。
//着色语言程序和设置常量
//所有后续呈现
self.baseEffect = [[GLKBaseEffect alloc] init];
self.baseEffect.useConstantColor = GL_FALSE;
self.baseEffect.constantColor = GLKVector4Make(30/255.0,144/255.0,255/255.0,1.0f);
//设置当前上下文中存储的背景色
self.context.clearColor = GLKVector4Make(255/255.0,192/255.0,203/255.0,1.0f);
//创建包含要绘制的顶点的顶点缓冲区
self.vertexBuffer = [[YFGLVertexAttribArrayBuffer alloc]
initWithAttribStride:sizeof(SceneVertex)
numberOfVertices:sizeof(vertices) / sizeof(SceneVertex)
bytes:vertices
usage:GL_STATIC_DRAW];
//设置纹理
CGImageRef imageRef = [[UIImage imageNamed:@"stars"] CGImage];
NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:@(1), GLKTextureLoaderOriginBottomLeft, nil];//CoreGraphics的坐标系问题导致纹理颠倒,需要颠倒过来
GLKTextureInfo *textureInfo = [GLKTextureLoader
textureWithCGImage:imageRef
options: options
error:NULL];
self.baseEffect.texture2d0.name = textureInfo.name;
self.baseEffect.texture2d0.target = textureInfo.target;
}
// GLKView委托方法:由视图控制器的视图调用
//每当Cocoa Touch请求视图控制器的视图
//画本身。(在这种情况下,渲染到一个框架缓冲区中
//与核心动画层共享内存
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
[self.baseEffect prepareToDraw];
//清除后帧缓冲区(删除之前的绘制)
[self.context clear:GL_COLOR_BUFFER_BIT];
[self.vertexBuffer prepareToDrawWithAttrib:GLKVertexAttribPosition
numberOfCoordinates:3
attribOffset:offsetof(SceneVertex, positionCoords)
shouldEnable:YES];
[self.vertexBuffer prepareToDrawWithAttrib:GLKVertexAttribTexCoord0
numberOfCoordinates:2
attribOffset:offsetof(SceneVertex, textureCoords)
shouldEnable:YES];
//使用前三个顶点绘制三角形
//当前绑定顶点缓冲区
[self.vertexBuffer drawArrayWithMode:GL_TRIANGLES
startVertexIndex:0
numberOfVertices:3];
}
//当视图控制器的视图被卸载时调用
//当您知道视图时,可以执行清理
//控制器的视图不会很快被要求重新绘制。
-(void)dealloc{
self.vertexBuffer = nil;
self.context=nil;
[EAGLContext setCurrentContext:nil];
}
@end
OpenGL ES3.png
网友评论