7

我正在用 C++ 编写代码来处理常见的 3D 内容 - 模型、材质、灯光等。但是,我发现要让任何东西正常工作,它都需要了解着色器。EG,要为材质设置统一变量,您需要从着色器中知道它们的句柄;要将网格加载到内存中,您需要知道不同in位置的句柄。

我最终得到了模型、材料等。每个都有一个着色器的句柄,所以他们可以做类似的事情glUniform1f(shader->getKdLocation(),kd),但这种烫手山芋对我来说似乎是糟糕的设计。我看过一些教程,其中制服和输入输出在着色器中进行硬编码(例如布局 = 0),然后仅使用glUniform1f(0,kd), 绑定。但是,这意味着我的其余代码只能与我特别布置的着色器一起使用,因此似乎是一个次优的解决方案。另外,我认为您不能对子例程执行此操作,这使得这是一个不一致的选项。

在获得着色器引用的所有事物和在某些情况下甚至无法正确实例化没有一个(例如网格)或在更多地方硬编码数字并不得不处理硬编码之后的问题之间似乎是一种选择。

应该能够让这些模型、灯光等独立运行/运行,并且只有在我为场景设置着色器时才能“工作”,但我似乎找不到可靠的方法来做到这一点。我的底线问题是处理着色器的最佳实践是什么?如果它不能解决我所有的问题,我很好,我只是想知道一个好的设计决策是什么以及为什么

4

2 回答 2

1

问题是你的引擎架构,或者它缺乏。在许多游戏引擎中,游戏对象分为几类,比如负责几何图形(顶点缓冲区等)的网格对象,材质对象(负责网格对象的外观)。在这样的设计,材质通常是一个实体,其中包含在渲染期间传递给着色器的制服信息。这样的设计提供了很大的灵活性,因为您可以重用,在不同的可渲染对象之间重新分配不同的材质。所以对于初学者来说可以将特定的着色器程序设置为特定的材质类型,因此每次绘制网格时,其材质都会与传递所有所需制服的着色器程序交互。

我建议您看一下开源 OpenGL 引擎,了解它是如何工作的。

于 2013-07-31T20:19:45.497 回答
0

对于客户端上的统一规范与着色器中布置的实际统一位置之间的松散关联,我也有同样的担忧。

您可以采取的一种方法是使用glGetUniformLocation根据其名称确定统一变量的位置。它可能仍然不完美,但它可能是你能做的最好的。

例子:

// Old way:
GLfloat myfloat = ...;
glUniform1f(0, myfloat);   // Hope that myfloat was supposed to go at location 0...

对比

// Slightly better...
GLfloat myfloat = ...;
GLint location = glGetUniformLocation(myprogram, "myfloat");
glUniform1f(location, myfloat);   // We know that a uniform with name "myfloat" goes at this location

glGetActiveUniform的一些额外工作还可以让您确保“myfloat”具有您所期望的类型/大小/等。

于 2013-08-01T12:25:12.610 回答