void RasterRenderer::GenerateUnshadedImage(bool is_terrain, unsigned height_scale) { const int min_height = is_terrain ? min(1000, (int)height_matrix.get_minimum()) : 0; const int height_factor = is_terrain ? max(2000, (int)height_matrix.get_maximum()) - min_height : 0; const short *src = height_matrix.GetData(); const BGRColor *oColorBuf = color_table + 64 * 256; BGRColor *dest = image->GetTopRow(); for (unsigned y = height_matrix.get_height(); y > 0; --y) { BGRColor *p = dest; dest = image->GetNextRow(dest); for (unsigned x = height_matrix.get_width(); x > 0; --x) { short h = *src++; if (gcc_likely(!RasterBuffer::is_special(h))) { h = height_factor > 0 ? (h - min_height) * 254 / height_factor : min(254, h >> height_scale); *p++ = oColorBuf[h]; } else if (!RasterBuffer::is_water(h)) { // we're in the water, so look up the color for water *p++ = oColorBuf[255]; } else { /* outside the terrain file bounds: white background */ *p++ = BGRColor(0xff, 0xff, 0xff); } }
void RasterRenderer::GenerateUnshadedImage(unsigned height_scale) { const short *src = height_matrix.GetData(); const BGRColor *oColorBuf = color_table + 64 * 256; BGRColor *dest = image->GetTopRow(); for (unsigned y = height_matrix.GetHeight(); y > 0; --y) { BGRColor *p = dest; dest = image->GetNextRow(dest); for (unsigned x = height_matrix.GetWidth(); x > 0; --x) { short h = *src++; if (gcc_likely(!RasterBuffer::IsSpecial(h))) { if (h < 0) h = 0; h = min(254, h >> height_scale); *p++ = oColorBuf[h]; } else if (RasterBuffer::IsWater(h)) { // we're in the water, so look up the color for water *p++ = oColorBuf[255]; } else { /* outside the terrain file bounds: white background */ *p++ = BGRColor(0xff, 0xff, 0xff); } } }
///////////////////////////////////////////////////////////////////////////// // CSTScreenBuffer CSTScreenBuffer::CSTScreenBuffer(int nWidth, int nHeight) : RawBitmap(nWidth, nHeight) { #ifdef USE_TERRAIN_BLUR m_pBufferTmp = (BGRColor*)malloc(sizeof(BGRColor)*GetHeight()*GetCorrectedWidth()); if(!m_pBufferTmp) { throw std::bad_alloc(); } #endif std::fill_n(GetBuffer(), GetHeight()*GetCorrectedWidth(), BGRColor(255, 255, 255)); }
RawBitmap::RawBitmap(unsigned nWidth, unsigned nHeight, const Color clr) :width(nWidth), height(nHeight), corrected_width(CorrectedWidth(nWidth)) { assert(nWidth > 0); assert(nHeight > 0); #ifdef ENABLE_SDL Uint32 rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; #else rmask = 0x00ff0000; gmask = 0x0000ff00; bmask = 0x000000ff; #endif amask = 0x00000000; surface = ::SDL_CreateRGBSurface(SDL_SWSURFACE, corrected_width, height, 24, rmask, gmask, bmask, amask); assert(!SDL_MUSTLOCK(surface)); buffer = (BGRColor *)surface->pixels; #else /* !ENABLE_SDL */ bi.bmiHeader.biSize = sizeof(bi.bmiHeader); bi.bmiHeader.biWidth = corrected_width; bi.bmiHeader.biHeight = height; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 24; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = 0; bi.bmiHeader.biXPelsPerMeter = 3780; bi.bmiHeader.biYPelsPerMeter = 3780; bi.bmiHeader.biClrUsed = 0; bi.bmiHeader.biClrImportant = 0; #if defined(_WIN32_WCE) && _WIN32_WCE < 0x0400 /* StretchDIBits() is bugged on PPC2002, workaround follows */ VOID *pvBits; HDC hDC = ::GetDC(NULL); bitmap = CreateDIBSection(hDC, &bi, DIB_RGB_COLORS, &pvBits, NULL, 0); ::ReleaseDC(NULL, hDC); buffer = (BGRColor *)pvBits; #else buffer = new BGRColor[corrected_width * height]; #endif #endif /* !ENABLE_SDL */ std::fill(buffer, buffer + corrected_width * height, BGRColor(clr.blue(), clr.green(), clr.red())); }
/** * Shade the given color according to the illumination value. * * illum = 64: Contour, mixed with 50% brown * illum < 0: Shadow, mixed with up to 50% dark blue * illum > 0: Highlight, mixed with up to 25% yellow * illum = 0: No shading */ gcc_const inline BGRColor TerrainShading(const int illum, RGB8Color color) { if (illum == -64) { // brown color mixed in for contours return BGRColor(MIX(100, color.Red(), 64), MIX(70, color.Green(), 64), MIX(26, color.Blue(), 64)); } else if (illum < 0) { // shadow to blue int x = std::min(63, -illum); return BGRColor(MIX(0, color.Red(), x), MIX(0, color.Green(), x), MIX(64, color.Blue(), x)); } else if (illum > 0) { // highlight to yellow int x = std::min(32, illum / 2); return BGRColor(MIX(255, color.Red(), x), MIX(255, color.Green(), x), MIX(16, color.Blue(), x)); } else return BGRColor(color.Red(), color.Green(), color.Blue()); }
void CSTScreenBuffer::VerticalBlur(unsigned int boxh, BGRColor* src, BGRColor* dst) { BGRColor *c, *d, *e; const unsigned int muli = (boxh * 2 + 1); const unsigned int iboxh = GetCorrectedWidth() * boxh; const unsigned int off1 = iboxh + GetCorrectedWidth(); const unsigned int off2 = GetHeight() - boxh - 1; const unsigned int bottom = GetHeight() - boxh; for (unsigned int x = GetCorrectedWidth(); --x;) { unsigned int tot_r = 0; unsigned int tot_g = 0; unsigned int tot_b = 0; unsigned int y; c = d = src + x; e = dst + x; for (y = boxh; y--; c += GetCorrectedWidth()) { tot_r += c->value.Red(); tot_g += c->value.Green(); tot_b += c->value.Blue(); } for (y = 0; y < GetHeight(); ++y) { unsigned int acc = muli; if (y > boxh) { c = d - off1; tot_r -= c->value.Red(); tot_g -= c->value.Green(); tot_b -= c->value.Blue(); } else { acc += y - boxh; } if (y < bottom) { c = d + iboxh; tot_r += c->value.Red(); tot_g += c->value.Green(); tot_b += c->value.Blue(); } else { acc += off2 - y; } (*e) = BGRColor((uint8_t) (tot_r / acc),(uint8_t) (tot_g / acc), (uint8_t) (tot_b / acc)); d += GetCorrectedWidth(); e += GetCorrectedWidth(); } } }
void CSTScreenBuffer::HorizontalBlur(unsigned int boxw, BGRColor* src, BGRColor* dst) { const unsigned int muli = (boxw * 2 + 1); BGRColor *c; const unsigned int off1 = boxw + 1; const unsigned int off2 = GetCorrectedWidth() - boxw - 1; const unsigned int right = GetCorrectedWidth() - boxw; for (unsigned int y = GetHeight(); y--;) { unsigned int tot_r = 0; unsigned int tot_g = 0; unsigned int tot_b = 0; unsigned int x; c = src + boxw - 1; for (x = boxw; x--; --c) { tot_r += c->value.Red(); tot_g += c->value.Green(); tot_b += c->value.Blue(); } for (x = 0; x < GetCorrectedWidth(); ++x) { unsigned int acc = muli; if (x > boxw) { c = src - off1; tot_r -= c->value.Red(); tot_g -= c->value.Green(); tot_b -= c->value.Blue(); } else { acc += x - boxw; } if (x < right) { c = src + boxw; tot_r += c->value.Red(); tot_g += c->value.Green(); tot_b += c->value.Blue(); } else { acc += off2 - x; } (*dst) = BGRColor((uint8_t) (tot_r / acc),(uint8_t) (tot_g / acc), (uint8_t) (tot_b / acc)); src++; dst++; } } }
void RasterRenderer::GenerateUnshadedImage(unsigned height_scale, const unsigned contour_height_scale) { const short *src = height_matrix.GetData(); const BGRColor *oColorBuf = color_table + 64 * 256; BGRColor *dest = image->GetTopRow(); for (unsigned y = height_matrix.GetHeight(); y > 0; --y) { BGRColor *p = dest; dest = image->GetNextRow(dest); unsigned contour_row_base = ContourInterval(*src, contour_height_scale); unsigned char *contour_this_column_base = contour_column_base; for (unsigned x = height_matrix.GetWidth(); x > 0; --x) { int h = *src++; if (gcc_likely(!RasterBuffer::IsSpecial(h))) { if (h < 0) h = 0; const unsigned contour_interval = ContourInterval(h, contour_height_scale); h = std::min(254, h >> height_scale); if (gcc_unlikely((contour_interval != contour_row_base) || (contour_interval != *contour_this_column_base))) { *p++ = oColorBuf[h-64*256]; *contour_this_column_base = contour_row_base = contour_interval; } else { *p++ = oColorBuf[h]; } } else if (RasterBuffer::IsWater(h)) { // we're in the water, so look up the color for water *p++ = oColorBuf[255]; } else { /* outside the terrain file bounds: white background */ *p++ = BGRColor(0xff, 0xff, 0xff); } contour_this_column_base++; } }
void CSTScreenBuffer::Create(int nWidth, int nHeight, COLORREF clr) { LKASSERT(nWidth>0); LKASSERT(nHeight>0); CreateBitmap(nWidth, nHeight); BGRColor bgrColor = BGRColor(GetBValue(clr), GetGValue(clr), GetRValue(clr)); int nPosition = 0; for (int y=0; y<nHeight; y++) { nPosition = m_nCorrectedWidth*y; for (int x=0; x<nWidth; x++) { m_pBuffer[nPosition] = bgrColor; nPosition++; } } }
void CSTScreenBuffer::Create(int nWidth, int nHeight, const Color clr) { assert(nWidth>0); assert(nHeight>0); CreateBitmap(nWidth, nHeight); BGRColor bgrColor = BGRColor(clr.blue(), clr.green(), clr.red()); int nPosition = 0; for (int y=0; y<nHeight; y++) { nPosition = m_nCorrectedWidth*y; for (int x=0; x<nWidth; x++) { m_pBuffer[nPosition] = bgrColor; nPosition++; } } }