Question

I am trying to select a specific region of a texture in LWJGL during the drawing process, but my efforts have been fruitless. How (if possible) can I select only a region of a whole texture during drawing.

Please note that I am nowhere new to Java, I am an experienced programmer, but not when it comes to LWGJL, as I'm still getting the full grasps with it.

Below is my code.

Sprite.java

public class Sprite
{
private Icon icon;
private int width;
private int height;
private int offcutX; // all below and this for selecting the region of the image.
private int offcutY;
private int imageX;
private int imageY;

public Sprite(TextureRegistry registry, String ref)
{
    this(registry, ref, 0, 0, 0, 0);
}
public Sprite (TextureRegistry registry, String ref, int offcutX, int offcutY, int imageX, int imageY)
{
    try
    {
        icon = registry.getIcon("net/blockbuster/resources/" + ref); // loads the icon and converts it to opengl-readable format. 
        width = icon.getIconWidth();
        height = icon.getIconHeight();
        this.offcutX = offcutX;
        this.offcutY = offcutY;
        this.imageX = imageX;
        this.imageY = imageY;
    }
    catch (IOException e)
    {
        e.printStackTrace();
        System.exit(-1);
    }
}
public int getWidth()
{
    return icon.getIconWidth();
}
public int getHeight()
{
    return icon.getIconHeight();
}
public void draw(int x, int y) // drawing method, called on every loop. 
{
    glPushMatrix();
    icon.bind();
    glTranslatef(x, y, 0);
    glBegin(GL_QUADS);
    { // I would like to be able to do this within this block. 
        glTexCoord2f(0, 0);
        glVertex2f(0, 0);
        glTexCoord2f(0, 1);
        glVertex2f(0, height);
        glTexCoord2f(1, 1);
        glVertex2f(width, height);
        glTexCoord2f(1, 0);
        glVertex2f(width, 0);
    }
    glEnd();
    glPopMatrix();
}
}

TextureRegistry.java

public class TextureRegistry
{
private HashMap<String, Icon> table = new HashMap<String, Icon>(); // map to hold all loaded textures

public Icon getIcon(String resourceName) throws IOException
{
    Icon tex = table.get(resourceName);
    if (tex != null)
    {
        return tex;
    }
    tex = getIcon(resourceName, GL_TEXTURE_2D, GL_RGBA8, GL_LINEAR, GL_LINEAR);
    table.put(resourceName, tex);
    return tex;
}
public Icon getIcon(String resourceName, int target, int dstPixelFormat, int minFilter, int magFilter) throws IOException
{
    BufferedImage image = loadImage(resourceName);
    int textureID = loadTexture(image);
    Icon icon = new Icon(target, textureID);
    icon.setWidth(image.getWidth());
    icon.setHeight(image.getHeight());
    return icon;
}
public static int loadTexture(BufferedImage image)
{
    int[] pixels = new int[image.getWidth() * image.getHeight()];
    image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
    ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4);
    for (int y = 0; y < image.getHeight(); y++)
    {
        for (int x = 0; x < image.getWidth(); x++)
        {
            int pixel = pixels[y * image.getWidth() + x];
            buffer.put((byte)((pixel >> 16) & 0xFF)); // r
            buffer.put((byte)((pixel >> 8) & 0xFF));  // g
            buffer.put((byte)(pixel * 0xFF));         // b
            buffer.put((byte)((pixel >> 24) & 0xFF)); // a
        }
    }
    buffer.flip();
    int textureID = glGenTextures();
    glBindTexture(GL_TEXTURE_2D, textureID);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
    return textureID;
}
public static BufferedImage loadImage(String ref) throws IOException 
{
    URL url = TextureRegistry.class.getClassLoader().getResource(ref);
    if (url == null)
    {
        throw new IOException("Cannot find: " + ref);
    }
    Image img = new ImageIcon(url).getImage();
    BufferedImage bufferedImage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
    Graphics g = bufferedImage.getGraphics();
    g.drawImage(img, 0, 0, null);
    g.dispose();
    return bufferedImage;
}
}

Icon.java

public class Icon
{
private int target;
private int iconID;
private int width;
private int height;
private int iconWidth;
private int iconHeight;
private float widthRatio;
private float heightRatio;

public Icon(int target, int iconID)
{
    this.target = target;
    this.iconID = iconID;
}
public void bind()
{
    glBindTexture(target, iconID); // binds the texture
}
public void setHeight(int newHeight)
{
    this.height = newHeight;
    setHeight();
}
public void setWidth(int newWidth)
{
    this.width = newWidth;
    setWidth();
}
public int getIconHeight()
{
    return height;
}
public int getIconWidth()
{
    return width;
}
public float getHeight()
{
    return heightRatio;
}
public float getWidth()
{
    return widthRatio;
}
public void setIconHeight(int iconHeight)
{
    this.iconHeight = iconHeight;
    setHeight();
}
public void setIconWidth(int iconWidth)
{
    this.iconWidth = iconWidth;
    setWidth();
}
private void setHeight()
{
    if (iconHeight != 0)
    {
        heightRatio = ((float)height) / iconHeight;
    }
}
private void setWidth()
{
    if (iconWidth != 0)
    {
        widthRatio = ((float)width) / iconWidth;
    }
}
}
Was it helpful?

Solution

To specify a region of a texture to be drawn all you need to do is modify your texCoords. Currently you are using your entire texture, if for example you wanted only the quarter of it closest to the origin you would use this in your draw method:

    glTexCoord2f(0, 0);
    glVertex2f(0, 0);
    glTexCoord2f(0, 1/2f);
    glVertex2f(0, height);
    glTexCoord2f(1/2f, 1/2f);
    glVertex2f(width, height);
    glTexCoord2f(1/2f, 0);
    glVertex2f(width, 0);

which would result in an image the same size as before although using only the bottom left quarter of the texture.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top