更新:因为我马上需要的东西,我创建了一个简单的着色器包装器,这样我需要的东西.您可以在这里找到: ShaderManager on GitHub.请注意,它是为Objective-C / iOS设计的,所以可能对所有人都不是有用的.如果您对设计改进有任何建议,请告诉我们!

原始问题:

我刚刚使用GLSL着色器.我熟悉GLSL语言和OpenGL界面,但是我无法设计一个使用着色器的简单API.

OpenGL的C界面与着色器交互似乎很麻烦.我似乎找不到任何涵盖API设计的网络上的教程.

我的问题是:有没有任何一个好的,简单的API设计或模式来包装OpenGL着色器程序API?

以下简单的例子.说我有一个顶点着色器只是模拟固定的功能和两个片段着色器 – 一个用于绘制光滑的矩形,一个用于绘制光滑的圆.我有以下文件:

Shader.vsh : Simple vertex shader,with the following inputs/outputs:
    -- Uniforms: mat4 Model,mat4 View,mat4 Projection
    -- Attributes: vec4 Vertex,vec2 TexCoord,vec4 Color
    -- varying: vec4 vColor,vec2 vTexCoord

Square.fsh : Fragment shader for drawing squares based on tex coord / color
Circle.fsh : Fragment shader for drawing circles based on tex coord / color

基本链接

现在使用这些标准的方法是什么?将上述着色器链接到两个OpenGL着色器程序?那是:

Shader.vsh + Square.fsh = SquareProgram
Shader.vsh + Circle.fsh = CircleProgram

或者,我可以创建一个大程序,其中片段着色器检查一些条件均匀变量,并调用一个着色器函数来生成其结果.例如:

Shader.vsh + Square.fsh + Circle.fsh + Main.fsh = ShaderProgram
//Main.fsh here would simply check whether to call out to square or circle

有两个单独的程序,我可能需要打电话

gluseProgram(CircleProgram); or gluseProgram(SquareProgram);

在每种类型的元素之前,我想绘制.在使用之前,我需要设置制服(模型/视图/投影)和每个程序的属性.这似乎太笨了

使用单一的ShaderProgram选项,我仍然需要在片段着色器中设置一些布尔开关(圆形或正方形),在绘制每个像素之前要进行检查.这也看起来很复杂.

作为一个附注,我允许将两个片段着色器(每个具有一个main()函数)链接到一个着色器程序中? OpenGL如何知道要调用哪一个?

设置变量

电话:

gluniform*
glVertexAttribPointer

用于在当前程序中设置制服和属性指针位置.

不同的类和结构可能需要从代码中的不同位置访问和设置当前着色器上的变量(或更改当前着色器).我不能想到一个很好的方式来实现,使着色器代码与要使用它的代码分离.

也就是说,我想要绘制的每个形状都需要设置顶点和纹理坐标属性 – 需要对由OpenGL生成的那些属性的句柄.

相机将需要将其投影矩阵设置为顶点着色器中的统一,而管理模型矩阵堆栈的类将需要在顶点着色器中设置自己的均匀度.

通过绘制场景改变着色器将意味着所有这些类都需要重新设置它们的制服和属性.

这个大多数人怎么设计呢?

一个由句柄或名称访问的着色器全局字典,其参数为getter和setter?

一个OO设计与着色器对象每个都有参数?

我看了下面的包装:

Jon’s Teapot: GLSL Shader Manager – 它将着色器包装在C类中.它似乎只是一个比C API执行OO原则的包装器,导致一个C API是一样的.

我经过任何设计,简化了Shader程序的使用,并不关心所使用的特定范例(OO,程序等)

解决方法

基本链接:

这里没有标准的方法.至少有两种一般方法:

>单片 – 一个着色器涵盖许多情况,使用均匀的布尔开关.这些分支不会影响性能,因为条件结果对于任何片段组(实际上对于所有片段)而言是不变的.
>多目标程序合成 – 主着色器声明一组入口点(如“get_diffuse”,“get_specular”等),它们在附加的单独的着色器对象中实现.这意味着每个对象的单独着色器,但任何类型的缓存都有帮助.

设置变量:制服

我将只描述我开发的方法.

每个着色器程序都有一个统一的字典列表.它用于在程序(重新)链接时填写统一的源列表.当程序激活时,它将通过统一列表,从其来源获取值并将其上传到GL.在结果中,数据与用户着色器程序没有直接关联,无论管理什么都不关心使用它的程序.

其中一个词典可以是例如核心词典,其中包含模型,视图变换,相机投影,也可以是别的内容.

设置变量:属性

首先,着色器程序是一个属性消费者,因此,必须从网格(或任何其他数据存储)中提取这些属性,并以需要的方式将其上传到GL.它还应该确保提供的属性的类型与请求的类型匹配.

当使用单片着色器方法时,当一个禁用的分支路径需要未提供的顶点属性时,可能会出现不愉快的情况.我会建议使用另一个属性的数据来​​提供丢失的数据,因为我们不关心这种情况下的实际值.

附:
您可以在这里找到这些想法的实际实现:http://code.google.com/p/kri/

ios – 如何设计一个简单的GLSL包装器,用于着色器使用的更多相关文章

  1. 为什么这个OpenGL ES 2.0着色器不能在iOS上使用我的VBO?

    如果有人能够了解这里出了什么问题,也许是对gl命令或其他一些不兼容的命令序列的错误排序,我将非常感谢你的帮助.尽管谷歌在“OpenGLES2.0编程指南”中进行了大量研究和研究,但我一直试图让这段代码整天都没有成功.我正在尝试在iPhone上的OpenGLES2.0中使用顶点缓冲区对象和自定义着色器.我试图交错来自以下类型的一系列自定义结构的顶点数据:位置,半径和颜色字节分别考虑顶点位置,点大小和

  2. ios – 为什么GLSL的算术函数会在iPad上产生与模拟器不同的结果?

    java-为什么这两个相似的代码片会产生不同的结果?haskell-产生不同解释器结果的等效函数javascript-为什么.css在Edge中产生不同的结果?颜色-为什么CSS过滤器hue-rotate会产生奇怪的结果?scala-为什么应用于2个函数的部分函数以2种不同的方式执行相同的操作会返回不同的结果?为什么用-fllvm编译这个Haskell程序产生不同的结果?angularjs-为什么ng-bind-html和$sanitize产生不同的结果?-代码日志,则不定义pow.>

  3. ios – 如何设计一个简单的GLSL包装器,用于着色器使用

    以下简单的例子.说我有一个顶点着色器只是模拟固定的功能和两个片段着色器–一个用于绘制光滑的矩形,一个用于绘制光滑的圆.我有以下文件:基本链接现在使用这些标准的方法是什么?将上述着色器链接到两个OpenGL着色器程序?一个OO设计与着色器对象每个都有参数?

  4. ios – GL_APPLE_shader_framebuffer_fetch gl_lastFragData

    我该怎么做才能真正使用这个扩展?

  5. 用swift+Metal shader文件编译framework动态库

    若想用swift语言生成库则只能生成动态库,若是纯swift代码脚本,问题不大,按一般流程就行。若是编译的库中有shader文件则需要先编译出Metal库。把shader文件和swift文件放在一起进行framework库的编译。编译成功后会自动生成一个default.Metallib文件,该文件为shader生成的库文件。使用letlibrary=device.newDefaultLibrary()直接加载Metal库。上面的方式是最简单的,另外,对shader文件,也可以不在xcode中编译库,而是采

  6. opengl – 如何在glShaderSource中将String作为GLchar **(char **)参数传递?

    我有一个存储在String值中的着色器:函数glShaderSource具有绑定签名:当我尝试直接将着色器String传递给glShaderSource时,我收到错误消息:如何正确传递String?经过半天的搜索,我找到了没有编译错误的工作解决方案,错误的内存访问失败了:

  7. android – 如何动画渐变?

    如何设置从颜色#1到颜色#2的渐变动画?

  8. android – 自定义ImageView类不与Picasso图像下载库一起使用

    提前致谢.解决方法对于使用Picasso的圆形图像,请使用实现Transformation的this类.

  9. 打开GL 2.0 Android错误0x501(GL_INVALID_VALUE)

    我试图在Android上构建一个小的OpenGL2.0演示应用程序,但我收到以下错误在日志猫在控制台中我的代码视图解决方法您正在调用OpenGLESAPI而没有当前的上下文错误,因为您正在创建三角形Triangletri=newTriangle();在OpenGL线程之外.只有OpenGL回调中的代码才会在opengl线程上执行.在onSurfaceCreated中放置tri=newTriangle(),这些错误应该消失.

  10. android – 垂直条纹背景的XML?

    我想设置一个查看背景,这是一个垂直条纹的常规网格.条纹在两种颜色之间交替出现.使用Bitmap来做到这一点很容易.例如:有没有办法严格执行这个XML可绘制,不使用位图资源?

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部