diff --git a/ImpressionistDoc.cpp b/ImpressionistDoc.cpp index f159b6c..855b39c 100644 --- a/ImpressionistDoc.cpp +++ b/ImpressionistDoc.cpp @@ -140,7 +140,7 @@ void ImpressionistDoc::swapContent() m_ucPainting = m_ucBitmap; m_ucBitmap = temp; m_ucOriginal = temp; - memcpy(m_ucBackup, m_ucPainting, m_nWidth*m_nHeight * 3); + //memcpy(m_ucBackup, m_ucPainting, m_nWidth*m_nHeight * 3); m_pUI->m_origView->refresh(); m_pUI->m_paintView->refresh(); } diff --git a/ImpressionistDoc.h b/ImpressionistDoc.h index ab0a1f7..2eec6c6 100644 --- a/ImpressionistDoc.h +++ b/ImpressionistDoc.h @@ -75,6 +75,7 @@ class ImpressionistDoc unsigned char* m_ucHistory; //for undo unsigned char* m_ucAnother; //for another image + unsigned char *m_ucBackup = NULL; int m_alphaMapWidth; int m_alphaMapHeight; diff --git a/LineBrush.cpp b/LineBrush.cpp index 77935d3..1baa095 100644 --- a/LineBrush.cpp +++ b/LineBrush.cpp @@ -85,7 +85,7 @@ void LineBrush::BrushEnd(const Point source, const Point target) void LineBrush::RightBegin(const Point source, const Point target) { - start = source; + start = target; } void LineBrush::RightMove(const Point source, const Point target) @@ -93,7 +93,7 @@ void LineBrush::RightMove(const Point source, const Point target) glColor3f(1, 0, 0); glBegin(GL_LINES); glVertex2d(start.x, start.y); - glVertex2d(source.x, source.y); + glVertex2d(target.x, target.y); glEnd(); } @@ -101,7 +101,7 @@ void LineBrush::RightEnd(const Point source, const Point target) { ImpressionistDoc* pDoc = GetDocument(); ImpressionistUI* dlg = pDoc->m_pUI; - int angle = static_cast(radToDeg(atan2(source.y - start.y, source.x - start.x))); + int angle = static_cast(radToDeg(atan2(target.y - start.y, target.x - start.x))); dlg->setLineAngle(angle); } diff --git a/PaintView.cpp b/PaintView.cpp index 19faf60..ffc44b2 100644 --- a/PaintView.cpp +++ b/PaintView.cpp @@ -31,7 +31,7 @@ extern std::vector> getGaussianKernel(float sigma, int size); #endif static int eventToDo; -static int isAnEvent=0; +static int isAnEvent = 0; static Point coord; void PaintView::updateViewport() @@ -60,7 +60,9 @@ void PaintView::updateViewport() }); m_pPaintBitstart = m_pDoc->viewport.dataPtr + 3 * ((m_pDoc->m_nPaintWidth * startrow) + scrollpos.x); + RestoreContent(); + m_pPaintBitstart = m_pDoc->m_ucPainting + 3 * ((m_pDoc->m_nPaintWidth * startrow) + scrollpos.x); } @@ -73,71 +75,66 @@ void PaintView::updatePainting() glFlush(); } -PaintView::PaintView(int x, - int y, - int w, - int h, - const char* l) - : Fl_Gl_Window(x,y,w,h,l) +PaintView::PaintView(int x, + int y, + int w, + int h, + const char* l) + : Fl_Gl_Window(x, y, w, h, l) { - m_nWindowWidth = w; - m_nWindowHeight = h; + m_nWindowWidth = w; + m_nWindowHeight = h; } void PaintView::draw() { - #ifndef MESA +#ifndef MESA // To avoid flicker on some machines. glDrawBuffer(GL_FRONT_AND_BACK); - #endif // !MESA +#endif // !MESA glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - if(!valid()) + if (!valid()) { glClearColor(0.7f, 0.7f, 0.7f, 1.0); // We're only using 2-D, so turn off depth - glDisable( GL_DEPTH_TEST ); + glDisable(GL_DEPTH_TEST); ortho(); - glClear( GL_COLOR_BUFFER_BIT ); + glClear(GL_COLOR_BUFFER_BIT); } scrollpos;// = GetScrollPosition(); scrollpos.x = 0; - scrollpos.y = 0; + scrollpos.y = 0; - m_nWindowWidth = w(); - m_nWindowHeight = h(); + m_nWindowWidth = w(); + m_nWindowHeight = h(); int drawWidth, drawHeight; - drawWidth = min( m_nWindowWidth, m_pDoc->m_nPaintWidth ); - drawHeight = min( m_nWindowHeight, m_pDoc->m_nPaintHeight ); - - if (m_pDoc->m_ucBackup) - { - memcpy(m_pDoc->m_ucPainting, m_pDoc->m_ucBackup, drawWidth*drawHeight * 3); - } + drawWidth = min(m_nWindowWidth, m_pDoc->m_nPaintWidth); + drawHeight = min(m_nWindowHeight, m_pDoc->m_nPaintHeight); startrow = m_pDoc->m_nPaintHeight - (scrollpos.y + drawHeight); - if ( startrow < 0 ) startrow = 0; + if (startrow < 0) startrow = 0; - m_pPaintBitstart = m_pDoc->m_ucPainting + + m_pPaintBitstart = m_pDoc->m_ucPainting + 3 * ((m_pDoc->m_nPaintWidth * startrow) + scrollpos.x); - m_nDrawWidth = drawWidth; - m_nDrawHeight = drawHeight; + m_nDrawWidth = drawWidth; + m_nDrawHeight = drawHeight; - m_nStartRow = startrow; - m_nEndRow = startrow + drawHeight; - m_nStartCol = scrollpos.x; - m_nEndCol = m_nStartCol + drawWidth; + m_nStartRow = startrow; + m_nEndRow = startrow + drawHeight; + m_nStartCol = scrollpos.x; + m_nEndCol = m_nStartCol + drawWidth; - if ( m_pDoc->m_ucPainting && !isAnEvent) + if (m_pDoc->m_ucPainting && !isAnEvent) { RestoreContent(); updateViewport(); @@ -145,64 +142,81 @@ void PaintView::draw() bool willSave = false; - if ( m_pDoc->m_ucPainting && isAnEvent) + if (m_pDoc->m_ucPainting && isAnEvent) { // Clear it after processing. - isAnEvent = 0; + isAnEvent = 0; + + Point source(coord.x + m_nStartCol, m_nEndRow - coord.y); + Point target(coord.x, m_nWindowHeight - coord.y); - Point source( coord.x + m_nStartCol, m_nEndRow - coord.y ); - Point target( coord.x, m_nWindowHeight - coord.y ); - // This is the event handler - switch (eventToDo) + switch (eventToDo) { case LEFT_MOUSE_DOWN: - // updatePainting(); + updatePainting(); m_pDoc->recordHistory(); - m_pDoc->m_pCurrentBrush->BrushBegin( source, target ); - // updateViewport(); + m_pDoc->m_pCurrentBrush->BrushBegin(source, target); + updateViewport(); break; case LEFT_MOUSE_DRAG: - // updatePainting(); - m_pDoc->m_pCurrentBrush->BrushMove( source, target ); + updatePainting(); + m_pDoc->m_pCurrentBrush->BrushMove(source, target); SaveCurrentContent(); - // updateViewport(); + updateViewport(); break; case LEFT_MOUSE_UP: - m_pDoc->m_pCurrentBrush->BrushEnd( source, target ); - // updatePainting(); - // SaveCurrentContent(); - // RestoreContent(); + m_pDoc->m_pCurrentBrush->BrushEnd(source, target); + updatePainting(); + SaveCurrentContent(); + RestoreContent(); willSave = true; break; case RIGHT_MOUSE_DOWN: + updateViewport(); m_pDoc->m_pCurrentBrush->RightBegin(source, target); break; case RIGHT_MOUSE_DRAG: - RestoreContent(); + updatePainting(); + updateViewport(); m_pDoc->m_pCurrentBrush->RightMove(source, target); + glFlush(); break; case RIGHT_MOUSE_UP: - RestoreContent(); + updatePainting(); + updateViewport(); m_pDoc->m_pCurrentBrush->RightEnd(source, target); break; default: - printf("Unknown event!!\n"); + printf("Unknown event!!\n"); break; } } - if(willAutoFill) + if (willAutoFill) { autoFill(); willAutoFill = false; willSave = true; - } else if (willPainterly) + glFlush(); + } + else if (willPainterly) { painterly(); willPainterly = false; willSave = true; + glFlush(); + } + else + { + // for debugging purpose + // Point source(coord.x + m_nStartCol, m_nEndRow - coord.y); + // Point target(coord.x, m_nWindowHeight - coord.y); + // if(source.x>=0 && source.y>=0 && source.x <= m_nWindowWidth-1 && source.y <= m_nWindowHeight) + // { + // m_pDoc->m_pCurrentBrush->BrushMove(source, target); + // } } @@ -214,22 +228,15 @@ void PaintView::draw() glDrawBuffer(GL_BACK); #endif // !MESA - if(willSave) + if (willSave) { SaveCurrentContent(); glFlush(); - memcpy(m_pDoc->m_ucBackup, m_pDoc->m_ucPainting, drawWidth*drawHeight * 3); + updateViewport(); } - updateViewport(); VideoProcessor::continueWriteStream(); - glFlush(); - if(m_pDoc->m_ucPainting && m_pDoc->m_ucBackup) - { - - memcpy(m_pDoc->m_ucPainting, m_pDoc->m_ucBackup, drawWidth*drawHeight * 3); - } } void PaintView::prepareAutoFill() @@ -247,41 +254,41 @@ void PaintView::preparePainterly() int PaintView::handle(int event) { - switch(event) + switch (event) { case FL_ENTER: // refresh(); - // redraw(); + // redraw(); break; case FL_PUSH: coord.x = Fl::event_x(); coord.y = Fl::event_y(); - if (Fl::event_button()>1) - eventToDo=RIGHT_MOUSE_DOWN; + if (Fl::event_button() > 1) + eventToDo = RIGHT_MOUSE_DOWN; else - eventToDo=LEFT_MOUSE_DOWN; - isAnEvent=1; + eventToDo = LEFT_MOUSE_DOWN; + isAnEvent = 1; redraw(); break; case FL_DRAG: coord.x = Fl::event_x(); coord.y = Fl::event_y(); - if (Fl::event_button()>1) - eventToDo=RIGHT_MOUSE_DRAG; + if (Fl::event_button() > 1) + eventToDo = RIGHT_MOUSE_DRAG; else - eventToDo=LEFT_MOUSE_DRAG; - isAnEvent=1; + eventToDo = LEFT_MOUSE_DRAG; + isAnEvent = 1; redraw(); m_pDoc->m_pUI->m_origView->setCursor(coord); break; case FL_RELEASE: coord.x = Fl::event_x(); coord.y = Fl::event_y(); - if (Fl::event_button()>1) - eventToDo=RIGHT_MOUSE_UP; + if (Fl::event_button() > 1) + eventToDo = RIGHT_MOUSE_UP; else - eventToDo=LEFT_MOUSE_UP; - isAnEvent=1; + eventToDo = LEFT_MOUSE_UP; + isAnEvent = 1; redraw(); break; case FL_MOVE: @@ -316,16 +323,16 @@ void PaintView::SaveCurrentContent() // out paint strokes glReadBuffer(GL_BACK); - glPixelStorei( GL_PACK_ALIGNMENT, 1 ); - glPixelStorei( GL_PACK_ROW_LENGTH, m_pDoc->m_nPaintWidth ); - - glReadPixels( 0, - m_nWindowHeight - m_nDrawHeight, - m_nDrawWidth, - m_nDrawHeight, - GL_RGB, - GL_UNSIGNED_BYTE, - m_pPaintBitstart ); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_ROW_LENGTH, m_pDoc->m_nPaintWidth); + + glReadPixels(0, + m_nWindowHeight - m_nDrawHeight, + m_nDrawWidth, + m_nDrawHeight, + GL_RGB, + GL_UNSIGNED_BYTE, + m_pPaintBitstart); } @@ -333,18 +340,18 @@ void PaintView::RestoreContent() { glDrawBuffer(GL_BACK); - glClear( GL_COLOR_BUFFER_BIT ); + glClear(GL_COLOR_BUFFER_BIT); - glRasterPos2i( 0, m_nWindowHeight - m_nDrawHeight ); - glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); - glPixelStorei( GL_UNPACK_ROW_LENGTH, m_pDoc->m_nPaintWidth ); - glDrawPixels( m_nDrawWidth, - m_nDrawHeight, - GL_RGB, - GL_UNSIGNED_BYTE, - m_pPaintBitstart); + glRasterPos2i(0, m_nWindowHeight - m_nDrawHeight); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ROW_LENGTH, m_pDoc->m_nPaintWidth); + glDrawPixels(m_nDrawWidth, + m_nDrawHeight, + GL_RGB, + GL_UNSIGNED_BYTE, + m_pPaintBitstart); -// glDrawBuffer(GL_FRONT); + // glDrawBuffer(GL_FRONT); } void PaintView::autoFill() @@ -367,26 +374,26 @@ void PaintView::autoFill() { for (int j = 0; j < h; j += s) { - points.emplace_back(randAlter(i,r), randAlter(j,r)); + points.emplace_back(randAlter(i, r), randAlter(j, r)); } } unsigned const seed = std::chrono::system_clock::now().time_since_epoch().count(); - std::shuffle(points.begin(), points.end(),std::default_random_engine(seed)); + std::shuffle(points.begin(), points.end(), std::default_random_engine(seed)); - for(auto& pt: points){ + for (auto& pt : points) { const int i = pt.x; const int j = pt.y; // const Point source(i + m_nStartCol, m_nEndRow - j); - if(randAttr) + if (randAttr) { - m_pDoc->m_pUI->setSize(randAlter(size,r)); - m_pDoc->m_pUI->setLineWidth(randAlter(lineWidth,r)); - m_pDoc->m_pUI->setLineAngle(randAlter(lineAngle,r)); + m_pDoc->m_pUI->setSize(randAlter(size, r)); + m_pDoc->m_pUI->setLineWidth(randAlter(lineWidth, r)); + m_pDoc->m_pUI->setLineAngle(randAlter(lineAngle, r)); } const Point target(i, j + m_nWindowHeight - m_nDrawHeight); m_pDoc->m_pCurrentBrush->BrushBegin(target, target); m_pDoc->m_pCurrentBrush->BrushEnd(target, target); - + } // glFlush(); @@ -415,23 +422,23 @@ void PaintView::kernelHelper(unsigned char* before, unsigned char* target, const { int size = kernel.size(); float total = 0; - for (int i = 0; i radii; - for(int i=0; im_pUI->m_painterlyBlur; std::vector> kernel = getGaussianKernel(blur, r); unsigned char* ref = new unsigned char[w*h * 3]; - if(blur == 0) + if (blur == 0) { memcpy(ref, m_pDoc->m_ucOriginal, w*h * 3); - }else + } + else { kernelHelper(m_pDoc->m_ucOriginal, ref, kernel, w, h, false); } @@ -509,7 +517,7 @@ void PaintView::paintLayer(unsigned char* canvas, unsigned char* ref, int r) { const int w = m_pDoc->m_nWidth; const int h = m_pDoc->m_nHeight; - int grid= r * m_pDoc->m_pUI->m_painterlyGridSize; + int grid = r * m_pDoc->m_pUI->m_painterlyGridSize; int threshold = m_pDoc->m_pUI->m_painterlyThreshold; std::vector strokes; @@ -517,11 +525,11 @@ void PaintView::paintLayer(unsigned char* canvas, unsigned char* ref, int r) std::vector diff(w*h); // 1. calculate difference matrix - for(int i = 0; ierror) + if (e > error) { argMax = Point(a, b); error = e; @@ -556,11 +564,12 @@ void PaintView::paintLayer(unsigned char* canvas, unsigned char* ref, int r) } sumError /= gridSum; - if(sumError > threshold) + if (sumError > threshold) { // std::vectors = makeStrokes(r, x, y, ref, w); strokes.push_back(argMax); - }else + } + else { nob.push_back(argMax); } @@ -572,10 +581,10 @@ void PaintView::paintLayer(unsigned char* canvas, unsigned char* ref, int r) std::shuffle(strokes.begin(), strokes.end(), rng); // std::random_shuffle(nob.begin(), nob.end()); int sizeOriginal = m_pDoc->getSize(); - for(auto&& p:strokes) + for (auto&& p : strokes) { m_pDoc->m_pUI->setSize(r); - m_pDoc->m_pCurrentBrush->BrushBegin(p.x,p.y,r,ref,canvas); + m_pDoc->m_pCurrentBrush->BrushBegin(p.x, p.y, r, ref, canvas); m_pDoc->m_pCurrentBrush->BrushEnd(p, p); } m_pDoc->m_pUI->setSize(sizeOriginal); diff --git a/polygonpainterly.bmp b/polygonpainterly.bmp deleted file mode 100644 index 0eac6c6..0000000 Binary files a/polygonpainterly.bmp and /dev/null differ