Unable to Draw in C++ on Raspberry Pi - c++

I have, thanks to some help, managed to get the program below to compile and run but although it keeps on chugging away I cannot see anything drawn on the Pi's screen.
I don't think that it is a problem unique to the use of openvg and ajstarks code as, during the problem I had compiling the test progam, I tried a different way of writing images (sorry, all I remember was that it was low level and didn't need the includes for openvg). It took a bit of searching and re-writing to get it to compile and when it did the same thing happened.
I persevered for a while, but got no where. There were some references to some sort of limitation with Raspberry Pi and X Windows leading to the same problem. You draw something but it doesn't display. Given that there were several comments suggesting that openvg worked, I went back to that and (thanks to a guy called Ross) eventually worked out why I couldn't compile the code.
So now I am at a point where I can compile code that others have got to run successfully, but it doesn't draw anything on the screen. I know that the code runs - it chews CPU cycles (well the official demo does, mine less so although it's still definitly going) and the code can be quit with
Another method of working with graphics has come across the same no-output-display problem, so I think the problem is somewhere on my Pi but I have drawn a blank on how to address the X Windows (or it might have been X11, wish I had kept the tabs open!) not wanting to draw issue.
Any help greatly appreciated, thanks in advance!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
extern "C" {
#include "VG/openvg.h"
#include "VG/vgu.h"
#include "fontinfo.h"
#include "shapes.h"
}
using namespace std;
int main (void) {
int width, height;
VGfloat w2, h2, w;
char s[3];
init(&width, &height); // Graphics initialization
w2 = (VGfloat)(width/2);
h2 = (VGfloat)(height/2);
w = (VGfloat)w;
Start(width, height); // Start the picture
Background(0, 0, 0); // Black background
Fill(44, 77, 232, 1); // Big blue marble
Circle(w2, 0, w); // The "world"
Fill(255, 255, 255, 1); // White text
TextMid(w2, h2, "hello, world", SerifTypeface, width/10); // Greetings
End(); // End the picture
fgets(s, 2, stdin); // Pause until RETURN]
finish(); // Graphics cleanup
exit(0);
}

Ok...
Thanks to a stroke of luck I have found the answer and it's odd. To me anyway...
In case anyone else encouters the problem, here is the (partial) solution which leads to another question to be posted shortly.
I am trying to run a programming club in my school and it's not practical to physically connect the Pi's to kb, mouse and monitor so they all auto-run VNC and we connect to the machines using Ultra-VNC. The programs are written in a shared directory and Eclipse C++ runs on the host; therefore all program output is viewed via VNC.
I had been continuing to try to solve the problem and at one point connected a keyboard and mouse and noticed that they seemed to be recognised (laser came on, Caps Lock toggled, etc.) but they didn't do anything when moved/typed on.
Eventually the penny began to teater on the edge as I got increasingly confused as to why no one else was having this problem. Is seemed odd that no one else had the issue and then I began to wonder more about the kb/mouse issue.
I tried plugging the HDMI output into a monitor at home (shool ones are still analogue d-sub!) and lo and behold, the physical kb and mouse worked. Then it got really strange!
Somehow I have 2 desktops running at the same time. The physical keyboard and mouse control one and VNC controls the other. Interestingly, VNC has the title Pi's X Desktop suggesting that the graphics problem might be something to do with X, but I am not sure for the reason below.
If I start a terminal window on 'Physical' desktop, it doesn't show up on 'VNC' desktop and vice versa - they seem to be independent, although that's not quite true.
When I run the test file on 'Physical' desktop, it works fine and can be controlled only using the physical kb. When I run it on 'VNC' desktop, it can be controlled only with the VNC kb but the output displays on the physical screen.
I really don't get this!
So, this answers the original question as the program does run on the Pi.
Off to post (hopefully a final) question on how to either get VNC to show the 'Physical' desktop or how to target the graphics output to the 'correct' desktop.

Related

GLFW Window on MacBook 16" displaying content only in upper left of window

I have a weird problem with GLFW on my MacBook Screen. I am creating a 1400 by 900 pixel window on my nearly 4k screen (3456 x 2234), so it should be really tiny. Instead what happens is that the window is 4 times the size (double in length and height) and my rendered content is only being displayed in the upper left of the screen.
I know that apple does some sketchy mapping stuff because of their wird aspect ratio display, but I searched for quite a while and no one has had the same problem.
What's even weirder is that if I create that window on an external monitor and drag it onto to laptop display, it works just fine. It only messes up when created on the laptop display itself.
I am using GLFW 3.3 and Vulkan 1.2.198 on macOS Monterey 12.1
Any help is appreciated.
EDIT: After trying nearly everything possible in my code and getting the same bug when using the minimal example from the GLFW getting started example, I came to the conclusion that this isn't code related as pointed out in the comments.
This appears to be an issue with how Mac displays report their resolution. Note that this is not a silver bullet but, when faced with the same issue, this worked for me.
The short of it is that the values that you're using to calculate your viewport are incorrect due to how the Mac display scales. The solution that I've found is to ask GLFW what you should set.
To get these values, just use the following function call. I am not sure what the glViewport equivalent is in vulkan, but this should theoretically work, and worked for me in OpenGL for the same problem.
int initial_framebuffer_width, initial_framebuffer_height;
glfwGetFramebufferSize(g_glfw_window, &initial_framebuffer_width,
&initial_framebuffer_height);
// Set your viewport here with the width and height.
If this didn't work, a good debugging step is to draw the window, then attempt to resize just a tiny bit, then print out the width and height values that GLFW gives in the framebuffer callback. You should notice that they might be much larger than what you set them to, this is how you know it's the scaling issue, and the above code should give you what you're looking for.

c++ GetPixel returning wrong values [duplicate]

This is my first post on this forum, please don't go hard on me if I didn't post it in the right place or if I did something wrong, I don't post in forums very much. So, I have this problem with GetPixel function. Basically, it should return the color decimal at x, y. The code I am about to post works perfectly on windows 7 32bit, but recently I bought a new laptop y50-70 with windows 8.1 64bit and the same code works completely different. I can't find any solution to the problem, can't even describe it. I think it could have something to do with desktop handle, HDC, GetDC(), GetPixel(), maybe even with my computer resolution, refresh rate or something like that... I have even recorded some videos which could help you understand the problem I am having because I can't even describe it correctly. It is like the real color is x = 219, y = 407 away from the place, where my mouse is pointing. The new laptop is 3 weeks old, I even tried to do system restore 1 time, but that didn't solve the problem.
Feel free to use this code, hope it will work fine for you:
#include <iostream>
#include <Windows.h>
using namespace std;
void Detect();
int main()
{
Detect();
return 0;
}
void Detect()
{
POINT p;
HDC hDC = GetDC(0);
int x, y;
while (!GetAsyncKeyState(VK_INSERT)) // Press insert to stop
{
GetCursorPos(&p);
x = p.x;
y = p.y;
hDC = GetDC(0);
cout << x << " " << y << " " << GetPixel(hDC, x, y) << endl;
Sleep(50);
}
ReleaseDC(0, hDC);
}
Links to the problem below:
https://youtu.be/q2H2M8WLHVI
https://youtu.be/UcneHwXaGoM
If anyone could at least help somehow or tell what to do, where to go, I would very, very much appreaciate it. One of the main reasons why I started programming is because something like this, working with colours, conditions, etc... and now I can't advance further which is really sad. Hope to hear a reply. Thank you.
This is probably an issue with DPI scaling.
If your new monitor has a higher-than-average number of dots per inch, then Windows, by default, will stretch the graphics. By default, Windows assumes that programs ignore the DPI. If Windows didn't stretch the graphics, then programs that didn't adjust for the DPI would have tiny text in tiny windows on high-density displays.
This is a bit of a hack. Some of the Windows APIs and messages that let you ask about the display and windows will translate the coordinates between an "average" 96 pixels-per-inch and whatever the actual DPI is for the monitor. Likewise, the APIs that let you size things do the opposite transformation. So this is all largely transparent to the program. But it's not perfect because not all the APIs can do the scaling in a consistent manner.
So my guess is that your laptop has a high-resolution display, GetPixel doesn't translate coordinates for DPI scaling, and the mouse position is transformed for DPI scaling. The result is that you're asking for a pixel that doesn't really line up with the mouse.
My suggested solution is the tell windows that your program is "DPI-aware". There are several ways to do this. The easiest in your case might be to call SetProcessDPIAware right at the beginning of your program. You could also do this be marking your program in the manifest. Depending on the compiler you're using, there might be a command line option to create the manifest you need automatically.
Another alternative that has worked for me, is to change a setting in the Control Panel, to disable per-device DPI Scaling. Are you running multiple monitors?
Win 8.1 introduced a new setting in the Control Panel, which says "Let me choose one DPI scaling for all displays". By defualt this is turned off. Turning it on has worked for me.
See this video to find the setting:
https://www.youtube.com/watch?v=sE3IUTPy1WA
I'm curious, so let me know if that works for you, when you don't use SetProccesDPIAware()

GetPixel returns incorrect values

This is my first post on this forum, please don't go hard on me if I didn't post it in the right place or if I did something wrong, I don't post in forums very much. So, I have this problem with GetPixel function. Basically, it should return the color decimal at x, y. The code I am about to post works perfectly on windows 7 32bit, but recently I bought a new laptop y50-70 with windows 8.1 64bit and the same code works completely different. I can't find any solution to the problem, can't even describe it. I think it could have something to do with desktop handle, HDC, GetDC(), GetPixel(), maybe even with my computer resolution, refresh rate or something like that... I have even recorded some videos which could help you understand the problem I am having because I can't even describe it correctly. It is like the real color is x = 219, y = 407 away from the place, where my mouse is pointing. The new laptop is 3 weeks old, I even tried to do system restore 1 time, but that didn't solve the problem.
Feel free to use this code, hope it will work fine for you:
#include <iostream>
#include <Windows.h>
using namespace std;
void Detect();
int main()
{
Detect();
return 0;
}
void Detect()
{
POINT p;
HDC hDC = GetDC(0);
int x, y;
while (!GetAsyncKeyState(VK_INSERT)) // Press insert to stop
{
GetCursorPos(&p);
x = p.x;
y = p.y;
hDC = GetDC(0);
cout << x << " " << y << " " << GetPixel(hDC, x, y) << endl;
Sleep(50);
}
ReleaseDC(0, hDC);
}
Links to the problem below:
https://youtu.be/q2H2M8WLHVI
https://youtu.be/UcneHwXaGoM
If anyone could at least help somehow or tell what to do, where to go, I would very, very much appreaciate it. One of the main reasons why I started programming is because something like this, working with colours, conditions, etc... and now I can't advance further which is really sad. Hope to hear a reply. Thank you.
This is probably an issue with DPI scaling.
If your new monitor has a higher-than-average number of dots per inch, then Windows, by default, will stretch the graphics. By default, Windows assumes that programs ignore the DPI. If Windows didn't stretch the graphics, then programs that didn't adjust for the DPI would have tiny text in tiny windows on high-density displays.
This is a bit of a hack. Some of the Windows APIs and messages that let you ask about the display and windows will translate the coordinates between an "average" 96 pixels-per-inch and whatever the actual DPI is for the monitor. Likewise, the APIs that let you size things do the opposite transformation. So this is all largely transparent to the program. But it's not perfect because not all the APIs can do the scaling in a consistent manner.
So my guess is that your laptop has a high-resolution display, GetPixel doesn't translate coordinates for DPI scaling, and the mouse position is transformed for DPI scaling. The result is that you're asking for a pixel that doesn't really line up with the mouse.
My suggested solution is the tell windows that your program is "DPI-aware". There are several ways to do this. The easiest in your case might be to call SetProcessDPIAware right at the beginning of your program. You could also do this be marking your program in the manifest. Depending on the compiler you're using, there might be a command line option to create the manifest you need automatically.
Another alternative that has worked for me, is to change a setting in the Control Panel, to disable per-device DPI Scaling. Are you running multiple monitors?
Win 8.1 introduced a new setting in the Control Panel, which says "Let me choose one DPI scaling for all displays". By defualt this is turned off. Turning it on has worked for me.
See this video to find the setting:
https://www.youtube.com/watch?v=sE3IUTPy1WA
I'm curious, so let me know if that works for you, when you don't use SetProccesDPIAware()

How do I Control Which Desktop C++ Graphics Output to on Raspberry Pi?

I am trying to run a programming club in my school and it's not practical to physically connect the Pi's to kb, mouse and monitor so they all auto-run VNC and we connect to the machines using Ultra-VNC. The programs are written in a shared directory and Eclipse C++ runs on the host; therefore all program output is viewed via VNC.
Everything was fine while programming in Python and when we started to use C++. However, I hit a brik wall when trying to get graphics to display. I could build a program that appeared to run, but which only gave terminal output - it would never display drawings on the screen. While trying to solve the problem and at one point connected a keyboard and mouse and noticed that they seemed to be recognised (laser came on, Caps Lock toggled, etc.) but they didn't do anything when moved/typed on.
Eventually the penny began to teater on the edge as I got increasingly confused as to why no one else was having this problem given that there seem to be a lot of people using openvg and I began to wonder more about the kb/mouse issue.
I tried plugging the HDMI output into a monitor at home (shool ones are still analogue d-sub!) and lo and behold, the physical kb and mouse worked. Then it got really strange!
Somehow I have 2 desktops running at the same time. The physical keyboard and mouse control one and VNC controls the other. If I start a terminal window on 'Physical' desktop, it doesn't show up on 'VNC' desktop and vice versa - they seem to be independent, although that's not quite true.
When I run the graphics executable on 'Physical' desktop, it works fine and can be controlled only using the physical kb. When I run it on 'VNC' desktop, it can be controlled only with the VNC kb but the output displays on the physical screen.
I really don't get this!
I kind of need to be able to run the programs over VNC, but I need to be able to tell the code I run which desktop to output to as it seems to default to the wrong one. Actually, it would be prefferable to get VNC to connect to the existing HDMI desktop rather than starting a new one but I cannot findout how to tell tightVNC to do that.
The code is here, but I think the problem might be in the init() function which is in a library, so it is probably better to get VNC on to the right desktop...
Thanks in advance for any help!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
extern "C" {
#include "VG/openvg.h"
#include "VG/vgu.h"
#include "fontinfo.h"
#include "shapes.h"
}
using namespace std;
int main (void) {
int width, height;
VGfloat w2, h2, w;
char s[3];
init(&width, &height); // Graphics initialization
w2 = (VGfloat)(width/2);
h2 = (VGfloat)(height/2);
w = (VGfloat)w;
Start(width, height); // Start the picture
Background(0, 0, 0); // Black background
Fill(44, 77, 232, 1); // Big blue marble
Circle(w2, 0, w); // The "world"
Fill(255, 255, 255, 1); // White text
TextMid(w2, h2, "hello, world", SerifTypeface, width/10); // Greetings
End(); // End the picture
fgets(s, 2, stdin); // Pause until RETURN]
finish(); // Graphics cleanup
exit(0);
}
See last comment - abandoned openvg and using X Windows.

OpenGL Window Overlay

What I need to do is create a program that overlays the whole screen and every 30 seconds the screen needs to flash black once.
the program just needs to be on top of everything, doesn't have to work over the top of games, but wouldn't say no if it did!
But i've got no idea where to start. Ideally the solution would be cross-platform for both windows and osx.
Does anybody have any ideas about where I should start or could whip up a quick demo?
OpenGL (you tagged it as such) will not help you with this.
Create a program, that overlays the whole screen,
The canonical way to do this is by creating a decorationless, borderless top level window with some stay-on-top property being set.
and every 30 seconds the screen needs to flash black once.
How do you define "flash back once"? You mean you want the display become visible for one single vertical retrace period or a given amount of time? Being the electronics tinkerer I am, honestly, I'd do this using a handfull of transistors, resistors and capacitors, blanking the analog VGA signal.
Anyway, if you want to do this using software, this is going to be hard work. If you'd do this using the aforementioned stay-on-top window, when you "flash" it away, all the programs with visible output would receive redraw events, which to process would take some time. In the best case scenario the system uses a compositing window manager which can practically immediately show the desktop. Without a compositor its going to be impossible to "flash" the screen.
Ideally the solution would be cross-platform for both windows and osx
A task like this can not be solved cross plattform. There's too much OS dependent work to do for this.
I presume this is for some kind of nerological or psychological experiment. I think doing this using some VGA intercepting circurity would be actually the easier, quicker to implement solution. I can help you with that. But I think there's another StackExchange better suited for this. Unfortunately digital display interfaces (DVI, HDMI and Display Port) use a complex line code scheme, which can not be blanked as easily as VGA, so you must have a computer capable of analog (=VGA) output and a display with a VGA input.