片段着色器
片段着色器是负责确定各片段的颜色,然后将片段发送到帧缓冲,以便合成到窗口。 就是在这个阶段确定模型的颜色
自己封装的Shader类(改进中…)
Shader.h
#pragma once
#include "sb7.h"
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <exception>
class Shader
{
public:
Shader();
Shader(const std::string vertexPath, const std::string fragmentPath);
Shader(const std::string vertexPath, const std::string tescPath, const std::string tesePath, const std::string fragmentPath);
void setVertexShder(const std::string vertexPath);
void setTescShader(const std::string tescPath);
void setTeseShader(const std::string tesePath);
void setFragmentShader(const std::string fragmentPath);
void use();
private:
GLuint program;
std::string shaderString;
const char* shaderSource;
std::ifstream shaderFile;
std::stringstream shaderSStream;
private:
void checkCompileErrors(unsigned int ID, std::string type);
void readShaderSource(std::string shaderFilePath);
void linkShader(GLuint shaderObject);
};
Shader.cpp
#include "Shader.h"
Shader::Shader(){}
Shader::Shader(const std::string vertexPath, const std::string fragmentPath)
{
program = glCreateProgram();
setVertexShder(vertexPath);
setFragmentShader(fragmentPath);
}
Shader::Shader(const std::string vertexPath, const std::string tescPath, const std::string tesePath, const std::string fragmentPath)
{
program = glCreateProgram();
setVertexShder(vertexPath);
setFragmentShader(fragmentPath);
setTescShader(tescPath);
setTeseShader(tesePath);
}
void Shader::setVertexShder(const std::string vertexPath)
{
readShaderSource(vertexPath);
GLuint vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
linkShader(vertexShader);
}
void Shader::setTescShader(const std::string tescPath)
{
readShaderSource(tescPath);
GLuint tescShader;
tescShader = glCreateShader(GL_TESS_CONTROL_SHADER);
linkShader(tescShader);
}
void Shader::setTeseShader(const std::string tesePath)
{
readShaderSource(tesePath);
GLuint teseShader;
teseShader = glCreateShader(GL_TESS_EVALUATION_SHADER);
linkShader(teseShader);
}
void Shader::setFragmentShader(const std::string fragmentPath)
{
readShaderSource(fragmentPath);
GLuint fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
linkShader(fragmentShader);
}
void Shader::use()
{
glUseProgram(program);
}
void Shader::readShaderSource(std::string shaderFilePath)
{
shaderSStream.str("");
memset(&shaderSource, '\0', sizeof(shaderSource));
if (!shaderFilePath.empty())
{
shaderFile.open(shaderFilePath);
shaderFile.exceptions(std::ifstream::badbit || std::ifstream::failbit);
try
{
if (!shaderFile.is_open())
{
throw std::exception("open fragment shader file fail");
}
shaderSStream << shaderFile.rdbuf();
shaderFile.close();
shaderString = shaderSStream.str();
shaderSource = shaderString.c_str();
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
}
}
void Shader::linkShader(GLuint shaderObject)
{
glShaderSource(shaderObject, 1, &shaderSource, NULL);
glCompileShader(shaderObject);
glAttachShader(program, shaderObject);
glLinkProgram(program);
checkCompileErrors(program, "PROGRAM");
glDeleteShader(shaderObject);
}
void Shader::checkCompileErrors(unsigned int ID, std::string type)
{
int success;
char infoLog[512];
if (type != "PROGRAM")
{
glGetShaderiv(ID, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(ID, 512, NULL, infoLog);
std::cout << "shader compile error: " << infoLog << std::endl;
}
}
else
{
glGetProgramiv(ID, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(ID, 512, NULL, infoLog);
std::cout << "program linking error: " << infoLog << std::endl;
}
}
}
shader file
vertex shader
#version 450 core
layout(location = 0) in vec4 offset;
out vec4 vs_color;
void main()
{
const vec4 vertices[] = vec4[3](vec4(0.25, -0.25, 0.5, 1.0),
vec4(-0.25, -0.25, 0.5, 1.0),
vec4(0.25, 0.25, 0.5, 1.0));
const vec4 colors[] = vec4[3](vec4(1.0, 0.0, 0.0, 1.0),
vec4(0.0, 1.0, 0.0, 1.0),
vec4(0.0, 0.0, 1.0, 1.0));
gl_Position = vertices[gl_VertexID];
vs_color = colors[gl_VertexID];
}
fragment shader
#version 450 core
in vec4 vs_color;
out vec4 color;
void main()
{
color = vs_color;
}
代码
#include "sb7.h"
#include "Shader.h"
#include <math.h>
class my_appliciation : public sb7::application
{
public:
void startup()
{
shader = new Shader("vertexShader.vert", "fragmentShader.frag");
glCreateVertexArrays(1, &vertex_array_object);
glBindVertexArray(vertex_array_object);
}
void render(double currentTime)
{
GLfloat attrib[] = { (float)sin(currentTime) * 0.5f + 0.5,
(float)cos(currentTime) * 0.6f + 0.5, 0, 0 };
shader->use();
glVertexAttrib4fv(0, attrib);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void shutdown()
{
}
private:
Shader* shader;
GLuint vertex_array_object;
};
DECLARE_MAIN(my_appliciation);
效果
|