自己封装的Shader类(后面继续改进)
shader.h
#pragma once
#include "sb7.h"
#include <string>
class Shader
{
public:
Shader();
Shader(const std::string vertexPath, const std::string fragmentPath);
void use();
private:
GLuint program;
std::string vertexString;
const char* vertexSource;
std::string fragmentString;
const char* fragmentSource;
private:
void checkCompileErrors(unsigned int ID, std::string type);
};
shader.cpp
#include "Shader.h"
#include <fstream>
#include <sstream>
#include <iostream>
#include <exception>
Shader::Shader(){}
Shader::Shader(const std::string vertexPath, const std::string fragmentPath)
{
std::ifstream vertexFile;
std::ifstream fragmentFile;
std::stringstream vertexSStream;
std::stringstream fragmentSStream;
program = glCreateProgram();
if (!vertexPath.empty())
{
vertexFile.open(vertexPath);
vertexFile.exceptions(std::ifstream::badbit || std::ifstream::failbit);
try
{
if (!vertexFile.is_open())
{
throw std::exception("open vertex shader file fail");
}
vertexSStream << vertexFile.rdbuf();
vertexFile.close();
vertexString = vertexSStream.str();
vertexSource = vertexString.c_str();
GLuint vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
glAttachShader(program, vertexShader);
glLinkProgram(program);
checkCompileErrors(program, "VERTEX");
glDeleteShader(vertexShader);
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
}
if (!fragmentPath.empty())
{
fragmentFile.open(fragmentPath);
fragmentFile.exceptions(std::ifstream::badbit || std::ifstream::failbit);
try
{
if (!fragmentFile.is_open())
{
throw std::exception("open fragment shader file fail");
}
fragmentSStream << fragmentFile.rdbuf();
fragmentFile.close();
fragmentString = fragmentSStream.str();
fragmentSource = fragmentString.c_str();
GLuint fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
checkCompileErrors(program, "PROGRAM");
glDeleteShader(fragmentShader);
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
}
}
void Shader::use()
{
glUseProgram(program);
}
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
vertex shader
#version 450 core
layout(location = 0) in vec4 offset;
layout(location = 1) in vec4 color;
out vec4 vs_color;
void main()
{
const vec4 vertices[3] = 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));
vs_color = color;
gl_Position = vertices[gl_VertexID] + offset;
}
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_application : public sb7::application
{
void startup()
{
shader = new Shader("vertexShader.vert", "fragShader.frag");
glCreateVertexArrays(2, vertex_arrays_object);
glBindVertexArray(vertex_arrays_object[0]);
glBindVertexArray(vertex_arrays_object[1]);
}
void render(double currentTime)
{
const GLfloat color[] = {
(float)sin(currentTime) * 0.5f + 0.5f,
(float)cos(currentTime) * 0.5f + 0.5f, 0.0f, 1.0f
};
glClearBufferfv(GL_COLOR, 0, color);
shader->use();
GLfloat attrib[]{
(float)sin(currentTime) * 0.5f,
(float)cos(currentTime) * 0.6f, 0.0, 0.0f
};
GLfloat triangleColor[] = {
(float)sin(currentTime) * 0.2f + 0.5f,
(float)cos(currentTime) * 0.2f + 0.5f, 0.0f, 1.0f
};
glVertexAttrib4fv(0, attrib);
glVertexAttrib4fv(1, triangleColor);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void shutdown()
{
}
private:
Shader* shader;
GLuint vertex_arrays_object[2];
};
DECLARE_MAIN(my_application);
出现过的问题
忽略了vao的创建和绑定
//创建数组对象
glCreateVertexArrays(2, vertex_arrays_object);
//绑定array对象到OpenGL上下文,让OpenGL知道这些数据
glBindVertexArray(vertex_arrays_object[0]);
glBindVertexArray(vertex_arrays_object[1]);
一开始我没有写上面的代码,导致一直无法绘制出图形,并且出现错误。 GL_INVALID_OPERATION error generated. Array object is not active.
展示
|