mirror of
https://github.com/JoeyDeVries/LearnOpenGL.git
synced 2026-01-30 20:13:22 +08:00
Initial commit, all code samples with working CMake script for VS/Windows.
This commit is contained in:
121
includes/learnopengl/shader.h
Normal file
121
includes/learnopengl/shader.h
Normal file
@@ -0,0 +1,121 @@
|
||||
#ifndef SHADER_H
|
||||
#define SHADER_H
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
GLuint Program;
|
||||
// Constructor generates the shader on the fly
|
||||
Shader(const GLchar* vertexPath, const GLchar* fragmentPath, const GLchar* geometryPath = nullptr)
|
||||
{
|
||||
// 1. Retrieve the vertex/fragment source code from filePath
|
||||
std::string vertexCode;
|
||||
std::string fragmentCode;
|
||||
std::string geometryCode;
|
||||
try
|
||||
{
|
||||
// Open files
|
||||
std::ifstream vShaderFile(vertexPath);
|
||||
std::ifstream fShaderFile(fragmentPath);
|
||||
std::stringstream vShaderStream, fShaderStream;
|
||||
// Read file's buffer contents into streams
|
||||
vShaderStream << vShaderFile.rdbuf();
|
||||
fShaderStream << fShaderFile.rdbuf();
|
||||
// close file handlers
|
||||
vShaderFile.close();
|
||||
fShaderFile.close();
|
||||
// Convert stream into string
|
||||
vertexCode = vShaderStream.str();
|
||||
fragmentCode = fShaderStream.str();
|
||||
// If geometry shader path is present, also load a geometry shader
|
||||
if(geometryPath != nullptr)
|
||||
{
|
||||
std::ifstream gShaderFile(geometryPath);
|
||||
std::stringstream gShaderStream;
|
||||
gShaderStream << gShaderFile.rdbuf();
|
||||
gShaderFile.close();
|
||||
geometryCode = gShaderStream.str();
|
||||
}
|
||||
}
|
||||
catch (std::exception e)
|
||||
{
|
||||
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
|
||||
}
|
||||
const GLchar* vShaderCode = vertexCode.c_str();
|
||||
const GLchar * fShaderCode = fragmentCode.c_str();
|
||||
// 2. Compile shaders
|
||||
GLuint vertex, fragment;
|
||||
GLint success;
|
||||
GLchar infoLog[512];
|
||||
// Vertex Shader
|
||||
vertex = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertex, 1, &vShaderCode, NULL);
|
||||
glCompileShader(vertex);
|
||||
checkCompileErrors(vertex, "VERTEX");
|
||||
// Fragment Shader
|
||||
fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragment, 1, &fShaderCode, NULL);
|
||||
glCompileShader(fragment);
|
||||
checkCompileErrors(fragment, "FRAGMENT");
|
||||
// If geometry shader is given, compile geometry shader
|
||||
GLuint geometry;
|
||||
if(geometryPath != nullptr)
|
||||
{
|
||||
const GLchar * gShaderCode = geometryCode.c_str();
|
||||
geometry = glCreateShader(GL_GEOMETRY_SHADER);
|
||||
glShaderSource(geometry, 1, &gShaderCode, NULL);
|
||||
glCompileShader(geometry);
|
||||
checkCompileErrors(geometry, "GEOMETRY");
|
||||
}
|
||||
// Shader Program
|
||||
this->Program = glCreateProgram();
|
||||
glAttachShader(this->Program, vertex);
|
||||
glAttachShader(this->Program, fragment);
|
||||
if(geometryPath != nullptr)
|
||||
glAttachShader(this->Program, geometry);
|
||||
glLinkProgram(this->Program);
|
||||
checkCompileErrors(this->Program, "PROGRAM");
|
||||
// Delete the shaders as they're linked into our program now and no longer necessery
|
||||
glDeleteShader(vertex);
|
||||
glDeleteShader(fragment);
|
||||
if(geometryPath != nullptr)
|
||||
glDeleteShader(geometry);
|
||||
|
||||
}
|
||||
// Uses the current shader
|
||||
void Use() { glUseProgram(this->Program); }
|
||||
|
||||
private:
|
||||
void checkCompileErrors(GLuint shader, std::string type)
|
||||
{
|
||||
GLint success;
|
||||
GLchar infoLog[1024];
|
||||
if(type != "PROGRAM")
|
||||
{
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||
if(!success)
|
||||
{
|
||||
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
|
||||
std::cout << "| ERROR::::SHADER-COMPILATION-ERROR of type: " << type << "|\n" << infoLog << "\n| -- --------------------------------------------------- -- |" << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glGetProgramiv(shader, GL_LINK_STATUS, &success);
|
||||
if(!success)
|
||||
{
|
||||
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
|
||||
std::cout << "| ERROR::::PROGRAM-LINKING-ERROR of type: " << type << "|\n" << infoLog << "\n| -- --------------------------------------------------- -- |" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user