collinsmith / riiablo

Diablo II remade using Java and LibGDX
http://riiablo.com
Apache License 2.0
872 stars 99 forks source link

rendering map results in gaps between DT1 tiles #62

Open collinsmith opened 4 years ago

collinsmith commented 4 years ago

I've noticed that under certain circumstances gaps show up when rendering the map tiles. This is typically visible as a 1px gap between tiles (floor isometric tiles and wall rle tiles). It seems this is some sort of issue with opengl that's usually fixed by adding some kind of texture border. This is a pretty difficult problem due to the nature of how the files are stored/loaded -- and I'm not even sure if adding this could fix the issue.

On mobile I was noticing the behavior much worse with the isometric floor appearing with gaps in the tiles. This was resolved by stretching the textures by 1px which caused another issue referenced by https://github.com/collinsmith/riiablo/issues/55#issuecomment-491589280.

In the meantime, I've noticed that the issue doesn't really seem to appear noticeably with an even resolution (I was debug rendering at 853x480 which is 16:9 version of 480p), when rendering at an even resolution (in my case 854x480) the issue did not appear. I've also removed the texture stretching, which seems to have resolved the jitter issue I referenced above.

I'll look into a better solution when I begin implementing lighting, as increasing the size of the texture for the tile could cause issues with that system.

Clipboard-2

collinsmith commented 4 years ago

I believe the issue is caused by multiple calls to the batch with the iso camera's projection matrix applied. I'd like to test a plausible fix which involves drawing everything to a fbo and then drawing that with scaling applied. I don't anticipate this being very degrading on performance, but I think I can also bind this fix to a CVAR. I think this should resolve this issue, because the backing texture should be a pixel-perfect render of the scene.

https://github.com/mattdesl/lwjgl-basics/wiki/FrameBufferObjects

//make the FBO the current buffer
fbo.begin()

//... clear the FBO color with transparent black ...
glClearColor(0f, 0f, 0f, 0f); //transparent black
glClear(GL_COLOR_BUFFER_BIT); //clear the color buffer

//since the FBO may not be the same size as the display, 
//we need to give the SpriteBatch our new screen dimensions
batch.resize(fbo.getWidth(), fbo.getHeight());

//render some sprites 
batch.begin();

//draw our track and thumb button
batch.draw(track, ...);
batch.draw(slider, ...);

batch.end(); //flushes data to GL

//now we can unbind the FBO, returning rendering back to the default back buffer (the Display)
fbo.end();

//reset the batch back to the Display width/height
batch.resize(Display.getWidth(), Display.getHeight());

//now we are rendering to the back buffer (Display) again
batch.begin();

//draw our offscreen FBO texture to the screen with the given alpha
batch.setColor(1f, 1f, 1f, alpha);
batch.draw(fbo, 0, 0);

batch.end();