Showing posts with label coding. Show all posts
Showing posts with label coding. Show all posts

Friday, 17 April 2009

Terrain 2

The algorithm I will implement is based on a restrictive quad tree approach. All this means is that for each node in the tree, each of its directly adjacent neighbours will need to be only one LOD level different. The reason for this is that the index buffers can be computed in advance and simply re-used for the 16 (2^4) different cases. Each of north, east, south and west can either be the same level or one less (if a neighbour is of a higher level then we would be a lower level to it and hence we would join two seams of the same detail - see figure 1).


Figure 1. Paint rocks

In regard to calculating the vertices, I'm thinking it might be a good idea to separate the load across cores (everyone uses multicore now right?). The general idea is to:-

  1. Traverse the tree splitting nodes as usual.
    1. Create child nodes, update neighbour pointers, etc. This may be recursive to keep the quadtree restricted to one LOD difference (note: pain, if not impossible, to parallelise).
    2. Add a pointer to each node that needs its vertices calculated to a list and defer actual calculation until after the tree has been processed.
  2. Simply dispatch calculation jobs to threads, these jobs are independent and nicely parallelisable.
  3. Vertex buffers also need to be created to please direct3d, shouldn't be too hard to squeeze them in somewhere.

Geomorphing is causing me to think, I can't find much on the internet to base my implementation from. I have never done anything to do with vertex interpolation before so this could be a horrible way of doing it. I'm thinking of sending the vertex shader: x, y, z, base_y where base_y is the value of y at the previous LOD level. This can be simply calculated by either taking the value as-is (for when the point coincides with the same point in the last LOD) or interpolating between two values from the last LOD (i.e. where there was an edge on a triangle). It's then just a case of interpolating between base_y and y for each vertex using a per frame shader constant.

Results soon.

Thursday, 16 April 2009

Terrain

In March last year I made a terrain renderer that used noise functions to generate a reasonable looking mountain range. Since then I've learned a lot and I would like to re-visit it but this time take into account:

  • Normal maps
  • Texturing
  • Interpolation between LOD levels
  • Decent lighting
  • Post processing (HDR?)
  • Lots of small optimisations
I would also like to give test driven design (TDD) a chance, and this seems like the perfect place to use it. I had a look at Boost.Test, being boost I trust it to be high quality. It also seems reasonably easy to use.

Here is the old terrain renderer on youtube:

Monday, 9 February 2009

Text rendering

I was looking for a good library for text rendering. Something that would support truetype faces, antialiasing and kerning and be relatively easy to use. I noticed freetype in the credits to Braid (which I really need to play when the PC version appears - the demo is awesome). So after a bit of research, I found it had everything I was looking for and decided to implement it in my renderer.

Most of the time I spent in implementing this was actually writing the parts of the renderer I needed. I used the approach of using freetype to render a string to a texture and then rendering a quad with this texture. However, I feel uneasy about this as it makes the assumption that the strings I'm rendering don't change much (how fast is freetype at rendering?) and that it will probably take up more texture memory than storing individual glyphs as textures. This is something I'd like to investigate more but at the moment don't have the time. Anyway here's something to look at:

Friday, 6 February 2009

Logging

It's often useful to use logging messages or error messages in case something abnormal happens. Or just for fun. A useful trick is to send them straight to the visual studio output window. Using a small amount of code we can even override std::cout and std::cerr which is pretty cool. I'm just going to dive straight into some code:

class logbuf : public std::streambuf
{
public:
    virtual std::streamsize xsputn( const char *s, std::streamsize n )
    {
        // Output to visual studio output window
        OutputDebugStringW(widen(s).c_str());
        return n;
    }
    virtual int overflow(int c = EOF)
    {
        if(c != EOF) OutputDebugString(widen(std::string(1, c)).c_str());
        return 1;
    }
private:
    int indent_;
    char last_;
};
int main(int argc, const char* argv[])
{
    // Create the new stream to redirect cout and cerr output to vs.
    logbuf merr;
    std::ostream out(&merr);

    // Smart class that will swap streambufs and replace them
    // when object goes out of scope.
    class StreamBuf_Swapper
    {
    public:
        StreamBuf_Swapper( std::ostream& orig, std::ostream& replacement )
            : buf_(orig.rdbuf()), str_(orig)
        { orig.rdbuf( replacement.rdbuf() ); }
        ~StreamBuf_Swapper() { str_.rdbuf( buf_ ); }
    private:
        std::streambuf* buf_;
        std::ostream& str_;
    } cerrswap(std::cerr, out), coutswap(std::cout, out);

    try
    {
        // ... Lots of code
    }
    catch( const std::exception& e )
    {
        std::cerr << e.what();
    }

    return 0;
}

This code takes the streambuf associated with cout and cerr and simply swaps it with a streambuf derived class (vsstream) that prints anything to the visual studio output window. Simple and useful. One other thing to note is that if the output window contains a line formatted:

<filename>(<line number>) : <message>

then it will automatically display that file and line in the editor when double clicked. A few more things you could do with it would be to log errors to a file as well or maybe have something differentiate between normal log messages and error messages (in fact, I'll probably have to do this at some point).

Monday, 19 January 2009

Plans

This journal (I hate the word blog) is going to be a place for me to organise my thoughts. I intend to list projects I'd like to do and follow them through development with regular posts showing the problems I encounter. I hope maybe it can be of use to others as well, but that is not my primary motive. Anyway, if you're actually reading this I must have done something right.

The list of projects I'd like to complete:

  • Collada loader
  • Decent text rendering
  • Screen space ambient occlusion (SSAO)
  • A simple memory allocation tracker
  • Light perspective shadow maps
  • Self-shadowed normal mapping
  • Rain on glass shader
  • Efficient perlin noise generated terrain with dynamic LOD
  • Sky dome with vertex shader to interpolate given colours
    • Real time modification of shader inputs

Also my loan came through last night so I went on a shopping spree. I ended up buying:

I'll try and do a brief review of them when I'm done reading.