blob: 150d067e4171636092a2b52cb134731cf833ce5f [file] [log] [blame]
Geoff Lang49be2ad2014-02-28 13:05:51 -05001//
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>
Geoff Lang712e3f42014-03-03 11:14:15 -050011#include <fstream>
12
13static std::string ReadFileToString(const std::string &source)
14{
Corentin Wallezf0ca9a02015-09-14 11:53:10 -070015 std::ifstream stream(source.c_str());
Geoff Lang712e3f42014-03-03 11:14:15 -050016 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);
Minmin Gong794e0002015-04-07 18:31:54 -070025 result.reserve(static_cast<unsigned int>(stream.tellg()));
Geoff Lang712e3f42014-03-03 11:14:15 -050026 stream.seekg(0, std::ios::beg);
27
28 result.assign((std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>());
29
30 return result;
31}
Geoff Lang49be2ad2014-02-28 13:05:51 -050032
33GLuint 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
Jamie Madill90c253a2015-12-15 15:14:08 -050049 if (infoLogLength > 0)
50 {
51 std::vector<GLchar> infoLog(infoLogLength);
52 glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
53 std::cerr << "shader compilation failed: " << &infoLog[0];
54 }
55 else
56 {
57 std::cerr << "shader compilation failed. <Empty log message>";
58 }
Geoff Lang49be2ad2014-02-28 13:05:51 -050059
60 glDeleteShader(shader);
61 shader = 0;
62 }
63
64 return shader;
65}
66
Geoff Lang712e3f42014-03-03 11:14:15 -050067GLuint CompileShaderFromFile(GLenum type, const std::string &sourcePath)
68{
69 std::string source = ReadFileToString(sourcePath);
70 if (source.empty())
71 {
72 return 0;
73 }
74
75 return CompileShader(type, source);
76}
77
Jamie Madillca03b352015-09-02 12:38:13 -040078GLuint CompileProgramWithTransformFeedback(
79 const std::string &vsSource,
80 const std::string &fsSource,
81 const std::vector<std::string> &transformFeedbackVaryings,
82 GLenum bufferMode)
Geoff Lang49be2ad2014-02-28 13:05:51 -050083{
84 GLuint program = glCreateProgram();
85
86 GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
87 GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
88
89 if (vs == 0 || fs == 0)
90 {
91 glDeleteShader(fs);
92 glDeleteShader(vs);
93 glDeleteProgram(program);
94 return 0;
95 }
96
97 glAttachShader(program, vs);
98 glDeleteShader(vs);
99
100 glAttachShader(program, fs);
101 glDeleteShader(fs);
102
Jamie Madillca03b352015-09-02 12:38:13 -0400103 if (transformFeedbackVaryings.size() > 0)
104 {
105 std::vector<const char *> constCharTFVaryings;
106
107 for (const std::string &transformFeedbackVarying : transformFeedbackVaryings)
108 {
109 constCharTFVaryings.push_back(transformFeedbackVarying.c_str());
110 }
111
112 glTransformFeedbackVaryings(program, static_cast<GLsizei>(transformFeedbackVaryings.size()),
113 &constCharTFVaryings[0], bufferMode);
114 }
115
Geoff Lang49be2ad2014-02-28 13:05:51 -0500116 glLinkProgram(program);
117
118 GLint linkStatus;
119 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
120
121 if (linkStatus == 0)
122 {
123 GLint infoLogLength;
124 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
125
126 std::vector<GLchar> infoLog(infoLogLength);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700127 glGetProgramInfoLog(program, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
Geoff Lang49be2ad2014-02-28 13:05:51 -0500128
Jamie Madillb4fd0c92014-10-01 17:40:24 -0400129 std::cerr << "program link failed: " << &infoLog[0];
Geoff Lang49be2ad2014-02-28 13:05:51 -0500130
131 glDeleteProgram(program);
132 return 0;
133 }
134
135 return program;
136}
Geoff Lang712e3f42014-03-03 11:14:15 -0500137
Jamie Madillca03b352015-09-02 12:38:13 -0400138GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource)
139{
140 std::vector<std::string> emptyVector;
141 return CompileProgramWithTransformFeedback(vsSource, fsSource, emptyVector, GL_NONE);
142}
143
Geoff Lang712e3f42014-03-03 11:14:15 -0500144GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath)
145{
146 std::string vsSource = ReadFileToString(vsPath);
147 std::string fsSource = ReadFileToString(fsPath);
148 if (vsSource.empty() || fsSource.empty())
149 {
150 return 0;
151 }
152
153 return CompileProgram(vsSource, fsSource);
154}