GteGLSLProgramFactory.cpp
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #include <GTEnginePCH.h>
9 #include <LowLevel/GteLogger.h>
13 using namespace gte;
14 
20 unsigned int GLSLProgramFactory::defaultFlags = 0; // unused in GLSL for now
21 
23 {
30 }
31 
32 std::shared_ptr<VisualProgram> GLSLProgramFactory::CreateFromNamedSources(
33  std::string const&, std::string const& vsSource,
34  std::string const&, std::string const& psSource,
35  std::string const&, std::string const& gsSource)
36 {
37  if (vsSource == "" || psSource == "")
38  {
39  LogError("A program must have a vertex shader and a pixel shader.");
40  return nullptr;
41  }
42 
43  GLuint vsHandle = Compile(GL_VERTEX_SHADER, vsSource);
44  if (vsHandle == 0)
45  {
46  return nullptr;
47  }
48 
49  GLuint psHandle = Compile(GL_FRAGMENT_SHADER, psSource);
50  if (psHandle == 0)
51  {
52  return nullptr;
53  }
54 
55  GLuint gsHandle = 0;
56  if (gsSource != "")
57  {
58  gsHandle = Compile(GL_GEOMETRY_SHADER, gsSource);
59  if (gsHandle == 0)
60  {
61  return nullptr;
62  }
63  }
64 
65  GLuint programHandle = glCreateProgram();
66  if (programHandle == 0)
67  {
68  LogError("Program creation failed.");
69  return nullptr;
70  }
71 
72  glAttachShader(programHandle, vsHandle);
73  glAttachShader(programHandle, psHandle);
74  if (gsHandle > 0)
75  {
76  glAttachShader(programHandle, gsHandle);
77  }
78 
79  if (!Link(programHandle))
80  {
81  glDetachShader(programHandle, vsHandle);
82  glDeleteShader(vsHandle);
83  glDetachShader(programHandle, psHandle);
84  glDeleteShader(psHandle);
85  if (gsHandle)
86  {
87  glDetachShader(programHandle, gsHandle);
88  glDeleteShader(gsHandle);
89  }
90  glDeleteProgram(programHandle);
91  return nullptr;
92  }
93 
94  std::shared_ptr<GLSLVisualProgram> program =
95  std::make_shared<GLSLVisualProgram>(programHandle, vsHandle,
96  psHandle, gsHandle);
97 
98  GLSLReflection const& reflector = program->GetReflector();
99  program->SetVShader(std::make_shared<VertexShader>(reflector));
100  program->SetPShader(std::make_shared<PixelShader>(reflector));
101  if (gsHandle > 0)
102  {
103  program->SetGShader(std::make_shared<GeometryShader>(reflector));
104  }
105  return program;
106 }
107 
108 std::shared_ptr<ComputeProgram> GLSLProgramFactory::CreateFromNamedSource(
109  std::string const&, std::string const& csSource)
110 {
111  if (csSource == "")
112  {
113  LogError("A program must have a compute shader.");
114  return nullptr;
115  }
116 
117  GLuint csHandle = Compile(GL_COMPUTE_SHADER, csSource);
118  if (csHandle == 0)
119  {
120  return nullptr;
121  }
122 
123  GLuint programHandle = glCreateProgram();
124  if (programHandle == 0)
125  {
126  LogError("Program creation failed.");
127  return nullptr;
128  }
129 
130  glAttachShader(programHandle, csHandle);
131 
132  if (!Link(programHandle))
133  {
134  glDetachShader(programHandle, csHandle);
135  glDeleteShader(csHandle);
136  glDeleteProgram(programHandle);
137  return nullptr;
138  }
139 
140  std::shared_ptr<GLSLComputeProgram> program =
141  std::make_shared<GLSLComputeProgram>(programHandle, csHandle);
142 
143  GLSLReflection const& reflector = program->GetReflector();
144  program->SetCShader(std::make_shared<ComputeShader>(reflector));
145  return program;
146 }
147 
149  std::string const& source)
150 {
151  GLuint handle = glCreateShader(shaderType);
152  if (handle > 0)
153  {
154  // Prepend to the definitions
155  // 1. The version of the GLSL program; for example, "#version 400".
156  // 2. A define for the matrix-vector multiplication convention if
157  // it is selected as GTE_USE_MAT_VEC: "define GTE_USE_MAT_VEC 1"
158  // else "define GTE_USE_MAT_VEC 0".
159  // 3. "layout(std140, *_major) uniform;" for either row_major or column_major
160  // to select default for all uniform matrices and select std140 layout.
161  // 4. "layout(std430, *_major) buffer;" for either row_major or column_major
162  // to select default for all buffer matrices and select std430 layout.
163  // Append to the definitions the source-code string.
164  auto const& definitions = defines.Get();
165  std::vector<std::string> glslDefines;
166  glslDefines.reserve(definitions.size() + 5);
167  glslDefines.push_back(version + "\n");
168 #if defined(GTE_USE_MAT_VEC)
169  glslDefines.push_back("#define GTE_USE_MAT_VEC 1\n");
170 #else
171  glslDefines.push_back("#define GTE_USE_MAT_VEC 0\n");
172 #endif
173 #if defined(GTE_USE_ROW_MAJOR)
174  glslDefines.push_back("layout(std140, row_major) uniform;\n");
175  glslDefines.push_back("layout(std430, row_major) buffer;\n");
176 #else
177  glslDefines.push_back("layout(std140, column_major) uniform;\n");
178  glslDefines.push_back("layout(std430, column_major) buffer;\n");
179 #endif
180  for (auto d : definitions)
181  {
182  glslDefines.push_back("#define " + d.first + " " + d.second + "\n");
183  }
184  glslDefines.push_back(source);
185 
186  // Repackage the definitions for glShaderSource.
187  std::vector<GLchar const*> code;
188  code.reserve(glslDefines.size());
189  for (auto const& d : glslDefines)
190  {
191  code.push_back(d.c_str());
192  }
193 
194  glShaderSource(handle, static_cast<GLsizei>(code.size()), &code[0],
195  nullptr);
196 
197  glCompileShader(handle);
198  GLint status;
199  glGetShaderiv(handle, GL_COMPILE_STATUS, &status);
200  if (status == GL_FALSE)
201  {
202  GLint logLength;
203  glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &logLength);
204  if (logLength > 0)
205  {
206  std::vector<GLchar> log(logLength);
207  GLsizei numWritten;
208  glGetShaderInfoLog(handle, static_cast<GLsizei>(logLength), &numWritten, log.data());
209  LogError("Compile failed:\n" + std::string(log.data()));
210  }
211  else
212  {
213  LogError("Invalid info log length.");
214  }
215  glDeleteShader(handle);
216  handle = 0;
217  }
218  }
219  else
220  {
221  LogError("Cannot create shader.");
222  }
223  return handle;
224 }
225 
226 bool GLSLProgramFactory::Link(GLuint programHandle)
227 {
228  glLinkProgram(programHandle);
229  int status;
230  glGetProgramiv(programHandle, GL_LINK_STATUS, &status);
231  if (status == GL_FALSE)
232  {
233  int logLength;
234  glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH, &logLength);
235  if (logLength > 0)
236  {
237  std::vector<GLchar> log(logLength);
238  int numWritten;
239  glGetProgramInfoLog(programHandle, logLength, &numWritten, log.data());
240  LogError("Link failed:\n" + std::string(log.data()));
241  }
242  else
243  {
244  LogError("Invalid info log length.");
245  }
246  return false;
247  }
248  else
249  {
250  return true;
251  }
252 }
#define GL_LINK_STATUS
Definition: glcorearb.h:757
void APIENTRY glDeleteProgram(GLuint program)
Definition: GteOpenGL.cpp:1944
virtual std::shared_ptr< ComputeProgram > CreateFromNamedSource(std::string const &csName, std::string const &csSource) override
int GLint
Definition: glcorearb.h:85
unsigned int GLuint
Definition: glcorearb.h:89
#define GL_COMPUTE_SHADER
Definition: glcorearb.h:2258
static std::string defaultCSEntry
#define GL_FALSE
Definition: glcorearb.h:199
std::vector< std::pair< std::string, std::string > > const & Get() const
void APIENTRY glDeleteShader(GLuint shader)
Definition: GteOpenGL.cpp:1957
GLuint Compile(GLenum shaderType, std::string const &source)
#define GL_GEOMETRY_SHADER
Definition: glcorearb.h:1532
GLbitfield GLuint program
Definition: glcorearb.h:1926
static std::string defaultGSEntry
void APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint *params)
Definition: GteOpenGL.cpp:2064
GLuint APIENTRY glCreateProgram()
Definition: GteOpenGL.cpp:1912
void APIENTRY glDetachShader(GLuint program, GLuint shader)
Definition: GteOpenGL.cpp:1970
int GLsizei
Definition: glcorearb.h:86
void APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
Definition: GteOpenGL.cpp:2268
virtual std::shared_ptr< VisualProgram > CreateFromNamedSources(std::string const &vsName, std::string const &vsSource, std::string const &psName, std::string const &psSource, std::string const &gsName, std::string const &gsSource) override
void APIENTRY glLinkProgram(GLuint program)
Definition: GteOpenGL.cpp:2255
static std::string defaultVSEntry
ProgramDefines defines
unsigned int GLenum
Definition: glcorearb.h:83
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:798
bool Link(GLuint programHandle)
GLsizei const GLchar *const * string
Definition: glcorearb.h:809
#define LogError(message)
Definition: GteLogger.h:92
GLbitfield flags
Definition: glcorearb.h:1591
#define GL_VERTEX_SHADER
Definition: glcorearb.h:729
#define GL_FRAGMENT_SHADER
Definition: glcorearb.h:728
#define GL_INFO_LOG_LENGTH
Definition: glcorearb.h:759
void APIENTRY glCompileShader(GLuint shader)
Definition: GteOpenGL.cpp:1899
static unsigned int defaultFlags
static std::string defaultVersion
#define GL_COMPILE_STATUS
Definition: glcorearb.h:756
GLuint APIENTRY glCreateShader(GLenum type)
Definition: GteOpenGL.cpp:1928
static std::string defaultPSEntry
void APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog)
Definition: GteOpenGL.cpp:2077
void APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog)
Definition: GteOpenGL.cpp:2103
void APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint *params)
Definition: GteOpenGL.cpp:2090
void APIENTRY glAttachShader(GLuint program, GLuint shader)
Definition: GteOpenGL.cpp:1873


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:00