ControlP5 and Processing 2.0 P2D/P3D renderers
in
Contributed Library Questions
•
3 months ago
In Processing 2.0's P2D and P3D renderers, smoothing causes artifacts (strange dots) in the controlP5 gui elements. Higher smoothing levels cause blurry text. This causes problems with sketches that use P2D or P3D in combination with ControlP5. I have tried multiple solutions to combat these issues, but none solve the problem or provide a solid workaround. First a code example that displays the problem.
Code Example
Solution 1
Using noSmooth(). This solves the problem for ControlP5, however it create ugly graphics in the rest of the sketch, making it an unusable workaround. With the P2D renderer it is no longer possible to call smooth() and noSmooth() before specific elements, because different smooth levels reset the graphics canvas. So the number of such calls is limited per draw() loop. So varying smooth() levels is not an option.
Solution 2
Use the JAVA2D renderer in the main sketch. This solves the problem for ControlP5, however this means you cannot reap the benefits of OpenGL rendering. More importantly you will be missing all the additional features, including for example custom retained PShapes. So sticking with JAVA2D is not (always) an option.
Solution 3
Using JAVA2D as the main renderer and a P2D PGraphics for the OpenGL graphics. This is not allowed by Processing. When you want P2D/P3D PGraphics you are required to also use P2D/P3D as the main renderer. This would have been a good option, but unfortunately it's just not possible right now. So using a JAVA2D main renderer with P2D PGraphics is not an option.
Solution 4
Using a custom controlFont in ControlP5. ControlP5 allows the user to change the font used in it's gui elements. I have tried setting it to for example Arial. However, the text quality problems persist, even given good quality settings in the createFont() method. So using a controlFont is not an option.
Solution 5
Using P2D as the main renderer and a JAVA2D PGraphics for the controlP5 gui elements. This is not supported by ControlP5. As far as I know there are no methods that enable you to draw controlP5 into a PGraphics directly. I also haven't found any examples of such a thing. However in my opinion this would be the best possible workaround. Unfortunately at the moment using P2D as the main renderer and drawing the controlP5 gui elements into a JAVA2D PGraphics is not an option.
Solution 6
In an attempt to move as much towards solution 5 as possible I have taken an old hack of mine and applied it to the latest versions of Processing and ControlP5. It works pretty good, so it is the workaround I am currently using. The downside is that the elements are drawn to two PGraphics at the same time (main and JAVA2D). Essentially this works all right, but it's still a hack, so I would hope for a more solid long-term solution. Here is the basic code for it...
The current solution 6 is the best I have at the moment, but as said it's not the ideal solution. I have filed an issue in ControlP5's googlecode issues list. Perhaps Andreas can implement a draw() method in ControlP5 itself that allows you to draw all gui elements directly to PGraphics (solution 5). That may be the best workaround to solve these issues in a more structural manner.
Has anybody else encountered this issue? And are there better workarounds or solutions for it?
Code Example
- import controlP5.*;
- ControlP5 cp5;
- void setup() {
- size(500, 300, P2D);
- // smoothing causes artifacts, higher smoothing blurs the text
- smooth(8);
- // noSmooth(); // without smoothing there are no artifacts
- cp5 = new ControlP5(this);
- cp5.addButton("b1");
- cp5.addButton("b2");
- cp5.addButton("b3");
- cp5.addButton("b4").linebreak();
- cp5.addSlider("s1");
- cp5.addSlider("s2");
- cp5.addSlider("s3").linebreak();
- cp5.addButton("b6");
- cp5.addButton("b7");
- cp5.addNumberbox("n1");
- cp5.addNumberbox("n2");
- }
- void draw() {
- background(255);
- }
Solution 1
Using noSmooth(). This solves the problem for ControlP5, however it create ugly graphics in the rest of the sketch, making it an unusable workaround. With the P2D renderer it is no longer possible to call smooth() and noSmooth() before specific elements, because different smooth levels reset the graphics canvas. So the number of such calls is limited per draw() loop. So varying smooth() levels is not an option.
Solution 2
Use the JAVA2D renderer in the main sketch. This solves the problem for ControlP5, however this means you cannot reap the benefits of OpenGL rendering. More importantly you will be missing all the additional features, including for example custom retained PShapes. So sticking with JAVA2D is not (always) an option.
Solution 3
Using JAVA2D as the main renderer and a P2D PGraphics for the OpenGL graphics. This is not allowed by Processing. When you want P2D/P3D PGraphics you are required to also use P2D/P3D as the main renderer. This would have been a good option, but unfortunately it's just not possible right now. So using a JAVA2D main renderer with P2D PGraphics is not an option.
Solution 4
Using a custom controlFont in ControlP5. ControlP5 allows the user to change the font used in it's gui elements. I have tried setting it to for example Arial. However, the text quality problems persist, even given good quality settings in the createFont() method. So using a controlFont is not an option.
Solution 5
Using P2D as the main renderer and a JAVA2D PGraphics for the controlP5 gui elements. This is not supported by ControlP5. As far as I know there are no methods that enable you to draw controlP5 into a PGraphics directly. I also haven't found any examples of such a thing. However in my opinion this would be the best possible workaround. Unfortunately at the moment using P2D as the main renderer and drawing the controlP5 gui elements into a JAVA2D PGraphics is not an option.
Solution 6
In an attempt to move as much towards solution 5 as possible I have taken an old hack of mine and applied it to the latest versions of Processing and ControlP5. It works pretty good, so it is the workaround I am currently using. The downside is that the elements are drawn to two PGraphics at the same time (main and JAVA2D). Essentially this works all right, but it's still a hack, so I would hope for a more solid long-term solution. Here is the basic code for it...
- pgControlP5.clear(); // clear the PGraphics
- beginRecord(pgControlP5);
- cp5.draw(); // draw ControlP5 to the regular screen (P2D) and the PGraphics (JAVA2D)
- endRecord();
- image(pgControlP5, 0, 0); // display the JAVA2D PGraphics on top of the regular screen
The current solution 6 is the best I have at the moment, but as said it's not the ideal solution. I have filed an issue in ControlP5's googlecode issues list. Perhaps Andreas can implement a draw() method in ControlP5 itself that allows you to draw all gui elements directly to PGraphics (solution 5). That may be the best workaround to solve these issues in a more structural manner.
Has anybody else encountered this issue? And are there better workarounds or solutions for it?
1