class_docstr: EXPERIMENTAL, USE WITH CAUTION
  
  This class implements methods for rasterizing a batch of heterogeneous
  Meshes using OpenGL. This rasterizer, as opposed to MeshRasterizer, is
  *not differentiable* and needs to be used with shading methods such as
  SplatterPhongShader, which do not require differentiable rasterizerization.
  It is, however, faster: on a 2M-faced mesh, about 20x so.
  
  Fragments output by MeshRasterizerOpenGL and MeshRasterizer should have near
  identical pix_to_face, bary_coords and zbuf. However, MeshRasterizerOpenGL does not
  return Fragments.dists which is only relevant to SoftPhongShader and
  SoftSilhouetteShader. These do not work with MeshRasterizerOpenGL (because it is
  not differentiable).
class_docstr_tok: ["EXPERIMENTAL",",","USE","WITH","CAUTION","This","class","implements","methods","for","rasterizing","a","batch","of","heterogeneous","Meshes","using","OpenGL",".","This","rasterizer",",","as","opposed","to","MeshRasterizer",",","is","*","not","differentiable","*","and","needs","to","be","used","with","shading","methods","such","as","SplatterPhongShader",",","which","do","not","require","differentiable","rasterizerization",".","It","is",",","however",",","faster",":","on","a","2M-faced","mesh",",","about","20x","so",".","Fragments","output","by","MeshRasterizerOpenGL","and","MeshRasterizer","should","have","near","identical","pix_to_face",",","bary_coords","and","zbuf",".","However",",","MeshRasterizerOpenGL","does","not","return","Fragments.dists","which","is","only","relevant","to","SoftPhongShader","and","SoftSilhouetteShader",".","These","do","not","work","with","MeshRasterizerOpenGL","(","because","it","is","not","differentiable",")","."]
docstr: Args:
      meshes_world: a Meshes object representing a batch of meshes with
          coordinates in world space. The batch must live on a GPU.
  
  Returns:
      Fragments: Rasterization outputs as a named tuple. These are different than
          Fragments returned by MeshRasterizer in two ways. First, we return no
          `dist` which is only relevant to SoftPhongShader which doesn't work
          with MeshRasterizerOpenGL (because it is not differentiable). Second,
          the 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 intersections. In
          contrast, MeshRasterizer's zbuf values are simply the distance of each
          ray intersection from the camera.
  
  Throws:
      ValueError if meshes_world lives on the CPU.
docstr_tok: ["Args",":","meshes_world",":","a","Meshes","object","representing","a","batch","of","meshes","with","coordinates","in","world","space",".","The","batch","must","live","on","a","GPU",".","Returns",":","Fragments",":","Rasterization","outputs","as","a","named","tuple",".","These","are","different","than","Fragments","returned","by","MeshRasterizer","in","two","ways",".","First",",","we","return","no","`","dist","`","which","is","only","relevant","to","SoftPhongShader","which","does","n't","work","with","MeshRasterizerOpenGL","(","because","it","is","not","differentiable",")",".","Second",",","the","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","intersections",".","In","contrast",",","MeshRasterizer","'s","zbuf","values","are","simply","the","distance","of","each","ray","intersection","from","the","camera",".","Throws",":","ValueError","if","meshes_world","lives","on","the","CPU","."]
code: def forward(self, meshes_world: Meshes, **kwargs) -> Fragments:
      """
      Args:
          meshes_world: a Meshes object representing a batch of meshes with
              coordinates in world space. The batch must live on a GPU.
  
      Returns:
          Fragments: Rasterization outputs as a named tuple. These are different than
              Fragments returned by MeshRasterizer in two ways. First, we return no
              `dist` which is only relevant to SoftPhongShader which doesn't work
              with MeshRasterizerOpenGL (because it is not differentiable). Second,
              the 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 intersections. In
              contrast, MeshRasterizer's zbuf values are simply the distance of each
              ray intersection from the camera.
  
      Throws:
          ValueError if meshes_world lives on the CPU.
      """
      if meshes_world.device == torch.device("cpu"):
          raise ValueError(
              "MeshRasterizerOpenGL works only on CUDA devices."
          )
  
      raster_settings = kwargs.get(
          "raster_settings", self.raster_settings
      )
      _check_raster_settings(raster_settings)
  
      image_size = (
          _parse_and_verify_image_size(raster_settings.image_size)
          or self.image_size
      )
  
      # OpenGL needs vertices in NDC coordinates with un-flipped xy directions.
      cameras_unpacked = kwargs.get("cameras", self.cameras)
      _check_cameras(cameras_unpacked)
      meshes_gl_ndc = _convert_meshes_to_gl_ndc(
          meshes_world, image_size, cameras_unpacked, **kwargs
      )
  
      # Perspective projection will happen within the OpenGL rasterizer.
      projection_matrix = cameras_unpacked.get_projection_transform(
          **kwargs
      )._matrix
  
      # Run OpenGL rasterization machinery.
      pix_to_face, bary_coords, zbuf = self.opengl_machinery(
          meshes_gl_ndc, projection_matrix, image_size
      )
  
      # Return the Fragments and detach, because gradients don't go through OpenGL.
      return Fragments(
          pix_to_face=pix_to_face,
          zbuf=zbuf,
          bary_coords=bary_coords,
          dists=None,
      ).detach()
  
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 2 for calling the MeshRasterizerOpenGL obj's underlying member method code with example usage: obj.forward(meshes_world) and returns: Fragments