Creating a GLFW Window

Started by Daxter, September 22, 2018, 05:26:17

Previous topic - Next topic

Daxter

I am taking a Computer Science class and a preliminary assignment I have in the course is to run an application called "Basic" to verify that I have Java and LWJGL set up correctly for the course. All of the needed files and code were provided and the paths were checked by the instructor to be right. When "Basic" runs, a window with a red background is supposed to be drawn and the console is to print the version of OpenGL I have. I am doing all of this from Command Prompt.

The problem is that this does not happen when I run the application. Instead I get a message that says "Failed to create the GLFW window". The files and path were tried on my instructor's Mac device and the window was drawn. My files and path are adapted for a Windows device according to my instructor. This instructor says that the code is not a problem but three lines of code were pointed out as errors.

So I was wondering if anyone has ever had an issue getting a GLFW Window to appear with the path and code being correct? If not, can anyone take a look at code to see what the problem could be? The instructor has not been responding to my emails and with under a week to finish this so I can proceed with four assignments and test review, I am very stressed out about this. Looking online only brought up code examples for this issue but in the syllabus for this course, this site was listed as a good resource.

Below is the code from my Basic.Java file; the errors shown in Command Prompt were on lines 116, 71, and 321 respectively. An exception is being thrown due to a value being set to null. Since I am just starting out in the course and was told the code was not an issue, I am not sure if this is the main issue or not or even how to fix this:

/*  this class should be extended to provide
    an event-driven, graphical application

   The extending class should have its own constructor
   where things can be set up before the window is prepared,
   with a call to super( window title, width in pixels, height in pixels,
                          nanoseconds in a step )

   Override these methods:

   init:  do things to be done once at the begining after the window
          is ready to go

   display:  draw the game world

   processInputs:  scan InputInfo queue and process all waiting input events
                   with appropriate changes to game objects
    
   update:  advance the simulation one full time step

*/

//  LWJGL release = 3.0.0 build 90
//  (earlier LWJGL3 download failed---Sys class seems to have disappeared,
//   but the code wasn't using it, anyway;  a few other little changes)

import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
 
import java.nio.ByteBuffer;
 
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL21.*;
import static org.lwjgl.opengl.GL33.*;
import static org.lwjgl.system.MemoryUtil.*;
 
public class Basic{
 
  // We need to strongly reference callback instances.
  private GLFWKeyCallback keyCallback;
  private GLFWCursorPosCallback cursorPosCallback;
  private GLFWMouseButtonCallback mouseButtonCallback;
 
  // The window handle
  private long window;

  private String title;
  private int width, height; // in pixel units
  private int stepNumber;
  private long timeStep;   // amount of time in a step in nanoseconds

  private long startTime;
 
  private int mouseX, mouseY;  // current mouse cursor position

  // create window given title, size in pixels, step time in nanoseconds
  public Basic( String windowLabel, int pw, int ph, long timeInNanos )
  {
    title = windowLabel;
    width = pw;  height = ph;
    stepNumber = 0;

    timeStep = timeInNanos;
    startTime = System.nanoTime();
  }

  public void start() {
    try{
      setup();   // get window ready to go
      loop();
 
      // Release window and window callbacks
      glfwFreeCallbacks(window);
      glfwDestroyWindow(window);

    } finally {
      // Terminate GLFW
      glfwTerminate();
    }
  }// start
 
  private void setup()
  {
    // Initialize GLFW. Most GLFW functions will not work before doing this.
    if( !glfwInit() )
      throw new IllegalStateException("Unable to initialize GLFW");
 
// Note:  these 4 hints seem necessary (at least on my Mac) to
//        get OpenGL version 3.3, but may cause problems in Windows
//--------------------------------------------------
    // Configure the window, choosing OpenGL version
    // and the core profile and forward compatibility
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
//--------------------------------------------------

    glfwWindowHint(GLFW_VISIBLE, 0 ); // the window will stay hidden after creation
    glfwWindowHint(GLFW_RESIZABLE, 0 ); // the window will not be resizable

    // Get the usable resolution of the primary monitor
    /*  could use this to detect full screen size on any monitor
// doesn't work!
    GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
    width = GLFWVidMode.width(vidmode);
    height = GLFWVidMode.height(vidmode);
System.out.println("width = " + width + " height = " + height );
    */

    // Create the window
    window = glfwCreateWindow(width, height, title, NULL, NULL);
    if( window == NULL )
      throw new RuntimeException("Failed to create the GLFW window");

    // Set up a key callback. 
    // It will be called every time a key is pressed, repeated or released.
    glfwSetKeyCallback(window, 
      keyCallback = new GLFWKeyCallback() 
      {
        public void invoke(long window, int key, 
                           int scancode, int action, 
                           int mods)
        {
          // whenever a key is pressed, the callback function
          // puts it in the InputInfo queue for processing later in an app
          InputInfo.add( new InputInfo( 'k', key, action, mods ) );
        }
      }
    );

    glfwSetCursorPosCallback( window,
       cursorPosCallback = new GLFWCursorPosCallback()
       {
         public void invoke(long window, double xpos, double ypos )
         {
           // whenever cursor moves, add input info
           InputInfo.add( new InputInfo( 'm', (int) Math.round(xpos),
                                              (int) Math.round(ypos) ) );
         }
       }
     );
 
    glfwSetMouseButtonCallback( window,
       mouseButtonCallback = new GLFWMouseButtonCallback()
       {
         public void invoke(long window, int button, int action, int mods )
         {
           // whenever mouse button is pressed, released, or repeated, make input info
           InputInfo.add( new InputInfo( 'b', button, action, mods ) );
         }
       }
    );

    glfwSetWindowPos( window, 0, 50 );
 
    // Make the OpenGL context current
    glfwMakeContextCurrent(window);

    // Enable v-sync
    glfwSwapInterval(1);

    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL );

    // Make the window visible
    glfwShowWindow(window);

  }
 
  private final static int NUMDELAYSPERYIELD = 5;  // hope not important

  private void loop()
  {
    // This line is critical for LWJGL's interoperation with GLFW's
    // OpenGL context, or any context that is managed externally.
    // LWJGL detects the context that is current in the current thread,
    // creates the ContextCapabilities instance and makes the OpenGL
    // bindings available for use.
//    GLContext.createFromCurrent();

    GL.createCapabilities();
 
    // show version information
    System.out.println("OpenGL vendor: " + glGetString( GL_RENDERER ) );
    System.out.println("OpenGL version: " + glGetString( GL_VERSION ) );
    System.out.println("GLSL version: " + 
                         glGetString( GL20.GL_SHADING_LANGUAGE_VERSION ) );

    init();

    // Run the rendering loop until the window wants to close
    long prevTime = System.nanoTime();
    long overTime = 0L;

    int numDelays = 0;

    while( ! glfwWindowShouldClose(window) )
    {
      stepNumber++;

      display();
      processInputs();
      update();

      long currentTime = System.nanoTime();

      // figure time spent on this step already in nanoseconds
      long elapsedTime = currentTime - prevTime;

      long sleepTime = timeStep - elapsedTime - overTime;

      if( sleepTime > 0 )
      {// have some time to sleep
        try{
          Thread.sleep( sleepTime/1000000L ); // sleep this many milliseconds
        }
        catch(InterruptedException ie)
        {}
        prevTime = System.nanoTime();  // will be the new before step time
        // figure how much too long it took with overhead from sleeping
        overTime = prevTime - currentTime - sleepTime;
      }
      else
      {// step took longer than timeStep
        overTime = 0L;
        prevTime = System.nanoTime();
        numDelays++;

        if( numDelays >= NUMDELAYSPERYIELD )
        {// give another thread a chance
          Thread.yield();
          numDelays = 0;
        }
      }
      
      glfwSwapBuffers(window); // swap the color buffers
 
      // Poll for window events. The key callback above will only be
      // invoked during this call.
      glfwPollEvents();
    }
  }
 
  // ---------------------- methods that can be called in app  -------

  public int getStepNumber()
  {
    return stepNumber;
  }

  // return time from start of application
  // in milliseconds
  public long getTime()
  {
    return (System.nanoTime() - startTime) / 1000000L;
  }

  public double getTimeStep()
  {
    return timeStep/1e9;  //convert from nanoseconds to seconds
  }

  public void restartStepNumbering()
  {
    stepNumber = 0;
  }

  public int getMouseX()
  {
    return mouseX;
  }

  public int getMouseY()
  {
    return mouseY;
  }

  public int getPixelWidth()
  {
    return width;
  }

  public int getPixelHeight()
  {
    return height;
  }

  // ---------------------- methods that can and should be overridden -------

  protected void init()
  {
    // Set the clear color once and for all
    glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
  }

  protected void processInputs()
  {
    while( InputInfo.size() > 0 )
    {// process next input info
      InputInfo info = InputInfo.get();
      System.out.println( info );
    }
    
  }

  protected void update() {
  }

  protected void display() {
    // clear the framebuffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    System.out.println("Step " + getStepNumber() );
  }

  public static void main(String[] args)
  {
    Basic t = new Basic( "Basic App (should be extended)", 800, 600, 33333333L );
    t.start();
  }
 
}


Any help or resources that can be provided other than "ask my instructor", "look into it online", or "struggle through it" would be very helpful. I can also provide the code for the Basic.save file if needed.

KaiHH

The most likely reason is that your graphics driver and/or card does not support the requested OpenGL 3.3 Core version. Try commenting out the lines glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); (the syntax highlighting in the code listing indicates that this is the case, but it isn't) and check whether it works this way. The code is not using any OpenGL 3.3 specific calls, so if there is no other issue, it should work this way. If that worked and at some point the tutor is indeed using any OpenGL >= 3.3 functions you either have to get the latest graphics card driver version and if that does not help, you have to simply get a newer card.
Which exact card (or Intel Integrated Graphics device) do you use btw.? You can check online which OpenGL version is supported by that card/device.

Daxter

Thanks for the help! That did work. The drivers I currently have do not support OpenGL 3.3 it seems. I will try to update the drivers. My current device is the Intel(R) Q965/Q963 Express Chipset Family. So I will check to make sure that device is supported by OpenGL 3.3.