on 23-05-2012 04:42 PM
Just wondering if I'm being far to ambitious but I am trying to draw a layer of moving tiles (1 pixel per frame) using a spriteList. Its only an experiment to see how much I can push the Vita. Unfortunately I'm only getting 18 frames per second on the Vita (60 in the simulator) .the tilesheet I'm using is a 512*512 24bit png with 32*32 tiles on it (so the tile size is 16*16 pixels).
Am I doing some thing horribly wrong or am I just being insane thinking that the Vita should be well able to handle this?
I've put the code below, which is just modified from the GameEngine2D HelloSprite.
<code>
using System.Collections;
using System.Collections.Generic;
using System;
using System.Diagnostics;
using System.Text;
using Sce.Pss.Core;
using Sce.Pss.Core.Graphics;
using Sce.Pss.Core.Input;
using Sce.Pss.Core.Imaging;
using Sce.Pss.Core.Environment;
using Sce.Pss.HighLevel.GameEngine2D;
using Sce.Pss.HighLevel.GameEngine2D.Base;
static class MyFirstTileSheet
{
static int TILE_SIZE = 16;
static int TILES_PER_SHEET = 32;
static int NUM_TILESX = 55;
static int NUM_TILESY = 33;
static void Main( string[] args )
{
Sce.Pss.Core.Graphics.GraphicsContext context = new Sce.Pss.Core.Graphics.GraphicsContext();
uint sprites_capacity = 500*4;
uint draw_helpers_capacity = 400*4;
Director.Initialize( sprites_capacity, draw_helpers_capacity, context );
Director.Instance.GL.Context.SetClearColor( Colors.Yellow );
// set debug flags that display rulers to debug coordinates
//Director.Instance.DebugFlags |= DebugFlags.DrawGrid;
// set the camera navigation debug flag (press left alt + mouse to navigate in 2d space)
Director.Instance.DebugFlags |= DebugFlags.Navigate;
var scene = new Scene();
scene.Camera.SetViewFromViewport();
var texture_info2 = new TextureInfo( new Texture2D("/Application/ASSETS/TILESHEETS/tileb.pn
var texture_info = new TextureInfo( new Texture2D("/Application/ASSETS/TILESHEETS/tilebd.p
var spriteList = new SpriteList(texture_info2);
var spriteList2 = new SpriteList(texture_info);
for(int i = 0; i<NUM_TILESX;i++)
{
for(int ii = 0; ii<NUM_TILESY;ii++)
{
SpriteUV sprite = new SpriteUV();
sprite.Quad.S = texture_info.TextureSizef/TILES_PER_SHEET;
sprite.UV.T = new Vector2((1.0f/TILES_PER_SHEET) * (float)(i%TILES_PER_SHEET), (1.0f/TILES_PER_SHEET) * (float)(ii%TILES_PER_SHEET));
sprite.UV.S = new Vector2((TILE_SIZE/texture_info.TextureSizef.X),(T
Vector2 xy = new Vector2( i*TILE_SIZE, ii*TILE_SIZE );
sprite.Position = scene.Camera.CalcBounds().Min + xy;
Vector2 v = scene.Camera.CalcBounds().Max;
spriteList.AddChild(sprite);
}
}
SpriteUV sprite2 = new SpriteUV();
sprite2.Quad.S = texture_info.TextureSizef/TILES_PER_SHEET;
sprite2.UV.T = new Vector2((1.0f/TILES_PER_SHEET) * (float)(1%TILES_PER_SHEET), (1.0f/TILES_PER_SHEET) * (float)(1%TILES_PER_SHEET));
sprite2.UV.S = new Vector2((TILE_SIZE/texture_info.TextureSizef.X),(T
Vector2 xyz = new Vector2( 1*16, 1*16 );
scene.AddChild( spriteList );
scene.AddChild( spriteList2 );
spriteList2.AddChild(sprite2);
Director.Instance.GL.SetBlendMode( BlendMode.Normal );
Director.Instance.RunWithScene( scene, true );
FPSCounter fps = new FPSCounter();
int frameCounter = 0;
while ( !Input2.GamePad0.Cross.Press )
{
int count = 0;
int XX = 0;
int YY = 0;
spriteList.Cleanup();
foreach (var SpriteUV in spriteList.Children) {
//Console.WriteLine(count);
XX = 0;
if(SpriteUV.Position.X+1>854){
XX = (((int)SpriteUV.Position.X - (NUM_TILESX * TILE_SIZE))+1);
}else{
XX = ((int)SpriteUV.Position.X + 1);
}
YY = 0;
if(SpriteUV.Position.Y+1>480){
YY = (((int)SpriteUV.Position.Y - (NUM_TILESY * TILE_SIZE))+1);
}else{
YY = ((int)SpriteUV.Position.Y + 1);
}
Vector2 xy = new Vector2(XX, YY);
SpriteUV.Position = xy;
count++;
}
count = 0;
Sce.Pss.Core.Environment.SystemEvents.CheckEvents(
#if EXTERNAL_INPUT
// it is not needed but you can set external input data if you want
List<TouchData> touch_data_list = Touch.GetData(0);
Input2.Touch.SetData( 0, touch_data_list );
GamePadData pad_data = GamePad.GetData(0);
Input2.GamePad.SetData( 0, pad_data );
#endif // #if EXTERNAL_INPUT
Director.Instance.Update();
Director.Instance.Render();
Director.Instance.GL.Context.SwapBuffers();
Director.Instance.PostSwap();
fps.printFPS(frameCounter); //To the console
}
Director.Terminate();
System.Console.WriteLine( "Bye!" );
}
static string getDebug(){
return "Wakka wakka";
}
}
</code>
Solved! Go to Solution.
on 25-05-2012 04:04 PM
Hi Clumfest,
There's not too much that I have to say regarding the performance, however a contributing factor is the 1815 sprites. Although you have these organised in a SpriteList which is great, there is obviously still an overhead to having a such large number of sprites, but this approach is still better compared to having individual SpriteUVs
I've also noticed that you are calling spriteList.CleanUp() each frame. This will not only stop the SpriteList's actions and schedules, but it will traverse all of its children nodes and perform the same action. When you get past this point, you've now stopped the actions and schedules on all 1816 node objects. Following this, you are then traversing all 1815 node objects again, adjusting their position. So to summarise, in each frame you are looking at the nodes, twice as much as you probably should.
It's not too clear why you are calling CleanUp(), as you have no actions or schedules running, so this seems a wasted operation. If you really need to call it, then in your foreach loop, you can call...
SpriteUV.UnscheduleAll(); SpriteUV.StopAllActions();
Hope this helps.
James
on 27-05-2012 01:46 AM
Whats the difference between SpriteUV and Sprite files? Any pros and cons?
Come join The Freenode IRC at Channel #pss-dev!
I am merely a graphics designer who wants to program, go figure.
on 29-05-2012 10:43 AM
Hi James,
Thanks for the input. I removed the CleanUp() (dont know why i was even calling it) and got a few extra frames per second. I've taken increased the tile size to 32x32 as well as switching to RawSpriteTile and have seen a massive improvement. 60 fps on the vita while displaying 3 overlaping sprite lists (each are 31X18 tiles each with a diffrent 512x512 .png for each). This should be more than enough for any game we will make.
The code is below for anyone that is interested, but I must give cred to YstadYakuza as I used his example from another post to guide me in my code.
//AppMain.cs
using System.Collections;
using System.Collections.Generic;
using System;
using System.Diagnostics;
using System.Text;
using Sce.Pss.Core;
using Sce.Pss.Core.Graphics;
using Sce.Pss.Core.Input;
using Sce.Pss.Core.Imaging;
using Sce.Pss.Core.Environment;
using Sce.Pss.HighLevel.GameEngine2D;
using Sce.Pss.HighLevel.GameEngine2D.Base;
static class MyFirstTileSheet
{
static int TILE_SIZE = 32;
static int TILES_PER_SHEET = 16;
static int NUM_TILESX = 31;
static int NUM_TILESY = 18;
static void Main( string[] args )
{
Sce.Pss.Core.Graphics.GraphicsContext context = new Sce.Pss.Core.Graphics.GraphicsContext();
uint sprites_capacity = 500;
uint draw_helpers_capacity = 400;
Director.Initialize( sprites_capacity, draw_helpers_capacity, context );
Director.Instance.GL.Context.SetClearColor( Colors.Yellow );
// set debug flags that display rulers to debug coordinates
//Director.Instance.DebugFlags |= DebugFlags.DrawGrid;
// set the camera navigation debug flag (press left alt + mouse to navigate in 2d space)
Director.Instance.DebugFlags |= DebugFlags.Navigate;
var scene = new Scene();
scene.Camera.SetViewFromViewport();
var width = Director.Instance.GL.Context.GetViewport().Width;
var height = Director.Instance.GL.Context.GetViewport().Height;
System.Console.WriteLine( width );
Console.WriteLine(" ");
System.Console.WriteLine( height );
Console.WriteLine(" ");
var texture_info = new TextureInfo( new Texture2D("/Application/ASSETS/TILESHEETS/tileb.pn g", false ),new Vector2i(TILES_PER_SHEET,TILES_PER_SHEET) );
var texture_info2 = new TextureInfo( new Texture2D("/Application/ASSETS/TILESHEETS/tilebd.p ng", false ),new Vector2i(TILES_PER_SHEET,TILES_PER_SHEET) );
var texture_info3 = new TextureInfo( new Texture2D("/Application/ASSETS/TILESHEETS/tilebe.p ng", false ),new Vector2i(TILES_PER_SHEET,TILES_PER_SHEET) );
TileList spriteList = new TileList(texture_info, NUM_TILESX*NUM_TILESX );
for(int i = 0; i<NUM_TILESX;i++)
{
for(int ii = 0; ii<NUM_TILESY;ii++)
{
TRS trs = new TRS(new Bounds2(new Vector2(i*TILE_SIZE,ii*TILE_SIZE),new Vector2((i*TILE_SIZE)+TILE_SIZE,(ii*TILE_SIZE)+TIL E_SIZE)));
RawSpriteTile sprite = new RawSpriteTile(trs,new Vector2i(i%TILES_PER_SHEET,ii%TILES_PER_SHEET),fal se, false);
sprite.Quad.S = new Vector2 (TILE_SIZE,TILE_SIZE);
sprite.TileIndex2D = new Vector2i(i%TILES_PER_SHEET,ii%TILES_PER_SHEET);
spriteList.AddChild(sprite);
}
}
TileList spriteList2 = new TileList(texture_info2, NUM_TILESX*NUM_TILESX );
for(int i = 0; i<NUM_TILESX;i++)
{
for(int ii = 0; ii<NUM_TILESY;ii++)
{
TRS trs = new TRS(new Bounds2(new Vector2(i*TILE_SIZE,ii*TILE_SIZE),new Vector2((i*TILE_SIZE)+TILE_SIZE,(ii*TILE_SIZE)+TIL E_SIZE)));
RawSpriteTile sprite = new RawSpriteTile(trs,new Vector2i(i%TILES_PER_SHEET,ii%TILES_PER_SHEET),fal se, false);
sprite.Quad.S = new Vector2 (TILE_SIZE,TILE_SIZE);//(int)(texture_info.Texture Sizef/TILES_PER_SHEET),(int)(texture_info.TextureS izef/TILES_PER_SHEET));
sprite.TileIndex2D = new Vector2i(i%TILES_PER_SHEET,ii%TILES_PER_SHEET);
spriteList2.AddChild(sprite);
}
}
TileList spriteList3 = new TileList(texture_info3, NUM_TILESX*NUM_TILESX );
for(int i = 0; i<NUM_TILESX;i++)
{
for(int ii = 0; ii<NUM_TILESY;ii++)
{
TRS trs = new TRS(new Bounds2(new Vector2(i*TILE_SIZE,ii*TILE_SIZE),new Vector2((i*TILE_SIZE)+TILE_SIZE,(ii*TILE_SIZE)+TIL E_SIZE)));
RawSpriteTile sprite = new RawSpriteTile(trs,new Vector2i(i%TILES_PER_SHEET,ii%TILES_PER_SHEET),fal se, false);
sprite.Quad.S = new Vector2 (TILE_SIZE,TILE_SIZE);//(int)(texture_info.Texture Sizef/TILES_PER_SHEET),(int)(texture_info.TextureS izef/TILES_PER_SHEET));
sprite.TileIndex2D = new Vector2i(i%TILES_PER_SHEET,ii%TILES_PER_SHEET);
Vector2 v = scene.Camera.CalcBounds().Max;
spriteList3.AddChild(sprite);
}
}
scene.AddChild(spriteList3);
scene.AddChild(spriteList2);
scene.AddChild(spriteList);
Director.Instance.GL.SetBlendMode( BlendMode.Normal );
Director.Instance.RunWithScene( scene, true );
FPSCounter fps = new FPSCounter();
int frameCounter = 0;
while ( !Input2.GamePad0.Cross.Press )
{
int count = 0;
int XX = 0;
int YY = 0;
int moveSpeed = 2;
for(int i =0;i<spriteList.Count;i++) {
count++;
TRS trs = new TRS(new Bounds2(new Vector2((spriteList.Sprites[i].Quad.T.X)+ 1,(spriteList.Sprites[i].Quad.T.Y)+ 1),new Vector2((spriteList.Sprites[i].Quad.T.X)+TILE_SIZE + 1,(spriteList.Sprites[i].Quad.T.Y)+TILE_SIZE + 1)));
spriteList.Sprites[i].Quad = trs;// new RawSpriteTile(trs,spriteList.Sprites[i].TileIndex2 D,false, false);
TRS trs2 = new TRS(new Bounds2(new Vector2((spriteList2.Sprites[i].Quad.T.X)- 1,(spriteList2.Sprites[i].Quad.T.Y)- 1),new Vector2((spriteList2.Sprites[i].Quad.T.X)+TILE_SIZ E - 1,(spriteList2.Sprites[i].Quad.T.Y)+TILE_SIZE - 1)));
spriteList2.Sprites[i].Quad = trs2;// new RawSpriteTile(trs2,spriteList2.Sprites[i].TileInde x2D,false, false);
TRS trs3 = new TRS(new Bounds2(new Vector2((spriteList3.Sprites[i].Quad.T.X)+1,(sprit eList3.Sprites[i].Quad.T.Y)- 1),new Vector2((spriteList3.Sprites[i].Quad.T.X)+TILE_SIZ E + 1,(spriteList3.Sprites[i].Quad.T.Y)+TILE_SIZE - 1)));
spriteList3.Sprites[i].Quad = trs3;
}
Sce.Pss.Core.Environment.SystemEvents.CheckEvents( );
Director.Instance.Update();
Director.Instance.Render();
Director.Instance.GL.Context.SwapBuffers();
Director.Instance.PostSwap();
fps.printFPS(frameCounter); //To the console
}
Director.Terminate();
System.Console.WriteLine( "Bye!" );
}
}
//TileList.cs
using Sce.Pss.Core;
using Sce.Pss.HighLevel.GameEngine2D.Base;
namespace Sce.Pss.HighLevel.GameEngine2D
{
public class TileList : Node
{
/// <summary>The list of RawSpriteTile objects to render.</summary>
//public List< RawSpriteTile > Sprites = new List< RawSpriteTile >();
public RawSpriteTile[] Sprites;
public Vector4 Color = Colors.White;
public BlendMode BlendMode = BlendMode.Normal;
public TextureInfo TextureInfo;
public SpriteRenderer.ISpriteShader Shader = (SpriteRenderer.ISpriteShader)Director.Instance.Sp riteRenderer.DefaultShader;
public int Count = 0;
public TileList(TextureInfo texture_info, int size)
{
Sprites = new RawSpriteTile[size];
TextureInfo = texture_info;
}
public override void Draw()
{
Director.Instance.GL.SetBlendMode( BlendMode );
Shader.SetColor( ref Color );
Shader.SetUVTransform( ref Math.UV_TransformFlipV );
Director.Instance.SpriteRenderer.BeginSprites( TextureInfo, Shader, Sprites.Length );
foreach ( RawSpriteTile sprite in Sprites )
{
Director.Instance.SpriteRenderer.FlipU = sprite.FlipU;
Director.Instance.SpriteRenderer.FlipV = sprite.FlipV;
TRS copy = sprite.Quad;
Director.Instance.SpriteRenderer.AddSprite( ref copy, sprite.TileIndex2D );
}
Director.Instance.SpriteRenderer.EndSprites();
}
public void moveSprite(RawSpriteTile rt, int index)
{
Sprites[index] = rt;
}
public void AddChild(RawSpriteTile rt)
{
Sprites[Count] = rt;
Count++;
}
/// <summary>
/// Based on the tile size and texture dimensions, return the corresponding size in pixels.
/// For example you might want to do something like bob.Quad.S = bob.CalcSizeInPixels().
/// </summary>
public Vector2 CalcSizeInPixels()
{
// in the tile case, all sprites have the same pixel size
return TextureInfo.TileSizeInPixelsf;
}
}
}
//FPSCounter.cs
using System;
using System.Collections.Generic;
using Sce.Pss.Core;
using Sce.Pss.Core.Graphics;
using Sce.Pss.Core.Environment;
using Sce.Pss.Core.Input;
using Sce.Pss.HighLevel.UI;
using System.Diagnostics;
public class FPSCounter
{
Stopwatch stopwatch;
int frameCounter;
public FPSCounter ()
{
frameCounter = 0;
stopwatch = Stopwatch.StartNew();
}
public void printFPS(int frames)
{
if((stopwatch.ElapsedMilliseconds/1000.0f) >= 1){
Console.WriteLine(frameCounter);
stopwatch.Reset();
stopwatch.Start();
frameCounter = 0;
Console.WriteLine("");
}else{
frameCounter++;
}
}
}
on 29-05-2012 11:10 AM
|
on 05-06-2012 03:35 PM
Hi there!
In my own experiments,the first into tilemap, i was able to draw an entire very large tile map (20k+ tile of 16x16 or 32/32) without any slowdown (on vita), and that's 20k+tile draw in one call. This one use one vertex buffer with an entire vertex array (coord+uv) made at initialization. But, it's deprecated now because
->
In another experiment, i have an method wich draw only the visible tile in the screen. I made a vertex array contening vertex coord + texture uv of all the map (created at initialization), and an index buffer. I refill the index buffer with the corresponding index of the visible tile (and only when needed by the scroll), then refresh the index array in the vertex buffer (vertexBuffer.setIndex(...)).
This one should be able to draw an infinite size tilemap (as the memory can handle, because that draw only the some visible tile in the screen in fact) always at the same speed. But the maximum size of the map is sadly the size of a ushort / 6 (each tile is made of 2 triangle). So i can have only 10922 tiles in my map (i'm looking for a better solution). Making your own tile engine is something good. In OpenGL, this rendering method can be very speedfull using instancied array.
As the first methode, i use only 1 draw call to draw the map. And for these 2 methods i use a large texture contening all the tile i need (so i don't bind the texturea lot of time).
--
I think the gameengine 2d is not suitable to draw and manage a large amount of sprites (but i haven't experimented so much with it, so ii can be wrong).
on 05-06-2012 05:55 PM
fr_romain1985, that is some good info. I'm starting down this path am progressing slowly. Is any of your drawing code available online to look at?
05-06-2012 08:59 PM - edited 05-06-2012 09:05 PM
fr_romain1985, that is some good info. I'm starting down this path am progressing slowly. Is any of your drawing code available online to look at?
Yeah sure i will share with you! I'm progressing slowly too ![]()
You can download my actual work here (it's at an early stage, especially the tilemap, but i have a new version to upload soon, wich use index and clipping).
http://www.notnotme.com/misc/!!MVita.zip
In the new version i have removed an old sample too.
Ok i've put the newer tilemap code online.
Here is the TileMap class: http://pastebin.com/p30WUGzv
Here is the loader class : http://pastebin.com/WKrKBBUg
I've mad a tilemap editor in javafx 2.1 also, but i will not share this part of code. Anyway the xml structure is pretty easy to understand (but it's a pain in the ass to write the code by hand).
Basically you will see how it work (with index and clipping), but this is at an early stage of developpement..
* edit: it's not bug free
on 14-06-2012 05:39 PM
PSM Developer Registration (for free) on PSM DevPortal is required to post on the forum.
Please sign out then sign in again to the forum and PSM DevPortal after you have completed the registration.
フォーラムへ投稿をするにはPSM DevPortalへの登録(無料)が必要です。
登録後はフォーラムと
PSM DevPortalを一度ログアウトし、再度ログインしてください。


Website ©2013 Sony Computer Entertainment Europe
All content, game titles, trade names and/or trade dress, trademarks, artwork and associated imagery are trademarks and/or copyright material of their respective owners. All rights reserved. [more info]
%%http://community.eu.playstation.com/t5/Announcements/Beta-Trial-Information/td-p/11386362
best_shooter.png%%http://community.eu.playstation.com/t5/Announcements/Introducing-Best-of-PlayStation/td-p/13741979
best_driver.png%%http://community.eu.playstation.com/t5/Announcements/Introducing-Best-of-PlayStation/td-p/13741979
best_performer.png%%http://community.eu.playstation.com/t5/Announcements/Introducing-Best-of-PlayStation/td-p/13741979
best_footballer.png%%http://community.eu.playstation.com/t5/Announcements/Introducing-Best-of-PlayStation/td-p/13741979
best_fighter.png%%http://community.eu.playstation.com/t5/Announcements/Introducing-Best-of-PlayStation/td-p/13741979
best_creator.png%%http://community.eu.playstation.com/t5/Announcements/Introducing-Best-of-PlayStation/td-p/13741979
best_action_player.png%%http://community.eu.playstation.com/t5/Announcements/Introducing-Best-of-PlayStation/td-p/13741979
dev2.png%%http://community.eu.playstation.com/t5/Website-and-Forum-Help-Feedback/Producer-and-Developer-Ranks/td-p/18407352
trophy.gif%%http://community.eu.playstation.com/t5/Website-and-Forum-Help-Feedback/The-Community-Awards-FAQ/td-p/18407096
PSlogoSM.png%%http://community.eu.playstation.com/t5/Website-and-Forum-Help-Feedback/Online-Support-Coordinator-rank/td-p/18414870