如OpenGL顶点后处理https://www.khronos.org/opengl/wiki/Vertex_Post-Processing中所述,在用户定义的剪切下,我试图剪切将每个顶点发送到顶点着色器中的平面。每个顶点仅提供一个索引,以便我可以访问UBO的数据,该数据包含在实际BIG数据推送之前确定并发送的剪切平面信息。
“ ......可以通过使用UBO存储裁剪区域的数组来减轻这种情况,每个顶点只需在该数组中指定一个整数索引即可。”
问题是我无法以简单的索引访问UBO,因为尽管数据已满且正确,但一起发送的剪辑索引缓冲区却无法正常工作。 (在NSight中检查)。
GPU只是认为我只想访问第一个裁剪矩形。 (ClipIndex始终等于0); 因此,它仅适用于我的简单imgui中的第一个窗口。
因此,我听说OpenGL从1.2版或更高版本开始就不接受索引。这是原因吗???他们甚至对UBO的大小设置了严格的限制(我认为是6kb)。那我无法访问数据的具体原因是什么?我可以从纹理中的任意位置获取纹理像素,但无法使用恒定大小的缓冲区获取一些简单数据。
它编译干净,我检查了错误并验证了程序。 也链接罚款。如果我将其硬设置到顶点着色器中,则可以正常工作。 这意味着如果我只想剪辑一个窗口(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);
}