0

As described in OpenGL Vertex Post-Processing https://www.khronos.org/opengl/wiki/Vertex_Post-Processing Under User-defined Clipping, I am trying to clip each vertex send to a plane in the vertex shader. Providing only an index per vertex, so that I can access the UBO's data, which contains the clipping plane information, determined and send before the actual BIG data push.

"...It is possible to mitigate this by using a UBO to store an array of clipping regions, with each vertex simply specifying an integer index into that array...."

The problem is that somehow I cannot access the UBO with a simple indexing, because the clip index buffer sent along just refuses to work, although the data is full and correct. (Inspected in NSight).

The GPU simply thinks that I want to access only the first clipping rect. (ClipIndex is always equal to ZERO); So it only works for the first window in my simple imgui.

So I have heard of OpenGL not accepting indexing since version 1.2 or something. Is this the reason??? They have even set a hard restriction on the size of the UBO (I think 6kb). What then is the specific reason why I cannot access my data? I can fetch a texel from wherever I want in a texture, but I cannot get some simple data with a constant size buffer.

It compiles clean, I have checked for errors and validated the program. Also links fine. If I hard set it into the vertex shader it works fine. Meaning that if I want to clip only for window one (Clip.Rects[1]) no problem. When I introduce a single contiguous array of indices, we are out of the game. The array is always treated as if it is full with ZEROs.

I know the code may not be optimal. For now we are trying to reach the working phase.

I am new to asking questions here, so please don't hate me for the wrong indentation of the code.

The alternatives, in my opinion, are to draw 6 or less verts per rectangle and each time I have to clip to a different plane do it manually changing the glScissor() or glClipPlane(). And the second one, which comes to mind, is to use a texture to store the data, which I don't like, because it is not a texture :D.

Why my approach is busted? And are there better ways to clip one contiguous array of vertex data to multiple planes?

   #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);


     }
2
  • 2
    I suspect of ClipIndex which is an integer in the GLSL code. If you pass it at C++ code by using glUniform1f then that is wrong. You must use glUniform1i (note the 'i' at the end) Commented May 6, 2019 at 15:50
  • in int ClipIndex;. I'd make the same guess as here. Commented May 6, 2019 at 21:28

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.