简体   繁体   English

对于 OpenGL 着色器,您将如何在 C++ 中编写一个接受所有类型的统一 Function?

[英]For OpenGL Shaders, how would you write a Uniform Function in C++ that accepts all types?

So say I have a Shader class and I want to have a Uniform function that sends the data I pass to the loaded Shader program所以说我有一个着色器 class 并且我想要一个统一的 function 将我传递给加载的着色器程序的数据发送

class Shader{
   unsigned int programid;
   template<typename Type>
   void Uniform(unsigned int location, Type object){
       //Some logic that passes the type data to the uniform using glUniform[?]()
   }
}

How would I write the Uniform function (using templates in C++) to accept any type (primitive OR object) and pass it to the Shader?我将如何编写 Uniform function(使用 C++ 中的模板)来接受任何类型(原始 OR 对象)并将其传递给着色器?

Examples:例子:

GLSL: uniform float Amount; GLSL: uniform float Amount; C++: shader.Uniform(somefloat); C++: shader.Uniform(somefloat);

GLSL: uniform vec3 Position; GLSL: uniform vec3 Position;

C++: C++:

template<typename Type, size_t Size>
Vector{ Type data[Size]; }

Vector<float, 3> position = {0.0f, 1.0f, 1.0f}
shader.Uniform(position);

GLSL: GLSL:

struct Light
{
  vec3 position;
  vec4 rotation;
  float luminosity;
  bool status;
};

uniform Light object;

C++: C++:

struct Light {
  Vector<float, 3> position;
  Vector<float, 4> rotation;
  float luminosity;
  bool status;
}
Light object = {{1.0f,0.0f,0.0f},{0.0f,0.0f,0.0f},0.75f,true};
shader.Uniform(object);

First, C++ and GLSL are statically typed languages, not dynamically typed like JavaScript or Python.首先,C++ 和 GLSL 是静态类型语言,不像 JavaScript 或 Python 那样动态类型。 So there is no actual way to write a C++ function that accepts any type.所以没有实际的方法来编写接受任何类型的 C++ function。 What your C++ template function does is, essentially, a text substitution.您的 C++ 模板 function 所做的基本上是文本替换。 Every time the C++ compiler sees the template used, eg "Vector", it takes the original template declaration and makes a new copy with "Type" and "Size" replaced by "float" and "3" respectively.每次 C++ 编译器看到使用的模板时,例如“Vector”,它都会获取原始模板声明并制作一个新副本,其中“Type”和“Size”分别替换为“float”和“3”。 And the compiler generates a unique mangled name to prevent linker errors something like __Vector_TypeFOO_SizeBAR...并且编译器会生成一个唯一的重整名称以防止 linker 错误,例如 __Vector_TypeFOO_SizeBAR...

(For sake of completeness, yes it's possible to implement your own dynamic typing in C/C++ with unions and/or pointer casts. But since you can't do either of those in GLSL, it doesn't help answer the question.) (为了完整起见,是的,可以使用联合和/或指针强制转换在 C/C++ 中实现您自己的动态类型。但由于您不能在 GLSL 中执行其中任何一项,因此无助于回答问题。)

So, since GLSL doesn't have templates to do the text replacement, you'll have to implement it yourself.因此,由于 GLSL 没有模板来进行文本替换,因此您必须自己实现它。 Load the source of your shader from file or whatever.从文件或其他任何内容加载着色器的源。 Before you pass it to glCompileShader, use your favourite string processing library to insert actual strings into placeholder text.在将其传递给 glCompileShader 之前,请使用您最喜欢的字符串处理库将实际字符串插入占位符文本。

Eg in your shader you could write something like:例如,在您的着色器中,您可以编写如下内容:

<TYPE><SIZE> position;

and your main program would do something like你的主程序会做类似的事情

src = loadShaderCode("example.template");
src.replace("<TYPE>", "vec");
src.replace("<SIZE>", "3");
shader = compileShader(src, ...);

Hope this helps.希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM