GLMakie. 2D textured Plane in 3D space

This might be a stupid question, but i want to have a simple 2d textured plane that sits in 3d space, rendered with Makie. Eventually there should be more complex 3D Meshes, but for now i struggle to even get a textured plane.

Here is what i have so far:

verts = [[-1.0,-1.0,-1.0],[1.0,-1.0,-1.0], [1.0,1.0,-1.0], [-1.0,1.0,-1.0]] #These could change specifically be rotated
points = [Point3(p) for p in verts]
poly = Polygon( points)
fig = Figure(resolution = (600,600))
axs = Axis3(fig[1,1],aspect = :data)
mesh!(axs,poly)# throws error : no method matching earcut_triangulate()

So this method doesn’t even render a polygon. I tried with the vertices as an array and face numbers, but i seem unable to texture that mesh.

faces = [
    1 2 3;
    3 4 1;
]
verts = [-1.0;-1.0;-1.0;; 1.0;-1.0;-1.0;; 1.0;1.0;-1.0;; -1.0;1.0;-1.0]
mesh!(axs,verts, faces)

This does what i want, but i seem unable to put a texture on top of my plane. Any ideas what i can do? Its hard to use GeometryObject, since the documentation is nonexistent, and there seem to be no 2d Rect for 3d rendering, so id rather avoid it. If GeometryObject.jl is the only way to texture 3D objects, a better documentation would be great. It also seems weird to me, that the library essentially redefines Vectors (Points) which seems to be a bad going forward with compatibility with other Julia modules.

You need texture coordinates (uv) to use textures. I don’t know if those can be generated when passing vertices and faces directly, but here is how you could do it with GeometryBasics:

ps = Point3f[[-1.0,-1.0,-1.0],[1.0,-1.0,-1.0], [1.0,1.0,-1.0], [-1.0,1.0,-1.0]]
uvs = Vec2f[(0, 0), (1, 0), (1, 1), (0, 1)]
fs = GLTriangleFace[(1, 2, 3), (1, 3, 4)]
m = GeometryBasics.Mesh(meta(ps, uv = uvs, normals = normals(ps, fs)), fs)

using FileIO
img = FileIO.load(Makie.assetpath("cow.png"))

fig = Figure()
ax = Axis3(fig[1, 1])
mesh!(ax, m, color = img)
1 Like

Not sure what you mean by re-defining since there is no Point type defined already? What’s the actual problem you have? We do reinterpret matrices with size(verts, 1) == 3 and for other types we try to convert, since we need that memory layout for OpenGL.
Vector{Vector{Float}} is a bad idea for performance, so I don’t see any reason why we should encourage that.

Its hard to use GeometryObject, since the documentation is nonexistent,

That is true to be fair, and I’m currently trying to free some time to work on https://github.com/JuliaGeometry/GeometryBasics.jl/pull/173, which should make GeometryBasics much more intuitive and better documented.

The kind of error you’re getting in your example should also be addressed by the above PR.

I recently tried to update the docs a bit for textured meshes, but it’s definitely still not complete:
https://docs.makie.org/v0.18.0/examples/plotting_functions/mesh/index.html#using_geometrybasicsmesh_and_buffersampler_type

Thanks so much, that did it.

First of all, thanks for all the work you do. Just started with Makie and love it so far.
If you need the Memory layout, than its fair. I just came from the perspective, that since Julia does Vectors/Matrices so good without any help from a library like numpy, it seems strange to redefine it.
I think my main frustration was, that the documentation for GeometryBasics was lacking, when i looked at it. Some object types that might be from the deprecated older library (forgot the name) that didn’t work and no overview of all the mesh types. Keep up the good work.

We could use just plain Julia arrays, but then you’d have to always use a matrix of floats instead of Vector{Point}, and then you’re never really sure which dimension was which, etc, which is an overall annoyance. We do that conversion for you where we can, but in general it’s much clearer what you mean when you use Point, I’d say. From a memory layout point of view, they’re the same.