refactoring loading shaders
This commit is contained in:
parent
61fe295753
commit
b27321336b
@ -1,5 +1,6 @@
|
||||
#include "OGL.h"
|
||||
#include "Camera.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
@ -122,6 +123,11 @@ void OGL::init() {
|
||||
throw new std::runtime_error(errMsg);
|
||||
}
|
||||
|
||||
// even successful call to glewInit() may cause setting global error GL_INVALID_ENUM,
|
||||
// so we need clear it in order to use glGetError() later
|
||||
// https://www.opengl.org/wiki/OpenGL_Loading_Library#GLEW_.28OpenGL_Extension_Wrangler.29
|
||||
utils::clearGLError();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClearDepth(1.0);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
61
src/Shaders/Shader.cpp
Normal file
61
src/Shaders/Shader.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include "Shader.h"
|
||||
#include "../utils.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
Shader::Shader(GLenum type, const std::string& path): _path(path), _type(type), _shader(0) {
|
||||
}
|
||||
|
||||
void Shader::compile() {
|
||||
std::ifstream is(_path, std::ios::binary);
|
||||
if(is) {
|
||||
std::ostringstream ss;
|
||||
ss << is.rdbuf();
|
||||
std::string text = ss.str();
|
||||
|
||||
_shader = glCreateShader(_type);
|
||||
utils::throwIfGLError("error creating shader");
|
||||
|
||||
const GLchar* textBuffer = text.c_str();
|
||||
glShaderSource(_shader, 1, &textBuffer, nullptr);
|
||||
utils::throwIfGLError("error setting shader source");
|
||||
|
||||
glCompileShader(_shader);
|
||||
utils::throwIfGLError("error compiling shader");
|
||||
|
||||
GLint success = GL_TRUE;
|
||||
glGetShaderiv(_shader, GL_COMPILE_STATUS, &success);
|
||||
if(success == GL_FALSE) {
|
||||
logCompileError();
|
||||
throw std::runtime_error("error compiling shader: " + _path);
|
||||
}
|
||||
} else {
|
||||
throw std::runtime_error("error opening file: " + _path);
|
||||
}
|
||||
}
|
||||
|
||||
Shader::operator GLuint() const {
|
||||
return _shader;
|
||||
}
|
||||
|
||||
Shader::~Shader() {
|
||||
glDeleteShader(_shader);
|
||||
}
|
||||
|
||||
void Shader::logCompileError() {
|
||||
std::cout << "shader: " << _shader << std::endl;
|
||||
GLint logSize = 0;
|
||||
glGetShaderiv(_shader, GL_INFO_LOG_LENGTH, &logSize);
|
||||
std::cout << "log length: " << logSize << std::endl;
|
||||
|
||||
auto log = std::make_unique<GLchar[]>(logSize);
|
||||
memset(log.get(), 0, (size_t)logSize);
|
||||
|
||||
glGetShaderInfoLog(_shader, logSize, &logSize, log.get());
|
||||
std::cout << "log: " << log.get() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
23
src/Shaders/Shader.h
Normal file
23
src/Shaders/Shader.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef GLTEST_SHADER_H
|
||||
#define GLTEST_SHADER_H
|
||||
|
||||
#include <string>
|
||||
#include <GL/glew.h>
|
||||
|
||||
class Shader {
|
||||
private:
|
||||
std::string _path;
|
||||
GLenum _type;
|
||||
GLuint _shader;
|
||||
|
||||
public:
|
||||
Shader(GLenum type, const std::string& path);
|
||||
void compile();
|
||||
operator GLuint() const;
|
||||
~Shader();
|
||||
|
||||
private:
|
||||
void logCompileError();
|
||||
};
|
||||
|
||||
#endif //GLTEST_SHADER_H
|
||||
@ -1,52 +1,27 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include "ShaderProgram.h"
|
||||
#include "Shader.h"
|
||||
#include "../utils.h"
|
||||
|
||||
ShaderProgram::ShaderProgram(const char* vertexShaderPath, const char* fragmentShaderPath) {
|
||||
FILE* f = fopen(vertexShaderPath, "rb");
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
_vertexShaderText = new char[fsize + 1];
|
||||
fread(_vertexShaderText, fsize, 1, f);
|
||||
fclose(f);
|
||||
_vertexShaderText[fsize] = 0;
|
||||
|
||||
_vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(_vertexShader, 1, (const GLchar**)&_vertexShaderText, nullptr);
|
||||
glCompileShader(_vertexShader);
|
||||
|
||||
GLint success = GL_TRUE;
|
||||
glGetShaderiv(_vertexShader, GL_COMPILE_STATUS, &success);
|
||||
if(success == GL_FALSE) {
|
||||
std::cout << "error compilling vertex shader" << std::endl;
|
||||
logCompileError(_vertexShader);
|
||||
}
|
||||
|
||||
f = fopen(fragmentShaderPath, "rb");
|
||||
fseek(f, 0, SEEK_END);
|
||||
fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
_fragmentShaderText = new char[fsize + 1];
|
||||
fread(_fragmentShaderText, fsize, 1, f);
|
||||
fclose(f);
|
||||
_fragmentShaderText[fsize] = 0;
|
||||
|
||||
_fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(_fragmentShader, 1,(const GLchar**)&_fragmentShaderText, nullptr);
|
||||
glCompileShader(_fragmentShader);
|
||||
|
||||
glGetShaderiv(_fragmentShader, GL_COMPILE_STATUS, &success);
|
||||
if(success == GL_FALSE) {
|
||||
std::cout << "error compilling fragment shader" << std::endl;
|
||||
logCompileError(_fragmentShader);
|
||||
}
|
||||
ShaderProgram::ShaderProgram(const std::string& vertexShaderPath, const std::string& fragmentShaderPath) {
|
||||
Shader vShader(GL_VERTEX_SHADER, vertexShaderPath);
|
||||
Shader fShader(GL_FRAGMENT_SHADER, fragmentShaderPath);
|
||||
|
||||
vShader.compile();
|
||||
fShader.compile();
|
||||
|
||||
_program = glCreateProgram();
|
||||
glAttachShader(_program, _vertexShader);
|
||||
glAttachShader(_program, _fragmentShader);
|
||||
if(_program == 0) {
|
||||
throw std::runtime_error("error creating shader program");
|
||||
}
|
||||
|
||||
glAttachShader(_program, vShader);
|
||||
utils::throwIfGLError("error attaching vertex shader to program");
|
||||
glAttachShader(_program, fShader);
|
||||
utils::throwIfGLError("error attaching fragment shader to program");
|
||||
glLinkProgram(_program);
|
||||
utils::throwIfGLError("error linking program");
|
||||
}
|
||||
|
||||
void ShaderProgram::use() const {
|
||||
@ -54,26 +29,8 @@ void ShaderProgram::use() const {
|
||||
}
|
||||
|
||||
ShaderProgram::~ShaderProgram() {
|
||||
delete[] _vertexShaderText;
|
||||
delete[] _fragmentShaderText;
|
||||
|
||||
glDeleteShader(_vertexShader);
|
||||
glDeleteShader(_fragmentShader);
|
||||
}
|
||||
|
||||
ShaderProgram::operator GLuint() const {
|
||||
return _program;
|
||||
}
|
||||
|
||||
void ShaderProgram::logCompileError(GLuint shader) {
|
||||
std::cout << "shader: " << shader << std::endl;
|
||||
GLint logSize = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize);
|
||||
std::cout << "log length: " << logSize << std::endl;
|
||||
|
||||
GLchar* log = new GLchar[logSize];
|
||||
memset(log, 0, (size_t)logSize);
|
||||
|
||||
glGetShaderInfoLog(shader, logSize, &logSize, log);
|
||||
std::cout << "log: " << log << std::endl;
|
||||
}
|
||||
|
||||
@ -8,19 +8,12 @@
|
||||
class ShaderProgram {
|
||||
private:
|
||||
GLuint _program;
|
||||
GLuint _vertexShader;
|
||||
GLuint _fragmentShader;
|
||||
char* _vertexShaderText;
|
||||
char* _fragmentShaderText;
|
||||
|
||||
public:
|
||||
ShaderProgram(const char* vertexShaderPath, const char* fragmentShaderPath);
|
||||
ShaderProgram(const std::string& vertexShaderPath, const std::string& fragmentShaderPath);
|
||||
void use() const;
|
||||
operator GLuint() const;
|
||||
~ShaderProgram();
|
||||
|
||||
private:
|
||||
void logCompileError(GLuint shader);
|
||||
};
|
||||
|
||||
|
||||
|
||||
28
src/utils.cpp
Normal file
28
src/utils.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
#include "utils.h"
|
||||
#include <GL/glew.h>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace utils {
|
||||
void throwIfGLError(const std::string& msg) {
|
||||
std::string err;
|
||||
while(true) {
|
||||
GLenum error = glGetError();
|
||||
if(error != GL_NO_ERROR) {
|
||||
const char* errorStr = (const char*)gluErrorString(error);
|
||||
if(errorStr) {
|
||||
err += std::string(errorStr) + "\n";
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!err.empty()) {
|
||||
throw std::runtime_error(msg + ": " + err);
|
||||
}
|
||||
}
|
||||
|
||||
void clearGLError() {
|
||||
while(glGetError() != GL_NO_ERROR);
|
||||
}
|
||||
}
|
||||
11
src/utils.h
Normal file
11
src/utils.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef GLTEST_UTILS_H
|
||||
#define GLTEST_UTILS_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace utils {
|
||||
void throwIfGLError(const std::string& msg);
|
||||
void clearGLError();
|
||||
}
|
||||
|
||||
#endif //GLTEST_UTILS_H
|
||||
Loading…
Reference in New Issue
Block a user