Shader.cc 5.36 KB
Newer Older
1
2
3
4
5
/***********************************************************************
 * Copyright 2011-2012 Computer Graphics Group RWTH Aachen University. *
 * All rights reserved.                                                *
 * Distributed under the terms of the MIT License (see LICENSE.TXT).   *
 **********************************************************************/
Robert Menzel's avatar
Robert Menzel committed
6

Robert Menzel's avatar
Robert Menzel committed
7
8
#include <ACGL/OpenGL/Objects/Shader.hh>
#include <ACGL/OpenGL/Tools.hh>
9
#include <ACGL/Utils/StringHelpers.hh>
Robert Menzel's avatar
Robert Menzel committed
10
11
12

#include <iostream>
#include <fstream>
13
#include <algorithm>
Robert Menzel's avatar
Robert Menzel committed
14
15

using namespace ACGL::Utils;
Robert Menzel's avatar
Robert Menzel committed
16
using namespace ACGL::OpenGL;
Robert Menzel's avatar
Robert Menzel committed
17

18
/*
19
bool Shader::setFromFileNoImportParsing(const std::string& _filename)
Robert Menzel's avatar
Robert Menzel committed
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{
    std::string line = "";
    std::string fileContent = "";
    
    std::ifstream fileStream(_filename.c_str(), std::ifstream::in);
    
    if(fileStream.is_open())
    {
        while (fileStream.good())
        {
            std::getline(fileStream,line);
            fileContent += line + "\n";
        }
        fileStream.close();
    }
    else
    {
        error() << "Failed to open file: " << _filename << std::endl;
        return false;
    }
    
41
42
43
44
45
46
47
48
49
50
51
52
53
    bool compileErrors = true;
    if ( setSource(fileContent, false) ) { // don't check for errors, we will do that on our own:
        std::string compileLog;
        getCompileLog( compileLog, compileErrors );
        if (compileLog.size() > 0) {
            if (compileErrors) {
                error() << "\nIn file: " << _filename << ": \n" << compileLog << "\n" << std::endl;
            } else {
                warning() << "\nIn file: " << _filename << ": \n" << compileLog << "\n" << std::endl;
            }
        }
    }
    return !compileErrors; // return true iff there were no errors
54
}*/
Robert Menzel's avatar
Robert Menzel committed
55

56
bool Shader::setFromFile(SharedShaderParser const& _sp)
57
{
Philip Trettner's avatar
Philip Trettner committed
58
59
    assert(_sp->getSources().size() > 0); // did you forget to call _sp->parse(...)?

60
    bool compileErrors = true;
61
    if ( setSources( _sp->getSources(), false) ) { // don't check for errors, we will do that on our own:
62
63
64
65
        std::string compileLog;
        getCompileLog( compileLog, compileErrors );
        if (compileLog.size() > 0) {
            if (compileErrors) {
66
                error() << "\nIn files: \n" << _sp->getFileNamesPrintable() << compileLog << "\n" << std::endl;
67
            } else {
68
                warning() << "\nIn files: \n" << _sp->getFileNamesPrintable() << compileLog << "\n" << std::endl;
69
70
71
            }
        }
    }
72
73
74
75
76

#ifdef ACGL_OPENGL_DEBUGGER_SUPPORT
    glObjectLabel( GL_SHADER, mObjectName, -1, _sp->getSources()[0].c_str() );
#endif

77
78
79
    return !compileErrors; // return true iff there were no errors
}

80
bool Shader::setSource(const std::string& _source, bool _checkForCompileErrors)
Robert Menzel's avatar
Robert Menzel committed
81
{
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
    const char *pProgramString = _source.c_str();
    glShaderSource(mObjectName, 1, &pProgramString, NULL); // can't create OpenGL errors
    if (!compile()) {
        return false;
    }
    // the compile call should work even if there are compile errors itself:
    bool compileErrors = false;
    if (_checkForCompileErrors) {
        std::string compileLog;
        getCompileLog( compileLog, compileErrors );
        if (compileLog.size() > 0) {
            if (compileErrors) {
                error() << compileLog << std::endl;
            } else {
                warning() << compileLog << std::endl;
            }
        }
    }
    return !compileErrors; // return true iff there were NO errors
Robert Menzel's avatar
Robert Menzel committed
101
102
}

103
104
bool Shader::setSources(const std::vector<std::string> &_sources, bool _checkForCompileErrors )
{
105
    unsigned int numberOfStrings = (unsigned int) _sources.size();
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
    const char **pProgramStrings = new const char*[ numberOfStrings ];

    for (unsigned int i = 0; i < numberOfStrings; ++i) {
        pProgramStrings[i] = _sources[i].c_str();
    }

    glShaderSource(mObjectName, numberOfStrings, pProgramStrings, NULL); // can't create OpenGL errors
    delete[] pProgramStrings;

    if (!compile()) {
        return false;
    }
    // the compile call should work even if there are compile errors itself:
    bool compileErrors = false;
    if (_checkForCompileErrors) {
        std::string compileLog;
        getCompileLog( compileLog, compileErrors );
        if (compileLog.size() > 0) {
            if (compileErrors) {
                error() << compileLog << std::endl;
            } else {
                warning() << compileLog << std::endl;
            }
        }
    }
    return !compileErrors; // return true iff there were NO errors
}

bool Shader::compile() const
Robert Menzel's avatar
Robert Menzel committed
135
{
136
    glCompileShader(mObjectName);
137
138
    return true;
}
Robert Menzel's avatar
Robert Menzel committed
139

140
141
void Shader::getCompileLog( std::string &_log, bool &_wasErrorLog ) const
{
Robert Menzel's avatar
Robert Menzel committed
142
143
    // check for shader compile errors:
    GLint shaderError;
144
    glGetShaderiv(mObjectName, GL_COMPILE_STATUS, &shaderError);
Robert Menzel's avatar
Robert Menzel committed
145
146
147
    if(shaderError != GL_TRUE)
    {
        // yes, errors
148
149
150
        _wasErrorLog = true;
    } else {
        _wasErrorLog = false;
Robert Menzel's avatar
Robert Menzel committed
151
152
    }

153
    // the log could be warnings:
Robert Menzel's avatar
Robert Menzel committed
154
    GLsizei length = 0;
155
    glGetShaderiv(mObjectName, GL_INFO_LOG_LENGTH, &length);
156
    if(length > 1) // null terminated, so 1 could also be empty
Robert Menzel's avatar
Robert Menzel committed
157
158
    {
        // a compile log can get produced even if there were no errors, but warnings!
159
        GLchar* pInfo = new char[length];
160
        glGetShaderInfoLog(mObjectName,  length, &length, pInfo);
161
162
        //error() << "Compile log: " << std::string(pInfo) << std::endl;
        _log = std::string( pInfo );
Robert Menzel's avatar
Robert Menzel committed
163
        delete[] pInfo;
164
165
    } else {
        _log = "";
Robert Menzel's avatar
Robert Menzel committed
166
167
    }
}