How to convert large arrays of quad primitives to triangle primitives?

后端 未结 2 1533
没有蜡笔的小新
没有蜡笔的小新 2021-01-19 01:41

I have an existing system, which provides 3D meshes. The provided data are an array of vertex coordinates with 3 components (x, y, z) and an index list. The issue is that th

2条回答
  •  旧时难觅i
    2021-01-19 01:48

    First I want to mention that this is not a question which I want to answer myself, but I want to provide my current solution to this issue. This means, that I'm still looking for "the" solution, the perfectly acceptable solution.

    In my solution, I decided to use Tessellation. I draw patches with a size of 4:

    glPatchParameteri( GL_PATCH_VERTICES, self.__patch_vertices )
    glDrawElements( GL_PATCHES, no_of_indices, GL_UNSIGNED_INT, 0 )
    

    The Tessellation Control Shader has a default behavior. The patch data is passed directly from the Vertex Shader invocations to the tessellation primitive generation. Because of that it can be omitted completely.

    The Tessellation Evaluation Shader uses a quadrilateral patch (quads) to create 2 triangles:

    #version 450
    
    layout(quads, ccw) in;
    
    in TInOut
    {
        vec3 pos;
    } inData[];
    
    out TInOut
    {
        vec3 pos;
    } outData;
    
    uniform mat4 u_projectionMat44;
    
    void main()
    {
        const int inx_map[4] = int[4](0, 1, 3, 2);
    
        float i_quad = dot( vec2(1.0, 2.0), gl_TessCoord.xy );
        int   inx    = inx_map[int(round(i_quad))];
    
        outData.pos = inData[inx].pos;
        gl_Position = u_projectionMat44 * vec4( outData.pos, 1.0 );
    }
    

    An alternative solution would be to use a Geometry Shader. The input primitive type lines_adjacency provides 4 vertices, which can be mapped to 2 triangles (triangle_strip). Of course this seems to be a hack, since a lines adjacency is something completely different than a quad, but it works anyway.

    glDrawElements( GL_LINES_ADJACENCY, no_of_indices, GL_UNSIGNED_INT, 0 );
    

    Geometry Shader:

    #version 450
    
    layout( lines_adjacency ) in;
    layout( triangle_strip, max_vertices = 4 ) out;
    
    in TInOut
    {
        vec3 pos;
    } inData[];
    
    out TInOut
    {
        vec3 col;
    } outData;
    
    uniform mat4 u_projectionMat44;
    
    void main()
    {
        const int inx_map[4] = int[4](0, 1, 3, 2);
        for ( int i=0; i < 4; ++i )
        {
            outData.pos = inData[inx_map[i]].pos;
            gl_Position = u_projectionMat44 * vec4( outData.pos, 1.0 );
            EmitVertex();
        }
        EndPrimitive();
    }
    

    An improvement would be to use Transform Feedback to capture new buffers, containing triangle primitives.

提交回复
热议问题