65.9K
CodeProject 正在变化。 阅读更多。
Home

OpenGL on iOS 上的纹理和着色器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.43/5 (5投票s)

2014 年 9 月 30 日

CPOL

3分钟阅读

viewsIcon

24353

downloadIcon

194

如何在iOS上开始使用OpenGL。

引言

本文演示了在iOS上使用OpenGL纹理以及常见的单例、MVC、出口和测试工作模式是多么容易。因此,OpenGL 是一项有用的技术,在其他平台上也可以使用。缺点是,2004年的非常旧的2.0版本是标准的,“新的”是OpenGL 3.0(2008年)。

截图:带有图片选择和红色滤镜效果滑块。

背景

我想更好地理解OpenGL,因为它具有良好的图形性能并兼容于其他项目。

使用代码

包含的示例项目源自Xcode的普通模板,遵循MVC模型,即模型-视图-控制器,它确实有助于将代码分离成有用的部分。因此,ViewController类充分利用了它的名称,它控制着视图的工作方式。重要的是Displaylink,因为它是由显示器或更好的GPU计时器回调以进行新的像素输出。

- (void)startDisplayLinkIfNeeded
{
 if (!_displayLink) {
  self.displayLink = [CADisplayLink displayLinkWithTarget:_viewOpenGL selector:@selector(display)];
  [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
  }
}

GUI在Main.storyboard中配置,其中存储了控件。它们通过Outlet“连接”到ViewController。我在mobiforge找到一个不错的教程。但是现在先不说这些了。

开始使用OpenGL

为了某种程度上利用OpenGL,我设计了一个OpenGLContext类,它在Objective-C中采用了典型的单例设计模式。

+ (instancetype)sharedInstance
{
    static OpenGLContext *theInstance = nil;
    static dispatch_once_t onceToken;    

    dispatch_once(&onceToken, ^{
        theInstance = [[OpenGLContext alloc] init];
    });

    return theInstance;
}

此对象持有EAGLContext的属性,以便在iOS上使用OpenGL。

@property(strong, nonatomic) EAGLContext *context;

这是使其工作的算法。如果我们有上下文,我们就完成了;否则,如果可以创建V3上下文,那就很好;否则,我们创建一个V2上下文。重要的是最后一行,将上下文设置为当前上下文。这是一个直接与显示驱动程序交互的全局函数。

- (int) createContext
{
  if( self.context != nil ) return 1;
  self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];

  if (!self.context) {
    NSLog(@"[Warn] Hardware doenst support OpenGL ES 3.0 context");
    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

    if (!self.context) {
      NSLog(@"[Error] failed to create an OpenGL ES 2.0 context");
      return -1;
    }
  }

  [EAGLContext setCurrentContext:self.context];

  return 0;
}

OpenGL中的纹理

纹理是OpenGL中的位图,因此我们需要一些纹理来查看一些彩色像素。代码在其他平台上看起来应该类似。

//set alignment
glPixelStorei(GL_PACK_ALIGNMENT, 1);
//activate textures
glEnable(GL_TEXTURE_2D);
//get an free and valid ID
glGenTextures(1, &texture);
//make active
glActiveTexture(GL_TEXTURE0 + texture);
// Bind the texture
glBindTexture(GL_TEXTURE_2D, texture);
// Setup texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//disable mipmapping
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);

//set the bits of the texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, colorData);

深入着色器

着色器是OpenGL中用于操纵图形输出的小型子程序。有两个独立的程序,一个称为顶点着色器,它计算坐标;另一个是片段着色器,它生成像素的颜色。要将它们加载到OpenGL中,需要对其进行编译、链接和加载。这在OpenGLProgram类中完成。

我还想指出着色器的复杂领域,它们具有不同类型的变量,这些变量在工作中起着重要作用。因此,我写了一些解释。

#version 100
//a compile-time constant, or a function parameter that is read-only
uniform mat4 modelViewProjectionMatrix;
//linkage between a vertex shader and OpenGL ES for per-vertex data
attribute vec4 position;
attribute vec2 texcoord;
//linkage between a vertex shader and a fragment shader for interpolated data
varying vec2 v_texcoord;
void main()
{
gl_Position = position;
v_texcoord = texcoord.xy;
}

我的代码的核心是滑块的这个处理程序。滑块的值可以更改,并进入操纵纹理输出的OpenGL程序。

- (IBAction)onChange:(id)sender
{
float value = [_slider value];
NSLog(@"Slider = %f", value);
NSString *sFloat = [NSString stringWithFormat:@"%.2f",value];
NSDictionary *dic = @{@"RED_FACTOR": sFloat};

OpenGLProgram *shader = [[OpenGLProgram alloc] init];

[shader loadShaders:@"Shader3" FragmentModify:dic];

[[_openGLContext shaders] setObject:shader atIndexedSubscript:2];

self.shader = [_openGLContext useProgramAtIndex:2];

[_shader linkValue:"pixel" Texture:_textureOpenGL];

[self.viewOpenGL display];

}

在Xcode中测试

Xcode对编写软件测试有一些很好的支持,我喜欢使用它。看看它 - 它真的值得。大多数情况下,使用measureBlock API进行性能测试是小菜一碟。

关注点

通过深入研究OpenGL,我学习了很多复杂的东西,这对于具有良好性能的大型图形输出非常有帮助。

Apple为嵌入式系统提供了良好的OpenGL文档,他们称之为OpenGL ES

接下来是使用Apple的Metal 新技术,听起来真的很棒。

像往常一样,我提供一个指向著名的Ray Wenderlich的链接,在那里可以找到许多有趣且解释良好的内容。

历史

初始版本。

© . All rights reserved.