Как описано в постобработке вершин OpenGL https://www.khronos.org/opengl/wiki/Vertex_Post-Processing В разделе «Пользовательское вырезание» я пытаюсь обрезать каждую отправленную вершину на плоскости в вершинном шейдере. Предоставляя только индекс для каждой вершины, чтобы я мог получить доступ к данным UBO, которые содержат информацию о плоскости отсечения, определенную и отправленную до фактической передачи больших данных.
"... Можно смягчить это, используя UBO для хранения массива областей отсечения, при этом каждая вершина просто указывает целочисленный индекс в этом массиве ...."
Проблема в том, что каким-то образом я не могу получить доступ к UBO с помощью простой индексации, потому что отправленный вместе буфер индекса индекса просто отказывается работать, хотя данные полны и верны. (Проверено в NSight).
Графический процессор просто думает, что я хочу получить доступ только к первому прямоугольнику отсечения.
(ClipIndex всегда равен нулю);
Так что это работает только для первого окна в моем простом imgui.
Итак, я слышал, что OpenGL не принимает индексацию начиная с версии 1.2 или чего-то в этом роде. Это причина ??? Они даже установили жесткое ограничение на размер UBO (я думаю, 6 КБ). Какова же причина, по которой я не могу получить доступ к своим данным? Я могу получить тексель из любой точки текстуры, но не могу получить некоторые простые данные с буфером постоянного размера.
Он компилируется чисто, я проверил ошибки и проверил программу.
Также ссылки в порядке. Если я установлю его в вершинный шейдер, он будет работать нормально.
Это означает, что если я хочу обрезать только для первого окна (Clip.Rects [1]), нет проблем.
Когда я представлю один непрерывный массив индексов, мы вышли из игры. Массив всегда обрабатывается так, как если бы он был заполнен нулями.
Я знаю, что код не может быть оптимальным. Пока мы пытаемся достичь рабочей фазы.
Я новичок в задании вопросов здесь, поэтому, пожалуйста, не ненавидите меня за неправильные отступы в коде.
Альтернативы, на мой взгляд, состоят в том, чтобы нарисовать 6 или менее вершин на прямоугольник, и каждый раз, когда мне нужно обрезать плоскость, делайте это вручную, изменяя glScissor () или glClipPlane ().
И второе, что приходит на ум, это использовать текстуру для хранения данных, что мне не нравится, потому что это не текстура: D.
Почему мой подход нарушен? И есть ли лучшие способы обрезать один непрерывный массив данных вершин в нескольких плоскостях?
#version 400 core
struct rect
{
float X;
float Y;
float Width;
float Height;
};
layout (shared) uniform clip_rects
{
rect Rects[50];
} Clip;
out float gl_ClipDistance[6]; // Clipping each vert to a rectangle plane
// Skippied some unrelated info colors depth...
in vec2 RectVBO;
in int ClipIndex;
uniform mat4 PCMatrix;
void main()
{
gl_Position = PCMatrix * vec4(RectVBO.xy, Depth, 1.0f);
//FIRST ATTEMPT (already in -1,1 space)
vec2 v0 = vec2(Clip.Rects[ClipIndex].X, Clip.Rects[ClipIndex].Y);
vec2 v1 = vec2(Clip.Rects[ClipIndex].X + Clip.Rects[ClipIndex].Width, Clip.Rects[ClipIndex].Y);
vec2 v2 = vec2(Clip.Rects[ClipIndex].X + Clip.Rects[ClipIndex].Width, Clip.Rects[ClipIndex].Y + Clip.Rects[ClipIndex].Height);
vec2 v3 = vec2(Clip.Rects[ClipIndex].X, Clip.Rects[ClipIndex].Y + Clip.Rects[ClipIndex].Height);
//END OF FIRST ATTEMPT
//Even this doesn't work!
//SECOND ATTEMPT
vec2 v0 = vec2(0.0f,0.0f);
vec2 v1 = vec2(0.0f,0.0f);
vec2 v2 = vec2(0.0f,0.0f);
vec2 v3 = vec2(0.0f,0.0f);
//NOTE: It only takes the first if block if we set it to 1, 2, 3
//for example its all set to the above zeroed out vec2s.
if(ClipIndex == 0)
{
v0 = vec2(Clip.Rects[0].X, Clip.Rects[0].Y);
v1 = vec2(Clip.Rects[0].X + Clip.Rects[0].Width, Clip.Rects[0].Y);
v2 = vec2(Clip.Rects[0].X + Clip.Rects[0].Width, Clip.Rects[0].Y + Clip.Rects[0].Height);
v3 = vec2(Clip.Rects[0].X, Clip.Rects[0].Y + Clip.Rects[0].Height);
}
else if(ClipIndex == 1)
{
v0 = vec2(Clip.Rects[1].X, Clip.Rects[1].Y);
v1 = vec2(Clip.Rects[1].X + Clip.Rects[1].Width, Clip.Rects[1].Y);
v2 = vec2(Clip.Rects[1].X + Clip.Rects[1].Width, Clip.Rects[1].Y + Clip.Rects[1].Height);
v3 = vec2(Clip.Rects[1].X, Clip.Rects[1].Y + Clip.Rects[1].Height);
} else if(ClipIndex == 2)
{
v0 = vec2(Clip.Rects[2].X, Clip.Rects[2].Y);
v1 = vec2(Clip.Rects[2].X + Clip.Rects[2].Width, Clip.Rects[2].Y);
v2 = vec2(Clip.Rects[2].X + Clip.Rects[2].Width, Clip.Rects[2].Y + Clip.Rects[2].Height);
v3 = vec2(Clip.Rects[2].X, Clip.Rects[2].Y + Clip.Rects[2].Height);
}
// END OF SECOND ATTEMPT
//Tried "local" variable indexing still no progress.
//THIRD ATTEMPT
vec2 v0 = vec2(0.0f,0.0f);
vec2 v1 = vec2(0.0f,0.0f);
vec2 v2 = vec2(0.0f,0.0f);
vec2 v3 = vec2(0.0f,0.0f);
for(int k = 0; k < 3; k++)
{
if(k == ClipIndex)
{
v0 = vec2(Clip.Rects[k].X, Clip.Rects[k].Y);
v1 = vec2(Clip.Rects[k].X + Clip.Rects[k].Width, Clip.Rects[k].Y);
v2 = vec2(Clip.Rects[k].X + Clip.Rects[k].Width, Clip.Rects[k].Y + Clip.Rects[k].Height);
v3 = vec2(Clip.Rects[k].X, Clip.Rects[k].Y + Clip.Rects[k].Height);
}
}
//END OF THIRD ATTEMPT
vec2 VecToVertex0 = gl_Position.xy - v0;
vec2 VecToVertex1 = gl_Position.xy - v1;
vec2 VecToVertex2 = gl_Position.xy - v2;
vec2 VecToVertex3 = gl_Position.xy - v3;
vec2 v0v1 = v1 - v0;
vec2 v1v2 = v2 - v1;
vec2 v2v0 = v0 - v2;
vec2 v0v2 = v2 - v0;
vec2 v2v3 = v3 - v2;
vec2 v3v0 = v0 - v3;
gl_ClipDistance[0] = dot(v0v1, VecToVertex0);
gl_ClipDistance[1] = dot(v1v2, VecToVertex1);
gl_ClipDistance[2] = dot(v2v0, VecToVertex2);
gl_ClipDistance[3] = dot(v0v2, VecToVertex0);
gl_ClipDistance[4] = dot(v2v3, VecToVertex2);
gl_ClipDistance[5] = dot(v3v0, VecToVertex3);
}