mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
splittable python windows
This commit is contained in:
@@ -116,7 +116,7 @@ set(SOURCES
|
||||
"simulationenvironment.cpp"
|
||||
"simulationstateserializer.cpp"
|
||||
"precipitation.cpp"
|
||||
"texturewindow.cpp"
|
||||
"pythonscreenviewer.cpp"
|
||||
|
||||
"network/network.cpp"
|
||||
"network/message.cpp"
|
||||
|
||||
16
Globals.cpp
16
Globals.cpp
@@ -807,13 +807,17 @@ global_settings::ConfigParse(cParser &Parser) {
|
||||
Parser.getTokens(1);
|
||||
Parser >> python_mipmaps;
|
||||
}
|
||||
else if (token == "python.monitormap")
|
||||
else if (token == "python.viewport")
|
||||
{
|
||||
Parser.getTokens(2, false);
|
||||
std::string pythonscreen;
|
||||
std::string monitorid;
|
||||
Parser >> pythonscreen >> monitorid;
|
||||
python_monitormap.emplace(std::make_pair(pythonscreen, monitorid));
|
||||
Parser.getTokens(8, false);
|
||||
|
||||
pythonviewport_config conf;
|
||||
Parser >> conf.surface >> conf.monitor;
|
||||
Parser >> conf.size.x >> conf.size.y;
|
||||
Parser >> conf.offset.x >> conf.offset.y;
|
||||
Parser >> conf.scale.x >> conf.scale.y;
|
||||
|
||||
python_viewports.push_back(conf);
|
||||
}
|
||||
else if (token == "network.server")
|
||||
{
|
||||
|
||||
@@ -182,7 +182,6 @@ struct global_settings {
|
||||
|
||||
std::chrono::duration<float> minframetime {0.0f};
|
||||
|
||||
std::unordered_map<std::string, std::string> python_monitormap;
|
||||
std::string fullscreen_monitor;
|
||||
|
||||
bool python_mipmaps = true;
|
||||
@@ -215,8 +214,8 @@ struct global_settings {
|
||||
std::string monitor;
|
||||
glm::ivec2 size;
|
||||
|
||||
glm::ivec2 offset;
|
||||
glm::ivec2 cut;
|
||||
glm::vec2 offset;
|
||||
glm::vec2 scale;
|
||||
};
|
||||
std::vector<pythonviewport_config> python_viewports;
|
||||
|
||||
|
||||
@@ -6899,10 +6899,10 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
||||
DynamicObject->asBaseDir + renderername :
|
||||
renderername ),
|
||||
tex->id,
|
||||
std::nullopt);
|
||||
nullptr);
|
||||
|
||||
if (Global.python_displaywindows)
|
||||
std::get<2>(m_screens.back()).emplace(tex->id, submodelname);
|
||||
std::get<2>(m_screens.back()) = std::make_unique<python_screen_viewer>(tex->id, submodelname);
|
||||
}
|
||||
// btLampkaUnknown.Init("unknown",mdKabina,false);
|
||||
} while (token != "");
|
||||
|
||||
4
Train.h
4
Train.h
@@ -16,7 +16,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "sound.h"
|
||||
#include "PyInt.h"
|
||||
#include "command.h"
|
||||
#include "texturewindow.h"
|
||||
#include "pythonscreenviewer.h"
|
||||
|
||||
// typedef enum {st_Off, st_Starting, st_On, st_ShuttingDown} T4State;
|
||||
|
||||
@@ -665,7 +665,7 @@ private:
|
||||
bool m_mastercontrollerinuse { false };
|
||||
float m_mastercontrollerreturndelay { 0.f };
|
||||
int iRadioChannel { 1 }; // numer aktualnego kana?u radiowego
|
||||
std::vector<std::tuple<std::string, GLuint, std::optional<texture_window>>> m_screens;
|
||||
std::vector<std::tuple<std::string, GLuint, std::unique_ptr<python_screen_viewer>>> m_screens;
|
||||
uint16_t vid { 0 };
|
||||
|
||||
public:
|
||||
|
||||
98
pythonscreenviewer.cpp
Normal file
98
pythonscreenviewer.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include "stdafx.h"
|
||||
#include "pythonscreenviewer.h"
|
||||
#include "application.h"
|
||||
#include "gl/shader.h"
|
||||
#include "gl/vao.h"
|
||||
#include "Logs.h"
|
||||
|
||||
void texture_window_fb_resize(GLFWwindow *win, int w, int h)
|
||||
{
|
||||
python_screen_viewer *texwindow = (python_screen_viewer*)glfwGetWindowUserPointer(win);
|
||||
texwindow->notify_window_size(win, w, h);
|
||||
}
|
||||
|
||||
python_screen_viewer::python_screen_viewer(GLuint src, std::string surfacename)
|
||||
{
|
||||
m_source = src;
|
||||
|
||||
for (const auto &viewport : Global.python_viewports) {
|
||||
if (viewport.surface == surfacename) {
|
||||
window_config conf;
|
||||
conf.size = viewport.size;
|
||||
conf.offset = viewport.offset;
|
||||
conf.scale = viewport.scale;
|
||||
conf.window = Application.window(-1, true, conf.size.x, conf.size.y,
|
||||
Application.find_monitor(viewport.monitor));
|
||||
|
||||
glfwSetWindowUserPointer(conf.window, this);
|
||||
glfwSetFramebufferSizeCallback(conf.window, texture_window_fb_resize);
|
||||
|
||||
m_windows.push_back(std::move(conf));
|
||||
}
|
||||
}
|
||||
|
||||
gl::shader vert("texturewindow.vert");
|
||||
gl::shader frag("texturewindow.frag");
|
||||
m_shader = std::make_unique<gl::program>(std::vector<std::reference_wrapper<const gl::shader>>({vert, frag}));
|
||||
|
||||
m_renderthread = std::make_unique<std::thread>(&python_screen_viewer::threadfunc, this);
|
||||
}
|
||||
|
||||
python_screen_viewer::~python_screen_viewer()
|
||||
{
|
||||
m_exit = true;
|
||||
m_renderthread->join();
|
||||
|
||||
for (auto &window : m_windows)
|
||||
glfwDestroyWindow(window.window);
|
||||
}
|
||||
|
||||
void python_screen_viewer::threadfunc()
|
||||
{
|
||||
for (auto &window : m_windows) {
|
||||
glfwMakeContextCurrent(window.window);
|
||||
|
||||
glfwSwapInterval(1);
|
||||
GLuint v;
|
||||
glGenVertexArrays(1, &v);
|
||||
glBindVertexArray(v);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_source);
|
||||
|
||||
window.ubo = std::make_unique<gl::ubo>(sizeof(gl::scene_ubs), 0, GL_STREAM_DRAW);
|
||||
}
|
||||
|
||||
while (!m_exit)
|
||||
{
|
||||
for (auto &window : m_windows) {
|
||||
glfwMakeContextCurrent(window.window);
|
||||
m_shader->unbind();
|
||||
gl::buffer::unbind();
|
||||
|
||||
m_shader->bind();
|
||||
window.ubo->bind_uniform();
|
||||
|
||||
m_ubs.projection = glm::mat4(glm::mat3(glm::translate(glm::scale(glm::mat3(), 1.0f / window.scale), window.offset)));
|
||||
window.ubo->update(m_ubs);
|
||||
|
||||
glViewport(0, 0, window.size.x, window.size.y);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
glfwSwapBuffers(window.window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void python_screen_viewer::notify_window_size(GLFWwindow *window, int w, int h)
|
||||
{
|
||||
for (auto &conf : m_windows) {
|
||||
if (conf.window == window) {
|
||||
conf.size.x = w;
|
||||
conf.size.y = h;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
32
pythonscreenviewer.h
Normal file
32
pythonscreenviewer.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "renderer.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
class python_screen_viewer
|
||||
{
|
||||
struct window_config {
|
||||
GLFWwindow *window;
|
||||
glm::ivec2 size;
|
||||
|
||||
glm::vec2 offset;
|
||||
glm::vec2 scale;
|
||||
|
||||
std::unique_ptr<gl::ubo> ubo;
|
||||
};
|
||||
|
||||
std::vector<window_config> m_windows;
|
||||
|
||||
GLuint m_source;
|
||||
std::shared_ptr<std::thread> m_renderthread;
|
||||
std::unique_ptr<gl::program> m_shader;
|
||||
gl::scene_ubs m_ubs;
|
||||
|
||||
std::atomic_bool m_exit = false;
|
||||
|
||||
void threadfunc();
|
||||
|
||||
public:
|
||||
python_screen_viewer(GLuint src, std::string name);
|
||||
~python_screen_viewer();
|
||||
|
||||
void notify_window_size(GLFWwindow *window, int w, int h);
|
||||
};
|
||||
31
shaders/texturewindow.vert
Normal file
31
shaders/texturewindow.vert
Normal file
@@ -0,0 +1,31 @@
|
||||
layout (std140) uniform scene_ubo
|
||||
{
|
||||
mat4 projection;
|
||||
mat4 lightview;
|
||||
float time;
|
||||
};
|
||||
|
||||
const vec2 vert[4] = vec2[]
|
||||
(
|
||||
vec2(-1.0, 1.0),
|
||||
vec2(-1.0, -1.0),
|
||||
vec2( 1.0, 1.0),
|
||||
vec2( 1.0, -1.0)
|
||||
);
|
||||
|
||||
const vec2 uv[4] = vec2[]
|
||||
(
|
||||
vec2(0.0, 1.0),
|
||||
vec2(0.0, 0.0),
|
||||
vec2(1.0, 1.0),
|
||||
vec2(1.0, 0.0)
|
||||
);
|
||||
|
||||
out vec2 f_coords;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(vert[gl_VertexID], 0.0, 1.0);
|
||||
f_coords = vec2(mat3(projection) * vec3(uv[gl_VertexID], 1.0));
|
||||
}
|
||||
|
||||
1
stdafx.h
1
stdafx.h
@@ -95,6 +95,7 @@
|
||||
#define GLM_FORCE_CTOR_INIT
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtx/matrix_transform_2d.hpp>
|
||||
#include <glm/gtc/matrix_access.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <glm/gtc/epsilon.hpp>
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "texturewindow.h"
|
||||
#include "application.h"
|
||||
#include "gl/shader.h"
|
||||
#include "gl/vao.h"
|
||||
#include "Logs.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(GLuint src, std::string surfacename)
|
||||
{
|
||||
m_source = src;
|
||||
|
||||
int window_w = m_win_w, window_h = m_win_h;
|
||||
|
||||
auto iter = Global.python_monitormap.find(surfacename);
|
||||
if (iter != Global.python_monitormap.end())
|
||||
monitor = Application.find_monitor((*iter).second);
|
||||
|
||||
if (monitor) {
|
||||
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
|
||||
window_w = mode->width;
|
||||
window_h = mode->height;
|
||||
}
|
||||
|
||||
m_window = Application.window(-1, true, window_w, window_h, monitor);
|
||||
|
||||
glfwSetWindowUserPointer(m_window, this);
|
||||
glfwSetFramebufferSizeCallback(m_window, texture_window_fb_resize);
|
||||
|
||||
m_renderthread = std::make_unique<std::thread>(&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);
|
||||
|
||||
{
|
||||
GLuint v;
|
||||
glGenVertexArrays(1, &v);
|
||||
glBindVertexArray(v);
|
||||
}
|
||||
|
||||
gl::shader vert("quad.vert");
|
||||
gl::shader frag("texturewindow.frag");
|
||||
gl::program shader(std::vector<std::reference_wrapper<const gl::shader>>({vert, frag}));
|
||||
gl::vao vao;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_source);
|
||||
shader.bind();
|
||||
vao.bind();
|
||||
|
||||
while (!m_exit)
|
||||
{
|
||||
// if texture resized, update window size (maybe not necessary?)
|
||||
// don't care when on fullscreen
|
||||
if ((GLAD_GL_VERSION_3_3 || GLAD_GL_ES_VERSION_3_1) && !monitor)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
#include "renderer.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
class texture_window
|
||||
{
|
||||
GLFWwindow *m_window;
|
||||
GLuint m_source;
|
||||
std::shared_ptr<std::thread> m_renderthread;
|
||||
GLFWmonitor *monitor = nullptr;
|
||||
|
||||
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(GLuint src, std::string name);
|
||||
~texture_window();
|
||||
|
||||
void notify_window_size(int w, int h);
|
||||
};
|
||||
Reference in New Issue
Block a user