How to do it...

To create a shader program that creates Bezier patches from input patches of 16 control points, use the following steps:

  1. Use the vertex shader from the Tessellating a 2D quad recipe.
  2. Use the following code for the tessellation control shader:
layout( vertices=16 ) out; 
 
uniform int TessLevel; 
 
void main() {
    // Pass along the vertex position unmodified 
    gl_out[gl_InvocationID].gl_Position =  
                 gl_in[gl_InvocationID].gl_Position; 
 
    gl_TessLevelOuter[0] = float(TessLevel); 
    gl_TessLevelOuter[1] = float(TessLevel); 
    gl_TessLevelOuter[2] = float(TessLevel); 
    gl_TessLevelOuter[3] = float(TessLevel); 
 
    gl_TessLevelInner[0] = float(TessLevel); 
    gl_TessLevelInner[1] = float(TessLevel); 
}

    1. Use the following code for the tessellation evaluation shader:
    layout( quads ) in; 
    out vec3 TENormal;   // Vertex normal in camera coords. 
    out vec4 TEPosition; // Vertex position in camera coords 
     
    uniform mat4 MVP; 
    uniform mat4 ModelViewMatrix; 
    uniform mat3 NormalMatrix; 
     
    void basisFunctions(out float[4] b, out float[4] db, float t) {
        float t1 = (1.0 - t); 
        float t12 = t1 * t1; 
     
        // Bernstein polynomials 
        b[0] = t12 * t1; 
        b[1] = 3.0 * t12 * t; 
        b[2] = 3.0 * t1 * t * t; 
        b[3] = t * t * t; 
     
        // Derivatives 
        db[0] = -3.0 * t1 * t1; 
        db[1] = -6.0 * t * t1 + 3.0 * t12; 
        db[2] = -3.0 * t * t + 6.0 * t * t1; 
        db[3] = 3.0 * t * t; 
    } 
     
    void main() {
        float u = gl_TessCoord.x; 
        float v = gl_TessCoord.y; 
     
        // The sixteen control points 
        vec4 p00 = gl_in[0].gl_Position; 
        vec4 p01 = gl_in[1].gl_Position; 
        vec4 p02 = gl_in[2].gl_Position; 
        vec4 p03 = gl_in[3].gl_Position; 
        vec4 p10 = gl_in[4].gl_Position; 
        vec4 p11 = gl_in[5].gl_Position; 
        vec4 p12 = gl_in[6].gl_Position; 
        vec4 p13 = gl_in[7].gl_Position; 
        vec4 p20 = gl_in[8].gl_Position; 
        vec4 p21 = gl_in[9].gl_Position; 
        vec4 p22 = gl_in[10].gl_Position; 
        vec4 p23 = gl_in[11].gl_Position; 
        vec4 p30 = gl_in[12].gl_Position; 
        vec4 p31 = gl_in[13].gl_Position; 
        vec4 p32 = gl_in[14].gl_Position; 
        vec4 p33 = gl_in[15].gl_Position; 
        // Compute basis functions 
        float bu[4], bv[4];   // Basis functions for u and v 
        float dbu[4], dbv[4]; // Derivitives for u and v 
        basisFunctions(bu, dbu, u); 
        basisFunctions(bv, dbv, v); 
     
        // Bezier interpolation 
        TEPosition = 
         p00*bu[0]*bv[0] + p01*bu[0]*bv[1] + p02*bu[0]*bv[2] +  
         p03*bu[0]*bv[3] + 
         p10*bu[1]*bv[0] + p11*bu[1]*bv[1] + p12*bu[1]*bv[2] +  
         p13*bu[1]*bv[3] + 
         p20*bu[2]*bv[0] + p21*bu[2]*bv[1] + p22*bu[2]*bv[2] +  
         p23*bu[2]*bv[3] + 
         p30*bu[3]*bv[0] + p31*bu[3]*bv[1] + p32*bu[3]*bv[2] +  
         p33*bu[3]*bv[3]; 
     
        // The partial derivatives 
        vec4 du = 
         p00*dbu[0]*bv[0]+p01*dbu[0]*bv[1]+p02*dbu[0]*bv[2]+  
         p03*dbu[0]*bv[3]+ 
         p10*dbu[1]*bv[0]+p11*dbu[1]*bv[1]+p12*dbu[1]*bv[2]+  
         p13*dbu[1]*bv[3]+ 
         p20*dbu[2]*bv[0]+p21*dbu[2]*bv[1]+p22*dbu[2]*bv[2]+  
         p23*dbu[2]*bv[3]+ 
         p30*dbu[3]*bv[0]+p31*dbu[3]*bv[1]+p32*dbu[3]*bv[2]+  
         p33*dbu[3]*bv[3]; 
     
        vec4 dv = 
         p00*bu[0]*dbv[0]+p01*bu[0]*dbv[1]+p02*bu[0]*dbv[2]+  
         p03*bu[0]*dbv[3]+ 
         p10*bu[1]*dbv[0]+p11*bu[1]*dbv[1]+p12*bu[1]*dbv[2]+  
         p13*bu[1]*dbv[3]+ 
         p20*bu[2]*dbv[0]+p21*bu[2]*dbv[1]+p22*bu[2]*dbv[2]+  
         p23*bu[2]*dbv[3]+ 
         p30*bu[3]*dbv[0]+p31*bu[3]*dbv[1]+p32*bu[3]*dbv[2]+  
         p33*bu[3]*dbv[3]; 
     
        // The normal is the cross product of the partials 
        vec3 n = normalize( cross(du.xyz, dv.xyz) ); 
     
        // Transform to clip coordinates 
        gl_Position = MVP * TEPosition; 
     
        // Convert to camera coordinates 
        TEPosition = ModelViewMatrix * TEPosition; 
        TENormal = normalize(NormalMatrix * n); 
    }

    1. Implement your favorite shading model within the fragment shader utilizing the output variables from the TES.
    2. Render the Bezier control points as a 16-vertex patch primitive. Don't forget to set the number of vertices per patch within the OpenGL application:
    glPatchParameteri(GL_PATCH_VERTICES, 16); 
    ..................Content has been hidden....................

    You can't read the all page of ebook, please click here login for view all page.
    Reset
    13.58.150.59