Home » Community » Newbie corner » smoother drawing
smoother drawing [message #27682] |
Thu, 29 July 2010 14:33  |
cullam
Messages: 8 Registered: July 2010 Location: St. John's Canada
|
Promising Member |
|
|
Hi guys. I've been creating a re-sizable display in UPP that uses some drawing functionality. Everything is working fine, but I was wondering if there was any way to use anti-aliased lines and edges, and possibly gradient fills. Obviously, using OpenGL is a possible option, but I was hoping to avoid it, since I'm only making simple 2D vector drawings, and there seems to be quite a lot of work to get Open GL up and running in an app.
Basically, what I've done so far works fine, but I'd like to be able to make "smoother" drawings, that don't look like they were whipped up in paintbrush!
Thanks a bunch.
-cullam
|
|
|
|
|
|
Re: smoother drawing [message #27688 is a reply to message #27682] |
Thu, 29 July 2010 16:12   |
mr_ped
Messages: 826 Registered: November 2005 Location: Czech Republic - Praha
|
Experienced Contributor |
|
|
I'm not sure and too lazy to check, but I think for your case you need to add Painter package, and use something like PainterDraw class (or DrawPainter) and apply that on that Draw& w.
edit: the DrawEllipse and other API calls should stay the same, so your code should work without change, just find out the way to switch it to new Painter object. In case you fail (unlikely), write here, somebody else will surely give you more exact advice.
[Updated on: Thu, 29 July 2010 16:15] Report message to a moderator
|
|
|
|
Re: smoother drawing [message #27691 is a reply to message #27682] |
Thu, 29 July 2010 16:42   |
cullam
Messages: 8 Registered: July 2010 Location: St. John's Canada
|
Promising Member |
|
|
Aha! This is looking much more promising!
So, I'm looking through the code in the example, but without any comments in it, I'm not entirely sure what I'm seeing.
Examples.h
#ifndef _PainterExamples_Examples_h_
#define _PainterExamples_Examples_h_
#include <CtrlLib/CtrlLib.h>
#include <Painter/Painter.h>
using namespace Upp;
#define IMAGECLASS TestImg
#define IMAGEFILE <PainterExamples/Test.iml>
#include <Draw/iml_header.h>
#define LAYOUTFILE <PainterExamples/Examples.lay>
#include <CtrlCore/lay.h>
void RegisterExample(const char *name, void (*ex)(Painter& pw));
struct App : TopWindow {
virtual void Paint(Draw& w);
SplitterFrame split;
ArrayCtrl list;
FrameBottom< WithCtrlLayout<StaticRect> > ctrl;
typedef App CLASSNAME;
void DoPaint0(Painter& sw);
void DoPaint(Painter& sw);
void Print();
void Benchmark();
void Sync();
void ToSlider(EditDouble *e, SliderCtrl *slider);
void ToEdit(EditDouble *e, SliderCtrl *slider);
void Pair(EditDouble& e, SliderCtrl& slider);
void ToSlider();
void Reset();
void Serialize(Stream& s);
App();
~App();
};
#endif
All the drawing classes in this example appear to take a reference to a Painter object, but I'm not quite sure where I get this object in the first place. In my app, my main is just:
#include "VectorsGUI.h"
#define VERSION "2010070801"
#define FILE_BASE "SQX-Drive"
#define FILE_TITLE String( FILE_BASE )
GUI_APP_MAIN
{
VectorsGUI(FILE_TITLE, FILE_BASE, VERSION ).Run();
}
... with everything of interest happening in my other classes. I believe the Paint() function I'm using came from inheriting my most important class from WithVectorsGUILayout<TopWindow>. What do I need to modify/do/include to be able to use Painter() instead? Is it some way of getting a Painter& to pass into Paint(), rather than a Draw&?
Thanks for the help. And it is very helpful to know that what I'm looking to do CAN be done simply! Now I just need to figure out how...
|
|
|
Re: smoother drawing [message #27692 is a reply to message #27682] |
Thu, 29 July 2010 16:56   |
mr_ped
Messages: 826 Registered: November 2005 Location: Czech Republic - Praha
|
Experienced Contributor |
|
|
Ok, some upp "magic" for you, or how I would proceed further:
Select the PainterExamples package
Open Examples.h
.. notice the line with virtual void Paint(Draw& w); declaration, after all you told me you draw your things there, right? So move on that line with cursor on the "Paint" word.
Now Alt+J.
You should end in main.cpp at line 80 with function definition.
And that was quite easy to understand for me, because I recently did some code with Image/ImageBuffer/RasterImage/Painter and other upp classes of that family. For you it will be maybe more cryptic, so here we go:
Size sz = GetSize(); //size of painting area of window
if(ctrl.transparent) { //this will create the color chessboard background if you tick that checkbox in app, otherwise the background is white
for(int y = 0; y < sz.cy; y += 32)
for(int x = 0; x < sz.cx; x += 32)
w.DrawRect(x, y, 32, 32, (x ^ y) & 32 ? Color(254, 172, 120) : Color(124, 135, 253));
//notice it's drawn into the old Draw thing without new Painter
}
ImageBuffer ib(sz); //this is raw RGBA memory array for SW rendering (allocating the "canvas" for Painter)
//here's the Painter class finally - BufferPainter is nothing more than
//Painter class extended to paint into ImageBuffer, which was created a line above
BufferPainter sw(ib, ctrl.quality); //init it with desired ImageBuffer and desired antialiasing mode (from GUI control)
DoPaint(sw); //some custom function which does the actual drawing and I didn't bother to look inside
//of course just go on the DoPaint with cursor and hit Alt+J to see what's there, if you are curious enough
//but basically you just need to do sw.drawEllipse, etc.. as you wish
w.DrawImage(0, 0, ib);
//and the resulting SW rendered RGBA image is rendered back to OS's window area represented by the original Draw& w instance.
Looks simple to me, but I'm used to UPP, so keep asking if you don't get anything, I will try to explain better. (but later, going off now)
|
|
|
Re: smoother drawing [message #27693 is a reply to message #27682] |
Thu, 29 July 2010 17:06   |
mr_ped
Messages: 826 Registered: November 2005 Location: Czech Republic - Praha
|
Experienced Contributor |
|
|
Did look into that DoPaint out of my curiosity and I think this will raise further questions from you, so to explain:
void App::DoPaint(Painter& sw)
{
if(ctrl.painting) {
PaintingPainter h(2000, 2000);
DoPaint0(h);
sw.Paint(h);
}
else
DoPaint0(sw);
}
If you tick that "painting" checkbox, the app is not drawing to that BufferPainter sw directly, but it firstly does allocate Painting disguised into PaintingPainter class (because you will paint to that Painting with Painter).
Painting is UPP class to only store Draw API calls without execution, so you can replay it later upon different target.
So with that checkbox ticked, that demo code does draw the chosen example in "dry run" into Painting, after it is finished, then the Painting is executed upon that ImageBuffer by line "sw.Paint(h);". But you could still use the Painting "h", so you can for example allocate some higher resolution printing area target, and do printingarea.Paint(h); to get the very same painting in different quality by different "painter", for example you can use the old low quality Draw to paint that Painting.
I hope I'm clear enough to be understood within 2-3 rereads. 
In case Painting is off, the examples are directly drawing to that ImageBuffer memory area, without storing the API calls anywhere, so it can't be replayed again.
|
|
|
|
|
|
|
Goto Forum:
Current Time: Sun Apr 27 22:15:53 CEST 2025
Total time taken to generate the page: 0.00854 seconds
|