图块集的 Jogl uv 坐标

问题描述

我目前正在学习 jogl,所以我可以制作自己的 2d 游戏。瓷砖的所有纹理都存储在一个大的瓷砖集中。 我尝试使用 Texture.getSubImageTexCoords() 绘制单个图块,但结果很奇怪:

weird result

我不确定如何准确地描述它,但是构成四边形的左上角三角形以一种非常奇怪的方式拉伸。 我只想显示图块集的一部分。 我尝试在网上寻找一些东西,但找不到任何东西。

这是我的代码

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,32); // sub texture coords
            } catch (IOException e) {
                e.printstacktrace();
            }

            // Set up
            drawable.getGL().glClearColor(0.3f,0.3f,0);
            glu = new glu();
            glu.gluOrtho2D(0,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,tc.top());
            gl.glVertex2f(x + width,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();
    }
}

图块集为 here

解决方法

我不使用 JOGL,但它看起来像你的

            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,tc.top());
            gl.glVertex2f(x + width,tc.top());

不正确。如果我们将每个 glVertex2f 与其下方的行配对,我想它应该看起来像

            gl.glVertex2f(x,tc.bottom());

            gl.glVertex2f(x,y + height);
            gl.glTexCoord2f(tc.left(),tc.top());

            gl.glVertex2f(x + width,y);
            gl.glTexCoord2f(tc.right,tc.bottom());
,

glTexCoord2f 设置 next 顶点的 texcoord。因此,您使用默认的 texcoord(无论是什么)渲染一个顶点,然后使用 previous 顶点的 texcoord 渲染每个顶点。最后一个 texcoord 调用什么也不做。 (好吧,它可能会作为当前的 texcoord 挂起并用于下一帧的第一个顶点)

你需要调用 glTexCoord2f before glVertex2f。

附言对 glColor3f/4f、glNormal3f 等也一样。