Esempio n. 1
0
    void nglInterpolateVertexZ(const VERTEX *from, const VERTEX *to, VERTEX *res)
    {
        GLFix diff = to->z - from->z;
        if(diff < GLFix(1) && diff > GLFix(-1))
            diff = 1;

        GLFix t = (GLFix(CLIP_PLANE) - from->z) / diff;

        res->x = from->x + (to->x - from->x) * t;
        res->y = from->y + (to->y - from->y) * t;
        res->z = CLIP_PLANE;

        #ifdef TEXTURE_SUPPORT
            res->u = from->u + (to->u - from->u) * t;
            res->u = res->u.wholes();
            res->v = from->v + (to->v - from->v) * t;
            res->v = res->v.wholes();
        #endif

        #ifdef INTERPOLATE_COLORS
            RGB c_from = rgbColor(from->c);
            RGB c_to = rgbColor(to->c);

            res->c = colorRGB(c_from.r + (c_to.r - c_from.r) * t, c_from.r + (c_to.r - c_from.r) * t, c_from.r + (c_to.r - c_from.r) * t);
        #else
            res->c = from->c;
        #endif
    }
Esempio n. 2
0
static void interpolateVertexXRight(const VERTEX *from, const VERTEX *to, VERTEX *res)
{
    GLFix diff = to->x - from->x;
    if(diff < GLFix(1) && diff > GLFix(-1))
        diff = 1;

    GLFix end = (SCREEN_WIDTH - 1);
    GLFix t = (end - from->x) / diff;

    res->x = end;
    res->y = from->y + (to->y - from->y) * t;
    res->z = from->z + (to->z - from->z) * t;

#ifdef TEXTURE_SUPPORT
    res->u = from->u + (to->u - from->u) * t;
    res->u = res->u.wholes();
    res->v = from->v + (to->v - from->v) * t;
    res->v = res->v.wholes();
#endif

#ifdef INTERPOLATE_COLORS
    RGB c_from = rgbColor(from->c);
    RGB c_to = rgbColor(to->c);

    res->c = colorRGB(c_from.r + (c_to.r - c_from.r) * t, c_from.r + (c_to.r - c_from.r) * t, c_from.r + (c_to.r - c_from.r) * t);
#else
    res->c = from->c;
#endif
}
Esempio n. 3
0
/****************************************************************************
REMARKS:
Draw the background image for the centering and refresh display
****************************************************************************/
static void drawBackground(void)
{
    char        buf[80];
    int         i,x,y,min,max;
    long        range;
    GA_palette  pal[256],*p;

    min = 32;
    max = 253;
    range = max - min;
    for (i = 0; i < 254; i++) {
        pal[i].Red = 0;
        pal[i].Blue = (((i*range)/254)+min);
        pal[i].Green = 0;
        }
    pal[254].Red = pal[254].Green = pal[254].Blue = 128;
    pal[255].Red = pal[255].Green = pal[255].Blue = 255;
    if (modeInfo.BitsPerPixel > 8) {
        for (i = 0; i < maxY; i++) {
            p = &pal[(i * 254L) / maxY];
            SetForeColor(rgbColor(p->Red,p->Green,p->Blue));
            draw2d.DrawLineInt(0,i,maxX,i,true);
            }
        }
    else {
        driver.SetPaletteData(pal,256,0,false);
        for (i = 0; i < maxY; i++) {
            SetForeColor((i * 254L) / maxY);
            draw2d.DrawLineInt(0,i,maxX,i,true);
            }
        defcolor = 255;
        }
    SetForeColor(defcolor);
    draw2d.DrawLineInt(0,0,maxX,0,true);
    draw2d.DrawLineInt(0,0,0,maxY,true);
    draw2d.DrawLineInt(maxX,0,maxX,maxY,true);
    draw2d.DrawLineInt(0,maxY,maxX,maxY,true);
    draw2d.DrawLineInt(maxX/2,0,maxX/2,maxY,true);
    draw2d.DrawLineInt(0,maxY/2,maxX,maxY/2,true);

    x = maxX/2 - 240;
    y = maxY/2 - 146;
    sprintf(buf,"Video mode: %d x %d %d bits per pixel",maxX+1,maxY+1,modeInfo.BitsPerPixel);
    WriteText(x,y,buf,defcolor);    y += 32;
    WriteText(x,y,"Adjust mode parameters with the following keys:",defcolor); y += 32;
    WriteText(x,y,"      \x1B Move image left",defcolor); y += 16;
    WriteText(x,y,"      \x1A Move image right",defcolor); y += 16;
    WriteText(x,y,"      \x18 Move image up",defcolor); y += 16;
    WriteText(x,y,"      \x19 Move image down",defcolor); y += 16;
    WriteText(x,y,"      + Increase brightness",defcolor); y += 16;
    WriteText(x,y,"      - Decrease brightness",defcolor); y += 16;
    WriteText(x,y,"      r Restore original values",defcolor); y += 16;
    y += 16;
    WriteText(x,y,"Press <Enter> to accept changes, ESC to quit without saving",defcolor);
}
Esempio n. 4
0
//Some textures have a different color in different biomes. We have to make them green. Grey grass just looks so unhealty
static void makeColor(const RGB &color, TEXTURE &texture, const int x, const int y, const int w, const int h)
{
    for(int x1 = x; x1 < w + x; x1++)
        for(int y1 = y; y1 < h + y; y1++)
        {
            RGB grey = rgbColor(texture.bitmap[x1 + y1*texture.width]);
            grey.r *= color.r;
            grey.g *= color.g;
            grey.b *= color.b;
            texture.bitmap[x1 + y1*texture.width] = colorRGB(grey);
        }
}
Esempio n. 5
0
File: ward.cpp Progetto: HapeMask/rt
rgbColor newWard::f(const vec3& wo, const vec3& wi) const{
    if(wo.y*wi.y < 0.f){
        return rgbColor(0.f);
    }

    const vec3 wh = halfVector(wo, wi);

    const float meanX = wh.x / alpha;
    const float meanZ = wh.z / beta;

    return Rs * exp( -(meanX*meanX + meanZ*meanZ) / (wh.y*wh.y)) /
        (4.f * PI * alpha * beta * sqrt(wo.y*wi.y));
}
Esempio n. 6
0
File: ward.cpp Progetto: HapeMask/rt
rgbColor newWard::sampleF(const float& u0, const float& u1, const vec3& wo, vec3& wi, float& pd) const{
    if(wo.y < 0.f) {
        pd = 0.f;
        return rgbColor(0.f);
    }

    const float phi = isIsotropic ? 
        TWOPI * u0 :
        atan2(beta * sin(TWOPI * u0), alpha * cos(TWOPI * u0));

    const float cosPhi = cos(phi);
    const float sinPhi = sin(phi);
    const float theta = isIsotropic ?
        atan(alpha * sqrt(-logf(u1))) :
        atan(
                                    sqrt(-logf(u1) /
                ((cosPhi*cosPhi)/(alpha*alpha) + (sinPhi*sinPhi)/(beta*beta)))
            );

    vec3 wh;
    sphericalToDirection(wh, sin(theta), cos(theta), phi);
    wh = normalize(wh);

    // Find the incident direction that corresponds to this half vector and the
    // reflected direction.
    wi = 2.f * dot(wo, wh) * wh - wo;
    if(wi.y < 0.f){
        pd = 0.f;
        return rgbColor(0.f);
    }

    // For the derivation of this PDF and the fact that it isn't the one
    // computed below, see Bruce Walter's TR from Cornell: PCG-05-06).
    //
    // Lots of cancellation between BRDF and PDF -> simpler calculations.
    pd = sqrt(wi.y*wo.y) / (abs(dot(wh, wo)) * pow(wh.y, 3));
    return Rs;
}
Esempio n. 7
0
rgbColor substrate::sampleF(const float& u0, const float& u1, const vec3& wo, vec3& wi, float& pd) const{
    if(u0 < 0.5f){
        const float u = 2.f * u0;
        cosineSampleHemisphere(wi, u, u1);
    }else{
        const float u = 2.f * (u0 - 0.5f);
        distrib->sampleF(u, u1, wo, wi, pd);

        if(wo.y * wi.y < 0){
            return rgbColor(0.f);
        }
    }

    pd = pdf(wo, wi);
    return f(wo, wi);
}
Esempio n. 8
0
/****************************************************************************
REMARKS:
Draw a simple moire pattern of lines on the display
****************************************************************************/
void DrawMoire(void)
{
    int     i,value;

    if (maxcolor >= 0x7FFFL) {
        for (i = 0; i < maxX; i++) {
            SetForeColor(rgbColor((uchar)((i*255L)/maxX),0,0));
            draw2d.DrawLineInt(maxX/2,maxY/2,i,0,rgbColor((uchar)((i*255L)/maxX),0,0));
            SetForeColor(rgbColor(0,(uchar)((i*255L)/maxX),0));
            draw2d.DrawLineInt(maxX/2,maxY/2,i,maxY,rgbColor(0,(uchar)((i*255L)/maxX),0));
            }
        for (i = 0; i < maxY; i++) {
            value = (int)((i*255L)/maxY);
            SetForeColor(rgbColor((uchar)value,0,(uchar)(255 - value)));
            draw2d.DrawLineInt(maxX/2,maxY/2,0,i,rgbColor((uchar)value,0,(uchar)(255 - value)));
            SetForeColor(rgbColor(0,(uchar)(255 - value),(uchar)value));
            draw2d.DrawLineInt(maxX/2,maxY/2,maxX,i,rgbColor(0,(uchar)(255 - value),(uchar)value));
            }
        }
    else {
        for (i = 0; i < maxX; i += 5) {
            SetForeColor(i % maxcolor);
            draw2d.DrawLineInt(maxX/2,maxY/2,i,0,true);
            SetForeColor((i+1) % maxcolor);
            draw2d.DrawLineInt(maxX/2,maxY/2,i,maxY,true);
            }
        for (i = 0; i < maxY; i += 5) {
            SetForeColor((i+2) % maxcolor);
            draw2d.DrawLineInt(maxX/2,maxY/2,0,i,true);
            SetForeColor((i+3) % maxcolor);
            draw2d.DrawLineInt(maxX/2,maxY/2,maxX,i,true);
            }
        }
    SetForeColor(defcolor);
    draw2d.DrawLineInt(0,0,maxX,0,true);
    draw2d.DrawLineInt(0,0,0,maxY,true);
    draw2d.DrawLineInt(maxX,0,maxX,maxY,true);
    draw2d.DrawLineInt(0,maxY,maxX,maxY,true);
}
Esempio n. 9
0
void Screen::savePng(char * outputFilename) const {
  clock_t startTimer, endTimer;

  printf("Saving file to \"%s\"...", outputFilename);
  fflush(stdout);
  startTimer = clock();

  int pixelCount = height * width;
  std::vector<unsigned char> png;
  for (int i = pixelCount - 1; i >=0; i--) {
    RGBColor rgbColor(pixels[i]);
    png.push_back(rgbColor.r);
    png.push_back(rgbColor.g);
    png.push_back(rgbColor.b);
    png.push_back(255);
  }
  lodepng::encode(outputFilename, png, width, height);

  endTimer = clock();
  printf("completed (%.3f seconds).\n", clockTime(startTimer, endTimer));
}
Esempio n. 10
0
void AP_Win32Dialog_Background::runModal(XAP_Frame * pFrame)
{
	UT_return_if_fail (pFrame);

	const gchar *  pszC = getColor();
	UT_RGBColor rgbColor(255,255,255);
	if(strcmp(pszC,"transparent") != 0)
	{
		UT_parseColor(pszC,rgbColor);
	}


	CHOOSECOLOR cc;                 // common dialog box structure 
	static COLORREF acrCustClr[16]; // array of custom colors 
	DWORD rgbCurrent;				// initial color selection

	rgbCurrent = RGB( rgbColor.m_red, rgbColor.m_grn, rgbColor.m_blu );

	// Initialize CHOOSECOLOR 
	ZeroMemory(&cc, sizeof(CHOOSECOLOR));
	cc.lStructSize = sizeof(CHOOSECOLOR);
	cc.hwndOwner = static_cast<XAP_Win32FrameImpl*>(pFrame->getFrameImpl())->getTopLevelWindow();
	cc.lpCustColors = (LPDWORD) acrCustClr;
	cc.rgbResult = rgbCurrent;
	cc.Flags = CC_RGBINIT |CC_ENABLEHOOK;
	cc.lpfnHook  = &AP_Win32Dialog_Background::s_hookProc;
	cc.lCustData = (LPARAM)this;
 
	if( ChooseColor(&cc) )
	{
		rgbCurrent = cc.rgbResult;

		UT_setColor( rgbColor, GetRValue(rgbCurrent), GetGValue(rgbCurrent), GetBValue(rgbCurrent) );
		setColor( rgbColor );

		setAnswer( a_OK );
	}
	else
		setAnswer( a_CANCEL );
}
Esempio n. 11
0
RgbwColor::RgbwColor(const HsbColor& color)
{
    RgbColor rgbColor(color);
    *this = rgbColor;
}
Esempio n. 12
0
// Function allocates and init a Game
static game_p gameNew(engine_p engine,
                      board_p board)
{
    game_p game = NULL;
    context_p screen = NULL;
    int hd = 0;

    ASSERT(NULL != board, "gameNew");

    game = (game_p)objectCreate(
        sizeof(game_t),
        (destructor_f)gameDestroy);

    game->board = boardRetain(board);

    screen = engineScreen(engine);

    game->width = contextWidth(screen);
    game->height = contextHeight(screen);
    game->padding = (game->width < game->height
                         ? game->width
                         : game->height) / 64;

    hd = engineHDSupported(engine);

    game->regular = fontRetain(
        fontLoad(hd ? fontNameRegularHD
                    : fontNameRegularSD));
    game->bold = fontRetain(fontLoad(
        hd ? fontNameBoldHD : fontNameBoldSD));

    game->status_line
        = MAX(fontLine(game->regular),
              fontLine(game->bold));

    game->images[0] = imageRetain(
        imageLoad(hd ? imageNameEmptyHD
                     : imageNameEmptySD));
    game->images[1] = imageRetain(imageLoad(
        hd ? imageName2HD : imageName2SD));
    game->images[2] = imageRetain(imageLoad(
        hd ? imageName4HD : imageName4SD));
    game->images[3] = imageRetain(imageLoad(
        hd ? imageName8HD : imageName8SD));
    game->images[4] = imageRetain(imageLoad(
        hd ? imageName16HD : imageName16SD));
    game->images[5] = imageRetain(imageLoad(
        hd ? imageName32HD : imageName32SD));
    game->images[6] = imageRetain(imageLoad(
        hd ? imageName64HD : imageName64SD));
    game->images[7] = imageRetain(imageLoad(
        hd ? imageName128HD : imageName128SD));
    game->images[8] = imageRetain(imageLoad(
        hd ? imageName256HD : imageName256SD));
    game->images[9] = imageRetain(imageLoad(
        hd ? imageName512HD : imageName512SD));
    game->images[10] = imageRetain(imageLoad(
        hd ? imageName1024HD : imageName1024SD));
    game->images[11] = imageRetain(imageLoad(
        hd ? imageName2048HD : imageName2048SD));
    game->images[12] = imageRetain(imageLoad(
        hd ? imageName4096HD : imageName4096SD));
    game->images[13] = imageRetain(imageLoad(
        hd ? imageName8192HD : imageName8192SD));
    game->images[14] = imageRetain(
        imageLoad(hd ? imageName16384HD
                     : imageName16384SD));
    game->images[15] = imageRetain(
        imageLoad(hd ? imageName32768HD
                     : imageName32768SD));
    game->images[16] = imageRetain(
        imageLoad(hd ? imageName65536HD
                     : imageName65536SD));
    game->images[17] = imageRetain(
        imageLoad(hd ? imageName131072HD
                     : imageName131072SD));

    game->cell
        = MIN(imageWidth(game->images[0]),
              imageHeight(game->images[0]));

    game->board_back = rgbColor(0xBB, 0xAD, 0xA0);

    return game;
};
Esempio n. 13
0
rgbColor whittedRayTracer::_L(ray& r, const int& depth) const{
    if(depth > MAX_DEPTH){
        return rgbColor(0.f);
    }

    const intersection isect = parent.intersect(r);
    //return rgbColor(0, isect.debugInfo / 1e8, 0);

    if(!isect.hit){
        return rgbColor(0.f);
    }else if(isect.li != NULL){
        return isect.li->L(r);
    }

    material& mat = isect.li ? *isect.li->getMaterial().get() : *isect.s->getMaterial().get();
    const vec3& normal = isect.shadingNormal;
    const bsdf& bsdf = mat.getBsdf(isect.uv);
    const vec3 wo = worldToBsdf(-r.direction, isect);

    bxdfType sampledType;
    rgbColor colorSum(0.f);

    if(isect.s->getMaterial()->isEmissive()){
        return mat.Le();
    }

    // Diffuse calculations.
    float lightPdf = 0.f;
    for(int i=0; i<parent.numLights(); ++i){
        const light& li = parent.getLight(i);
        if(li.isPointSource()){
            vec3 lightDir;
            const rgbColor Li = li.sampleL(r.origin, lightDir, sampleUniform(), sampleUniform(), lightPdf);
            const float lightDist = norm(lightDir);
            lightDir = normalize(lightDir);

            // Test for shadowing early.
            ray shadowRay(r.origin, lightDir);
            shadowRay.tMax = lightDist;
            if(!parent.intersectB(shadowRay)){
                const vec3 wi = worldToBsdf(lightDir, isect);
                const rgbColor f = bsdf.f(wo, wi, bxdfType(DIFFUSE | GLOSSY | REFLECTION)) + mat.Le();
                colorSum += f * dot(normal, lightDir) * (Li / lightPdf);
            }
        }else{
            rgbColor areaContrib(0.f);

            for(int j=0; j<areaSamples; ++j){
                vec3 lightDir;

                const rgbColor Li = li.sampleL(r.origin, lightDir, sampleUniform(), sampleUniform(), lightPdf);

                ray shadowRay(r.origin, normalize(lightDir));
                shadowRay.tMax = norm(lightDir) + EPSILON;

                if(!parent.intersectB(shadowRay) && li.intersect(shadowRay).hit){
                    lightDir = normalize(lightDir);
                    const vec3 wi = worldToBsdf(lightDir, isect);

                    const rgbColor f = bsdf.f(wo, wi, bxdfType(DIFFUSE | GLOSSY | REFLECTION)) + mat.Le();
                    areaContrib += f * dot(normal, lightDir) * (Li / lightPdf);
                }
            }
            colorSum += areaContrib / (float)areaSamples;
        }
    }

    // Trace specular rays.
    vec3 specDir;
    float pdf;
    const rgbColor fr =
        bsdf.sampleF(sampleUniform(), sampleUniform(), sampleUniform(),
                wo, specDir, bxdfType(GLOSSY | SPECULAR | REFLECTION), sampledType, pdf);

    if(!fr.isBlack()){
        specDir = bsdfToWorld(specDir, isect);
        ray r2(r.origin, specDir);
        colorSum += (fr / pdf) * _L(r2, depth+1) * abs(dot(specDir, normal));
    }

    const rgbColor ft =
        bsdf.sampleF(sampleUniform(), sampleUniform(), sampleUniform(),
                wo, specDir, bxdfType(GLOSSY | SPECULAR | TRANSMISSION), sampledType, pdf);

    if(!ft.isBlack()){
        specDir = bsdfToWorld(specDir, isect);
        ray r2(r.origin, specDir);
        colorSum += (ft / pdf) * _L(r2, depth+1) * abs(dot(specDir, normal));
    }

    if(!isFinite(colorSum.avg())) {
        return ERROR_COLOR;
    } else {
        return colorSum;
    }
}
Esempio n. 14
0
void terrainInit(const char *texture_path)
{
    terrain_current = loadTextureFromFile(texture_path);
    if(!terrain_current)
        terrain_current = &terrain; //Use default, included texture
    else
        puts("External texture loaded!");

    int fields_x = 16;
    int fields_y = 16;
    int field_width = terrain_current->width / fields_x;
    int field_height = terrain_current->height / fields_y;

    //Give grass and leaves color
    const RGB green = { 0.5f, 0.8f, 0.3f };
    makeColor(green, *terrain_current, 0, 0, field_width, field_height);
    makeColor(green, *terrain_current, 5 * field_width, 3 * field_height, field_width, field_height);
    makeColor(green, *terrain_current, 4 * field_width, 3 * field_height, field_width, field_height);

    //Also redstone
    drawTexture(*terrain_current, *terrain_current, 4 * field_width, 10 * field_height, field_width, field_height, 4 * field_width, 11 * field_height, field_width, field_height);
    const RGB red = { 0.9f, 0.1f, 0.1f };
    makeColor(red, *terrain_current, 4 * field_width, 11 * field_height, field_width, field_height);

    //And redstone switches
    drawTexture(*terrain_current, *terrain_current, 0 * field_width, 6 * field_height, field_width, field_height, 0 * field_width, 7 * field_height, field_width, field_height);
    const RGB red_tint = { 1.0f, 0.8f, 0.8f };
    makeColor(red_tint, *terrain_current, 0 * field_width, 7 * field_height, field_width, field_height);

    if(terrain_current->width == 256 && terrain_current->height == 256)
        terrain_resized = terrain_current;
    else
        terrain_resized = resizeTexture(*terrain_current, 256, 256);

    for(int y = 0; y < fields_y; y++)
        for(int x = 0; x < fields_x; x++)
        {
            //+1 and -2 to work around GLFix inaccuracies resulting in rounding errors
            TerrainAtlasEntry tea = terrain_atlas[x][y] = {textureArea(x * field_width + 1, y * field_height + 1, field_width - 2, field_height - 2),
                                                            textureArea(x * 16, y * 16, 16, 16) };

            BLOCK_TEXTURE bt = texture_atlas[y][x];
            if(bt.sides == 0)
                continue;

            if(bt.sides & BLOCK_BOTTOM_BIT)
                block_textures[bt.block][BLOCK_BOTTOM] = tea;
            if(bt.sides & BLOCK_TOP_BIT)
                block_textures[bt.block][BLOCK_TOP] = tea;
            if(bt.sides & BLOCK_LEFT_BIT)
                block_textures[bt.block][BLOCK_LEFT] = tea;
            if(bt.sides & BLOCK_RIGHT_BIT)
                block_textures[bt.block][BLOCK_RIGHT] = tea;
            if(bt.sides & BLOCK_FRONT_BIT)
                block_textures[bt.block][BLOCK_FRONT] = tea;
            if(bt.sides & BLOCK_BACK_BIT)
                block_textures[bt.block][BLOCK_BACK] = tea;
        }

    //Slight hack, you can't assign a texture to multiple blocks
    block_textures[BLOCK_GRASS][BLOCK_BOTTOM] = block_textures[BLOCK_DIRT][BLOCK_BOTTOM];

    //Prerender four times the same texture to speed up drawing, see terrain.h
    const BLOCK_TEXTURE quad_textures[] = { ALL(BLOCK_DIRT), SID(BLOCK_GRASS), TOP(BLOCK_GRASS), ALL(BLOCK_STONE), ALL(BLOCK_SAND), SID(BLOCK_WOOD), ALL(BLOCK_PLANKS_NORMAL), ALL(BLOCK_LEAVES) };
    terrain_quad = newTexture(field_width * 2 * (sizeof(quad_textures)/sizeof(*quad_textures)), field_height * 2);

    for(BLOCK b = 0; b <= BLOCK_NORMAL_LAST; b++)
        for(uint8_t s = 0; s <= BLOCK_SIDE_LAST; s++)
            quad_block_textures[b][s].has_quad = false;

    unsigned int x = 0;
    for(BLOCK_TEXTURE bt : quad_textures)
    {
        TextureAtlasEntry *tae = nullptr;

        if(bt.sides & BLOCK_BOTTOM_BIT)
            tae = &block_textures[bt.block][BLOCK_BOTTOM].current;
        if(bt.sides & BLOCK_TOP_BIT)
            tae = &block_textures[bt.block][BLOCK_TOP].current;
        if(bt.sides & BLOCK_LEFT_BIT)
            tae = &block_textures[bt.block][BLOCK_LEFT].current;
        if(bt.sides & BLOCK_RIGHT_BIT)
            tae = &block_textures[bt.block][BLOCK_RIGHT].current;
        if(bt.sides & BLOCK_FRONT_BIT)
            tae = &block_textures[bt.block][BLOCK_FRONT].current;
        if(bt.sides & BLOCK_BACK_BIT)
            tae = &block_textures[bt.block][BLOCK_BACK].current;

        if(!tae)
        {
            printf("Block %d has no texture!\n", bt.block);
            continue;
        }

        //- 1 to reverse the workaround above. Yes, I hate myself for this.
        drawTexture(*terrain_current, *terrain_quad, tae->left - 1, tae->top - 1, field_width, field_height, x, 0, field_width, field_height);
        drawTexture(*terrain_current, *terrain_quad, tae->left - 1, tae->top - 1, field_width, field_height, x + field_width, 0, field_width, field_height);
        drawTexture(*terrain_current, *terrain_quad, tae->left - 1, tae->top - 1, field_width, field_height, x+ field_width, field_height, field_width, field_height);
        drawTexture(*terrain_current, *terrain_quad, tae->left - 1, tae->top - 1, field_width, field_height, x, field_height, field_width, field_height);

        //Get an average color of the block
        RGB sum;
        for(unsigned int tex_x = tae->left - 1; tex_x <= tae->right; ++tex_x)
            for(unsigned int tex_y = tae->top - 1; tex_y <= tae->bottom; ++tex_y)
            {
                RGB rgb = rgbColor(terrain_current->bitmap[tex_x + tex_y*terrain_current->width]);
                sum.r += rgb.r;
                sum.g += rgb.g;
                sum.b += rgb.b;
            }

        int pixels = field_width * field_height;
        sum.r /= pixels;
        sum.g /= pixels;
        sum.b /= pixels;

        const COLOR darker = colorRGB(sum.r / GLFix(1.5f), sum.g / GLFix(1.5f), sum.b / GLFix(1.5f));

        //And add the workaround here again..
        TerrainQuadEntry tqe = { true, textureArea(x + 1, 1, field_width * 2 - 2, field_height * 2 - 2), colorRGB(sum), darker };

        if(bt.sides & BLOCK_BOTTOM_BIT)
            quad_block_textures[bt.block][BLOCK_BOTTOM] = tqe;
        if(bt.sides & BLOCK_TOP_BIT)
            quad_block_textures[bt.block][BLOCK_TOP] = tqe;
        if(bt.sides & BLOCK_LEFT_BIT)
            quad_block_textures[bt.block][BLOCK_LEFT] = tqe;
        if(bt.sides & BLOCK_RIGHT_BIT)
            quad_block_textures[bt.block][BLOCK_RIGHT] = tqe;
        if(bt.sides & BLOCK_FRONT_BIT)
            quad_block_textures[bt.block][BLOCK_FRONT] = tqe;
        if(bt.sides & BLOCK_BACK_BIT)
            quad_block_textures[bt.block][BLOCK_BACK] = tqe;

        x += field_width * 2;
    }

    //Part 2 of the hack above
    quad_block_textures[BLOCK_GRASS][BLOCK_BOTTOM] = quad_block_textures[BLOCK_DIRT][BLOCK_BOTTOM];

    if(lcd_type() == SCR_320x240_4)
    {
        greyscaleTexture(*terrain_current);
        greyscaleTexture(*terrain_resized);
        greyscaleTexture(*terrain_quad);
    }

    //Resize the glass texture to 32x32
    const TextureAtlasEntry &glass_tex = block_textures[BLOCK_GLASS][BLOCK_FRONT].current;
    glass_big = newTexture(32, 32);
    drawTexture(*terrain_current, *glass_big, glass_tex.left - 1, glass_tex.top - 1, field_width, field_height, 0, 0, 32, 32);
}