• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #include "shader_utils.h"
8 
9 #include <vector>
10 #include <iostream>
11 #include <fstream>
12 
ReadFileToString(const std::string & source)13 static std::string ReadFileToString(const std::string &source)
14 {
15     std::ifstream stream(source);
16     if (!stream)
17     {
18         std::cerr << "Failed to load shader file: " << source;
19         return "";
20     }
21 
22     std::string result;
23 
24     stream.seekg(0, std::ios::end);
25     result.reserve(stream.tellg());
26     stream.seekg(0, std::ios::beg);
27 
28     result.assign((std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>());
29 
30     return result;
31 }
32 
CompileShader(GLenum type,const std::string & source)33 GLuint CompileShader(GLenum type, const std::string &source)
34 {
35     GLuint shader = glCreateShader(type);
36 
37     const char *sourceArray[1] = { source.c_str() };
38     glShaderSource(shader, 1, sourceArray, NULL);
39     glCompileShader(shader);
40 
41     GLint compileResult;
42     glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
43 
44     if (compileResult == 0)
45     {
46         GLint infoLogLength;
47         glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
48 
49         std::vector<GLchar> infoLog(infoLogLength);
50         glGetShaderInfoLog(shader, infoLog.size(), NULL, infoLog.data());
51 
52         std::cerr << "shader compilation failed: " << infoLog.data();
53 
54         glDeleteShader(shader);
55         shader = 0;
56     }
57 
58     return shader;
59 }
60 
CompileShaderFromFile(GLenum type,const std::string & sourcePath)61 GLuint CompileShaderFromFile(GLenum type, const std::string &sourcePath)
62 {
63     std::string source = ReadFileToString(sourcePath);
64     if (source.empty())
65     {
66         return 0;
67     }
68 
69     return CompileShader(type, source);
70 }
71 
CompileProgram(const std::string & vsSource,const std::string & fsSource)72 GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource)
73 {
74     GLuint program = glCreateProgram();
75 
76     GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
77     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
78 
79     if (vs == 0 || fs == 0)
80     {
81         glDeleteShader(fs);
82         glDeleteShader(vs);
83         glDeleteProgram(program);
84         return 0;
85     }
86 
87     glAttachShader(program, vs);
88     glDeleteShader(vs);
89 
90     glAttachShader(program, fs);
91     glDeleteShader(fs);
92 
93     glLinkProgram(program);
94 
95     GLint linkStatus;
96     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
97 
98     if (linkStatus == 0)
99     {
100         GLint infoLogLength;
101         glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
102 
103         std::vector<GLchar> infoLog(infoLogLength);
104         glGetProgramInfoLog(program, infoLog.size(), NULL, infoLog.data());
105 
106         std::cerr << "program link failed: " << infoLog.data();
107 
108         glDeleteProgram(program);
109         return 0;
110     }
111 
112     return program;
113 }
114 
CompileProgramFromFiles(const std::string & vsPath,const std::string & fsPath)115 GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath)
116 {
117     std::string vsSource = ReadFileToString(vsPath);
118     std::string fsSource = ReadFileToString(fsPath);
119     if (vsSource.empty() || fsSource.empty())
120     {
121         return 0;
122     }
123 
124     return CompileProgram(vsSource, fsSource);
125 }
126