I am currently learning jogl so I can make my own 2d game. All the textures for the tiles are stored in a single large tileset.
I tried to use Texture.getSubImageTexCoords()
to draw a single tile, but the result was weird:
I'm not sure exactly how to describe it, but the upper left triangle that makes up the quad is stretching in a very strange way. I want to display just a section of the tileset. I tried looking for something online but couldn't find anything.
here is my code:
public class TestSubImage {
private GLU glu = new GLU();
private GLCanvas mainCanvas;
private Texture texture;
private TextureCoords tc;
class Listener implements GLEventListener {
public void init(GLAutoDrawable drawable) {
// Load texture
try {
texture = TextureIO.newTexture(TestSubImage.class.getResource("/images/sheet.png"), false, null);
texture.setTexParameteri(drawable.getGL(), drawable.getGL().GL_TEXTURE_MAG_FILTER, drawable.getGL().GL_NEAREST);
tc = texture.getSubImageTexCoords(0, 16, 16, 32); // sub texture coords
} catch (IOException e) {
e.printStackTrace();
}
// Set up
drawable.getGL().glClearColor(0.3f, 0.3f, 0.3f, 0);
glu = new GLU();
glu.gluOrtho2D(0, 512, 512, 0);
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
}
public void dispose(GLAutoDrawable drawable) {
}
public void display(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
// where to draw the image
int x = 100;
int y = 100;
int width = 200;
int height = 200;
gl.glColor3f(1, 1, 1);
// Draw the image
texture.enable(gl);
texture.bind(gl);
gl.glBegin(GL2.GL_QUADS);
gl.glVertex2f(x, y);
gl.glTexCoord2f(tc.left(), tc.bottom());
gl.glVertex2f(x, y + height);
gl.glTexCoord2f(tc.right(), tc.bottom());
gl.glVertex2f(x + width, y + height);
gl.glTexCoord2f(tc.right(), tc.top());
gl.glVertex2f(x + width, y);
gl.glTexCoord2f(tc.left(), tc.top());
gl.glEnd();
texture.disable(gl);
}
}
private void run() {
// Create window
JFrame frame = new JFrame("Texture Coords Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create profile and capabilities
final GLProfile profile = GLProfile.get(GLProfile.GL2);
GLCapabilities caps = new GLCapabilities(profile);
// Now set up the main GLCanvas
mainCanvas = new GLCanvas(caps);
mainCanvas.addGLEventListener(new Listener());
frame.getContentPane().add(mainCanvas);
frame.setSize(512, 512);
frame.setResizable(false);
frame.setVisible(true);
}
public static void main(String[] args) {
new TestSubImage().run();
}
}
The tileset is here.
glTexCoord2f
sets the texcoord for the next vertex. So, you are rendering one vertex with the default texcoord (whatever that is), and then you are rendering each vertex with the previous vertex's texcoord. And the last texcoord call does nothing. (Well, it probably hangs around as the current texcoord and gets used for the first vertex on the next frame)
You need to call glTexCoord2f before glVertex2f.
P.S. It works the same for glColor3f/4f, glNormal3f, etc.