在每个图像上放置相同的纹理 - JOGL

时间:2014-05-20 13:19:17

标签: java jogl

我正在使用JOGL创建2D游戏。在我的游戏中,它有方块,每个都有不同的类型,如水,草等。 我有一个Block类的ArrayList。每个块实例都具有块的类型和坐标。 我的问题是,在绘制块时,它们每个都具有相同的纹理而不是它们的类型。我想这可能是因为我需要在使用它之后禁用纹理,但这似乎可以消除所有内容的纹理。

GLCanvas类

float[] lightPos = new float[4];


private void doLighting( GL2 gl )
{
   lightPos[0] =0.5f;
   lightPos[1] = 0;
    lightPos[2] = 1f;
  lightPos[3] = 0.0001f;
    gl.glEnable(GLLightingFunc.GL_LIGHTING);
    gl.glEnable(GLLightingFunc.GL_LIGHT0);
    gl.glEnable(GL2.GL_COLOR_MATERIAL);
    float[] noAmbient ={ 0.2f, 0.2f, 0.2f, 1f }; // low ambient light
    float[] spec =    { 1f, 1f, 1f,1f }; // low ambient light
    float[] diffuse ={ 1f, 1f, 1f, 1f };
    // properties of the light
    gl.glLightfv(GLLightingFunc.GL_LIGHT0, GLLightingFunc.GL_AMBIENT, noAmbient, 0);
    gl.glLightfv(GLLightingFunc.GL_LIGHT0, GLLightingFunc.GL_SPECULAR, spec, 0);
    gl.glLightfv(GLLightingFunc.GL_LIGHT0, GLLightingFunc.GL_DIFFUSE, diffuse, 0);
    gl.glLightfv(GLLightingFunc.GL_LIGHT0, GLLightingFunc.GL_POSITION, lightPos, 0);
  gl.glLightf(GL2.GL_LIGHT0, GL2.GL_SPOT_CUTOFF, 45.0f);
}

private void render(GL2 gl) {
    gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);          // Clear The Screen And The Depth Buffer
    gl.glLoadIdentity();                          // Reset The Current Modelview Matrix
    //Draw the blocks from the Block Array List
    for(int i = 0; i < block.size(); i ++){
        block.get(i).draw(gl, moveX, moveY);
    }
    //Draw player
    gl.glColor3f(1, 1, 1);
    gl.glBegin(GL2.GL_QUADS);
    gl.glVertex2f(player.x,player.y);
    gl.glVertex2f(player.x + player.width,player.y);
    gl.glVertex2f(player.x + player.width,player.y + player.width);
    gl.glVertex2f(player.x,player.y + player.width);
    gl.glEnd();
}

@Override
public void display(GLAutoDrawable drawable) {
     GL2 gl = drawable.getGL().getGL2();
     gl.glClear(GL2.GL_DEPTH_BUFFER_BIT | GL2.GL_COLOR_BUFFER_BIT);
        gl.glEnable(GL2.GL_TEXTURE_2D);
        gl.glEnable(GL2.GL_BLEND);
        gl.glBlendFunc(GL2.GL_ONE, GL2.GL_ONE_MINUS_SRC_ALPHA);
        gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL2.GL_COLOR_ARRAY);
        gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
        gl.glLoadIdentity();
        doLighting(gl);
        setCamera(gl,120);
        render(gl);
}

@Override
public void dispose(GLAutoDrawable arg0) {
}

@Override
public void init(GLAutoDrawable drawable) {
     GL2 gl = drawable.getGL().getGL2();
     gl.glEnable(GL2.GL_TEXTURE_2D);
}
 private void setCamera(GL2 gl,float distance) {
        // Change to projection matrix.
        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();

        // Perspective.
        gl.glOrtho(0, Frame.WIDTH, Frame.HEIGHT, 0, 0, 1);
        gl.glMatrixMode(GL2.GL_MODELVIEW);

        //Disable z axis
        gl.glDisable(GL2.GL_DEPTH_TEST);
    }

@Override
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,
        int arg4) {
}

块类绘制方法

public void draw(GL2 gl, int moveX, int moveY) {

    if (texture == null) {

        try {
            texture = TextureIO.newTexture(new File(this.getClass().getClassLoader()
                    .getResource("com/world/images/" + type + ".png").getPath()), false);
               texture.enable(gl);
                texture.bind(gl);
                // Poor filtering. Needed !
                gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
                gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
        } catch (GLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    gl.glBegin(GL2.GL_QUADS);
    gl.glVertex2f(x * width + moveX, y * width + moveY);
    gl.glTexCoord2f(0, 0);
    gl.glVertex2f(x * width + width + moveX, y * width + moveY);
    gl.glTexCoord2f(1, 0);  
    gl.glVertex2f(x * width + width + moveX, y * width + width + moveY);
    gl.glTexCoord2f(1, 1);
    gl.glVertex2f(x * width + moveX, y * width + width + moveY);
    gl.glTexCoord2f(0, 1);
    gl.glEnd();
    gl.glFlush();
}

非常感谢您的帮助。问我是否做了一些不清楚的事情。

2 个答案:

答案 0 :(得分:0)

将gl.glTexParameteri()的调用移动到GLEventListener的init()方法中,它应该只被调用一次,它会影响整个纹理目标,而不仅仅是单个纹理,我不确定你需要先调用bind。在其他地方加载与块类型匹配的每个纹理,在绘制任何纹理网格之前调用gl.glEnable(GL2.GL_TEXTURE_2D),调用texture.bind(gl)(使用与块类型匹配的纹理),然后调用glBegin()和在绘制最后一个纹理网格后调用gl.glDisable(GL2.GL_TEXTURE_2D)。

答案 1 :(得分:0)

texture.enable()和texture.bind()必须在if语句之外,因为每次绘制纹理时都需要调用它们。

public void draw(GL2 gl, int moveX, int moveY) {

    if (texture == null) {
        try {
            texture = TextureIO.newTexture(
                    new File(this.getClass().getClassLoader().getResource("com/world/images/" + type + ".png").getPath()), false);
        } catch (GLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    texture.enable(gl);
    texture.bind(gl);
    gl.glEnable(GL2.GL_TEXTURE_2D);
    gl.glBegin(GL2.GL_QUADS);
    gl.glVertex2f(x * width + moveX, y * width + moveY);
    gl.glTexCoord2f(0, 0);
    gl.glVertex2f(x * width + width + moveX, y * width + moveY);
    gl.glTexCoord2f(1, 0);
    gl.glVertex2f(x * width + width + moveX, y * width + width + moveY);
    gl.glTexCoord2f(1, 1);
    gl.glVertex2f(x * width + moveX, y * width + width + moveY);
    gl.glTexCoord2f(0, 1);
    gl.glEnd();
    gl.glDisable(GL2.GL_TEXTURE_2D);


}