Stuck - newbies & textures

Okay . . . I’ve done as much research as I can, looked at a bunch of tutorials and am baffled why I can’t texture a simple polygon. I created a 64x64 texture in .png format and took some demo code I’d already used and adapted it to map a texture onto my polygon. There’s two variations where I get 2 different results.

Variation 1 - I insert two lines of code when I’m loading the texture


gl.texParameterf(GL.TEXTURE_2D,GL.TEXTURE_MIN_FILTER,GL.LINEAR);
gl.texParameterf(GL.TEXTURE_2D,GL.TEXTURE_MAG_FILTER,GL.LINEAR);

In this variation, I can tell from the logs that the program runs just fine, but I get a black screen. I would assume it’s displaying a beautiful black polygon at me.

Variation 2 - In this variation, I remove those two lines and VOILA, I get a nifty white polygon bouncing around my screen

I’m positive my texture is loading from the file okay, because in the logs I see the right sizes for the height and width. I’ve tried 64x64, 128x128 and 256x256, and when I change the image, it shows up in the logs.

I’m hoping wiser heads than mine might make something of this.

If anybody wants to see it, here’s the relevant code below. If there’s any important bits missing that may be important, let me know and I’ll post that too.

(sorry my code’s displaying all nasty . . . can’t get the indentations to work right.)


  private void glInit()
  {
    if(log.isDebugEnabled()) log.debug("glInit()");
  
    gl.determineAvailableExtensions();
    gl.enable(GL.TEXTURE_2D);
    gl.shadeModel(GL.SMOOTH);
    gl.matrixMode(GL.PROJECTION);
    gl.loadIdentity();
    glu.ortho2D(0,mode.width,0,mode.height);
    gl.matrixMode(GL.MODELVIEW);
    gl.loadIdentity();
    gl.viewport(0,0,mode.width,mode.height);
    gl.clearColor(0.0f,0.0f,0.0f,0.0f);
    if(GL.WGL_EXT_swap_control)
    {
      if(log.isDebugEnabled()) log.debug("swapcontrol");
      GL.wglSwapIntervalEXT(1);
    }
  }

  private Texture loadTexture(String filename)
  {
    BufferedImage newImage=null;
    File newFile=new File(filename);
    try
    {
      newImage=ImageIO.read(newFile);
    }
    catch(IOException e)
    {
      log.error("Could not load image in file: "+filename);
    }
    if(newImage==null && log.isDebugEnabled())log.debug("Texture didn't load correctly");
    Texture newTex=new Texture(newImage);
    return newTex;
  }

  protected void makeGLTextures(String[] newImages)
  {
    IntBuffer tempBuf=ByteBuffer.allocateDirect(4*(newImages.length)).asIntBuffer();
    Texture[] texList=new Texture[newImages.length];
    for(int loop=0; loop<newImages.length; loop++)
    {
      texList[loop]=loadTexture(newImages[loop]);
    }
    gl.genTextures(texList.length,Sys.getDirectBufferAddress(tempBuf));
    for(int loop=0; loop<texList.length; loop++)
    {
       if(log.isDebugEnabled()) log.debug("binding texture to name="+tempBuf.get(loop));
       if(log.isDebugEnabled()) log.debug("w="+texList[loop].getWidth());
       if(log.isDebugEnabled()) log.debug("h="+texList[loop].getHeight());
       if(log.isDebugEnabled()) log.debug("p="+texList[loop].getPtr());
       gl.bindTexture(GL.TEXTURE_2D,tempBuf.get(loop));
       gl.texParameterf(GL.TEXTURE_2D,GL.TEXTURE_MIN_FILTER,GL.LINEAR);
       gl.texParameterf(GL.TEXTURE_2D,GL.TEXTURE_MAG_FILTER,GL.LINEAR);
       gl.texImage2D(GL.TEXTURE_2D,0,GL.RGB,
                    texList[loop].getWidth(),texList[loop].getHeight(),0,GL.RGB,
                    GL.UNSIGNED_BYTE,texList[loop].getPtr());
if(log.isDebugEnabled()) log.debug("texture "+tempBuf.get(loop)+" successfully bound.");
    }
    addToTexIndex(tempBuf); //my own method defined elsewhere.  It works okay.
  }

Finally, my display code:


    halfx=size.x/2;
    halfy=size.y/2;
    gl.pushMatrix();
      gl.translatef(position.x,position.y,0);
      gl.rotatef(angle,0.0f,0.0f,1.0f);
      if(textured)
      {
        gl.bindTexture(GL.TEXTURE_2D,texName);
        if(log.isDebugEnabled()) log.debug("Binding Texture "+texName);
      }
      gl.begin(GL.QUADS);
        if(textured)
        {
          if(log.isDebugEnabled()) log.debug("textured");
          gl.texCoord2f(0.0f,0.0f);
          gl.vertex2f(-halfx,-halfy);
          gl.texCoord2f(1.0f,0.0f);
          gl.vertex2f(halfx,-halfy);
          gl.texCoord2f(1.0f,1.0f);
          gl.vertex2f(halfx,halfy);
          gl.texCoord2f(0.0f,1.0f);
          gl.vertex2f(-halfx,halfy);
        } else {
          if(log.isDebugEnabled()) log.debug("untextured");
          gl.vertex2f(-halfx,-halfy);
          gl.vertex2f(halfx,-halfy);
          gl.vertex2f(halfx,halfy);
          gl.vertex2f(-halfx,halfy);
        }
        gl.end();
      gl.popMatrix();

What’s the value of texName in the rendering portion of the code?

texName is the openGL texture name of the texture I’m assigning. It’s an int . . . I’m assuming that’s just a pointer to where openGL has decided to store my texture. At least, that’s my best guess given that I don’t really understand the architecture yet.

Basically, if you take a look in the loadGLTextures() method there’s a series of commands:


    IntBuffer tempBuf=ByteBuffer.allocateDirect(4*(newImages.length)).asIntBuffer();

    gl.genTextures(texList.length,Sys.getDirectBufferAddress(tempBuf)); 

    addToTexIndex(tempBuf); //my own method defined elsewhere.  It works okay. 

That just takes the set of texture names I’ve just generated and dumped them into a specific IntBuffer where I can get at them later in a more organized fashion. That’s the addToTexIndex(tempBuf) command.

I’ve looked at the logs and in the rendering code when I’m using the variable texName, texName==tempBuf.get(0) It’s the same value. If you actually want the integer representaion of that, I could prolly dig it out of the logs. I’d be surprised if it’s the same value every time, tho.

Any other questions?

-Nate

When you allocate direct buffers for use with LWJGL always remember to use the native byte ordering, that is

ByteBuffer.allocateDirect(blah).order(ByteOrder.nativeOrder()).asIntBuffer()

when allocating the texture names buffer (or other places where you use buffers).

  • elias

[quote]always remember to use the native byte ordering
[/quote]
Okay . . . good to know. What exactly does that do again? Suddenly my texture name is 1 every time . . . that’s prolly a good thing. I’m assuming I can’t always count on OpenGL giving me texture name in numerical order, right?

Unfortunately, that still doesn’t solve my problem . . . wait . . . nope . . . still getting black and . . . still getting white.

Any other thoughts?

-Nate

[quote]Okay . . . good to know. What exactly does that do again?
[/quote]
It makes Java output data in the underlying platform’s native byte order. As you’re pushing data straight to the native layer, without any translations being done by LWJGL, you need to pass it in the correct format.

[quote]I’m assuming I can’t always count on OpenGL giving me texture name in numerical order, right?
[/quote]
Correct. It probably will be, but there’s absolutely no reason why it should.

[quote]Any other thoughts?
[/quote]
Are you sure you’re getting a black poly there? Change the gl.clearColor values to (1.0f, 0.0f, 0.0f, 1.0f) and see if it’s black or just not displayed.

What is the texture you’re expecting to see? You’re sure you’re enabling and disabling texturing in the correct places?

[quote]You’re sure you’re enabling and disabling texturing in the correct places?
[/quote]
Well, now that’s an interesting question. Where are the appropriate places? I’m enabling texturing in my glInit() method, but not really anywhere else that I know of. Is there something other than this line that needs to be done?

gl.enable(GL.TEXTURE_2D);

I’ll go ahead and test out to see what color polygon I’m getting. I’m not sure I ever do actually set the clearcolor, so I’ll play around with that and post the results. Thanks tho.

-Nate