2015-03-16 21:23:59 +03:00
|
|
|
//
|
|
|
|
// Alpha rendering benchmark program for the Fast Light Tool Kit (FLTK).
|
|
|
|
//
|
2022-12-28 18:00:22 +03:00
|
|
|
// Copyright 1998-2022 by Bill Spitzak and others.
|
2015-03-16 21:23:59 +03:00
|
|
|
//
|
|
|
|
// This library is free software. Distribution and use rights are outlined in
|
|
|
|
// the file "COPYING" which should have been included with this file. If this
|
|
|
|
// file is missing or damaged, see the license at:
|
|
|
|
//
|
2020-07-01 19:03:10 +03:00
|
|
|
// https://www.fltk.org/COPYING.php
|
2015-03-16 21:23:59 +03:00
|
|
|
//
|
2020-07-01 19:03:10 +03:00
|
|
|
// Please see the following page on how to report bugs and issues:
|
2015-03-16 21:23:59 +03:00
|
|
|
//
|
2020-07-01 19:03:10 +03:00
|
|
|
// https://www.fltk.org/bugs.php
|
2015-03-16 21:23:59 +03:00
|
|
|
//
|
|
|
|
|
|
|
|
#include <FL/Fl.H>
|
|
|
|
#include <FL/Fl_Double_Window.H>
|
|
|
|
#include <FL/Fl_Button.H>
|
|
|
|
#include <FL/Fl_Image.H>
|
2018-02-01 00:17:17 +03:00
|
|
|
#include <FL/platform.H>
|
2015-03-16 21:23:59 +03:00
|
|
|
#include <FL/fl_draw.H>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2022-12-28 18:00:22 +03:00
|
|
|
// These constants define the image dimensions and
|
|
|
|
// the number of frames of the animation
|
|
|
|
const unsigned int dim = 256;
|
|
|
|
const unsigned int frames = 48;
|
2015-03-16 21:23:59 +03:00
|
|
|
|
2022-12-28 18:00:22 +03:00
|
|
|
static Fl_RGB_Image *img[frames];
|
2015-03-16 21:23:59 +03:00
|
|
|
static uchar curframe;
|
|
|
|
|
|
|
|
static void make_images() {
|
|
|
|
|
|
|
|
unsigned i;
|
2022-12-28 18:00:22 +03:00
|
|
|
for (i = 0; i < frames; i++) {
|
|
|
|
const unsigned size = dim * dim * 4;
|
2015-03-16 21:23:59 +03:00
|
|
|
uchar *data = new uchar[size];
|
|
|
|
|
|
|
|
memset(data, 0, size);
|
|
|
|
|
|
|
|
// First a black box, 10x10 pixels in the top-left corner
|
|
|
|
int x, y;
|
|
|
|
for (x = 0; x < 10; x++) {
|
|
|
|
for (y = 0; y < 10; y++) {
|
2022-12-28 18:00:22 +03:00
|
|
|
data[y * dim * 4 + x * 4 + 3] = 255;
|
2015-03-16 21:23:59 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// A fading sphere
|
|
|
|
uchar alpha = 255;
|
2022-12-28 18:00:22 +03:00
|
|
|
if (i < frames / 2)
|
|
|
|
alpha = uchar(255 * (i / ((float) frames / 2)));
|
2015-03-16 21:23:59 +03:00
|
|
|
else
|
2022-12-28 18:00:22 +03:00
|
|
|
alpha = uchar(255 * (((frames / 2) - (i - frames / 2)) / ((float) frames / 2)));
|
2015-03-16 21:23:59 +03:00
|
|
|
|
|
|
|
const int spherew = 60;
|
2022-12-28 18:00:22 +03:00
|
|
|
const int spherex = (dim - spherew) / 2;
|
2015-03-16 21:23:59 +03:00
|
|
|
const int maxdist = (spherew / 2) * (spherew / 2);
|
|
|
|
for (x = spherex; x < spherex + spherew; x++) {
|
|
|
|
for (y = 20; y < 20 + spherew; y++) {
|
|
|
|
|
|
|
|
float distx = x - (spherex + (float) spherew / 2);
|
|
|
|
float disty = y - (20 + (float) spherew / 2);
|
|
|
|
float dist = distx * distx + disty * disty;
|
|
|
|
|
|
|
|
if (dist > maxdist)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
const float fill = dist / maxdist;
|
2021-08-30 17:51:29 +03:00
|
|
|
const uchar grey = uchar(fill * 255);
|
2015-03-16 21:23:59 +03:00
|
|
|
|
|
|
|
uchar myalpha = alpha;
|
|
|
|
if (fill > 0.9)
|
2021-08-30 17:51:29 +03:00
|
|
|
myalpha *= uchar((1.0f - fill) * 10);
|
2015-03-16 21:23:59 +03:00
|
|
|
|
2022-12-28 18:00:22 +03:00
|
|
|
data[y * dim * 4 + x * 4 + 0] = grey;
|
|
|
|
data[y * dim * 4 + x * 4 + 1] = grey;
|
|
|
|
data[y * dim * 4 + x * 4 + 2] = grey;
|
|
|
|
data[y * dim * 4 + x * 4 + 3] = myalpha;
|
2015-03-16 21:23:59 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// A moving blob
|
2022-12-28 18:00:22 +03:00
|
|
|
const float pos = (i / (float) frames) * 2 - 0.5f;
|
2015-03-16 21:23:59 +03:00
|
|
|
|
2022-12-28 18:24:28 +03:00
|
|
|
const int xoffset = int(pos * dim);
|
|
|
|
const int yoffset = 2 * dim / 3;
|
|
|
|
const int w = dim / 4;
|
2015-03-16 21:23:59 +03:00
|
|
|
|
|
|
|
for (x = -w; x < w; x++) {
|
2022-12-28 18:00:22 +03:00
|
|
|
if (x + xoffset < 0 || x + xoffset >= (int)dim)
|
2015-03-16 21:23:59 +03:00
|
|
|
continue;
|
|
|
|
for (y = yoffset - w; y < yoffset + w; y++) {
|
|
|
|
const uchar grey = abs(y - yoffset);
|
2022-12-28 18:00:22 +03:00
|
|
|
data[y * dim * 4 + (x + xoffset) * 4 + 2] = grey;
|
|
|
|
data[y * dim * 4 + (x + xoffset) * 4 + 3] = 127;
|
2015-03-16 21:23:59 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-28 18:00:22 +03:00
|
|
|
img[i] = new Fl_RGB_Image(data, dim, dim, 4);
|
2015-03-16 21:23:59 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class window: public Fl_Double_Window {
|
|
|
|
public:
|
|
|
|
window(int X, int Y, const char *lbl): Fl_Double_Window(X, Y, lbl) {}
|
|
|
|
|
2022-12-30 21:14:36 +03:00
|
|
|
void draw() FL_OVERRIDE {
|
2015-03-16 21:23:59 +03:00
|
|
|
Fl_Double_Window::draw();
|
|
|
|
|
|
|
|
// Test both cx/cy offset and clipping. Both borders should have a 5-pixel edge,
|
|
|
|
// and the upper-left black box should not be visible.
|
|
|
|
fl_push_clip(5, 5, w() - 5, h() - 5);
|
2022-12-28 18:00:22 +03:00
|
|
|
img[curframe]->draw(0, 0, dim, dim, 5, 5);
|
2015-03-16 21:23:59 +03:00
|
|
|
fl_pop_clip();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static window *win;
|
|
|
|
|
|
|
|
static void cb(void *) {
|
|
|
|
|
|
|
|
win->redraw();
|
|
|
|
|
|
|
|
Fl::repeat_timeout(1.0f / 24, cb);
|
|
|
|
|
|
|
|
curframe++;
|
2022-12-28 18:00:22 +03:00
|
|
|
curframe %= frames;
|
2015-03-16 21:23:59 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
win = new window(256, 256, "Alpha rendering benchmark, watch CPU use");
|
|
|
|
win->color(fl_rgb_color(142, 0, 0));
|
|
|
|
|
|
|
|
make_images();
|
|
|
|
|
|
|
|
win->end();
|
|
|
|
win->show(argc, argv);
|
|
|
|
|
|
|
|
Fl::add_timeout(1.0f / 24, cb);
|
|
|
|
|
|
|
|
return Fl::run();
|
|
|
|
}
|