Rendering issues with SGDK

SGDK only sub forum

Moderator: Stef

Post Reply
superjoebob
Very interested
Posts: 66
Joined: Fri Oct 15, 2010 7:06 am
Location: Vancouver, Canada
Contact:

Rendering issues with SGDK

Post by superjoebob » Fri Feb 08, 2013 11:07 am

I spent the last few hours trying to figure out some rendering bugs and I've made little to no progress, so I think its time to ask someone who knows what they're doing! I've been experiencing some rendering bugs with a game I've been making in SGDK:

Image

As you can see the block is slightly stretched, and it's leaving behind residue from where it was on the last frame. It seems to happen worse near the top of the screen. I came across the problem while trying to figure out the solution to another problem I've been having, which would be my main problem:

Image
Image
Image

This is 3 frames from the game. In the first frame, a bullet is fired at the blocks immediately in front of the character.

In the second frame there is a bug: The bullet collides with the blocks on the second frame, cycles through, destroys the 2 green blocks, and clears their render on background plane B. This causes the red block above to go into its falling state, and clear its render on background plane B. Now, after this point in the update, the sprite updating for the blocks is refreshed. It looks at the red block, sees that it is falling and no longer part of the background layer, and it renders a block sprite. If you look at the second frame though, you'll notice that the block sprite is no where to be found. Interestingly enough the smoke puffs should also be rendered in frame 2, but they are not. None of the sprites that are supposed to render as a result of the block destruction are rendering until the 3rd frame. Obviously this causes an unsightly pop where blocks that are still alive disappear for a frame.

I've even had times with especially large combos where half the combo will disappear one frame, then half the next frame, when the code specifically states that the whole chunk should be removed in one frame.

This isn't the first case of it happening either, it was also happening on my level bar when the bar maxes out and goes back down to the bottom. This had the inverse problem though, there is a 8 x 16 sprite I use to render the very end of the bar to allow smooth interpolation, the rest of the bar is rendered to plane A with high priority. After the bar reset, no matter what I did, the sprite at the end would render for one extra frame even though It was told not to render anymore. Sometimes it would render in full, sometimes it would kinda half glitch render. But it would always be there. I ended up solving that problem and the block problem by keeping a variable and offsetting the actions by single frames, but its hacky as hell and I really don't like/shouldn't have to be doing it.

When a block lands on another block, its sprite stops drawing and it is rendered to the background plane. When a block falls or is destroyed, the background plane gets the checkerboard pattern rendered over it, and if the block is still alive its sprite is drawn. My render cycle is game update logic, followed by a call to RenderSprites in my manager which just cycles through all the sprite instances added and uses VDP_setSpriteP and VDP_updateSprites. Finally, VDP_waitVSync is called and the game loops over again.

I can't help but feel like I'm running into some kind of bandwidth issue with this? Would using DMA for the blocks help? If so, how the heck does it work in SGDK :P.
On a never ending quest to compose for the Genesis/Megadrive

superjoebob
Very interested
Posts: 66
Joined: Fri Oct 15, 2010 7:06 am
Location: Vancouver, Canada
Contact:

Post by superjoebob » Fri Feb 08, 2013 11:08 pm

Wait a minute my frame rate goes from 60 in the bugged frame to 46 in the next... This is a lag thing isn't it?
On a never ending quest to compose for the Genesis/Megadrive

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post by Stef » Fri Feb 08, 2013 11:47 pm

This is exactly a timing / lag issue, part of your screen / sprite are refreshed too late, during the next frame, specially during the active period which can make some "tearing" sprite / background effect.

Updating sprites can take a bit of time, try to use :

Code: Select all

VDP_setSpritePosition(...)
when you need to only update position of a sprite.

Also if you need to update severals sprites at once, use this method :

Code: Select all

VDP_setSprites(...)
The fastest way to update sprites is still to have your own sprites structure containing data in vdp format (you can use SGDK sources to understand how it is formated) and use DMA to transfer them.
But in your case you won't probably need that.

Another point which can be slow is the background update, try to profile your code with these methods to see what is slow in your code :

Code: Select all

startTimer(...)
getTimer(...)
Then use Gens KDebug, the message output dialog will display all messages and values outputed with these methods :

Code: Select all

KDebug_Alert(...)
KDebug_AlertNumber(...)
That help a lot for debugging / profiling :)

superjoebob
Very interested
Posts: 66
Joined: Fri Oct 15, 2010 7:06 am
Location: Vancouver, Canada
Contact:

Post by superjoebob » Sat Feb 09, 2013 1:49 am

Thanks Stef this is some very useful information. I'll probably rewrite my graphics context manager, thinking I might add the concept of a permanent sprite which keeps its sprite index and renders automatically using only VDP_setSpritePosition.

I've also had a hard time debugging things, I had no idea there was a debug log feature!
On a never ending quest to compose for the Genesis/Megadrive

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post by Stef » Sat Feb 09, 2013 12:01 pm

Yeah debugging is a pain on sega genesis, KDebug help a lot for that :)
Hopefully we will have better tools at sometime (Gens KMod++ ?) =)

Bitybity
Interested
Posts: 36
Joined: Wed Dec 07, 2011 2:09 am

Post by Bitybity » Sun Feb 10, 2013 4:12 am

Stupid question: Do you have HBlank enabled? and, do you wait the vertical blank? :V

superjoebob
Very interested
Posts: 66
Joined: Fri Oct 15, 2010 7:06 am
Location: Vancouver, Canada
Contact:

Post by superjoebob » Wed Feb 13, 2013 12:33 am

Not sure but I believe VDP_waitVSync does that?
On a never ending quest to compose for the Genesis/Megadrive

Post Reply