paysages3d/src/render/software/CanvasPreview.cpp

141 lines
2.5 KiB
C++
Raw Normal View History

2014-06-10 13:13:16 +00:00
#include "CanvasPreview.h"
2014-06-12 15:45:59 +00:00
#include "Color.h"
#include "CanvasLiveClient.h"
#include "Mutex.h"
#include "ColorProfile.h"
2014-06-12 15:45:59 +00:00
#include <cassert>
2014-06-10 13:13:16 +00:00
CanvasPreview::CanvasPreview()
{
width = 1;
height = 1;
2014-06-12 15:45:59 +00:00
pixels = new Color[1];
dirty_left = 1;
dirty_right = -1;
dirty_down = 1;
dirty_up = -1;
lock = new Mutex();
profile = new ColorProfile();
2014-06-10 13:13:16 +00:00
}
CanvasPreview::~CanvasPreview()
{
delete [] pixels;
2014-06-12 15:45:59 +00:00
delete lock;
delete profile;
2014-06-10 13:13:16 +00:00
}
void CanvasPreview::setSize(int real_width, int real_height, int preview_width, int preview_height)
{
2014-06-12 15:45:59 +00:00
lock->acquire();
2014-06-10 13:13:16 +00:00
delete [] pixels;
2014-06-12 15:45:59 +00:00
pixels = new Color[preview_width * preview_height];
2014-06-10 13:13:16 +00:00
width = preview_width;
height = preview_height;
2014-06-12 15:45:59 +00:00
dirty_left = width;
dirty_right = -1;
dirty_down = height;
dirty_up = -1;
lock->release();
reset();
}
void CanvasPreview::reset()
{
lock->acquire();
int n = width * height;
for (int i = 0; i < n; i++)
{
pixels[i] = COLOR_BLACK;
}
lock->release();
}
void CanvasPreview::initLive(CanvasLiveClient *client)
{
client->canvasResized(width, height);
client->canvasCleared(COLOR_BLACK);
setAllDirty();
}
void CanvasPreview::updateLive(CanvasLiveClient *client)
{
int x, y;
lock->acquire();
for (y = dirty_down; y <= dirty_up; y++)
{
for (x = dirty_left; x <= dirty_right; x++)
{
client->canvasPainted(x, y, profile->apply(pixels[y * width + x]));
2014-06-12 15:45:59 +00:00
}
}
dirty_left = width;
dirty_right = -1;
dirty_down = height;
dirty_up = -1;
lock->release();
}
void CanvasPreview::pushPixel(int real_x, int real_y, const Color &old_color, const Color &new_color)
{
lock->acquire();
// TODO Assert-check and transform coordinates
int x = real_x;
int y = real_y;
double fact = 1.0;
Color* pixel = pixels + (real_y * width + real_x);
pixel->r = pixel->r - old_color.r * fact + new_color.r * fact;
pixel->g = pixel->g - old_color.g * fact + new_color.g * fact;
pixel->b = pixel->b - old_color.b * fact + new_color.b * fact;
// Set pixel dirty
if (x < dirty_left)
{
dirty_left = x;
}
if (x > dirty_right)
{
dirty_right = x;
}
if (y < dirty_down)
{
dirty_down = y;
}
if (y > dirty_up)
{
dirty_up = y;
}
lock->release();
}
void CanvasPreview::setAllDirty()
{
lock->acquire();
dirty_left = 0;
dirty_right = width - 1;
dirty_down = 0;
dirty_up = height - 1;
lock->release();
2014-06-10 13:13:16 +00:00
}