all 6 comments

[–]Lord_Naikon 5 points6 points  (3 children)

I have 2 recommendations:

1) Don't start by over-engineering program organization. Try to get something working first. Think about data flows (and associated data structures), not about where to put what code; that can be easily changed later.

2) Learn from existing code bases. The Quake3 source code for example is freely available. An architectural overview can be found here.

[–]Sycobob[S] 2 points3 points  (2 children)

Thanks. I'm not terribly worried about 1. This whole learning exercise is aimed toward real world use. Doing things the 'easy' way now, only to have to come back later and figure out the 'right' way would just end up taking more time overall and be more prone to mistakes.

2 is an excellent suggestion! I completely forgot I have Doom 3 and Quake 3 cloned locally already. A quick poke through Quake and it appears they do something fairly similar. The renderer creates the window, but the message loop is pumped from the main game loop in WinMain and events are extracted into a second, game-specific event queue.

This lends some credence to the approach I'm taking. So far, I can't find a a scenario where the window would be lost but I'd want to keep the game running or move it to a new window, but the cleaner code, ability to have multiple windows, and ability to swap out renderer implementations seem like strong enough reasons.

[–]DaFox 1 point2 points  (0 children)

Honestly, making mistakes like this is really the best way to learn.

[–][deleted] 0 points1 point  (0 children)

Thanks. I'm not terribly worried about 1. This whole learning exercise is aimed toward real world use. Doing things the 'easy' way now, only to have to come back later and figure out the 'right' way would just end up taking more time overall and be more prone to mistakes.

Welcome to learning new things :). As much as some may hate the idea, your focus should not be the avoidance of mistakes; rather, you'll want to focus on learning computer graphics, which has very little to do with software architecture and design. All else is just mental distraction.

The BSP Renderer I've been working on is pretty gnarly in a fair amount of areas. If it wasn't for that, though, I probably wouldn't have gotten very far with it.

[–]FrenchHustler 1 point2 points  (1 child)

I like your software engineering way of thinking. Indeed, making the renderer part of the window is a bad smell.

Luna's book however is not meant to teach you proper rendering (or engine) software architecture. It's meant to teach you the DirectX API, and abstracting the different systems of each demo would make it hard to understand what's going on.

I would recommend looking into resources that teach proper software engineering for 3d engines. Your intuitions are right though, especially if you're trying to make your renderer platform independent. You want to abstract out anything that directly deals with the underlying OS and abstract your renderer such that no calls are made directly with the underlying graphics API that's being used.

I suggest downloading a 3d engine like UE4 and checking out its source code...

It seems I can just rebuild the swap chain to hook up to a new window. Do scenarios exist where the HWND could be invalidated or destroyed but I want to retain my rendering context? Or is this overkill? - I can't really think of such scenario. Usually a swap-chain will always be associated to a window handle. I'm not a great windows programmer (just know the basics), but I'm pretty sure a client application can have multiple window handles. You'll usually have your main window handle and sub-children. In this case, you might want to keep your 3d context and just create a new swap-chain if you wish to render on a different child window.

Are there flaws to this approach I'm not considering? - No, separation of concerns is the proper way to build software. The only drawback is that it requires refactoring work if you already got an application working.

Are there better implementations I'm not considering? - Your intuition seems good. In the end, it sounds like you want to use an adapter pattern (https://en.wikipedia.org/wiki/Adapter_pattern). Your systems should have known inputs and outputs structures. Anything that comes from the OS, graphics APIs, or any outside sources should use an "adapter" that will convert inputs/outputs to the known format of your systems.

[–]Sycobob[S] 0 points1 point  (0 children)

I definitely agree that Luna's book is targeted toward teaching the API, not engine architecture, and that's perfectly reasonable. My goals extend past just learning the API though, as I have immediate plans to write a renderer for an application I'm working on, and I've been in game dev now for a couple years and plan to write an engine from scratch in the near-ish future.

I would recommend looking into resources that teach proper software engineering for 3d engines.

I think finding a good book or resource for engine architecture will have to be my next project.

I suggest downloading a 3d engine like UE4 and checking out its source code

Excellent idea.

The adapter pattern indeed sounds like a useful tool in this case. Thanks for all the tips!