diff --git a/src/objects/mesh.nim b/src/objects/mesh.nim
index 74dfd06..046f3bb 100644
--- a/src/objects/mesh.nim
+++ b/src/objects/mesh.nim
@@ -252,53 +252,13 @@ proc clone*(self: MeshData): MeshData =
     d.users = @[]
     return d
 
-proc initMesh(self: Mesh, engine: MyouEngine, name: string, scene: Scene = nil,
+proc newMesh*[T](engine: MyouEngine, name: string="mesh", scene: Scene = nil,
         draw_method: MeshDrawMethod = Triangles,
         common_attributes: CommonMeshAttributes = {vertex, color},
         layout: AttributeList = @[],
-        # stride: int32 = layout.stride,
         skip_upload: bool = false,
         vertex_count: int32 = 0,
-        vertex_array: seq[float32] = @[],
-        index_array: seq[uint16] = @[],
-        pass: int32 = 0,
-    ): Mesh =
-    discard procCall(self.GameObject.initGameObject(engine, name))
-    self.otype = TMesh
-    self.passes = @[0'i32]
-    self.sort_sign = BackToFront
-    self.draw_method = draw_method
-    self.layout = layout
-    if layout.len == 0:
-        if vertex in common_attributes:
-            self.layout.add Attribute(name: "vertex", dtype: Float, count: 3)
-        if color in common_attributes:
-            self.layout.add Attribute(name: "vc_color", dtype: UByte, count: 4)
-        if normal in common_attributes:
-            self.layout.add Attribute(name: "normal", dtype: Byte, count: 4)
-        if uv in common_attributes:
-            self.layout.add Attribute(name: "uv_0", dtype: Float, count: 2)
-    let stride = self.layout.stride
-    
-    if vertex_array.len != 0:
-        var va = newArrRef(vertex_array)
-        var ia = newArrRef(index_array)
-        self.skip_upload = skip_upload
-        self.load_from_va_ia(@[va], @[ia])
-    elif vertex_count != 0:
-        self.ensure_capacity(vertex_count)
-    if scene != nil:
-        scene.add_object(self, name=name)
-    return self
-
-proc newMesh*(engine: MyouEngine, name: string="mesh", scene: Scene = nil,
-        draw_method: MeshDrawMethod = Triangles,
-        common_attributes: CommonMeshAttributes = {vertex, color},
-        layout: AttributeList = @[],
-        # stride: int32 = layout.stride,
-        skip_upload: bool = false,
-        vertex_count: int32 = 0,
-        vertex_array: seq[float32] = @[],
+        vertex_array: seq[T] = @[],
         index_array: seq[uint16] = @[],
         pass: int32 = 0,
     ): Mesh =
@@ -320,13 +280,64 @@ proc newMesh*(engine: MyouEngine, name: string="mesh", scene: Scene = nil,
     ## If you give a vertex array and an index array, they will be used directly
     ## as GPU buffers. If you only supply the vertex array, indices will
     ## implicitely be sequential.
-
+    
     # TODO: document pass and skip_upload
-    new(result)
-    result.otype = TMesh
+    let self = new Mesh
+    self.otype = TMesh
 
-    return initMesh(result, engine, name, scene, draw_method, common_attributes, layout, 
-        skip_upload, vertex_count, vertex_array, index_array, pass)
+    discard procCall(self.GameObject.initGameObject(engine, name))
+    self.otype = TMesh
+    self.passes = @[0'i32]
+    self.sort_sign = BackToFront
+    self.draw_method = draw_method
+    self.layout = layout
+    if layout.len == 0:
+        if vertex in common_attributes:
+            self.layout.add Attribute(name: "vertex", dtype: Float, count: 3)
+        if color in common_attributes:
+            self.layout.add Attribute(name: "vc_color", dtype: UByte, count: 4)
+        if normal in common_attributes:
+            self.layout.add Attribute(name: "normal", dtype: Byte, count: 4)
+        if uv in common_attributes:
+            self.layout.add Attribute(name: "uv_0", dtype: Float, count: 2)
+    let stride = self.layout.stride
+    
+    if vertex_array.len != 0:
+        var va = newArrRef(vertex_array).to float32
+        var ia = newArrRef(index_array)
+        self.skip_upload = skip_upload
+        self.load_from_va_ia(@[va], @[ia])
+    elif vertex_count != 0:
+        self.ensure_capacity(vertex_count)
+    if scene != nil:
+        scene.add_object(self, name=name)
+    return self
+
+proc newMesh*(engine: MyouEngine, name: string="mesh", scene: Scene = nil,
+        draw_method: MeshDrawMethod = Triangles,
+        common_attributes: CommonMeshAttributes = {vertex, color},
+        layout: AttributeList = @[],
+        skip_upload: bool = false,
+        vertex_count: int32 = 0,
+        pass: int32 = 0,
+    ): Mesh =
+    ## Create a new Mesh object. If you supply `scene` it will be added to that
+    ## scene.
+    ## 
+    ## The most common draw methods are `Triangles` (the default), `Points`,
+    ## `Lines`, and `TriangleStrip` (for `add_polygonal_line()`).
+    ## 
+    ## If you supply a layout, it will be used. Otherwise a layout will be
+    ## created from `common_attributes`, which by default is `{vertex, color}`.
+    ## The available common attributes are `{vertex, color, normal, uv}` and they
+    ## will be added in that order.
+    ## 
+    ## You can give a `vertex_count` to allocate a mesh with capacity for that
+    ## amount of vertices, but you can always resize it later. Meant to be used
+    ## with `add_vertex()` and `add_polygonal_line`
+    
+    newMesh[float32](engine, name, scene, draw_method, common_attributes, layout,
+            skip_upload, vertex_count, @[], @[], pass)
 
 proc add_vertex*(self: Mesh, x, y, z: float32, r, g, b, a: uint8): int {.discardable.} =
     ## Tries to add a vertex to the mesh with the specified position and color.
diff --git a/src/scene.nim b/src/scene.nim
index 38c3156..378c565 100644
--- a/src/scene.nim
+++ b/src/scene.nim
@@ -410,14 +410,13 @@ proc new_gameobject*(self: Scene, name: string): GameObject =
     ## Create a GameObject and add it to the scene.
     return self.engine.new_gameobject(name=name, scene=self)
 
-proc new_mesh*(self: Scene, name: string,
+proc new_mesh*[T](self: Scene, name: string,
         draw_method: MeshDrawMethod = Triangles,
         common_attributes: CommonMeshAttributes = {vertex, color},
         layout: AttributeList = @[],
-        # stride: int32 = layout.stride,
         skip_upload: bool = false,
         vertex_count: int32 = 0,
-        vertex_array: seq[float32] = @[],
+        vertex_array: seq[T] = @[],
         index_array: seq[uint16] = @[],
         pass: int32 = 0,
     ): Mesh =
@@ -441,6 +440,30 @@ proc new_mesh*(self: Scene, name: string,
     self.engine.new_mesh(name, self, draw_method, common_attributes, layout, 
         skip_upload, vertex_count, vertex_array, index_array, pass)
 
+proc new_mesh*(self: Scene, name: string,
+        draw_method: MeshDrawMethod = Triangles,
+        common_attributes: CommonMeshAttributes = {vertex, color},
+        layout: AttributeList = @[],
+        skip_upload: bool = false,
+        vertex_count: int32 = 0,
+        pass: int32 = 0,
+    ): Mesh =
+    ## Create a new Mesh object and add it to this scene.
+    ## 
+    ## The most common draw methods are `Triangles` (the default), `Points`,
+    ## `Lines`, and `TriangleStrip` (for `add_polygonal_line()`).
+    ## 
+    ## If you supply a layout, it will be used. Otherwise a layout will be
+    ## created from `common_attributes`, which by default is `{vertex, color}`.
+    ## The available common attributes are `{vertex, color, normal, uv}` and they
+    ## will be added in that order.
+    ## 
+    ## You can give a `vertex_count` to allocate a mesh with capacity for that
+    ## amount of vertices, but you can always resize it later. Meant to be used
+    ## with `add_vertex()` and `add_polygonal_line`
+    new_mesh[float32](self.engine, name, self, draw_method, common_attributes, layout, 
+        skip_upload, vertex_count, @[], @[], pass)
+
 proc newCamera*(self: Scene, name: string="camera",
         near_plane: float32 = 0.1,
         far_plane: float32 = 10000,