From fe25d8d0f7dc0d04b7246819e2ac6d1c00cac2f5 Mon Sep 17 00:00:00 2001 From: jffmichi <> Date: Fri, 27 Feb 2026 00:11:11 +0100 Subject: [PATCH] CAM: Fix new CAM simulator on macOS --- .../PathSimulator/AppGL/DlgCAMSimulator.cpp | 5 +- .../CAM/PathSimulator/AppGL/GuiDisplay.cpp | 68 +++--- src/Mod/CAM/PathSimulator/AppGL/GuiDisplay.h | 3 +- .../CAM/PathSimulator/AppGL/MillPathLine.cpp | 30 +-- .../CAM/PathSimulator/AppGL/MillPathLine.h | 6 +- .../PathSimulator/AppGL/MillSimulation.cpp | 8 + .../CAM/PathSimulator/AppGL/MillSimulation.h | 2 + .../CAM/PathSimulator/AppGL/OpenGlWrapper.h | 5 +- src/Mod/CAM/PathSimulator/AppGL/Shader.cpp | 211 ++++++++++-------- src/Mod/CAM/PathSimulator/AppGL/Shader.h | 5 +- .../CAM/PathSimulator/AppGL/SimDisplay.cpp | 23 +- src/Mod/CAM/PathSimulator/AppGL/SimDisplay.h | 3 +- src/Mod/CAM/PathSimulator/AppGL/SimShapes.cpp | 18 +- src/Mod/CAM/PathSimulator/AppGL/SimShapes.h | 2 +- 14 files changed, 212 insertions(+), 177 deletions(-) diff --git a/src/Mod/CAM/PathSimulator/AppGL/DlgCAMSimulator.cpp b/src/Mod/CAM/PathSimulator/AppGL/DlgCAMSimulator.cpp index 3f41bcbb4d..fd8018ba68 100644 --- a/src/Mod/CAM/PathSimulator/AppGL/DlgCAMSimulator.cpp +++ b/src/Mod/CAM/PathSimulator/AppGL/DlgCAMSimulator.cpp @@ -56,14 +56,11 @@ DlgCAMSimulator::DlgCAMSimulator(ViewCAMSimulator& view, QWidget* parent) viewCAMSimulator = &view; - QSurfaceFormat format; - format.setVersion(4, 1); // Request OpenGL 4.1 - for MacOS - format.setProfile(QSurfaceFormat::CoreProfile); // Use the core profile = for MacOS + QSurfaceFormat format = QSurfaceFormat::defaultFormat(); int samples = Gui::View3DInventorViewer::getNumSamples(); if (samples > 1) { format.setSamples(samples); } - format.setSwapInterval(2); format.setDepthBufferSize(24); format.setStencilBufferSize(8); setFormat(format); diff --git a/src/Mod/CAM/PathSimulator/AppGL/GuiDisplay.cpp b/src/Mod/CAM/PathSimulator/AppGL/GuiDisplay.cpp index c69ff9195b..a8b37118b1 100644 --- a/src/Mod/CAM/PathSimulator/AppGL/GuiDisplay.cpp +++ b/src/Mod/CAM/PathSimulator/AppGL/GuiDisplay.cpp @@ -35,24 +35,24 @@ using namespace MillSim; // clang-format off // NOLINTBEGIN(*-magic-numbers) static const std::vector defaultGuiItems = { - {.name=eGuiItemSlider, .vbo=0, .vao=0, .sx=28, .sy=-80, .actionKey=0, .hidden=false, .flags=0}, - {.name=eGuiItemThumb, .vbo=0, .vao=0, .sx=328, .sy=-94, .actionKey=1, .hidden=false, .flags=0}, - {.name=eGuiItemPause, .vbo=0, .vao=0, .sx=28, .sy=-50, .actionKey='P', .hidden=true, .flags=0}, - {.name=eGuiItemPlay, .vbo=0, .vao=0, .sx=28, .sy=-50, .actionKey='S', .hidden=false, .flags=0}, - {.name=eGuiItemSingleStep, .vbo=0, .vao=0, .sx=68, .sy=-50, .actionKey='T', .hidden=false, .flags=0}, - {.name=eGuiItemSlower, .vbo=0, .vao=0, .sx=113, .sy=-50, .actionKey=' ', .hidden=false, .flags=0}, - {.name=eGuiItemFaster, .vbo=0, .vao=0, .sx=158, .sy=-50, .actionKey='F', .hidden=false, .flags=0}, - {.name=eGuiItemX, .vbo=0, .vao=0, .sx=208, .sy=-45, .actionKey=0, .hidden=false, .flags=0}, - {.name=eGuiItem1, .vbo=0, .vao=0, .sx=230, .sy=-50, .actionKey=0, .hidden=false, .flags=0}, - {.name=eGuiItem5, .vbo=0, .vao=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0}, - {.name=eGuiItem10, .vbo=0, .vao=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0}, - {.name=eGuiItem25, .vbo=0, .vao=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0}, - {.name=eGuiItem50, .vbo=0, .vao=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0}, - {.name=eGuiItemRotate, .vbo=0, .vao=0, .sx=-140, .sy=-50, .actionKey=' ', .hidden=false, .flags=GUIITEM_CHECKABLE}, - {.name=eGuiItemPath, .vbo=0, .vao=0, .sx=-100, .sy=-50, .actionKey='L', .hidden=false, .flags=GUIITEM_CHECKABLE}, - {.name=eGuiItemAmbientOclusion, .vbo=0, .vao=0, .sx=-60, .sy=-50, .actionKey='A', .hidden=false, .flags=GUIITEM_CHECKABLE}, - {.name=eGuiItemView, .vbo=0, .vao=0, .sx=-180, .sy=-50, .actionKey='V', .hidden=false, .flags=0}, - {.name=eGuiItemHome, .vbo=0, .vao=0, .sx=-220, .sy=-50, .actionKey='H', .hidden=false, .flags=0}, + {.name=eGuiItemSlider, .vbo=0, .sx=28, .sy=-80, .actionKey=0, .hidden=false, .flags=0}, + {.name=eGuiItemThumb, .vbo=0, .sx=328, .sy=-94, .actionKey=1, .hidden=false, .flags=0}, + {.name=eGuiItemPause, .vbo=0, .sx=28, .sy=-50, .actionKey='P', .hidden=true, .flags=0}, + {.name=eGuiItemPlay, .vbo=0, .sx=28, .sy=-50, .actionKey='S', .hidden=false, .flags=0}, + {.name=eGuiItemSingleStep, .vbo=0, .sx=68, .sy=-50, .actionKey='T', .hidden=false, .flags=0}, + {.name=eGuiItemSlower, .vbo=0, .sx=113, .sy=-50, .actionKey=' ', .hidden=false, .flags=0}, + {.name=eGuiItemFaster, .vbo=0, .sx=158, .sy=-50, .actionKey='F', .hidden=false, .flags=0}, + {.name=eGuiItemX, .vbo=0, .sx=208, .sy=-45, .actionKey=0, .hidden=false, .flags=0}, + {.name=eGuiItem1, .vbo=0, .sx=230, .sy=-50, .actionKey=0, .hidden=false, .flags=0}, + {.name=eGuiItem5, .vbo=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0}, + {.name=eGuiItem10, .vbo=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0}, + {.name=eGuiItem25, .vbo=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0}, + {.name=eGuiItem50, .vbo=0, .sx=230, .sy=-50, .actionKey=0, .hidden=true, .flags=0}, + {.name=eGuiItemRotate, .vbo=0, .sx=-140, .sy=-50, .actionKey=' ', .hidden=false, .flags=GUIITEM_CHECKABLE}, + {.name=eGuiItemPath, .vbo=0, .sx=-100, .sy=-50, .actionKey='L', .hidden=false, .flags=GUIITEM_CHECKABLE}, + {.name=eGuiItemAmbientOclusion, .vbo=0, .sx=-60, .sy=-50, .actionKey='A', .hidden=false, .flags=GUIITEM_CHECKABLE}, + {.name=eGuiItemView, .vbo=0, .sx=-180, .sy=-50, .actionKey='V', .hidden=false, .flags=0}, + {.name=eGuiItemHome, .vbo=0, .sx=-220, .sy=-50, .actionKey='H', .hidden=false, .flags=0}, }; // NOLINTEND(*-magic-numbers) // clang-format on @@ -143,17 +143,6 @@ bool GuiDisplay::GenerateGlItem(GuiItem* guiItem) glBindBuffer(GL_ARRAY_BUFFER, guiItem->vbo); glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(Vertex2D), verts, GL_STATIC_DRAW); - // glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, nullptr); - // vertex array - glGenVertexArrays(1, &(guiItem->vao)); - glBindVertexArray(guiItem->vao); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)offsetof(Vertex2D, x)); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)offsetof(Vertex2D, tx)); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIbo); - glBindVertexArray(0); - return true; } @@ -197,22 +186,22 @@ bool GuiDisplay::HStretchGlItem(GuiItem* guiItem, float newWidth, float edgeWidt glBindBuffer(GL_ARRAY_BUFFER, guiItem->vbo); glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(Vertex2D), verts, GL_STATIC_DRAW); - glGenVertexArrays(1, &(guiItem->vao)); - glBindVertexArray(guiItem->vao); + return true; +} + +void GuiDisplay::SetupVertexAttribs(GuiItem* guiItem) +{ + glBindBuffer(GL_ARRAY_BUFFER, guiItem->vbo); + glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)offsetof(Vertex2D, x)); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)offsetof(Vertex2D, tx)); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIbo); - glBindVertexArray(0); - - return true; } void GuiDisplay::DestroyGlItem(GuiItem* guiItem) { GLDELETE_BUFFER((guiItem->vbo)); - GLDELETE_VERTEXARRAY((guiItem->vao)); } bool GuiDisplay::InitGui() @@ -271,6 +260,7 @@ void GuiDisplay::RenderItem(int itemId) if (item->hidden) { return; } + mat4x4 model; mat4x4_translate(model, (float)item->posx(), (float)item->posy(), 0); mShader.UpdateModelMat(model, {}); @@ -290,7 +280,7 @@ void GuiDisplay::RenderItem(int itemId) mShader.UpdateObjColor(mStdColor); } - glBindVertexArray(item->vao); + SetupVertexAttribs(item); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIbo); int nTriangles = (item->flags & GUIITEM_STRETCHED) == 0 ? 6 : 18; glDrawElements(GL_TRIANGLES, nTriangles, GL_UNSIGNED_SHORT, nullptr); @@ -466,6 +456,10 @@ int GuiDisplay::height() const void GuiDisplay::Render(float progress) { + if (!guiInitiated) { + return; + } + if (mPressedItem == nullptr || mPressedItem->name != eGuiItemThumb) { mItems[eGuiItemThumb].setPosx((int)(mThumbMaxMotion * progress) + mThumbStartX); } diff --git a/src/Mod/CAM/PathSimulator/AppGL/GuiDisplay.h b/src/Mod/CAM/PathSimulator/AppGL/GuiDisplay.h index c9070a3d1a..ea0c3c4e13 100644 --- a/src/Mod/CAM/PathSimulator/AppGL/GuiDisplay.h +++ b/src/Mod/CAM/PathSimulator/AppGL/GuiDisplay.h @@ -60,7 +60,7 @@ enum eGuiItems struct DefaultGuiItem { eGuiItems name; - unsigned int vbo, vao; + unsigned int vbo = 0; int sx, sy; // screen location int actionKey; // action key when item pressed bool hidden {}; // is item hidden @@ -126,6 +126,7 @@ private: void UpdateProjection(); bool GenerateGlItem(GuiItem* guiItem); bool HStretchGlItem(GuiItem* guiItem, float newWidth, float edgeWidth); + void SetupVertexAttribs(GuiItem* guiItem); void DestroyGlItem(GuiItem* guiItem); void RenderItem(int itemId); void SetupTooltips(); diff --git a/src/Mod/CAM/PathSimulator/AppGL/MillPathLine.cpp b/src/Mod/CAM/PathSimulator/AppGL/MillPathLine.cpp index 539bf7bcfc..6a28ab3d71 100644 --- a/src/Mod/CAM/PathSimulator/AppGL/MillPathLine.cpp +++ b/src/Mod/CAM/PathSimulator/AppGL/MillPathLine.cpp @@ -8,27 +8,24 @@ namespace MillSim { - -MillPathLine::MillPathLine() -{ - mVao = mVbo = 0; -} - void MillPathLine::GenerateModel() { mNumVerts = MillPathPointsBuffer.size(); void* vbuffer = MillPathPointsBuffer.data(); - // vertex array - glGenVertexArrays(1, &mVao); - glBindVertexArray(mVao); - // vertex buffer glGenBuffers(1, &mVbo); glBindBuffer(GL_ARRAY_BUFFER, mVbo); glBufferData(GL_ARRAY_BUFFER, mNumVerts * sizeof(MillPathPosition), vbuffer, GL_STATIC_DRAW); - // vertex attribs + // free + MillPathPointsBuffer.clear(); +} + +void MillPathLine::SetupVertexAttibs() +{ + glBindBuffer(GL_ARRAY_BUFFER, mVbo); + glEnableVertexAttribArray(0); glVertexAttribPointer( 0, @@ -39,31 +36,26 @@ void MillPathLine::GenerateModel() (void*)offsetof(MillPathPosition, X) ); glEnableVertexAttribArray(1); - glVertexAttribIPointer( + glVertexAttribPointer( 1, 1, GL_INT, + GL_FALSE, sizeof(MillPathPosition), (void*)offsetof(MillPathPosition, SegmentId) ); - - // unbind and free - glBindVertexArray(0); - MillPathPointsBuffer.clear(); } void MillPathLine::Clear() { MillPathPointsBuffer.clear(); glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); GLDELETE_BUFFER(mVbo); - GLDELETE_VERTEXARRAY(mVao); } void MillPathLine::Render() { - glBindVertexArray(mVao); + SetupVertexAttibs(); glDrawArrays(GL_LINE_STRIP, 0, mNumVerts); } diff --git a/src/Mod/CAM/PathSimulator/AppGL/MillPathLine.h b/src/Mod/CAM/PathSimulator/AppGL/MillPathLine.h index 9f785ec4de..b501c5ebf3 100644 --- a/src/Mod/CAM/PathSimulator/AppGL/MillPathLine.h +++ b/src/Mod/CAM/PathSimulator/AppGL/MillPathLine.h @@ -1,6 +1,7 @@ // SPDX-License-Identifier: LGPL-2.1-or-later #pragma once + #include namespace MillSim @@ -15,8 +16,8 @@ struct MillPathPosition class MillPathLine { public: - MillPathLine(); void GenerateModel(); + void SetupVertexAttibs(); void Clear(); void Render(); @@ -24,8 +25,7 @@ public: std::vector MillPathPointsBuffer; protected: - unsigned int mVbo; - unsigned int mVao; + unsigned int mVbo = 0; int mNumVerts; }; diff --git a/src/Mod/CAM/PathSimulator/AppGL/MillSimulation.cpp b/src/Mod/CAM/PathSimulator/AppGL/MillSimulation.cpp index b232b22697..fcb0c37d2a 100644 --- a/src/Mod/CAM/PathSimulator/AppGL/MillSimulation.cpp +++ b/src/Mod/CAM/PathSimulator/AppGL/MillSimulation.cpp @@ -65,6 +65,8 @@ void MillSimulation::Clear() mCurStep = 0; mPathStep = -1; mNTotalSteps = 0; + + simulationInitiated = false; } @@ -122,6 +124,8 @@ void MillSimulation::InitSimulation(float quality) mNPathSteps = (int)MillPathSegments.size(); millPathLine.GenerateModel(); InitDisplay(quality); + + simulationInitiated = true; } EndMill* MillSimulation::GetTool(int toolId) @@ -370,6 +374,10 @@ void MillSimulation::RenderBaseShape() void MillSimulation::Render() { + if (!simulationInitiated) { + return; + } + // set background glClearColor(bgndColor[0], bgndColor[1], bgndColor[2], 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); diff --git a/src/Mod/CAM/PathSimulator/AppGL/MillSimulation.h b/src/Mod/CAM/PathSimulator/AppGL/MillSimulation.h index 3ab644d751..284708d17f 100644 --- a/src/Mod/CAM/PathSimulator/AppGL/MillSimulation.h +++ b/src/Mod/CAM/PathSimulator/AppGL/MillSimulation.h @@ -113,6 +113,8 @@ protected: void RemoveTool(int toolId); protected: + bool simulationInitiated = false; + std::vector mToolTable; GCodeParser mCodeParser; GuiDisplay guiDisplay; diff --git a/src/Mod/CAM/PathSimulator/AppGL/OpenGlWrapper.h b/src/Mod/CAM/PathSimulator/AppGL/OpenGlWrapper.h index e6472cebc9..cc97de9ebf 100644 --- a/src/Mod/CAM/PathSimulator/AppGL/OpenGlWrapper.h +++ b/src/Mod/CAM/PathSimulator/AppGL/OpenGlWrapper.h @@ -25,6 +25,7 @@ #pragma once #include "DlgCAMSimulator.h" + #define gSimWindow CAMSimulator::DlgCAMSimulator::instance() #define glClearColor gSimWindow->glClearColor #define glBlendFunc gSimWindow->glBlendFunc @@ -36,6 +37,8 @@ #define glBindVertexArray gSimWindow->glBindVertexArray #define glEnableVertexAttribArray gSimWindow->glEnableVertexAttribArray #define glVertexAttribPointer gSimWindow->glVertexAttribPointer +#define glBindAttribLocation gSimWindow->glBindAttribLocation +#define glGetAttribLocation gSimWindow->glGetAttribLocation #define glShaderSource gSimWindow->glShaderSource #define glCompileShader gSimWindow->glCompileShader #define glDeleteShader gSimWindow->glDeleteShader @@ -44,7 +47,7 @@ #define glLinkProgram gSimWindow->glLinkProgram #define glGetProgramiv gSimWindow->glGetProgramiv #define glGetUniformLocation gSimWindow->glGetUniformLocation -#define glGetError gSimWindow->glGetError +#define glGetError(...) /* GL( */ gSimWindow->glGetError(__VA_ARGS__) /* ) */ #define glEnable gSimWindow->glEnable #define glColorMask gSimWindow->glColorMask #define glCullFace gSimWindow->glCullFace diff --git a/src/Mod/CAM/PathSimulator/AppGL/Shader.cpp b/src/Mod/CAM/PathSimulator/AppGL/Shader.cpp index c5adf2c325..356594d1db 100644 --- a/src/Mod/CAM/PathSimulator/AppGL/Shader.cpp +++ b/src/Mod/CAM/PathSimulator/AppGL/Shader.cpp @@ -33,6 +33,7 @@ #include "GlUtils.h" #include "Shader.h" #include +#include #include namespace MillSim @@ -199,13 +200,51 @@ bool CheckCompileResult(int shaderId, const char* shaderName, bool isVertex) return true; } +static void preprocessVertexShader(std::string& shader, std::map& attributes) +{ + // The new CAM simulator relies on "layout(location = x)" to specify vertex attributes. However, + // on macOS we're limited to OpenGL 2.1 and GLSL 1.20 and layout specifiers are not supported. + // We use a regex to search those specifiers and extract the information manually. This can then + // be used with glBindAttribLocation to achieve the same result. + + const std::regex attributeRegex { + "layout\\s*\\(\\s*location\\s*=\\s*(\\d+)\\s*\\)\\s*attribute\\s+(\\w+)\\s+(\\w+);" + }; + + for (int i = 0; i < (int)shader.size();) { + std::smatch match; + if (!std::regex_search(shader.cbegin() + i, shader.cend(), match, attributeRegex)) { + break; + } + + const int location = std::stoi(match[1]); + const std::string type = match[2]; + const std::string name = match[3]; + + attributes[location] = name; + + const std::string prefix {shader.cbegin(), match.prefix().second}; + const std::string suffix = match.suffix().str(); + + const std::string decl = "attribute " + type + " " + name + ";"; + + shader = prefix + decl + suffix; + i += decl.length(); + } +} + unsigned int Shader::CompileShader(const char* name, const char* _vertShader, const char* _fragShader) { vertShader = _vertShader; fragShader = _fragShader; + + std::map attributes; + preprocessVertexShader(vertShader, attributes); + const GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); GLint res = 0; - glShaderSource(vertex_shader, 1, &vertShader, NULL); + const char* vertShaderData[] = {vertShader.c_str()}; + glShaderSource(vertex_shader, 1, vertShaderData, NULL); glCompileShader(vertex_shader); if (CheckCompileResult(vertex_shader, name, true)) { glDeleteShader(vertex_shader); @@ -213,7 +252,8 @@ unsigned int Shader::CompileShader(const char* name, const char* _vertShader, co } const GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragment_shader, 1, &fragShader, NULL); + const char* fragShaderData[] = {fragShader.c_str()}; + glShaderSource(fragment_shader, 1, fragShaderData, NULL); glCompileShader(fragment_shader); if (CheckCompileResult(fragment_shader, name, false)) { glDeleteShader(fragment_shader); @@ -224,6 +264,11 @@ unsigned int Shader::CompileShader(const char* name, const char* _vertShader, co shaderId = glCreateProgram(); glAttachShader(shaderId, vertex_shader); glAttachShader(shaderId, fragment_shader); + + for (auto [pos, name] : attributes) { + glBindAttribLocation(shaderId, pos, name.c_str()); + } + glLinkProgram(shaderId); glGetProgramiv(shaderId, GL_LINK_STATUS, &res); @@ -279,13 +324,13 @@ void Shader::Destroy() const char* VertShader3DNorm = R"( - #version 330 core + #version 120 - layout(location = 0) in vec3 aPosition; - layout(location = 1) in vec3 aNormal; + layout(location = 0) attribute vec3 aPosition; + layout(location = 1) attribute vec3 aNormal; - out vec3 Normal; - out vec3 Position; + varying vec3 Normal; + varying vec3 Position; uniform mat4 model; uniform mat4 view; @@ -302,13 +347,13 @@ const char* VertShader3DNorm = R"( )"; const char* VertShader3DInvNorm = R"( - #version 330 core + #version 120 - layout(location = 0) in vec3 aPosition; - layout(location = 1) in vec3 aNormal; + layout(location = 0) attribute vec3 aPosition; + layout(location = 1) attribute vec3 aNormal; - out vec3 Normal; - out vec3 Position; + varying vec3 Normal; + varying vec3 Position; uniform mat4 model; uniform mat4 view; @@ -325,12 +370,12 @@ const char* VertShader3DInvNorm = R"( const char* VertShader2DTex = R"( - #version 330 core + #version 120 - layout(location = 0) in vec2 aPosition; - layout(location = 1) in vec2 aTexCoord; + layout(location = 0) attribute vec2 aPosition; + layout(location = 1) attribute vec2 aTexCoord; - out vec2 texCoord; + varying vec2 texCoord; uniform mat4 projection; uniform mat4 model; @@ -343,29 +388,26 @@ const char* VertShader2DTex = R"( )"; const char* FragShader2dTex = R"( - #version 330 + #version 120 - out vec4 FragColor; - in vec2 texCoord; + varying vec2 texCoord; uniform vec3 objectColor; uniform sampler2D texSlot; void main() { - vec4 texColor = texture(texSlot, texCoord); - FragColor = vec4(objectColor, 1.0) * texColor; + vec4 texColor = texture2D(texSlot, texCoord); + gl_FragColor = vec4(objectColor, 1.0) * texColor; } )"; const char* FragShaderNorm = R"( - #version 330 + #version 120 - out vec4 FragColor; - - in vec3 Normal; - in vec3 Position; + varying vec3 Normal; + varying vec3 Position; uniform vec3 lightPos; uniform vec3 lightColor; @@ -379,33 +421,29 @@ const char* FragShaderNorm = R"( float diff = max(dot(norm, lightDir), 0.0); vec3 diffuse = diff * lightColor; vec3 result = (lightAmbient + diffuse) * objectColor; - FragColor = vec4(result, 1.0); + gl_FragColor = vec4(result, 1.0); } )"; const char* FragShaderFlat = R"( - #version 330 + #version 120 - out vec4 FragColor; - - in vec3 Normal; - in vec3 Position; uniform vec3 objectColor; void main() { - FragColor = vec4(objectColor, 1.0); + gl_FragColor = vec4(objectColor, 1.0); } )"; const char* VertShader2DFbo = R"( - #version 330 core + #version 120 - layout(location = 0) in vec2 aPosition; - layout(location = 1) in vec2 aTexCoord; + layout(location = 0) attribute vec2 aPosition; + layout(location = 1) attribute vec2 aTexCoord; - out vec2 texCoord; + varying vec2 texCoord; void main(void) { @@ -415,27 +453,27 @@ const char* VertShader2DFbo = R"( )"; const char* FragShader2dFbo = R"( - #version 330 + #version 120 - out vec4 FragColor; - in vec2 texCoord; + varying vec2 texCoord; uniform sampler2D texSlot; void main() { - vec4 tc = texture(texSlot, texCoord); - FragColor = tc; + vec4 tc = texture2D(texSlot, texCoord); + gl_FragColor = tc; } )"; const char* VertShaderGeom = R"( - #version 330 core - layout (location = 0) in vec3 aPos; - layout (location = 1) in vec3 aNormal; + #version 120 - out vec3 Position; - out vec3 Normal; + layout(location = 0) attribute vec3 aPosition; + layout(location = 1) attribute vec3 aNormal; + + varying vec3 Position; + varying vec3 Normal; uniform bool invertedNormals; @@ -445,10 +483,10 @@ const char* VertShaderGeom = R"( void main() { - vec4 viewPos = view * model * vec4(aPos, 1.0); + vec4 viewPos = view * model * vec4(aPosition, 1.0); Position = viewPos.xyz; - mat3 normalMatrix = transpose(inverse(mat3(view * model))); + mat3 normalMatrix = /* transpose(inverse( */ mat3(view * model) /* )) */; Normal = normalMatrix * (invertedNormals ? -aNormal : aNormal); gl_Position = projection * viewPos; @@ -456,30 +494,26 @@ const char* VertShaderGeom = R"( )"; const char* FragShaderGeom = R"( - #version 330 core - layout (location = 0) out vec4 ColorTex; - layout (location = 1) out vec3 PositionTex; - layout (location = 2) out vec3 NormalTex; + #version 120 - in vec3 Position; - in vec3 Normal; + varying vec3 Position; + varying vec3 Normal; uniform vec3 objectColor; void main() { // Store position, normal, and diffuse color in textures - PositionTex = Position; - NormalTex = normalize(Normal); - ColorTex = vec4(objectColor, 1.0f); + gl_FragData[0] = vec4(objectColor, 1.0f); + gl_FragData[1] = vec4(Position, 0.0f); + gl_FragData[2] = vec4(normalize(Normal), 0.0f); } )"; const char* FragShaderSSAO = R"( - #version 330 core - layout (location = 0) out float AoData; + #version 120 - in vec2 texCoord; + varying vec2 texCoord; uniform sampler2D RandTex; uniform sampler2D PositionTex; @@ -497,8 +531,8 @@ const char* FragShaderSSAO = R"( { // Create the random tangent space matrix vec2 randScale = vec2( screenWidth / 4.0, screenHeight / 4.0 ); - vec3 randDir = normalize( texture(RandTex, texCoord.xy * randScale).xyz ); - vec3 n = normalize( texture(NormalTex, texCoord).xyz ); + vec3 randDir = normalize( texture2D(RandTex, texCoord.xy * randScale).xyz ); + vec3 n = normalize( texture2D(NormalTex, texCoord).xyz ); vec3 biTang = cross( n, randDir ); if( length(biTang) < 0.0001 ) // If n and randDir are parallel, n is in x-y plane biTang = cross( n, vec3(0,0,1)); @@ -507,7 +541,7 @@ const char* FragShaderSSAO = R"( mat3 toCamSpace = mat3(tang, biTang, n); float occlusionSum = 0.0; - vec3 camPos = texture(PositionTex, texCoord).xyz; + vec3 camPos = texture2D(PositionTex, texCoord).xyz; for( int i = 0; i < kernelSize; i++ ) { vec3 samplePos = camPos + Radius * (toCamSpace * SampleKernel[i]); @@ -517,7 +551,7 @@ const char* FragShaderSSAO = R"( p.xyz = p.xyz * 0.5 + 0.5; // Access camera space z-coordinate at that point - float surfaceZ = texture(PositionTex, p.xy).z; + float surfaceZ = texture2D(PositionTex, p.xy).z; float zDist = surfaceZ - camPos.z; // Count points that ARE occluded @@ -525,39 +559,38 @@ const char* FragShaderSSAO = R"( } float occ = occlusionSum / kernelSize; - AoData = 1.0 - occ; + gl_FragData[0] = vec4(1.0 - occ); } )"; const char* FragShaderSSAOBlur = R"( - #version 330 core - layout (location = 0) out float AoData; - - in vec2 texCoord; + #version 120 uniform sampler2D AoTex; + uniform float screenWidth; + uniform float screenHeight; + void main() { ivec2 pix = ivec2( gl_FragCoord.xy ); float sum = 0.0; for( int x = -1; x <= 2; ++x ) { for( int y = -1; y <= 2; y++ ) { - sum += texelFetch( AoTex, pix + ivec2(x,y), 0).r; + sum += texture2D( AoTex, (pix + ivec2(x,y)) / vec2(screenWidth, screenHeight), 0).r; } } float ao = sum * (1.0 / 16.0); - AoData = ao; + gl_FragData[0] = vec4(ao); } )"; const char* FragShaderSSAOLighting = R"( - #version 330 core - out vec4 FragColor; + #version 120 - in vec2 texCoord; + varying vec2 texCoord; uniform vec3 lightPos; uniform vec3 lightColor; @@ -580,25 +613,26 @@ const char* FragShaderSSAOLighting = R"( void main() { - vec3 pos = texture( PositionTex, texCoord ).xyz; - vec3 norm = texture( NormalTex, texCoord ).xyz; - vec4 DiffColorA = texture(ColorTex, texCoord); + vec3 pos = texture2D( PositionTex, texCoord ).xyz; + vec3 norm = texture2D( NormalTex, texCoord ).xyz; + vec4 DiffColorA = texture2D(ColorTex, texCoord); vec3 diffColor = DiffColorA.rgb; - float aoVal = ssaoActive ? texture( AoTex, texCoord).r : 1.0; + float aoVal = ssaoActive ? texture2D( AoTex, texCoord).r : 1.0; vec3 col = ambAndDiffuse(pos, norm, diffColor, aoVal); col = pow(col, vec3(1.0/2.2)); - FragColor = vec4( col, DiffColorA.a ); + gl_FragColor = vec4( col, DiffColorA.a ); } )"; const char* VertShader3DLine = R"( - #version 330 core + #version 120 - layout(location = 0) in vec3 aPosition; - layout(location = 1) in int aIndex; - flat out int Index; + layout(location = 0) attribute vec3 aPosition; + layout(location = 1) attribute float aIndex; + + varying float Index; uniform mat4 view; uniform mat4 projection; @@ -611,19 +645,18 @@ const char* VertShader3DLine = R"( )"; const char* FragShader3DLine = R"( - #version 330 + #version 120 - out vec4 FragColor; + varying float Index; - flat in int Index; uniform vec4 objectColorAlpha; uniform vec3 objectColor; uniform int curSegment; void main() { - if (Index > curSegment) FragColor = objectColorAlpha; - else FragColor = vec4(objectColor, objectColorAlpha.a); + if (Index > curSegment) gl_FragColor = objectColorAlpha; + else gl_FragColor = vec4(objectColor, objectColorAlpha.a); } )"; diff --git a/src/Mod/CAM/PathSimulator/AppGL/Shader.h b/src/Mod/CAM/PathSimulator/AppGL/Shader.h index 3cb1f956cb..e1ce8420e7 100644 --- a/src/Mod/CAM/PathSimulator/AppGL/Shader.h +++ b/src/Mod/CAM/PathSimulator/AppGL/Shader.h @@ -63,7 +63,6 @@ public: return shaderId > 0; } - protected: int mModelPos = -1; int mNormalRotPos = -1; @@ -88,8 +87,8 @@ protected: int mScreenWidthPos = -1; int mScreenHeightPos = -1; - const char* vertShader = nullptr; - const char* fragShader = nullptr; + std::string vertShader; + std::string fragShader; }; extern Shader* CurrentShader; diff --git a/src/Mod/CAM/PathSimulator/AppGL/SimDisplay.cpp b/src/Mod/CAM/PathSimulator/AppGL/SimDisplay.cpp index 914ac12726..5ea3b9ca95 100644 --- a/src/Mod/CAM/PathSimulator/AppGL/SimDisplay.cpp +++ b/src/Mod/CAM/PathSimulator/AppGL/SimDisplay.cpp @@ -91,11 +91,15 @@ void SimDisplay::CreateFboQuad() 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f }; - glGenVertexArrays(1, &mFboQuadVAO); glGenBuffers(1, &mFboQuadVBO); - glBindVertexArray(mFboQuadVAO); glBindBuffer(GL_ARRAY_BUFFER, mFboQuadVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices[0], GL_STATIC_DRAW); +} + +void SimDisplay::SetupVertexAttribs() +{ + glBindBuffer(GL_ARRAY_BUFFER, mFboQuadVBO); + glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); glEnableVertexAttribArray(1); @@ -149,7 +153,6 @@ void SimDisplay::CreateDisplayFbos() CreateGBufTex(GL_TEXTURE2, GL_RGB32F, GL_RGBA, GL_FLOAT, mFboNormTexture); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, mFboNormTexture, 0); - unsigned int attachments[3] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2}; glDrawBuffers(3, attachments); @@ -277,7 +280,6 @@ void SimDisplay::CleanGL() CleanFbos(); // cleanup geometry - GLDELETE_VERTEXARRAY(mFboQuadVAO); GLDELETE_BUFFER(mFboQuadVBO); // cleanup shaders @@ -368,6 +370,10 @@ void SimDisplay::ScaleViewToStock(StockObject* obj) void SimDisplay::RenderResult(bool recalculate, bool ssao) { + if (!displayInitiated) { + return; + } + if (mSsaoValid && ssao) { RenderResultSSAO(recalculate); } @@ -388,7 +394,7 @@ void SimDisplay::RenderResultStandard() shaderSSAOLighting.UpdateNormalTexSlot(2); shaderSSAOLighting.UpdateSsaoActive(false); // shaderSimFbo.Activate(); - glBindVertexArray(mFboQuadVAO); + SetupVertexAttribs(); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glActiveTexture(GL_TEXTURE0); @@ -423,7 +429,7 @@ void SimDisplay::RenderResultSSAO(bool recalculate) glBindTexture(GL_TEXTURE_2D, mFboPosTexture); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, mFboNormTexture); - glBindVertexArray(mFboQuadVAO); + SetupVertexAttribs(); glDrawArrays(GL_TRIANGLES, 0, 6); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -434,7 +440,8 @@ void SimDisplay::RenderResultSSAO(bool recalculate) shaderSSAOBlur.UpdateSsaoTexSlot(0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, mFboSsaoTexture); - glBindVertexArray(mFboQuadVAO); + shaderSSAOBlur.UpdateScreenDimension(mWidth, mHeight); + SetupVertexAttribs(); glDrawArrays(GL_TRIANGLES, 0, 6); } @@ -456,7 +463,7 @@ void SimDisplay::RenderResultSSAO(bool recalculate) glBindTexture(GL_TEXTURE_2D, mFboSsaoBlurTexture); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBindVertexArray(mFboQuadVAO); + SetupVertexAttribs(); glDrawArrays(GL_TRIANGLES, 0, 6); } diff --git a/src/Mod/CAM/PathSimulator/AppGL/SimDisplay.h b/src/Mod/CAM/PathSimulator/AppGL/SimDisplay.h index 8c41271369..b60fa07eb2 100644 --- a/src/Mod/CAM/PathSimulator/AppGL/SimDisplay.h +++ b/src/Mod/CAM/PathSimulator/AppGL/SimDisplay.h @@ -80,6 +80,7 @@ protected: void CreateDisplayFbos(); void CreateSsaoFbos(); void CreateFboQuad(); + void SetupVertexAttribs(); void CreateGBufTex(GLenum texUnit, GLint intFormat, GLenum format, GLenum type, GLuint& texid); void UniformHemisphere(vec3& randVec); void UniformCircle(vec3& randVec); @@ -127,7 +128,7 @@ protected: unsigned int mFboPosTexture = 0; unsigned int mFboNormTexture = 0; unsigned int mRboDepthStencil = 0; - unsigned int mFboQuadVAO = 0, mFboQuadVBO = 0; + unsigned int mFboQuadVBO = 0; // ssao frame buffers bool mSsaoValid = false; diff --git a/src/Mod/CAM/PathSimulator/AppGL/SimShapes.cpp b/src/Mod/CAM/PathSimulator/AppGL/SimShapes.cpp index a4b6270740..d00f38760d 100644 --- a/src/Mod/CAM/PathSimulator/AppGL/SimShapes.cpp +++ b/src/Mod/CAM/PathSimulator/AppGL/SimShapes.cpp @@ -333,9 +333,7 @@ void Shape::GenerateModel(const float* vbuffer, const GLushort* ibuffer, int num // vertex buffer glGenBuffers(1, &vbo); - GLClearError(); glBindBuffer(GL_ARRAY_BUFFER, vbo); - GLLogError(); glBufferData(GL_ARRAY_BUFFER, numVerts * sizeof(Vertex), vbuffer, GL_STATIC_DRAW); // index buffer @@ -343,15 +341,17 @@ void Shape::GenerateModel(const float* vbuffer, const GLushort* ibuffer, int num glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, nIndices * sizeof(GLushort), ibuffer, GL_STATIC_DRAW); - // vertex array - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); + numIndices = nIndices; +} + +void Shape::SetupVertexAttribs() +{ + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, x)); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, nx)); - - numIndices = nIndices; } void Shape::SetModelData(const std::vector& vbuffer, const std::vector& ibuffer) @@ -361,7 +361,7 @@ void Shape::SetModelData(const std::vector& vbuffer, const std::vector