/** draw a frame, interpolating between 2 "key frames" @param pcnt percentage of interpolation */ void EWCDisplay::_drawFrame(int pcnt) { int nextv; unsigned char h; unsigned char s; unsigned char v; //each row interpolates with the one before it for (unsigned char y = M_HEIGHT - 1; y > 0; y--) { for (unsigned char x = 0; x < M_WIDTH; x++) { h = _hueMask[y][x]; s = 255; nextv = (((100.0 - pcnt) * _matrix[x][y] + _pcnt * _matrix[x][y - 1]) / 100.0) - _valueMask[y][x]; v = (unsigned char)_max(0, nextv); _setPixel(x, y, RgbColor(HsbColor(h, s, v))); } } //first row interpolates with the "next" line for (unsigned char x = 0; x < M_WIDTH; x++) { h = _hueMask[0][x]; s = 255; v = (unsigned char)(((100.0 - _pcnt) * _matrix[x][0] + _pcnt * _line[x]) / 100.0); _setPixel(x, 0, RgbColor(HsbColor(h, s, v))); } }
void Renderer::_computeSections() { QSize imageSize = _image.size(); Ray ray; ray.type = Ray::Primary; while (1) { _renderingTasksMutex.lock(); if (_renderingTasks.isEmpty()) { _renderingTasksMutex.unlock(); return ; } QRect task = _renderingTasks.takeFirst(); _renderingTasksMutex.unlock(); for (int x = 0; x < task.width(); ++x) { for (int y = 0; y < task.height(); ++y) { Color pixel = Color::BLACK; int resolution = config->antialiasingResolution(); float subSize = 1.0f / resolution; Config::AntialiasingType type = config->antialiasingType(); for (float x1 = 0.0f; x1 < 1.0f; x1 += subSize) { for (float y1 = 0.0f; y1 < 1.0f; y1 += subSize) { float vx = 0; float vy = 0; if (type == Config::Random) { vx = float(qrand()) / RAND_MAX; vy = float(qrand()) / RAND_MAX; } else if (type == Config::Uniform) { vx = x1 + subSize / 2.0f; vy = y1 + subSize / 2.0f; } else if (type == Config::Jittered) { vx = x1 + subSize * float(qrand()) / RAND_MAX; vy = y1 + subSize * float(qrand()) / RAND_MAX; } else if (type == Config::Shirley) { float vx1 = x1 + subSize * float(qrand()) / RAND_MAX; float vy1 = y1 + subSize * float(qrand()) / RAND_MAX; vx = (vx1 < 0.5) ? (-0.5f + qSqrt(2.0f * vx1)) : (1.5f - qSqrt(2.0f - 2.0f * vx1)); vy = (vy1 < 0.5) ? (-0.5f + qSqrt(2.0f * vy1)) : (1.5f - qSqrt(2.0f - 2.0f * vy1)); } vx = (vx + x + task.left()) / imageSize.width(); vy = (vy + y + task.top()) / imageSize.height(); Intersection hit; _camera->ray(vx, -vy, ray); ray.time = float(qrand()) / RAND_MAX; _integrator->compute(ray, hit); pixel.AddScaled(hit.shade, 1.0f / (resolution * resolution)); } } _setPixel(x + task.left(), y + task.top(), pixel); } } } }
/** Den Bildschirm-Puffer auf die LED-Matrix schreiben. @param onChange: TRUE, wenn es Aenderungen in dem Bildschirm-Puffer gab, FALSE, wenn es ein Refresh-Aufruf war. */ void LedDriverDotStar::writeScreenBufferToMatrix(word matrix[16], boolean onChange, eColors a_color) { boolean updateWheelColor = false; if (((settings.getColor() == color_rgb_continuous) || (a_color == color_rgb_continuous)) && _transitionCompleted) { if ((millis() - _lastColorUpdate) > 300) { updateWheelColor = true; _lastColorUpdate = millis(); } } if (!_transitionCompleted && (_transitionCounter > 0)) { _transitionCounter--; } else { _transitionCounter = 0; } if (onChange || _dirty || _demoTransition || updateWheelColor || (((_transitionCounter == 0) || (Settings::TRANSITION_MODE_FADE == settings.getTransitionMode())) && !_transitionCompleted)) { uint32_t color = 0; uint32_t colorNew = 0; uint32_t colorOld = 0; uint32_t colorOverlay1 = 0; uint32_t colorOverlay2 = 0; byte brightnessOld = 0; byte brightnessNew = 0; _dirty = false; if (mode != STD_MODE_NORMAL) { _transitionCompleted = true; _demoTransition = false; } /************* MATRIX **************/ if (onChange || _demoTransition) { if (((helperSeconds == 0) || _demoTransition) && (mode == STD_MODE_NORMAL) && _transitionCompleted && !evtActive) { switch (settings.getTransitionMode()) { case Settings::TRANSITION_MODE_FADE: for (byte i = 0; i < 11; i++) { _matrixOld[i] = _matrixNew[i]; if (_demoTransition) { _matrixNew[i] = 0; } else { _matrixNew[i] = matrix[i]; } _matrixOverlay[i] = 0; } _transitionCompleted = false; _transitionCounter = FADINGCOUNTERLOAD; break; case Settings::TRANSITION_MODE_MATRIX: case Settings::TRANSITION_MODE_SLIDE: if (((rtc.getMinutes() % 5) == 0) || _demoTransition) { Transitions::resetTransition(); for (byte i = 0; i < 11; i++) { _matrixOld[i] = 0; _matrixOverlay[i] = 0; } _transitionCompleted = false; } break; case Settings::TRANSITION_MODE_NORMAL: if (_demoTransition) { for (byte i = 0; i < 11; i++) { _matrixNew[i] = 0; } _transitionCompleted = false; _transitionCounter = NORMALCOUNTERLOAD; } break; default: ; } } if (_transitionCompleted) { for (byte i = 0; i < 11; i++) { _matrixOld[i] = 0; _matrixNew[i] = matrix[i]; _matrixOverlay[i] = 0; } } } _demoTransition = false; if ((_transitionCounter == 0) && !_transitionCompleted) { switch (settings.getTransitionMode()) { case Settings::TRANSITION_MODE_MATRIX: _transitionCounter = MATRIXCOUNTERLOAD; _transitionCompleted = Transitions::nextMatrixStep(_matrixOld, _matrixNew, _matrixOverlay, matrix); break; case Settings::TRANSITION_MODE_SLIDE: _transitionCounter = SLIDINGCOUNTERLOAD; _transitionCompleted = Transitions::nextSlideStep(_matrixNew, matrix); break; case Settings::TRANSITION_MODE_NORMAL: _transitionCompleted = true; break; default: ; } } /************* BRIGHTNESS **************/ if ((Settings::TRANSITION_MODE_FADE == settings.getTransitionMode()) && !_transitionCompleted) { brightnessOld = map(_transitionCounter, 0, FADINGCOUNTERLOAD, 0, _brightnessInPercent); brightnessNew = map(_transitionCounter, FADINGCOUNTERLOAD, 0 , 0 , _brightnessInPercent); if (_transitionCounter == 0) { _transitionCompleted = true; } } else { brightnessNew = _brightnessInPercent; } /************* COLOR **************/ if ((a_color != color_none) && (a_color <= color_single_max)) { colorNew = _strip->Color(_brightnessScaleColor(brightnessNew, pgm_read_byte_near(&defaultColors[a_color].red)), _brightnessScaleColor(brightnessNew, pgm_read_byte_near(&defaultColors[a_color].blue)), _brightnessScaleColor(brightnessNew, pgm_read_byte_near(&defaultColors[a_color].green))); } else if ((settings.getColor() == color_rgb_continuous) || (a_color == color_rgb_continuous) ) { if (updateWheelColor) { if (_wheelPos >= 254) { _wheelPos = 0; } else { _wheelPos += 2; } } color = _wheel(_brightnessInPercent, _wheelPos); colorNew = _wheel(brightnessNew, _wheelPos); colorOld = _wheel(brightnessOld, _wheelPos); } else { color = _strip->Color(_brightnessScaleColor(_brightnessInPercent, defaultColors[settings.getColor()].red), _brightnessScaleColor(_brightnessInPercent, defaultColors[settings.getColor()].blue), _brightnessScaleColor(_brightnessInPercent, defaultColors[settings.getColor()].green)); colorNew = _strip->Color(_brightnessScaleColor(brightnessNew, defaultColors[settings.getColor()].red), _brightnessScaleColor(brightnessNew, defaultColors[settings.getColor()].blue), _brightnessScaleColor(brightnessNew, defaultColors[settings.getColor()].green)); colorOld = _strip->Color(_brightnessScaleColor(brightnessOld, defaultColors[settings.getColor()].red), _brightnessScaleColor(brightnessOld, defaultColors[settings.getColor()].blue), _brightnessScaleColor(brightnessOld, defaultColors[settings.getColor()].green)); } if ( (settings.getTransitionMode() == Settings::TRANSITION_MODE_MATRIX) && !_transitionCompleted ) { colorOverlay1 = _strip->Color(_brightnessScaleColor(_brightnessInPercent, 0), _brightnessScaleColor(_brightnessInPercent, 0), _brightnessScaleColor(_brightnessInPercent, 255)); colorOverlay2 = _strip->Color(_brightnessScaleColor(_brightnessInPercent, 0), _brightnessScaleColor(_brightnessInPercent, 0), _brightnessScaleColor(_brightnessInPercent, 255 * 0.5)); colorOld = _strip->Color(_brightnessScaleColor(_brightnessInPercent, 0), _brightnessScaleColor(_brightnessInPercent, 0), _brightnessScaleColor(_brightnessInPercent, 255 * 0.1)); } /************* WRITE OUT **************/ _clear(); for (byte y = 0; y < 10; y++) { for (byte x = 5; x < 16; x++) { word t = 1 << x; if ((settings.getTransitionMode() == Settings::TRANSITION_MODE_FADE) && ((_matrixOld[y] & t) == t) && ((_matrixNew[y] & t) == t) ) { _setPixel(15 - x, y, color); } else { if ((_matrixOverlay[y] & t) == t) { _setPixel(15 - x, y, colorOverlay1); } else if ((_matrixOverlay[y + 1] & t) == t) { _setPixel(15 - x, y, colorOverlay2); } else if ((_matrixOld[y] & t) == t) { _setPixel(15 - x, y, colorOld); } else if ((_matrixNew[y] & t) == t) { _setPixel(15 - x, y, colorNew); } } } } // wir muessen die Eck-LEDs und die Alarm-LED umsetzen... byte cornerLedCount[] = {1, 0, 3, 2, 4}; for ( byte i = 0; i < 5; i++) { if ((settings.getTransitionMode() == Settings::TRANSITION_MODE_FADE) && ((_matrixOld[cornerLedCount[i]] & _matrixNew[cornerLedCount[i]] & 0b0000000000011111) > 0) ) { _setPixel(110 + i, color); } else { if (((_matrixOld[cornerLedCount[i]] & 0b0000000000011111) > 0) ) { _setPixel(110 + i, colorOld); } else if (((_matrixNew[cornerLedCount[i]] & 0b0000000000011111) > 0) ) { _setPixel(110 + i, colorNew); } } } _strip->show(); } }
/** Einen X/Y-koordinierten Pixel in der Matrix setzen. */ void LedDriverDotStar::_setPixel(byte x, byte y, uint32_t c) { _setPixel(x + (y * 11), c); }