LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: abcdef on November 26, 2014, 19:08:04

Title: LWJGL3 - Displays and Windows (Few questions)
Post by: abcdef on November 26, 2014, 19:08:04
Hi

Firstly the new site looks great and I am looking forward to using LWJGL3. I have just kicked things off in migrating my project, it should be fairly simple but i have some questions / points

1) Can you update the javadoc for

public static java.nio.ByteBuffer glfwGetVideoModes(long monitor,
                                    java.nio.ByteBuffer count)

Its missing the information on Count which is referenced

http://www.glfw.org/docs/latest/group__monitor.html#ga820b0ce9a5237d645ea7cbb4bd383458

2) In this function I get a ByteBuffer back (which is a pretty weird design...but I'll go with it as I know you want to stick the api's religously), but there is no javadoc documentation on how I can interpret what is in this byte buffer. You have to go to the GLFW site to find out more. When digging a bit further on the GLFW site I realise I need to use the below, details of this would be useful in the javadoc.

http://www.glfw.org/docs/latest/structGLFWvidmode.html#details

I saw that there is a helper function for the singlular "getVideoMode" result ByteBuffer but I have no clue how to use this with multiple video modes being returned (an array of VideoModes is meant to be returned). Should I create my own helper class for this?

To me this is quite a complicated way to just get a list of video modes!

3) Am I correct in saying that when you create a window it can be any size? It doesn't have to match the window size of a valid video mode resolution?

4) How do I set the color depth of the window I am creating? If my desktop is 24 bit but I want to create a 16 bit window how to I go about doing this?

5) I noticed animated cursors are not in the glfw api (My favourite :)), can I take it support for these will be dependant on if GLFW supports them in the future?

Thanks

abcdef


Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: spasi on November 26, 2014, 20:17:55
Quote from: abcdef on November 26, 2014, 19:08:041) Can you update the javadoc for

public static java.nio.ByteBuffer glfwGetVideoModes(long monitor,
                                    java.nio.ByteBuffer count)

Its missing the information on Count which is referenced

http://www.glfw.org/docs/latest/group__monitor.html#ga820b0ce9a5237d645ea7cbb4bd383458

Thanks, this is a bug and will be fixed.

Quote from: abcdef on November 26, 2014, 19:08:042) In this function I get a ByteBuffer back (which is a pretty weird design...but I'll go with it as I know you want to stick the api's religously), but there is no javadoc documentation on how I can interpret what is in this byte buffer. You have to go to the GLFW site to find out more. When digging a bit further on the GLFW site I realise I need to use the below, details of this would be useful in the javadoc.

http://www.glfw.org/docs/latest/structGLFWvidmode.html#details

I saw that there is a helper function for the singlular "getVideoMode" result ByteBuffer but I have no clue how to use this with multiple video modes being returned (an array of VideoModes is meant to be returned). Should I create my own helper class for this?

To me this is quite a complicated way to just get a list of video modes!

This has been asked before, the reply is here (http://forum.lwjgl.org/index.php?topic=4800.msg29275#msg29275).

You have a good point about documentation, it is not immediately obvious how to use functions that accept or return structs. I will try to improve the JavaDoc of such functions with LWJGL-specific information. For now, just remember that for any native struct you see in an API, there's a corresponding (auto-generated) Java class with helper methods (org.lwjgl.system.glfw.GLFWvidmode in this case).

Quote from: abcdef on November 26, 2014, 19:08:043) Am I correct in saying that when you create a window it can be any size? It doesn't have to match the window size of a valid video mode resolution?

Yes, if it's a desktop-mode window (NULL monitor in glfwCreateWindow). For fullscreen (non-NULL monitor), I'm sure you have to match a valid vidmode, but I haven't tried what happens if you don't.

Quote from: abcdef on November 26, 2014, 19:08:044) How do I set the color depth of the window I am creating? If my desktop is 24 bit but I want to create a 16 bit window how to I go about doing this?

See the documentation for glfwWindowHint (http://javadoc.lwjgl.org/org/lwjgl/system/glfw/GLFW.html#glfwWindowHint(int,%20int)), you need to use the <channel>_BITS hints.

Quote from: abcdef on November 26, 2014, 19:08:045) I noticed animated cursors are not in the glfw api (My favourite :)), can I take it support for these will be dependant on if GLFW supports them in the future?

There won't be an API for this, because the current API already supports cursor animation. Just create a GLFWcursor for every frame of the animation and use glfwSetCursor to switch frames in your render loop. See here (https://github.com/glfw/glfw/blob/master/tests/cursoranim.c) for an example.
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: abcdef on November 27, 2014, 09:44:03
Thanks Spasi

Is the wiki editable in github by anyone? It might be useful to add info on all the questions people are raising there
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: spasi on November 27, 2014, 11:09:42
Yes, the wiki is editable by anyone.

Sorry that I haven't been able to work on the wiki and site in the last couple of weeks, but I'm 100% occupied with development. I've been working with users to reproduce and resolve issues, while also doing heavy work on new features.

After the alpha is out I'll hopefully be able to relax and focus on documentation. I will also compile a list of FAQ that will be published on the site.
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: jmguillemette on November 28, 2014, 05:44:29
im hoping you can elaborate on GLFW.glfwGetVideoModes

im lost on how we are to translate the resulting buffer to GLFWVidmode.. is there a order to the values and we just populate them in? or is there a helper method to take in a buffer and self populate?

thanks
j.
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: jmguillemette on November 28, 2014, 06:05:54
nevermind i figured it out.
takes a bit to wrap your head around the new approach but its workable :)

here is a sample for anyone else who gets caught on this.


public static void getDisplayModes(long window){
      PointerBuffer monitorBuf = GLFW.glfwGetMonitors();
      for(int x=0;x<monitorBuf.limit();x++){
         IntBuffer buf = BufferUtils.createIntBuffer(1);
         buf.put(10);
         buf.flip();
         ByteBuffer modes = GLFW.glfwGetVideoModes(monitorBuf.get(x), buf);
         
         for(int i=0;i<modes.limit();){
            ByteBuffer vidMode = BufferUtils.createByteBuffer(GLFWvidmode.SIZEOF);
            byte[] vidModeData = new byte[GLFWvidmode.SIZEOF];
            modes.get(vidModeData);
            vidMode.put(vidModeData);      
            vidMode.flip();
            int width = GLFWvidmode.width(vidMode);
            int height = GLFWvidmode.height(vidMode);
            System.out.println(width+","+height);
            i =i+GLFWvidmode.SIZEOF;
         }
      }
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: jmguillemette on November 28, 2014, 06:09:58
Quote from: spasi on November 27, 2014, 11:09:42
Yes, the wiki is editable by anyone.

Sorry that I haven't been able to work on the wiki and site in the last couple of weeks, but I'm 100% occupied with development. I've been working with users to reproduce and resolve issues, while also doing heavy work on new features.

After the alpha is out I'll hopefully be able to relax and focus on documentation. I will also compile a list of FAQ that will be published on the site.

As i write my engine if i make snippets like this one i will gladly put them int he wiki.
you may need to give me access to do so.
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: BrickFarmer on December 02, 2014, 21:14:10
Quote from: jmguillemette on November 28, 2014, 06:05:54
nevermind i figured it out.
takes a bit to wrap your head around the new approach but its workable :)

Thanks for that!  I hope this is on topic still, but I tried the code.  So I have two monitors atttached, and both get listed.  They only give "Generic PnP Monitor" as their names, but I can identify the monitor I want using the width and height.  However, when creating the window, it still uses the primary monitor for full screen.  I'm trying to get the second monitor fullscreen...

window = glfwCreateWindow(1920, 1200, "Hello World!", secondMonitorId, NULL);

Also I've set the following hint, but not sure it is even required for fullscreen.

glfwWindowHint(GLFW_DECORATED, GL_FALSE);

Is this the correct approach for fullscreen on second monitor?

using: LWJGL 3.0.0a
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: spasi on December 02, 2014, 21:24:33
Fullscreen on secondary monitor works fine for me (Windows 8.1). What is your operating system? Could you post the complete code you're using for selecting the monitor?
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: jmguillemette on December 03, 2014, 06:02:28
Quote from: BrickFarmer on December 02, 2014, 21:14:10
Thanks for that!

Anytime! :)
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: BrickFarmer on December 03, 2014, 08:35:31
Quote from: spasi on December 02, 2014, 21:24:33
Fullscreen on secondary monitor works fine for me (Windows 8.1). What is your operating system? Could you post the complete code you're using for selecting the monitor?

Windows 7

import org.lwjgl.BufferUtils;
import org.lwjgl.PointerBuffer;
import org.lwjgl.Sys;
import org.lwjgl.opengl.*;
import org.lwjgl.system.glfw.*;

import java.nio.ByteBuffer;
import java.nio.IntBuffer;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;
import static org.lwjgl.system.glfw.GLFW.*;

public class TriangleMain {
    private long window;
    private long riftMonitorId;
    private final int riftWidth = 1920;
    private final int riftHeight = 1080;

    public boolean findRift() {
        PointerBuffer monitorBuf = GLFW.glfwGetMonitors();
        for (int x = 0; x < monitorBuf.limit(); x++) {
            IntBuffer buf = BufferUtils.createIntBuffer(1);
            buf.put(10);
            buf.flip();
            long monitorId = monitorBuf.get(x);
            ByteBuffer modes = GLFW.glfwGetVideoModes(monitorId, buf);
            System.out.println(glfwGetMonitorName(monitorId));              // EDID not exposed?
            for (int i = 0; i < modes.limit();) {
                ByteBuffer vidMode = BufferUtils.createByteBuffer(GLFWvidmode.SIZEOF);
                byte[] vidModeData = new byte[GLFWvidmode.SIZEOF];
                modes.get(vidModeData);
                vidMode.put(vidModeData);
                vidMode.flip();
                int width = GLFWvidmode.width(vidMode);
                int height = GLFWvidmode.height(vidMode);
                if (width == riftWidth && height == riftHeight) {
                    System.out.println(width + "," + height + "," + monitorId);
                    riftMonitorId = monitorId;
                    return true;
                }
                i =i+GLFWvidmode.SIZEOF;
            }
            System.out.println("-----------------");
        }
        return false;
    }

    public void execute() {
        System.out.println("Hello LWJGL " + Sys.getVersion() + "!");
        try {
            init();
            loop();
            glfwDestroyWindow(window);
        } finally {
            glfwTerminate();
        }
    }

    private void init() {
        glfwSetErrorCallback(ErrorCallback.Util.getDefault());
        if (glfwInit() != GL11.GL_TRUE) {
            throw new IllegalStateException("Unable to initialize GLFW");
        }
        glfwDefaultWindowHints();
        // glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
        // glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
        // glfwWindowHint(GLFW_DECORATED, GL_FALSE);        // not required for fullscreen?

        if (findRift()) {
            window = glfwCreateWindow(riftWidth, riftHeight, "Hello World!", riftMonitorId, NULL);
            System.out.println("found rift and using it " + riftMonitorId);
        } else {
            window = glfwCreateWindow(riftWidth, riftHeight, "Hello World!", NULL, NULL);
            System.out.println("use rift debug mode");
        }
        if (window == NULL) {
            throw new RuntimeException("Failed to create the GLFW window");
        }
        WindowCallback.set(window, new WindowCallbackAdapter() {
            @Override
            public void key(long window, int key, int scancode, int action, int mods) {
                if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
                    glfwSetWindowShouldClose(window, GL_TRUE);
            }
        });
        // not relevant to fullscreen mode
        // ByteBuffer vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
        // glfwSetWindowPos(
        // window,
        // (GLFWvidmode.width(vidmode) - WIDTH) / 2,
        // (GLFWvidmode.height(vidmode) - HEIGHT) / 2
        // );
        glfwMakeContextCurrent(window);
        glfwSwapInterval(1);
        glfwShowWindow(window);
    }

    private void loop() {
        GLContext.createFromCurrent();
        glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
        while (glfwWindowShouldClose(window) == GL_FALSE) {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    }

    public static void main(String[] args) {
        new TriangleMain().execute();
    }
}
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: BrickFarmer on December 03, 2014, 08:53:06
The good news is that I have just tested this on OSX 10.8.5 and it works as expected :)
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: spasi on December 03, 2014, 10:18:12
First of all, your monitor/vidmode iteration code is unnecessarily complicated and wrong. This is the correct way:

PointerBuffer monitors = glfwGetMonitors();
IntBuffer modeCount = BufferUtils.createIntBuffer(1);
for ( int i = 0; i < monitors.limit(); i++ ) {
long monitor = monitors.get(i);

ByteBuffer modes = glfwGetVideoModes(monitor, modeCount);
for ( int j = 0; j < modeCount.get(0); j++ ) {
modes.position(j * GLFWvidmode.SIZEOF);

int width = GLFWvidmode.width(modes);
int height = GLFWvidmode.height(modes);
// ...
}
}

Since you're trying to identify a Rift, I don't think this can reliably be done using only the video modes (more than one monitor may support 1920x1080). Please see this issue (https://github.com/glfw/glfw/commit/16eb97dbc319aa904d901086b375549f98593713). It has not been resolved yet, but some functionality is already supported. You can use GLFWWin32.glfwGetWin32Monitor(), see if that provides enough information.
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: BrickFarmer on December 03, 2014, 11:03:04
Thanks! silly me, that mode was supported by both. 

Quote from: spasi on December 03, 2014, 10:18:12
You can use GLFWWin32.glfwGetWin32Monitor(), see if that provides enough information.

That call only gives me DISPLAY1 DISPLAY2.  The equivalent call on OSX just seems to return the cgDirectDisplayID?  I think what I probably need to access is the manufacturer, but it looks like EDID has been replaced by a new standard anyway, displayID.  So I guess I'm going to need a popup for now for selection. No problem.

The good news is that fullscreen is working for me now on both platforms :)
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: BrickFarmer on December 13, 2014, 15:18:09
Is it expected that activating full screen on my second monitor would trigger the mouse being moved onto that screen?
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: spasi on December 13, 2014, 20:01:43
This is not specified in GLFW, but it isn't surprising that it happens. It's probably standard behavior of the operating system.
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: BrickFarmer on December 15, 2014, 16:45:50
I mentioned that going full-screen seems to steal the mouse cursor, well it is a bit stranger than just that.  If I enable the cursor using this:

glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL)

Then the cursor location is moved to the center of the Y axis, however it is moved to the center of the x-axis with double the Rift screen width.

My screens are extended mode OSX 10.8.5 with my Rift to the left of my Laptop.

I have two examples to demonstrate this.

1. start and move mouse right.  It appears on the Rift from the left edge of the screen, leaves the right edge and arrives on the left edge of the laptop.

2. start and move mouse left. It appears on the Rift from the right edge of the screen, and stops on the left edge of the Rift.  Moving it right it then traverses the Rift display twice before arriving on the left edge of the laptop.

So its almost as though it thinks there are two rift displays to the left of my monitor and centers the cursor between these two displays.

I will try and get this running on windows tomorrow and compare behavior.
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: BrickFarmer on December 18, 2014, 11:20:38
Just to confirm that I'm seeing the same behavior on my win7 box.

In addition I'm seeing some strange fps values.  On my 4 yr old mac I get ~120fps for my single textured quad.  On my windows box I see 75fps.  I guessing that is probably due to vsync.  Is the a way to change that behavior, or is it graphics driver specific.  I dont mine the vsync, apart from the fact that over time my fps is sometimes dropping to 68fps, and for a while now its running at 63fps.  Possibly some modern windows thing I dont know about for power save on the GPU or CPU?

code linked in sig.
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: spasi on December 18, 2014, 11:25:24
Vsync is controlled with glfwSwapInterval().

Not sure about the fps drop, you'd have to do some profiling (GC? something in the Oculus SDK?). Does the JOGL version exhibit the same behavior?
Title: Re: LWJGL3 - Displays and Windows (Few questions)
Post by: BrickFarmer on December 18, 2014, 12:06:28
Quote from: spasi on December 18, 2014, 11:25:24
Vsync is controlled with glfwSwapInterval().

Not sure about the fps drop, you'd have to do some profiling (GC? something in the Oculus SDK?). Does the JOGL version exhibit the same behavior?

I think the drop is too large and continuous to be GC/SDK related.  And my JOGL version only runs on OSX so far, but I will feed back when I have tested that. 

the swapInterval didnt seem to make any difference, but I found a way to turn vsync off (was set to app specified) in the nvidia control panel. ~1500fps  8)

Probably its some power save function somewhere, since even with vsync off I'm seeing fluctuations of up to 300fps.

Any idea on the mouse behavior?