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 13static 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 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 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 61GLuint 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 72GLuint 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 115GLuint 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