p.s.作者没试过实际运行,也不知道行不行…
#include <GLES3/gl3.h>
#include <iostream>
enum Type
{
F = 0,
U = 4,
I = 8,
};
template < typename T > bool less(T a, T b, T c)
{
return (b > a && b < c);
}
int switch_num(int type)
{
int f = type - F;
int u = type - U;
int i = type - I;
if (less(0, f, 5))
return f;
else if (less(0, u, 5))
return u;
else if (less(0, i, 5))
return i;
else
return 0;
}
int switch_type(int type)
{
int num = switch_num(type);
if (num != 0)
return type - num;
else
return -1;
}
void glUniform(int target, int type, ...)
{
// 启用可变参列表
va_list vl;
va_start(vl, type);
// 参数的数量
int num = switch_num(type);
// 参数的类型
int t = switch_type(type);
switch (t)
{
case F:
[&]()
{
float value[4];
for(int i = 0;i < num;i++)
{
value[i] = va_arg(vl,float);
}
switch(num)
{
case 1:
glUniform1f(target,value[0]);
break;
case 2:
glUniform2f(target,value[0],value[1]);
break;
case 3:
glUniform3f(target,value[0],value[1],value[2]);
break;
case 4:
glUniform4f(target,value[0],value[1],value[2],value[3]);
break;
}
}();
break;
case U:
[&]()
{
unsigned int value[4];
for(int i = 0;i < num;i++)
{
value[i] = va_arg(vl,unsigned int);
}
switch(num)
{
case 1:
glUniform1ui(target,value[0]);
break;
case 2:
glUniform2ui(target,value[0],value[1]);
break;
case 3:
glUniform3ui(target,value[0],value[1],value[2]);
break;
case 4:
glUniform4ui(target,value[0],value[1],value[2],value[3]);
break;
}
}();
break;
case I:
[&]()
{
int value[4];
for(int i = 0;i < num;i++)
{
value[i] = va_arg(vl,int);
}
switch(num)
{
case 1:
glUniform1i(target,value[0]);
break;
case 2:
glUniform2i(target,value[0],value[1]);
break;
case 3:
glUniform3i(target,value[0],value[1],value[2]);
break;
case 4:
glUniform4i(target,value[0],value[1],value[2],value[3]);
break;
}
}();
break;
}
// 销毁可变参列表
va_end(vl);
}
int main()
{
// 例子
int target = 0;
glUniform(target, F + 2, 1.0, 2.0);
glUniform(target, U + 1, 1);
glUniform(target, I + 4, 1, 2, 3, 4);
glUniform(target, 3, 1.0, 2.0, 3.0); // 因为F是0,所以F+3=3
return 0;
}