Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# Add new textures to context
for texture in mesh_textures - self._mesh_textures:
texture._add_to_context()
# Remove old textures from context
for texture in self._mesh_textures - mesh_textures:
texture.delete()
self._mesh_textures = mesh_textures.copy()
shadow_textures = set()
for l in scene.lights:
# Create if needed
active = False
if (isinstance(l, DirectionalLight) and
flags & RenderFlags.SHADOWS_DIRECTIONAL):
active = True
elif (isinstance(l, PointLight) and
flags & RenderFlags.SHADOWS_POINT):
active = True
elif isinstance(l, SpotLight) and flags & RenderFlags.SHADOWS_SPOT:
active = True
if active and l.shadow_texture is None:
l._generate_shadow_texture()
if l.shadow_texture is not None:
shadow_textures.add(l.shadow_texture)
# Add new textures to context
for texture in shadow_textures - self._shadow_textures:
texture._add_to_context()
def _bind_and_draw_primitive(self, primitive, pose, program, flags):
# Set model pose matrix
program.set_uniform('M', pose)
# Bind mesh buffers
primitive._bind()
# Bind mesh material
if not flags & RenderFlags.DEPTH_ONLY:
material = primitive.material
# Bind textures
tf = material.tex_flags
if tf & TexFlags.NORMAL:
self._bind_texture(material.normalTexture,
'material.normal_texture', program)
if tf & TexFlags.OCCLUSION:
self._bind_texture(material.occlusionTexture,
'material.occlusion_texture', program)
if tf & TexFlags.EMISSIVE:
self._bind_texture(material.emissiveTexture,
'material.emissive_texture', program)
if tf & TexFlags.BASE_COLOR:
self._bind_texture(material.baseColorTexture,
'material.base_color_texture', program)
program.set_uniform(b.format('glossiness_factor'),
material.glossinessFactor)
# Set blending options
if material.alphaMode == 'BLEND':
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
else:
glEnable(GL_BLEND)
glBlendFunc(GL_ONE, GL_ZERO)
# Set wireframe mode
wf = material.wireframe
if flags & RenderFlags.FLIP_WIREFRAME:
wf = not wf
if (flags & RenderFlags.ALL_WIREFRAME) or wf:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
else:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
# Set culling mode
if material.doubleSided or flags & RenderFlags.SKIP_CULL_FACES:
glDisable(GL_CULL_FACE)
else:
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
else:
glEnable(GL_CULL_FACE)
glEnable(GL_BLEND)
glCullFace(GL_BACK)
glBlendFunc(GL_ONE, GL_ZERO)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
Returns
-------
color_im : (h, w, 3) uint8 or (h, w, 4) uint8
If :attr:`RenderFlags.OFFSCREEN` is set, the color buffer. This is
normally an RGB buffer, but if :attr:`.RenderFlags.RGBA` is set,
the buffer will be a full RGBA buffer.
depth_im : (h, w) float32
If :attr:`RenderFlags.OFFSCREEN` is set, the depth buffer
in linear units.
"""
# Update context with meshes and textures
self._update_context(scene, flags)
# Render necessary shadow maps
if not bool(flags & RenderFlags.DEPTH_ONLY):
for ln in scene.light_nodes:
take_pass = False
if (isinstance(ln.light, DirectionalLight) and
bool(flags & RenderFlags.SHADOWS_DIRECTIONAL)):
take_pass = True
elif (isinstance(ln.light, SpotLight) and
bool(flags & RenderFlags.SHADOWS_SPOT)):
take_pass = True
elif (isinstance(ln.light, PointLight) and
bool(flags & RenderFlags.SHADOWS_POINT)):
take_pass = True
if take_pass:
self._shadow_mapping_pass(scene, ln, flags)
# Make forward pass
retval = self._forward_pass(scene, flags)
for node in self._sorted_mesh_nodes(scene):
mesh = node.mesh
# Skip the mesh if it's not visible
if not mesh.is_visible:
continue
for primitive in mesh.primitives:
# Skip objects that don't have normals
if not primitive.buf_flags & BufFlags.NORMAL:
continue
# First, get and bind the appropriate program
pf = ProgramFlags.NONE
if flags & RenderFlags.VERTEX_NORMALS:
pf = pf | ProgramFlags.VERTEX_NORMALS
if flags & RenderFlags.FACE_NORMALS:
pf = pf | ProgramFlags.FACE_NORMALS
program = self._get_primitive_program(primitive, flags, pf)
program._bind()
# Set the camera uniforms
program.set_uniform('V', V)
program.set_uniform('P', P)
program.set_uniform('normal_magnitude', 0.05 * primitive.scale)
program.set_uniform(
'normal_color', np.array([0.1, 0.1, 1.0, 1.0])
)
# Finally, bind and draw the primitive
self._bind_and_draw_primitive(
depth_im[noninf] = 2 * z_near / (1.0 - depth_im[noninf])
else:
depth_im[noninf] = ((2.0 * z_near * z_far) /
(z_far + z_near - depth_im[noninf] *
(z_far - z_near)))
depth_im[inf_inds] = 0.0
# Resize for macos if needed
if sys.platform == 'darwin':
depth_im = self._resize_image(depth_im)
if flags & RenderFlags.DEPTH_ONLY:
return depth_im
# Read color
if flags & RenderFlags.RGBA:
color_buf = glReadPixels(
0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE
)
color_im = np.frombuffer(color_buf, dtype=np.uint8)
color_im = color_im.reshape((height, width, 4))
else:
color_buf = glReadPixels(
0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE
)
color_im = np.frombuffer(color_buf, dtype=np.uint8)
color_im = color_im.reshape((height, width, 3))
color_im = np.flip(color_im, axis=0)
# Resize for macos if needed
if sys.platform == 'darwin':
color_im = self._resize_image(color_im, True)
# Skip the mesh if it's not visible
if not mesh.is_visible:
continue
for primitive in mesh.primitives:
# Skip objects that don't have normals
if not primitive.buf_flags & BufFlags.NORMAL:
continue
# First, get and bind the appropriate program
pf = ProgramFlags.NONE
if flags & RenderFlags.VERTEX_NORMALS:
pf = pf | ProgramFlags.VERTEX_NORMALS
if flags & RenderFlags.FACE_NORMALS:
pf = pf | ProgramFlags.FACE_NORMALS
program = self._get_primitive_program(primitive, flags, pf)
program._bind()
# Set the camera uniforms
program.set_uniform('V', V)
program.set_uniform('P', P)
program.set_uniform('normal_magnitude', 0.05 * primitive.scale)
program.set_uniform(
'normal_color', np.array([0.1, 0.1, 1.0, 1.0])
)
# Finally, bind and draw the primitive
self._bind_and_draw_primitive(
primitive=primitive,
pose=scene.get_pose(node),
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
else:
glEnable(GL_BLEND)
glBlendFunc(GL_ONE, GL_ZERO)
# Set wireframe mode
wf = material.wireframe
if flags & RenderFlags.FLIP_WIREFRAME:
wf = not wf
if (flags & RenderFlags.ALL_WIREFRAME) or wf:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
else:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
# Set culling mode
if material.doubleSided or flags & RenderFlags.SKIP_CULL_FACES:
glDisable(GL_CULL_FACE)
else:
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
else:
glEnable(GL_CULL_FACE)
glEnable(GL_BLEND)
glCullFace(GL_BACK)
glBlendFunc(GL_ONE, GL_ZERO)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
# Set point size if needed
glDisable(GL_PROGRAM_POINT_SIZE)
if primitive.mode == GLTF.POINTS:
glEnable(GL_PROGRAM_POINT_SIZE)
glPointSize(self.point_size)
program.set_uniform(b.format('specular_factor'),
material.specularFactor)
program.set_uniform(b.format('glossiness_factor'),
material.glossinessFactor)
# Set blending options
if material.alphaMode == 'BLEND':
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
else:
glEnable(GL_BLEND)
glBlendFunc(GL_ONE, GL_ZERO)
# Set wireframe mode
wf = material.wireframe
if flags & RenderFlags.FLIP_WIREFRAME:
wf = not wf
if (flags & RenderFlags.ALL_WIREFRAME) or wf:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
else:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
# Set culling mode
if material.doubleSided or flags & RenderFlags.SKIP_CULL_FACES:
glDisable(GL_CULL_FACE)
else:
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
else:
glEnable(GL_CULL_FACE)
glEnable(GL_BLEND)
glCullFace(GL_BACK)
for texture in self._mesh_textures - mesh_textures:
texture.delete()
self._mesh_textures = mesh_textures.copy()
shadow_textures = set()
for l in scene.lights:
# Create if needed
active = False
if (isinstance(l, DirectionalLight) and
flags & RenderFlags.SHADOWS_DIRECTIONAL):
active = True
elif (isinstance(l, PointLight) and
flags & RenderFlags.SHADOWS_POINT):
active = True
elif isinstance(l, SpotLight) and flags & RenderFlags.SHADOWS_SPOT:
active = True
if active and l.shadow_texture is None:
l._generate_shadow_texture()
if l.shadow_texture is not None:
shadow_textures.add(l.shadow_texture)
# Add new textures to context
for texture in shadow_textures - self._shadow_textures:
texture._add_to_context()
# Remove old textures from context
for texture in self._shadow_textures - shadow_textures:
texture.delete()
self._shadow_textures = shadow_textures.copy()