LWJGL 3: loading HDR textures with StbImage in LWJGL 3?

Hey everyone, I’ve recently been trying out the STBImage bindings so I can take a HDR cubemap and map it to a cube. I’ve got the cube working, but the cubemap is picking up the wrong texture. With the int uniform location Sampler2D I cant switch textures but only to the terrain texture and object textures I have running elsewhere in the engine.

I wrote a whole post showing my process over on stack overflow. You are more welcome to check it out, but other wise here it is.

  1. My loader class holds all my loadTexture methods and I’m using an int method that stores the texture ID, currently the method looks like this:

     [quote]public int loadCubeMap(String textureFile) throws IOException {
     
      int texID = glGenTextures();
      glBindTexture(GL_TEXTURE_2D, texID);
      
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      
      ByteBuffer imageBuffer;
      IntBuffer w = BufferUtils.createIntBuffer(1);
      IntBuffer h = BufferUtils.createIntBuffer(1);
      IntBuffer comp = BufferUtils.createIntBuffer(1);
      ByteBuffer image;
      
      imageBuffer = IOUtil.ioResourceToByteBuffer(textureFile, 8 * 1024);
      
      if (!stbi_info_from_memory(imageBuffer, w, h, comp))
          throw new IOException("Failed to read image information: " + stbi_failure_reason());
      
      image = stbi_load_from_memory(imageBuffer, w, h, comp, 3);
      
      if (image == null)
          throw new IOException("Failed to load image: " + stbi_failure_reason());
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, w.get(0), h.get(0), 0, GL_RGB, GL_UNSIGNED_BYTE, image);
      
      stbi_image_free(image);
      
      return texID; }
    

[/quote]
Which I got from this demo lwjgl3-demos [here][1] with an example of an environment map using an HDR texture and using the STBImage java bindings. The method also uses a class in my utils package called IOUtil, which is from the example and works in the sample. (I also tried the HDR file from the learnOpengl tutorials which works fine with the example, but not with my own code);

I have a skybox shader and a skybox renderer which all seem to work well. The skybox renderer is written as below:

I am using a vertex and fragment shader which came from learnOpengl’s PBR tutorial.

The shader code works as well as it does, from the help of Thinmatrix’s tutorials.

I initialize the loadCubeMap function in the skybox renderer along with the file name, then initialize the skybox renderer in the master renderer class.

By the time I run it, I get no errors about the HDR texture and the loader, so I assume its accepting it. Most of it works.

I get a box and a texture, but the texture is binding to the wrong texture. Its binding the albedo ground texture that I use in my terrain, which I suppose is the default condition when things are not binding correctly, just guessing.

Edit: I just realized that the HDR map is used for a sphere, and I’m rendering a cube. (lol) Correction: that tutorial uses a cubemap :slight_smile:

So there, I can’t seem to figure out the problem. I will give it another whirl and see what I can improve on. Any help would be much appreciated.

You’re creating and sampling a 2D texture, but you’re binding a GL_TEXTURE_CUBE_MAP when rendering. Are you sure no OpenGL errors are raised? Try creating a debug context and registering a debug callback to make sure.

I’m actually roughly new to debugging, especially when it comes to code. But I found this link, so I’m going to try and wrap my head around it. https://github.com/LWJGL/lwjgl3-wiki/wiki/2.5.-Troubleshooting

I don’t quite understand the concept of contexts just yet, let alone debug contexts.

Would this be a good start?

[quote]// before context creation
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);

// after context creation
glfwMakeContextCurrent(window);
GL.createCapabilities();
Callback debugProc = GLUtil.setupDebugMessageCallback(); // may return null if the debug mode is not available

// cleanup
if ( debugProc != null )
debugProc.free();
[/quote]

[quote=“cybrmynd,post:3,topic:59176”]
Yes, that’s the easiest solution on Windows & Linux. If you’re on macOS, you’ll have to check for OpenGL errors manually (glGetError()).

So I placed the code into the display manager of my program and this spat out:

[quote][LWJGL] OpenGL debug message
ID: 0x2
Source: API
Type: PERFORMANCE
Severity: MEDIUM
Message: API_ID_RECOMPILE_FRAGMENT_SHADER performance warning has been generated. Fragment shader recompiled due to state change.
[LWJGL] OpenGL debug message
ID: 0x2
Source: API
Type: PERFORMANCE
Severity: MEDIUM
Message: API_ID_RECOMPILE_FRAGMENT_SHADER performance warning has been generated. Fragment shader recompiled due to state change.
[/quote]
I can see how this could be handy, though still confusing. Any tips you may suggest? Thanks a lot for the suggestion.

Have a look at this to see how to do cube maps.

https://learnopengl.com/#!Advanced-OpenGL/Cubemaps