Home | History | Annotate | Download | only in util
      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 
     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 
     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 
     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 
     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 
    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