Download src/Mod/CAM/PathSimulator/AppGL/Shader.cpp from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 17 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/CAM/PathSimulator/AppGL/Shader.cpp
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/CAM/PathSimulator/AppGL/Shader.cpp
-
curl -L -o Shader.cpp https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/CAM/PathSimulator/AppGL/Shader.cpp
17 kB
| // SPDX-License-Identifier: LGPL-2.1-or-later AND MIT | |
| /*************************************************************************** | |
| * Copyright (c) 2024 Shai Seger <shaise at gmail> * | |
| * * | |
| * This file is part of the FreeCAD CAx development system. * | |
| * * | |
| * This library is free software; you can redistribute it and/or * | |
| * modify it under the terms of the GNU Library General Public * | |
| * License as published by the Free Software Foundation; either * | |
| * version 2 of the License, or (at your option) any later version. * | |
| * * | |
| * This library is distributed in the hope that it will be useful, * | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
| * GNU Library General Public License for more details. * | |
| * * | |
| * You should have received a copy of the GNU Library General Public * | |
| * License along with this library; see the file COPYING.LIB. If not, * | |
| * write to the Free Software Foundation, Inc., 59 Temple Place, * | |
| * Suite 330, Boston, MA 02111-1307, USA * | |
| * * | |
| * * | |
| * Portions of this code are taken from: * | |
| * "OpenGL 4 Shading Language cookbook" Third edition * | |
| * Written by: David Wolff * | |
| * Published by: <packt> www.packt.com * | |
| * License: MIT License * | |
| * * | |
| * * | |
| ***************************************************************************/ | |
| namespace MillSim | |
| { | |
| Shader* CurrentShader = nullptr; | |
| Shader::~Shader() | |
| { | |
| Destroy(); | |
| } | |
| void Shader::UpdateModelMat(mat4x4 tmat, mat4x4 nmat) | |
| { | |
| if (mModelPos >= 0) { | |
| glUniformMatrix4fv(mModelPos, 1, GL_FALSE, (GLfloat*)tmat); | |
| } | |
| if (mNormalRotPos >= 0) { | |
| glUniformMatrix4fv(mNormalRotPos, 1, GL_FALSE, (GLfloat*)nmat); | |
| } | |
| } | |
| void Shader::UpdateProjectionMat(mat4x4 mat) | |
| { | |
| if (mProjectionPos >= 0) { | |
| glUniformMatrix4fv(mProjectionPos, 1, GL_FALSE, (GLfloat*)mat); | |
| } | |
| } | |
| void Shader::UpdateViewMat(mat4x4 mat) | |
| { | |
| if (mViewPos >= 0) { | |
| glUniformMatrix4fv(mViewPos, 1, GL_FALSE, (GLfloat*)mat); | |
| } | |
| } | |
| void Shader::UpdateEnvColor(vec3 lightPos, vec3 lightColor, vec3 ambient, float linearity) | |
| { | |
| if (mLightPosPos >= 0) { | |
| glUniform3fv(mLightPosPos, 1, lightPos); | |
| } | |
| if (mLightColorPos >= 0) { | |
| glUniform3fv(mLightColorPos, 1, lightColor); | |
| } | |
| if (mLightAmbientPos >= 0) { | |
| glUniform3fv(mLightAmbientPos, 1, ambient); | |
| } | |
| if (mLightLinearPos >= 0) { | |
| glUniform1f(mLightLinearPos, linearity); | |
| } | |
| } | |
| void Shader::UpdateScreenDimension(int width, int height) | |
| { | |
| if (mScreenWidthPos >= 0) { | |
| glUniform1f(mScreenWidthPos, (float)width); | |
| } | |
| if (mScreenHeightPos >= 0) { | |
| glUniform1f(mScreenHeightPos, (float)height); | |
| } | |
| } | |
| void Shader::UpdateObjColor(vec3 objColor) | |
| { | |
| if (mObjectColorPos >= 0) { | |
| glUniform3fv(mObjectColorPos, 1, objColor); | |
| } | |
| } | |
| void Shader::UpdateObjColorAlpha(vec4 objColor) | |
| { | |
| if (mObjectColorAlphaPos >= 0) { | |
| glUniform4fv(mObjectColorAlphaPos, 1, objColor); | |
| } | |
| } | |
| void Shader::UpdateNormalState(bool isInverted) | |
| { | |
| if (mInvertedNormalsPos >= 0) { | |
| glUniform1i(mInvertedNormalsPos, isInverted); | |
| } | |
| } | |
| void Shader::UpdateSsaoActive(bool isActive) | |
| { | |
| if (mSsaoActivePos >= 0) { | |
| glUniform1i(mSsaoActivePos, isActive); | |
| } | |
| } | |
| void Shader::UpdateTextureSlot(int slot) | |
| { | |
| if (mTexSlotPos >= 0) { | |
| glUniform1i(mTexSlotPos, slot); | |
| } | |
| } | |
| void Shader::UpdateColorTexSlot(int albedoSlot) | |
| { | |
| if (mAlbedoPos >= 0) { | |
| glUniform1i(mAlbedoPos, albedoSlot); | |
| } | |
| } | |
| void Shader::UpdatePositionTexSlot(int positionSlot) | |
| { | |
| if (mPositionPos >= 0) { | |
| glUniform1i(mPositionPos, positionSlot); | |
| } | |
| } | |
| void Shader::UpdateNormalTexSlot(int normalSlot) | |
| { | |
| if (mNormalPos >= 0) { | |
| glUniform1i(mNormalPos, normalSlot); | |
| } | |
| } | |
| void Shader::UpdateRandomTexSlot(int randSlot) | |
| { | |
| if (mRandTexPos >= 0) { | |
| glUniform1i(mRandTexPos, randSlot); | |
| } | |
| } | |
| void Shader::UpdateSsaoTexSlot(int ssaoSlot) | |
| { | |
| if (mSsaoPos >= 0) { | |
| glUniform1i(mSsaoPos, ssaoSlot); | |
| } | |
| } | |
| void Shader::UpdateKernelVals(int nVals, float* vals) | |
| { | |
| glUniform3fv(mSamplesPos, nVals, vals); | |
| } | |
| void Shader::UpdateCurSegment(int curSeg) | |
| { | |
| if (mCurSegmentPos >= 0) { | |
| glUniform1i(mCurSegmentPos, curSeg); | |
| } | |
| } | |
| bool CheckCompileResult(int shaderId, const char* shaderName, bool isVertex) | |
| { | |
| char log[1024]; | |
| int res = 0; | |
| GLsizei len; | |
| glGetShaderiv(shaderId, GL_COMPILE_STATUS, &res); | |
| if (res != 0) { | |
| return false; | |
| } | |
| int headerLen | |
| = snprintf(log, 48, "Error compiling %s %s shader: ", shaderName, isVertex ? "vertex" : "fragment"); | |
| glGetShaderInfoLog(shaderId, 1020 - headerLen, &len, log + headerLen); | |
| len += headerLen; | |
| if (len > 1020) { | |
| len = 1020; | |
| } | |
| log[len] = 0; | |
| Base::Console().error(log); | |
| return true; | |
| } | |
| unsigned int Shader::CompileShader(const char* name, const char* _vertShader, const char* _fragShader) | |
| { | |
| vertShader = _vertShader; | |
| fragShader = _fragShader; | |
| const GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); | |
| GLint res = 0; | |
| glShaderSource(vertex_shader, 1, &vertShader, NULL); | |
| glCompileShader(vertex_shader); | |
| if (CheckCompileResult(vertex_shader, name, true)) { | |
| glDeleteShader(vertex_shader); | |
| return 0xdeadbeef; | |
| } | |
| const GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); | |
| glShaderSource(fragment_shader, 1, &fragShader, NULL); | |
| glCompileShader(fragment_shader); | |
| if (CheckCompileResult(fragment_shader, name, false)) { | |
| glDeleteShader(fragment_shader); | |
| glDeleteShader(vertex_shader); | |
| return 0xdeadbeef; | |
| } | |
| shaderId = glCreateProgram(); | |
| glAttachShader(shaderId, vertex_shader); | |
| glAttachShader(shaderId, fragment_shader); | |
| glLinkProgram(shaderId); | |
| glGetProgramiv(shaderId, GL_LINK_STATUS, &res); | |
| if (res == 0) { | |
| Destroy(); | |
| return 0xdeadbeef; | |
| } | |
| // get all uniform parameters positions | |
| mModelPos = glGetUniformLocation(shaderId, "model"); | |
| mNormalRotPos = glGetUniformLocation(shaderId, "normalRot"); | |
| mProjectionPos = glGetUniformLocation(shaderId, "projection"); | |
| mViewPos = glGetUniformLocation(shaderId, "view"); | |
| mLightPosPos = glGetUniformLocation(shaderId, "lightPos"); | |
| mLightColorPos = glGetUniformLocation(shaderId, "lightColor"); | |
| mLightLinearPos = glGetUniformLocation(shaderId, "lightLinear"); | |
| mLightAmbientPos = glGetUniformLocation(shaderId, "lightAmbient"); | |
| mObjectColorPos = glGetUniformLocation(shaderId, "objectColor"); | |
| mObjectColorAlphaPos = glGetUniformLocation(shaderId, "objectColorAlpha"); | |
| mTexSlotPos = glGetUniformLocation(shaderId, "texSlot"); | |
| mInvertedNormalsPos = glGetUniformLocation(shaderId, "invertedNormals"); | |
| mSsaoActivePos = glGetUniformLocation(shaderId, "ssaoActive"); | |
| mAlbedoPos = glGetUniformLocation(shaderId, "ColorTex"); | |
| mPositionPos = glGetUniformLocation(shaderId, "PositionTex"); | |
| mNormalPos = glGetUniformLocation(shaderId, "NormalTex"); | |
| mSsaoPos = glGetUniformLocation(shaderId, "AoTex"); | |
| mRandTexPos = glGetUniformLocation(shaderId, "RandTex"); | |
| mSamplesPos = glGetUniformLocation(shaderId, "SampleKernel"); | |
| mCurSegmentPos = glGetUniformLocation(shaderId, "curSegment"); | |
| mScreenWidthPos = glGetUniformLocation(shaderId, "screenWidth"); | |
| mScreenHeightPos = glGetUniformLocation(shaderId, "screenHeight"); | |
| Activate(); | |
| return shaderId; | |
| } | |
| void Shader::Activate() | |
| { | |
| if (shaderId > 0) { | |
| glUseProgram(shaderId); | |
| } | |
| CurrentShader = this; | |
| } | |
| void Shader::Destroy() | |
| { | |
| if (shaderId == 0) { | |
| return; | |
| } | |
| glDeleteProgram(shaderId); | |
| shaderId = 0; | |
| } | |
| const char* VertShader3DNorm = R"( | |
| #version 330 core | |
| layout(location = 0) in vec3 aPosition; | |
| layout(location = 1) in vec3 aNormal; | |
| out vec3 Normal; | |
| out vec3 Position; | |
| uniform mat4 model; | |
| uniform mat4 view; | |
| uniform mat4 projection; | |
| uniform mat4 normalRot; | |
| void main(void) | |
| { | |
| vec4 viewPos = view * model * vec4(aPosition, 1.0); | |
| Position = vec3(model * vec4(aPosition, 1.0)); | |
| Normal = vec3(normalRot * vec4(aNormal, 1.0)); | |
| gl_Position = projection * viewPos; | |
| } | |
| )"; | |
| const char* VertShader3DInvNorm = R"( | |
| #version 330 core | |
| layout(location = 0) in vec3 aPosition; | |
| layout(location = 1) in vec3 aNormal; | |
| out vec3 Normal; | |
| out vec3 Position; | |
| uniform mat4 model; | |
| uniform mat4 view; | |
| uniform mat4 projection; | |
| uniform mat4 normalRot; | |
| void main(void) | |
| { | |
| gl_Position = projection * view * model * vec4(aPosition, 1.0); | |
| Position = vec3(model * vec4(aPosition, 1.0)); | |
| Normal = -vec3(normalRot * vec4(aNormal, 1.0)); | |
| } | |
| )"; | |
| const char* VertShader2DTex = R"( | |
| #version 330 core | |
| layout(location = 0) in vec2 aPosition; | |
| layout(location = 1) in vec2 aTexCoord; | |
| out vec2 texCoord; | |
| uniform mat4 projection; | |
| uniform mat4 model; | |
| void main(void) | |
| { | |
| gl_Position = projection * model * vec4(aPosition, 0.0, 1.0); | |
| texCoord = aTexCoord; | |
| } | |
| )"; | |
| const char* FragShader2dTex = R"( | |
| #version 330 | |
| out vec4 FragColor; | |
| in vec2 texCoord; | |
| uniform vec3 objectColor; | |
| uniform sampler2D texSlot; | |
| void main() | |
| { | |
| vec4 texColor = texture(texSlot, texCoord); | |
| FragColor = vec4(objectColor, 1.0) * texColor; | |
| } | |
| )"; | |
| const char* FragShaderNorm = R"( | |
| #version 330 | |
| out vec4 FragColor; | |
| in vec3 Normal; | |
| in vec3 Position; | |
| uniform vec3 lightPos; | |
| uniform vec3 lightColor; | |
| uniform vec3 objectColor; | |
| uniform vec3 lightAmbient; | |
| void main() | |
| { | |
| vec3 norm = normalize(Normal); | |
| vec3 lightDir = normalize(lightPos - Position); | |
| float diff = max(dot(norm, lightDir), 0.0); | |
| vec3 diffuse = diff * lightColor; | |
| vec3 result = (lightAmbient + diffuse) * objectColor; | |
| FragColor = vec4(result, 1.0); | |
| } | |
| )"; | |
| const char* FragShaderFlat = R"( | |
| #version 330 | |
| out vec4 FragColor; | |
| in vec3 Normal; | |
| in vec3 Position; | |
| uniform vec3 objectColor; | |
| void main() | |
| { | |
| FragColor = vec4(objectColor, 1.0); | |
| } | |
| )"; | |
| const char* VertShader2DFbo = R"( | |
| #version 330 core | |
| layout(location = 0) in vec2 aPosition; | |
| layout(location = 1) in vec2 aTexCoord; | |
| out vec2 texCoord; | |
| void main(void) | |
| { | |
| gl_Position = vec4(aPosition.x, aPosition.y, 0.0, 1.0); | |
| texCoord = aTexCoord; | |
| } | |
| )"; | |
| const char* FragShader2dFbo = R"( | |
| #version 330 | |
| out vec4 FragColor; | |
| in vec2 texCoord; | |
| uniform sampler2D texSlot; | |
| void main() | |
| { | |
| vec4 tc = texture(texSlot, texCoord); | |
| FragColor = tc; | |
| } | |
| )"; | |
| const char* VertShaderGeom = R"( | |
| #version 330 core | |
| layout (location = 0) in vec3 aPos; | |
| layout (location = 1) in vec3 aNormal; | |
| out vec3 Position; | |
| out vec3 Normal; | |
| uniform bool invertedNormals; | |
| uniform mat4 model; | |
| uniform mat4 view; | |
| uniform mat4 projection; | |
| void main() | |
| { | |
| vec4 viewPos = view * model * vec4(aPos, 1.0); | |
| Position = viewPos.xyz; | |
| mat3 normalMatrix = transpose(inverse(mat3(view * model))); | |
| Normal = normalMatrix * (invertedNormals ? -aNormal : aNormal); | |
| gl_Position = projection * viewPos; | |
| } | |
| )"; | |
| 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; | |
| in vec3 Position; | |
| in 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); | |
| } | |
| )"; | |
| const char* FragShaderSSAO = R"( | |
| #version 330 core | |
| layout (location = 0) out float AoData; | |
| in vec2 texCoord; | |
| uniform sampler2D RandTex; | |
| uniform sampler2D PositionTex; | |
| uniform sampler2D NormalTex; | |
| const int kernelSize = 64; | |
| uniform vec3 SampleKernel[kernelSize]; | |
| uniform float Radius = 20.0f; | |
| uniform float screenWidth = 800.0; | |
| uniform float screenHeight = 600.0; | |
| uniform mat4 projection; | |
| void main() | |
| { | |
| // 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 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)); | |
| biTang = normalize(biTang); | |
| vec3 tang = cross(biTang, n); | |
| mat3 toCamSpace = mat3(tang, biTang, n); | |
| float occlusionSum = 0.0; | |
| vec3 camPos = texture(PositionTex, texCoord).xyz; | |
| for( int i = 0; i < kernelSize; i++ ) { | |
| vec3 samplePos = camPos + Radius * (toCamSpace * SampleKernel[i]); | |
| // Project point | |
| vec4 p = projection * vec4(samplePos,1); | |
| p *= 1.0 / p.w; | |
| p.xyz = p.xyz * 0.5 + 0.5; | |
| // Access camera space z-coordinate at that point | |
| float surfaceZ = texture(PositionTex, p.xy).z; | |
| float zDist = surfaceZ - camPos.z; | |
| // Count points that ARE occluded | |
| if( zDist >= 0.0 && zDist <= Radius && surfaceZ > samplePos.z ) occlusionSum += 1.0; | |
| } | |
| float occ = occlusionSum / kernelSize; | |
| AoData = 1.0 - occ; | |
| } | |
| )"; | |
| const char* FragShaderSSAOBlur = R"( | |
| #version 330 core | |
| layout (location = 0) out float AoData; | |
| in vec2 texCoord; | |
| uniform sampler2D AoTex; | |
| 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; | |
| } | |
| } | |
| float ao = sum * (1.0 / 16.0); | |
| AoData = ao; | |
| } | |
| )"; | |
| const char* FragShaderSSAOLighting = R"( | |
| #version 330 core | |
| out vec4 FragColor; | |
| in vec2 texCoord; | |
| uniform vec3 lightPos; | |
| uniform vec3 lightColor; | |
| uniform vec3 lightAmbient; | |
| uniform bool ssaoActive; | |
| uniform sampler2D ColorTex; | |
| uniform sampler2D PositionTex; | |
| uniform sampler2D NormalTex; | |
| uniform sampler2D AoTex; | |
| vec3 ambAndDiffuse( vec3 pos, vec3 norm, vec3 diff, float ao ) { | |
| ao = pow(ao, 4); | |
| vec3 ambient = lightAmbient * diff * ao; | |
| vec3 s = normalize( lightPos - pos); | |
| float sDotN = max( dot(s,norm), 0.0 ); | |
| return ambient + lightColor * diff * sDotN; | |
| } | |
| void main() | |
| { | |
| vec3 pos = texture( PositionTex, texCoord ).xyz; | |
| vec3 norm = texture( NormalTex, texCoord ).xyz; | |
| vec4 DiffColorA = texture(ColorTex, texCoord); | |
| vec3 diffColor = DiffColorA.rgb; | |
| float aoVal = ssaoActive ? texture( 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 ); | |
| } | |
| )"; | |
| const char* VertShader3DLine = R"( | |
| #version 330 core | |
| layout(location = 0) in vec3 aPosition; | |
| layout(location = 1) in int aIndex; | |
| flat out int Index; | |
| uniform mat4 view; | |
| uniform mat4 projection; | |
| void main(void) | |
| { | |
| gl_Position = projection * view * vec4(aPosition, 1.0); | |
| Index = aIndex; | |
| } | |
| )"; | |
| const char* FragShader3DLine = R"( | |
| #version 330 | |
| out vec4 FragColor; | |
| 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); | |
| } | |
| )"; | |
| } // namespace MillSim | |