- objective-c - iOS 5 : Can you override UIAppearance customisations in specific classes?
- iphone - 如何将 CGFontRef 转换为 UIFont?
- ios - 以编程方式关闭标记的信息窗口 google maps iOS
- ios - Xcode 5 - 尝试验证存档时出现 "No application records were found"
更新:因为我马上需要一些东西,所以我创建了一个简单的着色器包装器来完成我需要的事情。您可以在这里找到它:ShaderManager on GitHub .请注意,它是为 Objective-C/iOS 设计的,因此可能并非对所有人都有用。如果您对设计改进有任何建议,请告诉我!
原始问题:
我刚开始使用 GLSL 着色器。我对 GLSL 语言和 OpenGL 接口(interface)非常熟悉,但是我在设计一个简单的 API 来使用着色器时遇到了问题。
OpenGL 与着色器交互的 C 接口(interface)看起来很麻烦。我似乎无法在网上找到任何涵盖此类 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);
在我要绘制的每种元素之前。然后我需要在使用之前设置每个程序的制服(模型/ View /投影)和属性。这看起来很笨拙。
使用单个 ShaderProgram 选项时,我仍然需要在片段着色器中设置某种 bool 开关(圆形或方形),以便在绘制每个像素之前进行检查。这看起来也很复杂。
附带说明一下,我是否可以将两个片段着色器(每个都有一个 main() 函数)链接到一个着色器程序中? OpenGL 如何知道调用哪一个?
电话:
glUniform*
glVertexAttribPointer
用于在当前程序上设置制服和属性指针位置。
不同的类和结构可能需要从代码中的不同位置访问和设置当前着色器上的变量(或更改当前着色器)。我想不出一个很好的方法来将着色器代码与想要使用它的代码分离。
也就是说,我要绘制的每个形状都需要设置顶点和纹理坐标属性 - 需要 OpenGL 生成的这些属性的句柄。
相机需要在顶点着色器中将其投影矩阵设置为统一,而管理模型矩阵堆栈的类需要在顶点着色器中设置自己的统一。
在绘制场景的过程中更改着色器意味着所有这些类都需要重新设置它们的制服和属性。
大多数人如何围绕这个进行设计?
通过句柄或名称访问的全局着色器字典,以及用于参数的 getter 和 setter?
一个 OO 设计,每个着色器对象都有参数?
我查看了以下包装器:
Jon's Teapot: GLSL Shader Manager - 这将着色器包装在 C++ 类中。它看起来只不过是一个在 C API 上强制执行 OO 原则的包装器,导致 C++ API 非常相似。
我追求任何一种简化着色器程序使用的设计,而不关心所使用的特定范例(面向对象、过程等)
最佳答案
我看到这是用 iOS 标记的,所以如果你偏爱 Objective-C,我会好好看看 Jeff LaMarche 的 GLProgram 包装类,他描述了 here并且有可用的源here .我在自己的应用程序中使用它来简化一些着色器程序设置,并使代码更简洁。
例如,您可以使用如下代码设置着色器及其属性和制服:
sphereDepthProgram = [[GLProgram alloc] initWithVertexShaderFilename:@"SphereDepth" fragmentShaderFilename:@"SphereDepth"];
[sphereDepthProgram addAttribute:@"position"];
[sphereDepthProgram addAttribute:@"inputImpostorSpaceCoordinate"];
if (![sphereDepthProgram link])
{
NSLog(@"Depth shader link failed");
NSString *progLog = [sphereDepthProgram programLog];
NSLog(@"Program Log: %@", progLog);
NSString *fragLog = [sphereDepthProgram fragmentShaderLog];
NSLog(@"Frag Log: %@", fragLog);
NSString *vertLog = [sphereDepthProgram vertexShaderLog];
NSLog(@"Vert Log: %@", vertLog);
[sphereDepthProgram release];
sphereDepthProgram = nil;
}
sphereDepthPositionAttribute = [sphereDepthProgram attributeIndex:@"position"];
sphereDepthImpostorSpaceAttribute = [sphereDepthProgram attributeIndex:@"inputImpostorSpaceCoordinate"];
sphereDepthModelViewMatrix = [sphereDepthProgram uniformIndex:@"modelViewProjMatrix"];
sphereDepthRadius = [sphereDepthProgram uniformIndex:@"sphereRadius"];
当您需要使用着色器程序时,您可以执行如下操作:
[sphereDepthProgram use];
这没有解决您在上面提出的分支与独立着色器的问题,但 Jeff 的实现确实提供了一些 OpenGL ES 样板着色器设置代码的良好封装。
关于ios - 如何为着色器设计一个简单的 GLSL 包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6166202/
我之前让 dll 注入(inject)器变得简单,但我有 Windows 7,我用 C# 和 C++ 做了它,它工作得很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我有几个不同的蜘蛛,想一次运行所有它们。基于 this和 this ,我可以在同一个进程中运行多个蜘蛛。但是,我不知道如何设计一个信号系统来在所有蜘蛛都完成后停止 react 器。 我试过了: cra
有没有办法在达到特定条件时停止扭曲 react 器。例如,如果一个变量被设置为某个值,那么 react 器应该停止吗? 最佳答案 理想情况下,您不会将变量设置为一个值并停止 react 器,而是调用
https://code.angularjs.org/1.0.0rc9/angular-1.0.0rc9.js 上面的链接定义了外部js文件,我不知道Angular-1.0.0rc9.js的注入(in
我正在尝试运行一个函数并将服务注入(inject)其中。我认为这可以使用 $injector 轻松完成.所以我尝试了以下(简化示例): angular.injector().invoke( [ "$q
在 google Guice 中,我可以使用函数 createInjector 创建基于多个模块的注入(inject)器。 因为我使用 GWT.create 在 GoogleGin 中实例化注入(in
我在 ASP.NET Core 1.1 解决方案中使用配置绑定(bind)。基本上,我在“ConfigureServices Startup”部分中有一些用于绑定(bind)的简单代码,如下所示: s
我在 Spring MVC 中设置 initBinder 时遇到一些问题。我有一个 ModelAttribute,它有一个有时会显示的字段。 public class Model { privat
我正在尝试通过jquery post发布knockoutjs View 模型 var $form = $('#barcodeTemplate form'); var data = ko.toJS(vm
如何为包含多态对象集合的复杂模型编写自定义模型绑定(bind)程序? 我有下一个模型结构: public class CustomAttributeValueViewModel { publi
您好,我正在尝试实现我在 this article 中找到的扩展方法对于简单的注入(inject)器,因为它不支持开箱即用的特定构造函数的注册。 根据这篇文章,我需要用一个假的委托(delegate)
你好,我想自动注册我的依赖项。 我现在拥有的是: public interface IRepository where T : class public interface IFolderReposi
我正在使用 Jasmine 测试一些 Angular.js 代码。为此,我需要一个 Angular 注入(inject)器: var injector = angular.injector(['ng'
我正在使用 Matlab 代码生成器。不可能包含代码风格指南。这就是为什么我正在寻找一个工具来“ reshape ”、重命名和重新格式化生成的代码,根据我的: 功能横幅约定 文件横幅约定 命名约定 等
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我开发了一种工具,可以更改某些程序的外观。为此,我需要在某些进程中注入(inject)一个 dll。 现在我基本上使用这个 approach .问题通常是人们无法注入(inject) dll,因为他们
我想使用 swing、spring 和 hibernate 编写一个 java 应用程序。 我想使用数据绑定(bind)器用 bean 的值填充 gui,并且我还希望它反射(reflect) gui
我有这段代码,当两个蜘蛛完成后,程序仍在运行。 #!C:\Python27\python.exe from twisted.internet import reactor from scrapy.cr
要点是 Spring Batch (v2) 测试框架具有带有 @Autowired 注释的 JobLauncherTestUtils.setJob。我们的测试套件有多个 Job 类提供者。因为这个类不
我是一名优秀的程序员,十分优秀!