前言:
我们现在把着色器的代码读取,编译,链接,以及检查错误封装成一个类,不然的话 写起来麻烦臃肿
这里就不详细说了 直接上代码了
Shader
shader.h
shader.cpp
#include "Shader.h"
Shader::Shader(const GLchar * vertexPath, const GLchar * fragmentPath)
{
std::string vertexCode;
std::string fragmentCode;
std::ifstream vShaderFile;
std::ifstream fShaderFile;
vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try {
vShaderFile.open(vertexPath);
fShaderFile.open(fragmentPath);
std::stringstream vShaderStream, fShaderStream;
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fShaderFile.rdbuf();
vShaderFile.close();
fShaderFile.close();
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
}
catch (std::ifstream::failure e)
{
std::cerr << "Failed read file" << std::endl;
}
const char* vShaderCode = vertexCode.c_str();
const char* fShaderCode = fragmentCode.c_str();
unsigned int vertex, fragment;
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
checkComplileError(vertex, "VERTEX");
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fShaderCode, NULL);
glCompileShader(fragment);
checkComplileError(fragment,"FRAGMENT");
ID = glCreateProgram();
glAttachShader(ID, vertex);
glAttachShader(ID, fragment);
glLinkProgram(ID);
checkComplileError(ID, "PROGRAM");
glDeleteShader(vertex);
glDeleteShader(fragment);
}
Shader::~Shader()
{
}
void Shader::use()
{
glUseProgram(ID);
}
void Shader::checkComplileError(unsigned int shader, std::string type)
{
int success;
char infoLog[1024];
if (type != "PROGRAM")
{
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
std::cerr << "Failed to complie shader:" << infoLog << std::endl;
}
}
else
{
glGetProgramiv(shader, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
std::cout << "Failed to link shader:" << infoLog << std::endl;
}
}
}
默认的构造就是传着色器的路径,然后读取代码进行编译链接以及检错,这样就方便多了
这两个就是我创建的着色器的文件,后缀和名字没有限制 想怎么命名都可以
使用shader
// testOpenGl_2shaderClass.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <glad/glad.h>
#include <iostream>
#include "openGL/include/GLFW/glfw3.h"
#include "Shader.h"
inline void frameBuffer_size_callback(GLFWwindow* w, int width, int height)
{
glViewport(0, 0, width, height);
}
int main()
{
std::cout << "Hello opengl!\n";
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "learnOpengl", NULL, NULL);
if (window == NULL)
{
std::cout << "opengl window failed" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, frameBuffer_size_callback);
/*glad:load all opengl function pointer */
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "failed to initalize glad" << std::endl;
return -1;
}
//读取 编译 连接 shader
Shader m_shader("vertexShader.vs","fragmentShader.fs");
float vertices[] =
{
//位置 //颜色
0.5f,-0.5f,0.0f, 1.0f,0.5f,1.0f,
-0.5f,-0.5f,0.0f, 0.0f,1.0f,0.0f,
0.0f,0.5f,0.0f,0.0f,0.0f,1.0f
};
unsigned int VBO, VAO;
//创建vertex array 绑定设置 vertex buffer 配置 verter 属性
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER,VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
m_shader.use();
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
system("pause");
}