From fbcd933d565c425aefda001f646c78d7fb650909 Mon Sep 17 00:00:00 2001 From: milek7 Date: Thu, 25 Oct 2018 18:07:43 +0200 Subject: [PATCH] rendering python to individual windows --- CMakeLists.txt | 1 + Globals.cpp | 5 +++ Globals.h | 5 ++- Train.cpp | 11 +++++- Train.h | 3 +- shaders/texturewindow.frag | 14 +++++++ texturewindow.cpp | 81 ++++++++++++++++++++++++++++++++++++++ texturewindow.h | 22 +++++++++++ 8 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 shaders/texturewindow.frag create mode 100644 texturewindow.cpp create mode 100644 texturewindow.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ea6447d..13c3dbc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,7 @@ set(SOURCES "simulationenvironment.cpp" "simulationstateserializer.cpp" "precipitation.cpp" +"texturewindow.cpp" "map.cpp" "ref/glad/src/glad.c" diff --git a/Globals.cpp b/Globals.cpp index ea7b72ac..721a9829 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -753,6 +753,11 @@ global_settings::ConfigParse(cParser &Parser) { Parser.getTokens(1); Parser >> map_enabled; } + else if (token == "python.displaywindows") + { + Parser.getTokens(1); + Parser >> python_displaywindows; + } } while ((token != "") && (token != "endconfig")); //(!Parser->EndOfFile) // na koniec trochę zależności if (!bLoadTraction) // wczytywanie drutów i słupów diff --git a/Globals.h b/Globals.h index 0b31cad0..9cdccd6c 100644 --- a/Globals.h +++ b/Globals.h @@ -176,6 +176,9 @@ struct global_settings { bool dds_upper_origin = false; bool captureonstart = true; + bool python_displaywindows = false; + bool map_enabled = true; + int gfx_framebuffer_width = -1; int gfx_framebuffer_height = -1; bool gfx_shadowmap_enabled = true; @@ -187,8 +190,6 @@ struct global_settings { GLenum gfx_format_depth = GL_DEPTH_COMPONENT32F; bool gfx_skippipeline = false; bool gfx_shadergamma = false; - - bool map_enabled = true; bool gfx_usegles = false; // methods diff --git a/Train.cpp b/Train.cpp index a605722b..ec1b4ed4 100644 --- a/Train.cpp +++ b/Train.cpp @@ -6004,7 +6004,7 @@ bool TTrain::Update( double const Deltatime ) && ( false == FreeFlyModeFlag ) ) { // don't bother if we're outside fScreenTimer = 0.f; for( auto const &screen : m_screens ) { - Application.request( { screen.first, GetTrainState(), GfxRenderer.Texture( screen.second ).id } ); + Application.request( { std::get<0>(screen), GetTrainState(), GfxRenderer.Texture( std::get<1>(screen) ).id } ); } } // sounds @@ -6807,12 +6807,19 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) WriteLog( "Python Screen: invalid texture id " + std::to_string( material ) + " - Ignoring screen" ); continue; } + + texture_handle &tex = GfxRenderer.Material( material ).textures[0]; + // record renderer and material binding for future update requests m_screens.emplace_back( ( substr_path(renderername).empty() ? // supply vehicle folder as path if none is provided DynamicObject->asBaseDir + renderername : renderername ), - GfxRenderer.Material( material ).textures[0] ); + tex, + std::nullopt); + + if (Global.python_displaywindows) + std::get<2>(m_screens.back()).emplace(tex); } // btLampkaUnknown.Init("unknown",mdKabina,false); } while (token != ""); diff --git a/Train.h b/Train.h index 6bdd2c12..f3675973 100644 --- a/Train.h +++ b/Train.h @@ -17,6 +17,7 @@ http://mozilla.org/MPL/2.0/. #include "sound.h" #include "PyInt.h" #include "command.h" +#include "texturewindow.h" // typedef enum {st_Off, st_Starting, st_On, st_ShuttingDown} T4State; @@ -671,7 +672,7 @@ private: // McZapkie: do syczenia float fPPress, fNPress; int iRadioChannel { 1 }; // numer aktualnego kana?u radiowego - std::vector> m_screens; + std::vector>> m_screens; public: float fPress[20][3]; // cisnienia dla wszystkich czlonow diff --git a/shaders/texturewindow.frag b/shaders/texturewindow.frag new file mode 100644 index 00000000..80a3ebc8 --- /dev/null +++ b/shaders/texturewindow.frag @@ -0,0 +1,14 @@ +in vec2 f_coords; + +layout(location = 0) out vec4 out_color; + +#texture (tex1, 0, sRGB) +uniform sampler2D tex1; + +void main() +{ + vec2 texcoord = f_coords; + vec3 color = texture(tex1, texcoord).rgb; + + out_color = FBOUT(vec4(color, 1.0)); +} diff --git a/texturewindow.cpp b/texturewindow.cpp new file mode 100644 index 00000000..cbf9a9b0 --- /dev/null +++ b/texturewindow.cpp @@ -0,0 +1,81 @@ +#include "stdafx.h" +#include "texturewindow.h" +#include "application.h" +#include "gl/shader.h" +#include "gl/vao.h" + +void texture_window_fb_resize(GLFWwindow *win, int w, int h) +{ + texture_window *texwindow = (texture_window*)glfwGetWindowUserPointer(win); + texwindow->notify_window_size(w, h); +} + +texture_window::texture_window(texture_handle src) +{ + opengl_texture &tex = GfxRenderer.Texture(src); + tex.create(); + m_source = tex.id; + + glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE); + + GLFWwindow *root = Application.window(); + m_window = glfwCreateWindow(m_win_w, m_win_h, ("EU07: texture " + std::to_string(m_source)).c_str(), nullptr, root); + + glfwSetWindowUserPointer(m_window, this); + glfwSetFramebufferSizeCallback(m_window, texture_window_fb_resize); + + glfwFocusWindow(root); + + m_renderthread = std::make_unique(&texture_window::threadfunc, this); +} + +texture_window::~texture_window() +{ + m_exit = true; + m_renderthread->join(); + glfwDestroyWindow(m_window); +} + +void texture_window::threadfunc() +{ + glfwMakeContextCurrent(m_window); + glfwSwapInterval(1); + + gl::shader vert("quad.vert"); + gl::shader frag("texturewindow.frag"); + gl::program shader(std::vector>({vert, frag})); + gl::vao vao; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_source); + shader.bind(); + vao.bind(); + + while (!m_exit) + { + int w, h; + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); + if (m_tex_w != w || m_tex_h != h) + { + m_tex_w = w; + m_tex_h = h; + m_win_w = w; + m_win_h = h; + glfwSetWindowSize(m_window, w, h); // eh, not thread-safe (but works?) + } + + glViewport(0, 0, m_win_w, m_win_h); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glfwSwapBuffers(m_window); + } +} + +void texture_window::notify_window_size(int w, int h) +{ + m_win_w = w; + m_win_h = h; +} diff --git a/texturewindow.h b/texturewindow.h new file mode 100644 index 00000000..680a3d57 --- /dev/null +++ b/texturewindow.h @@ -0,0 +1,22 @@ +#include "renderer.h" +#include + +class texture_window +{ + GLFWwindow *m_window; + GLuint m_source; + std::shared_ptr m_renderthread; + + bool m_exit = false; + + int m_win_w = 500, m_win_h = 500; + int m_tex_w = 0, m_tex_h = 0; + + void threadfunc(); + +public: + texture_window(texture_handle src); + ~texture_window(); + + void notify_window_size(int w, int h); +};