class_docstr: A class holding OpenGL machinery used by MeshRasterizerOpenGL.
class_docstr_tok: ["A","class","holding","OpenGL","machinery","used","by","MeshRasterizerOpenGL","."]
docstr: Rasterize a single mesh using OpenGL.
  
  Args:
      mesh: A Meshes object, containing a single mesh only.
      projection_matrix: A 3x3 camera projection matrix, or a tensor of projection
          matrices equal in length to the number of meshes in meshes_gl_ndc.
      image_size: Image size to rasterize. Must be smaller than the max height and
          width stored in global_device_context_store.
  
  Returns:
      pix_to_faces: A 1HW1 tensor of ints, filled with -1 where no face projects
          to a given pixel.
      bary_coords: A 1HW3 float tensor, filled with -1 where no face projects to
          a given pixel.
      zbuf: A 1HW1 float tensor, filled with 1 where no face projects to a given
          pixel. NOTE: this zbuf uses the opengl zbuf convention, where the z-vals
          are between 0 (at projection plane) and 1 (at clipping distance), and
          are a non-linear function of the depth values of the camera ray inter-
          sections.
docstr_tok: ["Rasterize","a","single","mesh","using","OpenGL",".","Args",":","mesh",":","A","Meshes","object",",","containing","a","single","mesh","only",".","projection_matrix",":","A","3x3","camera","projection","matrix",",","or","a","tensor","of","projection","matrices","equal","in","length","to","the","number","of","meshes","in","meshes_gl_ndc",".","image_size",":","Image","size","to","rasterize",".","Must","be","smaller","than","the","max","height","and","width","stored","in","global_device_context_store",".","Returns",":","pix_to_faces",":","A","1HW1","tensor","of","ints",",","filled","with","-1","where","no","face","projects","to","a","given","pixel",".","bary_coords",":","A","1HW3","float","tensor",",","filled","with","-1","where","no","face","projects","to","a","given","pixel",".","zbuf",":","A","1HW1","float","tensor",",","filled","with","1","where","no","face","projects","to","a","given","pixel",".","NOTE",":","this","zbuf","uses","the","opengl","zbuf","convention",",","where","the","z-vals","are","between","0","(","at","projection","plane",")","and","1","(","at","clipping","distance",")",",","and","are","a","non-linear","function","of","the","depth","values","of","the","camera","ray","inter-","sections","."]
code: def _rasterize_mesh(
      self,
      mesh: Meshes,
      image_size: Tuple[int, int],
      projection_matrix: Optional[torch.Tensor] = None,
  ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
      """
      Rasterize a single mesh using OpenGL.
  
      Args:
          mesh: A Meshes object, containing a single mesh only.
          projection_matrix: A 3x3 camera projection matrix, or a tensor of projection
              matrices equal in length to the number of meshes in meshes_gl_ndc.
          image_size: Image size to rasterize. Must be smaller than the max height and
              width stored in global_device_context_store.
  
      Returns:
          pix_to_faces: A 1HW1 tensor of ints, filled with -1 where no face projects
              to a given pixel.
          bary_coords: A 1HW3 float tensor, filled with -1 where no face projects to
              a given pixel.
          zbuf: A 1HW1 float tensor, filled with 1 where no face projects to a given
              pixel. NOTE: this zbuf uses the opengl zbuf convention, where the z-vals
              are between 0 (at projection plane) and 1 (at clipping distance), and
              are a non-linear function of the depth values of the camera ray inter-
              sections.
      """
      height, width = image_size
      # Extract face_verts and move them to OpenGL as well. We use pycuda to
      # directly move the vertices on the GPU, to avoid a costly torch/GPU -> CPU
      # -> openGL/GPU trip.
      verts_packed = mesh.verts_packed().detach()
      faces_packed = mesh.faces_packed().detach()
      face_verts = verts_packed[faces_packed].reshape(-1, 9)
      _torch_to_opengl(face_verts, self.cuda_context, self.cuda_buffer)
  
      if projection_matrix is not None:
          self._projection_matrix_to_opengl(projection_matrix)
  
      # Start OpenGL operations.
      gl.glUseProgram(self.program)
  
      # Render an image of size (width, height).
      gl.glViewport(0, 0, width, height)
  
      gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.fbo)
      # Clear the output framebuffer. The "background" value for both pix_to_face
      # as well as bary_coords is -1 (background = pixels which the rasterizer
      # projected no triangle to).
      gl.glClearColor(-1.0, -1.0, -1.0, -1.0)
      gl.glClearDepth(1.0)
      # pyre-ignore Unsupported operand [58]
      gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
  
      # Run the actual rendering. The face_verts were transported to the OpenGL
      # program into a shader storage buffer which is used directly in the geometry
      # shader. Here, we only pass the number of these vertices to the vertex shader
      # (which doesn't do anything and passes directly to the geometry shader).
      gl.glBindVertexArray(self.vao)
      gl.glDrawArrays(gl.GL_POINTS, 0, len(face_verts))
      gl.glBindVertexArray(0)
  
      # Read out the result. We ignore the depth buffer. The RGBA color buffer stores
      # barycentrics in the RGB component and pix_to_face in the A component.
      bary_depth_p2f_gl = gl.glReadPixels(
          0,
          0,
          width,
          height,
          gl.GL_RGBA,
          gl.GL_FLOAT,
      )
  
      gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
      gl.glUseProgram(0)
  
      # Create torch tensors containing the results.
      bary_depth_p2f = (
          torch.frombuffer(bary_depth_p2f_gl, dtype=torch.float)
          .reshape(1, height, width, 1, -1)
          .to(verts_packed.device)
      )
  
      # Read out barycentrics. GL only outputs the first two, so we need to compute
      # the third one and make sure we still leave no-intersection pixels with -1.
      barycentric_coords = torch.cat(
          [
              bary_depth_p2f[..., :2],
              1.0 - bary_depth_p2f[..., 0:1] - bary_depth_p2f[..., 1:2],
          ],
          dim=-1,
      )
      barycentric_coords = torch.where(
          barycentric_coords == 3, -1, barycentric_coords
      )
      depth = bary_depth_p2f[..., 2:3].squeeze(-1)
      pix_to_face = bary_depth_p2f[..., -1].long()
  
      return pix_to_face, barycentric_coords, depth
  
imports: import warnings
  from typing import Optional, Tuple, Union
  import numpy
  import OpenGL.GL
  import pycuda.gl
  import torch
  import torch.nn
  from pytorch3d.structures.meshes import Meshes
  from ..cameras import FoVOrthographicCameras, FoVPerspectiveCameras
  from ..mesh.rasterizer import Fragments, RasterizationSettings
  from ..utils import parse_image_size
  from .opengl_utils import _torch_to_opengl, global_device_context_store
label_desc: Use image node_id 6 for calling the _OpenGLMachinery obj's underlying member method code with example usage: obj._rasterize_mesh(mesh, image_size, projection_matrix) and returns: pix_to_face,  barycentric_coords,  depth