diff options
author | Michael Lutz <michi@icosahedron.de> | 2021-03-20 19:43:54 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-20 19:43:54 +0100 |
commit | f0f96e3103c2e740fa4340a5f1854c41df65ffa2 (patch) | |
tree | 258d9ae4b04f3f93151bf6bb81f2a7682dd34232 | |
parent | c92358527bb14e26553a88ca04c34b715b1e9542 (diff) | |
download | openttd-f0f96e3103c2e740fa4340a5f1854c41df65ffa2.tar.xz |
Fix #8871: [OpenGL] Initialize all buffers after resize and clear back buffer. (#8877)
-rw-r--r-- | src/video/opengl.cpp | 43 | ||||
-rw-r--r-- | src/video/sdl2_opengl_v.cpp | 1 | ||||
-rw-r--r-- | src/video/win32_v.cpp | 1 |
3 files changed, 38 insertions, 7 deletions
diff --git a/src/video/opengl.cpp b/src/video/opengl.cpp index 26f6f4b4d..d142abfea 100644 --- a/src/video/opengl.cpp +++ b/src/video/opengl.cpp @@ -878,6 +878,22 @@ bool OpenGLBackend::InitShaders() } /** + * Clear the bound pixel buffer to a specific value. + * @param len Length of the buffer. + * @param data Value to set. + * @tparam T Pixel type. + */ +template <class T> +static void ClearPixelBuffer(size_t len, T data) +{ + T *buf = reinterpret_cast<T *>(_glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE)); + for (int i = 0; i < len; i++) { + *buf++ = data; + } + _glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); +} + +/** * Change the size of the drawing window and allocate matching resources. * @param w New width of the window. * @param h New height of the window. @@ -911,14 +927,16 @@ bool OpenGLBackend::Resize(int w, int h, bool force) if (_glClearBufferSubData != nullptr) { _glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_RGBA8, 0, pitch * h * bpp / 8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &black.data); } else { - uint32 *buf = (uint32 *)_glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE); - for (int i = 0; i < pitch * h; i++) { - *buf++ = black.data; - } - _glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + ClearPixelBuffer<uint32>(pitch * h, black.data); + } + } else if (bpp == 8) { + if (_glClearBufferSubData != nullptr) { + byte b = 0; + _glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_R8, 0, pitch * h, GL_RED, GL_UNSIGNED_BYTE, &b); + } else { + ClearPixelBuffer<byte>(pitch * h, 0); } } - _glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); _glActiveTexture(GL_TEXTURE0); _glBindTexture(GL_TEXTURE_2D, this->vid_texture); @@ -931,6 +949,7 @@ bool OpenGLBackend::Resize(int w, int h, bool force) _glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, nullptr); break; } + _glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); /* Does this blitter need a separate animation buffer? */ if (BlitterFactory::GetCurrentBlitter()->NeedsAnimationBuffer()) { @@ -944,10 +963,18 @@ bool OpenGLBackend::Resize(int w, int h, bool force) _glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo); _glBufferData(GL_PIXEL_UNPACK_BUFFER, pitch * h, nullptr, GL_DYNAMIC_DRAW); } - _glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + /* Initialize buffer as 0 == no remap. */ + if (_glClearBufferSubData != nullptr) { + byte b = 0; + _glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_R8, 0, pitch * h, GL_RED, GL_UNSIGNED_BYTE, &b); + } else { + ClearPixelBuffer<byte>(pitch * h, 0); + } _glBindTexture(GL_TEXTURE_2D, this->anim_texture); _glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr); + _glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); } else { if (this->anim_buffer != nullptr) { _glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo); @@ -975,6 +1002,8 @@ bool OpenGLBackend::Resize(int w, int h, bool force) _glUseProgram(this->remap_program); _glUniform2f(this->remap_screen_loc, (float)_screen.width, (float)_screen.height); + _glClear(GL_COLOR_BUFFER_BIT); + return true; } diff --git a/src/video/sdl2_opengl_v.cpp b/src/video/sdl2_opengl_v.cpp index 13ee082ba..86dc104dd 100644 --- a/src/video/sdl2_opengl_v.cpp +++ b/src/video/sdl2_opengl_v.cpp @@ -131,6 +131,7 @@ bool VideoDriver_SDL_OpenGL::AllocateBackingStore(int w, int h, bool force) MemSetT(&this->dirty_rect, 0); bool res = OpenGLBackend::Get()->Resize(w, h, force); + SDL_GL_SwapWindow(this->sdl_window); _screen.dst_ptr = this->GetVideoPointer(); _cur_palette.first_dirty = 0; diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index a802cdafa..1d9cd3e2b 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -1417,6 +1417,7 @@ bool VideoDriver_Win32OpenGL::AllocateBackingStore(int w, int h, bool force) this->dirty_rect = {}; bool res = OpenGLBackend::Get()->Resize(w, h, force); + SwapBuffers(this->dc); _screen.dst_ptr = this->GetVideoPointer(); return res; |