本章内容概述了如何绘制图像的使用和libgdx如何简化并通过sprite batch类优化了任务。
一张从它最初的格式(eg,PNG)被解码然后上传到图形处理器的图片被叫做纹理。绘制纹理,几何图形和纹理是通过指定每个几何图形的顶点来描述和应用实施的,这个顶点是与几何图形的纹理相一致的。。例如几何图形是一个矩形,然后应用纹理以便每个矩形的角落和纹理的角落相一致
在实际绘图中,首先纹理是有边界的,那么几何图形用OpenGL来绘制。由2者确认纹理在屏幕上位置尺寸和位置,一个是几何图形 另一个是如何配置OpenGL viewport。
许多2D游戏配置viewport来匹配屏幕分辨率。意思是几何图形由像素指定,在屏幕适当的尺寸和位置中使它容易绘制纹理。
绘制纹理映射到矩形这是很常见的。多次绘制同一个纹理或者纹理的不同部位也是很常见的。每次发送一个矩形到图形处理器来绘制这将是没有效率的 。对于被声明的纹理可以同时发送许多矩形到图形处理器。这就是SpriteBatch类做的事
SpriteBatch为每个矩形的绘制给出一个纹理坐标。它把没有提交给图形处理器的几何图形聚集到一起。如果和上一个纹理不同,那么它绑定上一个纹理,一起提交把几何图形聚集到一起绘制
,然后开始为新的纹理来聚集几何图形。
每隔几个矩形改变纹理是为了防止SpriteBatch批处理较多的几何图形来绘制。绑定纹理是一个有点昂贵的操作。由于这些原因。常见在大图像里存储许多小图像,在最大化几何图形的批处理或避免纹理改变之中的较大图像区域绘制。请参阅 TexturePacker 更多信息
使用SpriteBatch类如下:
publicclassGameimplementsApplicationListener{
privateSpriteBatch batch;
publicvoid create ()
{
batch =newSpriteBatch();
}
publicvoid render ()
{ Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);// 这句话用来清空屏幕
batch.begin(); // 绘制从这开始
batch.end();
}
publicvoid resize (int width,int height){}
publicvoid pause (){}
publicvoid resume (){}
publicvoid dispose (){}
}
所有SpriteBatch类的绘制需要调用 begin 和end方法。非SpriteBatch绘制不能发生begin 和 end。
Texture类解码一个图像文件并载入它到图形处理器的内存中。图像文件将被放置在一个角色assets的文件夹中。图像尺寸必须是2个N次方(如16X16,64X256等)
privateTexture texture; ...
texture =newTexture(Gdx.files.internal("image.png")); ...
batch.begin();
batch.draw(texture,10,10);
batch.end();
纹理被创建并通过SpriteBatch 来绘制。纹理绘制在一个高度和宽度为10,10的矩形相当的纹理大小。SpriteBatch有许多绘制纹理的方法
Method signature | Description |
draw(Texture texture, float x, float y) | Draws the texture using the texture's width and height |
draw(Texture texture, float x, float y, int srcX, int srcY, int srcWidth, int srcHeight) | Draws a portion of the texture. |
draw(Texture texture, float x, float y, float width, float height, int srcX, int srcY, int srcWidth, int srcHeight, boolean flipX, boolean flipY) | Draws a portion of a texture, stretched to the width and height, and optionally flipped. |
draw(Texture texture, float x, float y, float originX, float originY, float width, float height, float scaleX, float scaleY, float rotation, int srcX, int srcY, int srcWidth, int srcHeight, boolean flipX, boolean flipY) | This monster method draws a portion of a texture, stretched to the width and height, scaled and rotated around an origin, and optionally flipped. |
draw(Texture texture, float x, float y, float width, float height, float u, float v, float u2, float v2) | This draws a portion of a texture, stretched to the width and height. This is a somewhat advanced method as it uses texture coordinates from 0-1 rather than pixel coordinates. |
draw(Texture texture, float[] spriteVertices, int offset, int length) | This is an advanced method for passing in the raw geometry, texture coordinates, and color information. |
TextureRegion
TextureRegion类介绍了一个在纹理内的矩形对于仅绘制一部分纹理来说是有用的
privateTextureRegion region;
... texture =newTexture(Gdx.files.internal("image.png"));
region =newTextureRegion(texture,20,20,50,50);
... batch.begin();
batch.draw(region,10,10);
batch.end();
上方声明一个 20,,20,50,50的纹理部分,然后再10,10坐标处绘制。同样能通过纹理和SpriteBatch的其他参数来实现,但TextureRegion使它有一个单例用来方便声明。
SpriteBatch关于绘制纹理区域有许多方法。
Method signature | Description |
draw(TextureRegion region, float x, float y) | Draws the region using the width and height of the region. |
draw(TextureRegion region, float x, float y, float width, float height) | Draws the region, stretched to the width and height. |
draw(TextureRegion region, float x, float y, float originX, float originY, float width, float height, float scaleX, float scaleY, float rotation) | Draws the region, stretched to the width and height, and scaled and rotated around an origin. |
Sprite
Sprite 类声明一个用来绘制的几何图形的颜色和纹理区域
privateSprite sprite;
... texture =newTexture(Gdx.files.internal("image.png"));
sprite =newSprite(texture,20,20,50,50);
sprite.setPosition(10,10);
sprite.setRotation(45);
... batch.begin();
sprite.draw(batch);
batch.end();
上方20,20,50,50声明了纹理的一个部分。旋转45度后绘制在10,10。同样通过Texture 或者 TextureRegion 和SpriteBatch的其他参数。但Sprite使它有一个单例对象来方面声明一切。同样的因为Sprite只有在必要时才重新计算和存储几何图形。如果缩放,旋转或者其他性能在不改变帧数的情况下Sprite 将更有效率。
注意Sprite混合模式信息具有视图信息。这使Sprite 当应用一种设计模式,希望严格分开的
模型与视图时不适用。
在这种情况下,使用Texture 或textureregion可能更有意义。
当纹理绘制时,能使用Sprite来着色。
privateTexture texture;
privateTextureRegion region;
privateSprite sprite;
... texture =newTexture(Gdx.files.internal("image.png"));
region =newTextureRegion(texture,20,20,50,50);
sprite =newSprite(texture,20,20,50,50);
sprite.setPosition(100,10);
sprite.setColor(0,0,1,1);
... batch.begin();
batch.setColor(1,0,0,1);
batch.draw(texture,10,10);
batch.setColor(0,1,0,1);
batch.draw(region,50,10);
sprite.draw(batch);
batch.end();
上方显示怎样绘制纹理,纹理区域和sprite以及着色。颜色值用区域为1-0的RGBA来描述。如果blending(混合)被禁用Alpha则可以忽略。
Blending
Blending默认是打开的。意思是当一个纹理绘制时,纹理的半透明部分被已经在屏幕上位置的像素合并。
当Blending关闭时,已经在屏幕位置上的任何一切由纹理取代。除非blending是必要的,为了更高效一般建议关闭它。例如当一个巨大的背景图片绘制超出整个屏幕时,
首先禁用blend将获得性能提升。
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);// This cryptic line clears the screen清空屏幕.
batch.begin();
batch.disableBlending();
backgroundSprite.draw(batch);
batch.enableBlending(); // Other drawing here在这里绘制其他.
batch.end();
注意:每一帧确定清空屏幕。如果没有这么做aplha能绘制在纹理上数百次,使它不透明。同样的当每帧清除时一些GPU的运行结构会更好,即使不透明图片的绘制超出整个屏幕
Viewport
sprite batch管理自己的投影变换矩阵。当SpriteBatch 创建时,它使用当前应用程序的大小来启动一个根据y-up坐标的系统垂直方向投影。当被开始调用时,SpriteBatch 就启动了viewport。
注意:一旦我们有文件配置视图,我们应该链接在这里。
Performance tuning(性能优化)
SpriteBatch有一个构造函数,在发送到GPU之前可以被放到缓冲区,用来设置最大sprite的数量。如果太低(low),GPU则会造成额外的调用。
如果这是太高,该sprite batch将使用更多的内存。
SpriteBatch有一个public int的字段叫maxSpritesInBatch。这表明sprite的最高数量再一次发送到SpriteBatch的生命周期。设置一个巨大的SpriteBatch尺寸然后检查这个字段
能帮助确定理想的SpriteBatch大小。它将等于或者大于maxSpritesInBatch。这个字段可能在任意时刻被重置被0.
SpriteBatch 有一个public int 字段叫renderCalls。在end被调用之后,这个字段表明 在最后调用begin和end之间一个几何图形的batch发送到GPU。
当不同的纹理必须绑定时,或者SpriteBatch 有足够填充sprites 的缓存时发生。如果SpriteBatch 尺寸和renderCalls够大(可能超过15-20),它表明许多纹理将被绑定。
SpriteBatch有一个附加的构造函数根据size和一个buffer的数目。这是一个高级功能 原因是VBO(顶点缓冲对象)的使用而不是通常的虚拟应用。
维护一个列表的缓冲区,每次渲染调用list中的下一个(附近的包wrapping around)。当maxSpritesInBatch低renderCalls大时,它可能能提供一个小的性能提升
来源:https://www.cnblogs.com/tianjian/archive/2011/07/28/2120365.html