m3diaLib-Team / m3dctr-examples

Examples for the m3diaLib
6 stars 3 forks source link

More samples #2

Open Eeems opened 4 years ago

Eeems commented 4 years ago

I'd like to see a couple more samples include. I'd be happy to open a PR with them myself after getting some help figuring them out.

StuntHacks commented 4 years ago

Right now I sadly don't have the means to add these examples myself, however, I'll gladly assist you with these tasks, regardless whether you'll create a PR or not.

First of all, an OBJ-model can be loaded via m3d::Model::loadFromFile(). This model needs to be tessellated into triangles beforehand, though, or it will not render correctly. After loading, you can simply pass it to the drawTop() or drawBottom() functions of m3d::Screen in order to draw it on the respective screen. This approach for drawing on both screens works with all drawables.

In it's current state, this library doesn't support skeletal animation. You could, however, use frame-based model-animation. For that you will want to use m3d::Mesh::addPolygon() and m3d::Mesh::clearVertices() (since m3d::Model inherits from m3d::Mesh, it also has these functions). You could load all frames into memory, and then quickly clear all vertices and add the polygons of the new frame whenever you want to update the animation. Keep in mind that this approach isn't the most performant, though.

For custom shading, you can provide a shading-function to the two draw-functions of m3d::Screen. This gets called immediately before the draw()-function of the passed drawable, and can be used to execute custom code, or set set custom flags using citro3d. This way you could load your own shader, and then bind it in that function. See https://docs.stunthacks.eu/m3dialib/classm3d_1_1_screen.html#af43a49496e1b669cb0754f608c372b5a.

For a skybox, this isn't a primitive-feature of the library, so you would need to implement it yourself. You could simply draw a m3d::Cuboid with the texture of your skybox, moving with the camera, and bigger than your entire scene, so that everything is within this cuboid. You will probably need to disable culling, though, either globally using m3d::Screen::useCulling(), or (recommended) just for the skybox using the custom shading function discussed earlier.

Eeems commented 4 years ago

I had figured out how to load models yesterday on my own but I hadn't seen the t_shadingFunction parameter yet thanks! I'll have to play around with displaying on both screens and I'll put together a couple examples in a PR for that.

I've also kind of figured out a skybox using a similar method to m3d::Cuboid but I haven't played around with culling or a custom shader for it.

As for animation, I'd rather put together an example that actually performs well. In which case it seems like I should figure out how to add skeletal animation to the library and open a PR there before adding an example :)

I really appreciate all the help!

StuntHacks commented 4 years ago

Yes, skeletal animation definitely is the better approach. If, back when I made this, I had known how to do it, it would already exist :P The problem right now is that it would need a big restructuring of the m3d::Mesh-class (which would probably be good anyway), since it would then also need to store joints, as well as vertices' relations to them. There are, however, a lot of good resources on skeletal animation out there, and it's definitely not impossible, if you are dedicated to really implementing it.

Eeems commented 4 years ago

@StuntHacks I've got the model loading PR open and another WIP for the toon shading. I wouldn't mind some help with that one as I'm very lost when it comes to PICA200. Some pointers to a good tutorial/language reference or two would be appreciated.

I'll likely work on the skybox next.

Eeems commented 4 years ago

I'm having trouble figuring out how to properly implement toon shading. I've figured out how to load my own shader and bind it, but I'm not able to override the values that Screen is passing to draw(). Thus, it still seems to be using the default render3d.v.pica for calculation. Could you perhaps give me some pointers on what else I should be doing? The only thing I can think of is cloning m3d::Screen and changing the shader.

Eeems commented 4 years ago

image Left is my code, right is the devkitPro toon_shading example.

StuntHacks commented 4 years ago

Hi, sorry for not replying earlier, I just now saw this. In theory, m3d::Screen binds it's own shaders before calling the shading-function, meaning that anything you bind in there should overwrite anything bound by the Screen-class. Could you provide the code inside the shading-function so I can have a look at it?

Eeems commented 4 years ago

Sure, here is what I have currently: https://github.com/Eeems/m3dctr-examples/blob/toon-shading/graphics/3d/toon-shading/source/main.cpp I think I may have some uncommitted changes that I'll push up later.

Eeems commented 4 years ago

It looks like I don't have any uncommitted changes. I likely gave up trying to get it to work and didn't think any of my code was worth keeping.

StuntHacks commented 4 years ago

I am looking into it, although I'm currently rather busy with other stuff, sadly. However, I will definitely come back to this from time to time during the next days, if you still want to do this one. It may be that this is an actual issue with the library itself, in which case I will definitely create a hotfix.