1
$\begingroup$

So I'm looking at https://docs.blender.org/api/current/gpu.html?highlight=batch_for_shader

I just want to draw a cube with a single color using batch_for_shader(). I'm looking at the "Mesh with Random Vertex Colors" section, which does everything I need except adds random colors (like the name says). And I'm having a hard time figuring out what I can do to just replace it with a flat color.

Ideally I would also like to be able to give said cube a low-opacity, flat-shaded appearance, but I want to at least get the "easy" stuff working first...

I tried replacing the shader with '3D_UNIFORM_COLOR', removing

"color": vertex_colors

and adding the line

shader.uniform_float( "color", (1, 0, 0, 1) )

It at least runs, but it completely ignores the color value I try to give it.

The code as I have it now is as follows. (Move the default cube and leave it selected)

import bpy
import gpu
import numpy as np
from random import random
from gpu_extras.batch import batch_for_shader

mesh = bpy.context.active_object.data
mesh.calc_loop_triangles()

vertices = np.empty((len(mesh.vertices), 3), 'f')
indices = np.empty((len(mesh.loop_triangles), 3), 'i')

mesh.vertices.foreach_get(
    "co", np.reshape(vertices, len(mesh.vertices) * 3))
mesh.loop_triangles.foreach_get(
    "vertices", np.reshape(indices, len(mesh.loop_triangles) * 3))

shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
batch = batch_for_shader(
    shader, 'TRIS',
    {"pos": vertices },
    indices=indices,
)

shader.uniform_float( "color", (1, 0, 0, 1) )

def draw():
    gpu.state.depth_test_set('LESS_EQUAL')
    gpu.state.depth_mask_set(True)
    batch.draw(shader)
    gpu.state.depth_mask_set(False)


bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
$\endgroup$

1 Answer 1

2
$\begingroup$

I was able to get it working by modifying a different example from the page. I had actually tried this one previously, but I must have mistyped something because this time it worked.

The working code is as follows:

import bpy
import gpu
from gpu_extras.batch import batch_for_shader

coords = (
    (-1, -1, -1), (+1, -1, -1),
    (-1, +1, -1), (+1, +1, -1),
    (-1, -1, +1), (+1, -1, +1),
    (-1, +1, +1), (+1, +1, +1))

indices = (
    (0, 1, 3), (0, 2, 3), (4,5,7), (4,6,7),
    (0,4,5), (0,1,5), (2,0,4), (2,6,4),
    (1,3,7), (1, 5,7), (3, 2, 6), (3,6, 7))

shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
batch = batch_for_shader(shader, 'TRIS', {"pos": coords}, indices=indices)

def draw():
    shader.bind()
    shader.uniform_float("color", (1, 0, 0, 0.25))
    batch.draw(shader)

bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .