-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathShaderProgram.cpp
138 lines (115 loc) · 3.69 KB
/
ShaderProgram.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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
135
136
#include "ShaderProgram.hpp"
#include <iostream>
#include <fstream>
#include "Texture.hpp"
ShaderProgram::ShaderProgram( const char * vertexFileName, const char * fragmentFileName )
{
load( vertexFileName, fragmentFileName );
}
ShaderProgram::~ShaderProgram()
{
//dtor
}
void ShaderProgram::load( const char * vertexFileName, const char * fragmentFileName )
{
std::string vertexCode = readFile ( vertexFileName );
GLuint vertexShaderId = compileShader( GL_VERTEX_SHADER, vertexCode );
std::string fragmentCode = readFile ( fragmentFileName );
GLuint fragmentShaderId = compileShader( GL_FRAGMENT_SHADER, fragmentCode );
if ( vertexShaderId && fragmentShaderId ) { // all is ok
id = linkProgram( vertexShaderId, fragmentShaderId ); // remember program by id
glDeleteShader( vertexShaderId ); // free shader resources
glDeleteShader( fragmentShaderId ); // free shader resources
} else {
id = 0; // no program on error
}
}
GLuint ShaderProgram::getUniformLocation( const char * aName )
{
return glGetUniformLocation( id, aName );
}
GLuint ShaderProgram::getAttribLocation( const char * aName )
{
return glGetAttribLocation( id, aName );
}
/**
* make this shaderprogram the active one
*/
void ShaderProgram::use()
{
glUseProgram( id ); // make this the active shaderprogram
}
void ShaderProgram::draw( unsigned int count )
{
glDrawElements( GL_TRIANGLES, count, GL_UNSIGNED_INT, (GLvoid*)0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
}
// private members
// read the shader code into string
std::string ShaderProgram::readFile( const char * fileName )
{
// Read the Vertex Shader code from the file
std::string code;
std::ifstream file ( fileName, std::ios::in);
if(file.is_open()){
std::cout << "Reading shader " << fileName << std::endl;
std::string line = "";
while(getline(file, line)) { // read per line
code += "\n" + line; // add to string
}
file.close(); // close on finish
} else {
std::cout << "Error reading shader " << fileName << std::endl;
code = "";
}
return code;
}
// compile the code, and detect errors.
GLuint ShaderProgram::compileShader( GLenum type, std::string & shaderCode)
{
std::cout << "Compiling shader " << std::endl;
// Compile Vertex Shader
const char * codePointer = shaderCode.c_str();
GLuint shaderId = glCreateShader( type ); // get shader id
glShaderSource( shaderId, 1, &codePointer , NULL );
glCompileShader( shaderId );
// Check compiler result
GLint result = GL_FALSE;
glGetShaderiv( shaderId, GL_COMPILE_STATUS, &result);
if ( result ) {
std::cout << "Shader compiled ok" << std::endl;
return shaderId;
} else { // get error message
int count;
glGetShaderiv( shaderId, GL_INFO_LOG_LENGTH, &count);
//std::vector<char> errorMessage( count+1 );
char errorMessage[ count+1 ];
glGetShaderInfoLog( shaderId, count, NULL, errorMessage);
std::cout << errorMessage << std::endl;
return 0; // no shader id
}
}
// link the two shaders and return the program id
GLuint ShaderProgram::linkProgram ( GLuint vertexShaderId, GLuint fragmentShaderId )
{
// Link the program
GLuint programId = glCreateProgram();
glAttachShader( programId, vertexShaderId);
glAttachShader( programId, fragmentShaderId);
glLinkProgram( programId);
// Check the program
GLint result = GL_FALSE;
glGetProgramiv( programId, GL_LINK_STATUS, &result );
if ( result ) {
std::cout << "program linked ok" << std::endl;
return programId;
} else { // error, show message
int count;
glGetProgramiv( programId, GL_INFO_LOG_LENGTH, &count );
//std::vector<char> ProgramErrorMessage( max(count, int(1)) );
char errorMessage[ count+1 ];
glGetProgramInfoLog( programId, count, NULL, errorMessage );
std::cout << errorMessage << std::endl;
return 0;
}
}