我试图在绘图过程中选择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;
}
}
}
答案 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);
这将导致图像与之前的图像大小相同,尽管仅使用纹理的左下角四分之一。