The render.opengl()
operator is working fine for all modes. But notice that it takes a screenshot of the first viewport found, quoting the docs: "Take a snapshot of the active viewport". So in case you have multiple 3d viewports open at the same time it takes the first one in the area list of your screen (Screen.Areas
).
Obviously the simplest option is to close all 3d viewports except one, set the shading mode, call the operator and pass write_still=True
to take the screenshot as well as saving the file into the default Output directory:
>>> bpy.ops.render.opengl(write_still=True)
In case you have multiple viewports open and you'd like to specify the area for the screenshot, you can override the context when calling render.opengl()
operator. See the following demo on how to find the first 3d viewport set to 'WIREFRAME'
and take a screenshot:
Blender 3.2+
import bpy
C = bpy.context
for area in C.screen.areas:
if area.type == 'VIEW_3D':
# Check for WIREFRAME, SOLID, RENDERED, MATERIAL
if area.spaces.active.shading.type == 'WIREFRAME':
with C.temp_override(area=area):
bpy.ops.render.opengl(write_still=True)
break
Blender 2.8+
import bpy
C = bpy.context
for area in C.screen.areas:
if area.type=='VIEW_3D':
# Check for WIREFRAME, SOLID, RENDERED, MATERIAL
# area.spaces.active.shading.type
if area.spaces.active.shading.type == 'WIREFRAME':
override = C.copy()
override['area'] = area
bpy.ops.render.opengl(override, write_still=True)
break
In order to set the filename, just temporary assign your path to the RenderSettings.filepath
property. Demo on how to take a screenshot of the first viewport found set to 'WIREFRAME'
and save the result to the directory of the current blend file:
Blender 3.2+
file_path = bpy.path.abspath("//screenshot")
for area in C.screen.areas:
if area.type=='VIEW_3D':
if area.spaces.active.shading.type == 'WIREFRAME':
# Store the current output path and set it
temp = C.scene.render.filepath
C.scene.render.filepath = file_path
with C.temp_override(area=area):
bpy.ops.render.opengl(write_still=True)
# Restore the output path
C.scene.render.filepath = temp
break
print (file_path)
Blender 2.8+
file_path = bpy.path.abspath("//screenshot")
for area in C.screen.areas:
if area.type=='VIEW_3D':
if area.spaces.active.shading.type == 'WIREFRAME':
# Store the current output path and set it
temp = C.scene.render.filepath
C.scene.render.filepath = file_path
override = C.copy()
override['area'] = area
bpy.ops.render.opengl(override, write_still=True)
# Restore the output path
C.scene.render.filepath = temp
break
print (file_path)