Textures

Im having some difficulty applying a texture to a quad. I have used :


image3 = ImageIO.read(new BufferedInputStream(this.getClass().getClassLoader().getResourceAsStream ("tilepng.png")));

to import an image and then used :


ImageUtils.texImage2D(gl, image3);

to create a texture.

finaly I used:


gl.glGenTextures(1,textureid);
gl.glBindTexture (GL.GL_TEXTURE_2D, textureid[0]);

to id the texture.

Later I:


gl.glTexEnvf( GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE );
                  gl.glEnable(GL.GL_TEXTURE_2D);
                  gl.glBindTexture (GL.GL_TEXTURE_2D, textureid[0]);
                  gl.glBegin (GL.GL_QUADS);
                  gl.glTexCoord2f (0.0f, 0.0f);
                  gl.glVertex2f (0.0f, 0.0f);
                  gl.glTexCoord2f (32.0f, 0.0f);
                  gl.glVertex2f (32.0f, 0.0f);
                  gl.glTexCoord2f (32.0f, 32.0f);
                  gl.glVertex2f (32.0f, 32.0f);
                  gl.glTexCoord2f (0.0f, 32.0f);
                  gl.glVertex2f (0.0f, 32.0f);
                  gl.glEnd ();                        
                  gl.glDisable (GL.GL_TEXTURE_2D); 


The quad shows up one the screen but it is white and not with a texture.

Any suggestions?

You must bind the texture before loading.

More specifically, you haven’t done anything of the sort:


glu.gluBuild2DMipmaps(GL.GL_TEXTURE_2D,pixelFormat,width,height,pixelFormat,GL.GL_UNSIGNED_BYTE,glBuffer);

which loads the actual texture data onto the card. That or an equivalent glTexImage2D call are neccessary. Otherwise you get the OpenGL default texture which IIRC is white.

-edit- actually, what does the texImage2D method do ?? that might do the job for you. Is it a utility library from somewhere else ? if so check to see if it returns a texture ID. If all it does is call the afore mentioned build2DMipMaps or alternatively texImage2D then you need to call it AFTER you call bindTexture.
so …


gl.glGenTextures(1,textureid);
gl.glBindTexture (GL.GL_TEXTURE_2D, textureid[0]); 
ImageUtils.texImage2D(gl, image3);

D.

I have tried binding before loading and it is still white.


 public static void texImage2D(GL gl, BufferedImage image) {
           int width = image.getWidth();
           int height = image.getHeight();

           int[] rawData = image.getRGB(0, 0, width, height, null, 0, width);
           convertJavaToGL(width, height, rawData);
           
           gl.glPushClientAttrib(GL.GL_CLIENT_PIXEL_STORE_BIT);
           gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 4);
           gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 4, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_INT_8_8_8_8, rawData);
           gl.glPopClientAttrib();
     }

This is image utils.

And i did this order to load.


image3 = ImageIO.read(new BufferedInputStream(this.getClass().getClassLoader().getResourceAsStream ("tilepng.png")));
            gl.glEnable(GL.GL_TEXTURE_2D);
            gl.glGenTextures(1,textureid);
            gl.glBindTexture (GL.GL_TEXTURE_2D, textureid[0]);
            
            ImageUtils.texImage2D(gl, image3);
            gl.glDisable (GL.GL_TEXTURE_2D);

it still doesnt work.

hmmm. I can’t see anything immediately wrong with that. I presume the convertJavaToGL flips the byte ordering on the int from ARGB to RGBA ? Are your textures square and of the correct dimensions ? (powers of 2). Try using a gluBuild2DMipMaps call instead of texImage2D. You should be using it to build texture objects for display anyway, and its more forgiving of sizing errors.

D.

I might be wrong but when i try modulate i have nothing.
Try to change your

GL.GL_MODULATE

parameter by

GL.GL_LINEAR

.

[quote]I might be wrong but when i try modulate i have nothing.
Try to change your

GL.GL_MODULATE

parameter by

GL.GL_LINEAR

.
[/quote]
GL_LINEAR isn’t actually a valid parameter for texEnvf. You might be thinking of GL_REPLACE which entirely disregards the previous fragment color, lighting for example will be ignored. GL_MODULATE just modulates the texture color with the incoming fragment color, It shouldn’t have any bearing on whats going wrong here.

D.

TexCoord2f values should be between the range of 0 and 1, not pixels, like .25, .25 would be upper left corner to 25% towards the lower right corner. edit: unless you are trying to tile them 32 times across the quad

Oops, you are right i read to quick i make confusion with
glTexParameter

ordinarily TexCoord2f values ought to be in the range 0-1 , not Vertex2f values, which can be anything at all depending on how his projection matrix is set up. I didn’t actually notice that his texCoord values were ranged from 0-32. However this would still result in the texture being tiled across the quad 32 times rather than nothing displaying at all so its probably not the problem at hand.

D.

whoops, copied and pasted wrong line. I edited the other with a different line.

From the code, I didn’t that he was trying to tile it though. It could be a problem if the image is 32 pixels and the quad is 32 (depending on the scale of the quad) though, it might end up so small that it looks like dots, but the odds of the dot being white…your right though, it’s likely not the problem.

I must remember to never write anything before having my morning coffee :slight_smile:

errr…maybe he is trying to tile it, I just noticed the name of the .png (i’ll go get some coffee now :wink: )

I put up a class that does textures in a relatively self-contained way (given that the rest of your framework works).

It’s at:

http://davidson.dl.stevens-tech.edu/personal/dkruger/ImageTile.java

I changed the image utils method to



public static void texImage2D(GL gl,GLU glu, BufferedImage image) {
           
              int width = image.getWidth();
           int height = image.getHeight();
           ByteBuffer dest = null;
           int[] rawData = image.getRGB(0, 0, width, height, null, 0, width);
           convertJavaToGL(width, height, rawData);
           int[] data = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
           dest = ByteBuffer.allocateDirect(data.length * BufferUtils.SIZEOF_INT);
           dest.order(ByteOrder.nativeOrder());
           dest.asIntBuffer().put(data, 0, data.length);
           gl.glPushClientAttrib(GL.GL_CLIENT_PIXEL_STORE_BIT);
           gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 4);
          // gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 4, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_INT_8_8_8_8, rawData);
           glu.gluBuild2DMipmaps(GL.GL_TEXTURE_2D,GL.GL_RGBA,width,height,GL.GL_RGBA,GL.GL_UNSIGNED_BYTE,dest);
         
           gl.glPopClientAttrib();
     }


It now gives my a gray screen. How exactly does the 2dMipmaps method work?

Also, im only trying to map one 3232 texture to one 3232 quad

[quote]Also, im only trying to map one 3232 texture to one 3232 quad
[/quote]
Ahh…ok, then you do want it to be in the range of 0-1 for the texcoords, like:

gl.glBegin (GL.GL_QUADS);

gl.glTexCoord2f (0.0f, 0.0f);
gl.glVertex2f (0.0f, 0.0f);
gl.glTexCoord2f (1.0f, 0.0f);
gl.glVertex2f (32.0f, 0.0f);
gl.glTexCoord2f (1.0f, 1.0f);
gl.glVertex2f (32.0f, 32.0f);
gl.glTexCoord2f (0.0f, 1.0f);
gl.glVertex2f (0.0f, 32.0f);
gl.glEnd ();

I fixed that before but it still does the same thing

I changed it again. What i did before made no sese.


public static void texImage2D(GL gl,GLU glu, BufferedImage image) {
        int width = image.getWidth();
        int height = image.getHeight();
   
        int[] rawData = image.getRGB(0, 0, width, height, null, 0, width);
        convertJavaToGL(width, height, rawData);
         
        gl.glPushClientAttrib(GL.GL_CLIENT_PIXEL_STORE_BIT);
        gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 4);
        
        glu.gluBuild2DMipmaps(GL.GL_TEXTURE_2D,GL.GL_RGBA,width,height,GL.GL_RGBA,GL.GL_UNSIGNED_BYTE,rawData);
        gl.glPopClientAttrib();
       } 



It ran but the tile is still white

AHHH, YES!!!, It worked. In addition to changing that method i changed the order of my initializations:



image3 = ImageIO.read(new BufferedInputStream(this.getClass().getClassLoader().getResourceAsStream ("moveobject.gif")));
            
            gl.glEnable(GL.GL_TEXTURE_2D);
            gl.glGenTextures(1,textureid);
            gl.glBindTexture (GL.GL_TEXTURE_2D, textureid[0]);
            ImageUtils.texImage2D(gl,glu, image3);
            gl.glDisable (GL.GL_TEXTURE_2D);


Thank you all!!!

wait a minute… all my textures have a red tint. I didnt notice on that example because it was a red square. Why the heck could that be?