 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
centralunit
Joined: 19 Nov 2006 Posts: 4
|
Posted: Sun Nov 19, 2006 12:58 pm Post subject: [solved] Issues with Transparent Texture in VRAM |
|
|
Greetings!
When I use a 128x128 transparent texture, staticly allocated in VRAM, I get 5-6 white line artifakts across the texture. However if I use the same texture in system ram it works perfectly. The format Im using is 4444, Ive also tried 8888 but same result.
I dont think it's an texture allocation problem since my other textures work like they should. Im mixing 5650 and 4444 textures. Ive tried to only have my transparent texture in VRAM but I get the same white artifakts.
I also don't think it's a cache flush problem since it's only my transparent texture that get these artifacts.
Im also using the PSPTexTool, created by Henrik Rydgård, to convert my png textures.
here is my code for GU Init
| Code: |
m_pBackBuffer = m_VRAM.getStaticVramBuffer( m_BufferWidth, m_ScreenHeight, GU_PSM_5650 );
m_pFrontBuffer = m_VRAM.getStaticVramBuffer( m_BufferWidth, m_ScreenHeight, GU_PSM_5650 );
m_pZBuffer = m_VRAM.getStaticVramBuffer( m_BufferWidth, m_ScreenHeight, GU_PSM_4444 );
m_pShadowMapTarget = m_VRAM.getStaticVramTexture( 128, 128, GU_PSM_4444 );
sceGuInit();
sceGuStart( GU_DIRECT, GetDrawList() );
sceGuDrawBuffer( GU_PSM_5650, m_pBackBuffer, m_BufferWidth );
sceGuDispBuffer( m_ScreenWidth, m_ScreenHeight, m_pFrontBuffer, m_BufferWidth );
sceGuDepthBuffer( m_pZBuffer, m_BufferWidth );
sceGuOffset( 2048 - (m_ScreenWidth/2),2048 - (m_ScreenHeight/2) );
sceGuViewport( 2048,2048, m_ScreenWidth, m_ScreenHeight);
sceGuDepthRange( 65535,0 );
sceGuScissor( 0, 0, m_ScreenWidth, m_ScreenHeight );
sceGuEnable(GU_SCISSOR_TEST);
sceGuDepthFunc(GU_GEQUAL);
sceGuEnable(GU_DEPTH_TEST);
sceGuFrontFace(GU_CW);
sceGuShadeModel(GU_SMOOTH);
sceGuEnable(GU_CULL_FACE);
sceGuEnable(GU_TEXTURE_2D);
sceGuEnable(GU_CLIP_PLANES);
// sceGuClutMode(GU_PSM_4444,0,255,0);
// sceGuClutLoad(256/8,palette);
sceGuEnable(GU_LIGHTING);
sceGuEnable(GU_LIGHT0);
sceGuEnable(GU_LIGHT1);
sceGuFinish();
sceGuSync(0,0);
sceDisplayWaitVblankStart();
sceGuDisplay(GU_TRUE);
|
here is the code for uploading the texture to vram. Im doing this when I load my level. getStaticVramTexture is the same as in the sdk samples.
| Code: |
void TextureManager::UploadTexture( unsigned int a_idTexture, bool a_bStatic )
{
Texture* pTexture = m_vTexturePool[ a_idTexture ];
if( a_bStatic )
{
pTexture->m_pVRAM = m_pVRAM->getStaticVramTexture( pTexture->m_ulCanvasWidth, pTexture->m_ulHeight, pTexture->m_Format );
sceGuStart( GU_DIRECT, m_pDevice->GetDrawList() );
sceGuCopyImage( pTexture->m_Format, 0, 0, pTexture->m_ulWidth, pTexture->m_ulHeight, pTexture->m_ulCanvasWidth, pTexture->m_pBuffer, 0, 0, pTexture->m_ulCanvasWidth, pTexture->m_pVRAM );
sceGuFinish();
sceGuSync( 0, 0 );
}
else
{
pTexture->m_pVRAM = (void*) sceGuGetMemory( (pTexture->m_ulCanvasWidth*pTexture->m_ulCanvasHeight)*pTexture->m_bpp );
sceGuCopyImage( pTexture->m_Format, 0, 0, pTexture->m_ulWidth, pTexture->m_ulHeight, pTexture->m_ulCanvasWidth, pTexture->m_pBuffer, 0, 0, pTexture->m_ulCanvasWidth, pTexture->m_pVRAM );
sceGuTexSync();
}
}
|
here is the code for activating the texture
| Code: |
void TextureManager::SetTexture( unsigned int a_idTexture )
{
Texture* pTexture = m_vTexturePool[ a_idTexture ];
sceGuEnable( GU_TEXTURE_2D );
sceGuTexFunc( GU_TFX_MODULATE, GU_TCC_RGBA );
sceGuTexWrap( GU_REPEAT, GU_REPEAT );
sceGuTexFilter( GU_LINEAR, GU_LINEAR );
sceGuTexScale( 1.0f, 1.0f );
sceGuTexOffset( 0.0f, 0.0f );
if( pTexture->m_pVRAM != NULL )
{
sceGuTexMode( pTexture->m_Format, 0, 0, pTexture->m_bSwizzled );
sceGuTexImage( 0, pTexture->m_ulCanvasWidth, pTexture->m_ulCanvasHeight, pTexture->m_ulCanvasWidth, pTexture->m_pVRAM );
}
else
{
sceGuTexMode( pTexture->m_Format, 0, 0, pTexture->m_bSwizzled );
sceGuTexImage( 0, pTexture->m_ulCanvasWidth, pTexture->m_ulCanvasHeight, pTexture->m_ulCanvasWidth, pTexture->m_pBuffer );
}
}
|
this is how I render the transparent objects.
| Code: |
sceGuStart( GU_DIRECT, GetDrawList() );
sceGuClearColor( 0xff554433 );
sceGuClearDepth( 0 );
sceGuClear( GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT );
sceGuTexEnvColor( 0xffff00 );
sceGuAmbientColor( 0xffffffff );
sceGuSpecular(12.0f);
sceGuAmbient(0x00222222);
// Update camera
m_pCamera->Update( m_CellSelector.GetPos() );
sceGumMatrixMode(GU_MODEL);
sceGuDisable( GU_LIGHTING );
sceGuEnable( GU_BLEND );
sceGuBlendFunc( GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 );
sceGuTexFunc( GU_TFX_MODULATE, GU_TCC_RGBA );
m_pTextureManager->SetTexture( 4 );
// Draw player X
for( size_t i=0; i<m_PlayerXData.m_vOnCells.size(); i++ )
{
sceGumLoadIdentity();
sceGumTranslate( &m_PlayerXData.m_vOnCells[i]->m_vPos );
sceGumDrawArray( GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_NORMAL_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_3D, m_PlayerXMesh.GetNumVerts(), 0, m_PlayerXMesh.GetVertices() );
}
sceGuFinish();
sceGuSync( 0, 0 );
sceDisplayWaitVblankStart();
m_pBackBuffer = sceGuSwapBuffers();
|
Hope I have provided you all with usefull information. Tell me if I need to add something. Thanks in advance.
PS. Ill try to get a screenshot.
// CentralUnit
Last edited by centralunit on Mon Nov 20, 2006 10:45 pm; edited 1 time in total |
|
| Back to top |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Sun Nov 19, 2006 10:58 pm Post subject: Re: Issues with Transparent Texture in VRAM |
|
|
| Quote: | here is the code for uploading the texture to vram. Im doing this when I load my level. getStaticVramTexture is the same as in the sdk samples.
| Code: |
void TextureManager::UploadTexture( unsigned int a_idTexture, bool a_bStatic )
{
Texture* pTexture = m_vTexturePool[ a_idTexture ];
if( a_bStatic )
{
pTexture->m_pVRAM = m_pVRAM->getStaticVramTexture( pTexture->m_ulCanvasWidth, pTexture->m_ulHeight, pTexture->m_Format );
sceGuStart( GU_DIRECT, m_pDevice->GetDrawList() );
sceGuCopyImage( pTexture->m_Format, 0, 0, pTexture->m_ulWidth, pTexture->m_ulHeight, pTexture->m_ulCanvasWidth, pTexture->m_pBuffer, 0, 0, pTexture->m_ulCanvasWidth, pTexture->m_pVRAM );
sceGuFinish();
sceGuSync( 0, 0 );
}
else
{
pTexture->m_pVRAM = (void*) sceGuGetMemory( (pTexture->m_ulCanvasWidth*pTexture->m_ulCanvasHeight)*pTexture->m_bpp );
sceGuCopyImage( pTexture->m_Format, 0, 0, pTexture->m_ulWidth, pTexture->m_ulHeight, pTexture->m_ulCanvasWidth, pTexture->m_pBuffer, 0, 0, pTexture->m_ulCanvasWidth, pTexture->m_pVRAM );
sceGuTexSync();
}
}
|
|
I think you got something wrong about sceGuGetMemory and it's usage. It does not allocate memory in VRAM or sth alike. All it does is return a pointer into your drawlist of the given size (which lies in system memory and not in VRAM). This pointer then is only legal during the one sceGuStart/sceGuFinish block (unless you have a double-buffered drawlist). After that, the memory in that area is very probable overwritten by commands for GU (which could lead to artifacts), so it's generally bad to store your textures there. Apart from that, you waste a lot of time (and memory) copying your texture from one position in sysram to another one, which you anyway would need to do every frame.
So basically, your whole "non-static" case is ambigious and should be removed.
If you want dynamic textures in VRAM, you need a dynamic memory manager for it. Fortunately, I already wrote one quite some time ago (http://www.fx-world.org/wordpress/?p=13). You need to exchange your getStaticVramTexture and getStaticVramBuffer with valloc for it to work properly. Your texture then will stay 'static' as long as you don't vfree the pointer. Only problem left with dynamic VRAM textures then is to free their pointer after every drawing cycle (and catch the cases when the valloc fails because of insufficient VRAM), so you need to manage that properly.
Regards,
Raphael _________________ <Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl |
|
| Back to top |
|
 |
centralunit
Joined: 19 Nov 2006 Posts: 4
|
Posted: Sun Nov 19, 2006 11:23 pm Post subject: |
|
|
Hi Raphael, Thanks for your reply.
Yeah I know sceGuGetMemory only copy the texture to the displaylist. I only implemented this for test purpuse. I do not upload my textures during the game loop. I upload them (a_bStatic = true) when I load the level. Since I don't have that many textures this works for now.
Ive looked at your memory manager and good work on it. Ill probably use this when I have a more complex world that needs lots of textures.
But I still find it odd that only transparent textures get artifakts.
Ill try to find a host for my textures and screens so that I can show you.
// CentralUnit |
|
| Back to top |
|
 |
centralunit
Joined: 19 Nov 2006 Posts: 4
|
Posted: Mon Nov 20, 2006 2:54 am Post subject: |
|
|
Here is some screens.
Only have 1 transparent texture in VRAM, also using the posted code to draw it.
All textures in VRAM
All textures in VRAM except the transparent one
Only transparent texture in VRAM rest in system.
png of the transparent texture
ptx file of the texture. non swizzled.
http://www.starman.nu/centralunit/MarkerX.ptx |
|
| Back to top |
|
 |
rapso
Joined: 28 Mar 2005 Posts: 147
|
Posted: Mon Nov 20, 2006 6:58 pm Post subject: |
|
|
| try to copy the texture back to sysmem after some frames and use it, to see if it has been modified. |
|
| Back to top |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Mon Nov 20, 2006 7:34 pm Post subject: |
|
|
| centralunit wrote: | Hi Raphael, Thanks for your reply.
Yeah I know sceGuGetMemory only copy the texture to the displaylist. I only implemented this for test purpuse. I do not upload my textures during the game loop. I upload them (a_bStatic = true) when I load the level. Since I don't have that many textures this works for now.
|
So I am right to suppose that your textures don't end up in the drawlist, but atm only in VRAM (only the a_bStatic = true case occurs)?
Looking from the cases you showed, it seems that the upload to VRAM somehow creates those white lines in your transparent texture (3rd picture with trans texture not in VRAM does not show those lines).
I can not see any real reason for this, but I noticed you don't have a sceGuTexSync call after your static upload case. In theory this shouldn't be a problem, because the texture upload should be finished at least after the first few frames, but still it would be good habit to make sure all copying has finished before you make use of the textures.
Best would be to follow rapso's tip to check back the texture by downloading it back again from VRAM and check for consistency.
The white edges around your texture however seem independant of location of the texture, so it's more likely that your (transparent) image loader or the image converter is the source of the problem (though it's hard to see a pattern that could be caused by a faulty loader - the pattern is hardly resembled by any functional algorithm that could be used there).
BTW: Are the faces of the boxes all made up of two triangles, or more? IE, could the white corners be triangles that do not get textured due to some cause? _________________ <Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl |
|
| Back to top |
|
 |
rapso
Joined: 28 Mar 2005 Posts: 147
|
Posted: Mon Nov 20, 2006 7:43 pm Post subject: |
|
|
| Raphael wrote: |
The white edges around your texture however seem independant of location of the texture, |
probably they're kinda selection markers :) |
|
| Back to top |
|
 |
centralunit
Joined: 19 Nov 2006 Posts: 4
|
Posted: Mon Nov 20, 2006 9:48 pm Post subject: |
|
|
Thanks for all the replys.
| Quote: |
try to copy the texture back to sysmem after some frames and use it, to see if it has been modified.
|
Good stuff Rapso, thanks for the tip.
| Quote: |
So I am right to suppose that your textures don't end up in the drawlist, but atm only in VRAM (only the a_bStatic = true case occurs)?
|
Yes, you are right. Sorry If I confused you. I should have removed that code when I posted.
| Quote: |
The white edges around your texture however seem independant of location of the texture, so it's more likely that your (transparent) image loader or the image converter is the source of the problem (though it's hard to see a pattern that could be caused by a faulty loader - the pattern is hardly resembled by any functional algorithm that could be used there).
|
zomg.. yeah, It was the image loader for png files that was the root of all evil.
| Quote: |
BTW: Are the faces of the boxes all made up of two triangles, or more? IE, could the white corners be triangles that do not get textured due to some cause?
|
All the faces have two triangles. The white corners are actially a untextured separate mesh. I use it for selecting and moving around in the world. The X texture was a X shaped mesh from the beginning, so that I could create a shadowmap and project it on the ground but it didn't looked that good so I tossed that idea and that's when I started to use transparent textures intead.
----------
Last night I took a break from debugging and instead continued developing. I added more textures, meshes and gameplay. I also started to notice that the texture white lines started to spread to other non transparent textures.
I went through all my textures and loaders and found out that it was my font texture that I use for on-screen debugging that had been faulty allocated in the system ram. So it was only a freaky coincidence that it started to affekt transparent textures and nothing else.
Thanks Raphael and Rapso you all your work.
// CentralUnit. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|