作为图形硬件的软件接口,OpenGL用途是将二维和三维对象呈现到帧缓冲区中。 这些对象描述为顶点序列, (定义几何对象) 或定义图像) 像素,将内存连续的顶点数据,通过Opengl接口送入显卡缓存,并且通过接口来告诉显卡怎么解释这些显存中的数据。这里就用到了几个重要的部分,就是着色器(shader)。
- 顶点着色器
顶点着色器(Vertex Shader)是几个可编程着色器中的一个。如果我们打算做渲染的话,现代OpenGL需要我们至少设置一个顶点和一个片段着色器。
vertex.glsl
#version 330 core
layout (location = 0) in vec3 Position;
void main()
{
gl_Position = vec4(Position.x, Position.y, Position.z, 1.0);
}
- 片段着色器
fragment.glsl
#version 330 core
out vec4 color;
void main()
{
color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
- C++封装着色器程序
着色器程序相当于放入显卡的一个程序,它对每个显存的点进行处理,它最大的优点是利用每个显卡GPU单元可以并行处理,极大的节省计算时间。
ShaderProgram.h
#pragma once
#include <iostream>
#define GLEW_STATIC
#include "./include/GL/glew.h"
#include "./include/GLFW/glfw3.h"
class ShaderProgram
{
public:
ShaderProgram();
~ShaderProgram();
bool init(const char *vertexSour, const char* fragmentSour);
bool use();
bool unUse();
private:
GLint creatShader(const char* shaderSour, GLuint shaderType);
GLint creatShaderProgram(GLuint vertexShader, GLuint fragShader);
GLuint m_progamShader;
};
ShaderProgram.cpp
#include "./include/shaders/ShaderProgram.h"
static const uint16_t cn_logBufferMax = 512;
ShaderProgram::ShaderProgram()
{
m_progamShader = -1;
}
ShaderProgram::~ShaderProgram()
{
if (m_progamShader != -1)
{
glDeleteProgram(m_progamShader);
}
}
bool ShaderProgram::init(const char* vertexSour, const char* fragmentSour)
{
GLint verShader = creatShader(vertexSour, GL_VERTEX_SHADER);
if (verShader < 0)
{
return false;
}
GLint fragShader = creatShader(fragmentSour, GL_FRAGMENT_SHADER);
if (fragShader < 0)
{
return false;
}
int program = creatShaderProgram(verShader, fragShader);
if (program < 0)
{
return false;
}
m_progamShader = program;
glDeleteShader(verShader);
glDeleteShader(fragShader);
return true;
}
bool ShaderProgram::use()
{
if (m_progamShader <= 0)
{
return false;
}
glUseProgram(m_progamShader);
return true;
}
bool ShaderProgram::unUse()
{
if (m_progamShader <= 0)
{
return false;
}
glUseProgram(0);
return true;
}
GLint ShaderProgram::creatShader(const char* shaderSour, GLuint shaderType)
{
GLuint shaderInst = glCreateShader(shaderType);
glShaderSource(shaderInst, 1, &shaderSour, nullptr);
glCompileShader(shaderInst);
GLint sucess;
GLchar log[cn_logBufferMax];
glGetShaderiv(shaderInst, GL_COMPILE_STATUS, &sucess);
if (!sucess)
{
glGetShaderInfoLog(shaderInst, sizeof(log), nullptr, log);
std::cout << "ERROR::SHADER::<<"<< shaderType <<"::COMPILATION_FAILED\n" << log << std::endl;
return -1;
}
return shaderInst;
}
GLint ShaderProgram::creatShaderProgram(GLuint vertexShader, GLuint fragShader)
{
GLuint progamShader = glCreateProgram();
glAttachShader(progamShader,vertexShader);
glAttachShader(progamShader, fragShader);
glLinkProgram(progamShader);
GLint success;
GLchar log[cn_logBufferMax];
glGetProgramiv(progamShader, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(progamShader, sizeof(log), nullptr, log);
std::cout << "ERROR::PROGRAM::<<::COMPILATION_FAILED\n" << log << std::endl;
glDeleteShader(vertexShader);
glDeleteShader(fragShader);
return -1;
}
return progamShader;
}