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