I have an OpenGL Tessellated Sphere and I want to cut a cylindrical hole in it

前端 未结 3 2041
野趣味
野趣味 2020-11-29 14:12

I am working on a piece of software which generated a polygon mesh to represent a sphere, and I want to cut a hole through the sphere. This polygon mesh is only an overlay a

3条回答
  •  一整个雨季
    2020-11-29 14:33

    Well if you want just to render this (visualize) then may be you do not need to change the generated meshes at all. Instead use Stencil buffer to render your sphere with the holes. For example I am rendering disc (thin cylinder) with circular holes near its outer edge (as a base plate for machinery) with combination of solid and transparent objects around so I need the holes are really holes. As I was lazy to triangulate the shape as is generated at runtime I chose stencil for this.

    1. Create OpenGL context with Stencil buffer

      I am using 8 bit for stencil but this technique uses just single bit.

    2. Clear stencil with 0 and turn off Depth&Color masks

      This has to be done before rendering your mesh with stencil. So if you have more objects rendered in this way you need to do this before each one of them.

    3. Set stencil with 1 for solid mesh

    4. Clear stencil with 0 for hole meshes

    5. Turn on Depth&Color masks and render solid mesh where stencil is 1

    In code it looks like this:

    // [stencil]
    glEnable(GL_STENCIL_TEST);
    // whole stencil=0
    glClearStencil(0);
    glClear(GL_STENCIL_BUFFER_BIT);
    // turn off color,depth
    glStencilMask(0xFF);
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    glDepthMask(GL_FALSE);
    // stencil=1 for solid mesh
    glStencilFunc(GL_ALWAYS,1,0xFF);
    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    glCylinderxz(0.0,y,0.0,r,qh);
    // stencil=0 for hole meshes
    glStencilFunc(GL_ALWAYS,0,0xFF);
    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    for(b=0.0,j=0;j<12;j++,b+=db)
        {
        x=dev_R*cos(b);
        z=dev_R*sin(b);
        glCylinderxz(x,y-0.1,z,dev_r,qh+0.2);
        }
    // turn on color,depth
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glDepthMask(GL_TRUE);
    // render solid mesh the holes will be created by the stencil test
    glStencilFunc(GL_NOTEQUAL,0,0xFF);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    glColor3f(0.1,0.3,0.4);
    glCylinderxz(0.0,y,0.0,r,qh);
    glDisable(GL_STENCIL_TEST);
    

    where glCylinderxz(x,y,z,r,h) is just function that render cylinder at (x,y,z) with radius r with y-axis as its rotation axis. The db is angle step (2*Pi/12). Radiuses are r-big, dev_r-hole radius, dev_R-hole centers And qhis the thickness of the plate.

    The result looks like this (each of the 2 plates is rendered with this):

    This approach is more suited for thin objects. If your cuts leads to thick enough sides then you need to add a cut side rendering otherwise the lighting could be wrong on these parts.

提交回复
热议问题