123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- #include <fstream>
- #include <cstring>
- #include "client/engine/shader/ShaderProgram.h"
- ShaderProgram::ShaderProgram()
- {
- }
- ShaderProgram::~ShaderProgram()
- {
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
- glDeleteProgram(program);
- }
- bool ShaderProgram::isValid() const
- {
- return valid;
- }
- GLuint ShaderProgram::getProgram() const
- {
- return program;
- }
- void ShaderProgram::compile(const GLchar* vertexPath, const GLchar* fragmentPath)
- {
- if(valid)
- {
- return;
- }
- GLchar* vertexData = readFile(vertexPath);
- if(vertexData == nullptr)
- {
- cout << "cannot read " << vertexPath << endl;
- return;
- }
- GLchar* fragmentData = readFile(fragmentPath);
- if(fragmentData == nullptr)
- {
- cout << "cannot read " << fragmentPath << endl;
- delete[] vertexData;
- return;
- }
-
- compile(vertexPath, vertexData, fragmentPath, fragmentData);
- delete[] vertexData;
- delete[] fragmentData;
- }
- GLchar* ShaderProgram::readFile(const GLchar* name)
- {
- ifstream in;
- in.open(name);
- if(!in.fail())
- {
- int size = 128;
- int index = 0;
- GLchar* content = new GLchar[size];
-
- while(true)
- {
- GLchar c = in.get();
- if(in.eof())
- {
- break;
- }
- if(index >= size - 1)
- {
- GLchar* newContent = new GLchar[size * 2];
- memcpy(newContent, content, size);
- size *= 2;
- delete[] content;
- content = newContent;
- }
- content[index] = c;
- index++;
- }
-
- content[index] = '\0';
- index++;
-
- in.close();
- return content;
- }
- return nullptr;
- }
- bool ShaderProgram::checkShaderErrors(const GLchar* name, GLuint shader)
- {
- bool returnValue = false;
-
- //cout << "compiling " << name << " shader ..." << endl;
- GLenum error = glGetError();
- if(error)
- {
- cout << "compiling of " << name << " failed" << endl;
- cout << "error: " << glGetError() << endl;
- returnValue = true;
- }
- //else
- //{
- // cout << "no error occured ..." << endl;
- //}
-
- GLint compiled[1];
- glGetShaderiv(shader, GL_COMPILE_STATUS, compiled);
- if(compiled[0])
- {
- //cout << name << " shader successfully compiled" << endl;
- }
- else
- {
- cout << "compiling of " << name << " failed:" << endl;
- GLchar buffer[512];
- GLsizei bufferSize = 512;
- GLsizei charsUsed = 0;
- glGetShaderInfoLog(shader, bufferSize, &charsUsed, buffer);
- // glGetProgramInfoLog should be null terminated ...
- buffer[bufferSize - 1] = '\0';
- cout << buffer << endl;
- returnValue = true;
- }
- return returnValue;
- }
- void ShaderProgram::compile(const GLchar* vertexPath, const GLchar* vertexData, const GLchar* fragmentPath, const GLchar* fragmentData)
- {
- vertexShader = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vertexShader, 1, &vertexData, nullptr);
- glCompileShader(vertexShader);
- if(checkShaderErrors(vertexPath, vertexShader))
- {
- return;
- }
-
- fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fragmentShader, 1, &fragmentData, nullptr);
- glCompileShader(fragmentShader);
- if(checkShaderErrors(fragmentPath, fragmentShader))
- {
- return;
- }
- program = glCreateProgram();
- glAttachShader(program, vertexShader);
- glAttachShader(program, fragmentShader);
- glLinkProgram(program);
-
- //cout << "linking shaders to program ..." << endl;
- GLenum error = glGetError();
- if(error)
- {
- cout << "linking of " << vertexPath << " and " << fragmentPath << " failed" << endl;
- cout << "error: " << glGetError() << endl;
- return;
- }
- //else
- //{
- // cout << "no error occured ..." << endl;
- //}
- GLint compiled[1];
- glGetProgramiv(program, GL_LINK_STATUS, compiled);
- if(compiled[0])
- {
- //cout << "shaders successfully linked" << endl;
- }
- else
- {
- cout << "linking of " << vertexPath << " and " << fragmentPath << " failed:" << endl;
- GLchar buffer[512];
- GLsizei bufferSize = 512;
- GLsizei charsUsed = 0;
- glGetProgramInfoLog(program, bufferSize, &charsUsed, buffer);
- // glGetProgramInfoLog should be null terminated ...
- buffer[bufferSize - 1] = '\0';
- cout << buffer << endl;
- return;
- }
- valid = true;
- }
|