HELP: Red Book Texture Example Conversion

Hi. I’m having a bit of trouble converting the Red Book’s texture example. It just display a gray square instead of a checker image mapped to the square. The image, as you recall from that example of yore, is generated from code; it isn’t loaded from a file or URL. Well, here’s the code below.


import net.java.games.jogl.*;
import net.java.games.jogl.util.*;

import java.nio.*;
import javax.imageio.*;

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;


public class textureSample
{
  public static void main(String[] args)
  {
    GLCapabilities caps = new GLCapabilities();
    //caps.setDepthBits(24);
    
    GLCanvas canvasPane = GLDrawableFactory.getFactory().
      createGLCanvas(caps);
    
    canvasPane.addGLEventListener(new CheckerRenderer());
    new Animator(canvasPane).start();
        
    JFrame.setDefaultLookAndFeelDecorated(true);
    JFrame jframe = new JFrame("Checkers");
    jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    jframe.add(canvasPane);
    
    jframe.getToolkit().setDynamicLayout(true);
    jframe.setSize(512, 512);
    jframe.setVisible(true);
  }
  
  static class CheckerRenderer
    implements  GLEventListener
  {
    int x, y, w, h;
    
    private int imageW = 64; // image dims, remember power of 2s
    private int imageH = 64;
    private int imageC = 3; // C for Color component, num of
        
    private ByteBuffer checker;
    private int [] textureIDs;
    
    public CheckerRenderer()
    {
      textureIDs = new int[1];
      this.makeChecker();
    }
    
    private void makeChecker()
    {
      checker = ByteBuffer.allocateDirect(imageW * imageH * imageC);

      for (int w = 0; w < imageW; w++)
      {
        for (int h = 0; h < imageH; h++)
        {
          byte c = 0;
          if ((w%2)==0 && (h%2)==0)
            c = 127;
          else
            c = -128;
          checker.put( ((w * imageW + h) * 3), c);
          checker.put( ((w * imageW + h) * 3 + 1), (byte)c);
          checker.put( ((w * imageW + h) * 3 + 2), (byte)c);          
          
          System.err.print("("+checker.get() + ", " + checker.get() + ", " 
            + checker.get() + /*", " + checker.get() +*/ ")");
        }
        System.err.println("");
      }
    }//
    
    
    public void init(GLDrawable d)
    {
      final GL gl = d.getGL();
      
      gl.glClearColor(0, 0, 0, 0);

      gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
      
      gl.glGenTextures(1, textureIDs);
      gl.glBindTexture(GL.GL_TEXTURE_2D, textureIDs[0]);

      gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP);
      gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP);
      
      gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
      gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
      
      gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB,
        imageW, imageH, 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE,
        checker);
      
      gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_DECAL);
            
      gl.glEnable(GL.GL_TEXTURE_2D);
      gl.glBindTexture(GL.GL_TEXTURE_2D, textureIDs[0]);
      gl.glShadeModel(gl.GL_FLAT);
            
      //gl.glEnable(GL.GL_DEPTH_TEST);
      //gl.glDepthFunc(gl.GL_LESS);
    }
    
    public void reshape(GLDrawable d, int x, int y, int w, int h)
    {
      final GL gl = d.getGL();
      final GLU glu = d.getGLU();
      
      gl.glViewport(x, y, w, h);
      
      gl.glMatrixMode(GL.GL_PROJECTION);  gl.glLoadIdentity();
      glu.gluPerspective(60, 1.f * (float) w / (float)h, 1, 30);
      gl.glMatrixMode(GL.GL_MODELVIEW);  gl.glLoadIdentity();
      gl.glTranslated(0.0, 0.0, -3.6);
      
    }
    public void display(GLDrawable d)
    {
      GL gl = d.getGL();
      
      gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
                  
      gl.glBegin(GL.GL_QUADS);
      
      gl.glTexCoord2d(0, 0);  gl.glVertex3d(-2, -1, 0);
      gl.glTexCoord2d(0, 1);  gl.glVertex3d(-2, 1, 0);
      gl.glTexCoord2d(1, 1);  gl.glVertex3d(0, 1, 0);
      gl.glTexCoord2d(1, 0);  gl.glVertex3d(0, -1, 0);
      
      gl.glEnd();     
      
      gl.glFlush();
    }
    public void displayChanged(GLDrawable d, boolean device, boolean mode)
    {
    }
  }
}//end class

By the way, in this example, when using the default Java L&F with GLCanvas resizing the window smaller has no effect–It will not lemme resize to a smaller window. Any comment or help is very much appreciated. - AK77

See comments in code —^

should be:
(byte)0x00 and (byte)0xFF
or (byte)0 and (byte)255

Hi. I am not seeing the connection between byte and OpenGL’s UNSIGNED_BYTE. Java byte ranges from -128 to 127; while UNSIGNED_BYTE from 0 to 255. I would be getting a checker image not a square. My assignment to the variable is valid in the byte range but in valid for UNSIGNED_BYTE from GL. Assigning DO i need to convert ByteBuffer to IntBuffer? You know what lemme test your code first before I continue to sound like an ass. - AK77

Have you actually read my comment in your source-code? :-\

You actually GET a checker-board, but the differences in brightness are so tiny you can’t really see it!

[tr][td]signed byte[/td][td][/td][td]in bits[/td][td][/td][td]unsigned byte[/td][td][/td][td]shade[/td][/tr]
[tr][td]127[/td][td]->[/td][td]0111 1111[/td][td]->[/td][td]127[/td][td]->[/td][td]grey[/td][/tr]
[tr][td]-128[/td][td]->[/td][td]1000 0000[/td][td]->[/td][td]128[/td][td]->[/td][td]grey[/td][/tr]
[tr][td]0[/td][td]->[/td][td]0000 0000[/td][td]->[/td][td]0[/td][td]->[/td][td]black[/td][/tr]
[tr][td]255 or -1[/td][td]->[/td][td]1111 1111[/td][td]->[/td][td]255[/td][td]->[/td][td]white[/td][/tr]

See?

Hi, Riven. Thanks! Your help cleared up me confusion. It works. I need to bit fiddle more. Thanks again for taking your time to answer this post. :-[- AK77