bl_demo_sprites.cpp (8549B)
1 #include <stdlib.h> 2 #include <vector> 3 4 #include "bl_qt_headers.h" 5 #include "bl_qt_canvas.h" 6 7 #include "../bench/images_data.h" 8 9 class MainWindow : public QWidget { 10 Q_OBJECT 11 12 public: 13 QTimer _timer; 14 QSlider _count_slider; 15 QComboBox _renderer_select; 16 QComboBox _comp_op_select; 17 QCheckBox _limit_fps_check; 18 QBLCanvas _canvas; 19 20 BLRandom _random; 21 std::vector<BLPoint> _coords; 22 std::vector<BLPoint> _steps; 23 std::vector<uint32_t> _sprite_ids; 24 25 bool _animate = true; 26 BLCompOp _comp_op = BL_COMP_OP_SRC_OVER; 27 28 BLImage _sprites_blend2d[4]; 29 QImage _sprites_qt[4]; 30 31 enum ShapeType { 32 kShapeRect, 33 kShapeRectPath, 34 kShapeRoundRect, 35 kShapePolyPath, 36 }; 37 38 MainWindow() : _random(0x1234) { 39 QVBoxLayout* vBox = new QVBoxLayout(); 40 vBox->setContentsMargins(0, 0, 0, 0); 41 vBox->setSpacing(0); 42 43 QGridLayout* grid = new QGridLayout(); 44 grid->setContentsMargins(5, 5, 5, 5); 45 grid->setSpacing(5); 46 47 QBLCanvas::init_renderer_select_box(&_renderer_select); 48 _comp_op_select.addItem("SrcOver", QVariant(int(BL_COMP_OP_SRC_OVER))); 49 _comp_op_select.addItem("SrcCopy", QVariant(int(BL_COMP_OP_SRC_COPY))); 50 _comp_op_select.addItem("SrcAtop", QVariant(int(BL_COMP_OP_SRC_ATOP))); 51 _comp_op_select.addItem("DstAtop", QVariant(int(BL_COMP_OP_DST_ATOP))); 52 _comp_op_select.addItem("Xor", QVariant(int(BL_COMP_OP_XOR))); 53 _comp_op_select.addItem("Plus", QVariant(int(BL_COMP_OP_PLUS))); 54 _comp_op_select.addItem("Multiply", QVariant(int(BL_COMP_OP_MULTIPLY))); 55 _comp_op_select.addItem("Screen", QVariant(int(BL_COMP_OP_SCREEN))); 56 _comp_op_select.addItem("Overlay", QVariant(int(BL_COMP_OP_OVERLAY))); 57 _comp_op_select.addItem("Darken", QVariant(int(BL_COMP_OP_DARKEN))); 58 _comp_op_select.addItem("Lighten", QVariant(int(BL_COMP_OP_LIGHTEN))); 59 _comp_op_select.addItem("Color Dodge", QVariant(int(BL_COMP_OP_COLOR_DODGE))); 60 _comp_op_select.addItem("Color Burn", QVariant(int(BL_COMP_OP_COLOR_BURN))); 61 _comp_op_select.addItem("Hard Light", QVariant(int(BL_COMP_OP_HARD_LIGHT))); 62 _comp_op_select.addItem("Soft Light", QVariant(int(BL_COMP_OP_SOFT_LIGHT))); 63 _comp_op_select.addItem("Difference", QVariant(int(BL_COMP_OP_DIFFERENCE))); 64 _comp_op_select.addItem("Exclusion", QVariant(int(BL_COMP_OP_EXCLUSION))); 65 66 _limit_fps_check.setText(QLatin1String("Limit FPS")); 67 68 _count_slider.setOrientation(Qt::Horizontal); 69 _count_slider.setMinimum(1); 70 _count_slider.setMaximum(10000); 71 _count_slider.setSliderPosition(200); 72 73 _canvas.on_render_blend2d = std::bind(&MainWindow::on_render_blend2d, this, std::placeholders::_1); 74 _canvas.on_render_qt = std::bind(&MainWindow::on_render_qt, this, std::placeholders::_1); 75 76 connect(&_renderer_select, SIGNAL(activated(int)), SLOT(onRendererChanged(int))); 77 connect(&_comp_op_select, SIGNAL(activated(int)), SLOT(onCompOpChanged(int))); 78 connect(&_limit_fps_check, SIGNAL(stateChanged(int)), SLOT(onLimitFpsChanged(int))); 79 connect(&_count_slider, SIGNAL(valueChanged(int)), SLOT(onCountChanged(int))); 80 81 grid->addWidget(new QLabel("Renderer:"), 0, 0); 82 grid->addWidget(&_renderer_select, 0, 1); 83 84 grid->addWidget(new QLabel("Comp Op:"), 0, 2); 85 grid->addWidget(&_comp_op_select, 0, 3); 86 87 grid->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding), 0, 4); 88 grid->addWidget(&_limit_fps_check, 0, 5, Qt::AlignRight); 89 90 grid->addWidget(new QLabel("Count:"), 1, 0, 1, 1, Qt::AlignRight); 91 grid->addWidget(&_count_slider, 1, 1, 1, 7); 92 93 vBox->addLayout(grid); 94 vBox->addWidget(&_canvas); 95 setLayout(vBox); 96 97 connect(&_timer, SIGNAL(timeout()), this, SLOT(onTimer())); 98 connect(new QShortcut(QKeySequence(Qt::Key_P), this), SIGNAL(activated()), SLOT(onToggleAnimate())); 99 100 onInit(); 101 } 102 103 void showEvent(QShowEvent* event) override { _timer.start(); } 104 void hideEvent(QHideEvent* event) override { _timer.stop(); } 105 void keyPressEvent(QKeyEvent* event) override {} 106 107 void onInit() { 108 _sprites_blend2d[0].read_from_data(_resource_babelfish_png, sizeof(_resource_babelfish_png)); 109 _sprites_blend2d[1].read_from_data(_resource_ksplash_png , sizeof(_resource_ksplash_png )); 110 _sprites_blend2d[2].read_from_data(_resource_ktip_png , sizeof(_resource_ktip_png )); 111 _sprites_blend2d[3].read_from_data(_resource_firewall_png , sizeof(_resource_firewall_png )); 112 113 for (uint32_t i = 0; i < 4; i++) { 114 const BLImage& sprite = _sprites_blend2d[i]; 115 116 BLImageData sprite_data; 117 sprite.get_data(&sprite_data); 118 119 _sprites_qt[i] = QImage( 120 static_cast<unsigned char*>(sprite_data.pixel_data), 121 sprite_data.size.w, 122 sprite_data.size.h, 123 int(sprite_data.stride), QImage::Format_ARGB32_Premultiplied); 124 } 125 126 setCount(_count_slider.sliderPosition()); 127 _limit_fps_check.setChecked(true); 128 _updateTitle(); 129 } 130 131 double randomSign() noexcept { return _random.next_double() < 0.5 ? 1.0 : -1.0; } 132 133 Q_SLOT void onToggleAnimate() { _animate = !_animate; } 134 Q_SLOT void onRendererChanged(int index) { _canvas.set_renderer_type(_renderer_select.itemData(index).toInt()); } 135 Q_SLOT void onCompOpChanged(int index) { _comp_op = (BLCompOp)_comp_op_select.itemData(index).toInt(); }; 136 Q_SLOT void onLimitFpsChanged(int value) { _timer.setInterval(value ? 1000 / 120 : 0); } 137 Q_SLOT void onCountChanged(int value) { setCount(size_t(value)); } 138 139 Q_SLOT void onTimer() { 140 if (_animate) { 141 double w = _canvas.image_width(); 142 double h = _canvas.image_height(); 143 144 size_t size = _coords.size(); 145 for (size_t i = 0; i < size; i++) { 146 BLPoint& vertex = _coords[i]; 147 BLPoint& step = _steps[i]; 148 149 vertex += step; 150 if (vertex.x < 0 || vertex.x >= w) { 151 vertex.x -= step.x; 152 if (vertex.x < 0) vertex.x = 0; 153 if (vertex.x >= w) vertex.x = w - 1; 154 step.x = -step.x; 155 } 156 157 if (vertex.y < 0 || vertex.y >= h) { 158 vertex.y -= step.y; 159 if (vertex.y < 0) vertex.y = 0; 160 if (vertex.y >= h) vertex.y = h - 1; 161 step.y = -step.y; 162 } 163 } 164 } 165 166 _canvas.update_canvas(true); 167 _updateTitle(); 168 } 169 170 void on_render_blend2d(BLContext& ctx) noexcept { 171 ctx.set_comp_op(BL_COMP_OP_SRC_COPY); 172 ctx.fill_all(bl_background_for_comp_op(_comp_op)); 173 ctx.set_comp_op(_comp_op); 174 175 size_t size = _coords.size(); 176 int rectSize = 128; 177 int halfSize = rectSize / 2; 178 179 for (size_t i = 0; i < size; i++) { 180 int x = int(_coords[i].x) - halfSize; 181 int y = int(_coords[i].y) - halfSize; 182 ctx.blit_image(BLPointI(x, y), _sprites_blend2d[_sprite_ids[i]]); 183 } 184 } 185 186 void on_render_qt(QPainter& ctx) noexcept { 187 ctx.setCompositionMode(QPainter::CompositionMode_Source); 188 ctx.fillRect(0, 0, _canvas.image_width(), _canvas.image_height(), bl_rgba_to_qcolor(bl_background_for_comp_op(_comp_op))); 189 ctx.setRenderHint(QPainter::Antialiasing, true); 190 ctx.setCompositionMode(bl_comp_op_to_qt_composition_mode(_comp_op)); 191 192 size_t size = _coords.size(); 193 int rectSize = 128; 194 int halfSize = rectSize / 2; 195 196 for (size_t i = 0; i < size; i++) { 197 int x = int(_coords[i].x) - halfSize; 198 int y = int(_coords[i].y) - halfSize; 199 ctx.drawImage(QPoint(x, y), _sprites_qt[_sprite_ids[i]]); 200 } 201 } 202 203 void setCount(size_t size) { 204 int w = _canvas.image_width(); 205 int h = _canvas.image_height(); 206 size_t i = _coords.size(); 207 208 if (w < 16) w = 128; 209 if (h < 16) h = 128; 210 211 _coords.resize(size); 212 _steps.resize(size); 213 _sprite_ids.resize(size); 214 215 while (i < size) { 216 _coords[i].reset(_random.next_double() * (w - 1), 217 _random.next_double() * (h - 1)); 218 _steps[i].reset((_random.next_double() * 2 + 1) * randomSign(), 219 (_random.next_double() * 2 + 1) * randomSign()); 220 _sprite_ids[i] = _random.next_uint32() % 4u; 221 i++; 222 } 223 } 224 225 void _updateTitle() { 226 char buf[256]; 227 snprintf(buf, 256, "Sprites [%dx%d] [Count=%zu] [RenderTime=%.2fms FPS=%.1f]", 228 _canvas.image_width(), 229 _canvas.image_height(), 230 _coords.size(), 231 _canvas.average_render_time(), 232 _canvas.fps()); 233 234 QString title = QString::fromUtf8(buf); 235 if (title != windowTitle()) 236 setWindowTitle(title); 237 } 238 }; 239 240 int main(int argc, char *argv[]) { 241 QApplication app(argc, argv); 242 MainWindow win; 243 244 win.setMinimumSize(QSize(400, 320)); 245 win.resize(QSize(580, 520)); 246 win.show(); 247 248 return app.exec(); 249 } 250 251 #include "bl_demo_sprites.moc"