I'm working on some app that gets the users width for their multiple monitors, assume they don't have any monitors on top, and then provide them with multiple buttons/frames, so that they can black out whichever monitors they wish.
MY ISSUE
All's well and good, apart from location compatability stuff.
If someone has 4 1920 width monitors, how can I position my reference/starting frames at the leftest monitor, so that I can say "proceed 1920 pixels, make a frame, ..."?
You'd think "Use setLocationtoNull, but how does that work?? You'd think it's simply the middle monitor, length/2; but what is the middle monitor!? It can't be totalScreensLength/2, because that'd mean the program is split in half between the monitors! (so it's most likely the middle of the main manitor).
And not using any setLocations, the program is at the top left of the main monitor.... BUT WHAT IS THE MAIN MONITOR??
If I knew how java figured which monitor was "main", that would solve my issue (and no, knowing merely the main monitors resolution via Toolkit.getScreenSize() would not be enough info).
//creating invis black frames
for(int c=0;c<inArr.length;c++){
int xLoc=0;
for(int i=0;i<c;i++){
/**/ xLoc+=resList[i];
}System.out.println(xLoc);
JFrame blackOut=new JFrame();
blkList.add(blackOut);
blackOut.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
blackOut.getContentPane().setBackground(Color.BLACK);
blackOut.setUndecorated(true);
blackOut.setSize(resList[c],5000);
/**/blackOut.setLocation(xLoc-1280,-2000);
blackOut.setVisible(false);
}
This is the code that makes the program work, because it's hardcoded for my setup of 1280,1920,1440.
The issue is at blackOut.setLocation(xLoc-1280,-2000); I must know where exactly the starting frame would be, so I can move the frame to the left, so 'scaling' works. This is what's happening here:
the frame starts at the top left of my middle, 1920 monitor, so I move the frame 1280 pixels left so it is at the top left of my leftest monitor.
Sorry if this is too verbose, just want to give enough detail.
Also, recently discovered this and went into its documentation, but I don't understand how I could use the data, and am unsure if it's able to provide me the information necessary (know what monitor is main, and be able to differentiate monitors, even if they're the same resolution)
This might be a partial answer.
From the linked discovery of yours, you can get the default configuration and bounds of each device by calling graphicsDevice.getDefaultConfiguration().getBounds(). This includes the coordinates / offset of each screen as well as the individual screen size.
In the implementation for GraphicsEnvironment.getScreenDevices() by SunGraphicsEnvironment screen devices are created by iterating over the number of screens and creating a device for each index - the index is passed to each device.
Related
I need some help with a Java assignment I have, I'm required to build a clone of Pac-Man.
The problem is, I don't know how to draw the movements of the Pac-Man or the Ghosts. I'm thinking I should only draw the walls once, and continiously redraw the characters, but I don't know how I should do it or what methods of drawing I should use.
Generally speaking, it is no good idea not to redraw the complete GUI of any game you write several times each second (the quotient of complete redraws over a second is referred to as the 'frame-rate' of a game). If you do not do this, you might observe weird effects like: The contents look strange if you resize or move the window in case its not displayed in full-screen, there might by weird graphical effects, and, most important, the images of your game-characters won't disappear at their previous positions, if you do not draw the background over them again.
Common approach is to set up a Thread that is not doing anything else but invoking some redraw methods about 60 times each second (60 fps (frames per second) appear fluent to the human eye as our temporal resolution lies in that scale) and to use another Thread that updates the position data of the characters and passes it to the draw-Thread together with the static wall-position-data.
I realize that the OpenGL fixed-function pipeline is thoroughly deprecated by this point, but the engine I'm working with is built upon an old codebase that had never demonstrated any problem of this sort until I upgraded my development machine this month and I'd really rather not rewrite all the rendering architecture when it still fits my needs completely, aside from this bug.
Essentially, while everything in the game I'm developing renders correctly 99.999% of the time, every now and again there will be a single-frame flicker (maybe one frame every 20 seconds or so?). I recorded video to catch a frame-by-frame comparison of what was flickering and discovered that on these sporadic frames, only part of what ought to be an indivisible sprite on my end is being rendered.
An example of what I mean
(correct output on the left, glitchy frame on the right)
And a larger example (note the errors on the left side of the screen)
The engine outputs these draw calls in a fixed order each frame, and yet sometimes some of them appear to be skipped such that things which are drawn later appear, while things which should always be drawn before them do not.
If one looks closely, you can see that all the text-rendering glitches involve skipping blocks of exactly 8 glyphs, but when I peered into the text-rendering code, each complete label is sent between a single pair of glBegin(GL_QUADS) and glEnd(), which to the best of my understanding should be an indivisible action. How can OpenGL render some of those vertices but not others?
Here's the actual code specifically for that label rendering:
glBegin(GL_QUADS);
for (int i = startChar * 8; i < endChar * 8; i+=2)
{
glTexCoord2f(texCoord[i], texCoord[i+1]);
glVertex3f(x + vertCoord[i], y + vertCoord[i+1], z);
}
glEnd();
And yet, 1 frame in 2000 or something will seemingly ignore groups of exactly 32 of these vertices.
I've been stymied trying to figure out any possible cause to this problem, as it's well out of my depth and appears to be essentially 'impossible', as best goes my limited understanding of OpenGL operation (and I want to stress that this code has been unchanged for ages and only began to demonstrate problems when run on my new PC). I'm wondering if anyone could potentially at least point me in the direction of something that could cause this sort of issue....
Edit: Since it was asked, I'm running Windows 10 with an GeForce GTX 1060. Previous system where this bug did not occur was Windows 7 with a Radeon HD 4850, in case this might be relevant.
Well after spending some time on test machine with AMD Radeon R7 to debug similar issue on one of my apps this helped me:
my app was combining transparent and solid objects (just few) using old GL 1.0 api due to compatibility reasons (as with VBO and other stuff there is always some problem in one card or another so the user can always switch to GL 1.0).
We usually use nVidia cards for control PC but this time we had to use AMD and after Installing drivers strange flickering occurs. Part of scene was changing color randomly on each frame render. All the objects where rendered with the same code (even function) and some where OK all the time and some where flickering all the time.
Removing transparency got no effect so that was not the point. AMD where picky about the number and type of vertexes rendered in the past and it seems the behavior returns (after some constant number of faces rendered). I also remembered on similar problem with Intel which was really picky about color description.
So I combined both errors and find the place where my App start to do strange thing and place there
glColor4f(0.0,0.0,0.0,0.0);
To reset the Alpha channel (which was not used in that part of code at all just in the transparency and reseted correctly there). And it solved my issues (at least for now).
Without MCVE I can only guess if your issue is related to this but you might try to add some dummy glColor4f calls through out your rendering code to see if the behavior changes ...
To help emphasize your problem try to increase the number of rendered faces per frame (without clear screen or buffer swap) as it tends to be tighted to number of rendered faces (processed vertexes).
In many multimonitor setups featuring monitors of varying stand heights, the vertical positions of the monitors can be adjusted in software so that their graphics align correctly. A vertical displacement is added to the Windows mouse coordinates to give this effect; shown in purple in the diagram:
I am building a program that needs to know when the user's mouse has reached the top of any of their monitors. I tried using MouseInfo.getPointerInfo().getLocation().y==0, but this will not work when the monitors have been displaced in software because the top of the monitor may not always be zero.
Is there a reliable and efficient way to identify this offset across multiple displays?
Thanks to #Siguza's comment, I was able to do what I was trying to accomplish. Simply put, you can find the Rectangle object for the monitor that the mouse is on by using this code: MouseInfo.getPointerInfo().getDevice().getDefaultConfiguration().getBounds()
The Rectangle can also be found for each monitor using the monitor's numerical index within Windows. The code GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getDefaultConfiguration().getBounds() will return the Rectangle for the main monitor (index 0), other monitors can be accessed by changing the index of the GraphicsDevice
The vertical displacement of the monitor is in the .y property of the Rectangle object; this value can be used to identify the topmost coordinate of the monitor.
#Siguza's Comment:
Haven't tested it, but according to the docs, GraphicsConfiguration.getBounds() sounds like what you're looking for. You should be able to get all monitors with GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(), and their configurations with .getConfigurations(), but I idk how to choose from that array.
I have a component placement problem. First I'll try to give (possibly useful) information and then tell you about the main problem:
My System: Windows 8.1 64bit, Java 1.8.0_60 32bit
What I'm trying to do is: After I learn screen resolutions of all connected screens, I'm placing some swing components around the screen. This means that I need to know the resolutions of the screens.
I'm using multiple monitors.
3840 x 2160 (main monitor)
1920 x 1080 (secondary)
I use:
graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
devices = graphicsEnvironment.getScreenDevices();
And for the main screen device:
devices[i].getDefaultConfiguration().getBounds()
returns [0, 0, 2560, 1440]. Instead of the right values 3840 x 2160.
Interesting thing is;
devices[i].getDisplayMode().getWidth() and getHeight()
returns the right 3840 and 2160 values.
Note: This difference does not happen in any other resolution selection of the screen. For example, if I select 1920 x 1080 for the main screen, both "getDefaultConfiguration().getBounds()" and "getDisplayMode().getWidth()" returns the right values.
Now,
You can say that I'm already getting the right dimensions. So, what is the matter?
The thing is, when I try to position my SWING components, they are placed in wrong positions. For example, an element at [3750, 0, 10, 10] ends up inside the second monitor, while It should have been on the right upper corner of the first screen.
Another example: As you know, a fixed sized component would appear smaller in higher resolutions. Since its pixel percentage related to screen gets smaller, the component itself also looks smaller. For example; When I increase my screen's resolution from 1920x1080 to 2560x1440, my components gets smaller. But, when I increase the resolution from 2560x1440 to 3840x2160; they stay in the same size.
I hope I was clear about the problem.
I know of one Windows 8+ specific feature, which might manifest in that way: per-display DPI setting. The feature is supposed to keep application window at the same size physically, even when dragging them across displays with different density.
This is achieved by rendering the application's window into a intermediate buffer, which then is scaled by the DWM taking the target screen DPI into account.
This feature can be disabled, using following dialog:
It has to be done on the file containing the executable program, which displays any frames. In Java, it's somewhat convoluted, since it's a hosting application. Changing this on java(w).exe should alter the behavior globally.
Typically, this kind of flag adjustment is done by a software installer. It's possible to wrap the java jar into a exe with a thin wrapper. I like launch4j the most for this task. The wrapper exe and the jar file can be wrapped into a installer script, which sets the flag at installation time.
I have been developing a game for Android and I had an idea for catering for the different screen sizes, and I would like feedback on whether the idea is a good one, and how it can be improved, or if it shall be scrapped.
What I have is a 2d size scrolling game, where it is locked it landscape mode. Because screen sizes vary, the width of the screen (usually height, but it is in landscape so I shall refer to it as width) changes. This causes all sorts of problems for me with moving the background because it is basically two identical pictures scrolling, and as one leaves the screen the other begins to replace it, so I must catch the image when it has just left the screen, so it can be reset and ready to scroll again. This means it must reach an int value every time, else it will not be caught and both images would scroll off screen.
My idea, which I have briefly tested is as follows. Truncate the screen size to the nearest 100px. Add 100 to this value and have that as the width for the background images. Then divide this value by 100 and use this as the rate of px per frame it moves. This would mean that the background would move at a similar rate dependent upon screen size (set frame rate of 25FPS). It would move faster on larger screens and slower of smaller screens, but would move at the same speed relative (1% per second or whatever).
Is this idea flawed? I have tested it vaguely on a few screen sizes but the emulator is verry laggy, and I only have a couple of devices to test it on (I am only 18 so I cannot get my hands on many!).
Any feedback appreciated.