1 ////////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2012-2016 by Bertram (Valyria Tear)
3 //                         All Rights Reserved
4 //
5 // This code is licensed under the GNU GPL version 2. It is free software
6 // and you may modify it and/or redistribute it under the terms of this license.
7 // See http://www.gnu.org/copyleft/gpl.html for details.
8 ////////////////////////////////////////////////////////////////////////////////
9 
10 /** ****************************************************************************
11 *** \file    gl_shader.cpp
12 *** \author  Authenticate, James Lammlein
13 *** \brief   Source file for shaders used in OpenGL.
14 *** ***************************************************************************/
15 
16 #include "gl_shader.h"
17 
18 #include "utils/utils_common.h"
19 #include "utils/exception.h"
20 #include "utils/utils_strings.h"
21 
22 #include <cassert>
23 #include <cstring>
24 
25 namespace vt_video
26 {
27 namespace gl
28 {
29 
Shader(GLenum type,const std::string & data)30 Shader::Shader(GLenum type, const std::string &data) :
31     _shader(0)
32 {
33     bool errors = false;
34 
35     // Create the shader.
36     if (!errors) {
37         _shader = glCreateShader(type);
38 
39         GLenum error = glGetError();
40         if (error != GL_NO_ERROR) {
41             errors = true;
42             PRINT_ERROR << "Failed to create the shader." << std::endl;
43             assert(error == GL_NO_ERROR);
44         }
45     }
46 
47     // Send the source code to the shader.
48     if (!errors) {
49         const GLint length[] = { static_cast<GLint>(data.length()) };
50         const GLchar* strings[] = { data.c_str() };
51 
52         glShaderSource(_shader, 1, strings, length);
53 
54         GLenum error = glGetError();
55         if (error != GL_NO_ERROR) {
56             errors = true;
57             PRINT_ERROR << "Failed to set the shader's source. Shader ID: " <<
58                            vt_utils::NumberToString(_shader) <<
59                            std::endl;
60             assert(error == GL_NO_ERROR);
61         }
62     }
63 
64     // Compile the shader.
65     if (!errors) {
66         glCompileShader(_shader);
67 
68         GLenum error = glGetError();
69         if (error != GL_NO_ERROR) {
70             errors = true;
71             PRINT_ERROR << "Failed to compile the shader. Shader ID: " <<
72                            vt_utils::NumberToString(_shader) <<
73                            std::endl;
74             assert(error == GL_NO_ERROR);
75         }
76     }
77 
78     // Check for shader syntax errors.
79     if (errors)
80         return;
81 
82     GLint is_compiled = -1;
83     glGetShaderiv(_shader, GL_COMPILE_STATUS, &is_compiled);
84 
85     // Return if the shader compilation went well
86     if (is_compiled != 0)
87         return;
88 
89     // Retrieve the compiler output.
90     GLint length = 0;
91     glGetShaderiv(_shader, GL_INFO_LOG_LENGTH, &length);
92 
93     // Allocate space for the log.
94     char* log = new char[length];
95     memset(log, 0, length);
96     glGetShaderInfoLog(_shader, length, &length, log);
97 
98     PRINT_ERROR << "Failed to compile the shader. Shader ID: " <<
99                     vt_utils::NumberToString(_shader) << " Compiler Output: " <<
100                     log << std::endl;
101 
102     // Clean up the log.
103     delete [] log;
104     log = nullptr;
105 
106     assert(is_compiled != 0);
107 }
108 
~Shader()109 Shader::~Shader()
110 {
111     if (_shader != 0) {
112         glDeleteShader(_shader);
113         _shader = 0;
114     }
115 }
116 
Shader(const Shader &)117 Shader::Shader(const Shader&)
118 {
119     throw vt_utils::Exception("Not Implemented!", __FILE__, __LINE__, __FUNCTION__);
120 }
121 
operator =(const Shader &)122 Shader& Shader::operator=(const Shader&)
123 {
124     throw vt_utils::Exception("Not Implemented!", __FILE__, __LINE__, __FUNCTION__);
125     return *this;
126 }
127 
128 } // namespace gl
129 
130 } // namespace vt_video
131