Game Dev the hard way

So I've been toying with some game dev too but rather than just using unity like a sensible person I decided to write my own engine in C++ using opengl3

What i've got is not quite a game more a collection of systems and parts I'm still playing with. I'm not flying completely blind in that there are some excellent tutorials online for this sort of thing and the original design of this was based heavily on a series of lwjgl tutorials by a chap called ThinMatrix on youtube but that's java so I've had to make quite a lot of changes and figure out various changes needed to make things work. Plus I've added a load of my own ideas on top of that like using xml for a lot of the object parameters and things like the gui.

It's mostly crappy programmer art I botched together and a few things that I swiped. It currently supports things like normal maps but mostly I've not added any it even has code for parallax maps but there are none of that. It does do specular maps which most of the items have one in there. The terrain is generated using a height map and then has a texture blending system to determine grass vs path vs dirt etc. It's using three types of lights run in the shaders one directional ambient light (eg a sun) then point lights and spot lights it runs multiple lights the 10 most nearest spot and point lights get loaded into the shaders to calculate the lighting on top of the directional one. It also has distance fog but not any culling as yet. There is a simple particle system.

I was sort of playing with a minecraft/factorio sort of game so I have minerals you can see coal, copper ore, iron ore, and trees for wood. The engine uses texture map to determine where the resources should show up. You can see I've got it harvesting stuff by the bar filling up and the stuff appears in the inventory.

I've done some buildings like chests which you can drag and drop things into furnaces that can take ore and fuel then turn it into metal the recipies for that are stored in the XML. I also started on a factory that can make other buildings but it's a bit buggy. Buildings it also have a series of state machines that can be defined in the XML that allows for lights or particle systems to react to the building state. You can see this in the furnace as it turns on with a flickering light and particle system when it fires up.

You can already place buildings and other buildable objects into the world it indicates where you can and can't place stuff based on the colour of the thing.

I've also toyed with a few other things like a turret that currently just spins, a sort of moving truck thing that runs a simple fake assembly language to allow it to be configured in the game but I've not put an interface in there to change it yet. Also just added some enemies with some very simple AI they randomly wander about until they see the player and then follow you around unless they loose sight of you then they go back to randomly moving.

I've just got skeletal animation working using collada files (sort of I can import files but the ones I generate come out a bit odd) it took ages to figure out how to get it to work even with a few tutorials I found and it's still a work in progress.

Up until now it's mostly been about making the engine nuts and bolts working loading models rendering them getting them animated working with opengl but it's getting more to the point that I can try out more game ideas. Theres still a lot of graphics and utility stuff I could work on the text rendering is an old system that has to be seperate from the gui so it always goes over the top of things I really want to fix that, things like shadows water post processing effects things like a skybox reflections view frustum culling and so on. It's also the way of things that I'm tempted to stop working on this version and redo since I can see a load of ways to improve things. We'll see where it goes from here.

Comments

Legend!

I appreciate the huge amount of effort and complexity than went into this. That's seriously impressive. Also really pleased to have a game dev buddy; even if you're chosen the hardest way imaginable.

Is the landmass one big texture map or have you painted the textures in layers? Looks like there is collision detection, is that inside OpenGL or did you have to write that too?

Do you have a "finished" state in mind? How are you keeping your code? Is there a download anywhere?

brainwipe's picture

The land mass is basically three seperate textures (grass, grass with flowers, and the path like texture) all combined using a blend map with the magic happening inside the fragment shader basically sampling the blend map then assigning the texture based on the value. You could obviously bake that out but this way there is the possibility of changing the textures on the fly or swapping them out etc.

There isn't any collision detection and Opengl doesn't have any inbuilt mechanism to handle that opengl basically just makes polygons maps textures and pushes pixels to the screen just graphics and nothing else any other part has to be done yourself.

Are you talking about the green spheres that show up? That sort of is collision detection but it's for the ray hit detect for mouse picking working out if a ray hits a sphere is actually fairly easy so that's what I've been using.

I might add something like bullet physics which would include collision detection as a side benefit as well as full physics simulation. Ive put it in things like this before and it's fairly easy to work with saves having to write a complex physics simulator from scratch.

Not really sure of an end point at this stage I thing I might just toy with making something simple as I've never really made a complete game just parts and I think I would learn a lot about how to put it all together levels menus gameplay etc. Maybe a diablo or roguelike sort of thing.

The code is on bitbucket in a private repo it's a bit of a mess the ide I was (codelite) using nicely organsises things with virtual folders so I see it all organised in seperate folders the reality is all files dumped in one folder :S also the code in those files is not neat :S

I think I can invite a few people to view the thing I'm just using the free account which has up to 5 users I think so I can invite you to take a look at the horrors that lurk. Use a bunch of helper libraries for the matrix math glm and it's cohorts.

Evilmatt's picture

Thanks for code access. I'll take a look when I get a chance. I'm so impressed with your game and I completely understand the need to have a creative toy to play with.

I thought there was collision detection because the mobs weren't clipping inside the player.

One thing I have found really useful is getting others to play with it. Kate and Felix have both had a go; which is why I haven't pressed you fellows for your time ... yet. Felix in particular is very good at telling me what I should do next or what is a bit rubbish. Brutal but useful. Kate is useful because she shows me where the "vernacular of modern games" isn't obvious and what sort of a tutorial I should write. Please get an exe uploaded, I'm keen to have a play!

brainwipe's picture

I put an exe in there or at least allowed git to store it since I'd been rejecting all the places it could store intermediate or linker object files which tend to be large and are of no use to anyone unless you are really working some esoteric gdb stuff and in this instance where you can just generate them from the code they just eat up huge amounts of space for no gain.

Probably needs the paths for the res and the exe to be right but if you clone it should put it in roughly the right form. I realised the shaders are in amongst the source files when they should probably be in the res directory something to maybe fix.

Been tweaking a few things so there's some unfinished stuff to do water which just renders the stuff again in a smaller texture.

Also added a simple skybox and daynight cycle here's a clip before I started breaking things again

Evilmatt's picture

WOW! Love the day/night cycle! Clever stuff. Are you going to fade colours too?

brainwipe's picture

probably the fog colour is a uniform so I can change it making it fade through a set of colours more matching the day or night would make the effect work better.

Evilmatt's picture

Added water tiles

Evilmatt's picture

Bump map with reflection, nice! Will you be making any interaction (ripples) with entities that touch the water?

brainwipe's picture

possibly maybe some sort texture I render to as models enter the water to generate the ripples or some such.

Did some shadows

Some bugs still lurking in the frustum calculations I think or possible the directional light is able to come from beneath the world and causing some errors or weird effects.

Evilmatt's picture

How many FPS is that? The YouTube vid looks a touch jerky.

brainwipe's picture

hmmm I thought it might be debug running but doesn't look that jerky in real life maybe some sort of encoder issue

Evilmatt's picture

did a bit more work on the shadows now filtering is there and some self shadowing. Still some sort of bug in the shadowbox where the rotation is out of phase somehow so that it's facing the wrong way at 90 and -90 not been able to find that yet. Doesn't generate shadows for the animated objects as they are more complex to render so need a different vertex shader to support those.

Evilmatt's picture

Very look. I like that it's some kind of post-apocalyptic hug-fest while you're trying to test!

brainwipe's picture

fixed a few issues with the shadow maps so they rotate correctly still getting an odd artifact at certain angles where it shadows everything not sure why that is yet. Extended the code to allow for shadows and selfshadowing of animated entities.

Evilmatt's picture

added some code to do post processing of the image currently just a bit of test code where it renders to a texture then ups the contrast before rendering to the screen but shows the underpinning steps are working. You can also see the shadow bug towards the end where it just covers the ground in shadow at certain angles.

Evilmatt's picture

Your progress is pretty rapid! Impressive stuff. Do you have a goal that you're aiming for? When will you know that you're done?

brainwipe's picture

I was thinking about switching from the current rendering method to using a gbuffer (rendering the data diffuse normals specular etc out to various buffers then combining them later) but to do that there are a lot of extra pieces that need to be in place before it can work. Getting the ability to render to framebuffers is the first step in that direction which is what I'm doing for this postprocessing effects.

Evilmatt's picture

In Unity, they suggest pre-rendering ambient occlusion maps and then applying them as a texture. Are you going to make those in the gbuffer? For a shadow that doesn't really change (it's ambient), it kind of makes sense to have it as a texture map.

It's the first time that I've considered moving off lightwave because occlusion maps is something Blender does really well.

brainwipe's picture

So the main reason to move to gbuffer is more dynamic lights (a technique called deferred lighting). Traditional forward rendering you have to upload to the shader all the lights you want and process the dynamic lighting for each light for each piece of geometry. The more lights you have the more you need to upload the more processing the shader has to do and the slower things run the amount of calculations is an order of geometry * number of lights. Typically with this method you don't want more than a few tens of lights. You can limit this to just lights near the player but you still tend to get that lights switching on and off with distance.

A gbuffer separates out the rendering such that for each scene you render different properties to a set of buffers, typically you would do one diffuse colour pass one normal pass one specular pass one shadow pass one depth pass then combine these later to generate your final scene. For efficiency you try and pack as much information into a single render pass as possible so often you use different colour channels for different information.

For the lights you have a simple model scaled to the size and shape of the light type basically the light volume and then you render those with their own shader programs. Since the models encompass the area of the light in question they trigger fragment shader execution on only the pixels in the scene that they are effecting. We can then use the information in the various passes to calculate the lighting on those pixels

It reduces the number of calls from a geometery * num lights scale to a number of pixels * number of lights scale and we can have hundreds of lights.

Evilmatt's picture

Couple of minor additions
Gaussian blur post processing effect

AA with multisampled FBO's

Evilmatt's picture

From the gaussian blur effect progressed to a simple bloom/glow effect

Evilmatt's picture

added code to do multiple render targets so the glow is now a separate render target using the glow maps so only objects with glow maps get rendered to that target. Sky also glows but might change that.

Evilmatt's picture

Sky looks very glowy indeed! Great work, EMW. Love it.

One of the things I need to sort out with mine is occlusion shading on the join between different objects. That's where you have one object resting on another. I can't bake the occlusion map for that because the ground is procedurally generated. How would you do it in yours?

brainwipe's picture

You mean terrain self shadowing?

You could probably calculate something similar to the way shadows are genreated by using a depth pass rendered from the light source fustrum using the terrain data then Projective texture map that onto the terrain for some terrain self shadow.

Or if you could replicate the height map maybe you could simulte something based on the light direction since the terrain while procedural is static and it's a fixed light position. You would just need to calculate some sort of shadow map when generating the terrain.

Evilmatt's picture

Sort of terrain self-shadow. I think my actual problem right now is that the sun isn't casting any bloody shadows at all! I need to go back through my releases and work out at which point they disappeared. Once it's casting against, I am sure shadows will be cast where two objects meet.

brainwipe's picture

I remember there being options to set things as either casting shadows or receiving shadows so either the directional light isn't casting shadows or the object isn't receiving them or perhaps both :D

Evilmatt's picture