Environment mapping

Hi,

I would like to do some environment mapping on a mesh. I found articles speaking about it but I’m lost right now.
Bascily, I want to use 1 2D textures to make reflexion (metal/glass material feeling). There is functions to generate Texture Coords but I don’t really know whish on to use.

  • GL_SPHERE_MAP seems to don’t seem to work well but and it don’t rotate with the view
  • GL_EYE_LINEAR seems to be the one to be used but I don’t manage to work with it

(It is my 3D engine, I’m making it for learning propose)



GL11.glPushMatrix();
GL11.glMultMatrix(view.getFloatBuffer());  

      GL11.glEnable(GL11.GL_BLEND);
      GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
      GL11.glDisable(GL11.GL_COLOR_MATERIAL);
      GL11.glColor4f(1, 1, 1,environmentMapping);
      GL11.glEnable(GL11.GL_TEXTURE_2D);
      mesh.getWorld().getEnvironmentMapping().bind();
      
      GL11.glTexGeni(GL11.GL_S, GL11.GL_TEXTURE_GEN_MODE, GL11.GL_SPHERE_MAP);
      GL11.glTexGeni(GL11.GL_T, GL11.GL_TEXTURE_GEN_MODE, GL11.GL_SPHERE_MAP);
      GL11.glEnable(GL11.GL_TEXTURE_GEN_S);
      GL11.glEnable(GL11.GL_TEXTURE_GEN_T);
      
        GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
        GL11.glVertexPointer(3, 0, model.getVertices());
        
        GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
        GL11.glNormalPointer(3,model.getNormales());
    
        GL11.glDrawElements(GL11.GL_TRIANGLES, model.getIndexes());
   
        GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY);
        GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);

      GL11.glDisable(GL11.GL_TEXTURE_GEN_S);
      GL11.glDisable(GL11.GL_TEXTURE_GEN_T);
          
GL11.glPopMatrix();


I found an example using GL_SPHERE_MAP in LWJGL (Nehe lesson 26). It was using glBegin / glEnd.
So I remove glDrawElements for glBegin / glEnd then GL_SPHERE_MAP works…

I don’t get why it doesn’t work with glDrawElements ???

Some more elements :

  • tested on another machine same result (so it is not a driver problem)
  • nothing in the opengl reference for GL_SPHERE_MAP… can’t find anything on this problem right now :’(

No one is using environment map ?

hehe, this is probably gunna end up like teh generator thing b4.

you are gunna be like “ahh I was bored of waiting, so I jsut figured it out :/” lol

What exactly is the problem, i.e. what is the visual outcome of your code? I’m using environment mapping in a very similar way, your code looks fine to me at first glance…does the call to bind() binds the texture?

Edit: Looking a bit closer…are you sure that this line:


GL11.glNormalPointer(3,model.getNormales());

is correct? A stride of 3 looks suspicious to me. Try 0 or 12 instead, if your normals are stored one after the other without gaps.

… no… no I could’nt…
DOH !

I was pretty sure that was a stupid error… Thanks a lot Egon :wink:

Ok, it works with SPHERE_MAP. Now I’m going for REFLECTION_MAP with CubeMap (first time I use cube map ;D).
And of course, I have a problem :persecutioncomplex:

If I don’t enable GL_TEXTURE_CUBE_MAP, I got (it seems allright to me) :

But when I enable GL_TEXTURE_CUBE_MAP, the teapot is all white.


      GL11.glEnable(GL11.GL_BLEND);
      GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
      //GL11.glDisable(GL11.GL_COLOR_MATERIAL);
      GL11.glColor4f(1, 1, 1,environmentMapping);
      //GL11.glEnable(GL11.GL_TEXTURE_2D);
      
      GL11.glMatrixMode(GL11.GL_TEXTURE);
      GL11.glPushMatrix();
      GL11.glMultMatrix(camera.getTrans().getFloatBuffer());
      
      GL11.glEnable(GL13.GL_TEXTURE_CUBE_MAP);
            
      GL11.glEnable(GL11.GL_NORMALIZE);
      
      GL11.glEnable(GL11.GL_TEXTURE_GEN_S);
      GL11.glEnable(GL11.GL_TEXTURE_GEN_T);
      GL11.glEnable(GL11.GL_TEXTURE_GEN_R);
      
      GL11.glTexGeni(GL11.GL_S, GL11.GL_TEXTURE_GEN_MODE,GL13.GL_REFLECTION_MAP);
      GL11.glTexGeni(GL11.GL_T, GL11.GL_TEXTURE_GEN_MODE,GL13.GL_REFLECTION_MAP);
      GL11.glTexGeni(GL11.GL_R, GL11.GL_TEXTURE_GEN_MODE,GL13.GL_REFLECTION_MAP);
      
      mesh.pass(false,true);
           
      GL11.glDisable(GL11.GL_TEXTURE_GEN_S);
      GL11.glDisable(GL11.GL_TEXTURE_GEN_T);
      GL11.glDisable(GL11.GL_TEXTURE_GEN_R);
      
      GL11.glDisable(GL11.GL_NORMALIZE);
      
      GL11.glDisable(GL13.GL_TEXTURE_CUBE_MAP);
      
      GL11.glPopMatrix();
      GL11.glMatrixMode(GL11.GL_MODELVIEW);

This code seems good for me, so it must be an error in setting up the cube map.


public void create()
    {
      GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
        
      IntBuffer scratch = BufferUtils.createIntBuffer(1);
      GL11.glGenTextures(scratch);
    
      int error = GL11.glGetError();
      if( error != GL11.GL_NO_ERROR)
      {
        System.out.println("Texture.create : error OpenGL ("+error+")");
      }
      
      handle = scratch.get(0);
      
      System.out.println("Creating cube map : "+handle);
    }

public void bind()
    {
        GL11.glBindTexture(GL13.GL_TEXTURE_CUBE_MAP, handle);
        lastBind = handle;
        
      System.out.println("Binding cube map : "+lastBind);
    }

public void setImages(BufferedImage positiveX,BufferedImage negativeX,
                          BufferedImage positiveY,BufferedImage negativeY,
                          BufferedImage positiveZ,BufferedImage negativeZ)
    {
      bind();
        
      GL11.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_REPLACE);
      
      setImage(GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_X,positiveX);
      setImage(GL13.GL_TEXTURE_CUBE_MAP_NEGATIVE_X,negativeX);
      setImage(GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_Y,positiveY);
      setImage(GL13.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,negativeY);
      setImage(GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_Z,positiveZ);
      setImage(GL13.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,negativeZ);
    }

public void setImage(int place, int width, int height, int type, IntBuffer imageData)
    {    
      System.out.println(lastBind+"Setting image to "+place+" (type :"+type+")");
        
      GL11.glTexImage2D(place, 0, GL11.GL_RGBA, width, height, 
                        0, type, GL11.GL_UNSIGNED_BYTE, imageData);
 
      int error = GL11.glGetError();
      if( error != GL11.GL_NO_ERROR)
      {
        System.out.println("Texture.setImage : error OpenGL ("+error+")");
      }
    }

public void setImage(int place,BufferedImage img)
    {
      // System.out.println("IMAGE : opaque("+img.getTransparency()+") type("+img.getType()+")");
        
      if(img.getTransparency() == Transparency.OPAQUE)
      {
        if ((img.getType() == BufferedImage.TYPE_BYTE_BINARY)||(img.getType() == BufferedImage.TYPE_BYTE_INDEXED))
        {
          BufferedImage img2 = new BufferedImage(img.getWidth(),img.getHeight(),BufferedImage.TYPE_3BYTE_BGR);
          Graphics g = img2.getGraphics();
          g.drawImage(img, 0, 0, null);
          g.dispose();
          setImage(place,img2);
        }
        else
        {
          ByteBuffer imageData = ByteBuffer.allocateDirect(3 * img.getWidth() * img.getHeight());
          byte data[] = (byte[]) img.getRaster().getDataElements(0, 0, img.getWidth(), img.getHeight(), null);
          imageData.put(data);
          imageData.flip();
        
          setImage(place,img.getWidth(),img.getHeight(),RGB,imageData);
        }
      }
      else
      {
        if ((img.getType() == BufferedImage.TYPE_BYTE_BINARY)||(img.getType() == BufferedImage.TYPE_BYTE_INDEXED))
        {
          BufferedImage img2 = new BufferedImage(img.getWidth(),img.getHeight(),BufferedImage.TYPE_INT_ARGB);
          Graphics g = img2.getGraphics();
          g.drawImage(img, 0, 0, null);
          g.dispose();
          setImage(place,img2);
        }
        else if (img.getType() == BufferedImage.TYPE_INT_ARGB )
        {
          IntBuffer imageData = Util.IntBuffer(img.getWidth() * img.getHeight());
          int data[] = (int[]) img.getRaster().getDataElements(0, 0, img.getWidth(), img.getHeight(), null);
          imageData.put(data);
          imageData.flip();
        
          setImage(place,img.getWidth(),img.getHeight(),RGBA,imageData);
        }
        else
        {
          ByteBuffer imageData = ByteBuffer.allocateDirect(4 * img.getWidth() * img.getHeight());
          byte data[] = (byte[]) img.getRaster().getDataElements(0, 0, img.getWidth(), img.getHeight(), null);
          imageData.put(data);
          imageData.flip();
        
          setImage(place,img.getWidth(),img.getHeight(),RGBA,imageData);
        }
      }
    }

And it give me in the console :

Creating cube map : 8
Binding cube map : 8
8Setting image to 34069 (type :6407)
8Setting image to 34070 (type :6407)
8Setting image to 34071 (type :6407)
8Setting image to 34072 (type :6407)
8Setting image to 34073 (type :6407)
8Setting image to 34074 (type :6407)

So it seems good too ??? ??? ???
Any advices to how to debug that ?

Sorry…

I miss a GL_TEXTURE_2D in GL11.glTexParameteri(GL13.GL_TEXTURE_CUBE_MAP, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); when I have copy&past…

Still have to make correction of my texture orientation and it is done :wink: