To learn OpenGL, I am writing a little wrapper using the (almost) latest C++ standard. I would like a review on the shape and vertices class, what I did wrong, what I can improve, and what I can change.vertices.hpp#pragma once#include <cassert>#include <vector>#define GLEW_STATIC#include <GL/glew.h>namespace pck{class Vertices{    public:        Vertices(std::initializer_list<GLfloat> p);        Vertices(std::initializer_list<GLfloat> p, std::initializer_list<GLfloat> c);        Vertices(std::initializer_list<GLfloat> p, std::initializer_list<GLfloat> c, std::initializer_list<GLfloat> t);        int vertices_number() { return vertices_number_; };        GLfloat* data() { return vertices_.data(); };        size_t size() { return vertices_.size(); };        GLfloat* positions() { return positions_.data(); };        size_t positions_size() { return positions_.size(); };        GLfloat* colors() { return colors_.data(); };        size_t colors_size() { return colors_.size(); };        GLfloat* textures() { return textures_.data(); };        size_t textures_size() { return textures_.size(); };    private:        void init();        int vertices_number_;        std::vector<GLfloat> positions_;        std::vector<GLfloat> colors_;        std::vector<GLfloat> textures_;        std::vector<GLfloat> vertices_;};}vertices.cpp#include <pck/vertices.hpp>#include <iostream>using namespace pck;Vertices::Vertices(std::initializer_list<GLfloat> p) :    positions_(p){    init();}Vertices::Vertices(std::initializer_list<GLfloat> p, std::initializer_list<GLfloat> c) :    positions_(p), colors_(c){    init();}Vertices::Vertices(std::initializer_list<GLfloat> p, std::initializer_list<GLfloat> c, std::initializer_list<GLfloat> t) :    positions_(p), colors_(c), textures_(t){    init();}voidVertices::init(){    assert(positions_.size() % 3 == 0 && Error positions size);    assert(colors_.size() % 3 == 0 && Error colors size);    assert(textures_.size() % 2 == 0 && Error textures size);    for(size_t i = 0; i < (positions_.size() / 3); i++)    {        for(size_t j = 0; j < 3; j++)            vertices_.push_back(positions_[i * (positions_.size() / (positions_.size() / 3)) + j]);        for(size_t k = 0; k < 3; k++)        {            if(colors_.size() != 0)                vertices_.push_back(colors_[i * (colors_.size() / ((colors_.size() / 3))) + k]);            else                vertices_.push_back(0);        }        for(size_t l = 0; l < 2; l++)        {            if(textures_.size() != 0)                vertices_.push_back(textures_[i * (textures_.size() / (textures_.size() / 2)) + l]);            else                vertices_.push_back(0);        }    }    vertices_number_ = positions_.size() / (positions_.size() / 3);}drawable.hpp#pragma oncenamespace pck{class Drawable{    public:        virtual void draw() = 0;};}shape.hpp#pragma once#include <string>#include <vector>#define GLEW_STATIC#include <GL/glew.h>#include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>#include <glm/gtc/type_ptr.hpp>#include <SOIL/SOIL.h>#include <pck/drawable.hpp>#include <pck/program.hpp>#include <pck/vertices.hpp>namespace pck{class Shape : public Drawable{    public:        Shape(Vertices* v);        Shape(Vertices* v, std::initializer_list<GLuint> i);        ~Shape();        void set_program(Program* program);        void set_texture(std::string path);        void draw();    private:        Vertices* vertices_;        std::vector<GLuint> indices_;        int vertices_number_;        GLuint VBO_;        GLuint VAO_;        GLuint EBO_;        Program* program_ = nullptr;        int tex_width_;        int tex_height_;        unsigned char* image_ = nullptr;        GLuint texture_;};}shape.cpp#include <pck/shape.hpp>using namespace pck;Shape::Shape(Vertices* v) :        vertices_number_(v->vertices_number()), vertices_(v){    glGenVertexArrays(1, &VAO_);    glGenBuffers(1, &VBO_);    glBindVertexArray(VAO_);    glBindBuffer(GL_ARRAY_BUFFER, VBO_);    glBufferData(GL_ARRAY_BUFFER, vertices_->size() * sizeof(GLfloat), vertices_->data(), GL_STATIC_DRAW);    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);    glEnableVertexAttribArray(0);    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));    glEnableVertexAttribArray(1);    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));    glEnableVertexAttribArray(2);    glBindVertexArray(0);}Shape::Shape(Vertices *v, std::initializer_list<GLuint> i) :    vertices_number_(indices_.size()), vertices_(v), indices_(i){    glGenVertexArrays(1, &VAO_);    glGenBuffers(1, &VBO_);    glGenBuffers(1, &EBO_);    glBindVertexArray(VAO_);    glBindBuffer(GL_ARRAY_BUFFER, VBO_);    glBufferData(GL_ARRAY_BUFFER, vertices_->size() * sizeof(GLfloat), vertices_->data(), GL_STATIC_DRAW);    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO_);    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_.size() * sizeof(GLfloat), indices_.data(), GL_STATIC_DRAW);    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);    glEnableVertexAttribArray(0);    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));    glEnableVertexAttribArray(1);    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));    glEnableVertexAttribArray(2);    glBindBuffer(GL_ARRAY_BUFFER, 0);    glBindVertexArray(0);}Shape::~Shape(){    delete program_;    glDeleteVertexArrays(1, &VAO_);    glDeleteBuffers(1, &VBO_);    glDeleteBuffers(1, &EBO_);}voidShape::set_program(Program* program){    program_ = program;}voidShape::set_texture(std::string path){    glBindVertexArray(VAO_);    glGenTextures(1, &texture_);    glBindTexture(GL_TEXTURE_2D, texture_);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    image_ = SOIL_load_image(path.c_str(), &tex_width_, &tex_height_, 0, SOIL_LOAD_RGB);    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex_width_, tex_height_, 0, GL_RGB, GL_UNSIGNED_BYTE, image_);    glGenerateMipmap(GL_TEXTURE_2D);    SOIL_free_image_data(image_);    glBindTexture(GL_TEXTURE_2D, 0);}voidShape::draw(){    if(texture_ != 0)        glBindTexture(GL_TEXTURE_2D, texture_);    if(program_ != nullptr)        program_->use();    glBindVertexArray(VAO_);    if(EBO_ == 0)        glDrawArrays(GL_TRIANGLES, 0, vertices_number_);    else       glDrawElements(GL_TRIANGLES, vertices_number_, GL_UNSIGNED_INT, 0);    glBindVertexArray(0);}An example of utilisation; a square made from 2 triangles with a texture:#include <iostream>#include <vector>#define GLEW_STATIC#include <GL/glew.h>#include <pck/shape.hpp>#include <pck/shader.hpp>#include <pck/program.hpp>#include <pck/window.hpp>const GLuint WIDTH = 800, HEIGHT = 600;int main(){    pck::Window window(Pancake Texture Example, WIDTH, HEIGHT);    pck::Program* prog = new pck::Program(pck::VertShader(texture.vs), pck::FragShader(texture.fs));    pck::Vertices* v = new pck::Vertices({        // Positions         0.5f,  0.5f, 0.0f,         0.5f, -0.5f, 0.0f,        -0.5f, -0.5f, 0.0f,        -0.5f,  0.5f, 0.0f    }, {        // Colors         1.0f, 0.0f, 0.0f,         0.0f, 1.0f, 0.0f,         0.0f, 0.0f, 1.0f,         1.0f, 1.0f, 0.0f    }, {        // Texture coords         1.0f, 1.0f,         1.0f, 0.0f,         0.0f, 0.0f,         0.0f, 1.0f    });    pck::Shape* s = new pck::Shape(v, {        0, 1, 3,        1, 2, 3    });    s->set_program(prog);    s->set_texture(crate.jpg);    bool quit = false;    SDL_Event e;    while(!quit)    {        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);        while( SDL_PollEvent(&e) != 0 )        {             if(e.type == SDL_QUIT)             {                 quit = true;             }             else if(e.type == SDL_KEYDOWN)             {                 if(e.key.keysym.sym == SDLK_ESCAPE)                     quit = true;             }        }        s->draw();        window.render();    }    return 0;}
C++ OpenGL3.3 wrapper
c++;opengl