Generate texture for a heightmap

Posted by James on Game Development See other posts from Game Development or by James
Published on 2012-04-20T13:55:44Z Indexed on 2012/09/23 9:50 UTC
Read the original article Hit count: 265

Filed under:
|
|
|

I've recently been trying to blend multiple textures based on the height at different points in a heightmap. However i've been getting poor results. I decided to backtrack and just attempt to recreate one single texture from an SDL_Surface (i'm using SDL) and just send that into opengl. I'll put my code for creating the texture and reading the colour values. It is a 24bit TGA i'm loading, and i've confirmed that the rest of my code works because i was able to send the surfaces pixels directly to my createTextureFromData function and it drew fine.

struct RGBColour
{
    RGBColour() : r(0), g(0), b(0) {}
    RGBColour(unsigned char red, unsigned char green, unsigned char blue) : r(red), g(green), b(blue) {}

    unsigned char r;
    unsigned char g;
    unsigned char b;
};


    // main loading code
SDLSurfaceReader* reader = new SDLSurfaceReader(m_renderer);
reader->readSurface("images/grass.tga");

// new texture
unsigned char* newTexture = new unsigned char[reader->m_surface->w * reader->m_surface->h * 3 * reader->m_surface->w];

for (int y = 0; y < reader->m_surface->h; y++)
{
    for (int x = 0; x < reader->m_surface->w; x += 3)
    {
        int index = (y * reader->m_surface->w) + x;

        RGBColour colour = reader->getColourAt(x, y);

        newTexture[index] = colour.r;
        newTexture[index + 1] = colour.g;
        newTexture[index + 2] = colour.b;
    }
}

unsigned int id = m_renderer->createTextureFromData(newTexture, reader->m_surface->w, reader->m_surface->h, RGB);

    // functions for reading pixels
RGBColour SDLSurfaceReader::getColourAt(int x, int y)
{
    Uint32 pixel;
    Uint8 red, green, blue;
    RGBColour rgb;

    pixel = getPixel(m_surface, x, y);

    SDL_LockSurface(m_surface);

    SDL_GetRGB(pixel, m_surface->format, &red, &green, &blue);

    SDL_UnlockSurface(m_surface);

    rgb.r = red;
    rgb.b = blue;
    rgb.g = green;

    return rgb;
}

    // this function taken from SDL documentation
// http://www.libsdl.org/cgi/docwiki.cgi/Introduction_to_SDL_Video#getpixel
Uint32 SDLSurfaceReader::getPixel(SDL_Surface* surface, int x, int y)
{
    int bpp = m_surface->format->BytesPerPixel;

    Uint8 *p = (Uint8*)m_surface->pixels + y * m_surface->pitch + x * bpp;

    switch (bpp) 
    {
    case 1:
        return *p;
    case 2:
        return *(Uint16*)p;
    case 3:
        if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
            return p[0] << 16 | p[1] << 8 | p[2];
        else
            return p[0] | p[1] << 8 | p[2] << 16;
    case 4:
        return *(Uint32*)p;
    default:
        return 0;
    }
}

I've been stumped at this, and I need help badly! Thanks so much for any advice.

© Game Development or respective owner

Related posts about c++

Related posts about textures