From ae2c0602511ab79bfd669ec6965d55952daa6545 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sun, 14 Jul 2024 15:49:35 +0300 Subject: [PATCH] Qt: Shader editor now works --- include/panda_qt/shader_editor.hpp | 5 +-- include/renderer_gl/renderer_gl.hpp | 1 + src/core/renderer_gl/renderer_gl.cpp | 59 ++++++++++++++++++---------- src/panda_qt/main_window.cpp | 9 +++++ src/panda_qt/shader_editor.cpp | 2 +- 5 files changed, 52 insertions(+), 24 deletions(-) diff --git a/include/panda_qt/shader_editor.hpp b/include/panda_qt/shader_editor.hpp index 009381a0b..86bc1149a 100644 --- a/include/panda_qt/shader_editor.hpp +++ b/include/panda_qt/shader_editor.hpp @@ -17,12 +17,11 @@ class ShaderEditorWindow : public QDialog { Zep::IZepReplProvider replProvider; static constexpr float fontSize = 14.0f; + public: // Whether this backend supports shader editor - bool shaderEditorSupported = true; + bool supported = true; - public: ShaderEditorWindow(QWidget* parent, const std::string& filename, const std::string& initialText); void setText(const std::string& text) { zepWidget.GetEditor().GetMRUBuffer()->SetText(text); } - void setEnable(bool enable); }; \ No newline at end of file diff --git a/include/renderer_gl/renderer_gl.hpp b/include/renderer_gl/renderer_gl.hpp index 4c2d9e66c..c947583e6 100644 --- a/include/renderer_gl/renderer_gl.hpp +++ b/include/renderer_gl/renderer_gl.hpp @@ -92,6 +92,7 @@ class RendererGL final : public Renderer { // Note: The caller is responsible for deleting the currently bound FBO before calling this void setFBO(uint handle) { screenFramebuffer.m_handle = handle; } void resetStateManager() { gl.reset(); } + void initUbershader(OpenGL::Program& program); #ifdef PANDA3DS_FRONTEND_QT virtual void initGraphicsContext([[maybe_unused]] GL::Context* context) override { initGraphicsContextInternal(); } diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp index 3c68b8f9e..cfa32319c 100644 --- a/src/core/renderer_gl/renderer_gl.cpp +++ b/src/core/renderer_gl/renderer_gl.cpp @@ -57,24 +57,7 @@ void RendererGL::initGraphicsContextInternal() { OpenGL::Shader vert({vertexShaderSource.begin(), vertexShaderSource.size()}, OpenGL::Vertex); OpenGL::Shader frag({fragmentShaderSource.begin(), fragmentShaderSource.size()}, OpenGL::Fragment); triangleProgram.create({vert, frag}); - gl.useProgram(triangleProgram); - - textureEnvSourceLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvSource"); - textureEnvOperandLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvOperand"); - textureEnvCombinerLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvCombiner"); - textureEnvColorLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvColor"); - textureEnvScaleLoc = OpenGL::uniformLocation(triangleProgram, "u_textureEnvScale"); - - depthScaleLoc = OpenGL::uniformLocation(triangleProgram, "u_depthScale"); - depthOffsetLoc = OpenGL::uniformLocation(triangleProgram, "u_depthOffset"); - depthmapEnableLoc = OpenGL::uniformLocation(triangleProgram, "u_depthmapEnable"); - picaRegLoc = OpenGL::uniformLocation(triangleProgram, "u_picaRegs"); - - // Init sampler objects. Texture 0 goes in texture unit 0, texture 1 in TU 1, texture 2 in TU 2, and the light maps go in TU 3 - glUniform1i(OpenGL::uniformLocation(triangleProgram, "u_tex0"), 0); - glUniform1i(OpenGL::uniformLocation(triangleProgram, "u_tex1"), 1); - glUniform1i(OpenGL::uniformLocation(triangleProgram, "u_tex2"), 2); - glUniform1i(OpenGL::uniformLocation(triangleProgram, "u_tex_lighting_lut"), 3); + initUbershader(triangleProgram); auto displayVertexShaderSource = gl_resources.open("opengl_display.vert"); auto displayFragmentShaderSource = gl_resources.open("opengl_display.frag"); @@ -814,5 +797,41 @@ void RendererGL::deinitGraphicsContext() { printf("RendererGL::DeinitGraphicsContext called\n"); } -std::string RendererGL::getUbershader() { return ""; } -void RendererGL::setUbershader(const std::string& shader) {} \ No newline at end of file +std::string RendererGL::getUbershader() { + auto gl_resources = cmrc::RendererGL::get_filesystem(); + auto fragmentShader = gl_resources.open("opengl_fragment_shader.frag"); + + return std::string(fragmentShader.begin(), fragmentShader.end()); +} + +void RendererGL::setUbershader(const std::string& shader) { + auto gl_resources = cmrc::RendererGL::get_filesystem(); + auto vertexShaderSource = gl_resources.open("opengl_vertex_shader.vert"); + + OpenGL::Shader vert({vertexShaderSource.begin(), vertexShaderSource.size()}, OpenGL::Vertex); + OpenGL::Shader frag(shader, OpenGL::Fragment); + triangleProgram.create({vert, frag}); + + initUbershader(triangleProgram); +} + +void RendererGL::initUbershader(OpenGL::Program& program) { + gl.useProgram(program); + + textureEnvSourceLoc = OpenGL::uniformLocation(program, "u_textureEnvSource"); + textureEnvOperandLoc = OpenGL::uniformLocation(program, "u_textureEnvOperand"); + textureEnvCombinerLoc = OpenGL::uniformLocation(program, "u_textureEnvCombiner"); + textureEnvColorLoc = OpenGL::uniformLocation(program, "u_textureEnvColor"); + textureEnvScaleLoc = OpenGL::uniformLocation(program, "u_textureEnvScale"); + + depthScaleLoc = OpenGL::uniformLocation(program, "u_depthScale"); + depthOffsetLoc = OpenGL::uniformLocation(program, "u_depthOffset"); + depthmapEnableLoc = OpenGL::uniformLocation(program, "u_depthmapEnable"); + picaRegLoc = OpenGL::uniformLocation(program, "u_picaRegs"); + + // Init sampler objects. Texture 0 goes in texture unit 0, texture 1 in TU 1, texture 2 in TU 2, and the light maps go in TU 3 + glUniform1i(OpenGL::uniformLocation(program, "u_tex0"), 0); + glUniform1i(OpenGL::uniformLocation(program, "u_tex1"), 1); + glUniform1i(OpenGL::uniformLocation(program, "u_tex2"), 2); + glUniform1i(OpenGL::uniformLocation(program, "u_tex_lighting_lut"), 3); +} \ No newline at end of file diff --git a/src/panda_qt/main_window.cpp b/src/panda_qt/main_window.cpp index d8aab126a..cfa45e85c 100644 --- a/src/panda_qt/main_window.cpp +++ b/src/panda_qt/main_window.cpp @@ -78,7 +78,11 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent) patchWindow = new PatchWindow(this); luaEditor = new TextEditorWindow(this, "script.lua", ""); shaderEditor = new ShaderEditorWindow(this, "shader.glsl", ""); + shaderEditor->setEnable(emu->getRenderer()->supportsShaderReload()); + if (shaderEditor->supported) { + shaderEditor->setText(emu->getRenderer()->getUbershader()); + } auto args = QCoreApplication::arguments(); if (args.size() > 1) { @@ -351,6 +355,11 @@ void MainWindow::dispatchMessage(const EmulatorMessage& message) { emu->getServiceManager().getHID().setTouchScreenPress(message.touchscreen.x, message.touchscreen.y); break; case MessageType::ReleaseTouchscreen: emu->getServiceManager().getHID().releaseTouchScreen(); break; + + case MessageType::ReloadUbershader: + emu->getRenderer()->setUbershader(*message.string.str); + delete message.string.str; + break; } } diff --git a/src/panda_qt/shader_editor.cpp b/src/panda_qt/shader_editor.cpp index 8a23c8548..122d841fd 100644 --- a/src/panda_qt/shader_editor.cpp +++ b/src/panda_qt/shader_editor.cpp @@ -43,7 +43,7 @@ ShaderEditorWindow::ShaderEditorWindow(QWidget* parent, const std::string& filen } void ShaderEditorWindow::setEnable(bool enable) { - shaderEditorSupported = enable; + supported = enable; if (enable) { setDisabled(false);