Streaming via Discord causes rendering problems and crashes
This issue began roughly around the beginning of June 2021, possibly with a Discord update. It affects Polymost as well as Classic (when compiled with USE_OPENGL=1).
If the player starts streaming the game while in Polymost mode, then within a few seconds, the screen will turn entirely black, both on his end and on the streaming output. If streaming is started while in a level, then the first observable effect is a constant black flickering. The flickering becomes more intense as the framerate is lowered, and finally results in a completely black screen at 30 FPS. Without a limit, no flickering is observed.
The second effect is seen once one loads a new map:
All tiles that were not present in the previous map and need to be newly loaded now render as black squares while streaming is still active. If streaming is disabled, these tiles will remain black squares, but any new tiles will load correctly again.
Since this issue started only a month ago, it is probably tied to a change in how Discord streaming works with OpenGL. Nevertheless, the latest version of eduke32 that does not show this issue in Polymost, and allows proper streaming with the current Discord, was r6882. In r6883 (a2d8dc8f) Pogokeen introduced dynamic tilepacking, and in the process changed how the functions glad_glActiveTexture(texture);
and glad_glBindTexture(target, textureID);
are called. While these changes are probably not wrong in themselves, they expose the issue we are now having.
For Classic mode, the issue started in r6919 (59bce45f), in which Classic mode was changed to use OpenGL to blit the 8bit buffer to the screen. As such, here we do not see individual black boxes and flicker, but instead a completely black screen at all times while streaming.
Debugging has shown that several changes can make the flickering and black rectangles in Polymost disappear, though they are probably all circumstancial. Limiting the value of tilesheetSize
to 2048 reduces the flickering, and allows the tiles to load properly. Setting r_useindexedcolortextures 0
also resolves the same issues, but breaks parallaxed sky textures and the level fog.
Removing the following line in polymost_activeTexture()
stops the issue also:
diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp
index b402944a7..0d58554bc 100644
--- a/source/build/src/polymost.cpp
+++ b/source/build/src/polymost.cpp
@@ -871,7 +871,7 @@ void polymost_shadeInterpolate(int32_t shadeInterpolate)
void polymost_activeTexture(GLenum texture)
{
- currentActiveTexture = texture;
+ //currentActiveTexture = texture;
glad_glActiveTexture(texture);
}
And changing the following conditional to always be entered has the same effect as the above:
diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp
index b402944a7..941ba66d7 100644
--- a/source/build/src/polymost.cpp
+++ b/source/build/src/polymost.cpp
@@ -880,7 +880,8 @@ void polymost_bindTexture(GLenum target, uint32_t textureID)
{
if (currentTextureID != textureID ||
textureID == 0 ||
currentActiveTexture != GL_TEXTURE0 ||
+ true ||
videoGetRenderMode() != REND_POLYMOST)
{
glad_glBindTexture(target, textureID);
HOWEVER, common to all these debugging steps is that it does not resolve the black screen when switching to Classic mode.
For Classic mode, I believe the problem may stem from void glsurface_blitBuffer()
.
void glsurface_blitBuffer()
{
if (!buffer)
return;
glActiveTexture(GL_TEXTURE0);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bufferRes.x, bufferRes.y, GL_RED, GL_UNSIGNED_BYTE, (void*) buffer);
glDrawArrays(GL_TRIANGLE_STRIP,
0,
4);
}
Removing the call to glActiveTexture()
inside this function has the same effect as when streaming over Discord. Perhaps the Discord hook is somehow interfering with the OpenGL function calls directly.
Finally, eduke32 can also crash while streaming over Discord. The backtrace for this points directly to the driver library: eduke32.crash.log
Edit: The same problem is also present in VoidSW, and all ports of the NBlood group.