Showing posts with label graphics. Show all posts
Showing posts with label graphics. Show all posts

Wednesday, August 28, 2013

2-D Tiles Renderer - Introduction

I got caught up in the Starbound hype, so I've decided to make a series on creating a 2-D tile-based renderer with procedural textures, normal mapping, pre-multiplied alpha, dynamic light and occlusion.  I guess you could think of it as a fan project.


Being a project of at least moderate size, it's a good idea to plan ahead, and to divide it into a set of smaller projects.  After some deliberation, I came up with the following parts, for a start:

  • Render to multiple layers, combine them, and post-process for gamma-correction and dithering.
  • Texture loader that can call generation procedures when a texture does not exist yet. (Maybe)
  • Texture generation procedures.  They output all seam types and orientations with multiple variants.
  • Tile renderer that uses instancing and hardware buffers.  It probably divides the map into patches.
  • Fast/parallel occlusion checking function.  Output format must match input format, for recursion.  Final output needs to be filterable. (e.g. feathering)
  • Background diorama renderer with parallax and altitude effects.
  • Planetary parameters object that can output the necessary rendering parameters; e.g. lighting and atmospherics.
  • Many more pieces that I'll think of later.
I probably won't finish the whole thing, but, if I end up with something useful, I'll release the source code.

I also intend to make this series of posts informative, but I have failed at that in the past.  I'll try harder this time.

Monday, November 26, 2012

Axonometric Graphics and Status Effects Redesign

After a lot of thought, I have decided that using actors is a better approach to persistent status effects than sticking modifiers onto an actor's statistics and removing them with events in an event queue.

This way one can have complicated effects that change with time, effects that only occur at certain places or under certain circumstances, effects can be the targets of spells and abilities, and it is much easier to add visuals to applied effects.  I feel certain I will find many more uses for this.

I have also grudgingly accepted that my game-play ideas require that the game is three-dimensional, so this weekend I added a third dimension to the map and to the base class for physical actors.  I have decided that "proper" 3-D graphics is still not an option, so I am implementing an axonometric graphics renderer.

Isometric graphics makes use of an isometric projection, which is a special case of an axonometric projection.  In an isometric projection, each three-dimensional axis is assigned a direction on the plane of the two-dimensional projection, the three directions are 120 degrees apart, and the scale of the axes are the same.  This gives a view without perspective, as if the world is seen using only parallel rays, and these rays are all parallel to the vector (1, 1, 1).

In an axonometric projection, the view still has no perspective, but the rays are no longer parallel to (1, 1, 1), but rather to a vector of my choosing.  So the axes' directions are no longer separated by 120 degrees, and are no longer at the same scale.  Calculating the new angles and scales from the rays' direction vector would be a chore, but fortunately one does not need to do that.  As most things in graphics go, getting it to look right is much more practical than making it be right.  Since the axonometric tiles will be drawn by hand and the computer will only assemble them accurate to within a pixel, it is sufficient to draw a cube by hand and use its measurements as the basis for all the rest of the tiles.


Wednesday, October 31, 2012

Useful links and a new perspective

I spent the last year programming lots of stuff, but with very little worth showing:

I got myself up to date with OpenGL 4.
I tried to learn OpenCL.  Will have to try again, though.
I wrote a terrain mesh simplifier, based on ideas from Shamus Young's Terrain Project.
I wrote an emulator for the DCPU-16 from Notch's new game 0x10c.
I designed ROBOL, a new programming language specialized for game AI and robotics.
I worked on a graphics engine based on dual-contouring of voxel data, deferred convex polyhedron volumetric lighting and portals, with gamma-correction, pre-multiplied alpha and dithering.
I wrote a buggy AI for a Tron lightcycles-like game as part of the Entelect R100000 challenge.

The graphics engine would be worth showing, except that I'm trying to implement it in OpenCL, and have thus far failed to really get it started.  Maybe I should try it in pure Java first...  modify the Cyclopean engine...

Meanwhile, I've decided to get away from 3-D graphics for a bit, and get back to simple 2-D sprites.  It's amazing what you can do with 2-D if you're artistic.  And the quality of my recent paintings do imply that I am sufficiently artistic.

Yesterday I had an idea for a project that would be simple enough to produce rapid progress:  A 2-D real-time RPG with a significant amount of modularity.  The modularity is needed so that I can start with a bare-bones game (i.e. rapid visible progress) and then add more ideas with time, until it has enough features.

Overall, I intend to update this blog every Sunday from now on.  I will mostly post about my new RPG: showing off screenshots, explaining design choices, hyping the innovative ideas, etcetera.  When I don't have time to work on the RPG, I will go more in-depth and technical on things that I did in my previous projects.

Hopefully, my new articles will teach others useful new tricks and give them understanding of some interesting algorithms.

Monday, March 21, 2011

Progress and Decisions

The mouse-look is now working entirely correctly.

I have added Newton's first and second laws of motion. I need to handle collision detection before I can add the third law.

To keep things running fast and to make the programming simpler, I will handle free-moving objects as non-rotating 'fuzzy' cylinders. What I mean by 'fuzzy', is that the radius of the cylinder is not constant, but rather depends on the kind of check one is doing. Horizontal checks will use the full radius, but for vertical checks round objects will have a radius of zero. This will allow flat objects to stack, round objects to stand on flat objects, and round objects to form piles. Most objects will be round, but I can definitely see some use for flat objects.

I have not decided how the map itself will be handled yet, because I first have to decide whether I should stick to cubes. I have read up on a technique called 'dual-contouring', which would allow me to use both smooth and angular shapes as I see fit.

Whether or not to use OpenCL is also a big decision to make.

Wednesday, March 2, 2011

Going Faster

I have been working on Cyclopean again.

I have modified the texture loader to be compatible with OpenGL 1.1, and to use direct buffers for sending the texture data to OpenGL. The compatibility issues were caused by my use of GL_UNSIGNED_INT_8_8_8_8_REV as the data type parameter. GL_UNSIGNED_BYTE works just as well, even though the buffer is an IntBuffer.

The process for creating a Vertex Buffer Object from map data now also uses a direct buffer, and I fixed a problem in the calculation of the size of the buffer, so there are no weird gigantic intermittent polygons anymore.

The rendering speed has increased dramatically now that everything is working right, so I am considering using a variant of this renderer for Nation Builder, instead of my shader-heavy normal-mapped high-detail 2-D renderer. The problem with the 2-D renderer is that it will take a lot of time to create good images for all the objects and creatures, and I just don't have the resources for that. Even if I decide to still use the 2-D renderer, I will have to downgrade the images to pixel-art level for practicality and remove the then-no-longer-needed shader programs.

Saturday, November 6, 2010

Got my texture on


Seems the texture wasn't working because the video memory was full. Rebooting cleared it right up. I added a placeholder for the lighting.

Clearly, I need to work on the memory cleanup next.

Friday, November 5, 2010

Many many cubes


Finally got the Cyclopean Engine's renderer fast enough for usage. Now I need to get the texture working.

When I was playing Minecraft the other day, I realized the potential for this kind of engine. It would be a bit stupid if Minecraft and Infiniminer were the only games to ever use it, or if everyone had to write their own. (It is trickier than one would think.) So, I decided to make my own engine, which will be free to use and probably open source (eventually), and my own game with that engine.

The name Cyclopean Engine refers to cyclopean architecture, which is when a building is constructed from huge stone blocks, usually made to fit neatly together. The game will probably be called Cyclopean Adventures, and will have some Lovecraft-style horror in it if I can manage that.

While most of the game world will be strictly Cartesian and/or Euclidean, I programmed it with see-through portals in mind, so it will be possible to have areas linked in impossible ways by invisible portals you might not notice, deviating from Cartesian and Euclidean concepts of space. For instance, a mysterious house might be larger on the inside than the outside, and breaking though a certain wall could lead you to a different universe.

I could even make one side of the portal larger than the other, so that objects can change size when passing through, although building stuff will make even less sense then.

By the way, the zone which is rendered consists of 262144 cubes, but it only renders the possibly-visible surfaces, which is why it is fast. If one were to fill the zone with a checkerboard pattern of translucent cubes, it could become very slow indeed.

Monday, September 27, 2010

Leaving the Home World

Galactic Throne's map generator now generates an empire for the player and automatically centers on Earth, the Human Empire's capital planet.

It also now keeps the empires' knowledge of the galaxy separate from the actual galaxy data, allowing the player and AIs to have incomplete knowledge. We might know a star's color simply because it is visible from Earth, but we need to explore it to determine what kind of planet there is. Some stars will not be visible from Earth, due to astronomical dust clouds for instance, and will need to be discovered with space craft or seen from another planet.

I have switched over to pre-multiplied alpha in the renderer, but the textures are not ready for that, so no screen shot today. I have also made a plan to speed up the renderer. It runs very well on slower graphics cards, while ironically going slow on my very fast PC. I think this happens because it sends a separate polygon batch for each star. I have decided to render everything with little square images and pre-multiplied alpha, so I can send them as a single batch of quads.

Thursday, September 16, 2010

Nation Builder - Now with ramps!


I have made extensive modifications to the texture generator. It can now create images for ramps and also contains multiple procedural shape generators.

Unfortunately, the ramps still look a bit cliff-like. A have some ideas that I can still try out, though.

The generator used to create the 'rock' texture that I use in the image above is based on a variant of the fault-lines method, but adapted to be tiling and three-dimensional.

I also have a 'sand' texture, using the same algorithm, and 'glass' and 'crystaline' textures generated with an algorithm based on Voronoi methods.

The next task is to create a mouse cursor and to allow the user to interact with the terrain. This will allow me to enable the user to designate digging areas and similar orders.

Wednesday, May 26, 2010

It's quiet. Too quiet.

Yes, I haven't posted anything since early April. The reasons are many, but unimportant.

The last few weeks I have been working on a much simpler game, in secret.

I got a big breakthrough in my work on OpenGL GUI components by reading an article or two about premultiplied alpha in textures.

The name 'premultiplied alpha' originally caused me to think 'Why would you want that?' When I discovered what it really meant, it became clear that I was thinking inside the box. Inside this box the name makes sense, but the concept seems useless. Here is the way out of the box:

Premultiplied alpha is actually a method to separate light that an object adds to the image from light removed by that object from the image. For instance, an opaque green object on a red background adds green light and removes the light from behind it, while a green flame would add green light without taking away any, and a transparent black object adds no light but takes away a portion of the background light. So now you can have all of these on the same texture, rendered simultaneously. Before, you would need to render them in separate passes and with different blending modes, easily doubling the amount of processing done.

Some more advantages are that textures with premultiplied alpha work well for stretching/shrinking the texture, for anisotropic filtering, and for DXT compression.

How it works is, the red, green and blue components of the texture only contains the amount of light added by the texture, and the alpha only contains the proportion of the background light to remove. So, for a non-glowing transparent object, it would be exactly like the normal texture, except that the added light is premultiplied by the alpha, and from there the name.

To render my GUI correctly, I no longer need to align the GUI elements' texels to the pixels, and it also does not matter if they stretch a bit, so I could greatly simplify the code. I have working buttons and images now.

I can now also scale in-game objects arbitrarily, and lighting is simpler than ever. I might not even need any shader programs at all this time.

Keyboard setup is working well, but I need to update my text renderer to use premultiplied alpha and fit in with the GUI components before I can make it possible to set it up from within the game.

Monday, March 8, 2010

Hello, world!


The new text renderer is working. I think I need a better font, though. I also need to refine the renderer a bit, to make it easier to use.

Tuesday, March 2, 2010

Qoppa Polli

I wanted to test the text renderer, which is definitely an essential part of the game, so I created a star name generator. The names are supposed to be generic, but when you colonize a planet you will be prompted to rename, and it will make a suggestion based on your species.

There are currently 6142 names that it can generate. Here are some examples:

Noir Coronae
Theta Diplodoci
Ni Terrae
Aqua Vici
Ni Ophidiae
Dio Orientis
Aghan Serpentis
Pansa Veni
Gimel Polli
Omega Gemini
Mu Planae
Kappa Loligo
Disigma Incubi
Kappa Animae
Phagun Angelae
Omega Planae
Aleph Succubae
Omega Genii
Aqua Avis
Psi Cloolu

Most of these will not fool an amateur astronomer, but they are a bit more creative than they would be otherwise. And there are some surprises for the observant and knowledgeable.

The text renderer, however, was not working well. Even after debugging one could hardly read the text. It was using a method by which the computer draws the symbols with polygons. When drawing such thin lines as was required by the smaller font sizes, the rasterizer missed the polygons entirely, leaving out the lines. I will create a bitmap based text renderer for my next attempt, which should work very nicely.

Friday, February 26, 2010

Walls and floors

I was thinking of a way to do ramps and stairways. After a lot of thought I found a way, and, in the process of adding it, I also made it separate the walls and floors properly, and the walls are now more upright.

My next task will be speeding up the renderer. It is going at about 5-7 FPS at 800x600 at the moment, but I think it can go much faster.

I might also experiment with adding ramps.

Monday, February 22, 2010

Texture alignment


Though you might not see much difference, the changes that I made are important during gameplay. All the stone type boundaries were off by a half cube along all three axes.

I had to modify the terrain shader program extensively, and unfortunately doubled the amount of texture memory required. This means that, to run on computers with 64MB texture memory, the application would need to use lower resolution textures. This is not a problem though, since I believe such graphics cards would not support my shader program anyway.

Friday, February 19, 2010

Again with the rocks

I made the texturing work properly. Just look at this beautiful red sandstone.

Afterward, I added the support for multiple rock types. It is not working nearly as well as this screenshot might lead you to believe. I think I should have stuck with red sandstone, rather than this yellow type. Also, the limestone is looking very blue due to the depth cue. I should fix that.

I am still deciding between using natural stone colors, classifying stone colors, or abstract stone colors.

Thursday, February 18, 2010

Stealth ninja stone

I implemented terrain material texturing today, and created some bright orange stone with which to test it.

Rocks that rock

I made the rock more rock-like and irregular, increased the texture detail and experimented with adding color to the rock.

I also experimented with making the rocks less round, but did not meet with success. I will leave this for much later; there are more important things to focus on.

I will either add soil and sand next, or modify it to allow different kinds of rock with different colors and patterns.

Wednesday, February 17, 2010

Depth and clarity

Today I added the depth cue. It makes it easier to see what is behind what and how far behind it is.

I also managed to make the inside of the rocks black.

Tuesday, February 16, 2010

Some visual upgrades

I have made the stone a bit more matte and fixed a bug in the texture generator. The bug was causing some warping, stopping stuff from fitting nicely.

I have been experimenting with different strengths of my current procedural detail-adder, but I think I should try to create a more rock-like procedure.

Procedural detail strength = 0.15:



















Procedural detail strength = 0.5:



















The lower strength gives a clearer image, but the higher strength looks more rocky. I'll be going with 0.15 for now, but I will reevaluate this when I have added some depth cues and created a more rock-like procedure.