def add_to_mesh(self, mesh: TriangleMesh): offset = self.body.position rotation = self.body.angle if isinstance(self.shape, Poly): vertices = [ glm.vec3(v.rotated(rotation) + offset, 0) for v in self.shape.get_vertices() ] for i in range(len(vertices) - 1): mesh.add_triangle( vertices[0], vertices[i + 1], vertices[i], ) elif self.shape_type == "circle": num_seg = 4 center = glm.vec3(offset, 0) vertices = [ glm.vec3( Vec2d(math.sin(s / num_seg * math.pi), math.cos(s / num_seg * math.pi)).rotated(rotation) * self.scale / 2. + offset, 0) for s in range(num_seg * 2 + 1) ] for i in range(len(vertices) - 1): mesh.add_triangle( center, vertices[i + 1], vertices[i], )
def create_mesh(self) -> MeshObject: mesh = TriangleMesh() mesh.create_attribute("a_part", 1, 0., gl.GLfloat) factory = MeshFactory() # head mesh.set_attribute_value("a_part", 0.) #factory.add_dodecahedron(mesh) factory.add_uv_sphere(mesh, .5, num_u=24, num_v=12) # eyes with factory: factory.translate((-.3, .3, .2)) factory.rotate_z(20) factory.add_cylinder(mesh, .2, .3) with factory: factory.translate((.3, .3, .2)) factory.rotate_z(-20) factory.add_cylinder(mesh, .2, .3) # left food mesh.set_attribute_value("a_part", 1.) factory.add_dodecahedron(mesh) # right food mesh.set_attribute_value("a_part", 2.) factory.add_dodecahedron(mesh) return MeshObject(mesh, num_parts=3, name="walker-mesh")
def build_object_mesh(self) -> TriangleMesh: mesh = TriangleMesh() mesh.create_attribute("a_color", 4, (1, 1, 1, .9)) #mesh.set_attribute_value("a_color", (1, 1, 1, .5)) for o in self.object_map.static_objects.values(): o.add_to_mesh(mesh) for o in self.object_map.objects: o.add_to_mesh(mesh) return mesh
def create_mesh(self, do_ambient=True): mesh = TriangleMesh() mesh.create_attribute("a_ambient", 3) def add_quad(p1, p2, p3, p4, *uvquad): mesh.add_quad(p1, p2, p3, p4, *uvquad) for p in (p1, p2, p3, p1, p3, p4): if do_ambient: mesh.add_attribute("a_ambient", self.get_ambient_color(*p)) else: mesh.add_attribute("a_ambient", (1, 1, 1)) for z in range(self.num_z): z1 = z + 1 for y in range(self.num_y): y1 = y + 1 for x in range(self.num_x): x1 = x + 1 b = self.block(x, y, z) if b.space_type: uvquad = self.tileset.get_uv_quad(b.texture) # bottom if not self.is_wall(x, y, z - 1, self.TOP): add_quad((x, y1, z), (x1, y1, z), (x1, y, z), (x, y, z), *uvquad) # top if not self.is_wall(x, y, z + 1, self.BOTTOM): add_quad((x, y, z1), (x1, y, z1), (x1, y1, z1), (x, y1, z1), *uvquad) # front if not self.is_wall(x, y - 1, z, self.BACK): add_quad((x, y, z), (x1, y, z), (x1, y, z1), (x, y, z1), *uvquad) # back if not self.is_wall(x, y + 1, z, self.FRONT): add_quad((x, y1, z), (x, y1, z1), (x1, y1, z1), (x1, y1, z), *uvquad) # left if not self.is_wall(x - 1, y, z, self.RIGHT): add_quad((x, y1, z), (x, y, z), (x, y, z1), (x, y1, z1), *uvquad) # right if not self.is_wall(x + 1, y, z, self.LEFT): add_quad((x1, y, z), (x1, y1, z), (x1, y1, z1), (x1, y, z1), *uvquad) #print("LEN", len(mesh._vertices), len(mesh._attributes["a_ambient"]["values"])) return mesh
def __init__(self, filename="./assets/pokeson.png"): self.tileset = Tileset.from_image(32, 32, filename) #print("agent", self.tileset) self.texture = None self.mesh = TriangleMesh() s = 1 uv = self.tileset.get_uv_quad(0) self.mesh.add_quad((-s, 0, 0), (s, 0, 0), (s, 2 * s, 0), (-s, 2 * s, 0), *uv) self.drawable_name = "agent-drawable" if not OpenGlAssets.has(self.drawable_name): draw = Drawable() draw.shader.set_vertex_source(VERTEX_SRC) draw.shader.set_fragment_source(FRAGMENT_SRC) self.mesh.update_drawable(draw) OpenGlAssets.register(self.drawable_name, draw) self.drawable = draw else: self.drawable = OpenGlAssets.get(self.drawable_name)
def create_mesh(self) -> MeshObject: mesh = TriangleMesh() mesh.create_attribute("a_part", 1, 0., gl.GLfloat) factory = MeshFactory() mesh.set_attribute_value("a_part", 0.) factory.add_uv_sphere(mesh, .5, num_u=12, num_v=6) return MeshObject(mesh, num_parts=3, name=f"{self.id}-mesh")
def __init__( self, name: str, object_map: Objects, tile_size: Tuple[int, int], tile_set_size: Tuple[int, int], ): super().__init__(name) self.object_map = object_map self.tile_size = tile_size self.tile_set_size = tile_set_size self.drawable = Drawable(f"{name}-drawable") self._element_buffer: Optional[ArrayBufferObject] = None self._element_texture: Optional[ArrayBufferObject] = None self.drawable.shader.set_vertex_source(DEFAULT_SHADER_VERSION + """ #include <vector.glsl> #line 35 uniform mat4 u_projection; uniform mat4 u_transformation; uniform mat4 u_transformation_inv; uniform ivec2 u_tile_size; uniform ivec2 u_tile_set_size; in vec4 a_position; in vec2 a_texcoord; in vec4 a_element_buffer; in vec4 a_element_texture; out vec4 v_pos; out vec2 v_texcoord; out vec4 v_color; void main() { vec4 position = a_position; position.xy *= a_element_buffer.w; position.xy = rotate_z(position.xy, a_element_buffer.z) + a_element_buffer.xy; int tile_idx = int(a_element_texture.w + .1); v_texcoord = a_texcoord / u_tile_set_size + vec2(tile_idx % u_tile_set_size.x, tile_idx / u_tile_set_size.x) / u_tile_set_size; v_pos = a_position; v_color = vec4(a_element_texture.xyz, 1); //v_world_normal = normalize((vec4(a_normal, 0.) * u_transformation_inv).xyz); gl_Position = u_projection * u_transformation * position; } """) self.drawable.shader.set_fragment_source(DEFAULT_SHADER_VERSION + """ #line 77 uniform sampler2D u_tex1; in vec4 v_pos; in vec2 v_texcoord; in vec4 v_color; out vec4 fragColor; void main() { vec4 col = texture(u_tex1, v_texcoord) * v_color; fragColor = col; } """) mesh = TriangleMesh() MeshFactory().add_quad(mesh, glm.vec3(-.5, -.5, 0), glm.vec3(-.5, .5, 0), glm.vec3(.5, .5, 0), glm.vec3(.5, -.5, 0)) mesh.update_drawable(self.drawable)
class InstancingNode(RenderNode): def __init__(self, name): super().__init__(name) factory = MeshFactory() self.mesh = TriangleMesh() factory.add_cube(self.mesh, 1.) self.drawable = self.mesh.create_drawable() self.drawable.shader.set_vertex_source(DEFAULT_SHADER_VERSION + """ #line 19 uniform mat4 u_projection; uniform mat4 u_transformation; uniform mat4 u_transformation_inv; in vec4 a_position; in vec3 a_normal; in vec4 a_color; in vec2 a_texcoord; in vec3 a_ambient; in vec4 a_instance_color; in mat4 a_instance_transform; out vec4 v_pos; out vec3 v_normal; out vec4 v_color; out vec2 v_texcoord; out vec3 v_ambient; out vec3 v_world_normal; void main() { vec4 position = a_instance_transform * a_position; v_pos = position; v_normal = a_normal; v_world_normal = normalize((vec4(a_normal, 0.) * u_transformation_inv).xyz); v_color = a_instance_color; v_texcoord = a_texcoord; v_ambient = a_ambient; gl_Position = u_projection * u_transformation * position; } """) self.drawable.shader.set_fragment_source(DEFAULT_SHADER_VERSION + """ #line 18 in vec4 v_pos; in vec4 v_color; in vec3 v_normal; in vec2 v_texcoord; uniform float u_time; out vec4 fragColor; vec3 lighting(in vec3 pos, in vec3 norm, in vec3 light_pos, in vec3 color) { vec3 light_norm = normalize(light_pos - pos); float d = max(0., dot(norm, light_norm)); return color * pow(d, 5.); } void main() { vec3 col = v_color.xyz + .02 * v_normal; vec3 norm = v_normal; //normalize(v_normal + .1 * sin(length(v_pos.xyz) * 34. - 5. * u_time)); col += .3 * lighting(v_pos.xyz, norm, vec3(3, 0, 1), vec3(1, .6, .4)); col += .3 * lighting(v_pos.xyz, norm, vec3(-3, 1, 2), vec3(.5, 1, .4)); col += .3 * lighting(v_pos.xyz, norm, vec3(1, 5, 3), vec3(.3, .6, 1)); fragColor = vec4(col, 1); } """) if 0: self.instance_colors = [ 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, ] self.instance_transforms = [ glm.mat4(1), glm.translate(glm.mat4(1), glm.vec3(1, 0, 0)), glm.translate(glm.mat4(1), glm.vec3(1, 1, 0)), glm.rotate(glm.translate(glm.mat4(1), glm.vec3(-.5, 1, 0)), glm.pi() / 4., glm.vec3(0, 1, 0)), ] else: self.instance_colors = [] self.instance_transforms = [] for i in range(500): self.instance_colors.append(random.uniform(0.1, 1.)) self.instance_colors.append(random.uniform(0.1, 1.)) self.instance_colors.append(random.uniform(0.1, 1.)) self.instance_colors.append(1.) self.instance_transforms.append( glm.translate( glm.mat4(1), 20. * glm.vec3(random.uniform(-1, 1), random.uniform(-1, 1), random.uniform(-1, 1)))) def num_multi_sample(self): return 32 def has_depth_output(self): return True def release(self): self.drawable.release() def create(self, rs: RenderSettings): self.drawable.prepare() vao: VertexArrayObject = self.drawable.vao vao.create_attribute_buffer( attribute_location=self.drawable.shader.attribute( "a_instance_color").location, num_dimensions=4, Type=GLfloat, values=self.instance_colors, divisor=1, ) if self.drawable.shader.has_attribute("a_instance_transform"): flat_transforms = [] for mat in self.instance_transforms: for col in mat: for v in col: flat_transforms.append(v) for i in range(4): vao.create_attribute_buffer( attribute_location=self.drawable.shader.attribute( "a_instance_transform").location + i, num_dimensions=4, Type=GLfloat, values=flat_transforms, stride=ctypes.sizeof(GLfloat) * 16, offset=ctypes.sizeof(ctypes.c_float) * 4 * i, divisor=1, ) def render(self, rs, pass_num): self.drawable.shader.set_uniform("u_time", rs.time) self.drawable.shader.set_uniform("u_projection", rs.projection.matrix) glEnable(GL_CULL_FACE) glEnable(GL_DEPTH_TEST) self.drawable.draw(num_instances=len(self.instance_colors))
def __init__(self, name): super().__init__(name) factory = MeshFactory() self.mesh = TriangleMesh() factory.add_cube(self.mesh, 1.) self.drawable = self.mesh.create_drawable() self.drawable.shader.set_vertex_source(DEFAULT_SHADER_VERSION + """ #line 19 uniform mat4 u_projection; uniform mat4 u_transformation; uniform mat4 u_transformation_inv; in vec4 a_position; in vec3 a_normal; in vec4 a_color; in vec2 a_texcoord; in vec3 a_ambient; in vec4 a_instance_color; in mat4 a_instance_transform; out vec4 v_pos; out vec3 v_normal; out vec4 v_color; out vec2 v_texcoord; out vec3 v_ambient; out vec3 v_world_normal; void main() { vec4 position = a_instance_transform * a_position; v_pos = position; v_normal = a_normal; v_world_normal = normalize((vec4(a_normal, 0.) * u_transformation_inv).xyz); v_color = a_instance_color; v_texcoord = a_texcoord; v_ambient = a_ambient; gl_Position = u_projection * u_transformation * position; } """) self.drawable.shader.set_fragment_source(DEFAULT_SHADER_VERSION + """ #line 18 in vec4 v_pos; in vec4 v_color; in vec3 v_normal; in vec2 v_texcoord; uniform float u_time; out vec4 fragColor; vec3 lighting(in vec3 pos, in vec3 norm, in vec3 light_pos, in vec3 color) { vec3 light_norm = normalize(light_pos - pos); float d = max(0., dot(norm, light_norm)); return color * pow(d, 5.); } void main() { vec3 col = v_color.xyz + .02 * v_normal; vec3 norm = v_normal; //normalize(v_normal + .1 * sin(length(v_pos.xyz) * 34. - 5. * u_time)); col += .3 * lighting(v_pos.xyz, norm, vec3(3, 0, 1), vec3(1, .6, .4)); col += .3 * lighting(v_pos.xyz, norm, vec3(-3, 1, 2), vec3(.5, 1, .4)); col += .3 * lighting(v_pos.xyz, norm, vec3(1, 5, 3), vec3(.3, .6, 1)); fragColor = vec4(col, 1); } """) if 0: self.instance_colors = [ 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, ] self.instance_transforms = [ glm.mat4(1), glm.translate(glm.mat4(1), glm.vec3(1, 0, 0)), glm.translate(glm.mat4(1), glm.vec3(1, 1, 0)), glm.rotate(glm.translate(glm.mat4(1), glm.vec3(-.5, 1, 0)), glm.pi() / 4., glm.vec3(0, 1, 0)), ] else: self.instance_colors = [] self.instance_transforms = [] for i in range(500): self.instance_colors.append(random.uniform(0.1, 1.)) self.instance_colors.append(random.uniform(0.1, 1.)) self.instance_colors.append(random.uniform(0.1, 1.)) self.instance_colors.append(1.) self.instance_transforms.append( glm.translate( glm.mat4(1), 20. * glm.vec3(random.uniform(-1, 1), random.uniform(-1, 1), random.uniform(-1, 1))))
class AgentRenderer: DOWN = 1 LEFT = 2 UP = 3 RIGHT = 4 def __init__(self, filename="./assets/pokeson.png"): self.tileset = Tileset.from_image(32, 32, filename) #print("agent", self.tileset) self.texture = None self.mesh = TriangleMesh() s = 1 uv = self.tileset.get_uv_quad(0) self.mesh.add_quad((-s, 0, 0), (s, 0, 0), (s, 2 * s, 0), (-s, 2 * s, 0), *uv) self.drawable_name = "agent-drawable" if not OpenGlAssets.has(self.drawable_name): draw = Drawable() draw.shader.set_vertex_source(VERTEX_SRC) draw.shader.set_fragment_source(FRAGMENT_SRC) self.mesh.update_drawable(draw) OpenGlAssets.register(self.drawable_name, draw) self.drawable = draw else: self.drawable = OpenGlAssets.get(self.drawable_name) def release(self): if self.texture is not None: OpenGlAssets.unregister(self.texture) OpenGlAssets.unregister(self.drawable) def render(self, projection, pos, dir, frame_num): self._update() trans = projection.matrix mat = glm.translate(trans, pos + (0, 0, 0)) p1 = mat * glm.vec4(0, 0, 0, 1) p2 = mat * glm.vec4(0, 1, 0, 1) p = p2 - p1 a = glm.atan(p.x, p.y) mat = glm.rotate(mat, a, (0, 0, 1)) mat = glm.rotate(mat, glm.pi() / 2., (1, 0, 0)) tile_idx = self.get_tileset_idx(dir, frame_num) self.texture.bind() self.drawable.shader.set_uniform("u_projection", mat) self.drawable.shader.set_uniform("u_tex_offset", self.tileset.get_uv_offset(tile_idx)) self.drawable.draw() def _update(self): if not self.texture: self.texture = self.tileset.create_texture2d() def get_tileset_idx(self, dir, frame_num): idx = (dir - 1) * self.tileset.width + frame_num return idx