#c# #opengl #glsl #fragment-shader #opentk
#c# #opengl #glsl #фрагментный шейдер #opentk
Вопрос:
Я следовал этому руководству до завершения и создал этот проект на основе этого кода, который включает отправку массива vec2 в фрагментный шейдер. Однако я изо всех сил пытаюсь реализовать это эффективно, поскольку все мои попытки передать массив в шейдер завершились неудачей (прошел бы только первый элемент, остальные были бы равны нулю). В настоящее время я обхожу эту проблему, создавая индивидуальные формы для каждого элемента, но это совсем не идеально (существует 4 массива, каждый из которых содержит 76 элементов). Кроме того, я бы в конечном итоге хотел заменить эти массивы на dvec2 (Vector2d в OpenTK), но мне не удается даже передать один, и я не уверен, почему… Я пробовал использовать все соответствующие перегрузки GL.Uniform2, но, похоже, ни один из них не работает. Вот соответствующие фрагменты моего кода (полный код можно просмотреть по приведенным выше ссылкам):
// These two functions successfully get the values to the shader
public void SetVector2(string name, Vector2 data)
{
GL.UseProgram(Handle);
GL.Uniform2(uniformLocations[name], data);
}
// But this one does so very undesirably, passing to independent variables rather than directly to a uniform array
public void SetVector2Array(string name, Vector2[] data)
{/*
// This fails
var floats = new float[data.Length * 2];
for (int i = 0; i < data.Length * 2; i = 2)
{
floats[i] = data[i / 2].X;
floats[i 1] = data[i / 2].Y;
}
GL.UseProgram(Handle);
//GL.Uniform2(uniformLocations[name], data.Length, floats);
GL.Uniform2(uniformLocations[name "[0]"], data.Length, floats);*/
GL.UseProgram(Handle);
for (int i = 0; i < data.Length; i )
{
GL.Uniform2(uniformLocations[name i], data[i]);
}
}
// This fails altogether... not really sure what value this sends, but it's not the right one
public void SetVector2d(string name, Vector2d data)
{
double[] d = new double[]
{
data.X,
data.Y,
};
GL.UseProgram(Handle);
GL.Uniform2(uniformLocations[name], 2, d);
}
Мой фрагментный шейдер выглядит следующим образом (я бы хотел заменить каждый из 4 массивов простым «uniform vec2 array_name»):
#define MAX_MATING_ITER 76
uniform vec2 ma0;
uniform vec2 ma1;
uniform vec2 ma2;
uniform vec2 ma3;
uniform vec2 ma4;
uniform vec2 ma5;
uniform vec2 ma6;
uniform vec2 ma7;
uniform vec2 ma8;
uniform vec2 ma9;
...
uniform vec2 md67;
uniform vec2 md68;
uniform vec2 md69;
uniform vec2 md70;
uniform vec2 md71;
uniform vec2 md72;
uniform vec2 md73;
uniform vec2 md74;
uniform vec2 md75;
// The 4 arrays I use
vec2 ma[MAX_MATING_ITER];
vec2 mb[MAX_MATING_ITER];
vec2 mc[MAX_MATING_ITER];
vec2 md[MAX_MATING_ITER];
void main()
{
ma[0] = ma0;
ma[1] = ma1;
ma[2] = ma2;
ma[3] = ma3;
ma[4] = ma4;
ma[5] = ma5;
ma[6] = ma6;
ma[7] = ma7;
ma[8] = ma8;
ma[9] = ma9;
...
md[66] = md66;
md[67] = md67;
md[68] = md68;
md[69] = md69;
md[70] = md70;
md[71] = md71;
md[72] = md72;
md[73] = md73;
md[74] = md74;
md[75] = md75;
// Rest of the code
}
Комментарии:
1. Я не могу найти
Uniform2(int, double[])
перегрузки в OpenTK. Откуда это берется? В принципе, шейдеры не поддерживаютdouble
s.2. @donggas90
Uniform2(int, int, double[])
,Uniform2(int, int, double*)
иUniform2(int, int, ref double)
допустимы.3. @Rabbid76 Я ошибся. Я подумал о мобильных GL ES , потому что в настоящее время Vulkan намного популярнее, чем GL для настольных компьютеров.