Fraxinus  2023.01.05-dev+develop.0da12
An IGT application
cxOpenGLShaders.cpp
Go to the documentation of this file.
1 #include "cxOpenGLShaders.h"
2 
3 #include <QString>
4 
5 namespace cx
6 {
7 
8 const std::string getVSReplacement_dec(std::string vtk_dec, int numberOfUploadedTextures)
9 {
10  QString temp;
11 
12  if(numberOfUploadedTextures != 0)
13  {
14  temp = QString(
15  "%1"
16  "\n\n"
17  "//CX: adding input and output variables for texture coordinates\n"
18  "const int number_of_textures = %4;\n"
19  "in vec3 %2[number_of_textures];\n"
20  "out vec3 %3[number_of_textures];\n"
21  )
22  .arg(vtk_dec.c_str())
23  .arg(VS_In_Vec3_TextureCoordinate.c_str())
24  .arg(VS_Out_Vec3_TextureCoordinate.c_str())
25  .arg(numberOfUploadedTextures);
26  }
27  else
28  {
29  //If there are no textures present we do not need a vertexshader
30  temp = vtk_dec.c_str();
31  }
32 
33  const std::string retval = temp.toStdString();
34  return retval;
35 }
36 
37 
38 const std::string getVSReplacement_impl(std::string vtk_impl, int numberOfUploadedTextures)
39 {
40  QString temp;
41 
42  if(numberOfUploadedTextures != 0)
43  {
44  temp = QString(
45  "%1"
46  "\n"
47  "%2 = %3;\n"
48  )
49  .arg(vtk_impl.c_str())
50  .arg(VS_Out_Vec3_TextureCoordinate.c_str())
51  .arg(VS_In_Vec3_TextureCoordinate.c_str());
52  }
53  else
54  {
55  //If there are no textures present we do not need a vertexshader
56  temp = vtk_impl.c_str();
57  }
58 
59  const std::string retval = temp.toStdString();
60  return retval;
61 }
62 
84 const std::string getSampleLutImplementation(int numberOfUploadedTextures)
85 {
86  std::string lut_sampler_code;
87 
88  for(int i=0; i<numberOfUploadedTextures; ++i)
89  {
90  std::string j = QString::number(i).toStdString();
91  std::string code = " if(texture_index == "+j+")\n"
92  " rgba_lut_values["+j+"] = texture("+FS_Uniform_1DTexture_LUT+"["+j+"], red_value);\n";
93  lut_sampler_code += code;
94  }
95 
96  return lut_sampler_code;
97 }
98 
99 const std::string getFS(int numberOfUploadedTextures)
100 {
101  std::string fs_shader_text;
102 
103  if(numberOfUploadedTextures != 0)
104  {
105  std::string number_of_textures = QString::number(numberOfUploadedTextures).toStdString();
106  fs_shader_text =
107  "//VTK::System::Dec\n"
108  "//VTK::Output::Dec\n\n"
109  ""
110  "in vec3 normalVCVSOutput;"
111  "in vec4 vertexVCVSOutput;"
112  ""
113  "//CX: adding custom fragment shader\n"
114  "const int number_of_textures = "+number_of_textures+";\n"
115  "in vec3 "+VS_Out_Vec3_TextureCoordinate+"[number_of_textures];\n"
116  "uniform sampler3D "+FS_Uniform_3DTexture_Volume+"[number_of_textures];\n"
117  "uniform sampler1D "+FS_Uniform_1DTexture_LUT+"[number_of_textures];\n"
118  "uniform float "+FS_Uniform_Window+"[number_of_textures];\n"
119  "uniform float "+FS_Uniform_Level+"[number_of_textures];\n"
120  "uniform float "+FS_Uniform_LLR+"[number_of_textures];\n"
121  "uniform float "+FS_Uniform_Alpha+"[number_of_textures];\n"
122  "out vec4 "+FS_Out_Vec4_Color+";\n"
123  ""
124  "const vec3 bounds_lo = vec3(0.0,0.0,0.0);"
125  "const vec3 bounds_hi = vec3(1.0,1.0,1.0);"
126  ""
127  "bool textureCoordinateIsOutsideTexture(in int texture_index)\n"
128  "{\n"
129  " vec3 texture_coordinate = "+VS_Out_Vec3_TextureCoordinate+"[texture_index];\n"
130  " return any(lessThan(texture_coordinate, bounds_lo)) || any(greaterThan(texture_coordinate, bounds_hi));\n"
131  "}\n"
132  ""
133  "float windowLevel(in float x, in float window_, in float level_)\n"
134  "{\n"
135  " return (x-level_)/window_ + 0.5;\n"
136  "}\n"
137  ""
138  "vec4 sampleLut(in int texture_index, in float red_value)\n"
139  "{\n"
140  " vec4 rgba_lut_values[number_of_textures];\n"
141  +getSampleLutImplementation(numberOfUploadedTextures)+
142  " return rgba_lut_values[texture_index];\n"
143  "}\n"
144  ""
145  "vec4 mergeTexture_GL_RED(in vec4 base_color,in int texture_index)\n"
146  "{\n"
147  " //Ignore drawing outside texture\n"
148  " bool outside = textureCoordinateIsOutsideTexture(texture_index);\n"
149  " if(outside)\n"
150  " {\n"
151  " return base_color;\n"
152  " }\n"
153  ""
154  " //Sampling from GL_RED 3D texture \n"
155  " vec4 rgba_texture_value = texture("+FS_Uniform_3DTexture_Volume+"[texture_index], "+VS_Out_Vec3_TextureCoordinate+"[texture_index]);\n"
156  " float red_value = rgba_texture_value.r;\n"
157  ""
158  " float llr = "+FS_Uniform_LLR+"[texture_index];\n"
159  " if(red_value < llr)\n"
160  " {\n"
161  " return base_color;\n"
162  " }\n"
163  ""
164  " red_value = windowLevel(red_value, "+FS_Uniform_Window+"[texture_index], "+FS_Uniform_Level+"[texture_index]);\n"
165  " red_value = clamp(red_value, 0.0, 1.0);\n"
166  ""
167  " vec4 color_rbga = sampleLut(texture_index, red_value);\n"
168  " color_rbga.a = "+FS_Uniform_Alpha+"[texture_index];\n"
169  " color_rbga = mix(base_color, color_rbga, "+FS_Uniform_Alpha+"[texture_index]);\n"
170  ""
171  " return color_rbga;\n"
172  "}\n"
173  ""
174  "vec4 mergeTexture(in vec4 base_color, in int texture_index)\n"
175  "{\n"
176  " return mergeTexture_GL_RED(base_color, texture_index);\n"
177  "}\n"
178  ""
179  "void main ()\n"
180  "{\n"
181  ""
182  " vec4 color = vec4(0.0, 0.0, 0.0, 1.0);\n"
183  " for(int i=0; i<number_of_textures; i++)\n"
184  " {\n"
185  " color = mergeTexture(color, i);\n"
186  " }\n"
187  ""
188  " // if input variable (in VS or FS) does not affect any used results it will be optimized out by some glsl compilers"
189  " // hack to make sure normalMC (used to calculate normalVCVSOutput in VS) is not optimized out\n"
190  " color += vec4(normalVCVSOutput, 0.0);\n "
191  " color -= vec4(normalVCVSOutput, 0.0);\n"
192  ""
193  " "+FS_Out_Vec4_Color+" = color;\n"
194  "}"
195  ;
196  }
197  else
198  {
199  //If there are no textures present we do not need a fragmentshader
200  fs_shader_text = "";
201  }
202 
203  return fs_shader_text;
204 }
205 
206 } //namespace cx
207 
const std::string getVSReplacement_impl(std::string vtk_impl, int numberOfUploadedTextures)
const std::string getFS(int numberOfUploadedTextures)
const std::string getSampleLutImplementation(int numberOfUploadedTextures)
getSampleLutImplementation generates code which will sample the LUT WITHOUT using a for loop...
const std::string getVSReplacement_dec(std::string vtk_dec, int numberOfUploadedTextures)
Namespace for all CustusX production code.