Games that I've shipped, that have sold lots of copies, have had a state machine and used switch
statements to choose the appropriate functionality. While ostensibly less flexible than an "OOP" state machine, it was far easier to work with than the OOP designs I've subsequently been subjected to.
It actually may be appropriate to have only one render function, but that function shouldn't know specifics about what it's doing. It'll have 3D and 2D passes (at least, for a 3D game, since even those often have 2D UI elements), but it doesn't need to know what "mode" the game is in.
The magic happens in the UpdateMainMenu or UpdateGame or UpdateInGameMenu functions, as well as the Start and Stop functions associated with switching states. Choose which with a switch statement on an enum and use it two places, switching states (one switch to stop the old state, one more to start the new one) and updating.
As I write that my alarm bells go off that this is a perfect opportunity to use OOP, but from experience I would advise against that. You don't want to end up in the situation where you have a million little states that are coming and going; you want to constrain it to the major "run modes," and each of those modes should be able to operate on data that tells it what to display. E.g. one state for the entire in-game menu, which "loads" data (usually, "updates its pointer to the data") to indicate what the behavior of the current screen is. There is nothing worse than having a hundred micro classes and not knowing which one triggers when, not to mention the duplicated logic that often arises from such a design (game developers are very bad at reducing duplication through refactoring).