Skybox remains white

I cannot believe it, I used Skybox like 20 times at least and now I cannot get it right:



  private void buildSkyBox() {
    skybox = new Skybox("skybox", 10, 10, 10);
    skybox.setTexture(Skybox.NORTH, TaskQueueUtil.loadImage(getClass().getClassLoader().getResource(
        game.getName().toLowerCase() + "/content3d/skybox/1.dds"), false));
    skybox.setTexture(Skybox.WEST, TaskQueueUtil.loadImage(getClass().getClassLoader().getResource(
        game.getName().toLowerCase() + "/content3d/skybox/4.dds"), false));
    skybox.setTexture(Skybox.SOUTH, TaskQueueUtil.loadImage(getClass().getClassLoader().getResource(
        game.getName().toLowerCase() + "/content3d/skybox/3.dds"), false));
    skybox.setTexture(Skybox.EAST, TaskQueueUtil.loadImage(getClass().getClassLoader().getResource(
        game.getName().toLowerCase() + "/content3d/skybox/2.dds"), false));
    skybox.setTexture(Skybox.UP, TaskQueueUtil.loadImage(getClass().getClassLoader().getResource(
        game.getName().toLowerCase() + "/content3d/skybox/6.dds"), false));
    skybox.setTexture(Skybox.DOWN, TaskQueueUtil.loadImage(getClass().getClassLoader().getResource(
        game.getName().toLowerCase() + "/content3d/skybox/5.dds"), false));

    GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Object>() {

      public Object call() throws Exception {
        skybox.preloadTextures();
        return null;
      } // call
    }); // update
   
    skybox.updateRenderState();
    modelRootNode.attachChild(skybox);
    modelRootNode.updateRenderState();
  } // buildSkyBox



The Skybox is where I want it to be and behaves perfectly like a good Skybox should, except it won't show my textures and just remains white.

I don't have a Light in my scene, everything is


bla.setLightCombineMode(LightState.OFF);



Excerpt from TaskQueueUtil:


  public static Texture loadImage(final URL path, final boolean flipped) {
    Future<Texture> future = GameTaskQueueManager.getManager().update(new Callable<Texture>() {

      public Texture call() throws Exception {
        Texture t = TextureManager.loadTexture(path, flipped);
        t.setFilter(Texture.FM_LINEAR);
        t.setMipmapState(Texture.MM_LINEAR_LINEAR);
        t.setAnisoLevel(1.0f);
        return t;
      } // call()
    }); // Callable

    try {
      return future.get();
    } catch(InterruptedException e) {
      e.printStackTrace();
    } catch(ExecutionException e) {
      e.printStackTrace();
    } // catch
    return null; // should not happen
  } // loadImage



I tried skybox.preloadTextures();
I tried other textures that are correctly loaded in other parts of the scene.
I searched the forums for hours now.
I'm at the end of my whits.

Please help, so long,
Andy

it looks like your loadImage() Method somehow returns null, debug and check why :slight_smile:

Thanks for the reply.



Unfortunately thats not it. The texture is loaded and the containing image object has the correct size, type, mipmaplevels, …   :(



I'm glad my comment is still valid: //should not happen



still white.


I would've thought that having no light wouldn't illuminate the skybox, but now I remember that it doesn't affect that.


  1. Do you have a fogstate? Make sure you don't have your end threshold too low.
  2. Are you sure you set your skybox up to have proper spacing?
  3. (Dumb) Are your images white?
  4. Try locking bounds and meshes… skybox.lockBounds(); skybox.lockMeshes();



    Here's mine…


    public static Skybox makeSkybox()
    {
        Skybox skybox = new Skybox("Skybox", 10, 10, 10);
       
        Texture north = TextureManager.loadTexture(FyrestoneClient.class.getClassLoader().getResource(textureDir + "north.jpg"));
        Texture south = TextureManager.loadTexture(FyrestoneClient.class.getClassLoader().getResource(textureDir + "south.jpg"));
        Texture east = TextureManager.loadTexture(FyrestoneClient.class.getClassLoader().getResource(textureDir + "east.jpg"));
        Texture west = TextureManager.loadTexture(FyrestoneClient.class.getClassLoader().getResource(textureDir + "west.jpg"));
        Texture up = TextureManager.loadTexture(FyrestoneClient.class.getClassLoader().getResource(textureDir + "updown.jpg"));
        Texture down = TextureManager.loadTexture(FyrestoneClient.class.getClassLoader().getResource(textureDir + "updown.jpg"));
       
        skybox.setTexture(Skybox.NORTH, north);
        skybox.setTexture(Skybox.SOUTH, south);
        skybox.setTexture(Skybox.EAST, east);
        skybox.setTexture(Skybox.WEST, west);
        skybox.setTexture(Skybox.UP, up);
        skybox.setTexture(Skybox.DOWN, up);
       
        skybox.lockBounds();
        skybox.lockMeshes();
       
        return skybox;
    }

  1. no fog state
  2. what do you mean with proper spacing?
  3. no  :wink:
  4. didn't help



    thank you so far  :slight_smile:

i just now saw, that you didnt call get() on the callable, which means it can get executed at some later point and most likely updateRenderstate is called before the textures are loaded…



try to add a modelRootNode.updateRenderstate() inside the callable, just after preloading the textures.



or add a .get() to make sure the call is executed right now.

thank you for the answer and you are right that I should call get. Unfortunately the skybox is still white  :expressionless:



The skybox- related code is currently:


  private void buildSkyBox() {
    skybox = new Skybox("skybox", 10, 10, 10);
    skybox.setTexture(Skybox.NORTH, TaskQueueUtil.loadImage(getClass().getClassLoader().getResource(
        game.getName().toLowerCase() + "/content3d/skybox/1.dds"), false));
    skybox.setTexture(Skybox.WEST, TaskQueueUtil.loadImage(getClass().getClassLoader().getResource(
        game.getName().toLowerCase() + "/content3d/skybox/4.dds"), false));
    skybox.setTexture(Skybox.SOUTH, TaskQueueUtil.loadImage(getClass().getClassLoader().getResource(
        game.getName().toLowerCase() + "/content3d/skybox/3.dds"), false));
    skybox.setTexture(Skybox.EAST, TaskQueueUtil.loadImage(getClass().getClassLoader().getResource(
        game.getName().toLowerCase() + "/content3d/skybox/2.dds"), false));
    skybox.setTexture(Skybox.UP, TaskQueueUtil.loadImage(getClass().getClassLoader().getResource(
        game.getName().toLowerCase() + "/content3d/skybox/6.dds"), false));
    skybox.setTexture(Skybox.DOWN, TaskQueueUtil.loadImage(getClass().getClassLoader().getResource(
        game.getName().toLowerCase() + "/content3d/skybox/5.dds"), false));

    Future<Object> future =  GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Object>() {

      public Object call() throws Exception {
        skybox.preloadTextures();
        skybox.lockBounds();
        skybox.lockMeshes();
        return null;
      } // call
    }); // update

    try {
      future.get();
    } catch(InterruptedException e) {
      e.printStackTrace();
    } catch(ExecutionException e) {
      e.printStackTrace();
    }
    modelRootNode.attachChild(skybox);
    modelRootNode.updateRenderState();
    logger.debug("created Skybox");
  } // buildSkyBox



The modelRootNode is created and added to a RenderPass like that:


    modelPass = new RenderPass();
    modelRootNode = new Node();
    modelPass.add(modelRootNode);
    modelPass.setEnabled(true);



All the other children of the modelRootNode (a big model) are rendered correctly with texture. No unusual in the (FINEST) log.

skybox still white.

Try taking out the game.getName() thing…?

Trussell said:

Try taking out the game.getName() thing...?


the correct texture is loaded (width, height, mipmaps, ...), so the path cant be it.

I'm not familiar with the Future<Object> class… what is it?

When you pass a Callable<Object> to the GameTaskQueueManager it is executed some time in the future and you won't be able to retrieve something (e.g. a return value).



But when you enqueue  the callable you can get a reference from the GTQM that is a Future<Object> object. With future.get() you make the current thread wait for the OpenGL Thread to execute the Callable and future.get() returns the Generic parameter, in this case an Object object but it can be any class.



so: future lets the current thread wait and you can retrieve a return value from the callable



I hope that is about right :wink:

jaw drops I haven't learned about threading at all, yet :slight_smile:

nothing new on the skybox issue?  :expressionless:

I have the same issue here, if i use .dds files the skybox is white. Other image formats work fine.


Only a certain variation of DDS is supported… DXT1-3-5 compressed, 2D (non-cubemap), DirectX9 format. Use ATI Compressonator to make compatible DDS images.

thank you for your replies.



I use the same .DDS skybox textures in another application and it works fine …  :expressionless: (copy and pasted it)

found it,



The problem is not the .DDS texture but the mipmapping of the texture.



The following setting will make the dds texture on the skybox be white:

t.setMipmapState(Texture.MM_LINEAR_LINEAR);



so long,
Andy