如何在LWJGL绘图过程中选择图像区域?

时间:2014-02-05 06:01:07

标签: java textures lwjgl

我试图在绘图过程中选择LWJGL中纹理的特定区域,但我的努力没有结果。如何(如果可能)我可以在绘图期间仅选择整个纹理的区域。

请注意,我是Java的新手,我是一名经验丰富的程序员,但在LWGJL方面并非如此,因为我仍然掌握它的全部内容。

以下是我的代码。

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;
    }
}
}

1 个答案:

答案 0 :(得分:1)

要指定要绘制的纹理区域,您只需修改texCoords即可。目前您正在使用整个纹理,例如,如果您只想要最接近原点的四分之一,那么您将在draw方法中使用它:

    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);

这将导致图像与之前的图像大小相同,尽管仅使用纹理的左下角四分之一。