2025-05-17

 

首先瞭解一下何為texture。按照英文解釋來理解:一個圖片從原始格式解碼並上傳到GPU就被稱為紋理。(說實話我不是很清楚這個的定義哈,求指點)

為瞭繪制texture,常常使用幾何來描述,通過幾何對應的頂點來描述紋理。比如要描述一個矩形,可以通過描述每個頂點來描述矩形。

 

要繪圖時,首先要綁定紋理,然後傳遞一個幾何描述給OpenGL進行繪制。而繪圖的大小和位置由幾何描述和OpenGL的viewport的設置共同決定。

當然大部分的遊戲都會讓viewport的大小和屏幕一致。這就意味使用像素更容易讓紋理繪制在合適的大小和位置。

 

繪制一個矩形的幾何圖形是非常常見的,同樣讓同一個紋理在不同位置以不同大小位置也是非常常見的,比如漫天的彈幕。但是每次都傳遞每個形狀到GPU進行繪制的效率是較低的。

所以許多相同紋理可以一起描述並一起送入GPU,這就是SpriteBatch類所要做的。

 

SpriteBatch被賦予瞭紋理和坐標以便每個圖形的繪制。它(SpriteBatch)匯集瞭很多圖形而沒有直接提交給GPU。如果它被賦予的紋理不同於原有的,它將保持原有的圖形,並獲取新的圖形。

上一篇文章其實就使用瞭SpriteBatch,但是沒有繪制圖形,現在我們來試試繪制。

先找張圖片來,分辨率必須是2的次方(如32*32,256*512)。

我截取瞭我的桌面的一部分,分辨率調成512*512。

image1

拷貝到assets文件夾中,圖片文件最好都是放在這個裡面哈。

SpxImage

然後修改代碼

 

 

 

private Texture texture;

實例化texture,texture=new Texture(Gdx.files.internal("image1.jpg"));

然後來說一下為什麼要將圖片放在assets文件夾中。

Gdx.files是libgdx的文件模塊,主要提供以下5大功能。

讀取文件

寫文件

復制文件

移動文件

列出文件和目錄

而獲取操作文件的FileHandle有4種方法。

 

1.Classpath

路徑相對於classpath,文件通常為隻讀。

 

2.Internal

內部文件路徑相對於程序根目錄或者android 的assets文件夾。

 

3.External

外部文件路徑是相對於SD卡根目錄

 

4.Absolute

 

assets文件夾本身就是存儲資源的文件夾,而且相比resource文件夾,它其中的資源不會生成R中的ID,用來放圖片很是合適。

 

所以用Gdx.files.internal("image1.jpg")獲取圖片,然後調用batch.draw(texture,20,10);繪制圖形,20,10是坐標,笛卡爾座標,以左下角為原點。

 

完整代碼:

 

 

package com.cnblogs.htynkn;

 

import com.badlogic.gdx.ApplicationListener; 

import com.badlogic.gdx.Gdx; 

import com.badlogic.gdx.graphics.GL10; 

import com.badlogic.gdx.graphics.Texture; 

import com.badlogic.gdx.graphics.g2d.SpriteBatch;

 

public class FirstGame implements ApplicationListener { 

    //繪圖用的SpriteBatch 

    private SpriteBatch batch; 

    //紋理 

    private Texture texture; 

    @Override

    public void create() { 

        batch = new SpriteBatch(); //實例化 

        texture=new Texture(Gdx.files.internal("image1.jpg")); 

    }

 

    @Override

    public void dispose() { 

        // TODO Auto-generated method stub

 

    }

 

    @Override

    public void pause() { 

        // TODO Auto-generated method stub

 

    }

 

    @Override

    public void render() { 

        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); //清屏 

        batch.begin(); 

        batch.draw(texture,20,10); 

        batch.end(); 

    }

 

    @Override

    public void resize(int width, int height) {  

        // TODO Auto-generated method stub

 

    }

 

    @Override

    public void resume() { 

        // TODO Auto-generated method stub

 

    }

 

效果:

  • SpxImage

    可以看到圖片不能完整顯示,而實際操作中我們也經常使用圖片的一部分,或者將多個圖片資源集合在一個圖片文件中。

    而要顯示圖片的一部分就可以使用TextureRegion類瞭。

    最常用的方法是draw(TextureRegion region, float x, float y, float width, float height)

    指定初始點和長寬。

    修改代碼:

 

 

 

package com.cnblogs.htynkn;

 

import com.badlogic.gdx.ApplicationListener; 

import com.badlogic.gdx.Gdx; 

import com.badlogic.gdx.graphics.GL10; 

import com.badlogic.gdx.graphics.Texture; 

import com.badlogic.gdx.graphics.g2d.SpriteBatch; 

import com.badlogic.gdx.graphics.g2d.TextureRegion;

 

public class FirstGame implements ApplicationListener { 

    //繪圖用的SpriteBatch 

    private SpriteBatch batch; 

    //紋理 

    private Texture texture; 

    //區域 

    private TextureRegion region; 

    @Override

    public void create() { 

        batch = new SpriteBatch(); //實例化 

        texture=new Texture(Gdx.files.internal("image1.jpg")); 

        region=new TextureRegion(texture, 30,80, 200,200); 

    }

 

    @Override

    public void dispose() { 

        // TODO Auto-generated method stub

 

    }

 

    @Override

    public void pause() { 

        // TODO Auto-generated method stub

 

    }

 

    @Override

    public void render() { 

        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); //清屏 

        batch.begin(); 

        batch.draw(region,0,0); 

        batch.end(); 

    }

 

    @Override

    public void resize(int width, int height) { 

        // TODO Auto-generated method stub

 

    }

 

    @Override

    public void resume() { 

        // TODO Auto-generated method stub

 

    }

 

} 

  • 效果:

    SpxImage

    也許你覺得TextureRegion不夠強大,沒有關系,還可以使用Sprite。

    Sprite不光包含TextureRegion的功能,還可以指定位置和顏色。

 

 

關鍵代碼:

 

view sourceprint?

sprite=new Sprite(texture, 80, 80, 400, 300); 

sprite.setPosition(10, 10); //位置 

sprite.setRotation(15);

稍微想一下前幾個例子就可以發現,其實Sprite的功能就是以上的集合。但是Sprite更方便,它用一個對象描述瞭一切。

 

完整代碼如下:

 

package com.cnblogs.htynkn;

 

import com.badlogic.gdx.ApplicationListener; 

import com.badlogic.gdx.Gdx; 

import com.badlogic.gdx.graphics.GL10; 

import com.badlogic.gdx.graphics.Texture; 

import com.badlogic.gdx.graphics.g2d.Sprite; 

import com.badlogic.gdx.graphics.g2d.SpriteBatch;

 

public class FirstGame implements ApplicationListener { 

    //繪圖用的SpriteBatch 

    private SpriteBatch batch; 

    //紋理 

    private Texture texture; 

    //精靈 

    private Sprite sprite; 

    @Override

    public void create() { 

        batch = new SpriteBatch(); //實例化 

        texture=new Texture(Gdx.files.internal("image1.jpg")); 

        sprite=new Sprite(texture, 80, 80, 400, 300); 

        sprite.setPosition(10, 10); //位置 

        sprite.setRotation(15); //旋轉 

    }

 

    @Override

    public void dispose() { 

        // TODO Auto-generated method stub

 

    }

 

    @Override

    public void pause() { 

        // TODO Auto-generated method stub

 

    }

 

    @Override

    public void render() { 

        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); //清屏 

        batch.begin(); 

        sprite.draw(batch); 

        batch.end(); 

    }

 

    @Override

    public void resize(int width, int height) { 

        // TODO Auto-generated method stub

 

    }

 

    @Override

    public void resume() { 

        // TODO Auto-generated method stub

 

    }

 

}

 

效果:

  • SpxImage

    同時可以通過sprite的setColor方法為圖形著色。

 

 

setColor(float r, float g, float b, float a)

其中顏色的表述都是介於0,1之間的數

 

SpxImageSpxImage

  • 繪制的內容基本就這麼多,下一篇是關於關於2D場景的。

    寫在最後:

    1.關於混合問題,默認是開啟混合瞭的。這意味著圖形繪制完成時半透明的部分已經被混合瞭。當混合被關閉是任何已經在場景上的東西都會被紋理代替,這適合繪制大背景。

     batch.disableBlending();

    backgroundSprite.draw(batch);

    batch.enableBlending();

    2.關於性能優化

    SpriteBatch 有個構造函數可以指定最大緩沖數目。如果數值過低會造成額外的GPU調用;過高的話將占用過多的內存。

    在SpriteBatch有個字段為maxSpritesInBatch,可以先設置一個很高的緩沖數目,然後觀察maxSpritesInBatch的值以確定合適的緩沖值。

    還有一個字段renderCalls,在end被調用時,它的值表示在begin和end之間幾何聲明被送入GPU的次數。

    還有一個構造函數可以指定緩沖大小和數量,合理的設置可以極大地提供性能。

 

作者:htynkn 出處:http://www.cnblogs.com/htynkn/

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *