OpenGL学习之简单的着色器管理类

为了方便使用着色器,我自己封装了一个着色器类

1. ShaderAdmin.h
//
//  ShaderAdmin.hpp
//  GL_Program
//
//

#ifndef ShaderAdmin_hpp
#define ShaderAdmin_hpp

#include <stdio.h>
#include <fstream>
#include <sstream>
#include <iostream>
#include <GL/glew.h>

using namespace std;
class ShaderAdmin
{
public:
    //着色器ID;
    GLuint m_program;
    //构造器读取并构建着色器
    ShaderAdmin(const GLchar *vertexPath,const GLchar *fragmentPath);
    ~ShaderAdmin();
    void Use();
private:
    //编译着色器
    void compileShader(const GLchar *vShaderCode,const GLchar *fShaderCode);
    //获取着色器编译错误日志,若没有获取到任何内容,则证明编译成功
    void getCompileShaderErrorLog(GLuint shader);
    //获取着色器连接错误日志,若没有获取到任何内容,则证明编译成功
    void getLinkShaderProgramErrorLog(GLuint shaderProgram);
};
#endif /* ShaderAdmin_hpp */
2. ShaderAdmin.cpp
//
//  ShaderAdmin.cpp
//  GL_Program
//

#include "ShaderAdmin.hpp"

ShaderAdmin::ShaderAdmin(const GLchar *vertexPath,const GLchar *fragmentPath)
{
    // 1. 从文件路径中获取顶点/片段着色器
    string vertexCode;
    string fragmentCode;
    ifstream vShaderFile;
    ifstream fShaderFile;
    //保证ifstream对象可以抛出异常
    vShaderFile.exceptions(ifstream::badbit);
    fShaderFile.exceptions(ifstream::badbit);
    try
    {
        //打开文件
        vShaderFile.open(vertexPath);
        fShaderFile.open(fragmentPath);
        if (!vShaderFile.is_open()||!fShaderFile.is_open())
        {
            cout << "无法打开文件!" << endl;
            return;
        }
        stringstream vShaderStream,fShaderStream;
        //读取文件的缓冲内容到流中
        vShaderStream << vShaderFile.rdbuf();
        fShaderStream << fShaderFile.rdbuf();
        //关闭文件
        vShaderFile.close();
        fShaderFile.close();
        //转换流至字符串
        vertexCode = vShaderStream.str();
        fragmentCode = fShaderStream.str();
    }
    catch (ifstream::failure e)
    {
        cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << endl;
    }

    const GLchar *vShaderCode = vertexCode.c_str();
    const GLchar *fShaderCode = fragmentCode.c_str();
    compileShader(vShaderCode, fShaderCode);
}
ShaderAdmin::~ShaderAdmin()
{

}
void ShaderAdmin::Use()
{
    glUseProgram(this->m_program);
}
void ShaderAdmin::compileShader(const GLchar *vShaderCode, const GLchar *fShaderCode)
{
    GLuint vShader,fShader;

    vShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vShader,1,&vShaderCode,NULL);
    glCompileShader(vShader);
    getCompileShaderErrorLog(vShader);

    fShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fShader,1,&fShaderCode,NULL);
    glCompileShader(fShader);
    getCompileShaderErrorLog(fShader);

    m_program = glCreateProgram();
    glAttachShader(m_program,vShader);
    glAttachShader(m_program,fShader);
    glLinkProgram(m_program);
    getLinkShaderProgramErrorLog(m_program);

    glDeleteShader(vShader);
    glDeleteShader(fShader);
}
void ShaderAdmin::getCompileShaderErrorLog(GLuint shader)
{
    GLint sucess;
    GLchar infoLog[512];
    glGetShaderiv(shader,GL_COMPILE_STATUS,&sucess);
    if (!sucess)
    {
        glGetShaderInfoLog(shader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
}
void ShaderAdmin::getLinkShaderProgramErrorLog(GLuint shaderProgram)
{
    GLint success;
    GLchar infoLog[512];
    glGetProgramiv(shaderProgram,GL_LINK_STATUS,&success);
    if (!success)
    {
        glGetShaderInfoLog(shaderProgram,512,NULL,infoLog);
    }
}
3. main.cpp
//  main.cpp
//  GL_Program
//

#include <iostream>
#include <stdlib.h>
#include <math.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "ShaderAdmin.hpp"

#define WIDTH 800
#define HEIGHT 600
#define TITLE "OpenGL"


void initGL();
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);

GLuint VAO,VBO,EBO;

int main(int argc, const char * argv[]) {
    // insert code here...
    initGL();
    GLFWwindow *win = glfwCreateWindow(WIDTH, HEIGHT, TITLE, nullptr,nullptr);
    if (win == nullptr)
    {
        cout << "Failed to create GLFW window!"<<endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(win);
    glfwSetKeyCallback(win, key_callback);

    glewExperimental = GL_TRUE;
    if(glewInit() != GLEW_OK)
    {
        cout << "Failed to initialize GLEW" << endl;
    }

    int width,height;
    glfwGetFramebufferSize(win, &width, &height);
    glViewport(0, 0, width, height);

    ShaderAdmin shader("shader/vShader.vert","shader/fShader.frag");
    while (!glfwWindowShouldClose(win))
    {
        glfwPollEvents();
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        shader.Use();
        GLfloat offset = 0.0f;
        glUniform1f(glGetUniformLocation(shader.m_program,"offset"),offset);

        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);

        glBindVertexArray(0);

        glfwSwapBuffers(win);
    }

    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);
    glfwTerminate();

    return 0;
}

void initGL()
{
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    //Mac环境必须添加下面这行才能生效
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
    // 当用户按下ESC键,我们设置window窗口的WindowShouldClose属性为true
    // 关闭应用程序
    if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}
void renderTriangle()
{
    GLfloat vertices[] = {
        0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,  // Bottom Right
        -0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,  // Bottom Left
        0.0f,  0.5f, 0.0f,  0.0f, 0.0f, 1.0f   // Top
    };

    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(GLfloat),(GLvoid *)0);
    glEnableVertexAttribArray(0);
    //颜色属性
    glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,6 * sizeof(GLfloat),(GLvoid *)(3*sizeof(GLfloat)));
    glEnableVertexAttribArray(1);

    glBindBuffer(GL_ARRAY_BUFFER,0);
    glBindVertexArray(0);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值