собственно сабж, я тут делаю , делаю 2д проект, по типу Братья пилоты - загадка атлантической сельди, и столкнулся с такими штуками как смазывание при скролле, долгая подгрузка с флешки...просто подгрузка около 5 мб - примерно 20 сек - что очень долго , особенно при больших уровнях с нетайловыми фонами. Даже при подгрузке 512х512 - куска фона - притормаживание более чем заметное. Есть какие-то замечания?
1. Ы? Не понял про размазывание.
2. 5mb - 20 секунд?? sceIoRead ? Если что-то невминяемое, например std::streams (респект тому, кто собрал STL :), то я возможно нихуя и не удивлен. Пасти код, посмотрим. Кстати, про флешку уже писали, лучше маленькую и быструю :)
Опиши это смазывание (неравномерность, motion blur:) , etc...)
sceIoRead ?
Юзаются fopen fread, я подозревал что сдк их както должно перегрузить под псп?? Если все не так то будем посмотреть sceIoRead )))
А смазывание такое - вот статическая картинка и на ней допустим черные полосы, так если ее скролить, то черное будет все )))....вобщем такое ощущение как в тфт след от мыши...вооотт....потому я и спрашиваю, а не тфт ли это??
а кстати, какие флешки "быстрые"? просто та что есть - это 1GB Memory Stick Pro Duo, просто интересно, надо будет прикупить тогда самую быструю )))
кстати, а кто слышал про хард драйвы к псп?? там вроде уже и 4Гб прикупить можно....может его юзать??
> кстати, а кто слышал про хард драйвы к псп?? там вроде уже и 4Гб прикупить можно....может его юзать??
Неофициально, есть адаптер 4 IN 1, который втыкается вместо memory stick. Позволяет использовать CF, SD и обычные memory stick.
Есть и официальный hard drive на 4 Гб, только не знаю где продают.
PS: Какая у тебя флешка (фирма)?
bada
Нежелательно libc юзать, лучше запретить. У меня пока используется несколько функций libc, которые прямо где надо и объявлены extern. Но это плохо.
bada
> Юзаются fopen fread, я подозревал что сдк их както должно перегрузить под псп?? Если все не так то будем посмотреть sceIoRead )))
Ничего не перегружает, это прямой драйвер устройства, задающийся ms0 host0 umd0 и т.д.
оно по этому имени как в Unix'e подключает драйвер того устройства которое отвечает за этот префикс
(sceIoAddDrv,sceIoDelDrv)
> А смазывание такое - вот статическая картинка и на ней допустим черные полосы, так если ее скролить, то черное будет все )))....вобщем такое ощущение как в тфт > след от мыши...вооотт....потому я и спрашиваю, а не тфт ли это??
Ищи проблему в GE Display List, очистка экрана (sceGuClear...)
Все это там, ибо такого не должно быть. Посмотри на BurnOut и пойми что на других играх такого убер-эффекта нет :)
насчет fopen таки перегружена в libc и там после какихто шаманств идет вызов sceIoOpen, мой глаз не заметил принципиальных тормозов в этой функции.
а насчет GE Display List и sceGuClear процесс такой приблеженно это то что было заимствавано из JGE
void Init() { sceGuInit( ); sceGuStart( GU_DIRECT, list); mVideoBufferStart = 0; sceGuDrawBuffer( BUFFER_FORMAT, ( void *)mVideoBufferStart, FRAME_BUFFER_WIDTH); mVideoBufferStart += FRAME_BUFFER_SIZE; sceGuDispBuffer( SCREEN_WIDTH, SCREEN_HEIGHT, ( void *)mVideoBufferStart, FRAME_BUFFER_WIDTH); mVideoBufferStart += FRAME_BUFFER_SIZE; mCurrentPointer = mVideoBufferStart; sceGuOffset( 2048 - ( SCREEN_WIDTH/2), 2048 - ( SCREEN_HEIGHT/2)); sceGuViewport( 2048, 2048, SCREEN_WIDTH, SCREEN_HEIGHT); sceGuScissor( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); sceGuEnable( GU_SCISSOR_TEST); sceGuFrontFace( GU_CW); sceGuEnable( GU_TEXTURE_2D); sceGuShadeModel( GU_SMOOTH); sceGuEnable( GU_BLEND); sceGuBlendFunc( GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); sceGuClear( GU_COLOR_BUFFER_BIT); sceGuFinish( ); sceGuSync( 0, 0); sceDisplayWaitVblankStart( ); sceGuDisplay( 1); } void GraphicCore::BeginRender( ) { sceKernelDcacheWritebackInvalidateAll( ); sceGuStart( GU_DIRECT, list); sceGuTexMode( TEXTURE_FORMAT, 0, 0, mSwizzle); sceGuTexFilter( GU_NEAREST, GU_NEAREST); } void GraphicCore::EndRender( ) { sceGuFinish( ); sceGuSync( 0, 0); if ( mVsync) { sceDisplayWaitVblankStart( ); } sceGuSwapBuffers( ); mCurrentTex = -1; mCurrentBlend = -1; }
соттветственно между бегин и идет вывод текстур
void GraphicCore::RenderQuad(Quad* quad, float xo, float yo, float angle, float xScale, float yScale) { if( quad == NULL) { return; } if ( mCurrentTex != quad->mTex->mTexId) { sceGuTexImage( 0, quad->mTex->mTexWidth, quad->mTex->mTexHeight, quad->mTex->mTexWidth, quad->mTex->mBitsPtr); mCurrentTex = quad->mTex->mTexId; } if ( mCurrentBlend != quad->mBlend) { sceGuTexFunc( quad->mBlend, GU_TCC_RGBA); mCurrentBlend = quad->mBlend; } //float destWidth = quad->mWidth*quad->mScaleX; float destHeight = quad->mHeight*yScale; float x = xo - quad->mHotSpotX*xScale; float y = yo - quad->mHotSpotY*yScale; float start, end; float width; float destWidth; float fixedWidth = SLICE_SIZE_F*xScale; float xx, yy; float cosAngle = cosf( angle); float sinAngle = sinf( angle); if ( quad->mHFlipped)// || quad->mVFlipped) { for ( end = quad->mX, start = quad->mX+quad->mWidth; start > end; start -= SLICE_SIZE_F) { // allocate memory on the current display list for temporary storage // in order to rotate, we use 4 vertices this time struct Vertex* vertices = ( struct Vertex*)sceGuGetMemory( 4 * sizeof( struct Vertex)); if ( ( start - SLICE_SIZE_F) > end) { width = SLICE_SIZE_F; destWidth = fixedWidth; } else { width = start-end; destWidth = width*xScale; } vertices[0].u = start; vertices[0].v = quad->mY; vertices[0].color = quad->mColor[0]; vertices[0].x = x; vertices[0].y = y; vertices[0].z = 0.0f; vertices[1].u = start - width; vertices[1].v = quad->mY; vertices[1].color = quad->mColor[1]; vertices[1].x = x + destWidth; vertices[1].y = y; vertices[1].z = 0.0f; vertices[2].u = start; vertices[2].v = quad->mY + quad->mHeight; vertices[2].color = quad->mColor[2]; vertices[2].x = x; vertices[2].y = y + destHeight; vertices[2].z = 0.0f; vertices[3].u = start - width; vertices[3].v = quad->mY + quad->mHeight; vertices[3].color = quad->mColor[3]; vertices[3].x = x + destWidth; vertices[3].y = y + destHeight; vertices[3].z = 0.0f; if ( quad->mVFlipped) { Swap( &vertices[0].v, &vertices[2].v); Swap( &vertices[1].v, &vertices[3].v); } if ( angle != 0.0f) { for ( int i=0;i<4;i++) { xx = ( cosAngle*( vertices[i].x-xo) - sinAngle*( vertices[i].y-yo) + xo); yy = ( sinAngle*( vertices[i].x-xo) + cosAngle*( vertices[i].y-yo) + yo); vertices[i].x = xx; vertices[i].y = yy; } } x += destWidth; sceGuDrawArray( GU_TRIANGLE_STRIP,GU_TEXTURE_32BITF|TEXTURE_COLOR_FORMAT|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, vertices); } } else { for ( start = quad->mX, end = quad->mX+quad->mWidth; start < end; start += SLICE_SIZE_F) { // allocate memory on the current display list for temporary storage // in order to rotate, we use 4 vertices this time struct Vertex* vertices = ( struct Vertex*)sceGuGetMemory( 4 * sizeof( struct Vertex)); if ( ( start + SLICE_SIZE_F) < end) { width = SLICE_SIZE_F; destWidth = fixedWidth; } else { width = end-start; destWidth = width*xScale; } vertices[0].u = start; vertices[0].v = quad->mY; vertices[0].color = quad->mColor[0]; vertices[0].x = x; vertices[0].y = y; vertices[0].z = 0.0f; vertices[1].u = start + width; vertices[1].v = quad->mY; vertices[1].color = quad->mColor[1]; vertices[1].x = x + destWidth; vertices[1].y = y; vertices[1].z = 0.0f; vertices[2].u = start; vertices[2].v = quad->mY + quad->mHeight; vertices[2].color = quad->mColor[2]; vertices[2].x = x; vertices[2].y = y + destHeight; vertices[2].z = 0.0f; vertices[3].u = start + width; vertices[3].v = quad->mY + quad->mHeight; vertices[3].color = quad->mColor[3]; vertices[3].x = x + destWidth; vertices[3].y = y + destHeight; vertices[3].z = 0.0f; if ( quad->mVFlipped) { Swap( &vertices[0].v, &vertices[2].v); Swap( &vertices[1].v, &vertices[3].v); } if ( angle != 0.0f) { for ( int i=0;i<4;i++) { xx = ( cosAngle*( vertices[i].x-xo) - sinAngle*( vertices[i].y-yo) + xo); yy = ( sinAngle*( vertices[i].x-xo) + cosAngle*( vertices[i].y-yo) + yo); vertices[i].x = xx; vertices[i].y = yy; } } x += destWidth; sceGuDrawArray( GU_TRIANGLE_STRIP,GU_TEXTURE_32BITF|TEXTURE_COLOR_FORMAT|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, vertices); } } }
bada
сорри не увидел про (fread,fopen) ними неззя пользоваться СОВСЕМ!!! я расказывал о sceIoOpen
bada
сходу :
texture width,height - какие (это важно ибо есть еще tbw)
какого разиера прямоугольничкм рендериш ?
destWidth destHeight
bada
Еще , внимательно прочитай FAQ -PSP Development про InvalidateCache
Он у тебя стоит в позорном месте
Для теста лучше таки поставить перед DrawArray и там можна InvalidateRange
гм..это получается что те библиотеки что портированы на псп типа pnglib надо
переписывать под sceIOOpen?
я загружаю картинки при помощи pnglib свизлю и это - высота и ширина которая получилась ,
прямоугольник рендера такой же.
вот
Texture * GraphicCore::LoadTexture(const char* filename, bool useVideoRAM)
{
int pixelformat = PIXEL_FORMAT;
u32* p32;
u16* p16;
png_structp png_ptr;
png_infop info_ptr;
unsigned int sig_read = 0;
png_uint_32 width, height;
int bit_depth, color_type, interlace_type, x, y;
u32* line;
FILE *fp;
if ((fp = fopen(filename, "rb")) == NULL)
{
LOG_ERROR("Cant find file : %s", filename);
return NULL;
}
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL)
{
fclose(fp);
return NULL;
}
png_set_error_fn(png_ptr, (png_voidp) NULL, (png_error_ptr) NULL, user_warning_fn);
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{
fclose(fp);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
return NULL;
}
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, sig_read);
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL);
png_set_strip_16(png_ptr);
png_set_packing(png_ptr);
if (color_type == PNG_COLOR_TYPE_PALETTE)
{
png_set_palette_to_rgb(png_ptr);
}
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
{
png_set_gray_1_2_4_to_8(png_ptr);
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
{
png_set_tRNS_to_alpha(png_ptr);
}
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
line = (u32*) malloc(width * 4);
if (!line)
{
fclose(fp);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
return NULL;
}
Texture * tex = new Texture();
if (tex)
{
tex->mWidth = width;
tex->mHeight = height;
tex->mFlip = false;
tex->mTexWidth = getNextPower2(width);
tex->mTexHeight = getNextPower2(height);
int size = tex->mTexWidth * tex->mTexHeight * sizeof(PIXEL_TYPE);
if (useVideoRAM && (mCurrentPointer + size) < 0x200000)
{
tex->mInVideoRAM = true;
tex->mBitsPtr = (PIXEL_TYPE*) (0x04000000+0x40000000+mCurrentPointer);
mCurrentPointer += size;
}
else
{
tex->mInVideoRAM = false;
tex->mBitsPtr = (PIXEL_TYPE*) memalign(16, size);
memset(tex->mBitsPtr, 0, size);
}
PIXEL_TYPE* buffer = tex->mBitsPtr;
if (mSwizzle)
{
buffer = (PIXEL_TYPE*) memalign(16, tex->mTexWidth * tex->mTexHeight * sizeof(PIXEL_TYPE));
memset(buffer, 0, tex->mTexWidth * tex->mTexHeight * sizeof(PIXEL_TYPE));
}
if (buffer)
{
tex->mTexId = mTexCounter++;
p32 = (u32*) buffer;
p16 = (u16*) p32;
for (y = 0; y < (int)height; y++)
{
png_read_row(png_ptr, (u8*) line, png_bytep_NULL);
for (x = 0; x < (int)width; x++)
{
u32 color32 = line[x];
u16 color16;
int a = (color32 >> 24) & 0xff;
int r = color32 & 0xff;
int g = (color32 >> 8) & 0xff;
int b = (color32 >> 16) & 0xff;
switch (pixelformat) {
case PSP_DISPLAY_PIXEL_FORMAT_565:
color16 = (r >> 3) | ((g >> 2) << 5) | ((b >> 3) << 11);
*(p16+x) = color16;
break;
case PSP_DISPLAY_PIXEL_FORMAT_5551:
color16 = (r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10) | ((a >> 7) << 15);
*(p16+x) = color16;
break;
case PSP_DISPLAY_PIXEL_FORMAT_4444:
color16 = (r >> 4) | ((g >> 4) << 4) | ((b >> 4) << 8) | ((a >> 4) << 12);
*(p16+x) = color16;
break;
case PSP_DISPLAY_PIXEL_FORMAT_8888:
color32 = r | (g << 8) | (b << 16) | (a << 24);
*(p32+x) = color32;
break;
}
}
p32 += tex->mTexWidth;
p16 += tex->mTexWidth;
}
if (mSwizzle)
{
swizzle_fast((u8*)tex->mBitsPtr, (const u8*)buffer, tex->mTexWidth*sizeof(PIXEL_TYPE), tex->mHeight);
free (buffer);
}
}
else
{
delete tex;
tex = NULL;
}
}
free (line);
png_read_end(png_ptr, info_ptr);
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
fclose(fp);
return tex;
}если много кода то скажите как под кат убрать
а насчет sceKernelDcacheWritebackInvalidateAll(); - он вроде и делает InvalidateRange и InalidateCache ??
он вроде таки и стоит перед выводом
те
BeginRender
Render (где каждый выводит свой спрайт)
EndRender
в чем трабла?
bada
Это КЕШ!!! Я же сказал где надо ставить (и то только для проверки)
По ответу я не понял какого конкретно размера то ,что плохо работает, я спрашиваю не потому что мне любопытно, поверь :)
А насчет CACHE таки почитай R4000 Users Manual, ибо ты очень конкретно путаешь и не понимаешь этой сущности.
bada
>> я загружаю картинки при помощи pnglib свизлю и это - высота и ширина которая получилась ,
Что это за код такой? Так игры не пишут :) Проблема не в fopen\fclose, проблема в религии, да...
Тема в архиве.